Jump to content
🌟 NEW Shelly Products Reveal Video! 🌟 NEUE Shelly-Produkte-Enthüllungsvideo! 🌟 ×
NOTICE / HINWEIS: iOS 18 Update and Today Widgets ×

Skriptänderung killt Shelly


Recommended Posts

Unter bestimmten Bedingungen können Skriptänderungen bzw. Fehler im Skript das Gerät unbrauchbar machen. Nach einem Neustart kann das Gerät nicht mehr gefunden werden, selbst nach einem manuellen Reset nicht. Eine rote LED blinkt, was beim Mini sichtbar ist. Der Fehler war reproduzierbar, und zwei Geräte wurden durch dieselbe Aktion zerstört. Kennt jemand dieses Problem?

Link to comment
Share on other sites

Posted (edited)
1 hour ago, Olsche said:

Es wäre hilfreich zu wissen um welches Script es sich handelt bzw welche Änderungen vorgenommen wurden um es selbst reproduzieren zu können. Gerne auch per PM

Ich habe eine E-Mail gesendet, die das Skript enthält. Ich kann es gerne hier erneut posten. Allerdings könnte das Problem auch damit zusammenhängen, dass es ein weiteres Shelly-Gerät gibt, das ebenfalls als Access Point und Extender konfiguriert war. Der Ausfall des Shellys trat jeweils unter denselben Bedingungen auf. Shelly2 war aktiv, und im Skript wurde nur der Teil auskommentiert, der den Access Point und den Extender betrifft. Vorher haben beide Geräte einwandfrei funktioniert.

// Läuft mit Shelly Softwareupdate 1.4.2
// Globale Variablen und Voreinstellungen
// Steuerung für die Umwälzpumpe der Poolheizung
// Dient dazu, dass die Pumpe regelmäßig kurz läuft, damit sich die Lager nicht festfressen
// und dass unter der eingestellten Außentemperatur der Kreislauf läuft, damit die Leitungen nicht einfrieren.
// Zusätzlich wird der Zustand des Relais abgefagt das zwischen Speicher und Pool den Kreislauf umschaltet.
// Steht der Keislauf auf Pool so wird auch die Poolpumpe eingeschaltet.
// Dieser Code läft auf dem 2. Shelly ohne Addon Modul mit der IP 192.168.0.17
// Die Grundkonfiguration wie Netzwerkeinstellung der beiden Shellys muss vorher über die Weboberfläche des jeweiligen Shellys erfolgen.
// Shwitch des Shellys mit adresse 192.168.0.17 muss auf ditacheed gesttellt werden. 
let schaltTemperatur = 4; // Temperaturschwelle für die Umwälzpumpe, unter dieser Schwelle wird umgewälzt
let dutyCycleHighinSecunds = 10; // Dauer, für die die Umwälzpumpe eingeschaltet bleibt (in Sekunden)
let dutyCycleLowinMinutes = 60;  // Dauer, für die die Umwälzpumpe ausgeschaltet bleibt (in Minuten)
// Ab hier nichts verändern
let dutyCycleHigh = dutyCycleHighinSecunds * 1000; // Dauer, (in Millisekunden)
let dutyCycleLow = dutyCycleLowinMinutes * 60000;  // Dauer, (in Millisekunden)
let IntervallOutputFlag = false; // Globales Bit für das Intervallsteuerung (true = eingeschaltet, false = ausgeschaltet)
let lastCycleEndTime = 0; // Zeitstempel des Endes des letzten Zyklus
let aussentemp = null; // Globale Variable für die Außentemperatur
let TempOutputFlag = false; // Globales Bit für den Relaiszustand (true = eingeschaltet, false = ausgeschaltet)
let switch_status = false; // Globale Variable für den Schalterstatus (Standardwert auf false gesetzt)
// Globale Variable für die gewünschte IP-Adresse shelly 2
const DESIRED_IP = "192.168.0.17";

// Funktion, um den Status des Schalters abzurufen
function getSwitchStatus(callback) {
  Shelly.call("HTTP.GET",{url: "http://192.168.0.18/rpc/Switch.GetStatus?id=0",},
    function(result) {
      try {
        let response = JSON.parse(result.body);
        callback(response);
      } catch (e) {
        print("Fehler beim Parsen der Antwort:", e.message);
        callback(null);
      }
    }
  );
}
// Funktion zum Aktualisieren des Schalterstatus
function updateSwitchStatus() {
  getSwitchStatus(function(status) {
    if (status !== null) {
      switch_status = status.output;
      //print("Poolpumpenkreislauf:", switch_status ? "Eingeschaltet" : "Ausgeschaltet");
    } else {
      print("Fehler beim Abrufen des Schalterstatus.");
    }
  });
}
// Funktion, um den Status des Temperatursensors abzurufen
function getTemperatureStatus(callback) {
  Shelly.call("HTTP.GET",{url: "http://192.168.0.18/rpc/Temperature.GetStatus?id=101",},
    function(result) {
      try {
        let response = JSON.parse(result.body);
        callback(response);
      } catch (e) {
        print("Fehler beim Parsen der Antwort:", e.message);
        callback(null);
      }
    }
  );
}
// Funktion zur Steuerung des Relais basierend auf der Temperatur
function temperatursteuerung() {
  getTemperatureStatus(function(temperature_status) {
    if (temperature_status !== null) {
      aussentemp = temperature_status.tC;
      print("Aktuelle Temperatur:", aussentemp, "°C", "Temperaturschwelle:", schaltTemperatur, "°C");
      TempOutputFlag = aussentemp < schaltTemperatur;
    } else {
      print("Fehler beim Abrufen des Temperaturstatus.");
    }
  });
}
// Funktion zur Steuerung des Relais basierend auf dem Intervall
function intervalControl() {
  let currentTime = Date.now();
  let cycleTime = currentTime - lastCycleEndTime;

  if (!TempOutputFlag) {
    print("Relais-Einschaltdauer:", dutyCycleHigh / 1000, "Sekunden");
    print("Relais-Ausschaltdauer:", dutyCycleLow / 60000, "Minuten");
    print("Derzeitiger Zeitstempel:", Math.floor(cycleTime / 60000), "Minuten und", Math.floor((cycleTime % 60000) / 1000), "Sekunden");
  }
  // Überprüfe, ob das Relais ein- oder ausgeschaltet werden muss
  if (cycleTime <= dutyCycleHigh) {
    // Relais einschalten, wenn die Zeit seit der letzten Aktivierung kleiner oder gleich der Einschaltdauer ist
    IntervallOutputFlag = true;
  } else if (cycleTime > dutyCycleHigh && cycleTime <= (dutyCycleHigh + dutyCycleLow)) {
    // Relais ausschalten, wenn die Zeit seit der letzten Aktivierung größer als die Einschaltdauer, aber kleiner oder gleich der gesamten Zyklussdauer ist
    IntervallOutputFlag = false;
  } else if (cycleTime > (dutyCycleHigh + dutyCycleLow)) {
    // Wenn die gesamte Zyklusdauer abgelaufen ist, aktualisiere den Zeitstempel des Endes des Zyklus
    lastCycleEndTime = currentTime;
  }
}
// Funktion zur Steuerung des Relais
function setRelayState(state) {
  Shelly.call("Switch.Set", { id: 0, on: state }, function(result, error_code, error_message) {
    if (error_code !== 0) {
      print("Fehler beim Schalten des Relais:", error_message);
    } else {
      print("Poolumwälzpumpenrelais:", state ? "Eingeschaltet" : "Ausgeschaltet");
    }
  });
}
// Setze den lokalen Eingang auf "detached"
function setDetachedMode() {
  Shelly.call("Switch.SetConfig", { id: 0, config: { input_mode: "detached" } }, function(result, error_code, error_message) {
    if (error_code !== 0) {
      print("Fehler beim Setzen des Detached-Modus:", error_message);
    } else {
      print("Lokaler Eingang auf Detached-Modus gesetzt.");
    }
  });
}
// Funktion zur automatischen Setzung der IP-Adresse
function setStaticIP(callback) {
  let ipConfig = {
    "config": {
      "sta": {
        "ipv4mode": "static",
        "ip": DESIRED_IP, // Globale IP-Adresse
        "netmask": "255.255.255.0",
        "gw": "192.168.0.1"
      }
    }
  };

  Shelly.call("Wifi.SetConfig", ipConfig, function(result, error_code, error_message) {
    if (error_code !== 0) {
      print("Fehler beim Setzen der IP-Adresse:", error_message);
      callback(false); // Rückmeldung im Fehlerfall
    } else {
      print("IP-Adresse erfolgreich gesetzt.");
      callback(true); // Erfolgreiche Rückmeldung
    }
  });
}

// Funktion zum Abrufen des WiFi-Status
function getWiFiStatus(callback) {
  Shelly.call("Wifi.GetStatus", {}, function(result, error_code, error_message) {
    if (error_code !== 0) {
      print("Fehler beim Abrufen des WiFi-Status:", error_message);
      callback(null); // Fehler, Rückgabe null
    } else {
      print("WiFi-Status-Rohdaten:", JSON.stringify(result));
      callback(result); // Erfolgreiche Rückgabe des Rohdaten-Status
    }
  });
}

// Funktion zur Konfiguration des WLANs und Access Points
function configureWiFiAndAP(callback) {
  Shelly.call("Wifi.GetConfig", {}, function(result, error_code, error_message) {
    if (error_code !== 0) {
      print("Fehler beim Abrufen der WiFi-Konfiguration:", error_message);
      callback(false); // Rückmeldung im Fehlerfall
      return;
    }

    if (!result || !result.ap) {
      print("Die Antwort enthält keine gültige Access Point-Konfiguration.");
      callback(false); // Fehlercode für ungültige Antwort
      return;
    }

    let apConfig = result.ap;
    let apNeedsRestart = !(apConfig && apConfig.enable); // Überprüfen, ob der AP aktiviert ist

    let wifiConfig = {
      "config": {
        "sta": {
          "ssid": "JP-sen-2G",
          "pass": "xxx",
          "enable": true,
          "ipv4mode": "static",
          "ip": DESIRED_IP,
          "netmask": "255.255.255.0",
          "gw": "192.168.0.1",
          "nameserver": "8.8.8.8",
          "is_open": false
        },
        "sta1": {
          "ssid": "W900J",
          "pass": "xxx",
          "enable": true,
          "ipv4mode": "static",
          "ip": DESIRED_IP,
          "netmask": "255.255.255.0",
          "gw": "192.168.0.1",
          "nameserver": "8.8.8.8",
          "is_open": false
        }//,
		//"ap": { Nach dem Asukommentieren dieses Teils erfolgte der Absturz
        //  "enable": true,
        //  "pass": "xxx",
        //  "is_open": false
        //},
        //"range_extender": {
        //  "enable": true
        //}
       }
    };

    Shelly.call("Wifi.SetConfig", wifiConfig, function(result, error_code, error_message) {
      if (error_code !== 0) {
        print("Fehler beim Setzen der WiFi-Konfiguration:", error_message);
        callback(false); // Rückmeldung im Fehlerfall
        return;
      }

      print("WiFi-Konfiguration erfolgreich gesetzt.");

      if (apNeedsRestart) {
        Shelly.call("Shelly.Reboot", { "delay_ms": 1000 }, function(result, error_code, error_message) {
          if (error_code !== 0) {
            print("Fehler beim Neustarten des Geräts:", error_message);
            callback(false); // Rückmeldung im Fehlerfall
          } else {
            print("Gerät wird neu gestartet in 1000 ms.");
            callback(true); // Erfolgreiche Rückmeldung
          }
        });
      } else {
        // Keine Notwendigkeit zum Neustarten, aber Überprüfung der Konfiguration
        Shelly.call("Wifi.GetConfig", {}, function(result, error_code, error_message) {
          if (error_code !== 0) {
            print("Fehler beim Abrufen der aktualisierten WiFi-Konfiguration:", error_message);
            callback(false); // Rückmeldung im Fehlerfall
          } else {
            let updatedApConfig = result.ap;
            if (updatedApConfig && updatedApConfig.enable) {
              print("Access Point wurde erfolgreich aktiviert.");
              callback(true); // Erfolgreiche Rückmeldung
            } else {
              print("Access Point konnte nicht aktiviert werden.");
              callback(false); // Rückmeldung im Fehlerfall
            }
          }
        });
      }
    });
  });
}

// Initialisierung
function init_Wlan() {
  print("Initialisierung gestartet.");
  configureWiFiAndAP(function(status) {
    if (status) { // WLAN-Konfiguration erfolgreich
      getWiFiStatus(function(status) {
        if (status !== null && status.sta_ip) {
          print("Gerät ist mit der IP-Adresse verbunden:", status.sta_ip);
          if (status.sta_ip !== DESIRED_IP) {
            setStaticIP(function(success) {
              if (success) {
                print("Statische IP-Adresse erfolgreich gesetzt.");
              } else {
                print("Fehler beim Setzen der statischen IP-Adresse.");
              }
            });
          } else {
            print("Die IP-Adresse ist bereits korrekt:", DESIRED_IP);
          }
        } else {
          print("Gerät ist nicht verbunden oder keine IP-Adresse erhalten.");
        }
      });
    } else {
      print("WLAN-Konfiguration fehlgeschlagen.");
    }
  });
}

// Funktion zur regelmäßigen Überprüfung der Intervallsteuerung
function startControl() {
	init_Wlan();
	setDetachedMode(); // Setze den lokalen Eingang auf "detached" einmal beim Start
  // Setze eine Funktion zur regelmäßigen Überprüfung alle 10 Sekunden
  Timer.set(6000, true, function() {
    updateSwitchStatus(); // Lese den Schalterstatus des Relais das den Solarkreislauf von Speicher auf Pool steuerert 
    intervalControl(); // Intervallsteuerung für Poolkreislauf Umwälzpumpe
    temperatursteuerung(); // Wintertemperatur überwachung für Poolkreislauf Umwälzpumpe
    //print("Poolpumpenkreislauf:", switch_status ? "Eingeschaltet" : "Ausgeschaltet");
    print("Der Kreislauf wurde", switch_status ? "auf die Poolheizung" : "auf den Speicher", "umgeschaltet");
    print("Aktuell wird ", TempOutputFlag ? "Eingeschaltet wiel die Ausentemperatur unter der Schwell liegt." : "die Temeraturüberwachug nicht aktiv");
    print("Aktueller Intervallzustand:", IntervallOutputFlag ? "Eingeschaltet" : "Ausgeschaltet");
    setRelayState(IntervallOutputFlag || TempOutputFlag || switch_status); // Aktualisiere den gewünschten Relaiszustand basierend auf den Flags
  });
}
// Starte Schleife
startControl();

 

Edited by johann.pascher
Link to comment
Share on other sites

  • Shelly

hab ich es richtig verstanden, dass die Shellys unrettbar sind und auch nicht via Factory reset wiederbelebar sind?

Das Problem besteht erst nach Auskommentieren der Zeilen, ohne Auskommentieren läuft der Skript?:

}//,
		//"ap": { Nach dem Asukommentieren dieses Teils erfolgte der Absturz
        //  "enable": true,
        //  "pass": "xxx",
        //  "is_open": false
        //},
        //"range_extender": {
        //  "enable": true
        //}
       
Link to comment
Share on other sites

  • Members
Posted (edited)

Sorry, das war nicht so. Ein Forennutzer des „alten“ Forums (OSTFRIESE?) hatte die Gefahr der „tödlichen“ Script entdeckt. Die 500ms sind genauso aus diesem Grund eingebaut worden. Und ja: Man kann das schaffen: Mit einem vorbereiteten Webhook lässt sich das Script in dieser Zeit deaktivieren.

Siehe hier:

https://www.smarthome-forum.eu/thread/25700-shelly-virus-für-gen2-3/?postID=269786#post269786

Edited by thgoebel
Link to comment
Share on other sites

11 minutes ago, thgoebel said:

Sorry, das war nicht so. Ein Forennutzer des „alten“ Forums (OSTFRIESE?) hatte die Gefahr der „tödlichen“ Script entdeckt.

Thx, gut zu wissen.

Das interpretiere ich so: Skript startet verzögert, damit der Shelly ready ist und man einen Werksreset machen kann, bevor ein Skript Amok läuft und die CPU "überlastet" ?

Sofern Johann

Quote

selbst nach einem manuellen Reset nicht

den Werksreset meint, scheint das hier nicht geholfen zu haben.

Edited by tvbshelly
Link to comment
Share on other sites

2 hours ago, Olsche said:

hab ich es richtig verstanden, dass die Shellys unrettbar sind und auch nicht via Factory reset wiederbelebar sind?

Das Problem besteht erst nach Auskommentieren der Zeilen, ohne Auskommentieren läuft der Skript?:

}//,
		//"ap": { Nach dem Asukommentieren dieses Teils erfolgte der Absturz
        //  "enable": true,
        //  "pass": "xxx",
        //  "is_open": false
        //},
        //"range_extender": {
        //  "enable": true
        //}
       

Ja richtig verstanden.

Link to comment
Share on other sites

Man könnte versuchen, in schneller Folge einfach per Shellskript oder externem Programm folgendes auf den Shelly zu feuern während er startet:

http://192.168.33.1/rpc/Script.Delete?id=1

Die id müsste man raten, aber so viele gibt es da ja auch nicht.

Alternativ

http://192.168.33.1/rpc/Script.SetConfig?id=1&config={"enable":false}

Ob sowas klappt, steht natürlich in den Sternen.

Edited by tvbshelly
Link to comment
Share on other sites

1 hour ago, thgoebel said:

Sorry, das war nicht so. Ein Forennutzer des „alten“ Forums (OSTFRIESE?) hatte die Gefahr der „tödlichen“ Script entdeckt. Die 500ms sind genauso aus diesem Grund eingebaut worden. Und ja: Man kann das schaffen: Mit einem vorbereiteten Webhook lässt sich das Script in dieser Zeit deaktivieren.

Siehe hier:

https://www.smarthome-forum.eu/thread/25700-shelly-virus-für-gen2-3/?postID=269786#post269786

Ich hatte dieses Problem bereits vor einigen Jahren bei einem anderen Skript und habe damals lange mit mehreren Entwicklern darüber geschrieben sowie Tickets eröffnet. Diese wurden jedoch immer wieder als erledigt geschlossen, obwohl das Problem offensichtlich nicht behoben war.

Link to comment
Share on other sites

6 minutes ago, tvbshelly said:

Man könnte versuchen, in schneller Folge einfach per Shellskript oder externem Programm folgendes auf den Shelly zu feuern während er startet:

http://192.168.33.1/rpc/Script.Delete?id=1

Die id müsste man raten, aber so viele gibt es da ja auch nicht.

Alternativ

http://192.168.33.1/rpc/Script.SetConfig?id=1&config={"enable":false}

Ob sowas klappt, steht natürlich in den Sternen.

Das funktioniert natürlich nicht, weil man, selbst wenn man den Netzwerkverkehr mit Wireshark überwacht, keinerlei Kommunikation mit dem Router sieht. Das Gerät ist tatsächlich komplett tot und startet keinerlei Netzwerkaktivitäten. Es könnte zwar theoretisch vorkommen, dass es entweder mit der Standard-IP oder einer automatisch zugewiesenen IP hochfährt, aber das kann in diesem Fall definitiv ausgeschlossen werden.

Link to comment
Share on other sites

1 hour ago, tvbshelly said:

Thx, gut zu wissen.

Das interpretiere ich so: Skript startet verzögert, damit der Shelly ready ist und man einen Werksreset machen kann, bevor ein Skript Amok läuft und die CPU "überlastet" ?

Sofern Johann

den Werksreset meint, scheint das hier nicht geholfen zu haben.

Manueller Werksreset per Taste 10 sekunde. 

Link to comment
Share on other sites

4 minutes ago, johann.pascher said:

Das funktioniert natürlich nicht, weil man, selbst wenn man den Netzwerkverkehr mit Wireshark überwacht, keinerlei Kommunikation mit dem Router sieht.

Das ist dann echt doof. Klar, ohne Verbindung geht nix.

Mir kommen diese 500ms einfach zu kurz vor, wie ich vorhin auch schon geschrieben habe.

14 minutes ago, johann.pascher said:

Ich hatte dieses Problem bereits vor einigen Jahren bei einem anderen Skript und habe damals lange mit mehreren Entwicklern darüber geschrieben sowie Tickets eröffnet. Diese wurden jedoch immer wieder als erledigt geschlossen, obwohl das Problem offensichtlich nicht behoben war.

Ein leider gängiges Problem, nicht nur bei diesem Hersteller.

Link to comment
Share on other sites

  • Members

Wenn man den oben verlinkten Thread im „anderen Forum“ liest, erkennt man, daß ein wegen Scriptschleife „toter“ Shelly durchaus gerettet werden kann, wenn Firmware größer 1.3.0 installiert ist. Alternativ flashe ich den Shelly neu (auch das kann man dort lesen)…

Link to comment
Share on other sites

Funktioniert bei den Gen2/3 Shellys eigentlich noch der alte Bootloader Trick der Gen1 Geräte mit 7 mal an/aus?

Sprich 30 Sekunden Strom weg. Strom an und dann im Wechsel an/aus sechs Mal mit Intervallen von weniger als 10 Sekunden. Beim siebten Mal laufen lassen.

Bei Gen1 wurde damit meine ich die Wiederherstellung aktiviert

Link to comment
Share on other sites

12 minutes ago, tvbshelly said:

Das ist dann echt doof. Klar, ohne Verbindung geht nix.

Mir kommen diese 500ms einfach zu kurz vor, wie ich vorhin auch schon geschrieben habe.

 

Die Meldung 'Gerät wird neu gestartet in 1000 ms.' reicht vollkommen aus, um den Kommentar im Log zu sehen. Das Problem ist nur, dass der Absturz vor der Reboot-Anweisung mit Verzögerung erfolgt, sodass man auf der Konsole keine Fehlermeldung sieht. Das eigentliche Problem liegt bei den Entwicklern, die die Abstürze nicht abfangen. Ich vermute sogar, dass dabei das System irgendwie überschrieben wird und danach gar nicht mehr hochfährt. Die Entwickler sollten wissen, wofür die rote LED gedacht ist, denn diese blinkt normalerweise nicht, sondern erst, wenn das Gerät tatsächlich ausgefallen ist.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Erstelle neue...