Wie Notify nur täglich ausführen und nicht bei jedem Trigger?

Begonnen von Grinsekatze, 02 September 2017, 11:26:10

Vorheriges Thema - Nächstes Thema

Per

Soll pro Pflanze oder pro Nachricht pro Tag nur eine Nachricht kommen?
Pro Pflanze geht einfach:
define Di_FlowerSensor DOIF (["Pflanzensensor.*:minFertility.low"] and [?SELF.cmd] == 8) \
({DebianMail('<Email>', 'Smarthome: Pflanzenstand', 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu wenig Fruchtbarkeit! Gebe etwas Dünger zum Wasser!', '')}) \
DOELSEIF (["Pflanzensensor.*:maxFertility.high"] and [?SELF:cmd] == 8) \
({DebianMail('<Email>', 'Smarthome Fuhrmann: Pflanzenstand', 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu viel Fruchtbarkeit! Der Boden ist zu stark gedüngt!', '')}) \
DOELSEIF (["Pflanzensensor.*:minLux.low"] and [?SELF:cmd] == 8) \
({DebianMail('<Email>', 'Smarthome: Pflanzenstand', 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu wenig Sonneneinstrahlung! Stelle sie ins Licht!', '')}) \
DOELSEIF (["Pflanzensensor.*:maxLux.high"] and [?SELF:cmd] == 8) \
({DebianMail('<Email>', 'Smarthome: Pflanzenstand', 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu viel Sonneneinstrahlung! Stelle sie in den Schatten!', '')}) \
DOELSEIF (["Pflanzensensor.*:minMoisture.low"] and [?SELF:cmd] == 8) \
({DebianMail('<Email>', 'Smarthome: Pflanzenstand', 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu wenig Wasser! Gieße die Pflanze!', '')}) \
DOELSEIF (["Pflanzensensor.*:maxMoisture.high"] and [?SELF:cmd] == 8) \
({DebianMail('<Email>', 'Smarthome: Pflanzenstand', 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu viel Wasser! Entferne etwas Wasser!', '')}) \
DOELSEIF (["Pflanzensensor.*:minTemperature.low"] and [?SELF:cmd] == 8) \
({DebianMail('<Email>', 'Smarthome: Pflanzenstand', 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') ist zu kalt! Stelle sie an einen wärmeren Ort!', '')}) \
DOELSEIF (["Pflanzensensor.*:maxTemperature.high"] and [?SELF:cmd] == 8) \
({DebianMail('<Email>', 'Smarthome: Pflanzenstand', 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') ist zu warm! Stelle sie an einen kälteren Ort!', '')}) \
DOELSEIF ([00:00])
attr Di_FlowerSensor comment Doif zum Überwachen der Pflanzensensoren.


Pro Meldung könntest du ein Flag/Userreading setzen und auswerten. Ist halt etwas mehr Schreibarbeit.

Grinsekatze

Es soll pro Pflanze nur jeweils eine Meldung pro DOIF-Zweig kommen. Wenn Also Pflanze 1 z.B. mehr Wasser und mehr Dünger benötigt, dann soll beides per Nachricht mitgeteilt werden - aber eben nur 1x pro Tag. Wenn aber Pflanze 2 auch mehr Wasser benötigt und etwa mehr Licht, dann soll das auch am selben Tag mitgeteilt werden (aber eben auch nur 1x pro Tag).

Ich hatte zunächst auch überlegt, ob ich es mit UserReadings im DOIF löse. Etwa per z.B. für Dünger (zu weinig) setreading Di_FlowerSensor "Fertility_".$DEVICE "low" die benötigten Readings erstellen und dann deie DOIF-Bedingungen um einen Timestamp-Check der benötigten UserReadings ergänzen. Doch da kam ich erstmal nicht weiter mit dem Timestamp-Vergleich. :D

Ich pobiere mal deinen Vorschlag aus, Danke.

Per

Zitat von: Grinsekatze am 07 September 2017, 23:56:21Doch da kam ich erstmal nicht weiter mit dem Timestamp-Vergleich.
"Billig-Variante": auf "true" oder "gesendet" setzen und  [0:00] alles resetten.

Grinsekatze

So richtig funktioniert die Lösung von Per nicht.
Ich bekomme seit Donnerstag keine Nachrichten mehr.

Dafür habe ich diese Meldungen im Log gefunden (für alle cmd des DOIF):
2017.09.08 06:00:45 1: PERL WARNING: Argument "" isn't numeric in numeric eq (==) at (eval 415940) line 1.
2017.09.08 06:00:45 3: eval: Di_FlowerSensor: warning in condition c03



Was bewirkt [?SELF:cmd] == 8 eigentlich?

Grinsekatze

So, ich habe meinen DOIF mal angepasst - und wieder komme ich nicht weiter. Langsam fühle ich mich wie ein Grundschüler. :/

define Di_FlowerSensor DOIF (["Pflanzensensor.*:minFertility.low"] and [?SELF:alarm.$DEVICE.Fertility] ne "low") \
({DebianMail('<E-Mail>', 'Smarthome: Pflanzenzustand: '.AttrVal("$DEVICE","alias","$DEVICE"), 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu wenig Fruchtbarkeit! Gebe etwas Dünger zum Wasser!', '')},\
(setreading $SELF alarm$DEVICEFertility low)) \
DOELSEIF (["Pflanzensensor.*:maxFertility.high"] and [?SELF:alarm.$DEVICE.Fertility] ne "high") \
({DebianMail('<E-Mail>', 'Smarthome: Pflanzenzustand: '.AttrVal("$DEVICE","alias","$DEVICE"), 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu viel Fruchtbarkeit! Der Boden ist zu stark gedüngt!', '')},\
(setreading $SELF alarm$DEVICEFertility high)) \
DOELSEIF (["Pflanzensensor.*:minLux.low"] and [?SELF:alarm.$DEVICE.Lux] ne "low") \
({DebianMail('<E-Mail>', 'Smarthome: Pflanzenzustand: '.AttrVal("$DEVICE","alias","$DEVICE"), 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu wenig Sonneneinstrahlung! Stelle sie ins Licht!', '')},\
(setreading $SELF alarm$DEVICELux low)) \
DOELSEIF (["Pflanzensensor.*:maxLux.high"] and [?SELF:alarm.$DEVICE.Lux] ne "high") \
({DebianMail('<E-Mail>', 'Smarthome: Pflanzenzustand: '.AttrVal("$DEVICE","alias","$DEVICE"), 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu viel Sonneneinstrahlung! Stelle sie in den Schatten!', '')},\
(setreading $SELF alarm$DEVICELux high)) \
DOELSEIF (["Pflanzensensor.*:minMoisture.low"] and [?SELF:alarm.$DEVICE.Moisture] ne "low") \
({DebianMail('<E-Mail>', 'Smarthome: Pflanzenzustand: '.AttrVal("$DEVICE","alias","$DEVICE"), 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu wenig Wasser! Gieße die Pflanze!', '')},\
(setreading $SELF alarm$DEVICEMoisture low)) \
DOELSEIF (["Pflanzensensor.*:maxMoisture.high"] and [?SELF:alarm.$DEVICE.Moisture] ne "high") \
({DebianMail('<E-Mail>', 'Smarthome: Pflanzenzustand: '.AttrVal("$DEVICE","alias","$DEVICE"), 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') hat zu viel Wasser! Entferne etwas Wasser!', '')},\
(setreading $SELF alarm$DEVICEMoisture high)) \
DOELSEIF (["Pflanzensensor.*:minTemperature.low"] and [?SELF:alarm.$DEVICE.Temperature] ne "low") \
({DebianMail('<E-Mail>', 'Smarthome: Pflanzenzustand: '.AttrVal("$DEVICE","alias","$DEVICE"), 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') ist zu kalt! Stelle sie an einen wärmeren Ort!', '')},\
(setreading $SELF alarm$DEVICETemperature low)) \
DOELSEIF (["Pflanzensensor.*:maxTemperature.high"] and [?SELF:alarm.$DEVICE.Temperature] ne "high") \
({DebianMail('<E-Mail>', 'Smarthome: Pflanzenzustand: '.AttrVal("$DEVICE","alias","$DEVICE"), 'Die Pflanze ('.AttrVal("$DEVICE","alias","$DEVICE").') ist zu warm! Stelle sie an einen kälteren Ort!', '')},\
(setreading $SELF alarm$DEVICETemperature high)) \
DOELSEIF ([00:00]) \
((setreading $SELF alarm*Fertility ok),\
(setreading $SELF alarm$DEVICELux ok),\
(setreading $SELF alarm$DEVICEMoisture ok),\
(setreading $SELF alarm$DEVICETemperature ok))
attr Di_FlowerSensor comment Doif zum Überwachen der Pflanzensensoren.
attr Di_FlowerSensor icon helper_doif


Wie man schön erkennen kann habe ich nun für jeden Sensor max. 4 Readings (alarm[Device][Fertility|Lux|Moisture|Temperature]) die drei Werte annehmen können: "low" (dann wird die Low-Warnung getrigert) "high" und "ok" (ist dann wird gar nichts getriggert).

Ich habe jedoch ein Problem beim reseten der Readings: Wenn ich im Reading $DEVICE verwende, dann wird (logischer weise) nur der Reading vom letzten auslösenden Device benutzt. * wird nicht angenommen. Gibt es eine Möglichkeit für die Reading-Angabe bei setreading einen RegEx zu verwenden (und ja, welchen)?

Ich habe früher mit diversen Sprachen gearbeitet. Doch hier ist die Syntax manchmal echt ekelig, etwa ein alarm$DEVICETemperature würde mir viel besser als alarm.$DEVICE.Temperature gefallen (aber dann auch hinterher ohne die Punkte im Namen).

Benni

Zitat von: Grinsekatze am 09 September 2017, 11:45:52
Ich habe früher mit diversen Sprachen gearbeitet. Doch hier ist die Syntax manchmal echt ekelig,

Dann vielleicht doch lieber mit notify und etwas Perl  ;D

*duckundweg*

betateilchen

und vor allem nicht so einen kompletten Roman in das DEF eines devices schreiben...

ZitatIch habe früher mit diversen Sprachen gearbeitet. Doch hier ist die Syntax manchmal echt ekelig,

Dann nimm ein einfaches notify, da kannst Du mit purem perl arbeiten. Das ist wenigstens verständlich.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

CoolTux

Ich wollte es gerade schreiben. Wo wir wieder bei DOIF wären und wie einfach es doch sein soll.

Aber egal. Warum zum Teufel wird nicht Udo sein Vorschlag von Seite 1 verwendet. Es ist das einfachste. Wenn man dann etwas weiter denkt macht man folgendes.

Man triggert auf alle Pflanzen und Events die man braucht. Man bastellt mit Perl ReadingAge Abfrage auf ein Reading im Notify. Am Ende setzt man das Reading für das Notify, es sollte aus Device und Event bestehen. Also readingname Pflanze1humidity value High. Das Reading ist zum unterscheiden der Devices und Events aber vor allem für den Timestamp. Das sind nicht Mal 8 Zeilen Perlcode.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Beta-User

Nur eine Anmerkung am Rande:

Einige wenige solcher eleganter und ausgetesteter Varianten im Wiki (Udo: keep cool) oder von mir aus angepinnt bei Automatisierung, dann würde sich vielleicht der eine oder andere überlegen, ob er das mit notify/perl nicht einfach ausprobiert.

So sind viele "Verluste" an "höhere" Module zu "beklagen" :'( ... und ich bin nicht der einzige, der sich einigermaßen frustriert von diesem Irrweg DOIF abgekehrt habt.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

CoolTux

Wenn ich heute Abend dazu kommen kann ich versuchen ein Beispiel zu erstellen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Grinsekatze

#25
Zitat von: CoolTux am 09 September 2017, 12:19:41Man triggert auf alle Pflanzen und Events die man braucht. Man bastellt mit Perl ReadingAge Abfrage auf ein Reading im Notify. Am Ende setzt man das Reading für das Notify, es sollte aus Device und Event bestehen. Also readingname Pflanze1humidity value High. Das Reading ist zum unterscheiden der Devices und Events aber vor allem für den Timestamp. Das sind nicht Mal 8 Zeilen Perlcode.

Das habe ich im Groben auch überlegt. Aber da ich nun schon ein DOIF gebaut habe, wollte ich zunächst testen, ob ich es damit auch umgesetzt bekomme.

Ich habe hier noch eine aktuellere Version des DOIF. Dort habe ich zum Schluss dann notgedrungener Weise deletereading verwendet und bei den Meldungen auch ein Log 3 Eintrag erstellt. Aber alleine, dass ich ewig den gleichen Code für jeden DOIF-Zweig angeben muss und es nicht zentral definieren und dann darauf zugreifen kann (ok, ginge per myUtlis) stört mich ja schon am DOIF. Ich finde die alten Notifys erheblich verständlicher - und oft auch kürzer.


Gut, ich habe meinen ursprünglichen Notify einmal erweitert:
define Notify_FlowerSensor notify Pflanzensensor.*:(minFertility|minLux|minMoisture|minTemperature|maxFertility|maxLux|maxMoisture|maxTemperature).(low|high) {\
my $alert;;\
my $device;;\
my $reading;;\
$device = AttrVal("$NAME","alias","$NAME");;\
$reading = "Fertility" if ($EVTPART0 =~ /Fertility$/);;\
$reading = "Lux"  if ($EVTPART0 =~ /Lux$/);;\
$reading = "Moisture"  if ($EVTPART0 =~ /Moisture$/);;\
$reading = "Temperature"  if ($EVTPART0 =~ /Temperature$/);;\
if ({ReadingsAge($SELF,$reading,0)} >= 86400) {\
if ($EVTPART1 eq "low") {\
$alert = "Die Pflanze (".$device.") hat zu wenig Fruchtbarkeit! Gebe etwas Dünger zum Wasser!" if ($EVTPART0 eq "minFertility");;\
$alert = "Die Pflanze (".$device.") hat zu wenig Sonneneinstrahlung! Stelle sie ins Licht!" if ($EVTPART0 eq "minLux");;\
$alert = "Die Pflanze (".$device.") hat zu wenig Wasser! Gieße die Pflanze!" if ($EVTPART0 eq "minMoisture");;\
$alert = "Die Pflanze (".$device.") ist zu kalt! Stelle sie an einen wärmeren Ort!" if ($EVTPART0 eq "minTemperature");;\
} elsif ($EVTPART1 eq "high") {\
$alert = "Die Pflanze (".$device.") hat zu viel Fruchtbarkeit! Der Boden ist zu stark gedüngt!" if ($EVTPART0 eq "maxFertility");;\
$alert = "Die Pflanze (".$device.") hat zu viel Sonneneinstrahlung! Stelle sie in den Schatten!" if ($EVTPART0 eq "maxLux");;\
$alert = "Die Pflanze (".$device.") hat zu viel Wasser! Entferne etwas Wasser!" if ($EVTPART0 eq "maxMoisture");;\
$alert = "Die Pflanze (".$device.") ist zu warm! Stelle sie an einen kälteren Ort!" if ($EVTPART0 eq "maxTemperature");;\
}\
setreading $SELF $NAME.$reading $EVTPART1
if ($alert) {DebianMail('<E-Mail>', 'Smarthome: Pflanzenstand', $alert, '')};;\
Log 3, "$device: Pflanzenwarnung: $alert" if ($alert);;\
}\
}
attr Notify_FlowerSensor comment Notify zum Überwachen der Pflanzensensoren.

CoolTux

#26
In meinen Augen viel zu viel Code. Alles wichtige kommt doch mit dem EVENT das musst Du doch nicht noch mal abfragen.
Alleine Deine RegEx geht viel viel kürzer.


define Notify_FlowerSensor notify Pflanzensensor.*:(min.*|max.*)
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Grinsekatze

#27
RegEx sind nicht gerade meine Stärke. Danke für den Tipp.

Edit:
Wobei ich jetzt nicht wirklich noch mehr Einsparpotential sehe.

$device benötige ich fürs Alias. Sonst kann hier im Haus niemand was mit der Meldung anfangen, weil sie dann nicht wissen, welche Pflanze gemeint ist.
$reading benötige ich, um die Anzahl der Readings gering zu halten. Sonst hätte ich pro Sensor 8 Readings. Jetzt sind es nur max. 4, da ich statt z.B. minTemperature und maxTemperature nur temperature verwende.
$alarm wird für die richtige Meldung benötigt.

Sonst werden ja nur die Bedingungen geprüft (Reading alt genug).

CoolTux

Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Damian

Zitat von: Grinsekatze am 09 September 2017, 14:34:32
Das habe ich im Groben auch überlegt. Aber da ich nun schon ein DOIF gebaut habe, wollte ich zunächst testen, ob ich es damit auch umgesetzt bekomme.

Ich habe hier noch eine aktuellere Version des DOIF. Dort habe ich zum Schluss dann notgedrungener Weise deletereading verwendet und bei den Meldungen auch ein Log 3 Eintrag erstellt. Aber alleine, dass ich ewig den gleichen Code für jeden DOIF-Zweig angeben muss und es nicht zentral definieren und dann darauf zugreifen kann (ok, ginge per myUtlis) stört mich ja schon am DOIF. Ich finde die alten Notifys erheblich verständlicher - und oft auch kürzer.


Gut, ich habe meinen ursprünglichen Notify einmal erweitert:
define Notify_FlowerSensor notify Pflanzensensor.*:(minFertility|minLux|minMoisture|minTemperature|maxFertility|maxLux|maxMoisture|maxTemperature).(low|high) {\
my $alert;;\
my $device;;\
my $reading;;\
$device = AttrVal("$NAME","alias","$NAME");;\
$reading = "Fertility" if ($EVTPART0 =~ /Fertility$/);;\
$reading = "Lux"  if ($EVTPART0 =~ /Lux$/);;\
$reading = "Moisture"  if ($EVTPART0 =~ /Moisture$/);;\
$reading = "Temperature"  if ($EVTPART0 =~ /Temperature$/);;\
if ({ReadingsAge($SELF,$reading,0)} >= 86400) {\
if ($EVTPART1 eq "low") {\
$alert = "Die Pflanze (".$device.") hat zu wenig Fruchtbarkeit! Gebe etwas Dünger zum Wasser!" if ($EVTPART0 eq "minFertility");;\
$alert = "Die Pflanze (".$device.") hat zu wenig Sonneneinstrahlung! Stelle sie ins Licht!" if ($EVTPART0 eq "minLux");;\
$alert = "Die Pflanze (".$device.") hat zu wenig Wasser! Gieße die Pflanze!" if ($EVTPART0 eq "minMoisture");;\
$alert = "Die Pflanze (".$device.") ist zu kalt! Stelle sie an einen wärmeren Ort!" if ($EVTPART0 eq "minTemperature");;\
} elsif ($EVTPART1 eq "high") {\
$alert = "Die Pflanze (".$device.") hat zu viel Fruchtbarkeit! Der Boden ist zu stark gedüngt!" if ($EVTPART0 eq "maxFertility");;\
$alert = "Die Pflanze (".$device.") hat zu viel Sonneneinstrahlung! Stelle sie in den Schatten!" if ($EVTPART0 eq "maxLux");;\
$alert = "Die Pflanze (".$device.") hat zu viel Wasser! Entferne etwas Wasser!" if ($EVTPART0 eq "maxMoisture");;\
$alert = "Die Pflanze (".$device.") ist zu warm! Stelle sie an einen kälteren Ort!" if ($EVTPART0 eq "maxTemperature");;\
}\
setreading $SELF $NAME.$reading $EVTPART1
if ($alert) {DebianMail('<E-Mail>', 'Smarthome: Pflanzenstand', $alert, '')};;\
Log 3, "$device: Pflanzenwarnung: $alert" if ($alert);;\
}\
}
attr Notify_FlowerSensor comment Notify zum Überwachen der Pflanzensensoren.


Und du bist sicher, dass der Code funktioniert? M. W. kennt notify kein $SELF.

Es ist die Frage, wie ausführlich man etwas programmieren will, alles was länger als 20-30 Perl-Zeilen ist, sollte man in eigene Routinen in myUtils auslagern, egal, ob mit notify oder DOIF.

Für mich hätte auch ein Dreizeiler für alle Devices gereicht z. B.:

[quote](["^Pflanzensensor:(low|high)$"] and [?$SELF:A_$DEVICE] ne "alert")
  ({DebianMail('yourname@gmail.com', 'FHEM - $EVENT warning from device: $DEVICE')}, setreading $SELF A_$DEVICE alert)
DOELSEIF ([00:00]) (deletereading $SELF A_.*)[/quote]


Alles Frage dessen, was man haben will.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF