Arrays in Openhab

Für welche Projekte verwendet Ihr OpenHAB? Was habt Ihr automatisiert? Stellt eure Projekte hier vor.

Moderatoren: Cyrelian, seppy

Antworten
Baumtasche
Beiträge: 82
Registriert: 14. Sep 2020 21:52
Answers: 0

Arrays in Openhab

Beitrag von Baumtasche »

Hallo zusammen,

wie in anderen Programmiersprachen auch, würde ich in Openhab gerne mit Arrays arbeiten. In erster Linie will ich folgenden Code eleganter mit einem Array umsetzten, wobei der Zähler des Arrays, den Monat widerspiegeln soll z.B anstatt ItemOfficeEngery_Jan fände ich es besser ItemOfficeEngery(1), ItemOfficeEngery(2) uaw., dann würde ich mir auch sehr viel Code ersparen. Trotz mehrstündiger Recherche im Internet, habe ich zwar hinweise auf Arrays und Openhab bzw. java erhalten, konnte aber nicht wirklich eine Anleitung oder ein Beispiel finden.

Der Wert von Office_MeterKwh wird stündlich in das jeweilige item Monatsverbrauch geschrieben, die ich mir dann in einer Sitemap anzeigen lasse.
Hat jemand eine Beschreibung für mich zum Thema Array?

Konkret sieht es bei mir aktuell so aus:

Code: Alles auswählen


rule "Berechnung Stromverbrauch - stündlich"

when
    Time cron "0 0 * * * ?"
then 
    
    val currMonth = now.getMonthOfYear
    
    if (currMonth == 1){
        ItemOfficeEngery_Jan.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Jan.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Jan.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Jan.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Jan.postUpdate(Wandschrank_MeterKwh.state)
    }
    if (currMonth == 2){
        ItemOfficeEngery_Feb.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Feb.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Feb.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Feb.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Feb.postUpdate(Wandschrank_MeterKwh.state)
    }
    if (currMonth == 3){
        ItemOfficeEngery_Mar.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Mar.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Mar.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Mar.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Mar.postUpdate(Wandschrank_MeterKwh.state)
    }    
    if (currMonth == 4){
        ItemOfficeEngery_Apr.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Apr.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Apr.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Apr.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Apr.postUpdate(Wandschrank_MeterKwh.state)
    }    
    if (currMonth == 5){
        ItemOfficeEngery_Mai.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Mai.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Mai.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Mai.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Mai.postUpdate(Wandschrank_MeterKwh.state)
    }    
    if (currMonth == 6){
        ItemOfficeEngery_Jun.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Jun.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Jun.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Jun.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Jun.postUpdate(Wandschrank_MeterKwh.state)
    }    
    if (currMonth == 7){
        ItemOfficeEngery_Jul.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Jul.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Jul.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Jul.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Jul.postUpdate(Wandschrank_MeterKwh.state)
    }    
    if (currMonth == 8){
        ItemOfficeEngery_Aug.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Aug.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Aug.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Aug.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Aug.postUpdate(Wandschrank_MeterKwh.state)
    }    
    if (currMonth == 9){
        ItemOfficeEngery_Sep.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Sep.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Sep.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Sep.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Sep.postUpdate(Wandschrank_MeterKwh.state)
    }    
    if (currMonth == 10){
        ItemOfficeEngery_Okt.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Okt.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Okt.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Okt.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Okt.postUpdate(Wandschrank_MeterKwh.state)
    }    
    if (currMonth == 11){
        ItemOfficeEngery_Nov.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Nov.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Nov.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Nov.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Nov.postUpdate(Wandschrank_MeterKwh.state)
    }    
    if (currMonth == 12){
        ItemOfficeEngery_Dez.postUpdate(Office_MeterKwh.state)
        ItemTechnikEngery_Dez.postUpdate(Technikraum_MeterKwh.state)
        ItemLumiEngery_Dez.postUpdate(Lumi_MeterKwh.state)
        ItemLichtkugelEngery_Dez.postUpdate(Lichtkugel_MeterKwh.state)
        ItemWandschrankEngery_Dez.postUpdate(Wandschrank_MeterKwh.state)
    }    
    val nOff01 = ItemOfficeEngery_Jan.state
    val nOff02 = ItemOfficeEngery_Feb.state


end

rule "Monatlicher - Reset Office Stromverbrauch"  

when
        Time cron "10 0 0 1 * ?" // 10 Sekunden nach Mitternacht zum 1. - um die rule zu entzerren
then 
        Office_MeterReset.sendCommand(ON)
        Office_MeterReset.sendCommand(OFF)
        Lumi_MeterReset.sendCommand(ON)
        Lumi_MeterReset.sendCommand(OFF)
        Lichtkugel_MeterReset.sendCommand(ON)
        Lichtkugel_MeterReset.sendCommand(OFF)
        Wandschrank_MeterReset.sendCommand(ON)
        Wandschrank_MeterReset.sendCommand(OFF)
        Technikraum_MeterReset.sendCommand(ON)
        Technikraum_MeterReset.sendCommand(OFF)
end

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

Re: Arrays in Openhab

Beitrag von udo1toni »

Du gehst das etwas ungeschickt an. Das erste wäre mal, die Items anders zu benennen. Es ist nicht sinnvoll, die abgekürzten Monatsnamen zu nehmen. Stattdessen solltest Du den Monat als Zahl verwenden. Das zweite wäre, die Räume ebenfalls mit einem Unterstrich abzusetzen. Das sähe, gut umgesetzt, so aus: (Label und anderes Drumrum habe ich weg gelassen, ebenso wie alle Monate ab März)

Code: Alles auswählen

Group:Number gEnergy
Number Energy_Office_01 (gEnergy)
Number Energy_Lumi_01 (gEnergy)
Number Energy_Technik_01 (gEnergy)
Number Energy_Lichtkugel_01 (gEnergy)
Number Energy_Wandschrank_01 (gEnergy)
Number Energy_Office_02 (gEnergy)
Number Energy_Lumi_02 (gEnergy)
Number Energy_Technik_02 (gEnergy)
Number Energy_Lichtkugel_02 (gEnergy)
Number Energy_Wandschrank_02 (gEnergy)
Das oberste Item der Liste ist ein Group Item. Alle anderen Items kommen in diese Gruppe (also von allen Monaten und allen Quellen). Das Wort "Item" zu Beginn ist unsinnig, es ist ja klar, dass es sich um ein Item handelt...
weiterhin haben wir die Quellitems, welche ebenfalls etwas angepasst werden sollten:

Code: Alles auswählen

Group:Number gMeterKwh
Number MeterKwh_Office (gMeterKwh)
Number MeterKwh_Technik (gMeterKwh)
Number MeterKwh_Lumi (gMeterKwh)
Number MeterKwh_Lichtkugel (gMeterKwh)
Number MeterKwh_Wandschrank (gMeterKwh)
Auch diese Items kommen also in eine (andere) Gruppe. Weiterhin ist darauf zu achten, dass alle korrespondierenden Namensteile jeweils identisch sind (also nicht Technikraum, sondern Technik). Der übergeordnete Name ist Energy bzw. MeterKwh, das ist also jeweils der erste Teil des Itemnamens und gleichzeitig der Gruppenname. Nun reduziert sich die Rule auf folgendes:

Code: Alles auswählen

rule "Berechnung Stromverbrauch - stündlich"
when
    Time cron "0 0 * * * ?"
then 
    gEnergy.members.filter[i|i.name.endsWith(String::format("%02d",now.getMonthOfYear))].forEach[k|
        k.postUpdate(gMeterKwh.members.filter[j|j.name.contains(k.name.split("_").get(1))].head.state)
    ]
end
Die erste Zeile filtert die erste Gruppe auf die Items, welche mit der zweistellig geschriebenen Monatszahl enden.
Diese Gruppe wird durchlaufen (forEach). Dabei wird für jedes der Items jeweils der Buchstabe k verwendet.
Das passiert nun in der zweiten Zeile.
Dem Item wird nun der Wert zugewiesen, welcher aus dem Item stammt, dessen zweiter Namensteil im Namen des aktuellen Items enthalten ist.

Bei jedem Aufruf werden also 5 Items aus der Gruppe gEnergy jeweils die Werte der fünf Items aus der Gruppe gMeterKwh zugewiesen. Welche Items genutzt werden, hängt nur vom aktuellen Monat ab.

Was Deine "Reset-Rule" betrifft, so könntest Du die Reset-Items ebenfalls in eine Gruppe packen und dann einfach diese Gruppe auf ON und OFF setzen. Wobei ich ziemlich sicher bin, dass der OFF-Befehl unnötig ist.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten