NEWS
Blocky und das Arbeiten mit einem Datum
-
Salut,
irgendwie habe ich einen Knoten in meinen Gedanken oder übersehe vielleicht was. Da ich bisher noch keine, von mir anzuwendende, Lösung gefunden habe versuche ich es mal mit einem Tread.
Fragestellung: Ich möchte ein Datum in ein Objekt schreiben. Dann möchte ich durch ein Script mit automatischer Auslösung alle X Minuten prüfen ob von dem Datum 5, 10 oder 20 Minuten verstrichen sind.
Aber fangen wir mit den 5 Minuten an.Ich schreibe das Datum in ein STRING Objekt. Mit einem OBJEKT Objekt klappt es nicht.
Zunächst schreibe ich aktuell das Datum und Uhrzeit weg in das Objekt.
Hier ist ein aktueller Wert in dem Objekt.
Mein aktueller Versuch ist das Datum und die Uhrzeit wieder aus dem Objekt zu holen und in eine Variable zu schreiben.
Dann wollte ich dem Wert in der Variable 5 Minuten addieren.
Wenn die aktuelle Zeit nun größer oder gleich dem Wert +5 Minuten ist, dann schick mal ne Mail oder sowas.
Bei der Addition der Minuten macht er aber nicht wirklich mit
Hier das aktuelle Script komplett:
Bin um Ideen/Vorschläge oder Hinweise dankbar.
-
@dapanic
Als allgemeine Informationen zur Zeitdiffernez gerne mal das Video anschauen:
https://youtu.be/sxkz3O6nfFQ?si=hiF-TmWUSCuB_co4 -
@dapanic sagte in Blocky und das Arbeiten mit einem Datum:
Bin um Ideen/Vorschläge oder Hinweise dankbar.
- Warum willst du per Heartbeat eine vorher vorgegebene Zeitverzögerung 'prüfen'. Warum nicht via Timeout eine Aktion um die entsprechende Zeit verzögern ?
Das Thema Mail nach 5 Minuten wenn die Garage noch offen ist löst man am einfachsten so:
- Warum willst du die Zeit in einem Anwender-lesbaren Format zur Berechnung nutzen ? Das ist doch Humbug. Für Berechnungen bietet sich an die aktuelle Zeit als 'DateTime Objekt' zu nutzen. Dieses ist (anders als Erwartet) kein JS Objekt, sondern eine Zahl mit der gerechnet werden kann. Sie ist in Millisekunden angegeben.
Wenn du also wissen willst ob seit Zeitpunkt A 5 Minuten vergangen sind, dann machst du
(unter der Bedingung das das was du in Time_A rein geschrieben hast auch als . .as date object. verwaltet wird. Nebenbei sind die üblichen 'timestamps' innerhalb des ioBroker auch in dem Format - sprich du kannst damit feststellen vor wieviel Minuten ein State geändert wurde.Parallel kannst du für eine Visu auch gerne noch eine String-Representation der gleichen Zeit ablegen - oder die Umrechnung in der Visu machen lassen. Da da zumeist JS benutzt wird, sähe das so aus:
Timestring = new Date(Time_A).toLocaleString("de-DE")
-
@asgothian @Shadowhunter23
Danke euch. -
@asgothian said in Blocky und das Arbeiten mit einem Datum:
@dapanic sagte in Blocky und das Arbeiten mit einem Datum:
Bin um Ideen/Vorschläge oder Hinweise dankbar.
- Warum willst du per Heartbeat eine vorher vorgegebene Zeitverzögerung 'prüfen'. Warum nicht via Timeout eine Aktion um die entsprechende Zeit verzögern ?
Meine Idee war dass ich, je nach vorher bestimmte Anzahl, Mails verschicken und dann die Garage schließe.
Mit deinem Block müsste ich ja dann im Grunde z.B. 4 Timeouts stareten.
Einen nach 5 Minuten, 10, 15 und 30 Minuten z.B. im 30 Minuten Block müsste dann nochmal der Schließimpuls gesteuert werden.
Daher dachte ich ich prüfe jede Minute, zähle einen Counter hoch für jede Auslösung und wenn der Counter der Vorgabe entspricht dann schließe. -
@dapanic sagte in Blocky und das Arbeiten mit einem Datum:
Mit deinem Block müsste ich ja dann im Grunde z.B. 4 Timeouts stareten.
Was spricht dagegen?
Man kann ja Funktionen verwenden, um Code nicht duplizieren zu müssen (dazu sind sie da).
Und innerhalb der Funktion kann (und sollte) man den Timeout stoppen und mit der berechneten neuen Zeitspanne neu starten.
Das Zauberwort an der Ecke lautet "Rekursion". Die Funktion ruft sich immer wieder selbst auf. Solange, bis entweder die vorgegebene Anzahl Durchläufe erreicht oder das Problem beseitigt wurde.
Sowas geht auch in Blockly recht elegant.Daher dachte ich ich prüfe jede Minute, zähle einen Counter hoch für jede Auslösung und wenn der Counter der Vorgabe entspricht dann schließe.
Wie @Asgothian schon schrieb, ist so ein "heartbeat" eine denkbar schlechte Variante um sowas zu lösen.
Denk nochmal drüber nach, ob es sinnvoll ist für einen Fall, der vielleicht 1x pro Woche auftritt (vermutlich deutlich seltener), etwas 1.440x jeden Tag der Woche auszuführen. -
@dapanic sagte in Blocky und das Arbeiten mit einem Datum:
Meine Idee war dass ich, je nach vorher bestimmte Anzahl, Mails verschicken und dann die Garage schließe.
Mit deinem Block müsste ich ja dann im Grunde z.B. 4 Timeouts stareten.
Einen nach 5 Minuten, 10, 15 und 30 Minuten z.B. im 30 Minuten Block müsste dann nochmal der Schließimpuls gesteuert werden.
Daher dachte ich ich prüfe jede Minute, zähle einen Counter hoch für jede Auslösung und wenn der Counter der Vorgabe entspricht dann schließe.Na ja, ich würde zunächst einmal ein Intervall starten. Läuft alle 5 Minuten. Darin ein Zähler hochzählen.
Bei 1, 2, 3 gibts eine Meldung. Bei 3 zusätzlich - Intervall anhalten
zusätzlich einen Timeout, in 30 Minuten den SchliessimpulsUnd wenn das ganze geschlossen ist, timeout und Intervall beenden.
Generell ist das was du geplant hattest ein sogenannter 'Heartbeat' - nach dem Herzschlag des Menschen der alles kontrolliert. Ein Heartbeat der ständig mit läuft ist Ressourcenverschwendung - insbesondere wenn es nur um dedizierte Aktivierungen geht. Besser ist es, mit gezielten Events zu arbeiten, die nur dann laufen wenn sie benötigt werden.
A.
Nachtrag: Geht auch ohne Zählen, siehe hier:
Wichtig - der Block
state value
undstate timestamp
(ja, der, es ist der gleiche) stammt aus dem Trigger Bereich, und ist da mitstate value
(oderwert
auf deutsch) vorgelegt.Nachtrag2: im Skript ist ein Typo drin - der
stopTimeout
Baustein ist eine Ebene zu hoch - er muss zumstop Intervall
Baustein. Da ich das Blockly nicht mehr habe kann ich nicht mal eben ein neues Bild erzeugen. -
@asgothian @Codierknecht
Abermals vielen Dank. Ich schaue mir das an. -
Das Prinzip. Nicht getestet und möglicherweise verbesserungsfähig.
Funktionsweise:
Beim Öffnen des Tores wird der Rundenzähler auf 0 gesetzt und damit die Funktion aufgerufen.
Die ermittelt die nötige Verzögerung anhand des Rundenzählers: Für die ersten 3 Durchläufe jeweils 5 und im letzten Durchlauf 15 Minuten.
Dann wird der passende Timeout gestartet. Sind die X Minuten abgelaufen, wird eine Nachricht gesendet und der Rundenzähler inkrementiert.
Ist der noch nicht größer als 4, ruft sich die Funktion mit geändertem Rundenzähler neu auf.Man muss bei Rekursionen nur aufpassen, dass man eine saubere Abbruchbedingung einbaut. Sonst produziert man sich eine herrliche Endlosschleife.
Edit
Die Änderung im Trigger sorgt dafür, dass nach dem Schließen des Toren nicht noch eine Meldung abgesetzt wird.