FHEM Forum

FHEM => Automatisierung => DOIF => Thema gestartet von: Nighthawk am 02 März 2022, 16:25:59

Titel: [gelöst] Vereinfachung des DOIFs
Beitrag von: Nighthawk am 02 März 2022, 16:25:59
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.
Titel: Antw:Vereinfachung des DOIFs
Beitrag von: Damian am 02 März 2022, 16:48:45
Du kannst folgende Perlfunktion nutzen:
http://www.hidemail.de/blog/substr-perl.shtml
Titel: Antw:Vereinfachung des DOIFs
Beitrag von: Nighthawk am 04 März 2022, 13:59:02
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
))   
Titel: Antw:Vereinfachung des DOIFs
Beitrag von: Damian am 04 März 2022, 16:21:30
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))})
Titel: Antw:Vereinfachung des DOIFs
Beitrag von: Nighthawk am 04 März 2022, 19:36:34
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.
Titel: Antw:Vereinfachung des DOIFs
Beitrag von: Damian am 04 März 2022, 19:41:32
Dann musst du mit ReadingsVal arbeiten, in etwa:

if (ReadingsVal ("Fenster_$raum",state,"") eq "open") {fhem("set...")}
Titel: Antw:Vereinfachung des DOIFs
Beitrag von: Nighthawk am 07 März 2022, 14:42:15
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
Titel: Antw:Vereinfachung des DOIFs
Beitrag von: Damian am 07 März 2022, 16:00:52
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!")}}
Titel: Antw:Vereinfachung des DOIFs
Beitrag 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.
Titel: Antw:Vereinfachung des DOIFs
Beitrag von: Damian am 07 März 2022, 16:33:59
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.
Titel: Antw:Vereinfachung des DOIFs
Beitrag von: Nighthawk am 07 März 2022, 18:02:49
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!
Titel: Antw:[gelöst] Vereinfachung des DOIFs
Beitrag von: Per am 24 April 2022, 12:01:07
Ohne Perl "Umwege" könnte man auch den Raum (room) abfragen, wenn gepflegt und passend.