Einfache Rule-Frage vom Anfänger

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Hoggle
Beiträge: 221
Registriert: 16. Dez 2017 10:49
Answers: 0

Einfache Rule-Frage vom Anfänger

Beitrag von Hoggle »

Hallo.
Was ist an der Definition falsch?

Code: Alles auswählen

var Lux_Mittel_var = ((LSSuedLux.state.floatValue + LSWestLux.state.floatvalue)) / 2//durchschnittlicher Lichtwert der beiden Lichtsensoren
    LUX_Mittel.postUpdate(Lux_Mittel_var)  
LSSuedLux+LSWestLux sind 2 Homematic-Lichtsensoren

Code: Alles auswählen

Number:Illuminance   LSWestLux         "Sonnensensor West"                            (gGarage, gWetterSensor)         ["Sensor"]   {channel="homematic:HmIP-SLO..."}

Number:Illuminance   LSSuedLux         "Sonnensensor Süd"                             (gTerrasse, gWetterSensor)         ["Sensor"] {channel="homematic:HM-Sen-LI-O"}
Fehlermeldung im frontail:

Code: Alles auswählen

2023-10-31 13:48:05.509 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Dummysfuellen-1' failed: 'floatValue' is not a member of 'org.openhab.core.types.State'; line 12, column 24, length 26 in Dummysfuellen
Okay, floatValue scheint das Problem zu sein, aber was ist zu tun?
Ich möchte eigentlich nur den Mittelwert der beiden Sensoren in einem Item (LUX_Mittel) abspeichern und in verschiedenen Rules weiter nutzen.

Code: Alles auswählen

 Number   LUX_Mittel                    "Durchschnittshelligkeit [%.2f LUX]"        (gDummy)
   
RPI4/8GB RAM mit openhabian (bullseye) - Kernel Linux 6.1.21-v8+ - openhab 4.0.2 - Release Build - HM-CCU3 - ZWave UZB-USB Stick - Wifi-LED-Stripes - Logitech Harmony Hub - AVM Fritzbox - Enigma2-Box - Gardena HUB - Fronius-Binding - Miele@Home

mad-mike
Beiträge: 491
Registriert: 6. Jan 2021 18:05
Answers: 3

Re: Einfache Rule-Frage vom Anfänger

Beitrag von mad-mike »

Moin,

Ich als Laie meine das die Klammer an falscher Position ist.

Code: Alles auswählen

var Lux_Mittel_var = ((LSSuedLux.state).floatValue + (LSWestLux.state).floatValue) / 2  //durchschnittlicher Lichtwert der beiden Lichtsensoren
:?:
Gruss mad-mike

openHABian 4.3.5 auf Raspberry Pi 4 Mod. b (8GB) ;)

Hoggle
Beiträge: 221
Registriert: 16. Dez 2017 10:49
Answers: 0

Re: Einfache Rule-Frage vom Anfänger

Beitrag von Hoggle »

Nach deinem Tip wie folgt geändert:

Code: Alles auswählen

 var Lux_Mittel_var = ((LSSuedLux.state).floatValue + (LSWestLux.state).floatvalue) / 2//durchschnittlicher Lichtwert der beiden Lichtsensoren
kommt folgende Meldung:

Code: Alles auswählen

2023-10-31 15:30:49.953 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'Dummysfuellen.rules', using it anyway:
The value of the local variable Lux_Mittel_var is not used
Was soll das bedeuten? Sagt Openhab wirklich nur, das die Variable nirgends benutzt wird?

Upps, da kommt doch ein Fehler:

Code: Alles auswählen

2023-10-31 15:34:47.668 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Dummysfuellen-1' failed: 'floatValue' is not a member of 'org.openhab.core.types.State'; line 12, column 24, length 28 in Dummysfuellen
Mit was muß ich das/den floatValue tauschen?
RPI4/8GB RAM mit openhabian (bullseye) - Kernel Linux 6.1.21-v8+ - openhab 4.0.2 - Release Build - HM-CCU3 - ZWave UZB-USB Stick - Wifi-LED-Stripes - Logitech Harmony Hub - AVM Fritzbox - Enigma2-Box - Gardena HUB - Fronius-Binding - Miele@Home

mad-mike
Beiträge: 491
Registriert: 6. Jan 2021 18:05
Answers: 3

Re: Einfache Rule-Frage vom Anfänger

Beitrag von mad-mike »

Code: Alles auswählen

 var Lux_Mittel_var = ((LSSuedLux.state as Number).floatValue + (LSWestLux.state as Number).floatvalue) / 2//durchschnittlicher Lichtwert der beiden Lichtsensoren
     LUX_Mittel.postUpdate(Lux_Mittel_var)  
:arrow:
Gruss mad-mike

openHABian 4.3.5 auf Raspberry Pi 4 Mod. b (8GB) ;)

Hoggle
Beiträge: 221
Registriert: 16. Dez 2017 10:49
Answers: 0

Re: Einfache Rule-Frage vom Anfänger

Beitrag von Hoggle »

Mhh, es scheint wirklich ein Problem mit dem "floatValue zu sein:

Code: Alles auswählen

2023-10-31 15:58:17.683 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'Dummysfuellen-1' failed: 'floatvalue' is not a member of 'java.lang.Number'; line 12, column 65, length 38 in Dummysfuellen
Und schwupps, einfach mal gelöscht und schon hat das Item einen Wert :D

Code: Alles auswählen

var Lux_Mittel_var = ((LSSuedLux.state as Number) + (LSWestLux.state as Number)) / 2//durchschnittlicher Lichtwert der beiden Lichtsensoren
     LUX_Mittel.postUpdate(Lux_Mittel_var)  

Code: Alles auswählen

2023-10-31 16:00:33.685 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'LUX_Mittel' changed from 5672.42500000 to 6149.07500000
RPI4/8GB RAM mit openhabian (bullseye) - Kernel Linux 6.1.21-v8+ - openhab 4.0.2 - Release Build - HM-CCU3 - ZWave UZB-USB Stick - Wifi-LED-Stripes - Logitech Harmony Hub - AVM Fritzbox - Enigma2-Box - Gardena HUB - Fronius-Binding - Miele@Home

mad-mike
Beiträge: 491
Registriert: 6. Jan 2021 18:05
Answers: 3

Re: Einfache Rule-Frage vom Anfänger

Beitrag von mad-mike »

Bei deiner Rule ist das ""V"" Klein geschrieben...
floatvalue
Ich meine das man mit dem :

Code: Alles auswählen

floatValue
die UoM weg bekommt, um mit den nackten Wert eines Item zu arbeiten in einer Rule.

hat bei mir aber noch nie ein Problem gemacht, dieses zu setzen, wenn auch kein UoM mit geliefert wird.


Aber dazu kann bestimmt jemand anders noch war ergänzen. :oops:
Gruss mad-mike

openHABian 4.3.5 auf Raspberry Pi 4 Mod. b (8GB) ;)

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

Re: Einfache Rule-Frage vom Anfänger

Beitrag von udo1toni »

Aaaalso :)

Ein Item hat verschiedene Eigenschaften. Eine der Eigenschaften ist .state. Wie der Name schon sagt, handelt es sich dabei um den Status des Items.
Achtung! Ein Status ist ein Status, nichts anderes.
openHAB ist an vielen Stellen sehr gnädig und konvertiert stillschweigend den Status in ein passendes Format, z.B. wenn man den Status in einen String einbaut. In Wirklichkeit wird aber nicht der Status eingebaut, sondern openHAB ergänzt die Methode .toString, um aus .state eben einen String zu zaubern.

Wenn Du einen Status hast, der eine Zahl enthält (z.B. ein Number Item Status) wird openHAB ebenfalls automatisch Konvertierungen ausführen, z.B. wenn Du in einer Bedingung den Status einfach mit einer Zahl vergleichst.

Du rufst allerdings eine Methode .floatValue auf. .state hat keine Methode .floatValue.

Um also die Methode .floatValue anwenden zu können, brauchst Du ein Objekt, welches diese Methode kennt, das wäre z.B. Number. Du musst also zunächst den Status in ein Objekt Number überführen, das geht am einfachstem mit dem Type casting .state as Number

Aber Achtung, beim Type casting wird der Wert ohne Rücksicht auf Verluste dem neuen Objekt zugewiesen. Wenn der Wert nicht zum neuen Objekttyp passt, kommt es zu einer NullPointer Exception. Du tust also gut daran, zunächst zu prüfen, ob der Status tatsächlich einen Wert vom Typ Number enthält.
Number Objekte kennen die Methode .floatValue, weshalb man anschließend eine Fließkommazahl hat.
Oftmals ist das Type Casting nicht unbedingt nötig, hier aber schon, denn nehmen wir an, Du hast zwei Status, 1.2 und 3.4. Wie gesagt handelt es sich um Status, nicht um Zahlen (auch wenn es sich um Status zweier Number Items handelt). Nun kommst Du mit dem Operator + um die beiden Status zu addieren, aber wie soll openHAB die beiden Status addieren? Soll es jeweils .state.toString ausführen und anschließend einen String 1.23.4 abliefern, oder soll es die Status als Zahl interpretieren?
Es kann z.B. ausreichen, einen weiteren Wert zu addieren, also 0.0 + status1 + status2 (oder vielleicht muss die 0.0 auch als letztes addiert werden?), durch das Objekt 0.0 wird die Berechnung als Float Wert erzwungen.
Sauber ist das aber nicht, und vor allem wird man sich vermutlich nach ein paar Monaten oder gar Jahren nicht mehr daran erinnern, die 0.0 weg löschen und sich anschließend wundern, warum die Rule nicht mehr funktioniert.

Deshalb lieber sauber arbeiten:

Code: Alles auswählen

val lxSued = if(LSSuedLux.state instanceof Number) (LSSuedLux.state as Number).floatValue else -1
val lxWest = if(LSWestLux.state instanceof Number) (LSWestLux.state as Number).floatValue else -1

var lxAvg  = 0.0
var count = 0

if(lxSued > 0) {
    count += 1
    lxAvg  += lxSued
}
if(lxWest > 0) {
    count += 1
    lxAvg  += lxWest
}
if(count > 1)
    lxAvg = lxAvg / count

LUX_Mittel.postUpdate(lxAvg)
Huch...
Zunächst werden beide Items ausgelesen. Falls ihr Status einem NumberType entpricht, wird der Wert als Number interpretiert und als Floatwert in die lokale Konstante übernommen, ansonsten wird dort -1 hineingeschrieben.
Nun werden zwei lokale Variablen definiert, lxAvg (Float) und count (Integer).
Wenn lxSued größer als 0 ist, wird es zu lxAvg addiert und count um eins erhöht. Das gleiche passiert anschließend für lxWest.
Abschließend wird lxAvg durch count geteilt, falls count größer als 1 ist.

In der Folge steht in lxAvg entweder 0, der Wert aus lxSued, der Wert aus lxWest oder das Mittel aus beiden Werten, je nachdem, ob keines der Items, eines der Items oder beide Items einen gültigen Wert liefern.
Natürlich kannst Du auch darauf vertrauen, dass die Sensoren immer einen gültigen Wert liefern und entsprechend einfach

Code: Alles auswählen

LUX_Mittel.postUpdate(((LSSuedLux.state as Number).floatValue + (LSWestLux.state as Number).floatValue)/2)
schreiben, aber das kann halt schnell mal schief gehen.

Der Code ist ungetestet :) aber das wäre mein Ansatz dazu...
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten