Beiträge von towiat

    Was muss ich ändern bzw. beachten, damit das Skript auch auf dem Shelly Plug S (Gen3) ausgeführt werden kann?

    Soweit mir bekannt ist, stehen für Scripte grundsätzlich 25 KB an Hauptspeicher zur Verfügung. Auf manchen Geräten reduziert sich das aber auf ca. 8 KB, wenn Matter aktiviert ist. Wenn du also Matter aktiv hast und es nicht benötigst, könntest du durch die Deaktivierung eventuell genug Speicher frei bekommen...

    was bringt mit der UDP log wenn keine Verbindung mehr besteht?

    Gute Frage - ich habe einmal nur auf den geäußerten Wunsch reagiert. Natürlich könnte man das Script beliebig ausbauen - man könnte auf Statusänderungen reagieren und Nachrichten im KVS oder WebStorage ablegen, um sie dann bei Wiederherstellung der Verbindung auszuwerten...

    Schaun wir mal, was OP sagt...

    Schade ist, dass ich in den UDP Logs des Shelly nicht sehe, mit welchem AP er sich verbindet/verbunden ist. Oder kann man den Loglevel erhöhen?

    Das folgende Script schreibt den aktuellen Status des WLAN im Sekundentakt ins Log (die Frequenz kannst du in Millisekunden variieren):

    JavaScript
    Timer.set(1000, true, function() {
      console.log(JSON.stringify(Shelly.getComponentStatus("wifi")));
    })

    Die Einträge im Log sehen dann so aus:

    Code
    {"sta_ip":"192.168.178.253","status":"got ip","ssid":"xxx","bssid":"xx:xx:xx:xx:xx:xx","rssi":-60}

    Vielleicht hilft's ja...

    Laut dem Log meines Pi-Hole hat mein Plus Plug S gestern exakt 4 DNS-Abfragen durchgeführt:

    Code
    Dec 22 13:05:24 dnsmasq[67]: query[A] updates.shelly.cloud from 192.168.178.253
    Dec 22 15:02:16 dnsmasq[67]: query[A] api.energy-charts.info from 192.168.178.253
    Dec 22 22:11:38 dnsmasq[67]: query[A] updates.shelly.cloud from 192.168.178.253
    Dec 22 22:38:39 dnsmasq[67]: query[A] powerstrip.internal from 192.168.178.253

    Der Zugriff auf api.energy-charts.info kommt von meinem Preissteuerungsscript; powerstrip.internal ist im Pi-Hole als lokaler Name für meinen Powerstrip hinterlegt (testweise aus einem Script aufgerufen).

    Offenbar kann der Shelly bei mir problemlos den via DHCP kommunizierten DNS aufrufen. Vielleicht gibt ja das Log des Pi-Hole genauere Aufschlüsse - bei mir ist es unter /var/log/pihole/pihole.log zu finden...

    kann jemand bestätigen, dass die Shellys bei DHCP tatsächlich nicht die IP des Nameserver setzen/speichern?

    Ich habe ein ähnliches Setup - ein PiHole, der in der Fritzbox als DNS-Server hinterlegt ist und fixe IP-Adressen via DHCP. Die Shellies haben bei mir auch keinen Nameserver eingetragen, können aber problemlos die lokalen Domain Names aus dem Pihole auflösen. Der Hauptunterschied zu deinem Setup ist wohl, dass ich für lokale Clients .internal als TLD verwende (TLS brauche ich im internen Netzwerk nicht).

    Ich lese gerade das "What you need to know" über die Änderungen, die offenbar mit Firmware 1.8 kommen.... da wird's wohl ein paar Anfragen im Forum geben - Beispiele:

    Zitat
    • Browsers and other clients may warn about certificate trust chain validation problem. The certificate is issued by Shelly private CA. Shelly will publish the chain of trust for importing into your client. Shelly application will have this chain of trust by default.
    • Account lockout after repeated failures within a time window, only established sessions are allowed.
    • Bluetooth channel is automatically disabled after setup; enabling it opens a 15-minute pairing window only.
    • You must complete initial configuration (admin password, Wi-Fi, etc.) within the guided 15-minute window after powering up/resetting the device.

    Siehe https://kb.shelly.cloud/knowledge-base…elly-and-eu-red

    HTTP Kommunikation (welche ich abfangen und ändern könnte)

    Du hast recht. Ich bin fälschlicherweise davon ausgegangen, dass der Shelly auch die Integrität der Nachricht verifiziert, aber die entsprechende Quality of Protection (auth-int) wird offensichtlich nicht unterstützt. Somit ist zwar das Passwort geschützt, aber der Inhalt der Nachricht ist manipulierbar. Asche auf mein Haupt...

    Es nützt genau das, was ich gesagt habe. Ein Eindringling kann durch Datenanalyse wahrscheinlich problemlos herausfinden, welcher Shelly dein Garagentor steuert - aber er kann es ohne Passwort nicht öffnen. Dass es besser ist, das Netzwerk von vornherein so abzusichern dass es ger nicht erst so weit kommt, halte ich für offensichtlich.

    Wie schon gesagt, bleibt es jedem selbst überlassen, ob er das machen will (ich tu's auch nicht).

    Die Shellys sprechen aktuell nur http - da ist das mit der Passwortsicherheit eh hinfällig.

    Da würde ich (ein bisschen) widersprechen. Die Grundidee der vom Shelly verwendeten Digest-Authentication ist es ja, dass das Passwort auch bei unverschlüsselten Verbindungen geheim bleibt (weil es nie im Klartext sondern nur als Teil eines Hashes übertragen wird, der für jede Abfrage neu berechnet wird).

    Ein potentieller Eindringling ins Netzwerk könnte zwar problemlos den (unverschlüsselten) Datenverkehr vom und zum Shelly mitlesen - ohne Kenntnis des Passwortes ist es ihm aber unmöglich, selbst Abfragen oder Befehle an den Shelly zu schicken.

    Ob die Absicherung gegen dieses Szenario den Aufwand für die Passworterstellung/-verwaltung rechtfertigt, ist wohl eine individuelle Entscheidung...

    Ich habe es bei meinem einfachen Test "zu simpel" versucht.

    Das ist eher eine Verkettung unglücklicher Umstände - der Shelly lehnt offenbar POST-Requests ohne Body ab und curl sendet keinen Body, wenn er nicht explizit angegeben wird. Deswegen geht curl http://ip/rpc/Shelly.GetStatus -X POST nicht durch, aber curl http://ip/rpc/Shelly.GetStatus -d "{}" oder curl http://ip/rpc/Shelly.GetStatus -d "xyz" sehr wohl - muss man auch einmal draufkommen...

    PHP ist nicht meine Baustelle, daher hier die Beispiele direkt in curl (die optionalen Parameter habe ich weggelassen). Es gibt zwei gleichwertige Methoden, um RPCs via POST zu schicken:

    1. Du schickst einen POST an den /rpc Endpunkt. Dann musst du einen vollständigen JSON_RPC Frame mit id, method und params verwenden:

    curl http://192.168.178.253/rpc -d '{"id": 0, "method": "Webhook.Create", "params": {"event": "switch.on", "cid": 0, "name": "Action-Name", "enable": true, "urls": ["https://meine-domain.de"]}}'

    2. Du schickst einen POST direkt an den /rpc/Webhook.Create Endpunkt. Dann reichen die Request-spezifischen Parameter im Body:

    curl http://192.168.178.253/rpc/Webhook.Create -d '{"event": "switch.on", "cid": 0, "name": "Action-Name", "enable": true, "urls": ["https://meine-domain.de"]}'

    Dokumentiert ist das alles hier...

    Ich habe Version 3.6 des Scriptes veröffentlicht - hier ist das Changelog:

    3.6 (2025-11-18)

    This release enhances the priceModifier function so that it can be used to calculate date- or time-dependent price variations (like variable grid fees which have become more widespread in many European countries).

    With this version, the script will pass both the price value and the date and time for each price into the priceModifier function. An example on how this can be used:

    A grid operator charges different grid fees depending on the time of day:

    • The fee is 10 ct/kWh during the peak hours from 7:00 to 9:00 and 18:00 to 20:00.
    • For the remainder of the day, the fee is 8 ct/kWh.

    The priceModifier can be modified like so to add these fees to the EPEX price:

    JavaScript
    function priceModifier(datetime, spotPrice) {
      let hour = datetime.getHours(); // extract hour from the datetime
      if (hour === 7 || hour === 8 || hour === 18 || hour === 19) {
        return spotPrice + 10; // peak hour - add 10 cent to the EPEX price
      }
      return spotPrice + 8; // normal hour - add 8 cent to the EPEX price
    }

    These modified prices are then used by the price analysis algorithm to determine the cheapest hours of the day.

    Note that the WebUI will display these modified prices (and not just the pure EPEX price) when this feature is used.

    Eine direkte Möglichkeit gibt es meines Wissens nach nicht, aber man kann sich mit der utc_offset Variable aus der sys-Komponente helfen. Die gibt den Abstand zur UTC in Sekunden an - in der mitteleuropäischen Zeitzone also 7200 bei Sommerzeit und 3600 bei Normalzeit.

    Die folgende Zeile legt eine Variable Sommerzeit an, die bei aktiver Sommerzeit auf true steht:

    JavaScript
    let Sommerzeit = Shelly.getComponentStatus("sys").utc_offset === 7200;

    Logischerweise würde ich annehmen, dass der Shelly die utc_offset Variable exakt zum Zeitpunkt der Zeitumstellung ändert, aber wirklich prüfen kann ich das nicht...

    Ich habe Version 3.5 des Scriptes veröffentlicht - hier ist das Changelog:

    3.5 (2025-10-18)

    This release contains two changes:

    • Changed: Price Retrieval
      As the price API sometimes delivers too many and/or erroneous price records especially for the Austrian market, the retrieval logic was slightly changed to try to compensate for that. This change should prevent the API from delivering more than 96 prices for a day (although I can not guarantee that since the API is not under my control).
    • New: Invert Switch
      A new configuration variable invertSwitch is available, which makes it possible to change the switching behavior of the script (useful for some electrical configurations):

      • When set to false (the default), the script turns the switch ON for the selected (cheapest) hours and OFF for the remaining hours.
      • When set to true, the script turns the switch OFF for the selected (cheapest) hours and ON for the remaining hours.

      Note: This change has no impact on the WebUI, which will always show ON for the selected (cheapest) and OFF for the remaining hours.

    Das Script ist wie immer auf GitHub zu finden: https://github.com/towiat/spotelly

    Ich habe Version 3.3 des Scriptes veröffentlicht. Hier ist das Changelog:

    3.3 (2025-10-06)

    Mit dieser Version werden nun 15-Minuten-Preise unterstützt. Da derzeit viele Verträge weiterhin mit Stundenpreisen arbeiten (die eigentlich nur der Durchschnitt der 15-Minuten-Preise für jede Stunde sind), unterstützt das Skript vorerst beide Modi: 60 Minuten und 15 Minuten.

    Die neue Konfigurationsvariable hourMode legt den zu verwendenden Modus fest:

    Wenn sie auf true gesetzt ist (die Grundeinstellung), berechnet und zeigt das Skript die Schaltzeiten für volle Stunden (basierend auf dem Durchschnittspreis für jede Stunde).

    Wenn sie auf false gesetzt ist, werden die Schaltzeiten basierend auf Viertelstunden berechnet und angezeigt. Alle Scriptfunktionen wie Zeitfenster, Blockmodus und Preislimits funktionieren wie erwartet und die Stundentabelle im WebUI ermöglicht die manuelle Anpassung der Ergebnisse. Es gibt jedoch einen Unterschied bei der Einrichtung des Scriptes:

    Im 15-Minuten-Modus definiert die Variable switchOnDuration die Dauer in Viertelstunden, nicht in Stunden. Wenn also z. B. eine Gesamteinschaltzeit von fünf Stunden konfiguriert werden soll, ist der korrekte Wert für diese Variable in diesem Modus 20.

    Das Script ist wie immer auf GitHub zu finden: https://github.com/towiat/spotelly