[gelöst] Vereinfachung des DOIFs

Begonnen von Nighthawk, 02 März 2022, 16:25:59

Vorheriges Thema - Nächstes Thema

Nighthawk

Hallo zusammen,

ich frage mich ob, bzw. wie man es hinbekommen könnte folgendes DOIF zu vereinfachen:

([SensorArbeitszimmer:lueften] eq "nein" and [?Fenster_Arbeitszimmer] eq "open") (set Signal send 🪟 Lüften bringt jetzt nichts mehr, Fenster im Arbeitszimmer zu!)
DOELSEIF
([SensorSchlafzimmer:lueften] eq "nein" and [?Fenster_Schlafzimmer] eq "open") (set Signal send 🪟 Lüften bringt jetzt nichts mehr, Fenster im Schlafzimmer zu!)
.
.


Die Namen der Umweltsensoren beginnen immer mit "Sensor" und enden mit der Zimmerbezeichnung, die Namen der Fenstersensoren beginnen immer mit "Fenster_" und enden ebenfalls mit der Zimmerbezeichnung.

Was ich mir vorstellen könnte wäre, 
die Abfrage des Fenstersensors in den Ausführungsteil zu verlegen und dort dann das $DEVICE vom Umweltsensor zu zerlegen (im Grunde muss nur der String Sensor entfernt werden) und mit diesem dann etwas ähnliches wie [Fenster_$DEVICESPLIT] eq "open" zu erzeugen.

Dies würde das riesige ungetüm auf eine Zeile reduzieren:

(["Sensor:^lueften:.nein") (IF [Fenster_$DEVICESPLIT] eq "open" (set Signal send 🪟 Lüften bringt jetzt nichts mehr, Fenster im $DEVICESPLIT zu!))
DOELSE


Leider habe ich keinen Plan wie ich das $DEVICE splitte und ob dies überhaupt in DOIF so möglich ist.

Für einen Wink mit dem Zaunpfahl wäre ich euch sehr dankbar.

Damian

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Nighthawk

#2
Hallo Damian,

leider bin ich bei Perl recht schnell raus :-(

würde so etwas funktionieren?

(((
               {$raum=substr($DEVICE,0,6,"");;},                                                     # erste 6 Zeichen mit löschen
               IF [Fenster_$raum] eq "open")                                                         # prüfen ob das Fenster in dem entsprechendem Raum offen ist
(set Signal send 🪟 Lüften bringt jetzt nichts mehr, Fenster im $raum zu!)))         # senden der Nachricht
   

oder eher so:
(((
               {$raum=substr($DEVICE,0,6,"");;                                                        # erste 6 Zeichen mit löschen
               if [Fenster_$raum] eq "open"                                                           # prüfen ob das Fenster in dem entsprechendem Raum offen ist
       fhem_set (Signal send 🪟 Lüften bringt jetzt nichts mehr, Fenster im $raum zu!);;}     # senden der Nachricht
))   

Damian

z. B.

([SensorArbeitszimmer:lueften] eq "nein" and [?Fenster_Arbeitszimmer] eq "open") (set Signal send 🪟 Lüften bringt jetzt nichts mehr, Fenster im Arbeitszimmer zu, Fenster im Raum {(substr("$DEVICE",8))})
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Nighthawk

Hallo Damian,

ich möchte ja das Doif so weit wie möglich reduzieren, daher würde ich gerne in der if Abfrage innerhalb des Ausführungsteils das Device zusammenstzen aus dem String "Fenster_" und dem auf den Zimmernamen gekürzten String, also {(substr("$DEVICE",6))}.

Beispiel:
wenn am SensorKueche das Reading lueften auf "nein" wechselt, wird im Ausführungsteil abgefragt ob das Device Fenster_{(substr("$DEVICE",6))}, woraus in diesem Fall das Device Fenster_Kueche enstehen würde, "open" ist und dann die Medung an das Signal Device abschickt.

Damian

Dann musst du mit ReadingsVal arbeiten, in etwa:

if (ReadingsVal ("Fenster_$raum",state,"") eq "open") {fhem("set...")}
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Nighthawk

Hallo Damian,

leider bekomme ich es so nicht zum Laufen, es kommt die Fehlermeldung "Modification of a read-only value attempted at (eval 122710) line 1."

Internals:
   DEF        (["^Sensor:^lueftenMoeglich:.nein$"])
((
{( my $raum = substr( "$DEVICE",0,6,"" ));;}
(if (ReadingsVal ("Fenster_$raum",state,"") eq "open") {fhem("set Signal send 🪟 Lüften bringt jetzt nichts mehr, Fenster im $raum zu!")})
))
DOELSE
   FUUID      5fffb2dc-f33f-357a-85c1-70c284d70ac2d537
   MODEL      FHEM
   NAME       di.Fenster_schliessen
   NOTIFYDEV  global,.*(^Sensor).*
   NR         334
   NTFY_ORDER 50-di.Fenster_schliessen
   STATE      cmd_1
   TYPE       DOIF
   VERSION    25720 2022-02-20 21:38:26
   Helper:
     DBLOG:
       cmd:
         logdb:
           TIME       1646660375.07581
           VALUE      1
       cmd_event:
         logdb:
           TIME       1646660375.07581
           VALUE      SensorArbeitszimmer
       cmd_nr:
         logdb:
           TIME       1646660375.07581
           VALUE      1
       error:
         logdb:
           TIME       1646660375.07581
           VALUE      Modification of a read-only value attempted at (eval 122710) line 1.
       mode:
         logdb:
           TIME       1646660017.89112
           VALUE      enabled
       state:
         logdb:
           TIME       1646660375.07581
           VALUE      cmd_1
   READINGS:
     2022-03-07 14:39:35   Device          SensorArbeitszimmer
     2022-03-07 14:39:35   cmd             1
     2022-03-07 14:39:35   cmd_event       SensorArbeitszimmer
     2022-03-07 14:39:35   cmd_nr          1
     2022-03-07 14:39:35   error           Modification of a read-only value attempted at (eval 122710) line 1.

     2022-03-07 14:33:37   mode            enabled
     2022-03-07 14:39:35   state           cmd_1
   Regex:
     accu:
     collect:
     cond:
       :
         0:
           "^Sensor:^lueftenMoeglich:.nein$" ^Sensor:^lueftenMoeglich:.nein$
   attr:
     cmdState:
     wait:
     waitdel:
   condition:
     0          ::EventDoIf('^Sensor',$hash,'^lueftenMoeglich:.nein$',0)
   do:
     0:
       0          ( {( my $raum = substr( "$DEVICE",0,6,"" ));;} (if (ReadingsVal ("Fenster_$raum",state,"") eq "open") {fhem("set Signal send 🪟 Lüften bringt jetzt nichts mehr, Fenster im $raum zu!")}) )
     1:
       0         
   helper:
     NOTIFYDEV  global,.*(^Sensor).*
     event      lueftenMoeglich: nein
     globalinit 1
     last_timer 0
     sleeptimer -1
     timerdev   SensorArbeitszimmer
     timerevent lueftenMoeglich: nein
     triggerDev SensorArbeitszimmer
     timerevents:
       humidity: 22
       brightness: 5897.0
       lueftenMoeglich: nein
       dewpoint: -1
     timereventsState:
       humidity: 22
       brightness: 5897.0
       lueftenMoeglich: nein
       dewpoint: -1
     triggerEvents:
       humidity: 22
       brightness: 5897.0
       lueftenMoeglich: nein
       dewpoint: -1
     triggerEventsState:
       humidity: 22
       brightness: 5897.0
       lueftenMoeglich: nein
       dewpoint: -1
   internals:
   readings:
   trigger:
   uiState:
   uiTable:
Attributes:
   room       02_Fenster_Tueren

Damian

Warum setzt du so viele Klammern?

(["^Sensor:^lueftenMoeglich:.nein$"])
{ my $raum = substr( "$DEVICE",0,6,"" ));if (ReadingsVal ("Fenster_$raum",state,"") eq "open") {fhem("set Signal send Lüften bringt jetzt nichts mehr, Fenster im $raum zu!")}}
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Nighthawk

Die Klammern habe ich doppelt gemacht, da ich im Hinterkopf hatte dass bei mehreren Befehlen im Ausführungsteil doppelt geklammert werden muss zusätzlich kommt meine Perl-Unkenntniss dazu.

Leider bekomme ich auch mit deiner Variante den gleichen Fehler :

{ my $raum = substr( "SensorArbeitszimmer",0,6,"" );if (ReadingsVal ("Fenster_$raum","state","") eq "open") {fhem("set Signal send  🪟  Lüften bringt jetzt nichts mehr, Fenster im X zu!")}}: Modification of a read-only value attempted at (eval 312853) line 1.

Damian

Zitat von: Nighthawk am 07 März 2022, 16:31:22
Die Klammern habe ich doppelt gemacht, da ich im Hinterkopf hatte dass bei mehreren Befehlen im Ausführungsteil doppelt geklammert werden muss zusätzlich kommt meine Perl-Unkenntniss dazu.

Leider bekomme ich auch mit deiner Variante den gleichen Fehler :

{ my $raum = substr( "SensorArbeitszimmer",0,6,"" );if (ReadingsVal ("Fenster_$raum","state","") eq "open") {fhem("set Signal send  🪟  Lüften bringt jetzt nichts mehr, Fenster im X zu!")}}: Modification of a read-only value attempted at (eval 312853) line 1.

Dann ist es kein DOIF-spezifischer Fehler, irgendwo fehlen dir Schreibrechte.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Nighthawk

Die substr Funktion wurde von mir falsch verwendet.

Hier die funktionierende Variante:
(["^Sensor:^lueftenMoeglich:.nein$"])
{ my $raum = substr( "$DEVICE",6 );if (ReadingsVal ("Fenster_$raum","state","") eq "open") {fhem("set Signal send  🪟  Lüften bringt jetzt nichts mehr, Fenster im $raum zu!")}}


Vielen Dank für deine Unterstützung und Geduld Damian!

Per

Ohne Perl "Umwege" könnte man auch den Raum (room) abfragen, wenn gepflegt und passend.