Seite 1 von 2

Blockly Zeit zwischen 21-6 Uhr in if-Abfrag3

Verfasst: 18. Nov 2023 13:06
von Hoggle
Ich denke, der Titel sagt alles, oder?
Kann mir da jemand helfen?
Ich finde keinen Block mit Zeiten, nur mit Datum.

Gesendet von meinem SM-G998B mit Tapatalk


Re: Blockly Zeit zwischen 21-6 Uhr in if-Abfrag3

Verfasst: 18. Nov 2023 13:33
von tim.l
Hey @Hoggle,

in dem Punkt "Dates & Times" gibt es ganz viele Blöcke. Alle Blöcke in denen DateTime steht, sind üblicherweise nicht nur ein Datum, sondern beinhalten auch die Zeit. Beispiel der "now" Block, enthält ein komplettes DateTime Object. Vgl. Log Ausgabe: 2023-11-18T13:31:07.132+01:00[SYSTEM]

D.h. du kannst einfach "now" nehmen, ein now, welches du auf 21.00 Uhr stellst und ein now welches du auf 06.00 Uhr stellst. Und dann kannst du es einfach vergleichen.

Beste Grüße,
Tim

Re: Blockly Zeit zwischen 21-6 Uhr in if-Abfrag3

Verfasst: 18. Nov 2023 13:40
von Harka
zum Bleistift
von21bis6.png

Re: Blockly Zeit zwischen 21-6 Uhr in if-Abfrag3

Verfasst: 18. Nov 2023 14:10
von Hoggle
Vielen, vielen Dank.
Genau das suchte ich. Hatte sogar schon einmal den richtigen Block gefunden, aber dann die weitere Logik nicht gesehen.
Das mit dem "einschachteln" der Blöcke muß ich noch verinnerlichen.

Re: Blockly Zeit zwischen 21-6 Uhr in if-Abfrag3

Verfasst: 19. Nov 2023 14:10
von Hoggle
So, jetzt habe ich das mal versucht, umzusetzen, aber irgendwo hakt es bei mir.
Ich habe ein Item, über das ich schalte, wenn ich im Urlaub bin

Code: Alles auswählen

    Switch   R_Urlaub                   "Urlaubsschaltung"                          (gDummy)  ["Status"]
Und ich habe einen Homematic-Schalter mit Beleuchtung, über den ich, wenn ich nicht im Urlaub bin, anzeigen lassen will, dass, wenn es nach 21 Uhr ist und die Garage offen steht, so das ich, bevor ich ins Bett gehe auch noch sehe, das ich auf den Garagenknopf drücken muß.
Wenn der Urlaubsschalter auf ON steht, möchte ich eine Meldung bekommen, wenn die Garage offen ist (Wenn zum Beispiel ein Nachbar die Blumen gegossen hat und dann vergessen hat, das Tor zu schließen (Das habe ich aber bis jetzt nur rudimentär gemacht und bedarf noch ein wenig Arbeit.
Aber im Moment löst die Blockly-Rule gar nicht aus.
Da ich nicht weiss, was ihr am Besten "lesen" könnt, habe ich mal alle Code-Schnipsel angehängt und auch das Bild mit den Blöcken.
Zur Erklärung: Ich möchte, wenn es nach 21 Uhr ist, über die LEDs des Wohnzimmerschalters darüber informiert werden, dass das Tor noch offen ist. Ich möchte beim auslösen den aktuellen Status der LED in "Dummy"-Items kopieren und wenn das Tor geschlossen wird soll der Ursprungszustand wieder zurück kopiert werden.
Wenn es vor 21 Uhr ist möchte ich nur für 10 Sekunden die LEDs anschalten, also mehr oder weniger als "Vorwarnung", denn die Garage gehört dem Auto meiner Frau :mrgreen:

Dafür gibt es ein Item, das Mittels Rule die 3 verschiedenen Stati des Tores bekommt (100=geschlossen, 0=offen, 50=teilweise geöffnet)

Dafür habe ich 2 Neigungssensoren ans Tor geschraubt und das funktioniert auch gut für meine Zwecke, also der Status wird aktualisiert.
Aber wieso leuchten die LED nicht?
Garagentor_Blockly2.png
Garagentor_Blockly.png

Code: Alles auswählen

var things = Java.type('org.openhab.core.model.script.actions.Things');


if (items.getItem('R_Urlaub').state != 'ON') {
  if (items.getItem('Garagentor_Status').state == '0' || items.getItem('Garagentor_Status').state == '50') {
    if (((time.ZonedDateTime.now()).hour()) >= 21 || ((time.ZonedDateTime.now()).hour()) < 6) {
      items.getItem('WZ_Lichtfarbe_Oben').sendCommand(items.getItem('WZSteckdoseFenster8COLOR').state);
      items.getItem('WZ_Lichtfarbe_Unten').sendCommand(items.getItem('WZSteckdoseFenster12COLOR').state);
      items.getItem('WZ_Lichtlevel_Oben').sendCommand(items.getItem('WZSteckdoseFenster8LEVEL').state);
      items.getItem('WZ_Lichtlevel_Unten').sendCommand(items.getItem('WZSteckdoseFenster12LEVEL').state);
      items.getItem('WZSteckdoseFenster8COLOR').sendCommand('BLUE');
      items.getItem('WZSteckdoseFenster12COLOR').sendCommand('BLUE');
      items.getItem('WZSteckdoseFenster8LEVEL').sendCommand('100');
      items.getItem('WZSteckdoseFenster12LEVEL').sendCommand('100');
    }
  } else if ((((time.ZonedDateTime.now()).hour()) >= 21 || ((time.ZonedDateTime.now()).hour()) < 6) && items.getItem('Garagentor_Status').state == '100') {
    items.getItem('WZSteckdoseFenster8LEVEL').sendCommand(items.getItem('WZ_Lichtlevel_Oben').state);
    items.getItem('WZSteckdoseFenster12LEVEL').sendCommand(items.getItem('WZ_Lichtlevel_Unten').state);
    items.getItem('WZSteckdoseFenster8COLOR').sendCommand(items.getItem('WZ_Lichtfarbe_Oben').state);
    items.getItem('WZSteckdoseFenster12COLOR').sendCommand(items.getItem('WZ_Lichtfarbe_Unten').state);
  } else if (items.getItem('Garagentor_Status').state != '100') {
    items.getItem('WZ_Lichtfarbe_Oben').sendCommand(items.getItem('WZSteckdoseFenster8COLOR').state);
    items.getItem('WZ_Lichtfarbe_Unten').sendCommand(items.getItem('WZSteckdoseFenster12COLOR').state);
    items.getItem('WZ_Lichtlevel_Oben').sendCommand(items.getItem('WZSteckdoseFenster8LEVEL').state);
    items.getItem('WZ_Lichtlevel_Unten').sendCommand(items.getItem('WZSteckdoseFenster12LEVEL').state);
    items.getItem('WZSteckdoseFenster8COLOR').sendCommand('BLUE');
    items.getItem('WZSteckdoseFenster12COLOR').sendCommand('BLUE');
    items.getItem('WZSteckdoseFenster8LEVEL').sendCommand('100');
    items.getItem('WZSteckdoseFenster12LEVEL').sendCommand('100');
    if (cache.private.exists('Garagentorlicht') === false || cache.private.get('Garagentorlicht').hasTerminated()) {
      cache.private.put('Garagentorlicht', actions.ScriptExecution.createTimer('Garagentorlicht', time.ZonedDateTime.now().plusSeconds(10), function () {
        items.getItem('WZSteckdoseFenster8LEVEL').sendCommand(items.getItem('WZ_Lichtlevel_Oben').state);
        items.getItem('WZSteckdoseFenster12LEVEL').sendCommand(items.getItem('WZ_Lichtlevel_Unten').state);
        items.getItem('WZSteckdoseFenster8COLOR').sendCommand(items.getItem('WZ_Lichtfarbe_Oben').state);
        items.getItem('WZSteckdoseFenster12COLOR').sendCommand(items.getItem('WZ_Lichtfarbe_Unten').state);
        }));
    };
  }
} else if (items.getItem('R_Urlaub').state != 'OFF' && items.getItem('Garagentor_Status').state != '100') {
  things.getActions('telegram', 'telegram:telegramBot:TelegramBot').sendTelegram(244528228, 'Das Garagentor ist offen');
}
Habe ich irgendwo einen "Denkfehler"?

Re: Blockly Zeit zwischen 21-6 Uhr in if-Abfrag3

Verfasst: 19. Nov 2023 15:19
von Harka
Moin,
sagt das Log (IP:9001) was? Mögliche Fehlerquellen sind der Vergleich von Zahlen (Garagentor_Status) mit Strings "100". Das war schon immer problematisch und ist seit OH 4 mit numericState leicht zu umgehen.
Ansonsten würde ich es etwas anders angehen. Erst mal ein Grundgerüst (siehe Beispiel - geht vermutlich noch besser). Dies testen in dem z.B. die 21 temporär durch eine 15 (Uhr) ersetzt wird. Danach schrittweise die Lampen. Hier muss eventuell teilweise auch mit numericState gearbeitet werden.
von21bis6v2.png

Re: Blockly Zeit zwischen 21-6 Uhr in if-Abfrag3

Verfasst: 19. Nov 2023 15:29
von udo1toni
Ich nehme an, das Item Garagentor_Status ist ein Rollershutter Item, welches als ungebunden ist und durch die Neigungssensoren (mittels Rule) exakt auf die Werte 0, 50 oder 100 gesetzt wird. Ich gehe davon aus, dass Du dieses Item für ein dynamische Icon verwendest.
Mein Tipp für diese Rule: erstelle zu Beginn eine Boolean Variable, die false ist, wenn der Status des Items 100 ist. Damit kannst Du anschließend an den entsprechenden Stellen den Code vereinfachen.

Weiter... das Item R_Urlaub kann (ordnungsgemäße Funktion von openHAB mal vorausgesetzt) nur zwei Status annehmen, nämlich ON oder OFF. Es ergibt keinen Sinn, hier in zwei Teilen einer if-Anweisung jeweils auf das Gegenteil zu prüfen (insbesondere, wenn Du beide Male mit != prüfst, das beinhaltet dann im Zweifel auch noch den dritten möglichen Status NULL, aber für beide Schleifenteile. Lass also die Bedingung im else-Teil einfach weg.

Die Uhrzeit können wir genauso vereinfachen, wie die Prüfung auf geschlossen/offen, also eine weitere Variable, welche false ist, wenn wir uns außerhalb der Zeitspanne befinden.

Wenn wir den bestehenden Code auf diese Weise vereinfachen, und die eigentlichen Aktionen mal kurz durch Aktionskommentare ersetzen, bleibt folgendes Gerüst übrig:

Code: Alles auswählen

var things = Java.type('org.openhab.core.model.script.actions.Things');

var bOpen = true
var bTime = false

if(items.getItem('Garagentor_Status').state == '100') bOpen = false
if(time.ZonedDateTime.now.hour >= 21 || time.ZonedDateTime.now.hour < 6) bTime = true

if (items.getItem('R_Urlaub').state != 'ON') {
    if (bOpen) {
        if (bTime)              // blau 100
    } else if (bTime && !bOpen) // normaler Status
    else if (bOpen) {
                                // blau
                                // timer
    }
} else 
    if (bOpen)                  // telegramm
Jetzt kannst Du ganz gut sehen, dass Deine Bedingungen keinen Sinn ergeben:
Wenn kein Urlaub, prüfst Du, ob das Tor offen ist. Ist das der Fall, wird geprüft, ob wir uns im Zeitfenster befinden und gegebenenfalls das blaue Licht eingeschaltet. Danach folgt ein else, so dass in diesem Fall nichts weiter passiert (die Bedingung bOpen ist ja schon erfüllt, also wird abgebrochen. )
Ist das Tor nicht offen und wir befinden uns im Zeitfenster, so wird auf normalen Zustand geschaltet.
Die dritte Bedingung wird also nur erreicht, wenn das Tor geschlossen ist und wir uns außerhalb des Zeitfensters befinden. Und nun prüfst Du, ob das Tor offen ist, was aber nicht der Fall sein kann -> die Bedingung ist an dieser Stelle der Rule niemals erfüllt.

Der "bessere" Aufbau des Codes:

Code: Alles auswählen

var things = Java.type('org.openhab.core.model.script.actions.Things');

var bOpen = true
var bTime = false

if(items.getItem('Garagentor_Status').state == '100') bOpen = false
if(time.ZonedDateTime.now.hour >= 21 || time.ZonedDateTime.now.hour < 6) bTime = true

if (items.getItem('R_Urlaub').state == 'ON') {
    if(bOpen) {                                // Telegramm }
} else {
    if(bTime) {
        if(bOpen) {                            // Blau }
        else {                                 // normal }
    } else {
        if(bOpen) {                            // blinken }
        else {                                 // aus }
    }
}
Fange mit den einfachsten Fällen an, Urlaub oder kein Urlaub.
Im Fall Urlaub prüfst Du im Do-Teil, ob offen und sendest in diesem Fall das Telegramm
Im Fall kein Urlaub unterscheidest Du ob das Zeitfenster erfüllt ist oder nicht.
Falls das Zeitfenster erfüllt ist, prüfst Du auf offen oder nicht offen und reagierst entsprechend.
Falls das Zeitfenster nicht erfüllt ist, prüfst Du auf offen oder nicht offen und reagierst entsprechend.

Baue zuerst die Abfragen, bevor Du irgendwelche Aktionen einbaust. In der Blockly Ansicht wird es vermutlich keine Kommentarfunktion geben, aber die Anzahl der Möglichkeiten ist ja begrenzt :) Wichtig ist, dass Du für jeden möglichen Fall einen "Ausgang" in der Logik hast, der auch sicher erreicht wird. Man kann diese Abfragen auch mit AND und ODER erreichen, das macht den Aufbau aber komplizierter und man gewinnt dabei nichts.

Ob der Timer Code so passt, kann ich nicht beurteilen :) da ich kein Blockly verwende...

Re: Blockly Zeit zwischen 21-6 Uhr in if-Abfrag3

Verfasst: 19. Nov 2023 15:32
von udo1toni
Harka hat geschrieben: 19. Nov 2023 15:19 Ansonsten würde ich es etwas anders angehen. Erst mal ein Grundgerüst.
Genau, ein ganz wichtiger Tipp an dieser Stelle (und der gilt eigentlich uneingeschränkt für alle Programmiersprachen)

Re: Blockly Zeit zwischen 21-6 Uhr in if-Abfrag3

Verfasst: 19. Nov 2023 19:19
von Hoggle
Hallo.
Also, alles gelöscht und nach einer kleinen Stärkung von vorne begonnen. Habe erst einmal wie oben geschrieben, ein Gerüst erstellt und dann langsam ergänzt (Was die Nachbarn wohl gedacht haben, das mein Tor immer auf und zu gefahren wurde :D ).
Jetzt läuft alles und ich bekomme nicht bei jeder Garagentorbewegung ein Telegram, sondern nur, wenn das Tor nach 17.00 Uhr länger als 5Minuten (Da muß ich mal schauen, wie schnell meine Frau so aus dem Auto hüpft und all die schönen Weihnachtsgeschenke ins Haus schleppt 8-) ).
Wahrscheinlich stelle ich den Timer auf 15 Minuten, dann sollte man einen Kofferraum doch ausgeräumt haben.
Hier mal meine Rule, vielleicht als Idee für andere ;)
Garagentor_Blockly3.png
Jetzt füge ich noch die LEDs mit ein und dann ist wieder ein Wochenende vorbei und ein kleines Projekt mehr abgeschlossen.
Danke für die Unterstützung.

Re: Blockly Zeit zwischen 21-6 Uhr in if-Abfrag3

Verfasst: 19. Nov 2023 19:46
von Harka
sehr schön. Nicht helfend mit Stoppuhr in der Hand ... :twisted:
Für die Nachbarn gibt es auch verschiedene Lösungsansätze. Du kannst z.B. ein Dummy-Dimmer-Item (Test_Garagentor_Status) erstellen und das Tor damit simulieren.