Hallo,
ich setze bei meinem Waschmaschinen-Device den Status in Abhängigkeit von Stromverbrauch. Dies funktioniert bestens. Wenn ich aber den Statuswechsel im DOIF abfrage, ist dort immer der letzte Status im Event-Wert vorhanden.
Bsp.: Ich setze den Status der Waschmaschine von running auf done. Dann hat das Reading state der Waschmaschine den Wert done. Das Reading e_Waschmaschine_state des DOIF aber running.
Hier meine Definitionen:
Waschmaschine
defmod Waschmaschine dummy
attr Waschmaschine userattr configPowerDone
attr Waschmaschine configPowerDone 3.00
attr Waschmaschine devStateIcon Aus:general_aus@black An:scene_washing_machine@red
attr Waschmaschine devStateStyle style="text-align:right"
attr Waschmaschine group Statusinformationen
attr Waschmaschine icon scene_washing_machine@black
attr Waschmaschine room Bad,Statuszentrale
attr Waschmaschine sortby 0,5
attr Waschmaschine stateFormat { my $state = ReadingsVal($name, "state", "");; my $power = ReadingsVal($name, "power", "");; if($state eq 'on') { "An" } elsif($state eq "done") { "Fertig" } elsif($state eq "running") { "waschmaschine_03 ($power W)" } else { "Aus" } }
setstate Waschmaschine Fertig
setstate Waschmaschine 2017-04-30 20:02:36 power 2
setstate Waschmaschine 2017-04-30 20:02:37 state done
defmod Waschmaschine.Fertig.DOIF DOIF ([Waschmaschine:state] eq 'done') \
(set Sonos_Buero:FILTER=state=appeared Speak 25 de \
'Die Waschmaschine ist fertig!')
attr Waschmaschine.Fertig.DOIF do always
attr Waschmaschine.Fertig.DOIF event-on-change-reading .*
attr Waschmaschine.Fertig.DOIF wait 180
setstate Waschmaschine.Fertig.DOIF cmd_1
setstate Waschmaschine.Fertig.DOIF 2017-04-30 20:02:36 Device Waschmaschine
setstate Waschmaschine.Fertig.DOIF 2017-04-30 19:48:18 cmd 1
setstate Waschmaschine.Fertig.DOIF 2017-04-30 19:48:18 cmd_event Waschmaschine
setstate Waschmaschine.Fertig.DOIF 2017-04-30 19:48:18 cmd_nr 1
setstate Waschmaschine.Fertig.DOIF 2017-04-30 20:02:36 e_Waschmaschine_state running
setstate Waschmaschine.Fertig.DOIF 2017-04-30 19:48:18 state cmd_1
setstate Waschmaschine.Fertig.DOIF 2017-04-30 20:02:15 wait_timer no timer
Wie am Zeitstempel zu sehen ist, wird zum gleichen Zeitpunkt in dem Device Waschmaschine das Reading state auf done gesetzt und im DOIF das Reading e_Waschmaschine_state auf running.
Wo liegt der Fehler?
Viele Grüße
juemuc
Warum interessiert Dich dieses Reading im DOIF?
Gruß,
Thorsten
ZitatWarum interessiert Dich dieses Reading im DOIF?
Gruß,
Thorsten
In Abhängigkeit vom Wert "done" möchte ich eine Aktion starten
VG
juemuc
Dabei beziehst Du Dich doch auf Waschmaschine:state und nicht auf Waschmaschine.Fertig.DOIF:e_Waschmaschine_state. ...und das ist auch gut so. Nochmal: was willst Du jetzt mit e_Waschmaschine_state?
Gruß,
Thorsten
Durch die DOIF-Definition werte ich ja nicht den Status des Gerätes direkt aus, sondern das Event, welches durch die Statusänderung erzeugt wird. Ich vermute, dass Waschmaschine.Fertig.DOIF:e_Waschmaschine_state den Wert des Ereignisses darstellt. Der Wert von Waschmaschine.Fertig.DOIF:e_Waschmaschine_power stimmt ja auch immer mit dem Wert im Device überein. Ich könnte natürlich das DOIF anders definieren, aber ich wüsste gerne die Ursache für dieses Verhalten. Ich habe bisher alle meine DOIFs so definiert, dass sie das Ereignis auswerten.
Ich habe gerade festgestellt, dass auch eine Änderung der DOIF-Definition nicht zum Ziel führt. Das DOIF enthält wohl die notwendigen Informationen in den e_Waschmaschine_Readings. Ich bin ratlos.
VG
juemuc
Zitat von: juemuc am 01 Mai 2017, 14:10:05
Durch die DOIF-Definition werte ich ja nicht den Status des Gerätes direkt aus, sondern das Event, welches durch die Statusänderung erzeugt wird.
Hä?
Warum enthält dann Deine Definition das hier?
[Waschmaschine:state]
Gruß,
Thorsten
Genau das ist meine Frage. Warum funktioniert es nicht :-(
Ups. Ich werte ja schon den Status und nicht das Event aus. Sorry für die Verwirrung. Das Ergebnis ist aber sowohl bei der Abfrage des Ereignisses als auch bei der Abfrage des Status gleich.
Wenn sich der Status des Gerätes sich von running nach done ändert, reagiert das DOIF nicht. Es bei einer erneuten Änderung. Also immer eine Statusänderung später. Meine Vermutung ist nun, dass es an dem Inhalt dieser Variablen liegt.
VG
juemuc
Nein, es liegt daran, dass "state" ein etwas besonderes Reading ist.
Die Lösung ist wahrscheinlich einfach [Waschmaschine] anstatt [Waschmaschine:state] hinzuschreiben.
Alternativ beim DOIF das Attribut addStateEvent setzen.
Gruß,
Thorsten
Die Readings im DOIF, die mit e_ beginnen entsprechen den Events, für die sich das DOIF-Modul aufgrund der Definition interessiert. Diese stellen lediglich eine Information dar, die man für Analyzezwecke heranziehen kann.
2017-04-30 20:02:36 e_Waschmaschine_state running
bedeutet lediglich, dass um 20:02:36 das entsprechende Ereignis stattgefunden hat, welches aufgrund des fehlenden DOELSE-Zweigs in deiner Definition zu keiner Aktion geführt hat.
Ja das habe ich vermutet. Aber genau um diese Zeit wurde der Status des Device auf "done" gesetzt (über ein anderes DOIF). Diese Statusänderung kann ich im DOIF nicht erkennen, da hier immer der "alte" Status zur Verfügung steht.
1. DOIF erkennt Änderung des Stromverbrauchs und setzt den Wert in der Waschmaschine (funktioniert bestens)
2. DOIF erkennt Änderung des Stromverbrauchs in der Waschmaschine und setzt in Abhängigkeit des alten Status einen neuen Status (funktioniert bestens)
3. DOIF soll nun auf diese Statusänderung reagieren -> Funktioniert nicht, da hier noch der "letzte" Status zur Verfügung steht, der im 2. DOIF verändert wurde. (warum auch immer).
Ich habe dies gesplittet, um im dritten DOIF mit einem "wait" ggf. auf eine weitere Zustandsänderung reagieren zu können. Ansonsten funktionieren alle DOIFs wie gewünscht.
@Thorsten: Die von Dir vorgeschlagenen Anpassungen haben leider zu keinem Erfolg geführt.
VG
juemuc
Zitat von: juemuc am 01 Mai 2017, 18:40:23@Thorsten: Die von Dir vorgeschlagenen Anpassungen haben leider zu keinem Erfolg geführt.
Ok, dann muss sich das der DOIF-Meister nochmal anschauen oder Du baust das ganze um auf notify, dann kann ich Dir vielleicht helfen.
Ich kann mir nur noch vorstellen, dass das event-on-change-reading .* in einem DOIF seltsame Effekte haben kann.
Gruß,
Thorsten
Im notify kann ich aber keine Verzögerung einbauen oder. Das 3. DOIF soll nur dann ausgeführt werden, wenn die Waschmaschine nicht innerhalb von 3 Minuten ausgeschaltet wird :-) Ansonsten könnte ich die Meldung ja auch direkt im 2. DOIF mit ausgeben.
VG
juemuc
Zitat von: juemuc am 01 Mai 2017, 20:22:56
Im notify kann ich aber keine Verzögerung einbauen
Du kannst ein temporäres at oder sleep nutzen, aber mit DOIF ist's komfortabler.
Zitat von: juemuc am 01 Mai 2017, 20:22:56
Im notify kann ich aber keine Verzögerung einbauen oder. Das 3. DOIF soll nur dann ausgeführt werden, wenn die Waschmaschine nicht innerhalb von 3 Minuten ausgeschaltet wird :-) Ansonsten könnte ich die Meldung ja auch direkt im 2. DOIF mit ausgeben.
Üblicherweise macht man das in etwa so:
define blabla notify Waschmaschine:.done sleep 180;; IF ([Waschmaschine] eq "done") (tuwasauchimmerdutunwillst)
Gruß,
Thorsten
Gib mal ein list des DOIF, wenn es nicht macht, was es machen sollte (sprich wenn die Waschmaschine "done" ist)
Hallo,
hier kann sehr schön erkennen, dass um 21:22:45 das DOIF den Wert running und das Device den Wert done bekommen hat.
defmod Waschmaschine.Fertig.DOIF DOIF ([Waschmaschine:state] eq 'done') \
(set Sonos_Buero:FILTER=state=appeared Speak 25 de \
'Die Waschmaschine ist fertig!')
attr Waschmaschine.Fertig.DOIF do always
attr Waschmaschine.Fertig.DOIF wait 180
setstate Waschmaschine.Fertig.DOIF initialized
setstate Waschmaschine.Fertig.DOIF 2017-05-01 21:22:45 Device Waschmaschine
setstate Waschmaschine.Fertig.DOIF 2017-04-30 22:39:23 cmd 0
setstate Waschmaschine.Fertig.DOIF 2017-05-01 21:22:45 e_Waschmaschine_state running
setstate Waschmaschine.Fertig.DOIF 2017-04-30 22:39:23 state initialized
defmod Waschmaschine dummy
attr Waschmaschine userattr configPowerDone
attr Waschmaschine configPowerDone 3.00
attr Waschmaschine devStateIcon Aus:general_aus@black An:scene_washing_machine@red
attr Waschmaschine devStateStyle style="text-align:right"
attr Waschmaschine event-on-change-reading .*
attr Waschmaschine group Statusinformationen
attr Waschmaschine icon scene_washing_machine@black
attr Waschmaschine room Bad,Statuszentrale
attr Waschmaschine sortby 0,5
attr Waschmaschine stateFormat { my $state = ReadingsVal($name, "state", "");; my $power = ReadingsVal($name, "power", "");; if($state eq 'on') { "An" } elsif($state eq "done") { "Fertig" } elsif($state eq "running") { "waschmaschine_03 ($power W)" } else { "Aus" } }
setstate Waschmaschine Fertig
setstate Waschmaschine 2017-05-01 21:22:45 power 1.28
setstate Waschmaschine 2017-05-01 21:22:45 state done
VG
juemuc
bitte ein list, d.h. list Waschmaschine.Fertig.DOIF in die Kommandozeile eingeben.
Ansonsten denke ich auch (wie von Thorsten schon gesagt) du solltest mal
([Waschmaschine] eq 'done')
verwenden
Hallo,
anbei die Info. Allerdings hat die Waschmaschine den aktuell den Status off/Aus.
Internals:
DEF ([Waschmaschine:state] eq 'done')
(set Sonos_Buero:FILTER=state=appeared Speak 25 de
'Die Waschmaschine ist fertig!')
NAME Waschmaschine.Fertig.DOIF
NR 135
NTFY_ORDER 50-Waschmaschine.Fertig.DOIF
STATE cmd_1
TYPE DOIF
Readings:
2017-05-01 21:28:45 Device Waschmaschine
2017-05-01 21:31:45 cmd 1
2017-05-01 21:31:45 cmd_event Waschmaschine
2017-05-01 21:31:45 cmd_nr 1
2017-05-01 21:28:45 e_Waschmaschine_state done
2017-05-01 21:31:45 state cmd_1
2017-05-01 21:31:45 wait_timer no timer
Condition:
0 ReadingValDoIf($hash,'Waschmaschine','state') eq 'done'
Devices:
0 Waschmaschine
all Waschmaschine
Do:
0:
0 set Sonos_Buero:FILTER=state=appeared Speak 25 de 'Die Waschmaschine ist fertig!'
1:
Helper:
event power: 0.00
globalinit 1
last_timer 0
sleepdevice Waschmaschine
sleepsubtimer -1
sleeptimer -1
timerdev Waschmaschine
timerevent power: 0.00
triggerDev Waschmaschine
timerevents:
power: 0.00
off
timereventsState:
power: 0.00
off
triggerEvents:
power: 0.00
off
triggerEventsState:
power: 0.00
off
Internals:
Itimer:
Readings:
0 Waschmaschine:state
all Waschmaschine:state
Regexp:
0:
All:
State:
State:
Trigger:
Attributes:
do always
wait 180
Die Tipps von Thorsten habe ich schon ohne Erfolg ausprobiert. Das notify funktioniert auch nur mit
define Waschmaschine.Fertig.notify notify Waschmaschine:.*
Weder done noch Fertig anstatt des * funktioniert.
VG
juemuc
Zitat von: juemuc am 01 Mai 2017, 22:13:38
define Waschmaschine.Fertig.notify notify Waschmaschine:.*
Weder done noch Fertig anstatt des * funktioniert.
Auch nicht das?
define Waschmaschine.Fertig.notify notify Waschmaschine:done
...also ohne den Punkt.
Gruß,
Thorsten
das "list" ist natürlich nur interessant, wenn das DOIF gerade nicht macht, was es soll...
Schalte mal deinen Dummy manuell und gucke im Event-Monitor, was da ankommt.
Ich werde wohl auf das 3. DOIF verzichten und das 2. DOIF ausbauen. ICh muss hier nur noch den sleep-befehl vernünftig einbauen.
DOELSEIF \
([Waschmaschine:power] <= AttrVal("Waschmaschine", \
"configPowerDone", 3) and \
[Waschmaschine:state] eq 'running') \
(set Waschmaschine done,\
IF ([Waschmaschine:state] eq "done") \
(set Sonos_Buero:FILTER=state=appeared Speak 5 de \
'Die Waschmaschine ist fertig!'))
(set Waschmaschine done,\
sleep 180,\
IF ([Waschmaschine:state] eq "done") \
(set Sonos_Buero:FILTER=state=appeared Speak 5 de \
'Die Waschmaschine ist fertig!')
blockiert fhem für 3 Minuten.
VG
juemuc
PS.: Mehr leider erst wieder am nächsten WE. Vorerst Danke für Eure Unterstützung.
du kannst das auch ohne sleep lösen :
(
(set Waschmaschine done)
(IF ([Waschmaschine:state] eq "done") \
(set Sonos_Buero:FILTER=state=appeared Speak 5 de \
'Die Waschmaschine ist fertig!')
)
)
mit wait 0,180
Zitat von: juemuc am 01 Mai 2017, 22:45:41blockiert fhem für 3 Minuten.
In meinem notify-Beispiel blockiert das sleep nicht. Ich finde es etwas seltsam, wenn es im DOIF blockiert.
@Damian: ??
Gruß,
Thorsten
Sleep blockiert auch beim IF und DOIF nicht, wenn man es "richtig" angibt. Die Sache ist aber historisch bedingt nicht einheitlich geregelt.
Beim DOIF kann man auch mit Semikolons als Trennzeichen arbeiten, daher reicht hinter Sleep ein Semikolon als Trennzeichen. Ein Sleep mit Komma dahinter blockiert bei DOIF.
IF kann nicht mit Semikolons als Trennzeichen arbeiten. Ich habe inzwischen aber eingebaut, dass beim IF ein Komma hinter einem Sleep nicht blockiert.
Hallo Damian,
wie muss ich den hier den sleep-Befehl einbinden (nach dem set Waschmaschine done)?
DOELSEIF
([Waschmaschine:power] <= AttrVal("Waschmaschine",
"configPowerDone", 3) and
[Waschmaschine:state] eq 'running')
(set Waschmaschine done,
IF ([Waschmaschine:state] eq "done")
(set Sonos_Buero:FILTER=state=appeared Speak 1 de
'Die Waschmaschine ist fertig!'))
Wenn ich das Komma durch ein Semikolon ersetze, kommt die Fehlermeldung
Zitatset Waschmaschine done; IF (running eq "done") (set Sonos_Buero:FILTER=state=appeared Speak 1 de 'Die Waschmaschine ist fertig!'): Bareword "running" not allowed while "strict subs" in use at (eval 8138) line 1
Wenn ich aber kein Semikolon setze, blockiert der sleep-Befehl.
VG
juemuc
Zitat von: juemuc am 05 Mai 2017, 22:52:21
Hallo Damian,
wie muss ich den hier den sleep-Befehl einbinden (nach dem set Waschmaschine done)?
DOELSEIF
([Waschmaschine:power] <= AttrVal("Waschmaschine",
"configPowerDone", 3) and
[Waschmaschine:state] eq 'running')
(set Waschmaschine done,
IF ([Waschmaschine:state] eq "done")
(set Sonos_Buero:FILTER=state=appeared Speak 1 de
'Die Waschmaschine ist fertig!'))
Wenn ich das Komma durch ein Semikolon ersetze, kommt die Fehlermeldung Wenn ich aber kein Semikolon setze, blockiert der sleep-Befehl.
VG
juemuc
in dem Fall mit Befehlssequenzen mit wait arbeiten:
DOELSEIF
([Waschmaschine:power] <= AttrVal("Waschmaschine",
"configPowerDone", 3) and
[Waschmaschine:state] eq 'running')
(set Waschmaschine done)
(IF ([Waschmaschine:state] eq "done")
(set Sonos_Buero:FILTER=state=appeared Speak 1 de
'Die Waschmaschine ist fertig!'))
wait 0,<Sekundenangabe>
@Damian: Vielen Dank für Deinen Hinweis. Damit funktioniert es wie gewünscht und ich kann auf ein weiteres DOIF verzichten.
VG
juemuc