Lektionen aus der Umstellung von OpenHab 2.4 auf 3.3 (wegen lokalem SH)

  • Jetzt da das lokale SmartHome für alle Generationen von Zentralen für alle Verfügbar ist, ist es nur eine Frage der Zeit, bis Livisi die Cloud API für die externen Systeme wie OpenHab und ioBroker abschaltet - habe ich mir jedenfalls gedacht...

    Ergo muss ich endlich mal die Baustellen bezüglich meiner OpenHab Installationen (klein im Ferienhaus, groß Zuhause) angehen und das machen, wovor ich mich so lange erfolgreich gedrückt habe: Der Umstieg von 2.4 (kein lokales Binding) auf 3.x (lokales Binding)


    Ich habe mich lange davor gedrückt, da ich ein rein Datei basiertes Setup habe und ich wirklich sehr viele, teils komplexe, Regeln verwende. Mit OH 3.x wurden einige Dinge die mich betreffen geändert, bspw. der Format der Zeitangaben, und es war für mich klar, dass ich mich da reinfuchsen muss.


    Für diejenigen, die nicht mit Dateien arbeiten, ist das folgende nicht so interessant - für allen anderen ist es hoffentlich eine Hilfe bei ihren Upgrade.


    Hier möchte ich auf zwei Änderungen eingehen, die mich in den Regeln besonders betrafen:

    triggeringItem

    Diese Umstellungen waren der leichte Teil, da ich hier einfach mit "replace" die entsprechenden Stellen ändern konnte:

    • triggeringItem.name wird zu triggeringItemName
    • triggeringItem.state wird zu newState (wie bei mir in 98% der Fälle) oder zu previousState

    Jodatime

    Keine Ahnung, warum das gemacht wurde und was die genauen technischen Details sind - relevant für mich ist nur, wie funktioniert es jetzt?

    Nice to know

    Eine für mich wichtige Lektion war, dass fast alle Anwendungen der Zeit/Datum in Regeln über den Typ ZonedDateTime erfolgen sollten.

    • now, also der übliche Aufruf um eine Zeit/Datum zu bekommen ist jetzt vom Typ ZonedDateTime
    • Alternative zu now ist auch ZonedDateTime.now()
    • Des weiteren gibt es noch das LocalDateTime, welches u.a. über die Funktion now.toLocalDateTime() kreiert werden kann
    • Items vom Typ DateTime speichern scheinbar als LocalDateTime - hier muss also beim Lesen und Schreiben auf eine Konvertierung geachtet werden.
    • Die Umwandlung von ZonedDateTime in LocalDateTime erfolgt bspw. über now.toLocalDateTime()
    • Die Umwandlung von LocalDateTime in ZonedDateTime erfolgt bspw. über varName.getZonedDateTime()

    Lesen und Schreiben von/in Items

    • Lesen: var sunrise = (SunSunrise.state as DateTimeType).getZonedDateTime()
    • Schreiben: ShellyPumpStarted.sendCommand(pumpStarted.toLocalDateTime().toString)

    Rechnen mit Zeiten/Datum

    Häufig musst Du in Regeln bestimmte Zeitpunkte ausrechnen, oder Zeiten addieren/subtrahieren:

    • Heute Mittag (heute 12:30): var nextNoon = now.with(LocalTime.MIDNIGHT).plusHours(12).plusMinutes(30)
    • 5 später: var in5min = now.plusMinutes(5)
    • 5min vor Mitternacht: var fiveMinBeforeMidnight = now.addDays(1).with(LocalTime.MIDNIGHT).minusMinutes(5)

    Vergleich

    Manchmal musst Du herausfinden, ob eine Zeit vor oder nach einem anderen Zeitpunkt liegt:

    • Jetzt ist vor "Heute Mittag": now.isAfter(nextNoon)
    • Jetzt ist nach "Heute Mittag": now.isBefore(nextNoon)

    Formatierte Ausgabe der Zeit/Datum

    Früher habe ich dies einfach mit toString gemacht, aber das liefert heute Fehlermeldungen. So geht es:

    • Am Anfang der Regeldatei folgenden Import durchführen: import java.time.format.DateTimeFormatter
    • Dann kannst Du Variablen vom Typ ZonedDateTime wie folgt formatieren: nextNoon.format(DateTimeFormatter.ofPattern("HH:mm")

    Timer

    Timer sind manchmal kompliziert, aber folgende einfache Regeln helfen mir ungemein:

    • createTimer und reschedule wollen den Datentyp ZonedDateTime haben
    • Um einen Timer in verschiedenen Regeln innerhalb einer Datei nutzen zu können, musst Du im am Dateianfang, unter den Importen deklarieren: var Timer myTimer = null
    • Prüfen, ob ein Timer aktiv ist: if (myTimer !== null) {...}
    • Prüfen, ob ein Timer noch läuft: if (myTimer !== null && !myTimer.hasTerminated()) {...}
    • Timer starten: myTimer = createTimer(now.plusMinutes(5), [ | //Do something... ])
    • Timer neu starten: myTimer.reschedule(now.plusMinutes(5))
    • Timer abbrechen: myTimer?.cancel() und in neuer Zeile myTimer = null

    Lektion

    Eigentlich ist die Umstellung gar nicht soooo kompliziert, wenn man weiß, was wie geändert werden muss - das herauszufinden hat mich allerdings einige Zeit gekostet.

    ...so, das war es fürs erste. Ich habe hoffentlich keine groben Fehler eingebaut und vielleicht hilft es jemanden :) :vulcan:


    Weitere Lektionen folgen bestimmt...

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!