Zeiltschaltuhr mit ECMAScript-2021

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Mac3
Beiträge: 13
Registriert: 1. Feb 2023 08:51
Answers: 0

Zeiltschaltuhr mit ECMAScript-2021

Beitrag von Mac3 »

Hallo Zusammen,

ich versuche seit einiger Zeit eine Zeitschaltuhr über ein Skript zu erstellen.
Leider bisher erfolglos. Ich weiß nämlich nicht, ob die Befehle/Syntax JS Edition 11 noch aktuell bzw. richtig sind.

Gibt es .intValue, now.getMinuteOfHour, now.getHourOfDay noch?
Oder liegt der Fehler ganz woanders?

nachstehend mein mein bisheriges Skript:

Code: Alles auswählen

if ( items.getItem('ZZBewaesserung_Links_Zeitschaltuhr_Schalter').state == 'ON') {
    var sollMinute = items.getItem('ZZBewaesserung_Links_Zeitschaltuhr_Minuten').state.intValue;
    var sollStunde = items.getItem('ZZBewaesserung_Links_Zeitschaltuhr_Stunden').state.intValue;
    
    if (sollMinute == now.getMinuteOfHour && sollStunde == now.getHourOfDay){
	    items.getItem('test').sendCommand('ON');
        }
    }
Viele Grüße
Marcel

Harka
Beiträge: 489
Registriert: 30. Apr 2021 13:13
Answers: 19

Re: Zeiltschaltuhr mit ECMAScript-2021

Beitrag von Harka »

Moin,
probiere mal bitte

Code: Alles auswählen

var now = time.ZonedDateTime.now();
if ( items.getItem('ZZBewaesserung_Links_Zeitschaltuhr_Schalter').state == 'ON') {
    var sollMinute = items.getItem('ZZBewaesserung_Links_Zeitschaltuhr_Minuten').numericState;
    var sollStunde = items.getItem('ZZBewaesserung_Links_Zeitschaltuhr_Stunden').numericState;
    
    if (sollMinute == now.minute() && sollStunde == now.hour()){
	    items.getItem('test').sendCommand('ON');
        }
    }
Quelle: https://github.com/openhab/openhab-js und Blockly

Mac3
Beiträge: 13
Registriert: 1. Feb 2023 08:51
Answers: 0

Re: Zeiltschaltuhr mit ECMAScript-2021

Beitrag von Mac3 »

Danke für deine schnelle Antwort,
leider funktioniert das auch nicht :S

Benutzeravatar
udo1toni
Beiträge: 15247
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Zeiltschaltuhr mit ECMAScript-2021

Beitrag von udo1toni »

Frage 1: welche exakte Version von openHAB nutzt Du denn?
Frage 2: Ist Dir bewusst, dass es elegantere Möglichkeiten für die Aufgabe gibt?

Ganz grundsätzlich arbeitet openHAB bis einschließlich Version 2.5.12 (das ist die letzte der 2er Reihe) mit Joda Time. Dort wäre .getMinuteOfHour und .getHourOfDay korrekt für die beiden Werte.
Ab Version 3.0.0 arbeitet openHAB mit JavaTime, welches auch von den Maintainern von Joda Time als Nachfolger empfohlen wird. JavaTime hat starke Ähnlichkeiten zu Joda Time, unterscheidet sich teilweise aber auch erheblich, so müsste es z.B. .getHour und .getMinute heißen.
Allerdings arbeitet Nashorn (aka ECMAScript-2021+) mit JS-Joda, wo es dann .hour bzw. .minute wären.
Ab openHAB4 kommt dann GraalJS (aka ECMAScript 2022+) zum Einsatz, welches aber ebenfalls JS-Joda einsetzt.

Das Mischmasch der verschiedenen Zeitmodelle macht das Leben nicht einfacher :)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Mac3
Beiträge: 13
Registriert: 1. Feb 2023 08:51
Answers: 0

Re: Zeiltschaltuhr mit ECMAScript-2021

Beitrag von Mac3 »

Ich nutze derzeit die openhab version 3.4.1
Lohnt es sich schon auf Openhab4 upzudaten?

Leider funktioniert der Code von Harka auch nicht und das müsste dann schon JS-Joda sein oder?
Wärest du bereit mir den JS-Joda-Code für meine Zeitschaltuhr bereitzustellen?
Oder liegt der Fehler an meinen Items?
Meine Items : ZZBewaesserung_Links_Zeitschaltuhr_Minuten & ZZBewaesserung_Links_Zeitschaltuhr_Stunden sind vom type: Number, Sematic Class: Setpoint und Sematic Property: Timestamp deklariert.

Welche elegantere Möglichkeit gäbe es denn?
Es ist dabei schon wichtig, dass man die Zeiten in der mainUI über Items verändern kann, da ich nicht der einzige Benutzer bin.

Benutzeravatar
udo1toni
Beiträge: 15247
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Zeiltschaltuhr mit ECMAScript-2021

Beitrag von udo1toni »

Elegantere Methoden:
  1. ein Online Kalender. Immer wieder...
    Du legst z.B. bei Google Calendar eine Kalender an, den gibst Du an jeden frei, der die Zeiten anpassen können soll. Der Kalender wird z.B. direkt mit dem Smartphone Kalender verknüpft, so dass die Termine jeweils im eigenen Kalender mit auftauchen. Die Termine werden als Wiederholevents angelegt, so dass niemand groß raten muss, was exakt einzutragen ist - zusätzliche Zeiten werden einfach als Kopie eines vorhandenen Termins erstellt.
    In openHAB bindest Du den Kalender über das passende Binding ein. Natürlich kannst Du auch andere Kalender verwenden, z.B. den vom iPhone, wichtig ist nur, dass er über das iCal Format online erreichbar ist.
  2. Zeitauswahl nicht über Stunde und Minute, oder zumindest nicht in der Form
Die Liste erhebt keinen Anspruch auf Vollständigkeit :)

Da ich meine Scripte alle ausschließlich per DSL erstelle kann ich Dir nicht mit konkretem JavaScript Code helfen. JavaScript sollte man verwenden, wenn man sich mit JavaScript auskennt. Man sollte nicht zu JavaScript greifen, weil die DSL "so komisch" ist.
Für Menschen, die visuell veranlagt sind, ist Blockly eine attraktive Alternative. Blockly generiert ebenfalls JavaScript. Der Vorteil ist aber, dass man im Editor jederzeit sehen kann, welche Befehle und Funktionen man überhaupt nutzen kann - das ist für Laien sicherlich ein wichtiges Argument.

Ansonsten als reiner DSL Code:

Code: Alles auswählen

rule "Zeitschaltuhr - dumm"
when
    Time cron "0 * * * * ?" // minütlich
then
    var Integer iSoll = 0
    if(ZZBewaesserung_Links_Zeitschaltuhr_Minuten.state instanceof Number)
        iSoll = (ZZBewaesserung_Links_Zeitschaltuhr_Minuten.state as Number).intValue
    if(ZZBewaesserung_Links_Zeitschaltuhr_Stunden.state instanceof Number)
        iSoll = iSoll + 60 * (ZZBewaesserung_Links_Zeitschaltuhr_Stunden^.state as Number).intValue

    if(now.get(ChronoField.MINUTE_OF_DAY) == iSoll)
        test.sendCommand(ON)
end
Die Rule schaut jede Minute nach, ob die eingestellte Zeit der aktuellen Zeit entspricht. Dabei verwendet sie allerdings die Minute des Tages, statt Stunde und Minute getrennt zu betrachten.
Leider steht .getMinuteOfDay in JavaTime nicht zur Verfügung, aber mit .get(ChronoField.MINUTE_OF_DAY) bekommt man das gleiche Ergebnis (und ChronoField bietet noch massig andere "speziellere" Formate an, ist also wesentlich potenter)

Aber auch das ist nicht wirklich elegant, es wird 60 * 24 pro Tag geprüft, ob eine bestimmte Zeit erreicht ist. Besser:

Code: Alles auswählen

// globale Variablen müssen vor der ersten Rule in der Datei definiert werden!
var Timer tWaterLeft = null

rule "Zeitschaltuhr - besser"
when
    Item ZZBewaesserung_Links_Zeitschaltuhr_Minuten changed or // Minute geändert
    Item ZZBewaesserung_Links_Zeitschaltuhr_Stunden changed or // Stunde geändert
    Time is midnight // Mitternacht
then
    var Integer iSoll = 0
    if(ZZBewaesserung_Links_Zeitschaltuhr_Minuten.state instanceof Number)
        iSoll = (ZZBewaesserung_Links_Zeitschaltuhr_Minuten.state as Number).intValue
    if(ZZBewaesserung_Links_Zeitschaltuhr_Stunden.state instanceof Number)
        iSoll = iSoll + 60 * (ZZBewaesserung_Links_Zeitschaltuhr_Stunden^.state as Number).intValue

    if(test.state != ON) {
        tWaterLeft?.cancel
        tWaterLeft = createTimer(now.with(LocalTime.MIDNIGHT).plusMinutes(iSoll),[|
            test.sendCommand(ON)
        ])
    }
end
Die Rule triggert einmal täglich um Mitternacht, sowie falls jemand über die UI Änderungen an Minute und/oder Stunde vornimmt.
Die Rule liest wie gehabt die Werte als Minute des Tages aus und erstellt einen passenden Timer für den Tag, unter der Voraussetzung, dass gerade keine Bewässerung stattfindet. Im Schnitt wird die Rule also wesentlich seltener ausgeführt - dennoch wird die Bewässerung damit genauso zuverlässig funktionieren.

Weiterhin kann man sich überlegen, ob die Eingabe der Zeit über zwei Items noch zeitgemäß ist. Man kann sich da auch gut an mechanischen Zeitschaltuhren orientieren - auch dort kann meist nicht minutengenau ausgewählt werden, wann die Uhr schalten soll, je nach Modell gibt es vielleicht alle 15 Minuten eine Schaltmöglichkeit, es gibt sogar Wochenschaltuhren nach dem gleichen Prinzip, die dann nur alle zwei Stunden eine Schaltmöglichkeit bieten - entsprechend 84 Schaltreitern in einem Kreis angeordnet.

Im Grunde ist aber Bewässerung eine Funktion, die sich viel besser automatisieren lässt, als über Schaltuhren, die dann womöglich täglich manuell angepasst werden. Als Eckpunkte werden dabei dann Wetterdaten (Vorhersage, aktuelle Temperatur und Sonneneinstrahlung) sowie Bodenfeuchtesensoren herangezogen, meinetwegen auch das Datum und der Ferienkalender. Und vielleicht möchte man noch eine Option vorsehen, die Automatik zu deaktivieren, so dass der Beregner nicht die Gartenparty sprengt ;)
Es gibt hier im Forum auch einige Beispiele, von simpel bis totally overengineered :) Mit einer solchen Automation reduziert sich die Eingabe aber auf einen Schalter, eben Automatik An oder Aus.
Und je nach Menge der Regner kann sogar eine autarke Steuerung sinnvoll sein, z.B. mit openSprinkler, welches sich dann wieder in openHAB einbinden lässt (vor allem, um die Automatik zu deaktivieren...)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Mac3
Beiträge: 13
Registriert: 1. Feb 2023 08:51
Answers: 0

Re: Zeiltschaltuhr mit ECMAScript-2021

Beitrag von Mac3 »

Danke für deine sehr ausführliche Antwort. Starker Support!

Das ganze über einen Onlinekalender einbinden kommt für uns leider nicht in frage. Trotzdem ein guter Hinweis.

Einen Schalter, mit dem man die Zeitschaltuhr abschaltet, hatte ich bereits in meiner ersten Variante mit berücksichtigt.

Ich habe gerade beide deiner DSL-Sricpt-Varianten getestet. Die zweite über den Timer ist auf jeden Fall die charmantere, daher auch meine präferierte Lösung.
Leider funktionieren beide Varianten bei mir nicht.
Ich habe es sowohl als sricpt als auch als Rule mit auswählbaren triggern getestet

Hast du/ihr noch einen Tipp für mich woran es liegen kann?
Zuletzt geändert von Mac3 am 21. Jul 2023 10:23, insgesamt 1-mal geändert.

Benutzeravatar
udo1toni
Beiträge: 15247
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Zeiltschaltuhr mit ECMAScript-2021

Beitrag von udo1toni »

Du musst den Code zwingend über eine Textdatei anlegen, das geht nicht über die UI. Der Speicherort ist zwingend exakt $OPENHAB_CONF/rules/ und der Dateiname muss zwingend und exakt auf .rules enden ( z.B. auf einem Raspberry Pi mit openHABian Image /etc/openhab/rules/meine.rules ). Unterordner sind nicht erlaubt.

Wenn Du über die UI arbeiten willst, musst Du den Rahmen der Rule weg lassen. Die Rule mit Timer funktioniert nicht über die UI, da sie auf eine globale Variable angewiesen ist. Also nur die erste Variante, als UI-DSL Rule (Code-Ansicht):

Code: Alles auswählen

configuration: {}
triggers:
  - id: "1"
    configuration:
      cronExpression: 0 * * * * ? *
    type: timer.GenericCronTrigger
conditions: []
actions:
  - inputs: {}
    id: "4"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: >2
            var Integer iSoll = 0
            if(ZZBewaesserung_Links_Zeitschaltuhr_Minuten.state instanceof Number)
                iSoll = (ZZBewaesserung_Links_Zeitschaltuhr_Minuten.state as Number).intValue
            if(ZZBewaesserung_Links_Zeitschaltuhr_Stunden.state instanceof Number)
                iSoll = iSoll + 60 * (ZZBewaesserung_Links_Zeitschaltuhr_Stunden^.state as Number).intValue

            if(now.get(ChronoField.MINUTE_OF_DAY) == iSoll)
                test.sendCommand(ON)
    type: script.ScriptAction
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Mac3
Beiträge: 13
Registriert: 1. Feb 2023 08:51
Answers: 0

Re: Zeiltschaltuhr mit ECMAScript-2021

Beitrag von Mac3 »

Um mit der UI zu arbeiten, benötige ich dann doch den time cron trigger und nicht um Mitternacht, und die Veränderung ZZBewaesserung_Links_Zeitschaltuhr_ items. oder habe ich einen Denkfehler?

Sorry. Ich stehe gerade auf dem Schlauch.....

Benutzeravatar
udo1toni
Beiträge: 15247
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Zeiltschaltuhr mit ECMAScript-2021

Beitrag von udo1toni »

Ja, stimmt, mein Fehler... das kommt davon, wenn man das eine denkt und das andere schreibt...

Hab's oben geändert...
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten