OH3: DSL Rules - Timer

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
DavGre
Beiträge: 84
Registriert: 11. Mär 2019 15:47
Answers: 0

OH3: DSL Rules - Timer

Beitrag von DavGre »

Hallo,

ich bin gerade dabei, die ersten Schritte in OH3 zu machen. Ich habe bereits ein umfangreiches OH 2.5 System am laufen und will nun Stück für Stück umziehen.

Die folgende Rule macht mir aktuell Probleme:

Code: Alles auswählen

var Timer AlarmTimerBriefkasten = null
  

if(Anwesenheitskontrolle.state == ON && Nachtmodus.state == OFF) {
        Echo_WZ_PlayAlarmSound.sendCommand('ECHO:system_alerts_melodic_03')
            if (AlarmTimerBriefkasten === null) {
                AlarmTimerBriefkasten = createTimer(now.plusSeconds(8)) [|
                AlarmTimerBriefkasten.cancel()
                AlarmTimerBriefkasten = null
                Echo_WZ_PlayAlarmSound.sendCommand('')
                Echo_WZ_TTS_Volume.sendCommand(60)
                Echo_WZ_TTS.sendCommand('<speak>Die Post ist da</speak>')
                Briefkasten_Status.sendCommand(1)
                ]
    }}
    else if(Anwesenheitskontrolle.state != ON || Nachtmodus.state != OFF) {
        Briefkasten_Status.sendCommand(1)
    }
Im Log bekomme ich folgendes angezeigt:

Code: Alles auswählen

   1. Cannot refer to the non-final variable AlarmTimerBriefkasten inside a lambda expression; line 10, column 379, length 21

   2. Cannot refer to the non-final variable AlarmTimerBriefkasten inside a lambda expression; line 11, column 426, length 21
Kann mir jemand helfen?
von udo1toni » 13. Mär 2021 15:25
Du musst die Rule zum Einen weiterhin in einer *.rules Datei anlegen (nur dort stehen globale Variablen zur Verfügung).
Zum Anderen musst Du now durch zonedDateTime.now ersetzen.

Der Befehl AlarmTimerBriefkasten.cancel() ist innerhalb des Timers unsinnig. Das Löschen des Zeigers AlarmTimerBriefkasten = null solltest Du lieber zum Abschluss des Lambda ausführen. Vermutlich wäre es auch sinnvoll, den Befehl Echo_WZ_PlayAlarmSound.sendCommand('ECHO:system_alerts_melodic_03') mit in die Bedingung zu nehmen. So:

Code: Alles auswählen

var Timer AlarmTimerBriefkasten = null

Briefkasten_Status.sendCommand(1)
if(Anwesenheitskontrolle.state == ON && Nachtmodus.state == OFF && AlarmTimerBriefkasten === null) {
    Echo_WZ_PlayAlarmSound.sendCommand('ECHO:system_alerts_melodic_03')
    AlarmTimerBriefkasten = createTimer(zonedDateTime.now.plusSeconds(8), [|
        Echo_WZ_PlayAlarmSound.sendCommand('')
        Echo_WZ_TTS_Volume.sendCommand(60)
        Echo_WZ_TTS.sendCommand('<speak>Die Post ist da</speak>')
        AlarmTimerBriefkasten = null
    ])
}
Die zweite Bedingung ist unnötig, denn es ist das Gegenteil von der ersten Bedingung. Es wird also in beiden Fällen Das Kommando Briefkasten_Status 1 gesendet. Vermutlich sollte das eher ein postUpdate sein, es sei denn, Du verwendest den Befehl 1 über eine Rule oder ein Binding. Ich empfehler immer, das Lambda als Parameter von createTimer anzugeben (also die schließende Klammer erst hinter dem Lambda, dafür ein Komma zwischen dem Wert und dem Lambda)

Die Definition des Timers (var Timer ... ) muss über der ersten Rule in der *.rules Datei erfolgen, aber das weißt Du eh ;)
Gehe zur vollständigen Antwort

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

Re: OH3: DSL Rules - Timer

Beitrag von udo1toni »

Du musst die Rule zum Einen weiterhin in einer *.rules Datei anlegen (nur dort stehen globale Variablen zur Verfügung).
Zum Anderen musst Du now durch zonedDateTime.now ersetzen.

Der Befehl AlarmTimerBriefkasten.cancel() ist innerhalb des Timers unsinnig. Das Löschen des Zeigers AlarmTimerBriefkasten = null solltest Du lieber zum Abschluss des Lambda ausführen. Vermutlich wäre es auch sinnvoll, den Befehl Echo_WZ_PlayAlarmSound.sendCommand('ECHO:system_alerts_melodic_03') mit in die Bedingung zu nehmen. So:

Code: Alles auswählen

var Timer AlarmTimerBriefkasten = null

Briefkasten_Status.sendCommand(1)
if(Anwesenheitskontrolle.state == ON && Nachtmodus.state == OFF && AlarmTimerBriefkasten === null) {
    Echo_WZ_PlayAlarmSound.sendCommand('ECHO:system_alerts_melodic_03')
    AlarmTimerBriefkasten = createTimer(zonedDateTime.now.plusSeconds(8), [|
        Echo_WZ_PlayAlarmSound.sendCommand('')
        Echo_WZ_TTS_Volume.sendCommand(60)
        Echo_WZ_TTS.sendCommand('<speak>Die Post ist da</speak>')
        AlarmTimerBriefkasten = null
    ])
}
Die zweite Bedingung ist unnötig, denn es ist das Gegenteil von der ersten Bedingung. Es wird also in beiden Fällen Das Kommando Briefkasten_Status 1 gesendet. Vermutlich sollte das eher ein postUpdate sein, es sei denn, Du verwendest den Befehl 1 über eine Rule oder ein Binding. Ich empfehler immer, das Lambda als Parameter von createTimer anzugeben (also die schließende Klammer erst hinter dem Lambda, dafür ein Komma zwischen dem Wert und dem Lambda)

Die Definition des Timers (var Timer ... ) muss über der ersten Rule in der *.rules Datei erfolgen, aber das weißt Du eh ;)
openHAB4.3.6 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

Antworten