Beiträge von Phil1994

    Eine Warteschlange für parallel ausstehende HTTP-Anfragen sind für mich fraglich. Durch den Timeout welchen ich eingebaut habe, können keine parallel ausstehende Requests entstehen. Zu deinem zweiten Punkt hätte ich noch eine Frage:

    Zitat
    • Man könnte die Anzahl der Timer, die von dem Skript verwendet werden, reduzieren, indem man den Timer, der für das Absetzen der HTTP-Anfrage verwendet wird, entfernt und stattdessen die HTTP-Anfrage direkt in der runLoop()-Funktion aufruft.

    Die runLoop-Funktion wird ja nur einmal ausgeführt, ich möchte aber die HTTP-Anfragen dauerhaft ausführen. Gäbe es für die runLoop-Funktion die Möglichkeiten einer sleep-Funktion um die HTTP-Anfragen vielleicht in einer Schleife ausführen zu können? Ich hatte mich mal in der Doku umgesehen aber keine sleep-Funktion gefunden.

    PS: Bis jetzt läuft das Skript noch. Es gibt allerdings das Problem, dass in letzter Zeit die Sonne nie richtig geschienen hat, sodass der Set-Switch-RPC-Call in letzter Zeit nicht ausgeführt wurde. Ich bin aber trotzdem hoffnungsvoll, dass wir das Problem mit der Reduzierung der RPC-Verschachtelungen um 1 bereits eliminiert haben. Ich könnte theoretisch mal die Sonne scheinen lassen, indem ich den Schwellwert runtersetze, damit der Schalter öfter geöffnet wird.

    Habe gerade mal etwas rumprobiert, indem ich in einem Testskript mehrere GetStatus verschachtelt habe à la:

    Dabei stell sich heraus, dass der Shelly bereits schon bei einer Verschachtelung von 4 manchmal Probleme kriegt. Und diese Verschachtelung von 4 habe ich bei meinem Steuerungsscript sogar schon erreicht via den folgenden Calls: Switch.GetStatus -> Timer -> POST-Request -> Switch.Set.

    Probiere jetzt erstmal den vorgeschlagenen `Shelly Status Handler` aus.

    I just found out you can actually get the time from the device itself. This way you're not depending on some time server running. It works like this:

    [script][/script]

    [script]Shelly.call("Sys.GetStatus", [/script]

    [script] {}, [/script]

    [script] function (res, error_code, error_msg, ud) { [/script]

    [script] print("Current time is:", res.time); [/script]

    [script] }, [/script]

    [script]); [/script]

    [script][/script]

    You could use a timer to ask a time server what time it is every minute and check if it is currently 23:00. I tried to do a test implementation below. You still have to insert your schedule enabling into the if clause. Also change the time zone accordingly, I currently set it to German time. There is also the problem with missing the target time because the polling intervall is exactly 60 seconds, which means we could possibly skip it. Good luck:

    [script] [/script]

    [script]let CONFIG = { [/script]

    [script] pollingInterval: 60 * 1000, [/script]

    [script] pollingUrl: "https://timeapi.io/api/Time/curre…e=Europe/Berlin", [/script]

    [script] hour: 23, [/script]

    [script] minute: 00, [/script]

    [script]}; [/script]

    [script]
    [/script]

    [script]Timer.set( [/script]

    [script] CONFIG.pollingInterval, [/script]

    [script] true, // Run periodically [/script]

    [script] function (ud) { [/script]

    [script] Shelly.call("HTTP.REQUEST", [/script]

    [script] { method: "GET", url: CONFIG.pollingUrl, timeout: 10 }, [/script]

    [script] function (res, error_code, error_msg, ud) { [/script]

    [script] print("errors-http-post:", error_code, error_msg); [/script]

    [script] if (error_code === 0) { [/script]

    [script] let parsedBody = JSON.parse(res.body); [/script]

    [script] print("Time server response:", res.body); [/script]

    [script] if (parsedBody.hour === CONFIG.hour && parsedBody.minute === CONFIG.minute) { [/script]

    [script] print("test"); [/script]

    [script] // do your thing [/script]

    [script] } [/script]

    [script] } [/script]

    [script] }, [/script]

    [script] null [/script]

    [script] ); [/script]

    [script] }, [/script]

    [script] null [/script]

    [script]); [/script]

    [script][/script]

    Sprichst du konkret von dem Aufruf von Timer.set()? Dieser Aufruf ist nur einmal bei Initialisierung des Scripts und dürfte eigentlich nicht mehrfach ausgeführt werden. Oder meinst du, dass das Skript mehrmals gleichzeitig ausgeführt wird? Das würde mich stark wundern, davon habe ich noch nirgends so gelesen. Ich habe das Skript zwar im Autostart, aber dies sollte eigentlich nicht für ein paralleles Ausführen sorgen...

    > Ich hab deinen Code mal grob überfolgen du nutzt einen Asynchronen Timer um den Asynchronen Callback immer wieder periodisch neu zu starten richtig?

    Ja genau, ich setze somit alle 2 Minuten einen HTTP-Request ab.

    > Wie viele Durchgänge schaft der Code den bevor die Meldung kommt, also wie lange genau läuft es stabil? Einige Tage ist nicht sonderlich genau.

    Ich kann es nicht genau sagen, weil ich gerade nicht im Fehlerzustand bin. Ich werde mal darauf achten, vielleicht taucht das Problem auch immer zur selben Uhrzeit auf.

    Ich habe heute mal einen Endpunkt in Python geschrieben und etwas mit dem Timeout rumgespielt. Der Timeout funktioniert tatsächlich, so wie ich ihn implementiert habe. Mir ist dann aufgefallen, dass es auch bei einem Timeout zu einem Aufruf des Callbacks kommt, in welchem ich die Datenverarbeitung mache. Ich habe nun die Datenverarbeitung in eine Bedingung gesetzt, die prüft, ob der Request tatsächlich geglückt ist. Ich hoffe hiermit ist das Problem gegessen. Falls nicht, werde ich hier mal den Log mit Error posten, falls nochmals einer auftaucht.

    Welches Gerät fragst du ab? Ich frage einen Solarlog 1200, der hat eine JSON-Schnittstelle.

    Was verstehst du als Solaranlage? Ich habe in meinem ursprünglichen Post vom Abfragen meiner Solaranlage gesprochen, weil ich die Situation vereinfachen wollte. Es spielt keine Rolle, mit welchem Gerät ich mich verbinde, weil die Datenübertragung bereits funktioniert. Mein Problem ist, dass mein gesetzter Timeout nicht funktioniert, da spielt das Endgerät keine Rolle dabei, weil das rein clientseitig ist.

    Wie lautet deine Polling Url? Die URL bringt dir nichts, weil das Gerät in meinem Heimnetzwerk ist und nicht von aussen zugänglich.

    > Wenn laut deiner Aussage natürlich nicht mehrere Anfragen sein können da du ja einen Timeout hast. Wenn ich in die Api docs schaue hat der Shelly.call keinen timeout!

    Der Timeout Parameter kommt vom Post-Request, siehe hier: https://shelly-api-docs.shelly.cloud/gen2/Component…s/HTTP#httppost. Die Parameter, welche man dem Shelly.call gibt, werden an die Post-Schnittstelle weitergegeben.

    Seven of Nine  Devil Man kann es auch im Code erkennen, aber hier noch einmal beschrieben: Ich habe ein Polling-Intervall das 2 Minuten gross ist, d.h. es wird alle 2 Minuten ein POST-Request geschickt. Den Timeout, den ich auf dem Post-Request habe, ist 1 Sekunde lang. Theoretisch ist es also gar nicht möglich, dass hierbei 5 Requests in der Luft hängen, weil das mit der Polling-Rate und dem Timeout nicht vereinbar ist.

    Ich habe mir ein Skript gebaut, das meine Solaranlage fragt, wie viel Strom produziert wird und bei dem Erreichen eines Schwellwerts dann das Laden des Elektroautos startet. Die Skript-Logik scheint zu funktionieren, weil das Regeln über einige Zeit (zumindest über mehrere Stunden) funktioniert. Nach einige Tagen allerdings kriege ich dann immer eine Meldung im Sinne von "maximale Anzahl an API-Aufrufen (5) erreicht" und der Timer und damit auch die Ladesteuerung funktioniert nicht mehr. Ich habe nun bereits einen Timeout für den HTTP-Request eingebaut, allerdings hat der auch keine Besserung gebracht. Hat hier jemand eine Idee, welche API-Aufrufe hier zu einer Blockierung führen könnten?

    I build a script that charges my car whenever there is enough sun energy coming from my solar panels. However after running properly for a while, the script always says "maximum API calls reached (5)" and the timer stops working. I Already added a timeout for the POST request, but it didn't help. Any ideas?

    Liebe Grüsse, Best,

    Philipp :)