Hallo,
ich hoffe mir kann jemand helfen das ganze ans laufen zu bekommen und am besten noch so das ich verstehe was ich da mache.
Idee:
Das Reading "alarm"der DS18B20 zu nutzen um eine Meldung per Mail zu generieren wenn die Temperatur einen bestimmten Wert unterschreitet und "alarm" auf "1" gesetzt wird.
Die DHT22 Sensoren haben ein Userreading "alarm".
Nach der Meldung wird der dummy Frostalarm auf "Alarm" gesetzt und soll weitere Mails unterbinden solange die Alarm nicht zurückgesetzt wurde.
aktueller Code mit diversen Problemen:
.*DHT22:.*|.*_Temp:.* {
my $alarm=ReadingsVal($_,"alarm","0");
my $temp=ReadingsVal($_,"temperature","122");
my $templow=ReadingsVal($_,"templow","122");
my $Status=InternalVal("Frostalarm","STATE","tilt");
{ if (($alarm !~ m/0/) && ($Status eq "Aus" {
{DebianMail('mail@mail.de','FHEM Frostwarnung','Die Temperatur von ' .$NAME. ' liegt bei ' .$temp)}
fhem ("set Frostalarm on");
Log 3, "$NAME : Frostwarnung Temp: $temp";
}
else {
fhem ("set Frostalarm off");
Log 3,"$NAME : Frostwarnung Temp: $temp";
}
}
}
"$_" ist wohl mein erster Fehler, da die Werte nicht korrekt bzw. gar nicht übernommen werden.
Mir sind da leider aufgrund fehlender Kenntnis die Ideen ausgegangen.
Im Log werden 2 Einträge über else generiert, und zwar für jedes geänderte Reading eines Devices.
Hier temperature und alarm
2016.01.12 15:23:59 3: EMZ_Temp : Frostwarnung Temp: 122
2016.01.12 15:23:59 3: EMZ_Temp : Frostwarnung Temp: 122
das ("set Frostalarm off") ist leider auch noch nicht von großer Dauer, da so bei jedem 3.ten Lauf wieder der Stauts wieder Aus.
Ich hoffe das ist einigermaßen verständlich :-[
Gruß
Sven
Fangen wir mal an Anfang an:
Als sich die Biene auf die Blume setzte ... :P - ne Blödsinn (sorry).
Ich hab nur grad etwas Zeit und würde mich breit schlagen lassen das mit dir durchzugehen.
Erstmal - brav das du das über das DEF machst.
Das erleichtert die Hilfe ungemein.
Hier
.*DHT22:.*|.*_Temp:.* {
triggert dein notify auf
-) alles was auf DHT22 UND
-) alles was auf _Temp endet
--) mit allen Readings die die Geräte haben.
Willst du das so?
Was DHT22 ist verstehe ich noch aber was sind die Geräte mit _Temp am Schluss?
Wie gesagt - wir gehen es mal langsam an.
Edith: Ich liefer dir deswegen keine fertige Lösung (obwohl es für mich schneller erledigt wäre) weil ich möchte das du verstehst was der Code macht.
Alternativ: Mit einem DOIF ist auch lösbar, etwa so
define di DOIF ([Sensor:temperature] < [Sensor:templow] ) (({DebianMail(...)}))
DOELSEIF ([Sensor:temperature] > ([Sensor:templow] + 3))
Sendet 1 Mail und dann erst wieder, wenn die Temperatur 3°C über templow liegt und danach templow wieder unterschritten wird.
@Ellert
Du hattest 5 Minuten Zeit meinen Beitrag zu lesen.
Wenn du dir die Zeit nimmst und dem TE erklärst was der/DEIN Code macht darfst du gerne weiter machen und ich bin raus.
Moin Puschel74,
vielen Dank für Dein Angebot mir das ganze zu erklären.
"_Temp" ist im Namen aller DS18B20 Devices vorhanden. Bsp. (EMZ_Temp)
Die Abfrage soll alle Devices abfangen mit alarm Reading. (momentan 5 Stk.)
Aber ich benötige für die Mail ja auch das Reading "temperature".
@Ellert
Danke für den Vorschlag,
aber wie gesagt ich möchte das ganze was ich da zusammen stricke auch verstehen und nicht ewig hier den DAU spielen.
und da es sich um mehrere Sensoren handel die auch gerne noch zuwachs bekommen, ist eine variable Lösung, die ich nicht jedes mal erweitern muss besser.
Gruß
Sven
Mit dem Hinweis auf DOIF und dem schlichten Beispiel wollte ich zeigen, dass es auf der FHEM-Ebene möglich ist fast ohne Perl-Code auszukommen.
Das DOIF war für mich als Einsteiger vor etwa einem Jahr eine gute Hilfe, da ich mit Perl und Regulären Ausdrücken noch keine Erfahrung hatte.
Bei Interesse, hätte ich natürlich geholfen eine individuelle Lösung zu entwickeln.
Das DOIF bietet in einer funktionierenden Testversion DOIF neue Features: Generalisierung, $DEVICE, $EVENT, Attribut notexist (http://forum.fhem.de/index.php/topic,46327.msg380929.html#msg380929) die Möglichkeit Gerätenamen über Reguläre Ausdrücke anzusprechen.
Eine Lösung mit einem notify und Perlcode zu suchen ist ein guter Weg Erfahrungen zu sammeln, genauso wie das Verwenden von Alternativen.
Bin natürlich auch für alle Ideen offen.
Hatte nur irgendwie im Kopf das DOIF nichts für mehrere Devices ist.
Aber lasse mich auch gerne hier eines besseren beleeren.
Hat sich wohl auch einiges geändert zum Jahreswechsel.
DOIF geht genauso, da ich es aber nicht benutze kann ich nur Hilfe zu notify anbieten.
Zitat"_Temp" ist im Namen aller DS18B20 Devices vorhanden. Bsp. (EMZ_Temp)
Ok, soll dann bei Änderung des Reading
temperature das notify triggern oder wenn sich
alarm ändert?
Wenn es nur bei alarm auslösen soll und du KEINE anderen Sensoren mit diesem reading hast genügt ein einfaches:
.*:alarm
als regexp.
Hier triggert von JEDEM Device das Reading alarm wenn es ein Event generiert.
Events kannst du dir im EventMonitor anschauen.
Wenn es mehrere Geräte mit dem Reading gibt und es sollen NUR deine Geräte mit _Temp am Ende des Namens triggern dann sollte das regexp so
.*_Temp:alarm
aussehen.
An das Reading temperatur kommen wir im notify immer noch dran ;)
Soll aber von JEDEM Geräte das Reading alarm UND temperatur triggern dann passt dieses regexp:
.*:(alarm|temperature).*
Aber ACHTUNG! Hier triggert JEDES Event des Reading temperature.
Das kann durchaus jede Menge werden und ist evtl. nicht nötig.
Wenn du also nur auf alarm triggern (hören) willst sind die beiden obigen passender.
Edith:
.*:alarm {
Log(1,"$NAME - $EVENT");
}
Das mal ins DEF eingeben und im Logfile schauen wenn alarm ein Event auslöst - und das Ergebniss bitte mal posten.
Ja sorry ich werfe gerne mit Klammern um mich die evtl. unnötig sind - aber so funktionieren meine Codes bei mir zumindest wunderbar 8)
Edith1: @Ellert
Wenn du die Muße hast darfst du natürlich auch zu DOIF helfen - sorry für meinen "harschen" Einwurf.
Der TE soll ja was lernen ;D
ZitatOk, soll dann bei Änderung des Reading temperature das notify triggern oder wenn sich alarm ändert?
Nein nur bei Änderung des Readings alarm soll das ganze ausgelöst werden.
Hatte auch das regexp
.*DHT22:alarm:.*|.*_Temp:alarm:.*
definiert aber wieder geändert weil ich nicht wusste wie ich sonst an die Werte temperature etc.komme.
Nur die Geräte .*DHT22 und .*_Temp haben bis jetzt das Reading, theoretisch würde dann ja .*:alarm reichen
Mir ist kein weiteres Gerät bekannt :-[ in der Config das dieses Reading hat und nicht dazugehört, wäre für spätere Erweiterungen ja dann auch die bessere Variante.
Schau oben mein Edith und probier das mal aus.
@Puschel74: Alles ist gut, ich werde deine Lerneinheit nicht unterbrechen. Wofür steht eigentlich TE? Teilnehmende Einheit?
Zitat von: Ellert am 13 Januar 2016, 12:27:23
Wofür steht eigentlich TE? Teilnehmende Einheit?
Nein,
Thread
Ersteller ;D
ZitatMir ist kein weiteres Gerät bekannt
Dem kommen wir mit meinem Edith auf die Schliche ;)
Ich habe das DEF ein wenig abgeändert auf
.*:alarm:.* {
Log(1,"$NAME - $EVENT");
}
Logeinträge seit dem.
2016.01.13 13:06:36 1: EMZ_Temp - alarm: 1
2016.01.13 13:06:54 1: Pumpe_Temp - alarm: 0
2016.01.13 13:07:24 1: Speicher_Temp - alarm: 0
2016.01.13 13:30:06 1: Keller.DHT22 - alarm: 0
2016.01.13 13:30:08 1: Keller.DHT22[b] - [/b]alarm: 0
2016.01.13 13:30:57 3: Kueche_TH : measured-temp: 19.1
Wieso werden die alarm Einträge mit - angezeigt und die anderen mit: ??
Warum der Keller 2 mal gelistet ist ist mir ein Rätsel aber ist jetzt auch nicht relevant denke ich.
ZitatWieso werden die alarm Einträge mit - angezeigt und die anderen mit: ??
Weil wir in unserem code als Trenner - drinne haben.
Gut zu erkennen sind auch die unterschiedlichen Loglevel - 1 bei uns und 3 aus FHEM.
Keller hat 2 Events erzeugt mit 2 Sekunden unterschied daher wird er auch zweimal geloggt.
Sorry für das löschen aber erst kommt noch $EVENT dran.$EVENT besteht aus 2 Teilen:
Zitatalarm: 1
d.h. in $EVTPART0 steht
alarm:und in $EVTPART1 steht
1 (oder eben
0).
.*:alarm:.* {
Log(1,"$NAME - $EVTPART0 -- $EVTPART1");
}
sollte das beweisen.
Und ich dachte ich habe schon Hallos.
Dann hebe ich mir das Log Temperatur mal für gleich auf ;)
EVTPART habe ich schon gelernt ;D
Habs aber nochmal der Vollständigkeit halber gemacht
2016.01.13 14:30:06 1: Keller.DHT22 - alarm: -- 0
2016.01.13 14:30:07 1: Keller.DHT22 - alarm: 0
2016.01.13 14:30:07 1: Keller.DHT22 - alarm: -- 0
So jetzt aber der Temperatur Log
2016.01.13 14:06:42 1: EMZ_Temp - alarm: 1
2016.01.13 14:06:42 1: Temperatur: 11.5625
2016.01.13 14:07:00 1: Pumpe_Temp - alarm: 0
2016.01.13 14:07:00 1: Temperatur: 10.5
2016.01.13 14:07:07 3: Kind_TH : measured-temp: 18.5
2016.01.13 14:07:36 1: Speicher_Temp - alarm: 0
2016.01.13 14:07:36 1: Temperatur: 9.4375
zu dem DEF
.*:alarm:.* {
my $temp=ReadingsVal($NAME,"temperature",122);
Log(1,"$NAME - $EVENT");
Log(1,"Temperatur: ".$temp);
}
Hatte für die Variable my $temp im ReadingsVal($_,.... angegeben.
Ich habe keine Ahnung was das $_ bewirkt, aber $NAME ist definitiv zielführend ;D
In dem Fall hast du ja alles zusammen was du brauchst ;)
Das
if (($alarm !~ m/0/)
kannst du auch so
if (($alarm != 0)
schreiben.
Ach ja, nochwas wegen dem Loglevel:
Ich hab global verbose bei mir auf 2 und mache die Logeinträge in meinen Codes, wie zu sehen, mit Loglevel 1
Ich mag die "normalen" Statusmeldungen in meinem Logfile nicht.
Edith: Kleiner Tipp noch - mit sprintf (siehe Perl-Wiki) kannst du deine Temperaturwerte runden lassen.
Leider noch nicht so ganz. :(
Die Temperatur der DHT22 wird mit dem Reading Temperature angegeben, in dem Fall muss ich eine weitere Vaiable erstellen oder kann man die so ähnlich erweitern?
my $temp=ReadingsVal($NAME,"temperature"|"Temperature","122");
So bekomme ich leider auch bei jedem neuen triggern des alarms mit 1 eine neue Mail gesendet.
Das würde ich gerne noch unterbinden.
Die Idee von Ellert
ZitatSendet 1 Mail und dann erst wieder, wenn die Temperatur 3°C über templow liegt und danach templow wieder unterschritten wird.
Finde ich garnicht so unschön.
Wollte das über einen dummy Frostalarm lösen der mit auf Alarm gesetzt wird.
Zitat von: Puschel74 am 13 Januar 2016, 14:58:42
Edith: Kleiner Tipp noch - mit sprintf (siehe Perl-Wiki) kannst du deine Temperaturwerte runden lassen.
Noch ein kleiner Tipp: fhem kennt die Funktion round() die mit zwei Werten aufgerufen wird: round(3.1415926536,2) rundet pi auf zwei Stellen nach dem Komma.
Aber lasst Euch nicht weiter stören.
Nein, readings musst du einzeln in Variablen speichern und vergleichen.
der Variablenamen muss aber eindeutig sein.
Du kannst versuchen im Device mit dem Reading alarm das Attribut event-on-change-reading zu setzen.
Dann wird nur ein Event generiert wenn sich was ändert.
Ich habe bei mir keinen Dummy sondern ein Reading im Device mit setreading gesetzt sobald für dieses Gerät die Batterie-leer-Meldung gesendet
wurde.
So kommt pro Device immer nur eine Mail.
Edith: Danke betateilchen - ich lern auch immer wieder noch was dazu 8)
Evtl. eine blöde Frage emperature geht hier nicht oder?
Wie im Bsp. [Bb]attery
Danke für den Tipp, round[] kannte ich noch nicht.
Kann mir einer die Bedeutung von
if (($alarm !~ m/0/)
und dem geheimnisvollen
$_
erklären?
Irgendwie zeigt er das Tt in den Klammern nicht an und die Formatierung ist auch merkwürdig.
Ich mach wieder alles kaputt.
Zum auslesen eines Wertes mittels ReadingsVal?
Nein - da mWn das Reading nicht als regexp angegeben werden kann.
Vielen Dank für die tolle Unterstützung.
Muss leider für heute pausieren. Melde mich morgen früh wieder mit neuen Ergebnissen.
Danke
Sven
Gerne.
OT - trifft sich gut kann ich meine HM-SEC-SD in Betrieb nehmen - BTT
Zitat von: newby am 13 Januar 2016, 15:23:07
Danke für den Tipp, round[] kannte ich noch nicht.
Achtung: runde Klammern, keine eckigen!
Zitat von: newby am 13 Januar 2016, 15:23:07
Kann mir einer die Bedeutung von
if ($alarm !~ m/0/)
Da wird geprüft, ob der Inhalt (!) der Variablen $alarm NICHT die Ziffer 0 enthält.
Zitat von: newby am 13 Januar 2016, 15:23:07
und dem geheimnisvollen
$_
erklären?
Das ist eine perl-interne Variable, davon gibt es eine ganze Menge, z.B. auch $1, $2, $] usw.
Die Bedeutung solcher Varianlen findest Du in der perl Doku, das ist nichts fhem spezifisches.
Zitat von: newby am 13 Januar 2016, 15:23:07
Kann mir einer die Bedeutung von
if (($alarm !~ m/0/)
Ich versuche es mal als "regexegasteniker" mit Hilfe von Selfhtml (https://wiki.selfhtml.org/wiki/Perl/Operatoren) und Perldoc (http://perldoc.perl.org/perlre.html) (Das (http://www.infos24.de/perle/handbuch/8_regular_expression.htm)ist auch nicht schlecht) bin ich der Bedeutung näher gekommen:
$_ ist die Default Variable
Das Ausrufezeichen kehrt etwas um.
Der ~ (Binding) Operator
m/0/ ist der matching Operator, der hier auf 0 prüft.
betateilchen (!Puschel) ;) war schneller und hat es vor allem richtig erklärt, ich habs immer noch nicht von alleine verstanden.
Irgendwann muss es doch mal werden. ::)
Gruß Otto
P.S. Sorry ich habe nur mitgelesen 8)
ZitatPuschel war schneller und hat es vor allem richtig erklärt,
Nenene, das war betateilchen und !Puschel ;D
Zitat von: Puschel74 am 13 Januar 2016, 16:16:39
Nenene, das war betateilchen und !Puschel ;D
Hast ja Recht, wenn man auf "schreiben" drückt und sieht es hat schon einer, kann das lesen dann manchmal Glücksache sein.
Hatte ja die Statusmeldung angedroht.
Aktueller Code
.*:alarm:.* {
my $alarm=ReadingsVal($NAME,"alarm","0");
my $temp=ReadingsVal($NAME,"temperature","122");
my $frost=ReadingsVal("Frostalarm","state","tilt");
{ if ($alarm != 0) {
{DebianMail('mail@mail.de','FHEM Frostwarnung','Die Temperatur von ' .$NAME. ' ist ' .$temp)}
fhem ("set Frostalarm on");
Log(1,"$NAME - $EVENT Frostalarm: $frost Alarm: $alarm");
Log(1,"Temperatur: ".$temp);
}
else {
fhem ("set Frostalarm off");
Log(1,"Else $NAME - $EVENT Frostalarm: $frost Alarm: $alarm");
Log(1,"Temperatur: ".$temp);
}
}
}
funktioniert einwandfrei.
Geändert habe ich noch
alarm:.*
.*:alarm:.*
da der Dummy Frostalarm sonst ein Event auslöste.
Durch das setzen von "event-on-change-reading" in den Devices wird das mehrfache senden unterbunden.
Das Problem mit der Ttemperature habe ich auf unkonventionelle Weise einfach über ein weiteres UserReading "temperature" im Device gelöst.
Sorry :-[
Wieder ein Stück weiter und schlauer 8)
Nächstes Project steht schon an.