Tasmota und Rules ist auch so eine Sache, und ist dann halt auch nicht so simpel in der Cloud, bzw. halt anders zu integrieren. Würde gerne beim Shelly Ökosystem bleiben...
Habs mal mit Chat Gpt versucht, und bis auf das blinken vor dem Ablauf der PIR Zeit scheint es zu funktionieren, irgendwie erschreckend... hier mal der KI generierte Source Code:
/******************************************************
* Shelly Dimmer 0-10V PM Gen3
* PIR + Taster Steuerung mit Blink + PIR-Sperre
* Fertiges Script basierend auf realen Events
******************************************************/
/************** KONFIGURATION ************************/
let DIM_AUTO = 40; // Helligkeit PIR
let DIM_MANUAL = 90; // Dauerlicht Taster
let AUTO_OFF_TIME = 60000; // ms
let WARNING_TIME = 4000; // Blink vor AUS
let BLOCK_TIME = 15000; // PIR Sperre nach Taster
let BLINK_TIME = 300; // Blinkintervall
/************** STATUS ********************************/
let state = "OFF";
// Timer Handles
let tAuto=null, tWarn1=null, tWarn2=null, tBlock=null;
// Zeitstempel
let autoOffAt=0, warnAt=0, blockUntil=0;
// Flanken
let lastPIR=false, lastBTN=false;
/************** HILFSFUNKTIONEN ************************/
function logEvent(msg){ print("[EVENT]",msg); }
function setLight(pct){ Shelly.call("Light.Set",{id:0,on:pct>0,brightness:pct}); }
function clearTimer(t){ if(t) Timer.clear(t); }
function clearAllTimers(){ clearTimer(tAuto); clearTimer(tWarn1); clearTimer(tWarn2); }
/************** HARDWARE-KONFIGURATION *****************/
function configureHardware(){
setLight(0);
logEvent("Dimmer auf 0% gesetzt");
Shelly.call("Input.SetConfig",{id:0,mode:"detached"},function(r){
if(r && r.success) logEvent("S1 (PIR) auf detached gesetzt");
else logEvent("S1 Konfig versucht (keine Rückmeldung)");
});
Shelly.call("Input.SetConfig",{id:1,mode:"detached"},function(r){
if(r && r.success) logEvent("S2 (Taster) auf detached gesetzt");
else logEvent("S2 Konfig versucht (keine Rückmeldung)");
});
}
/************** ZUSTANDSFUNKTIONEN *********************/
function setOff(){
setLight(0);
state="OFF"; autoOffAt=0; warnAt=0;
logEvent("STATE → OFF");
}
function enterAuto(){
setLight(DIM_AUTO);
state="AUTO";
logEvent("STATE → AUTO (PIR aktiv)");
restartAutoTimer();
}
function enterManual(){
clearAllTimers();
setLight(DIM_MANUAL);
state="MANUAL";
logEvent("STATE → MANUAL (Dauerlicht)");
}
function enterBlocked(){
setOff();
state="BLOCKED";
blockUntil=Date.now()+BLOCK_TIME;
logEvent("STATE → BLOCKED (PIR gesperrt)");
clearTimer(tBlock);
tBlock=Timer.set(BLOCK_TIME,false,function(){
state="OFF"; blockUntil=0;
logEvent("BLOCK ENDE → OFF");
});
}
/************** TIMER **********************************/
function restartAutoTimer(){
clearTimer(tAuto);
warnAt=Date.now()+(AUTO_OFF_TIME-WARNING_TIME);
autoOffAt=Date.now()+AUTO_OFF_TIME;
tAuto=Timer.set(AUTO_OFF_TIME-WARNING_TIME,false,startWarning);
}
function startWarning(){
state="WARNING";
logEvent("STATE → WARNING (Blink vor AUS)");
setLight(0);
tWarn1=Timer.set(BLINK_TIME,false,function(){ setLight(DIM_AUTO); });
tWarn2=Timer.set(BLINK_TIME*2,false,function(){ setLight(0); });
Timer.set(WARNING_TIME,false,setOff);
}
/************** INPUT HANDLING ************************/
Shelly.addEventHandler(function(e){
if(e.name!=="input") return;
// PIR S1 (id:0)
if(e.id===0){
let pirHigh=false;
if("event" in e.info && e.info.event==="toggle") pirHigh = e.info.state;
if(pirHigh===lastPIR) return;
lastPIR=pirHigh;
if(pirHigh){
logEvent("PIR → HIGH");
if(state==="BLOCKED"){ logEvent("PIR ignoriert (BLOCKED)"); return; }
if(state==="OFF"){ enterAuto(); return; }
if(state==="AUTO"
state==="WARNING"){ restartAutoTimer(); logEvent("AUTO Timer Reset"); }
}
}
// Taster S2 (id:1)
if(e.id===1){
let btnHigh=false;
if("event" in e.info && e.info.event==="toggle") btnHigh = e.info.state;
if(btnHigh===lastBTN) return;
lastBTN=btnHigh;
if(btnHigh){
logEvent("TASTER gedrückt");
if(state==="OFF"){ enterManual(); return; }
if(state==="AUTO"
state==="WARNING"
state==="MANUAL"){ enterBlocked(); return; }
}
}
});
/************** DEBUG TICK ****************************/
Timer.set(1000,true,function(){
let now=Date.now();
let a=autoOffAt?((autoOffAt-now)/1000).toFixed(1):"-";
let w=warnAt?((warnAt-now)/1000).toFixed(1):"-";
let b=blockUntil?((blockUntil-now)/1000).toFixed(1):"-";
print("[DBG] STATE:",state,"| auto:",a,"| warn:",w,"| block:",b);
});
/************** INIT **********************************/
configureHardware();
setOff();
logEvent("SYSTEM START → Licht AUS, Eingänge konfiguriert, bereit");