Unkontrolliertes AN/AUS-Schalten von Lampen(Leuchten) bei Änderung von Item-Stammdaten

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Unkontrolliertes AN/AUS-Schalten von Lampen(Leuchten) bei Änderung von Item-Stammdaten

Beitrag von peter-pan »

Hallo in die Runde.

Ich habe einige "Zigbee2mqtt-Lampen" (Paulmann) und kann diese per Switch(Sonoff SNZB-01/SNZB-01P) und DSL-Rule an- und ausschalten. Die Switche erkennen "single/double/long"

Ein kleiner (unerwünschter) Nebeneffekt tritt auf, wenn ich Änderungen in der .items-Datei vornehme. Dann nämlich wird irgend eine meiner Rules ausgelöst und eine Lampe angeschaltet.

zigbee2mqtt_switches.items:

Code: Alles auswählen

//                          Mini Switch SNZB01 - 01 snzb_01_01
Group                       gsnzb01_01                 "Sensor SNZB-01 01"                               <snzb_01>               (gEG_Kind2)                        ["Sensor"]
String                      snzb01_01_action           "Sensor SNZB-01 01 Zustand"                       <snzb_01>               (gsnzb01_01)                       ["Switch"]                                  { channel="mqtt:topic:danny:snzb0101:action" }     
Number:ElectricPotential    snzb01_01_voltage          "Sensor SNZB-01 01 Spannung [%.1f]"               <snzb_01>               (gsnzb01_01)                       ["Voltage"]                                 { channel="mqtt:topic:danny:snzb0101:voltage" }        
Number:Dimensionless        snzb01_01_battery          "Sensor SNZB-01 01 Batterie"                      <snzb_01>               (gsnzb01_01)                       ["Level"]                                   { channel="mqtt:topic:danny:snzb0101:battery", unit="%" }       
Number                      snzb01_01_linkquality      "Sensor SNZB-01 01 LQI "                          <snzb_01>               (gsnzb01_01)                       ["Frequency"]                               { channel="mqtt:topic:danny:snzb0101:linkquality", stateDescription=" " [pattern="%.0f LQI"] }     
zigbee2mqtt_switch.rules

Code: Alles auswählen

rule "miniswitch_snzb01_01"
  when
   Item snzb01_01_action received update
  then
//   logInfo("miniswitch_snzb01_02", "{}", snzb01_01_action.label)
      switch (snzb01_01_action.state) {
         case "single" : {
            var location = getLocation(LidlLedLamp_01)
            if (LidlLedLamp_01.state == ON) {
                LidlLedLamp_01.sendCommand(OFF)
                logInfo("single 1 -   if", "{} - {} Lampe ausgeschaltet: {}", snzb01_01_action.state.toString, LidlLedLamp_01.label, location.label)
                return;
            }
            else (LidlLedLamp_01.state == OFF) {
                  LidlLedLamp_01.sendCommand(ON)
                  logInfo("single 1 - else", "{} - {} Lampe angeschaltet:  {}", snzb01_01_action.state.toString, LidlLedLamp_01.label, location.label)
                  return;
            }
          }
         case "double" : {
            var location = getLocation(Be2709w_01)
            if (Be2709w_01.state == ON) {
                Be2709w_01.sendCommand(OFF)
                logInfo("double 1 -   if", "{} - {} Lampe ausgeschaltet: {}", snzb01_01_action.state.toString, Be2709w_01.label, location.label)
                return;
            }
            else (Be2709w_01.state == OFF) {
                  Be2709w_01.sendCommand(ON)
                  logInfo("double 1 - else", "{} - {} Lampe angeschaltet:  {}", snzb01_01_action.state.toString, Be2709w_01.label, location.label)
                  return;
            }
         }
         case "long" : {
            var location = getLocation(Be2709w_02)
            if (Be2709w_02.state == ON) {
                Be2709w_02.sendCommand(OFF)
                logInfo("long 1 -   if", "{} - {} Lampe ausgeschaltet: {}", snzb01_01_action.state.toString, Be2709w_02.label, location.label)
                return;
            }
            else (Be2709w_02.state == OFF) {
                  Be2709w_02.sendCommand(ON)
                  logInfo("long 1 - else", "{} - {} Lampe angeschaltet:  {}", snzb01_01_action.state.toString, Be2709w_02.label, location.label)
                  return;
            }
         }
        }
 end
Es passiert relativ selten, dass ich nach dem SetUp noch Änderungen im ".items-file" vornehme, aber wenn jemand eine Lösung weiss, dann nehme ich die gerne auf.
von udo1toni » 13. Nov 2024 20:06
Nun ja, es dürfte klar sein, warum das passiert:
Wenn man Items über Textdateien pflegt, und Änderungen an den Items vornimmt, wird jedes Item in der betreffenden Datei aus der ItemRegistry gelöscht und anschließend neu erzeugt. Da das Item mit einem Channel verlinkt ist, wird es unmittelbar mit dem gerade anliegenden Status des Channels versorgt, also upgedatet. Auch eine Änderung des Triggers auf changed hilft hier mutmaßlich nicht, denn das neu angelegte Item hat zunächst den Status NULL, wird also geändert, mal abgesehen davon, dass die Rule dann nicht mehr wie gewünscht funktionieren wird.

Meine erste Frage an dieser Stelle ist allerdings: warum verwendest Du überhaupt ein Item zum Triggern der Rule? Besser wäre es, den action Channel als Typ trigger zu definieren. Die Rule kannst Du dann auf den Trigger

Code: Alles auswählen

Channel 'mqtt:topic:danny:snzb0101:action' triggered
ändern und die Implizite Variable receivedEvent verwenden, um zwischen single, double und long zu unterscheiden.
Und ich wäre nicht ich, wenn ich nicht eine grundsätzliche "Verbesserung" der Rule vorzuschlagen hätte...

Code: Alles auswählen

rule "miniswitch snzb01 01"
  when
   Channel 'mqtt:topic:danny:snzb0101:action' triggered
  then
    var Item itZiel 
    switch(receivedEvent) {
        case "single" : itZiel = LidlLedLamp_01
        case "double" : itZiel = Be2709w_01
        case "long"   : itZiel = Be2709w_02
        default : {
            logWarn("miniswitch","Da ist was schief gegangen! Unbekanntes Event {} empfangen!", receivedEvent)
            return;
        }
    }
    var strLocation = getLocation(itZiel).label                // Location Label ermitteln
    val strOnOff    = if(itZiel.state != ON) "ein" else "aus"  // künftiger Zustand

    logInfo("miniswitch", "{} - {} Lampe {}geschaltet: {}", receivedEvent, itZiel.label, strOnOff, strLocation)
    itZiel.sendCommand(if(itZiel.state != ON) ON else OFF)
 end
Ich bin mit nicht zu 100 % sicher, ob die Typzuweisung für itZiel so korrekt ist, kann es aber gerade nicht ausprobieren. Der Punkt ist aber, dass der Code für alle drei Fälle identisch ist - bis auf das zu manipulierende Item. Entsprechend erscheint es sinnvoll, zunächst einen Stellvertreter für das Item zu erschaffen und dann diesen Stellvertreter zu verwenden.

Denke bitte auch immer daran, dass der erste an die Log-Anweisungen übergebene String der Name des Loggers ist - genauer der letzte Teil des Loggernamens. der vollständige Name lautet org.openhab.core.model.script.miniswitch, damit kann man das Logverhalten für diesen Logger steuern. Es ist in den wenigsten Fällen korrekt, innerhalb einer Rule verschiedene Logger zu verwenden.

Falls es mit dem Ausdruck var Item itZiel Probleme geben sollte, wäre ein Umweg, das über ein Group Item zu machen und das Item aus der Gruppe übergeben zu lassen:

Code: Alles auswählen

    var itZiel = gLampen.members.filter[i|i.name == "LidlLedLamp_01"].head
    switch(receivedEvent) {
        case "single" : itZiel = gLampen.members.filter[i|i.name == "LidlLedLamp_01"].head
        case "double" : itZiel = gLampen.members.filter[i|i.name == "Be2709w_01"].head 
        case "long"   : itZiel = gLampen.members.filter[i|i.name == "Be2709w_02"].head
        default : {
            logWarn("miniswitch","Da ist wasschief gegangen! Unbekanntes Event {} empfangen!",receivedEvent)
            return;
        }
    }
Die erste Zuweisung ist in diesem Fall nur der Trick, ohne starke Typisierung auszukommen ;) Eventuell heißt der Datentyp auch GenericItem?
Gehe zur vollständigen Antwort
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

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

Re: Unkontrolliertes AN/AUS-Schalten von Lampen(Leuchten) bei Änderung von Item-Stammdaten

Beitrag von udo1toni »

Nun ja, es dürfte klar sein, warum das passiert:
Wenn man Items über Textdateien pflegt, und Änderungen an den Items vornimmt, wird jedes Item in der betreffenden Datei aus der ItemRegistry gelöscht und anschließend neu erzeugt. Da das Item mit einem Channel verlinkt ist, wird es unmittelbar mit dem gerade anliegenden Status des Channels versorgt, also upgedatet. Auch eine Änderung des Triggers auf changed hilft hier mutmaßlich nicht, denn das neu angelegte Item hat zunächst den Status NULL, wird also geändert, mal abgesehen davon, dass die Rule dann nicht mehr wie gewünscht funktionieren wird.

Meine erste Frage an dieser Stelle ist allerdings: warum verwendest Du überhaupt ein Item zum Triggern der Rule? Besser wäre es, den action Channel als Typ trigger zu definieren. Die Rule kannst Du dann auf den Trigger

Code: Alles auswählen

Channel 'mqtt:topic:danny:snzb0101:action' triggered
ändern und die Implizite Variable receivedEvent verwenden, um zwischen single, double und long zu unterscheiden.
Und ich wäre nicht ich, wenn ich nicht eine grundsätzliche "Verbesserung" der Rule vorzuschlagen hätte...

Code: Alles auswählen

rule "miniswitch snzb01 01"
  when
   Channel 'mqtt:topic:danny:snzb0101:action' triggered
  then
    var Item itZiel 
    switch(receivedEvent) {
        case "single" : itZiel = LidlLedLamp_01
        case "double" : itZiel = Be2709w_01
        case "long"   : itZiel = Be2709w_02
        default : {
            logWarn("miniswitch","Da ist was schief gegangen! Unbekanntes Event {} empfangen!", receivedEvent)
            return;
        }
    }
    var strLocation = getLocation(itZiel).label                // Location Label ermitteln
    val strOnOff    = if(itZiel.state != ON) "ein" else "aus"  // künftiger Zustand

    logInfo("miniswitch", "{} - {} Lampe {}geschaltet: {}", receivedEvent, itZiel.label, strOnOff, strLocation)
    itZiel.sendCommand(if(itZiel.state != ON) ON else OFF)
 end
Ich bin mit nicht zu 100 % sicher, ob die Typzuweisung für itZiel so korrekt ist, kann es aber gerade nicht ausprobieren. Der Punkt ist aber, dass der Code für alle drei Fälle identisch ist - bis auf das zu manipulierende Item. Entsprechend erscheint es sinnvoll, zunächst einen Stellvertreter für das Item zu erschaffen und dann diesen Stellvertreter zu verwenden.

Denke bitte auch immer daran, dass der erste an die Log-Anweisungen übergebene String der Name des Loggers ist - genauer der letzte Teil des Loggernamens. der vollständige Name lautet org.openhab.core.model.script.miniswitch, damit kann man das Logverhalten für diesen Logger steuern. Es ist in den wenigsten Fällen korrekt, innerhalb einer Rule verschiedene Logger zu verwenden.

Falls es mit dem Ausdruck var Item itZiel Probleme geben sollte, wäre ein Umweg, das über ein Group Item zu machen und das Item aus der Gruppe übergeben zu lassen:

Code: Alles auswählen

    var itZiel = gLampen.members.filter[i|i.name == "LidlLedLamp_01"].head
    switch(receivedEvent) {
        case "single" : itZiel = gLampen.members.filter[i|i.name == "LidlLedLamp_01"].head
        case "double" : itZiel = gLampen.members.filter[i|i.name == "Be2709w_01"].head 
        case "long"   : itZiel = gLampen.members.filter[i|i.name == "Be2709w_02"].head
        default : {
            logWarn("miniswitch","Da ist wasschief gegangen! Unbekanntes Event {} empfangen!",receivedEvent)
            return;
        }
    }
Die erste Zuweisung ist in diesem Fall nur der Trick, ohne starke Typisierung auszukommen ;) Eventuell heißt der Datentyp auch GenericItem?
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: Unkontrolliertes AN/AUS-Schalten von Lampen(Leuchten) bei Änderung von Item-Stammdaten

Beitrag von peter-pan »

Hallo Udo,
erstmal Danke für dein feedback.
Bin gerade nach Hause gekommen und habe deine Info gelesen. Werde mich morgen mit deinen Tipps auseinander setzen und diese testen. Ich gehe aber davon aus, dass es damit klappt.
Ich hatte heute auch schon mit dem Channel-Trigger experimentiert, aber bei mir wollte es nicht klappen. Wahrscheinlich habe ich mit der Syntax Probleme gehabt.

Was das Verhalten der Rule(s) beim Ändern eines Items anbelangt, so habe ich dies zum ersten mal bemerkt seit ich mit "Z2M" arbeite, obwohl mein SetUp zu 90% aus Text-Dateien besteht.

Ich melde mich, aber schon mal Danke im voraus.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

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

Re: Unkontrolliertes AN/AUS-Schalten von Lampen(Leuchten) bei Änderung von Item-Stammdaten

Beitrag von udo1toni »

Die Frage ist ja, ob Du received update als Trigger nutzt. Ich habe sozusagen 99% per Textdateien, aber ich habe so gut wie keine Rules mit received update...
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: Unkontrolliertes AN/AUS-Schalten von Lampen(Leuchten) bei Änderung von Item-Stammdaten

Beitrag von peter-pan »

udo1toni hat geschrieben: 13. Nov 2024 23:49 Die Frage ist ja, ob Du received update als Trigger nutzt. Ich habe sozusagen 99% per Textdateien, aber ich habe so gut wie keine Rules mit received update...
Genau das ist der Punkt. Ein received update hab ich nur noch in einer Regel, aber da passiert das Verhalten nicht (komischerweise) :? .

Ich habe jetzt die erste Rule 1:1 kopiert, aber der Channel-Trigger löst nicht aus. Ausserdem ist, wie du bereits vermutet hast der Typ "ITEM" anscheinend nicht ganz regelkonform.

Code: Alles auswählen

2024-11-14 12:09:23.118 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model 'zigbee_switch.rules' has errors, therefore ignoring it: [200,9]: no viable alternative at input 'Item'
.

Irgend etwas muss noch mit dem Channel-Trigger sein. Deshalb kann ich das receivedEvent auch nicht in der zweiten Rule benutzen.

Kann es sein, dass man irgendwie in der MQTT-Bridge noch einen Trigger-Channel setzen muss ? Irgendwo hab ich mal was im englischen Forum gelesen, weiss aber nicht mehr wo.

Bin etwas ratlos :oops: :cry:
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: Unkontrolliertes AN/AUS-Schalten von Lampen(Leuchten) bei Änderung von Item-Stammdaten

Beitrag von peter-pan »

:D :D
Das Ganze hat mir doch keine Ruhe gelassen und deshalb habe ich nochmal bisschen in meinem SetUp "rumgekruschtelt" und bin dann auf eine alte Regel gestossen, mit der ich mal das "LWT-Logging" an und ausschalten kann und dabei ging es um das temporäre Zwischenspeichern von Items.

Code: Alles auswählen

import org.openhab.core.model.script.ScriptServiceUtil
//===============================================================================================
rule "gLWT_Logging"

when Member of gLWT changed
then
   if(Tasmota_LWT_Logging.state == ON) {
      var GenericItem tempItemName = ScriptServiceUtil.getItemRegistry.getItem(triggeringItem.name.replace("_Unreach","_IPAddress")) as  GenericItem
      logInfo ("lwt", "Gerät: {} - IP: {} - Zustand {}",triggeringItem.label, tempItemName.state.toString, triggeringItem.state.toString)     
    }
end
//===============================================================================================
Ausserdem habe ich noch einen Post im internationalen Forum gefunden der das Problem mit den MQTT-Triggern beschrieben hatte.

Nachdem ich nun diese "Nebengeräusche" entfernen konnte, klappt das mit der Regel vorzüglich. Ich werde aber jetzt auch noch mal mit der anderen Regel probieren.

.things (mit zusätzlichem Trigger-Channel)

Code: Alles auswählen

Thing mqtt:topic:danny:snzb0101 "Sonoff SNZB01 01"  (mqtt:broker:danny )   @ "zigbee2mqtt"// [ availabilityTopic="tele/esp01s-02/LWT", payloadNotAvailable="Offline", payloadAvailable= "Online" ] 
    {
    Channels:
        Type string  : action       "SNZB01 01 Ein/Aus"                     [ stateTopic="zigbee2mqtt/snzb_01_01/action" ]
        Type number  : voltage      "SNZB01 01 Batterie-Spannung"           [ stateTopic="zigbee2mqtt/snzb_01_01/voltage", unit="mV" ]
        Type number  : battery      "SNZB01 01 Batterie-Level"              [ stateTopic="zigbee2mqtt/snzb_01_01/battery", unit="%" ] 
        Type number  : linkquality  "SNZB01 01 Empfangsstärke LQI"          [ stateTopic="zigbee2mqtt/snzb_01_01", transformationPattern="JSONPATH:$.linkquality" ]
        Type trigger : click        "SNZB01 01 Trigger"                     [ stateTopic="zigbee2mqtt/snzb_01_01/action" ]
    }
.rules (GenericItem)

Code: Alles auswählen

rule "miniswitch snzb01 01 test"
  when
   Channel 'mqtt:topic:danny:snzb0101:click' triggered
  then
    var  GenericItem itZiel 
    switch(receivedEvent) {
        case "single" : itZiel = LidlLedLamp_01
        case "double" : itZiel = Be2709w_01
        case "long"   : itZiel = Be2709w_02
        default : {
            logWarn("miniswitch","Da ist was schief gegangen! Unbekanntes Event {} empfangen!", receivedEvent)
            return;
        }
    }
    var strLocation = getLocation(itZiel).label                // Location Label ermitteln
    val strOnOff    = if(itZiel.state != ON) "ein" else "aus"        // künftiger Zustand

    logInfo("miniswitch", "{} - {} Lampe {}geschaltet: {}", receivedEvent, itZiel.state, strOnOff, strLocation)
    itZiel.sendCommand(if(itZiel.state != ON) ON else OFF)
 end
Vielen Dank nochmal für die Hilfe und die schönen kurzen und übersichtlichen Rules.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

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

Re: Unkontrolliertes AN/AUS-Schalten von Lampen(Leuchten) bei Änderung von Item-Stammdaten

Beitrag von udo1toni »

Super :)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten