// ###########################################################
// Shelly 1PM Plus (Gen4) – folgt zwei Toren (Shelly 2PM im Cover-Modus)
// mit Sonnenstands-Sperre (nur nachts aktiv)
// ###########################################################
//
// Regeln (pro Tor geprüft, nur aktiv wenn es dunkel ist!):
// - Bei 20% öffnen -> Licht EIN
// - Bei 100% -> Licht holdTime EIN, danach AUS (nur einmal)
// - Wenn Tor von 100% auf <100% fährt (Start Schließen) -> Licht EIN
// - Bei 20% schließen -> Licht AUS
//
// ###########################################################
// IP-Adressen der beiden Shelly 2PM (Torsteuerungen)
let garageDoors = [
"192.168.178.109", // Tor 1
"192.168.178.110" // Tor 2
];
// Abfrageintervall (ms)
let interval = 5000; // alle 5 Sekunden
// Haltezeit wenn Tor komplett offen (in Sekunden)
let holdTime = 120;
// interne Zustände
let lastOn = false;
let holdTimer = null;
let holdActive = false;
let lastPos = { "192.168.178.109": null, "192.168.178.110": null };
// Sonnenauf-/untergang
let sunrise = null;
let sunset = null;
// === Hilfsfunktionen ===
function switchLight(on) {
Shelly.call("Switch.Set", { id: 0, on: on });
lastOn = on;
print("Licht", on ? "EIN" : "AUS");
}
function cancelHoldTimer() {
if (holdTimer !== null) {
Timer.clear(holdTimer);
holdTimer = null;
print("Hold-Timer abgebrochen");
}
}
function isNight() {
if (!sunrise || !sunset) return true; // wenn keine Werte -> sicherheitshalber aktiv
let now = (new Date()).getTime() / 1000; // aktuelle Zeit in UNIX Sekunden
return (now < sunrise || now > sunset);
}
function updateSunTimes() {
Shelly.call("Sys.GetStatus", {}, function(res) {
if (res && res.sunrise && res.sunset) {
sunrise = res.sunrise;
sunset = res.sunset;
print("Sonnenaufgang:", sunrise, "Sonnenuntergang:", sunset);
} else {
print("Keine Sonnenzeiten gefunden – Nacht-Check immer TRUE");
}
});
}
// === Hauptfunktion: prüft beide Tore ===
function checkCovers() {
if (!isNight()) {
// Tagsüber -> Licht sicher ausschalten und überspringen
if (lastOn) {
switchLight(false);
cancelHoldTimer();
holdActive = false;
}
print("Tag erkannt – Steuerung gesperrt");
return;
}
// Zustand pro Tor prüfen
for (let i = 0; i < garageDoors.length; i++) {
let ip = garageDoors[i];
let url = "http://" + ip + "/rpc/Cover.GetStatus?id=0";
Shelly.call("HTTP.GET", { url: url }, function(res) {
if (!res || res.code !== 200) {
print("HTTP Fehler an Tor", ip, ":", res ? res.code : "kein Ergebnis");
return;
}
try {
let data = JSON.parse(res.body);
let pos = data.current_pos;
if (typeof pos === "string") pos = parseFloat(pos);
print("Tor", ip, "Position:", pos, "%", "(last:", lastPos[ip], ")");
// --- Regel 2: Bei 100% -> Licht holdTime EIN, danach AUS (nur einmal)
if (pos >= 100) {
if (!holdActive) {
holdActive = true;
if (!lastOn) {
switchLight(true);
print("Licht EIN (Tor", ip, "100%, Timer gestartet)");
}
cancelHoldTimer();
holdTimer = Timer.set(holdTime * 1000, false, function() {
switchLight(false);
print("Licht AUS (Timer abgelaufen bei 100%)");
});
}
lastPos[ip] = pos;
return;
}
// --- Regel 3: Start Schließen von 100% -> Licht EIN
if (lastPos[ip] !== null && lastPos[ip] >= 100 && pos < 100) {
if (!lastOn) {
switchLight(true);
print("Licht EIN (Start Schließen Tor", ip, ")");
}
holdActive = false;
cancelHoldTimer();
}
// --- Regel 1: Bei 20% öffnen -> Crossing von <20% auf >=20%
if (lastPos[ip] !== null && lastPos[ip] < 20 && pos >= 20) {
if (!lastOn) {
switchLight(true);
print("Licht EIN (Tor", ip, "öffnet über 20%)");
}
}
// --- Regel 4: Bei 20% schließen -> Crossing von >20% auf <=20%
if (lastPos[ip] !== null && lastPos[ip] > 20 && pos <= 20) {
// prüfe, ob beide Tore <= 20 sind → erst dann aus
let allClosed = true;
for (let j = 0; j < garageDoors.length; j++) {
if (garageDoors[j] !== ip && lastPos[garageDoors[j]] !== null && lastPos[garageDoors[j]] > 20) {
allClosed = false;
break;
}
}
if (allClosed && lastOn) {
switchLight(false);
print("Licht AUS (beide Tore geschlossen, letzter war", ip, ")");
}
holdActive = false;
cancelHoldTimer();
}
lastPos[ip] = pos;
} catch (e) {
print("Parsing Fehler an Tor", ip, ":", e);
}
});
}
}
// === Timer starten ===
Timer.set(interval, true, checkCovers);
// Sonnenauf-/untergang alle 10 min aktualisieren
updateSunTimes();
Timer.set(600000, true, updateSunTimes);
Alles anzeigen
So hier mal eine erweiterte Licht Steuerung für einen Shelly 1 pm gen 4 der das Licht schaltet und auf 2 x 2 pm im Rolltormodus horcht, das heißt ein Tor offen und das andere öffnet sich ebenfalls, bleibt das Licht 120 Sekunden an, erst wenn beide geschlossen sind, geht auch das Licht aus.
Entweder nach den 120 sek bei einem Offen eins geschlossen oder beide geschlossen sofort wieder aus.
Ihr müsst das Skript auf den 1 pm kopieren und die ip der Rolltore eben anpassen viel Spass damit.
*****************************ACHTUNG********ACHTUNG********************ACHTUNG**************ACHTUNG************************************************
Ich weise Ausdrücklich darauf hin das programierungen mit Skripten funktionieren können, und nicht müssen, hier ist jeder selbst dafür verantwortlich und muss auch alle Sicherheitsregeln beachten alle meine Angaben sind somit ohne Gewähr und Rechtlichkeit verbunden.