Status eines ITEM speichern und wiederherstellen

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

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

Re: Status eines ITEM speichern und wiederherstellen

Beitrag von udo1toni »

Und nicht vergessen, everyMinute als Strategy zu definieren.

Es gibt noch eine weitere Möglichkeit, nämlich in Klammern ein true mit dazu schreiben:

Code: Alles auswählen

Wohnzimmer_Rollo2_Level.previousState(true).state
Das erzwingt den letzten Status, der vom aktuellen Status abweicht.

Weiterhin gäbe es noch die Möglichkeit, sich zu merken, wann der Fernseher eingeschaltet wurde (z.B. mittels Persistence) und gezielt den Status aufzurufen, der zu diesem Zeitpunkt aktiv war:

Code: Alles auswählen

Wohnzimmer_Rollo2_Level.historicState(Fernseher.previousState(true).timestamp).state
Voraussetzung ist dann allerdings, dass sich der Status des Fernsehers noch nicht geändert hat. Im Zweifel ist es in diesem Fall also besser, den Zeitpunkt des Einschaltens in einem eigenen Item zu speichern,
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

domjo75
Beiträge: 159
Registriert: 22. Jan 2019 11:10
Answers: 0

Re: Status eines ITEM speichern und wiederherstellen

Beitrag von domjo75 »

peter-pan hat geschrieben: 21. Jan 2022 15:17 Wie sieht denn deine Regel aus ?

Code: Alles auswählen

rule "Rollo 2 WZ @ TV an"
when
    Item SonyBraviaKD55X8005C_PowerStatus changed from OFF to ON
then

    logInfo("Rollo 2 WZ @ TV an", "TV {} Rollo2-Level = {}% Helligkeit = {} isNight = {}", SonyBraviaKD55X8005C_PowerStatus.state, Wohnzimmer_Rollo2_Level.state , Hueoutdoorlightsensor2_Illuminance.state, isNight.state)

    if(SonyBraviaKD55X8005C_PowerStatus.state == ON && Wohnzimmer_Rollo2_Level.state <= 75 && Hueoutdoorlightsensor2_Illuminance.state as Number >= 4500) {
        //if(SonyBraviaKD55X8005C_PowerStatus.state == ON && Wohnzimmer_Rollo2_Level.state <= 75 && Hueoutdoorlightsensor2_Illuminance.state >= 4500|lx)
        Wohnzimmer_Rollo2_LastLevel.sendCommand(Wohnzimmer_Rollo2_Level.state)
        Wohnzimmer_Rollo2_Level.sendCommand(tPosALL)
        logInfo("Rollo 2 WZ @ TV an", "TV {} Rollo2 Wohnzimmer auf Beschattung ({}%)", SonyBraviaKD55X8005C_PowerStatus.state, tPosALL)
    }
    if(SonyBraviaKD55X8005C_PowerStatus.state == ON && Wohnzimmer_Rollo2_Level.state <= 75 && isNight.state == OFF ) {
        Wohnzimmer_Rollo2_LastLevel.sendCommand(Wohnzimmer_Rollo2_Level.state)
        Wohnzimmer_Rollo2_Level.sendCommand(tPosALL)
        logInfo("Rollo 2 WZ @ TV an", "TV {} Rollo2 Wohnzimmer auf Beschattung ({}%)", SonyBraviaKD55X8005C_PowerStatus.state, tPosALL)
        logInfo("Rollo 2 WZ @ TV an", "Wohnzimmer_Rollo2_Level letzter Status: {}", Wohnzimmer_Rollo2_Level.previousState.state)
    }
end

rule "Rollo 2 WZ @ TV aus"
when
    Item SonyBraviaKD55X8005C_PowerStatus changed from ON to OFF
then
    logInfo("Rollo 2 WZ @ TV aus", "TV {} Rollo2-Level = {}% Rollo2-LastLevel = {}% Rollo2-previousState = {}%", SonyBraviaKD55X8005C_PowerStatus.state, Wohnzimmer_Rollo2_Level.state , Wohnzimmer_Rollo2_LastLevel.state, Wohnzimmer_Rollo2_Level.previousState.state)
    logInfo("Rollo 2 WZ @ TV aus", "TV {} Rollo2 Wohnzimmer zurück auf {}%", SonyBraviaKD55X8005C_PowerStatus.state, Wohnzimmer_Rollo2_LastLevel.state)
    Wohnzimmer_Rollo2_Level.sendCommand(Wohnzimmer_Rollo2_LastLevel.state)
    //Wohnzimmer_Rollo2_Level.sendCommand(Wohnzimmer_Rollo2_Level.previousState.state)
end
Das ist die komplette Rule die das Fenster beschattet, sobald der Fernseher an geht und wieder auf den letzten Stand bringt, wenn der TV wieder OFF geht.
Zur Zeit noch mit einem LastLevel HilfsItem, viel Loggin und Prüfung auf isNight = OFF ( wird dann später ON )

Code: Alles auswählen

2022-01-22 12:37:33.898 [INFO ] [core.model.script.Rollo 2 WZ @ TV an] - TV ON Rollo2-Level = 50% Helligkeit = 1759.9486638014696 lx isNight = OFF
2022-01-22 12:37:33.904 [INFO ] [core.model.script.Rollo 2 WZ @ TV an] - TV ON Rollo2 Wohnzimmer auf Beschattung (82%)
2022-01-22 12:37:33.910 [INFO ] [core.model.script.Rollo 2 WZ @ TV an] - Wohnzimmer_Rollo2_Level letzter Status: 50
2022-01-22 12:38:03.842 [INFO ] [ore.model.script.Rollo 2 WZ @ TV aus] - TV OFF Rollo2-Level = 82% Rollo2-LastLevel = 50% Rollo2-previousState = 82%
2022-01-22 12:38:03.844 [INFO ] [ore.model.script.Rollo 2 WZ @ TV aus] - TV OFF Rollo2 Wohnzimmer zurück auf 50%
2022-01-22 12:39:03.821 [INFO ] [core.model.script.Rollo 2 WZ @ TV an] - TV ON Rollo2-Level = 0% Helligkeit = 1588.1810142998268 lx isNight = OFF
2022-01-22 12:39:03.827 [INFO ] [core.model.script.Rollo 2 WZ @ TV an] - TV ON Rollo2 Wohnzimmer auf Beschattung (82%)
2022-01-22 12:39:03.829 [INFO ] [core.model.script.Rollo 2 WZ @ TV an] - Wohnzimmer_Rollo2_Level letzter Status: 0
2022-01-22 12:39:33.832 [INFO ] [ore.model.script.Rollo 2 WZ @ TV aus] - TV OFF Rollo2-Level = 82% Rollo2-LastLevel = 0% Rollo2-previousState = 82%
2022-01-22 12:39:33.834 [INFO ] [ore.model.script.Rollo 2 WZ @ TV aus] - TV OFF Rollo2 Wohnzimmer zurück auf 0%
Man sieht hier schön, dass previousState immer den Status vom letzten Change annimmt.

Code: Alles auswählen

2022-01-22 12:37:33.910 [INFO ] [core.model.script.Rollo 2 WZ @ TV an] - Wohnzimmer_Rollo2_Level letzter Status: 50 <-- das ist previoiusState
2022-01-22 12:38:03.842 [INFO ] [ore.model.script.Rollo 2 WZ @ TV aus] - TV OFF Rollo2-Level = 82% Rollo2-LastLevel = 50% Rollo2-previousState = 82%
Das Script funktioniert jetzt so wie gewünscht. Ich würde es aber toll finden, wenn ich auf mein LastLevel Item verzichten könnte und gegebene Mechanismen nutzen könnte. Ausserdem lerne ich wieder was dazu :)
EveryMinute habe ich eingebaut.
Übrigens, kann ich die beiden IF´s in der ON-Rule nicht irgendwie OR verknüpfen??

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

Re: Status eines ITEM speichern und wiederherstellen

Beitrag von udo1toni »

Du nutzt ja schon &&, das Gegenstück dazu ist ||.

Code: Alles auswählen

if(a && b) -> a UND b müssen true sein
if(a || b) -> a ODER b muss true sein
De Abfrage des Powerstatus ist sinnfrei, da die Rule ja dadurch triggert, dass der Status auf ON gewechselt hat.

Hast Du mal

Code: Alles auswählen

Wohnzimmer_Rollo2_Level.previousState(true).state
ausprobiert? Das liefert den letzten Status, der vom aktuellen Status abweicht.

Ansonsten sollte eine Rule ausreichen:

Code: Alles auswählen

rule "Rollo 2 WZ @ TV"
when
    Item SonyBraviaKD55X8005C_PowerStatus changed
then
    val swPower = SonyBraviaKD55X8005C_PowerStatus.state // alternativ: val swPower = newState
    val nLevel2 = Wohnzimmer_Rollo2_Level.state
    val nIllu   = Hueoutdoorlightsensor2_Illuminance.state

    if(swPower == ON) {
        logInfo("rollo2wz_tv", "TV {} Rollo2-Level = {}% Helligkeit = {} isNight = {}", swPower, nLevel2 , nIllu, isNight.state)
        if(nLevel2 <= 75) {
            if(isNight.state == OFF || nIllu >= 4500) {
                Wohnzimmer_Rollo2_Level.sendCommand(tPosALL)
                logInfo("rollo2wz_tv", "TV {} Rollo2 Wohnzimmer auf Beschattung ({}%)", swPower, tPosALL)
                logInfo("rollo2wz_tv", "Wohnzimmer_Rollo2_Level letzter Status: {}", Wohnzimmer_Rollo2_Level.previousState(true).state)
            }
        }
    } else if(newState == OFF) {
        logInfo("rollo2wz_tv", "TV {} Rollo2-Level = {}% Rollo2-previousState = {}%", swPower, nLevel2, Wohnzimmer_Rollo2_Level.previousState(true).state)
        Wohnzimmer_Rollo2_Level.sendCommand(Wohnzimmer_Rollo2_Level.previousState(true).state)
    }
end
Die lokalen Konstanten hier nur, um ein wenig der langen Namen Herr zu werden...

Fährt tatsächlich nur der eine Laden? Oder hast Du am Ende mehrere Rules, die auf SonyBraviaKD55X8005C_PowerStatus changed triggern?
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

domjo75
Beiträge: 159
Registriert: 22. Jan 2019 11:10
Answers: 0

Re: Status eines ITEM speichern und wiederherstellen

Beitrag von domjo75 »

udo1toni hat geschrieben: 22. Jan 2022 14:19 Du nutzt ja schon &&, das Gegenstück dazu ist ||.
ich meine das so in der Art.
if(SonyBraviaKD55X8005C_PowerStatus.state == ON && Wohnzimmer_Rollo2_Level.state <= 75 && (Hueoutdoorlightsensor2_Illuminance.state as Number >= 4500 || isNight == ON))

De Abfrage des Powerstatus ist sinnfrei, da die Rule ja dadurch triggert, dass der Status auf ON gewechselt hat.
Wir haben mal eine WindowsHandler Rule gebaut, die meine Fenster auf TILT setzt, wenn der jeweilige Sensor geöffnet wird. Sobald ein Sensor der Triggergruppe auslöst durchläuft er die ganze Rule. Ist dann ein Fenster auf der Tilt-Position und der Sensor ist CLOSED, fährt er den Rollo runter, obwohl der Sensor gar nicht getriggert hat. Die Bedingung ist TRUE daher reagiert er richtig.
Um das zu verhindern biege ich in der Rule über if(triggeringItem.name == "WohnzimmerT_Terrassentuer1_State"... ab
Das habe ich einfach nur kopiert. Ist nicht so optimal, stimmt.
Hast Du mal

Code: Alles auswählen

Wohnzimmer_Rollo2_Level.previousState(true).state
ausprobiert? Das liefert den letzten Status, der vom aktuellen Status abweicht.
Ich hab´s mal eingebaut. Montag schau ich mal ins LOG
Ansonsten sollte eine Rule ausreichen:

Code: Alles auswählen

rule "Rollo 2 WZ @ TV"
when
    Item SonyBraviaKD55X8005C_PowerStatus changed
then
    val swPower = SonyBraviaKD55X8005C_PowerStatus.state // alternativ: val swPower = newState
    ...
    } else if(newState == OFF) {
    
Die lokalen Konstanten hier nur, um ein wenig der langen Namen Herr zu werden...
wo wird denn NEWSATE gesetzt? Das verstehe ich nicht
Fährt tatsächlich nur der eine Laden? Oder hast Du am Ende mehrere Rules, die auf SonyBraviaKD55X8005C_PowerStatus changed triggern?
Ja, wenn der Rollo auf ist, blendet die Sonne im Fernseher bzw die Nachbarn glotzen im Dunkeln mit

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

Re: Status eines ITEM speichern und wiederherstellen

Beitrag von udo1toni »

domjo75 hat geschrieben: 22. Jan 2022 21:21 wo wird denn NEWSATE gesetzt? Das verstehe ich nicht
newState, nicht NEWSATE. In openHAB ist jedes einzelnen Zeichen exakt wie angegeben zu schreiben ;).
Die Rule wird durch den Trigger changed ausgelöst, damit steht die implizite Variable newState zur Verfügung (ebenso wie die implizite Variable previousState, nicht zu verwechseln mit Item.perviousState, was nur zur Verfügung steht, wenn das Item persistiert wird.
domjo75 hat geschrieben: 22. Jan 2022 21:21 Ja, wenn der Rollo auf ist, blendet die Sonne im Fernseher bzw die Nachbarn glotzen im Dunkeln mit
Das kenne ich, aber bei uns sind es sieben Fenster und es ist natürlich sonnenstandsabhängig, welches der Fenster stört :) Aber die Nachbarn können nicht mit gucken, der Winkel ist dafür zu ungünstig :lol:
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

domjo75
Beiträge: 159
Registriert: 22. Jan 2019 11:10
Answers: 0

Re: Status eines ITEM speichern und wiederherstellen

Beitrag von domjo75 »

udo1toni hat geschrieben: 22. Jan 2022 23:25 Die Rule wird durch den Trigger changed ausgelöst, damit steht die implizite Variable newState zur Verfügung (ebenso wie die implizite Variable previousState, nicht zu verwechseln mit Item.perviousState, was nur zur Verfügung steht, wenn das Item persistiert wird.
Ahh ok... ich verstehe. Das muss man halt wissen :D

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

Re: Status eines ITEM speichern und wiederherstellen

Beitrag von udo1toni »

Steht alles in der offiziellen Doku... ;)
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

domjo75
Beiträge: 159
Registriert: 22. Jan 2019 11:10
Answers: 0

Re: Status eines ITEM speichern und wiederherstellen

Beitrag von domjo75 »

Hast Du mal

Code: Alles auswählen

Wohnzimmer_Rollo2_Level.previousState(true).state
ausprobiert? Das liefert den letzten Status, der vom aktuellen Status abweicht.
Das mag er nicht so:

Code: Alles auswählen

2022-01-23 18:48:13.871 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'HandleWindowCovers-3' failed: rrd4j does not allow querys without a begin date, unless order is descending and a single value is requested in HandleWindowCovers

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

Re: Status eines ITEM speichern und wiederherstellen

Beitrag von udo1toni »

Das ist eine eher ungewöhnliche Fehlermeldung :)
Kann es sein, dass nicht mit everyChange, everyMinute persistiert wird?
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

domjo75
Beiträge: 159
Registriert: 22. Jan 2019 11:10
Answers: 0

Re: Status eines ITEM speichern und wiederherstellen

Beitrag von domjo75 »

sorry, ich konnte heute erst weiter machen.

Meine rrd4j.persist sieht so aus:

Code: Alles auswählen

Strategies {
        everyHour : "0 0 * * * ?"
        everyDay  : "0 0 0 * * ?"
        everyMinute : "0 * * * * ?"

        // if no strategy is specified for an Item entry below, the default list will be used
       default = everyChange
}

Items {
        // persist the Item state of Heating_Mode and Notifications_Active on every change and restore them from the db at startup
        Wohnzimmer_Rollo2_Level: strategy = everyChange, everyMinute, restoreOnStartup
        Sideboard_Helligkeit: strategy = everyChange, everyMinute, restoreOnStartup
        Stehlampe_Essecke: strategy = everyChange, everyMinute, restoreOnStartup
        // additionally, persist all temperature and weather values every hour
        // Temperature*, Weather* : strategy = everyHour
}

Antworten