-
Autor
Neu: Das Skript unter Setup 3 erlaubt nun auch die Eingabe von Benutzer und Passwort.
Hier die Lösung für das Problem, dass keine Blindtime unter einer Minute eingestellt werden kann.
Funktioniert mit Motion und Motion 2.
Setup 1: Der Motion schaltet einen Shelly Aktor direkt:
Hier tragt ihr im Aktor bei Output switched ON url folgende URL ein.
dadurch wird der Motion sofort wieder scharf geschaltet.
Setup 2: Ihr habt ein übergeordnetes System:
Sorgt dafür, dass das Sytem bei Erkennung einer Bewegung den unter Setup 1 genannten Befehl absetzt.
Setup 3: Ihr wollt es bequem und habt einen beliebigen Gen2 Shelly im gleichen Netz wie der/die Motion/s:
Verwendet dieses Skript und tragt in der Config alle gewünschten Motions ein:
fbt (Was die Abkürzung bedeutet, überlasse ich eurer Fantasie)
//GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
//More information: https://www.gnu.org/licenses/gpl-3.0.txt
//ABSOLUTELY NO WARRANTY!!!
//Version: 0.9.91
//Runs on Shelly Gen. 2
//Made by Ostfriese
//This script reduces the BLINDTIME
//of Shelly Motions
//to a few (< 3) seconds with a trick.
let CONFIG = {
motion_ips : ["192.168.0.101", "192.168.0.51"],
user: '',
pass: ''
}
//
//Define global variables.
//The ip of this Shelly.
let own_ip = '';
//The id of this script
let script_id = 0;
//Some needed variables.
let motion_count = CONFIG.motion_ips.length;
let busy = false;
let starting = true;
let startup = null
let temp_res
let ip_str = ''
let userpass = ''
//Get ip of this Shelly.
function get_own_ip() {
Shelly.call('Shelly.GetConfig', '',
function(result, error_code, error_message) {
own_ip = result.wifi.sta.ip;
}
);
}
//Output.
function log(to_log) {
console.log(to_log);
}
//Replace character in string.
function replace (str,find,rep) {
let ret_val = "";
for (let i=0; i<str.length; i++) {
if (str[i] === find) {
ret_val += rep;
}
else {
ret_val += str[i];
}
}
return ret_val;
}
//Basic html escape. Expandable by adding
//characters and escapes one to one.
function escape(str) {
let chars = [':' ,'/' ,'?' ,'=' ,'&'];
let escape = ['%3A','%2F','%3f','%3D','%26']
for (let i in chars) {
if(str.indexOf(chars[i]) > -1) {
str = replace(str,chars[i],escape[i])
}
}
return str;
}
function ip_to_str(ip) {
while (ip.length < 16) {
ip += ' ';
}
return ip;
}
//Send HTTP response to the client (Motion).
function send_response(response, body) {
response.code = 200;
response.body = body;
response.send();
log(body);
}
//This makes the trick mentioned above.
function blindtime_reset() {
response = temp_res
let wake_up_url = 'http://' + userpass + ip + '/settings/actions?index=0';
wake_up_url += '&enabled=true'+'&name=' + action_type;
ip_str = ip_to_str(ip);
Shelly.call('http.get', {url:wake_up_url,timeout:5},
function(result, error_code, error_message,action_type) {
if(error_code === 0) {
send_response(response, 'Blindtime reset : ' + ip_str + ' done');
}
else {
send_response(response, 'Blindtime reset : ' + ip_str + ' Error');
}
}
);
}
//Wait for HTTP requests from clients.
function watch(request,response) {
//Get the part after ? of the request.
ip = request.query;
//Begin configuration. Done once per Motion.
if(motion_count >0) {
motion_count -= 1;
//Get settings from client.
url ='http://' + userpass + ip + '/settings/actions';
action_type = 'motion_on';
Shelly.call('http.get', {url:url,timeout:10},
function(result, error_code, error_message,action_type) {
if(error_code === 0) {
let body = JSON.parse(result.body);
//Get action urls for MOTION DETECTED of the client.
let actions = JSON.parse(JSON.stringify(body['actions'][action_type]));
let urls = actions[0].urls;
//Build config url to reconfigure client.
let conf_url = 'http://' + userpass + ip + '/settings/actions?index=0';
conf_url += '&enabled=true'+'&name=' + action_type;
let i = 0;
for (let k in urls) {
let url = (urls[i]['url']);
if(url.indexOf('/fbt?') < 0) {
let int = (urls[i]['int']);
if(int === '') {
int = '0000-0000';
}
conf_url += '&urls[' + i + '][url]=' + escape(url);
conf_url += '&urls[' + i + '][int]=' + int;
i += 1;
}
}
//Append an action to tell this HTTP Server about movements.
int = '0000-0000';
url = 'http://' + own_ip + '/script/' + script_id + '/fbt?' + ip
ip_str = ip;
conf_url += '&urls[' + i + '][url]=' + url;
conf_url += '&urls[' + i + '][int]=' + int;
ip_str = ip_to_str(ip);
Shelly.call('http.get', {url:conf_url,timeout:5},
function(result, error_code, error_message,action_type) {
if(error_code === 0) {
log('Configure motion : ' + ip_str + ' done');
busy = false;
}
else {
log('Configure motion : ' + ip_str + ' ERROR');
busy = false;
}
}
);
}
},action_type
);
}
//End configuration.
//If already configured just re-enable the
//MOTION DETECTED to skip blindtime.
else {
ip_str = ip_to_str(ip);
log('Motion detected : ' + ip_str);
temp_res = response;
blindtime_reset();
}
}
//Starts the configuration of all Motions.
//Adding an action to MOTION DETECTED to trigger
//the function watch of this script at every detected move.
function start() {
//log(motion_count);
if(starting) {
starting = false;
Timer.clear(startup);
startup = Timer.set(1 * 1000,true,start);
}
if(busy || own_ip === '') {
return;
}
if(motion_count > 0) {
busy = true;
ip = CONFIG.motion_ips[motion_count - 1];
url = 'http://localhost/script/' + script_id + '/fbt?' + ip;
ip_str = ip_to_str(ip)
log('Configure motion : ' + ip_str);
Shelly.call('http.get', {url:url,timeout:5});
}
//Configuration done.
else {
Timer.clear(startup);
busy = false;
}
}
function main() {
log('Start...');
get_own_ip();
script_id = Shelly.getCurrentScriptId();
if (CONFIG.user) {
userpass = CONFIG.user + ':' + CONFIG.pass + '@';
}
//Register endpoint fbt for HTTP server.
//E.g.: http://192.168.0.16/script/6/fbt
HTTPServer.registerEndpoint('fbt',watch);
//Give some time for a proper start after reboot.
startup = Timer.set(3 * 1000,false,start);
}
main();
Alles anzeigen
Dass das Ganze funktioniert, sieht man direkt am Motion. Bei eingeschlteter LED.
Ohne o.g. Tricks:
Bei Erkennung einer Bewegung blinkt der Motion einmal rot.
Mit o.g. Tricks:
Bei Erkennung einer Bewegung blinkt der Motion einmal rot und kurz darauf blau
Somit habt ihr die volle Kontrolle und seid nicht auf diese übertriebene Akkuspareinstellung angewiesen.
Negative Auswirkungen auf den Akkuverbrauch konnte ich nicht feststellen. Ich habe z.B. zwei Motion in einemTreppenhaus verbaut seit 1 1/2 Jahren und musste ein mal laden.