Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Off Topic
    4. Microcontroller
    5. Howto: Shelly Pro2 Notprogramm bei Boilersteuerung

    NEWS

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Monatsrückblick - April 2025

    Howto: Shelly Pro2 Notprogramm bei Boilersteuerung

    This topic has been deleted. Only users with topic management privileges can see it.
    • spicer
      spicer last edited by spicer

      Hallo Gemeinde

      Ich steuere die Boiler per Shelly Pro2.
      Dieses wird wiederum vom RPI mit ioBroker angesteuert.
      Hab mir nun ein Shelly Script geschrieben, welches aktiv wird, wenn 2 Tage keine Zustandsveränderung der internen Shelly-Relais stattgefunden hat.
      Das Script schaltet in diesem Fall die beiden Relais um 10:00 Uhr für 4h ein.
      Die oben fett geschriebenen Werte können im Script-Kopf angepasst werden.
      let debug = true; dient zum Einrichten. So sieht man unter "Diagnostics" mehr Log Output und die Zeiten werden auf ein paar Minuten gekürzt.

      Wenn das RPI abschmiert und ich (für längere Zeit) nicht zuhause bin (zBsp Urlaub), heizen die Boiler trotzdem auf.
      Ohne Warmwasser hätte der Mieter wohl nicht so Freude ^^

      Folgend das Script, welches direkt ins Shelly geschrieben wird.

      // Konfiguration
      
      let debug = false;   // Debug ein/aus
      let startHour = 10;  // Startzeit (Stunden) für das tägliche Einschalten
      let startMinute = 0; // Startzeit (Minuten) für das tägliche Einschalten
      let daysDelay = 2;   // Nach Tagen Relais einschalten
      let duration = 240;  // Einschaltdauer (Minuten)
      
      ////////////////////////////////////////////////////////////////////////
      
      if (debug) {
          print("Skript gestartet.");
          print("Debug Modus. Einschaltdauer auf 2 Minuten gesetzt!");
          duration = 2; // 2 Minuten für den Debug-Modus
      }
      
      duration = duration * 60 * 1000; // Umrechnung von Minuten in Millisekunden
      
      let maxNoChangeTime;
      if (!debug) {
          maxNoChangeTime = daysDelay * 24 * 60 * 60 * 1000; // Tage in Millisekunden
      } else {
          maxNoChangeTime = 60 * 1000; // 60 Sekunden in Millisekunden
      }
      
      // Variablen
      let ignoreRelayChange = false;    // Flag, um Relaisänderungen zu ignorieren
      let lastRelayChange = Date.now(); // Zeitpunkt der letzten Relais-Änderung
      let backupModeActive = false;     // Gibt an, ob der Backup-Modus aktiv ist
      let boilerOnTimer = null;         // Timer-Referenz für das automatische Ausschalten
      
      // Funktion: Boiler einschalten
      function turnOnBoilers() {
        if (ignoreRelayChange) return; // Verhindern, dass Relaisänderungen während des Einschaltens erkannt werden
        print("Schalte Boiler ein (Relais 1 und 2)");
        ignoreRelayChange = true; // Relaisänderungen bis zum Ausschalten ignorieren
        Shelly.call("Switch.Set", { id: 0, on: true }, function(response) {
          if (response.error) {
            print("Fehler beim Einschalten von Relais 1:", response.error);
          } else {
            print("Relais 1 eingeschaltet");
          }
        });
        Shelly.call("Switch.Set", { id: 1, on: true }, function(response) {
          if (response.error) {
            print("Fehler beim Einschalten von Relais 2:", response.error);
          } else {
            print("Relais 2 eingeschaltet");
          }
        });
        // Nach 2 Sekunden das Flag zurücksetzen, um Relaisänderungen zuzulassen
        Timer.set(2000, false, function() {
          ignoreRelayChange = false; // Nach 2 Sekunden dürfen Relais-Events wieder verarbeitet werden
        });
      }
      
      // Funktion: Boiler ausschalten
      function turnOffBoilers() {
        print("Schalte Boiler aus (Relais 1 und 2)");
        Shelly.call("Switch.Set", { id: 0, on: false }, function(response) {
          if (response.error) {
            print("Fehler beim Ausschalten von Relais 1:", response.error);
          } else {
            print("Relais 1 ausgeschaltet");
          }
        });
        Shelly.call("Switch.Set", { id: 1, on: false }, function(response) {
          if (response.error) {
            print("Fehler beim Ausschalten von Relais 2:", response.error);
          } else {
            print("Relais 2 ausgeschaltet");
          }
        });
      }
      
      // Funktion: Backup-Modus starten
      function startBackupMode() {
        if (!backupModeActive) {
          print("Backup-Modus aktiviert, Boiler schalten täglich für {duration} Stunden ein.");
          backupModeActive = true;
        }
      }
      
      // Funktion: Backup-Modus beenden
      function stopBackupMode() {
        if (backupModeActive) {
          print("Backup-Modus deaktiviert, Steuerung erfolgt wieder über Relais-Änderungen.");
          backupModeActive = false;
      
          // Sicherstellen, dass Boiler ausgeschaltet sind und Timer gestoppt wird
          if (boilerOnTimer) {
            Timer.clear(boilerOnTimer);
            boilerOnTimer = null;
          }
          turnOffBoilers();
        }
      }
      
      // Funktion: Überprüfen, ob eingeschaltet werden muss
      function checkAndTurnOn() {
        let now = new Date(); // Aktuelle Zeit
        let timeElapsed = Date.now() - lastRelayChange;
      
        if (debug) {
          print("Aktuelle Zeit:", now.toString());  // Debug-Ausgabe: Aktuelle Zeit
          print("Zeit seit der letzten Relais-Änderung (ms):", timeElapsed);  // Debug-Ausgabe: Zeit seit der letzten Änderung
        }
      
        if (timeElapsed > maxNoChangeTime) {
          startBackupMode();
      
          // Berechne den Zielzeitpunkt für den aktuellen Tag (Startzeit)
          let targetTimeMillis = now.getTime(); // Aktuellen Zeitpunkt in Millisekunden holen
      
          // Berechne die Zeitdifferenz bis zur Startzeit
          let targetTimeMillisAdjusted = targetTimeMillis
            - (now.getHours() * 3600000)  // Stunden in Millisekunden subtrahieren
            - (now.getMinutes() * 60000)  // Minuten in Millisekunden subtrahieren
            - (now.getSeconds() * 1000)   // Sekunden in Millisekunden subtrahieren
            - now.getMilliseconds();      // Millisekunden subtrahieren
      
          // Füge die Startzeit hinzu
          targetTimeMillisAdjusted += (startHour * 3600000) + (startMinute * 60000);
      
          if (targetTimeMillisAdjusted < now.getTime()) {
            // Falls Zielzeit in der Vergangenheit liegt, setzen wir den nächsten Tag
            targetTimeMillisAdjusted += 24 * 60 * 60 * 1000; // 24 Stunden in Millisekunden
          }
      
          // Zielzeitpunkt erstellen
          let targetDate = new Date(targetTimeMillisAdjusted);
      
          if (debug) {
            print("Zielzeitpunkt:", targetDate.toString());  // Debug-Ausgabe: Zielzeitpunkt
          }
      
          // Berechne die Zeitdifferenz
          let timeDiff = Math.abs(now.getTime() - targetDate.getTime()); // Zeitdifferenz
          if (debug) {
            print("Zeitdifferenz (Millisekunden):", timeDiff);  // Debug-Ausgabe: Zeitdifferenz
          }
      
          if (timeDiff < 60 * 1000 || debug) {  // 1-Minuten-Fenster
            print("Es ist Zeit, die Boiler einzuschalten.");
            turnOnBoilers();
      
            // Timer setzen, um die Boiler nach der Dauer auszuschalten
            if (!boilerOnTimer) {
              boilerOnTimer = Timer.set(duration, false, function () {
                print("{duration} Stunden vergangen, schalte Boiler aus.");
                turnOffBoilers();
                boilerOnTimer = null;
              });
            }
          } else {
            if (debug) {
              print("Es ist noch nicht Zeit, die Boiler einzuschalten.");  // Debug-Ausgabe, wenn es noch nicht Zeit ist
            }
          }
        } else {
          // Deaktivieren des Backup-Modus, wenn eine Relais-Änderung festgestellt wurde
          stopBackupMode();
        }
      }
      
      // Funktion: Relais-Event überwachen
      Shelly.addEventHandler(function (event) {
        // Prüfen, ob das Event von einem Relais kommt und ob wir gerade Relaisänderungen ignorieren
        if ((event.component === "switch:0" || event.component === "switch:1") && !ignoreRelayChange) {
          print("Relais-Event erkannt:", event.component);
      
          // Aktualisiere die Zeit der letzten Änderung
          lastRelayChange = new Date().getTime();
          backupModeActive = false;
          if (debug) {
            print("Relais-Status geändert, Zeit aktualisiert:", lastRelayChange);
          }
        }
      });
      
      // Timer: Überprüfe alle 3 Minuten
      Timer.set(180 * 1000, true, function () {
        checkAndTurnOn();
      });
      

      Nach dem Speichern des Scripts nicht vergessen, Run on startup einzuschalten und Status auf Play ( > klicken) zu bringen! Wenn Running! drunter steht, ist alles in Ordnung.

      Auswahl_008.png

      1 Reply Last reply Reply Quote 0
      • First post
        Last post

      Support us

      ioBroker
      Community Adapters
      Donate

      939
      Online

      31.7k
      Users

      79.7k
      Topics

      1.3m
      Posts

      1
      1
      98
      Loading More Posts
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes
      Reply
      • Reply as topic
      Log in to reply
      Community
      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
      The ioBroker Community 2014-2023
      logo