FHEM Forum

FHEM => Automatisierung => Thema gestartet von: roedert am 17 Oktober 2014, 08:35:12

Titel: setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: roedert am 17 Oktober 2014, 08:35:12
Ich habe ein selbstdefiniertes Reading in einem FS20-Device. Wenn ich dieses aus der Befehlszeile im Webfrontend oder per telnet:7072 heraus mit "setreading...." setze ist alles ok - das reading wird geändert, protokolliert (File- und DbLog) und in einer definierten Readingshistory angezeigt.

Wenn ich jedoch aus einem notify mit perl-Code heraus das setreading ausführe wird es nicht protokolliert - weder in DB- noch in FileLog, der Rest ist aber in Ordnung, d.h. das reading wurde gesetzt und auch in der Readingshistory angezeigt.

def xxx notify xxx:xxxx {if (xxxx) {fhem("setreading ........")}}

PS: Ich habe den Titel mal geändert ..... es hat sich herausgestellt, dass nicht der Perl-Code "schuld", sondern der Aufruf aus einem Notify heraus
Titel: Antw:setreading: keine Protokollierung aus Perl-Code heraus
Beitrag von: Icinger am 17 Oktober 2014, 08:53:06
Hi....So sollts klappen:

def xxx notify xxx:xxxx {if (xxxx) {ReadingSingleUpdate($hash,$reading,$value,1)}}
Titel: Antw:setreading: keine Protokollierung aus Perl-Code heraus
Beitrag von: roedert am 17 Oktober 2014, 09:02:49
Danke, werde ich mal testen......

Aber was ist das ... ReadingSingleUpdate?
Ok, was es ist kann ich mir denken ... aber bisschen mehr Hintergrund wäre schon schön  ;)

Dazu konnte ich nirgends was finden ... nicht in der Commandref, Forum oder Wiki?

Edit: Ausprobiert und klappt nicht  :(
Undefined subroutine &main::ReadingSingleUpdate called at (eval 384275) line 9.
Titel: Antw:setreading: keine Protokollierung aus Perl-Code heraus
Beitrag von: Icinger am 17 Oktober 2014, 09:27:19
Sorry, mein Fehler: RedingsSingleUpdate

Nähere Infos findest du zB hier: http://www.fhemwiki.de/wiki/DevelopmentModuleIntro#Readings (http://www.fhemwiki.de/wiki/DevelopmentModuleIntro#Readings)

Damit triggerst du das FHEM-Interne Event-System

lg, Ici
Titel: Antw:setreading: keine Protokollierung aus Perl-Code heraus
Beitrag von: roedert am 17 Oktober 2014, 09:36:23
Ok, bestens Dank ... durch die Suche bin ich grade auf einen Beitrag gestossen mit dem gleichen Problem.
Aus einem Notify heraus wird kein Event und somit auch kein Logeintrag ausgelöst  :(

http://forum.fhem.de/index.php?topic=14515.0
Titel: Antw:setreading: keine Protokollierung aus Perl-Code heraus
Beitrag von: justme1968 am 17 Oktober 2014, 09:42:18
setreading macht nichts anderes als RedingsSingleUpdate aufzurufen.

hast du dir userreadings angeschaut?

vielleicht schreibst du mal was du genau machen möchtest.

gruß
  andre
Titel: Antw:setreading: keine Protokollierung aus Perl-Code heraus
Beitrag von: roedert am 17 Oktober 2014, 10:04:31
ok, die Erklärung ... die Überwachung der Katze  :D

An der Katzenklappe sind 2 Magnetkontakte angebracht ... innen und aussen, diese sind mit einem FS20-Sender FS20S4M verbunden uns senden also on/dimup oder off/dimmdown.

Allerdings pendelt die Katzenklappe, ist aber kein Problem, der zuerst ausgelöste Magnetkontakt ist der richtige - in FHEM kann ich das mit event-min-interval abbilden:

def Katzenklappe.Sensor FS20 xxxx xx
attr Katzenklappe.Sensor event-min-interval state:4


In einem entsprechenden Notify wollte ich dann das eigene Reading "drin" setzen ... was ja auch soweit alles klappt.
def Katzenklappe.Sensor_nfy Katzenklappe.Sensor:(on|off|dimup|dimdown) {fhem("setreading $NAME drin " . ($EVENT eq "on" || $EVENT eq "dimup") ? 1 : 0) }

Problem ist nun, dass dieses setreading im notify eben kein event und kein Logging auslöst wie es ja in dem genannten Forumsbeitrag auch bestätigt wird.

Vorher hatte ich statt dem zusätzlichen Reading von Katzenklappe.Sensor einen DUMMY genutzt - da hat auch das Logging funktioniert.
Aber ein eigenes Reading wäre die übersichtlichere Lösung gewesen.
Titel: Antw:setreading: keine Protokollierung aus Perl-Code heraus
Beitrag von: justme1968 am 17 Oktober 2014, 10:11:33
aber genau dafür ist doch userReadings da.

was du auch probieren kannst ist zusätzlich zum setreading ein trigger... aufruf machen. dann sollte es auch gehen.

gruss
  andre
Titel: Antw:setreading: keine Protokollierung aus Perl-Code heraus
Beitrag von: roedert am 17 Oktober 2014, 10:34:56
Zitat von: justme1968 am 17 Oktober 2014, 09:42:18
hast du dir userreadings angeschaut?

Ja ... hilft aber in meinem Fall nicht, da die userreadings immer 1:1 gesetzt werden und sich nicht von dem event-min-intervall beeinflussen lassen.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: rudolfkoenig am 17 Oktober 2014, 10:49:28
Wenn man ein Reading R fuer Geraet G aus einem Notify fuer dieses Geraet G setzt, dann wird fuer R kein Event generiert.
Gilt fuer Events generell, ist nicht notify-spezifisch.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: justme1968 am 17 Oktober 2014, 10:55:04
es sollte auch in deinem fall helfen wenn du die zeit selber mit berücksichtigst. du hast den readingsTimestamp des letzen update und die aktuelle zeit.

gruss
  andre
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: justme1968 am 17 Oktober 2014, 11:00:03
man könnte den trigger mit einem at verzögern. dann wird das event generiert. das sollte auch bei setreading gehen fällt mir gerade auf.

@rudi: gibt es ausser einem eventuellen rekursions problem noch einen anderen grund die events explizit nicht zu generieren? das ist glaube ich schon öfter als problem aufgefallen.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: roedert am 17 Oktober 2014, 11:13:26
def Katzenklappe.Sensor_nfy notify Katzenklappe.Sensor:(on|off|dimup|dimdown) {fhem("define kk_tmp at +00:00:01 setreading $NAME drin ".(($EVENT eq "on" || $EVENT eq "dimup")?1:0))}

funktioniert  :D

Aber ist eigentlich nur ein unschöner Workaround mit dem zusätzlichen at.
Ist die Frage ob die Einschränkung dass aus einem notify heraus nicht noch einmal ein Event generiert werden kann, wirklich einen tieferen Sinn/Grund hat.
Außer natürlich der eventuellen Rekursion wenn man da "Mist" baut.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: rudolfkoenig am 17 Oktober 2014, 11:54:45
@andre: ja:
- Aktuelle Implementierung: Events werden an $hash->CHANGED drangehaengt, und zum Schluss alle NotifyFns aufgerufen. Wenn ein notify hier was  dranhaengt, dann bekommen die bereits aufgerufenen NotifyFns diesen Wert nicht. Bestimmte Module (average, dewpoint) setzen die Notify-Prioritaet und bearbeiten CHANGED direkt, aber der generischen reading*Update ist das untersagt.
- Alternativ koennte man waehrend der NotifyFn Schleife neue Events in $hash->CHANGED2 sammeln, und man wiederholt die Schleife zum Schluss nochmal, falls hier was drin ist. Was alles fuer diese Aenderung angefasst werden muesste, weiss ich nicht.
- der Code in fhem.pl (bzw. in den diversen Modulen, die Dispatch/DoTrigger/etc aufrufen) ist so verworren bezueglich Reihenfolge/Verschachtelung, dass ich mich nicht traue es anzufassen. Oder anders: die mehrere Tage Zeit zum reparieren sind es mir nicht Wert.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: justme1968 am 17 Oktober 2014, 12:15:52
@roedert: das ganze sollte noch einfacher werden wenn man statt dem at ein fhem sleep verwendet. also etwa so:{my $state = (($EVENT eq "on" || $EVENT eq "dimup")?1:0); fhem("sleep1;; setreading $NAME $state")}

@rudi: wie wäre es in der doku zu setreading zu erwähnen das es nicht innerhalb eines notify funktioniert und auf den workaround mit fhem sleep hinweisen? oder gleich in setreading ein temporäres at/sleep zu verwenden wenn es innerhalb eines notify aufgerufen wird.

das würde die von dir befürchteten nebenwirkungen einer 'richtigen' lösung umgehen und sollte von aufwand überschaubar sein.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: roedert am 17 Oktober 2014, 12:30:37
Zitat von: justme1968 am 17 Oktober 2014, 12:15:52
@roedert: das ganze sollte noch einfacher werden wenn man statt dem at ein fhem sleep verwendet. also etwa so:{my $state = (($EVENT eq "on" || $EVENT eq "dimup")?1:0); fhem("sleep1;; setreading $NAME $state")}

Ändert das was? Es wird doch nur verzögert - aber doch immer noch aus einem notify aufgerufen.
Durch das erstellte "at" kommt es aus einem völlig neuen Umfeld - unabhängig von dem Notify.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: roedert am 17 Oktober 2014, 12:33:13
Zitat von: justme1968 am 17 Oktober 2014, 12:15:52@rudi: wie wäre es in der doku zu setreading zu erwähnen das es nicht innerhalb eines notify funktioniert

setreading selbst funktioniert ja, es löst aus dem notify heraus eben nur keinen Event und kein Log-Eintrag aus
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: justme1968 am 17 Oktober 2014, 12:35:27
@roedert: es ist nur etwas kürzer zum hinschreiben und es gibt keine warnung falls es das at schon gibt.

@rudi: das ist klar. aber das kein event erzeugt wird steht nicht in der doku und hat schon mehr als ein mal verwirrt.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: Elektrolurch am 17 Oktober 2014, 15:21:21
Hallo,

ich hatte so ein ähnliches Problem, mit dem Codeschnipsel des Telefonmonitors:
Die Events hatte ich per notify auf den FB_CallMonitor ausgewertet und beim FB_Call_Monitor mir readings für die Darstellung einer Liste angelegt.
Die wurde nicht on-screen aktualisiert, erst nach  Drücken von F5.
Nachdem ich aus dem Codeschnipsel ein eigenes Modul "Neues Modul Telefonmonitor (TM)" gebastelt habe und die readings der Listendarstellung nicht mehr beim FB_CallMonitor abgelegt habe, funktioniert auch die Aktualisierung auf dem Screen.
Aber da muss man erst einmal draufd kommen.....!
Ich hatte im Forum hier nachgefragt, aber da wusste das auch niemand so recht, warum das nicht funktionierte.....

Gut, wieder was gelernt.
Also, in einem notify keine readings desselben Objektes aktualisieren, wenn man log oder events braucht....

Gruß


Elektrolurch
Titel: Antw:setreading: keine Protokollierung aus Perl-Code heraus
Beitrag von: roedert am 17 Oktober 2014, 16:35:19
Zitat von: justme1968 am 17 Oktober 2014, 09:42:18
hast du dir userreadings angeschaut?

ok, das ist der andere Ansatz:

attr Katzenklappe.Sensor userReadings drin:(on|off|dimup|dimdown) {((Value($name) eq "on" || Value($name) eq "dimup")?1:0)}

Dies berücksichtig aber wie schon geschrieben das event-min-intervall nicht. Kann ich in dieses Userreading irgendwie soviel Logik bringen, dass es nur gesetzt wird wenn das vorherige Event länger als zB 4sec alt ist?

Durch das Pendeln der Katzenklappe darf ich eben nur das erste Event auswerten (was die "Richtung" vorgibt), die folgenden Meldungen des Magnetkontakten muss ich für ein paar Sekunden ignorieren.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: justme1968 am 17 Oktober 2014, 16:47:45
wie oben schon geschrieben: mit ReadingsTimestamp solltest du dir den zeitpunkt des letzten draussen readings holen können und mit jetzt vergleichen. eventuell musst du dir die zeit extra in einem .drausenTimestamp reading merken.

alles in allem finde ich die version mit sleep am kürzesten und elegantesten.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: roedert am 17 Oktober 2014, 19:24:50
Zitat von: justme1968 am 17 Oktober 2014, 12:15:52
@roedert: das ganze sollte noch einfacher werden wenn man statt dem at ein fhem sleep verwendet. also etwa so:{my $state = (($EVENT eq "on" || $EVENT eq "dimup")?1:0); fhem("sleep1;; setreading $NAME $state")}

Habs ausprobiert - es ändert aber nix.
Leuchtet ja auch ein - das temporäre "at" ist ja nicht wegen der 1sec Pause eingebaut, sondern darum, weil ein setreading auf das gleiche Device aus einem notify eben kein Event/Logeintrag generiert.
Da ändert auch ein sleep nix dran.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: justme1968 am 17 Oktober 2014, 19:34:49
das fhem sleep macht genau das. es legt intern ein temporäres at an und alles was danach kommt wird unsbhängig und nicht mehr im notify ausgeführt.

siehst du etwas im log?

gruß
  ander
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: roedert am 17 Oktober 2014, 20:30:53
Sorry, es funktioniert doch ... es war nur ein kleiner Fehler drin und ich hatte vorhin gar nicht ins Log geschaut.

{my $state = (($EVENT eq "on" || $EVENT eq "dimup")?1:0); fhem("sleep1;; setreading $NAME $state")}

Er mag das Doppel-Semikolon nach dem sleep nicht, mit einem Semikolon geht es.
Klar, in der cfg-Datei muss das Doppel-Semikolon stehen - nicht aber wenn ich es in der WebGui einpflege.

Mit ;; kommt im Log
sleep 1;; setreading Katzenklappe.Sensor drin 0 : Cannot interpret 1; as seconds
Katzenklappe:Sensor_nfy return value: Cannot interpret 1; as seconds
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: rudolfkoenig am 18 Oktober 2014, 08:25:33
@andre: habe die Doku erweitert, mit deinem sleep Vorschlag. Einen direkten Einbau in setreading halte ich fuer gefaehrlich, weil man in manchen Faellen direkt nach dem Aufruf der Wert noch nicht gesetzt waere, und das kann verwirren.
Titel: Antw:setreading: kein Event und Protokollierung aus einem notify heraus
Beitrag von: justme1968 am 18 Oktober 2014, 09:17:43
ich finde gut das es dokumentiert ist.

wenn man in setreading das readingsupdate sofort macht und mit sleep einen trigger aufruf hinterher schickt wenn es aus einem notify aufgerufen wird wäre der wert sofort aktuell und nur das event wäre in diesem fall verzögert.