Itemnamen aus Variablen zusammensetzen

Allgemeine Fragen rund um die "Smart Home" Hardware/Komponenten

Moderatoren: seppy, udo1toni

MISPEZI
Beiträge: 23
Registriert: 16. Jan 2022 15:00
Answers: 0

Re: Itemnamen aus Variablen zusammensetzen

Beitrag von MISPEZI »

Vielen Dank für deinen Input.
Mein direktes Problem ist gelöst - die Zerlegung und Auswahl aus der zweiten Gruppe funktioniert.
Ich werde meine Items überarbeiten und die Namen geschickter wählen, auch hier hast du mir sehr geholfen.
Damit sollte ich meinen rule-Djungel erheblich lichten können.

Zu dem LWT-Problem habe ich einen anderen Ansatz gefunden den ich mir noch genauer ansehen werde.
Es gibt mit ESPEASY eine Systemvariable, die UPTIME heißt. Hier wird die Verbindungszeit zum WLAN hochgezählt und die läßt sich loggen...

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

Re: Itemnamen aus Variablen zusammensetzen

Beitrag von udo1toni »

MISPEZI hat geschrieben: 22. Jan 2022 18:08 Es gibt mit ESPEASY eine Systemvariable, die UPTIME heißt. Hier wird die Verbindungszeit zum WLAN hochgezählt und die läßt sich loggen...
Ja, auch eine Möglichkeit. Es bleibt spannend.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

MISPEZI
Beiträge: 23
Registriert: 16. Jan 2022 15:00
Answers: 0

Re: Itemnamen aus Variablen zusammensetzen

Beitrag von MISPEZI »

Ich habe mal angefangen meine Rules zu lichten. Mit deinem Ansatz kann ich ja glatt 4 Bandwürmer töten und weil es nicht mehr so lang ist die Rules gleich in den Aufruf einbauen.
Soweit so gut.
Das hat mich natürlich auf die Idee gebraucht "Warum für die Kommunikation mit den ESPs jeweils eine eigene Rule aufbauen?" Gesagt getan.
Ich habe 2 ESPs auf Versuchsplatinen verkabelt und mit denen teste ich jetzt ob und wie das geht und ob es sinnvoll ist.
Angefangen habe ich mit der Rückgabe der Rollostände von den ESPs wenn sie gefahren wurden. Dazu habe ich mir folgendes überlegt:

Code: Alles auswählen

// Regel --- ein ESP sendet Rollostand
rule " ein ESP sendet Rollostand"
    when
        Member of gRS_RS changed          // ein ESP sendet neuen Rollostand
    then 
        val StringBuilder strName = new StringBuilder
        val Myname1 = triggeringItem.name
    logInfo("Rollo-Sendebetrieb","Auslösendes Item: {}",Myname1.toString)
        val Myname = triggeringItem.name.split("_")
            strName.append(Myname.get(0))
            strName.append("_")
            strName.append(Myname.get(1))
            strName.append("_")
            strName.append(Myname.get(2))
            RE_Number = Myname.get(2) 
    logInfo("Rollo-Sendebetrieb","Suchbegriff: {}",strName.toString)
        val Myname2 = gRS_NAME.members.filter[l| l.name.startsWith(strName.toString)].head  
        if (Myname2 !== null) { 
    logInfo("Rollo-Sendebetrieb","gefundenes Item: {}",Myname2.toString)
        }
            gRS_NAME.members.filter[m|
                m.name.startsWith(strName.toString)
                ].head.postUpdate((triggeringItem.state as Number)*10)                            // .head -> das erste Item der Ergebnisliste
        logInfo("Rollo-Sendebetrieb","Rollo {} hat Wert {} gesendet", RE_Number, triggeringItem.state.toString)
        else {
    logInfo("Rollo-Sendebetrieb","kein Item gefunden")
        }
        logInfo("Rollo-Sendebetrieb","jetzt ist Item = {}", triggeringItem.name.toString)
        sendTelegram("bot1", "R"+ RE_Number + " : Rollostand "+ triggeringItem.state.toString)

end 
Die LogInfos sind erstmal zur Kontrolle.
hier das Ergebnis:
2022-01-26 12:22:54.012 [INFO ] [home.model.script.Rollo-Sendebetrieb] - Auslösendes Item: RS_EGSZ_10_RS

2022-01-26 12:22:54.029 [INFO ] [home.model.script.Rollo-Sendebetrieb] - Suchbegriff: RS_EGSZ_10

2022-01-26 12:22:54.050 [INFO ] [home.model.script.Rollo-Sendebetrieb] - kein Item gefunden

2022-01-26 12:22:54.064 [INFO ] [home.model.script.Rollo-Sendebetrieb] - Rollo 10 hat Wert 4.8 gesendet

2022-01-26 12:22:54.069 [INFO ] [home.model.script.Rollo-Sendebetrieb] - jetzt ist Item = RS_EGSZ_10_RS
Myname2 ist immer null - wird also nicht gefunden
Es gibt aber das Item RS_EGSZ_10_DRW in der Gruppe gRS_NAME

Eine Idee wo mein Fehler liegt?

MISPEZI
Beiträge: 23
Registriert: 16. Jan 2022 15:00
Answers: 0

Re: Itemnamen aus Variablen zusammensetzen

Beitrag von MISPEZI »

Der Code hat durch die Kopiererei einen Syntaxfehler. Hier der Richtige:

Code: Alles auswählen

// Regel --- ein ESP sendet Rollostand
rule " ein ESP sendet Rollostand"
    when
        Member of gRS_RS changed          // ein ESP sendet neuen Rollostand
    then 
        val StringBuilder strName = new StringBuilder
        val Myname1 = triggeringItem.name
    logInfo("Rollo-Sendebetrieb","Auslösendes Item: {}",Myname1.toString)
        val Myname = triggeringItem.name.split("_")
            strName.append(Myname.get(0))
            strName.append("_")
            strName.append(Myname.get(1))
            strName.append("_")
            strName.append(Myname.get(2))
            RE_Number = Myname.get(2) 
    logInfo("Rollo-Sendebetrieb","Suchbegriff: {}",strName.toString)
        val Myname2 = gRS_NAME.members.filter[l| l.name.startsWith(strName.toString)].head  
        if (Myname2 !== null) { 
    logInfo("Rollo-Sendebetrieb","gefundenes Item: {}",Myname2.toString)
            gRS_NAME.members.filter[m|
                m.name.startsWith(strName.toString)
                ].head.postUpdate((triggeringItem.state as Number)*10)                            // .head -> das erste Item der Ergebnisliste
        logInfo("Rollo-Sendebetrieb","Rollo {} hat Wert {} gesendet", RE_Number, triggeringItem.state.toString)
        }
        else {
    logInfo("Rollo-Sendebetrieb","kein Item gefunden")
        }
        logInfo("Rollo-Sendebetrieb","jetzt ist Item = {}", triggeringItem.name.toString)
        sendTelegram("bot1", "R"+ RE_Number + " : Rollostand "+ triggeringItem.state.toString)

end 

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

Re: Itemnamen aus Variablen zusammensetzen

Beitrag von udo1toni »

Du nutzt eine Variable, ohne sie zu definieren. Oder ist RE_Nummer global definiert?

Achte auch auf die Einrückungen. Es geht dabei ausschließlich um Lesbarkeit, aber allgemein werden immer Blöcke eingerückt. Ein Block beginnt mit { oder [ und endet mit } oder ]. Eine bedingte Verzweigung wirkt immer ausschließlich auf den nächsten Befehl. Sollen mehrere Befehle bedingt ausgeführt werden, so müssen sie mit {} eingeschlossen werden. Ein else ist nur zulässig, wenn exakt der vorvorige Befehl ein if() war. Es sei denn, nach dem if() folgt ein {} Block, dann darf zwischen if() und else exakt dieser Block sein.

Das Objekt Myname2 ist kein String! es handelt sich um ein Item. Entsprechend musst Du, um den Namen auszugeben auch Myname2.name verwenden. .name liefert immer einen String zurück, toString ist also in dem Fall sinnlos.

Der Code sollte also eher so aussehen:

Code: Alles auswählen

// Regel --- ein ESP sendet Rollostand
rule " ein ESP sendet Rollostand"
when
    Member of gRS_RS changed          // ein ESP sendet neuen Rollostand
then 
    val StringBuilder strName = new StringBuilder
    val Myname1 = triggeringItem.name
    logInfo("Rollo-Sendebetrieb","Auslösendes Item: {}",Myname1)
    val Myname = triggeringItem.name.split("_")
    strName.append(Myname.get(0))
    strName.append("_")
    strName.append(Myname.get(1))
    strName.append("_")
    strName.append(Myname.get(2))
    val RE_Number = Myname.get(2)
    logInfo("Rollo-Sendebetrieb","Suchbegriff: {}",strName.toString)
    val Myname2 = gRS_NAME.members.filter[l| l.name.startsWith(strName.toString)].head
    if (Myname2 !== null) { 
        logInfo("Rollo-Sendebetrieb","gefundenes Item: {}",Myname2.name.toString)
        Myname2.postUpdate((triggeringItem.state as Number)*10)                            // .head -> das erste Item der Ergebnisliste
        logInfo("Rollo-Sendebetrieb","Rollo {} hat Wert {} gesendet", RE_Number, triggeringItem.state)
    } else {
        logInfo("Rollo-Sendebetrieb","kein Item gefunden")
    }
    logInfo("Rollo-Sendebetrieb","jetzt ist Item = {}", triggeringItem.name)
    sendTelegram("bot1", "R"+ RE_Number + " : Rollostand "+ triggeringItem.state.toString)
end 
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

MISPEZI
Beiträge: 23
Registriert: 16. Jan 2022 15:00
Answers: 0

Re: Itemnamen aus Variablen zusammensetzen

Beitrag von MISPEZI »

Danke dir vielmals.
Den Unterschied zwischen Variablen und Items werde ich verinnerlichen.
Die etwas konfuse Programmstruktur ist nur der Tatsache geschuldet die logs hinterher sofort zu finden um sie wieder zu löschen. Normalerweise rücke ich ein - sonst findet man in meinem Chaos nix mehr. Werd es aber vor der nächsten Kopie berücksichtigen.

Eine Frage hab ich aber noch und zwar zum triggeringItem.
Es ist ja so, dass in einer anderen Rule alle Rollos mit zB. Zeitsteuerung in einer Liste zusammengefaßt und nacheinander abgearbeitet werden.
Die Fahrbefehle gegen aus kurz nacheinander an die ESPs.
Das wird mit Sicherheit dazu führen, das sich das triggeringItem ändert während die obige Rule abgearbeitet wird.
Wenn er intern keinen Pointer auf das auslösende Item setzt, müßte ich also verhindern dass die Rule erneut abgearbeitet wird solange die vorherige Abarbeitung nicht beendet ist.
Hast du auch darauf vielleicht eine hilfreiche Antwort?

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

Re: Itemnamen aus Variablen zusammensetzen

Beitrag von udo1toni »

MISPEZI hat geschrieben: 26. Jan 2022 13:49 Danke dir vielmals.
Den Unterschied zwischen Variablen und Items werde ich verinnerlichen.
Die etwas konfuse Programmstruktur ist nur der Tatsache geschuldet die logs hinterher sofort zu finden um sie wieder zu löschen.
Das musst Du nicht tun :) Du kannst stattdessen das Logging pro Logger gezielt steuern.

??? ;)

Es gibt vier verschiedene Logbefehle, logDebug(), logInfo(), logWarn() und logError(). Diese Befehle erzeugen einen Eintrag im Log mit dem jeweiligen Loglevel (DEBUG, INFO, WARN, ERROR). Jeder dieser BEfehle erwartet zwei Strings als Parameter. Dabei ist der erste String der verwendete Loggername und der zweite String die auszugebende Meldung. Der Loggername ist tatsächlich nur ein Teil des Loggernamens, denn der Loggername ist hierarchisch organisiert. Alle Rules Logger gehören zum Zweig org.openhab.core.model.script. Wenn Du (wie ich immer wieder gerne erwähne...) den Loggernamen im log-Befehl entsprechend kurz und mindestens innerhalb derselben Rule gleich setzt, kannst Du bequem in der karaf Konsole per Befehl im laufenden System das Logging steuern (ob die verschiedenen Log-Befehle auch ausgegeben werden, einfach
log:set WARN org.openhab.core.model.script.loggername und schon werden nur noch logWarn() und logError() ausgegeben...
MISPEZI hat geschrieben: 26. Jan 2022 13:49 Eine Frage hab ich aber noch und zwar zum triggeringItem.
Es ist ja so, dass in einer anderen Rule alle Rollos mit zB. Zeitsteuerung in einer Liste zusammengefaßt und nacheinander abgearbeitet werden.
Die Fahrbefehle gegen aus kurz nacheinander an die ESPs.
Das wird mit Sicherheit dazu führen, das sich das triggeringItem ändert während die obige Rule abgearbeitet wird.
Wenn er intern keinen Pointer auf das auslösende Item setzt, müßte ich also verhindern dass die Rule erneut abgearbeitet wird solange die vorherige Abarbeitung nicht beendet ist.
Hast du auch darauf vielleicht eine hilfreiche Antwort?
Warum? Die Rule sollte einfach mehrfach parallel ausgeführt werden, es sind schließlich unterschiedliche Items.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

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

Re: Itemnamen aus Variablen zusammensetzen

Beitrag von udo1toni »

MISPEZI hat geschrieben: 26. Jan 2022 13:49 Danke dir vielmals.
Den Unterschied zwischen Variablen und Items werde ich verinnerlichen.
Die etwas konfuse Programmstruktur ist nur der Tatsache geschuldet die logs hinterher sofort zu finden um sie wieder zu löschen.
Das musst Du nicht tun :) Du kannst stattdessen das Logging pro Logger gezielt steuern.

??? ;)

Es gibt vier verschiedene Logbefehle, logDebug(), logInfo(), logWarn() und logError(). Diese Befehle erzeugen einen Eintrag im Log mit dem jeweiligen Loglevel (DEBUG, INFO, WARN, ERROR). Jeder dieser BEfehle erwartet zwei Strings als Parameter. Dabei ist der erste String der verwendete Loggername und der zweite String die auszugebende Meldung. Der Loggername ist tatsächlich nur ein Teil des Loggernamens, denn der Loggername ist hierarchisch organisiert. Alle Rules Logger gehören zum Zweig org.openhab.core.model.script. Wenn Du (wie ich immer wieder gerne erwähne...) den Loggernamen im log-Befehl entsprechend kurz und mindestens innerhalb derselben Rule gleich setzt, kannst Du bequem in der karaf Konsole per Befehl im laufenden System das Logging steuern (ob die verschiedenen Log-Befehle auch ausgegeben werden, einfach
log:set WARN org.openhab.core.model.script.loggername und schon werden nur noch logWarn() und logError() ausgegeben...
MISPEZI hat geschrieben: 26. Jan 2022 13:49 Eine Frage hab ich aber noch und zwar zum triggeringItem.
Es ist ja so, dass in einer anderen Rule alle Rollos mit zB. Zeitsteuerung in einer Liste zusammengefaßt und nacheinander abgearbeitet werden.
Die Fahrbefehle gegen aus kurz nacheinander an die ESPs.
Das wird mit Sicherheit dazu führen, das sich das triggeringItem ändert während die obige Rule abgearbeitet wird.
Wenn er intern keinen Pointer auf das auslösende Item setzt, müßte ich also verhindern dass die Rule erneut abgearbeitet wird solange die vorherige Abarbeitung nicht beendet ist.
Hast du auch darauf vielleicht eine hilfreiche Antwort?
Warum? Die Rule sollte einfach mehrfach parallel ausgeführt werden, es sind schließlich unterschiedliche Items.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

MISPEZI
Beiträge: 23
Registriert: 16. Jan 2022 15:00
Answers: 0

Re: Itemnamen aus Variablen zusammensetzen

Beitrag von MISPEZI »

Sorry das ich so lange für die Antwort gebraucht habe. Ich mußte einiges ändern und viel lesen :D . Habe dafür jetzt ein paar dumme Fragen gespart.
Also zurück zum Thema:
Dank deiner Hilfe gibt es jetzt Ordnung im Rollo-Urwald.
1 Regel setzt bei Systemstart alle Werte
1 Regel kümmert sich um den Datenaustausch mit den ESPs
1 Regel erledigt die Fahranweisungen
1 Regel steuert die Modi ein (Sonne, Zeit, manuell)
und damit kann man soviele Rollos bedienen, wie man mag.

Für meine letzte Frage habe ich hier von Rich Koshak eine Antwort gefunden :
https://community.openhab.org/t/why- ... dea/47695
Demnach können also 5 Langlaufrules gleichzeitig bearbeitet werden, der Rest kommt in eine Warteschleife.
Wenn ich jetzt auf die Idee komme, mir die Bewegungsvorgänge der Rollos in der Sidemap aus Prozentwerte der Rolloshutteritems anzeigen zu lassen erzeuge ich Rules die um die 30 sec laufen - wenn ich mit Thead::sleep(1000) arbeite. Benutze ich einen Timer wirds erheblich länger, da zwischendurch andere Rules ausgeführt werden. Also auf den Gimmick verzichten!?
Und wenn schon Gimmick dann auch richtig - es ist ja nicht so, als ob eine 50%-Fahrzeit das Rollo auch zu 50% schließt - es dürften eher 90% sein.
Man kann es beliebig kompliziert machen...
Oder die Fahrbewegung nur andeuten. zB. down (0 - 25- 50- 75- Pause 0 25 50 75 Pause - bis das Relais abschaltet)
Hast du dazu eine Idee?

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

Re: Itemnamen aus Variablen zusammensetzen

Beitrag von udo1toni »

Ich bin kein Freund von "Echtzeit" Rückmeldung der Rollladenfahrten Ich zeige hier nur die aktuelle Position an, wenn der Laden steht.
Die 5-Rules-Regel gilt übrigens so nicht uneingeschränkt.

1. Es sind 5 + 2 Rules (zwei timergesteuerte, fünf durch andere Trigger ausgelöste) Beide Werte könnte man auch anpassen.
2. Das gilt aber auch nur für openHAB 1 und openHAB 2. In openHAB3 wurde der zugehörige Code stark verändert, die geteilten Threads gibt es so nicht mehr (leider).

3. Vergiss Thread::sleep für alle, was länger als (sagen wir mal) 500 Millisekunden dauert. Allgemein sollte eine Rule nach Möglichkeit nach einigen hundertstel Sekunden durch sein, weshalb mit einem Scheduler ohne weiteres auch hundert Rollladenfahrten parallel sekundengenau upgedatet werden könnten. Der Trick ist, so wenig Zeit wie möglich dazu zu verwenden, der Rest erledigt sich quasi von selbst. Wie gesagt bin ich kein Freund davon, meine Hausautomation soll sich möglichst langweilen und nicht ständig am Limit laufen...
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten