[gelöst] 2 Zustände in Dummy aggregieren mittels Notify

Begonnen von Jorge3711, 04 Juni 2017, 21:09:07

Vorheriges Thema - Nächstes Thema

Jorge3711

Hallo zusammen,

ich habe mir mit dem HM-MOD-Em-8 und 2 seiner Channels einen Türfensterkontakt (TFK) für die Fensterzustände gekippt und offen gebaut. Jetzt habe ich für ein und das selbe Fenster in FHEM 2 Geräte, was unschön ist. Meine Idee war nun den Gesamtzustand des Fensters in einem Dummy zu aggregieren und für die optische Darstellung in FHEMWEB zu benutzen.

Der Dummy sieht wie folgt aus:


Internals:
   CFGFN
   NAME       FensterDummy
   NR         8277
   STATE      tilted
   TYPE       dummy
   Readings:
     2017-06-04 18:37:20   state           tilted
Attributes:
   devStateIcon closed:fts_window_1w@green tilted:fts_window_1w_tilt@red open:fts_window_1w_open@red
   room       Schlafzimmer
   setList    closed open tilted


Die TFKs liefern folgende Events im Eventmonitor (gefiltert nach sec.tfk.eg.sz_li.*:(open|closed|tilted) (Notify-Type: deviceName:event):

2017-06-04 18:37:20 CUL_HM sec.tfk.eg.sz_li_02 tilted
2017-06-04 18:37:27 CUL_HM sec.tfk.eg.sz_li_02 closed
2017-06-04 18:37:29 CUL_HM sec.tfk.eg.sz_li_01 open
2017-06-04 18:37:32 CUL_HM sec.tfk.eg.sz_li_01 closed


Im Notify wollte, ich da ich mich gerade in Perl einarbeite, als Fingerübung mit etwas Perlcode dann entsprechend der meldenden TFKs den Dummy "schalten". Allerdings scheitere ich mit allen Versuchen die ich bisher unternommen habe. Der FensterDummy ändert seinen Zustand nicht, im Log habe ich keine Fehlermeldungen, auch am Notify sehe ich keine Änderungen in den Readings.

Der derzeitige Stand des Notify sieht so aus:


sec.tfk.eg.sz_li.*:(open|closed|tilted){
my state1 = InternalVal("sec.tfk.eg.sz_li_01", "STATE", nA);;
my state2 = InternalVal("sec.tfk.eg.sz_li_02", "STATE", nA);;
if($NAME eq "sec.tfk.eg.sz_li_01" and $EVTPART1 eq "open"){
fhem("set FensterDummy open");;
}
elseif($NAME eq "sec.tfk.eg.sz_li_02" and $EVTPART1 eq "open" and $state1 eq "closed"){
fhem("set FensterDummy tilted");;
}
else{
fhem("set FensterDummy closed");;
}
}


Die TFKs haben eine Besonderheit:
Wenn das Fenster ganz offen steht, sind beide TFKs im Zustand offen (bzw. tilted + open), wenn das Fenster gekippt ist, nur einer. Das habe ich versucht in obigem Code zu berücksichtigen mit $state1 und $state2 und der Auswertung in den if-Zweigen.

Ich denke, mein Fehler ist entweder im Suchmuster des Notify oder in meiner "Eventauswertung" zu suchen. Für die Events habe ich auch schon $EVENT versucht, auch erfolglos. Beim Suchmuster bin ich mir nicht so sicher, ob das falsch ist, da es so im Eventmonitor das liefert was ich sehen will. Jedenfalls sehe ich jetzt den Wald vor lauter Bäumen nicht mehr. :(

Denkanstoß willkommen. :-)

Lösung:
Zwischen Notify Bedingung und dem (Perl) Ausführungsteil muss ein Leerzeichen sein. Erstellt man das Notify mit "(DEV_REGEX1|DEV_REGEX2){PERLCODE}" funktioniert das Notify nicht (der Codemirror Editor meckert im übrigen auch nicht).

DeeSPe


  • Statt InternalVal("sec.tfk.eg.sz_li_....","STATE","") lieber ReadingsVal("sec.tfk.eg.sz_li_....","state","") benutzen.
  • Bei (open|closed|tilted), ohne vorheriges Reading, gibt es kein $EVTPART1.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

Beta-User

Schau' Dir doch mal structure an. Evtl. muß die priority angepaßt werden...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Jorge3711

Zitat von: DeeSPe am 04 Juni 2017, 22:31:33

  • Statt InternalVal("sec.tfk.eg.sz_li_....","STATE","") lieber ReadingsVal("sec.tfk.eg.sz_li_....","state","") benutzen.
  • Bei (open|closed|tilted), ohne vorheriges Reading, gibt es kein $EVTPART1.

Gruß
Dan

Warum lieber die Readings abfragen statt den Internals? Habe die if Abfragen auf $EVENT geändert und das ganze sieht jetzt so aus:

sec.tfk.eg.sz_li.*:(open|closed|tilted){
my state1 = ReadingsVal("sec.tfk.eg.sz_li_01", "state", nA);;
my state2 = ReadingsVal("sec.tfk.eg.sz_li_02", "state", nA);;
if($NAME eq "sec.tfk.eg.sz_li_01" and $EVENT eq "open"){
fhem("set FensterDummy open");;
}
elsif($NAME eq "sec.tfk.eg.sz_li_02" and $EVENT eq "tilted" and $state1 eq "closed"){
fhem("set FensterDummy tilted");;
}
else{
fhem("set FensterDummy closed");;
}
}


Leider ändert sich der FensterDummy nicht bei Statuswechsel der Fenster.

@Beta_User:
Da ich das ganze als Perl-Fingerübung sehe kommt structure nicht in Frage. Ich möchte es mit Notify/Perl lösen. :)

DeeSPe

Zitat von: Jorge3711 am 05 Juni 2017, 09:20:07
Warum lieber die Readings abfragen statt den Internals?

Weil man das nun mal so macht!
STATE kann vom User mit z.B. stateFormat beliebig angepasst werden.
Das Reading state nimmt normalerweise nur bestimmte Werte(bereiche) an.
STATE wird so ziemlich als letztes gesetzt, weil es eben noch z.B. durch stateFormat durch muss.

Der Defaultwert bei ReadingsVal gehört in Anführungszeichen wenn er keine Zahl ist.

Wird denn das notify überhaupt getriggert bei open|tilted|closed?

Gruß
Dan

EDIT: Was spricht dagegen zwischendurch mal ein paar Log/Debug Ausgaben einzubauen?
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

Jorge3711

#5
Zitat von: DeeSPe am 05 Juni 2017, 10:28:54
Weil man das nun mal so macht!
STATE kann vom User mit z.B. stateFormat beliebig angepasst werden.
Das Reading state nimmt normalerweise nur bestimmte Werte(bereiche) an.
STATE wird so ziemlich als letztes gesetzt, weil es eben noch z.B. durch stateFormat durch muss.

Der Defaultwert bei ReadingsVal gehört in Anführungszeichen wenn er keine Zahl ist.

Danke für die Erklärung! :-)

Zitat
EDIT: Was spricht dagegen zwischendurch mal ein paar Log/Debug Ausgaben einzubauen?

Nichts, und das hat mich fuxig gemacht, weil ich noch nicht mal ein einfachst Notify mit Perlcode Debug("Hallo Welt!") hinbekommen habe. Bis ich irgendwann darauf gekommen bin, dass zwischen den runden Klammern der Notify-Bedingung und den geschweiften Klammern ein Leerzeichen sein muss. Danach funktionierten meine Notifys alle und ich konnte lernen.

Schlußendlich sieht mein Notify jetzt so aus und tut was ich erwarte:


Internals:
   CFGFN
   DEF        sec.tfk.eg.sz_li.*:contact:.* {
if($NAME eq "sec.tfk.eg.sz_li_01"){
fhem("set FensterDummy $EVTPART1");;
Log3("$NAME", 3, "Fenster $NAME was $EVTPART1");;
}
elsif($NAME eq "sec.tfk.eg.sz_li_02"){
my $state1 = ReadingsVal("sec.tfk.eg.sz_li_01", "state", "nA");;
if($state1 eq "closed"){
fhem("set FensterDummy $EVTPART1");;
Log3("$NAME", 3, "Fenster $NAME was $EVTPART1");;
}
else{}
}
}
   NAME       n_sz_window
   NOTIFYDEV  sec.tfk.eg.sz_li.*
   NR         8337
   NTFY_ORDER 50-n_sz_window
   REGEXP     sec.tfk.eg.sz_li.*:contact:.*
   STATE      2017-06-07 18:15:10
   TYPE       notify
   Readings:
     2017-06-07 11:31:34   state           active
Attributes:


Schlussendlich hat mich dieses Leerzeichen fast das gesamte lange Wochenende gekostet, grml.