hier mal mein aktueller Stand - ANFÄNGER level - freu mich über feedback, das geht sicher auch einfacher...
Code
let state=0;
// 0 - starup, waiting for normal input
// 1 - light on - waiting for auto off
// 2 - flashing for auto off
// 3 - flashing for permanent on
// 4 - permanent on
let CONFIG = {
defaultTickerDelay : 0.500, // secs for checking state
defaultTimeout : 30, // seconds for auto off
defaultFlashCounter : 3, // how often to flash
defaultFlashTime : 4.500, // secs between flashes
defaultFlashOffTime : 0.500, // secs in off during flashing
defaultLongPressTime : 1.500, // secs to keep button pressed for permanent on
};
let tickerHandle = 0;
let buttonHandle = 0;
let btn_down_ts = 0; // time of last btn_down
let switch_on_ts = 0; // ts for last light on
let switchState = false;
let next_on_ts = 0;
let next_off_ts = 0;
let debug = false; // TRUE for print to console, false by default
function RelaySet(state)
{
Shelly.call("switch.set",{ id: 0, on: state},function (result, code, msg, ud) {},null);
switchState = state;
}
function Check(event){
let info = event.info;
if (debug) { print(JSON.stringify(info));}
if (info.component === "switch:0" && info.state !== undefined)
{
switchState = info.state;
}
if (info.component === "input:0")
{
if (info.event === "btn_down")
{
btn_down_ts = info.ts;
buttonHandle = Timer.set(CONFIG.defaultTickerDelay*1000,false,checkButton,info.ts + CONFIG.defaultTickerDelay);
if (debug) { print ("button down now: ", info.ts); }
}
else if (info.event === "btn_up")
{
Timer.clear(buttonHandle); // stop buttonChecker
let btn_down_duration = info.ts - btn_down_ts;
if (debug) { print ("button down duration ", btn_down_duration , " ( ", info.ts, " - ", btn_down_ts, " )");}
if (state === 0)
{ // turn light on and activate auto off
state = 1;
if (debug) { print ("State set to 1");}
RelaySet(true);
switch_on_ts = info.ts;
tickerHandle = Timer.set(CONFIG.defaultTickerDelay*1000,false,tick,info.ts +CONFIG.defaultTickerDelay );
}
else if (state === 1)
{ // light is normal on - normal off
state = 0;
if (debug) { print ("State set to 0"); }
RelaySet(false);
Timer.clear(tickerHandle); // stop ticker
}
else if (state === 2)
{ // was blinking - back to normal on
Timer.clear(tickerHandle); // stop ticker
state = 1;
if (debug) { print ("State set from 2 back to 1"); }
switch_on_ts = info.ts;
RelaySet(true);
tickerHandle = Timer.set(CONFIG.defaultTickerDelay*1000,false,tick,info.ts + CONFIG.defaultTickerDelay);
}
else if (state === 3)
{ // on the way to perm on - ignore
if (debug) { print ("late release 1"); }
}
else if (state === 4)
{ // was perm on - back to off
if (btn_down_duration > CONFIG.defaultLongPressTime)
{ // still during switching on - ignore
if (debug) { print ("late release 2"); }
} else {
Timer.clear(tickerHandle); // stop ticker
state = 0;
if (debug) { print ("State set from 4 back to 0"); }
RelaySet(false);
}
}
}
}
}
function checkButton (ts)
{
if (debug) { print("checkButton ", ts); }
let btn_down_duration = ts - btn_down_ts;
if (debug) { print ("Button down for ", btn_down_duration , " ( ", ts, " - ", btn_down_ts, " )"); }
if (btn_down_duration > CONFIG.defaultLongPressTime)
{
if (debug) { print ("Long press detected"); }
state = 3;
if (debug) { print ("State set to 3"); }
RelaySet(true);
next_off_ts = ts + CONFIG.defaultFlashOffTime;
tickerHandle = Timer.set(CONFIG.defaultTickerDelay*1000,false,tick,ts + CONFIG.defaultTickerDelay); // ticker will handle rest
} else
{
buttonHandle = Timer.set(CONFIG.defaultTickerDelay*1000,false,checkButton,ts + CONFIG.defaultTickerDelay); // restart timer on new ts
}
}
function tick(ts)
{
if (debug) { print("tick ", ts); }
tickerHandle = Timer.set(CONFIG.defaultTickerDelay*1000,false,tick,ts + CONFIG.defaultTickerDelay); // restart timer on new ts
let switch_on_duration = (ts - switch_on_ts);
if (state === 1 ) // waiting for timed off
{
if (debug) { print ("switch_on_duration ",switch_on_duration); }
if (switch_on_duration > CONFIG.defaultTimeout - CONFIG.defaultFlashCounter * (CONFIG.defaultFlashTime + CONFIG.defaultFlashOffTime) )
{
state=2; // start flashing
if (debug) { print ("State set to 2"); }
RelaySet(false);
next_on_ts = ts + CONFIG.defaultFlashOffTime;
}
} else if (state === 2) // blinking
{
if (switch_on_duration > CONFIG.defaultTimeout) // enough - off now
{
state=0;
if (debug) { print ("State set to 0"); }
RelaySet(false);
Timer.clear(tickerHandle);
} else if ((switchState === false) && (next_on_ts < ts))
{
RelaySet(true);
next_off_ts = ts + CONFIG.defaultFlashTime;
} else if (switchState === true && next_off_ts < ts)
{
RelaySet(false);
next_on_ts = ts + CONFIG.defaultFlashOffTime;
}
if (debug) { print ("next on ", next_on_ts, " next off ", next_off_ts); }
} else if (state === 3) // blinking for perm on
{
if (switchState === true && next_off_ts < ts)
{
RelaySet(false);
next_on_ts = ts + CONFIG.defaultFlashOffTime;
} else if ((switchState === false) && (next_on_ts < ts))
{
RelaySet(true);
state=4;
if (debug) { print ("State set to 4"); }
Timer.clear(tickerHandle); // ticker job done
}
}
}
Shelly.addEventHandler(Check);
Alles anzeigen