Wecker mit verschiedenen Einstellungen triggert nicht korrekt

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
MrCrashy
Beiträge: 113
Registriert: 2. Jan 2021 09:53
Answers: 0

Wecker mit verschiedenen Einstellungen triggert nicht korrekt

Beitrag von MrCrashy »

Hallo,
Ich habe meine openHAB - App mit meinem Wecker verbunden um das Licht in der Küche beim aufstehen einzuschalten, wenn es draußen noch dunkel ist. Das funktioniert auch zuverlässig.
Nun wollte ich ein paar Variablen einbauen, um z.B. Das Licht im "Manuellen Modus" nach 30, 60 oder 90 Minuten ausschalten zu können und, falls gewünscht, meine Alexa mit ausgewähltem Radiosender und der ausgewählten Lautstärke einzuschalten.

Ich habe die Rule einmal ausprobiert und Sie hat auch funktioniert. Beim zweiten mal funktionierte diese aber nicht mehr :?:
Laut den Loggs triggert die Rule aber.

Items:
- Radio_Station1: Mein Radiosender als String, da ich in der App mehrere Sender zur Auswahl haben will.
- Kitchen_Duration1: Die Dauer meiner Beleuchtung in der Küche.
- Radio_Volume1: Die Lautstärke der Alexa.

Mir ist eine Sache jedoch vorab schon aufgefallen:
Mein VSC zweigt mir hier folgenden Fehler an:

Code: Alles auswählen

Cannot refer to the non-final variable strRS inside a lambda expression

Code: Alles auswählen

Echo_Living_Room_RadioStationId.sendCommand(strRS)
Das hier ist meine eigentliche Rule:

Code: Alles auswählen

rule "Wecker Elias"
when 
    Item AlarmElias changed 
then 
    val String strRS = Radio_Station1.state.toString
    val Integer sd = (Kitchen_Duration1.state as DecimalType).intValue
    val vm = (Radio_Volume1.state as DecimalType).intValue
    if(newState instanceof DateTimeType){
        sendNotification("mail", "Wecker: Weckzeit gesetzt.")
        if(timerAlarmElias !== null){
            sendNotification("mail", "Wecker: Neue Weckzeit gestezt.")
            timerAlarmElias.reschedule(newState.toLocaleZone.zonedDateTime)
        } else {
            sendNotification("mail", "Wecker: Neuer Alarm.")
            timerAlarmElias = createTimer(newState.toLocaleZone.zonedDateTime, [|
                if(KitchenLight_On1.state == ON && Night.state == ON){
                    HUE_Kitchen_Spotlight1.sendCommand(ON)
                } else if(KitchenLight_On1.state == OFF) {
                    HUE_Kitchen_Spotlight1.sendCommand(ON)
                    tKitchenAutoOff1 = createTimer(now.plusMinutes(sd), [|
                        HUE_Kitchen_Spotlight1.sendCommand(OFF)
                    ])
                }
                if(Radio_On1.state == ON){
                    Echo_Living_Room_Radio.sendCommand(ON)
                    Echo_Living_Room_RadioStationId.sendCommand(strRS)
                    Echo_Living_Room_Volume.sendCommand(vm)
                }   
                timerAlarmElias = null
            ])
        }
    } else {
        if(timerAlarmElias !== null){
            timerAlarmElias.cancel
            timerAlarmElias = null
        }
    }
end 
Ich verstehe nicht ganz, warum beim ersten mal die Rule funktioniert hat. Beim zweiten mal jedoch nicht.
Hat jemand sowas in der Art schonmal gemacht oder weiß welchen Fehler ich gemacht habe?

MFG
Elias

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

Re: Wecker mit verschiedenen Einstellungen triggert nicht korrekt

Beitrag von udo1toni »

Die Rule wird auch beim ersten Mal nicht funktioniert haben :)

Die Fehlermeldung bedeutet, dass die Konstante strRS innerhalb des Codes, der vom Timer ausgeführt wird, nicht bekannt ist.
Das erschließt sich auch,wenn man über den Code nachdenkt. strRS wird in der Rule definiert. In der Rule wird auch der Timer angelegt, aber der Timer ist unabhängig von der Rule. Die Rule wird beendet, wenn der Timer den Code ausführt, existiert die Variable nicht (und selbst wenn, befindet sie sich nicht im Kontext des Timer Codes).
Das Gleiche gilt sinngemäß auch für die anderen Konstanten vm und sd.
Da alle drei Konstanten nur einmal genutzt werden, nämlich innerhalb des Timers, könntest Du einfach die Definition ins Lambda verschieben (der Timer Code Block zwischen [| und ]) und dieses Problem sollte gelöst sein.
openHAB4.3.6 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

MrCrashy
Beiträge: 113
Registriert: 2. Jan 2021 09:53
Answers: 0

Re: Wecker mit verschiedenen Einstellungen triggert nicht korrekt

Beitrag von MrCrashy »

Ok, so wie du das beschreibst macht es natürlich Sinn. Ich bin immer davon ausgegangen, dass die var/val oben stehen müssen. Dass die Rule aber mit einem Timer startet, da habe ich nicht drüber Nachgedacht.

Ich habe das mal Rasch geändert und am Ende der Rule eine LogInfo gesetzt. Trotzdem wird die Rule nicht ausgeführt.
Müsste aber nicht wenigstens die LogInfo ausgeführt werden?

Die Rule sieht jetzt so aus:

Code: Alles auswählen

rule "Wecker Elias"
when 
    Item AlarmElias changed 
then 
    if(newState instanceof DateTimeType){
        sendNotification("mail", "Wecker: Weckzeit gesetzt.")
        if(timerAlarmElias !== null){
            sendNotification("mail", "Wecker: Neue Weckzeit gestezt.")
            timerAlarmElias.reschedule(newState.toLocaleZone.zonedDateTime)
        } else {
            sendNotification("mail", "Wecker: Neuer Alarm.")
            timerAlarmElias = createTimer(newState.toLocaleZone.zonedDateTime, [|
                val String strRS = Radio_Station1.state.toString
                val Integer sd = (Kitchen_Duration1.state as DecimalType).intValue
                val vm = (Radio_Volume1.state as DecimalType).intValue
                if(Radio_On1.state == ON){
                    Echo_Living_Room_Radio.sendCommand(ON)
                    Echo_Living_Room_RadioStationId.sendCommand(strRS)
                    Echo_Living_Room_Volume.sendCommand(vm)
                } 
                if(KitchenLight_On1.state == ON){
                    if(Night.state == ON){
                        HUE_Kitchen_Spotlight1.sendCommand(ON)
                    } else {
                        HUE_Kitchen_Spotlight1.sendCommand(OFF)
                    }
                } else {
                    HUE_Kitchen_Spotlight1.sendCommand(ON)
                    tKitchenAutoOff1 = createTimer(now.plusMinutes(sd), [|
                        HUE_Kitchen_Spotlight1.sendCommand(OFF)
                    ])
                }
                logInfo("Wecker", "Wecker ist an!")
                timerAlarmElias = null
            ])
        }
    } else {
        if(timerAlarmElias !== null){
            timerAlarmElias.cancel
            timerAlarmElias = null
        }
    }
end 

Antworten