Beiträge von towiat

VPN/Proxy erkannt

Es scheint, dass Sie einen VPN- oder Proxy-Dienst verwenden. Bitte beachten Sie, dass die Nutzung eines solchen Dienstes die Funktionalität dieser Webseite einschränken kann.

    Unter der Annahme, dass du mit Timer.set() arbeitest:

    intern nutzen die shellys zur zeitbasierten Ausführung einen cron deamon.

    Für Timer stimmt das nicht - die arbeiten mit der Uptime des Gerätes. Das geht auch implizit aus der Dokumentation der (in FW 1.5.x neuen) Timer.getInfo() Methode hervor:

    Der Inhalt kann nicht angezeigt werden, da Sie keine Berechtigung haben, diesen Inhalt zu sehen.

    Das macht ja auch Sinn, weil Timer damit auch auf Geräten funktionieren, die mangels Internetzugang keine Zeitsynchronisation durchführen können.

    Meine Vermutung ist, dass die interne Uhr des Shellys zu schnell läuft und daher ein Drift zwischen Uptime und Realzeit auftritt. Das könntest du überprüfen, indem du z. B. die Differenz in der Uptime innerhalb von exakt 24 Stunden misst.

    Wenn diese Vermutung zutrifft, wäre die Lösung - wie von thgoebel vorgeschlagen - ein Schedule, weil der natürlich an der Systemzeit hängt.

    Hallo Coloschni ,

    Eine Berechnung nach dem Durchschnittspreis wird vom Script nicht unterstützt.

    Du könntest ein ähnliches Resultat erzielen, indem du das Script so aufsetzt, dass es nur die zwölf günstigsten Stunden des Tages schaltet:

    JavaScript
    let switchOnDuration = 12; // minimum 1, maximum 24
    let timeWindowStartHour = 0; // minimum 0, maximum 23
    let timeWindowEndHour = 0; // minimum 0, maximum 23
    let blockMode = false; // set calculation mode
    let priceLimit = Infinity; // in cent/kWh

    Das liefert natürlich andere Resultate als eine Durchschnittspreisberechnung, bei der die Anzahl der geschalteten Stunden abhängig von der Preisstruktur des Tages schwanken würde - aber vielleicht reicht es ja für deine Zwecke.

    Es kann passieren, dass ein Script die Shelly-CPU derartig auslastet, dass sie nicht mehr antworten kann. Das könnte z. B. durch eine Endlosschleife im Script ausgelöst werden (die hier offensichtlich nicht vorliegt). Und wenn das Script auf Autostart steht, geht es nach einem Reboot sofort wieder los.

    Keine Ahnung warum der Shelly bei diesem Script so rumzickt, aber um ihn wieder ansprechbar zu machen könntest du versuchen, das Script mittels RPC zu stoppen.

    Dazu müsstest du den RPC http://192.168.1.126/rpc/Script.Stop?id=1 (unter der Annahme, dass das Script die ID 1 hat) via Browser/curl/iwr so oft aufrufen, bis er durchkommt - das kann durchaus ein paar Versuche benötigen...

    Um einen Schedule auf demselben Gerät anzulegen, würde ich übrigens nicht über HTTP.GET gehen, sondern den RPC direkt aufrufen - das würde dann so aussehen:

    JavaScript
    Shelly.call("Schedule.Create", {
     enable: true,
     timespec: "0 16 3 * * 0",
     calls: [{ method: "Cover.Open", params: { id: 0 } }],
    });

    The property for the content type in the HTTP.POST RPC is named content_type, not Content-Type - this could already be the solution for this:

    JavaScript
    let parms = {
          "url": "http://<INTERNAL_IP>/php/controls.php",
          "content_type":"application/x-www-form-urlencoded",
          "body": body
        };

    Du kannst keine Werte aus dem Shelly.call ins Hauptprogramm zurückgeben. Du kannst allerdings die Variablen im Hauptprogramm anlegen und sie dann aus dem Shelly.call heraus updaten:

    In vielen Fällen ist das allerdings nicht das, was du willst.

    Die Frage ist: soll direkt nach der Abfrage der Werte eine Aktion mit diesen Werten ausgeführt werden?

    Wenn die Antwort darauf "ja" ist, solltest du die entsprechende Logik direkt in der Funktion ausführen und nicht im Hauptteil des Scriptes. Wenn du beschreibst, was du nach der Abfrage der Werte machen willst, können wir das noch genauer diskutieren.

    Du könntest dem Benutzer einen Link geben, der die Autorisierung mit der URL in der Form http://admin:password@x.x.x.x/script/x/Dauerbetrieb mitschickt - damit wäre das Passwort natürlich dem Benutzer gegenüber exponiert.

    Ansonsten fiele mir nur ein Zwischenschritt ein - z. B. ein minimaler Webserver, der das HTML ausliefert und im Hintergrund dann den autorisierten Aufruf an den Shelly schickt...

    Grundsätzlich sollte das funktionieren - Fehler -104 ist ein Timeout und deutet stark darauf hin, dass die IP-Adresse nicht korrekt ist.

    Es ist aber generell keine gute Praxis, das eigene Gerät über seine Netzwerkadresse abzufragen. Es gibt zwei Möglichkeiten, wie du das anders lösen kannst:

    1. Könntest du einfach die IP-Adresse 127.0.0.1 verwenden - das ist die Loopbackadresse, die immer auf das eigene Gerät verweist:

    JavaScript
    Shelly.call(
     "HTTP.GET",
     {
       url: "http://127.0.0.1/rpc/Shelly.GetStatus",
     },
     function (result, error) {
       print(result);
       print(error);
     },
    );

    2. Könntest du GetStatus direkt und ohne Umweg über HTTP.GET aufrufen:

    JavaScript
    Shelly.call("Shelly.GetStatus", {}, function (result, error) {
     print(result);
     print(error);
    });

    Diese Variante hätte den Vorteil, dass in result schon ein fertiges JSON-Objekt steckt und du nicht JSON.Parse() verwenden musst, um die Antwort in ein JSON zu konvertieren.

    Beide Möglichkeiten sollten dich ans Ziel bringen...

    Spotelly 2.0: Tester gesucht

    Nachdem das Script offensichtlich einen kleinen, aber feinen Nutzerkreis gefunden hat, habe ich nun eine neue Version mit einigen zusätzlichen Features erstellt. Aufgrund einiger Limitationen in der Ursprungsversion musste ich dazu im Code kräftig umrühren und einige strukturelle Änderungen vornehmen.

    Die neue Version läuft in meinen Tests klaglos, aber angesichts der doch signifikanten Änderungen wäre es schön, wenn sich ein paar Mutige finden würden, die das Script vor der "offiziellen" Freigabe installieren und mir Feedback über eventuelle Probleme geben.

    Wie man an die Vorabversion kommt, beschreibe ich am Ende - vorher noch eine Übersicht über die Änderungen zwischen Version 1.2 und 2.0:

    Geändert: API

    Anstelle des Awatter APIs wird nun das API von http://energy-charts.info verwendet. Dieses API wird vom Fraunhofer-Institut für Solare Energiesysteme (ISE) bereitgestellt und hat den Vorteil, dass es Preisdaten für das gesamte Marktgebiet der Strombörse EPEX anbietet (und das Script somit nicht mehr nur in Deutschland und Österreich verwendbar ist).

    Die Konfigurationsvariable awattarCountry wurde durch epexBZN (für Bidding Zone) ersetzt. Die EPEX unterteilt ihr Marktgebiet in Marktzonen, die nicht unbedingt mit den Landesgrenzen übereinstimmen müssen. Jede Zone wird durch einen Code identifiziert, der der in der Dokumentation verlinkten Tabelle entnommen werden kann.

    Deutsche Benutzer müssen in diese Variable den Wert DE-LU eintragen (weil Deutschland und Luxemburg eine gemeinsame Marktzone betreiben). Für österreichische Benutzer lautet der Code AT (Großschreibung ist in beiden Fällen wichtig!).

    Geändert: Abruflogik und Fehlertoleranz

    In der Vorversion war es notwendig, den Abrufzeitpunkt für die Preisdaten in einer Variable festzulegen. Diese Variable existiert nun nicht mehr - das Script führt den Preisabruf selbsttätig ab ca. 15:00 Uhr durch (der genaue Zeitpunkt ist leicht zufallsgesteuert, um die Last für den API-Server etwas zu verteilen).

    Sollte der API-Aufruf scheitern (weil die Tagespreise noch nicht im API-Server eingepflegt wurden oder auch aufgrund von Netzwerkproblemen etc.), startet das Script in Abständen von 20 Minuten so lange neue Versuche, bis die Daten erfolgreich abgerufen werden konnten. Normalerweise stehen die Preise irgendwann zwischen 15:00 und 17:00 zur Verfügung.

    Neu: nonBlockMode

    Über die neue Konfigurationsvariable blockMode kann nun zwischen zwei Betriebsmodi gewählt werden:

    Steht blockMode auf true (die Grundeinstellung), bleibt alles wie bisher - das Script identifiziert innerhalb des vorgegebenen Zeitfensters den zusammenhängenden Block von x Stunden mit dem niedrigsten Durchschnittspreis und aktiviert die Stromzufuhr für diesen Block.

    Wenn blockMode auf false gestellt wird, werden die x günstigsten Stunden im definierten Zeitfenster aktiviert - unabhängig davon, ob diese Stunden aufeinander folgen oder nicht.

    In beiden Modi wird für jede einzelne Stunde ein Check gegen das (optionale) Preislimit ausgeführt - sollte der Preis das Limit überschreiten, unterbleibt der Einschaltvorgang für die jeweilige Stunde.

    Entfernt: KVS-Eintrag

    Bisher hat das Script die berechneten Schaltzeiten über einen KVS-Eintrag kommuniziert. Für den neuen nonBlockMode ist das aufgrund der größeren Anzahl von Schaltaktionen nicht mehr praktikabel - ich habe daher die KVS-Logik entfernt und an dessen Stelle über einen HTTP-Endpunkt eine Infoseite implementiert - siehe den nächsten Punkt.

    Neu: HTTP-Endpunkt

    Das Script bietet nun einen HTTP-Endpunkt, der mit mit der URL http://<ipDesShelly>/script/<script_id>/spotelly aufgerufen werden kann. Gibt man obige URL im Browser ein, erhält man eine tabellarische Übersicht der berechneten Schaltzeiten samt den zugehörigen Preisen:

    Der Inhalt kann nicht angezeigt werden, da Sie keine Berechtigung haben, diesen Inhalt zu sehen.

    Neu: priceModifier

    In der Grundeinstellung zeigt das Script die EPEX-Großhandelspreise an. Das sind aber üblicherweise nicht die Preise, die an den Stromlieferanten zu bezahlen sind - viele Anbieter verrechnen einen Aufschlag auf den Marktpreis und dazu kommt natürlich noch die Umsatzsteuer und vielleicht noch andere Abgaben oder Gebühren.

    In der Funktion priceModifier kann eine Formel hinterlegt werden, mit der der Marktpreis auf den tatsächlich zu bezahlenden Preis umgerechnet wird (und der so modifizierte Preis wird dann auch im HTTP-Endpunkt angezeigt).

    Beispiel: Ein österreichischer Anbieter verrechnet den EPEX-Spotpreis zuzüglich eines Aufschlages von netto 1.3 cent/kWh und auf diesen Betrag kommt dann noch die landesübliche Umsatzsteuer von 20 %. Diese Kalkulation würde man in der priceModifier Funktion so abbilden:

    JavaScript
    function priceModifier(spotPrice) {
      return (spotPrice + 1.3) * 1.2;
    }

    Neu: switchID

    Über die Konfigurationsvariable switchID kann bei Multi-Switch Geräten festgelegt werden, welcher Switch vom Script gesteuert werden soll. Jede Script-Instanz kann nur einen einzigen Switch verwalten.


    Das waren die Änderungen - um auf die neue Version zuzugreifen, muss im Github-Repository auf die dev Branch umgestellt werden:

    Der Inhalt kann nicht angezeigt werden, da Sie keine Berechtigung haben, diesen Inhalt zu sehen.

    Nach Bestätigung dieser Auswahl sieht man die neue Version inklusive der überarbeiteten Dokumentation (es schadet wahrscheinlich nicht, diese Dokumentation einmal komplett durchzulesen ;)).

    Und hier ist noch einmal der Link auf das Repository:

    https://github.com/towiat/spotelly

    Für Fragen, Probleme, Wünsche und auch sonst alles stehe ich wie immer zur Verfügung ;).

    Der folgende Code tut, was du willst:

    JavaScript
    Shelly.call(
     "HTTP.GET",    // führe einen http GET request aus...
     {
       url: "http://192.168.2.60/rpc/Shelly.GetStatus", // ... und zwar auf diese URL
     },
     function (result, error) {
       print(result);
       print(error);
     },
    );

    Es reicht nicht, bei Shelly.call einfach eine URL reinzustecken - du musst sagen, welchen RPC du ausführen willst (in diesem Fall ist das ein HTTP GET Request) und gegebenenfalls die Parameter mitgeben, die dieser RPC verlangt (in diesem Fall ist der Parameter die URL die du aufrufen willst).

    Das Script ist in der vorliegenden Form tatsächlich nicht lauffähig, weil die Definition der Variablen SCAN_DURATION und ACTIVE_SCAN fehlt.

    Die Änderungshistorie zeigt, dass es am 5. Dezember 2024 eine Überarbeitung der Beispielscripte gab und in diesem Zuge sind die entsprechenden Programmzeilen (wohl unabsichtlich) gelöscht worden. Eine komplette Übersicht aller am 5. Dezember vorgenommen Änderungen zeigt der entsprechende Commit:

    https://github.com/ALLTERCO/shell…aa051540a4b907a

    Das bedeutet auch, dass die überarbeitete Version nie getestet wurde, weil dieser Fehler dann sofort aufgefallen wäre.

    Die einfachste Lösung ist vermutlich, die Version vor diesen Änderungen zu verwenden - die kann man sich aus der Git-Historie herausziehen. Hier ist der entsprechende Link:

    https://raw.githubusercontent.com/ALLTERCO/shell…le-shelly-dw.js

    Hallo familieschaal ,

    Ich habe mir das durch den Kopf gehen lassen und ich sehe keinen Sinn darin, das in diesem Script zu integrieren. Abgesehen von den Konsequenzen für die Programmierung (das Script müsste, abhängig von der Präsenz des Temperatursensors, unterschiedlich agieren) und für die Benutzerfreundlichkeit (die Konfiguration wäre ebenfalls unterschiedlich und komplexer) ist eine temperaturbezogene Steuerung auch einfach nicht der Zweck dieses Scriptes.

    Das Script soll sich ausschließlich um die preisbasierte Steuerung kümmern - und die Wärmepumpe muss ja in irgendeiner Form sowieso temperaturbezogen agieren (und den Energiebedarf selbsttätig reduzieren, wenn kein Heizbedarf besteht).

    Natürlich besteht immer die Möglichkeit das Script selbst anzupassen, aber in die von mir gepflegte "Standardversion" werde ich das nicht aufnehmen.

    In der Diskussion im Thread FritzBox reconnect über Script hat ostfriese erwähnt, dass bereits öfters nach einem Script gefragt wurde, das eine FRITZ!Box rebooten kann. Nachdem ich gerade in der Materie drin war, habe ich noch ein bisschen recherchiert und in den folgenden Links Vorlagen gefunden, die ich für den Shelly adaptieren konnte:

    https://www.media-techport.de/2023/08/fritzb…ipt-neustarten/

    https://forum.heimnetz.de/threads/repeat…en-tr-064.1061/

    Das folgende Script kann zumindest eine 6490 Cable erfolgreich rebooten:

    Da der Reboot offenbar zwingend eine Autorisierung erfordert, müssen Benutzer und Passwort im Klartext im Script eingetragen werden - ob das klug ist, muss jeder selber wissen ;-).

    Ich bitte um Feedback, falls das Ding auf anderen Modellen nicht funktionieren sollte - ich bin kein großer Fritzbox-Experte, aber ich werde mein Bestes tun ;).