FHEM Forum

FHEM => Frontends => Thema gestartet von: Uli Zappe am 16 April 2013, 20:42:22

Titel: longpoll funktioniert nicht bei setstate :-(
Beitrag von: Uli Zappe am 16 April 2013, 20:42:22
Hallo,

ich habe das Problem, dass ich etliche Geräte (Computer, andere Geräte im Netzwerk, Audioanlage, ...) in FHEM steuern möchte, die auch auf andere Weise als über FHEM aktiviert oder deaktiviert werden können. Um den korrekten Gerätestatus in FHEM anzeigen zu können, gehe ich generell immer wie folgt vor:

Ein "Schalt"-Objekt erlaubt das Ändern des Gerätestatus via FHEM; in aller Regel ist das ein dummy-Modul, dem via notify für Ein und Aus entsprechende Shellskripte zugeordnet sind, die dann Netzwerkbefehle, Infrarotbefehle o.ä. auslösen.

Ein "Status"-Objekt empfängt den Gerätestatus (z.B. ping-Abfrage via PRESENCE, oder FS20-Master/Slave-Sender, der auf den Stromverbrauch reagiert, etc.).

Über notify und setstate wird dann das "Schalt"-Objekt vom "Status"-Objekt auf den korrekten Anzeigestatus gesetzt.

Nur dummerweise aktualisiert longpoll das nicht auf der Weboberfläche, da es offenbar nur auf set, nicht auf setstate reagiert. set kann ich aber keinesfalls verwenden, weil sich sonst ungewollte Rückkopplungen ergeben könnten. Beispiel: Ein Gerät, das nur verzögert auf einen Aus-Befehl reagiert, würde dann über das noch auf Ein stehende "Status"-Objekt sofort wieder eingeschaltet.

Daher meine Frage: gibt es irgendeine Möglichkeit, longpoll auch auf setstate reagieren zu lassen? Ein set kommt wie geschildert nicht in Frage.

Vielen Dank im Voraus für evtl. Hinweise/Tipps!

Uli
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: rudolfkoenig am 17 April 2013, 08:40:57
Longpoll reagiert wie notify/etc auf events, und setstate loest (mit Absicht) kein events aus.
Das Frontend ist im gewissen Sinne damit genau sowas wie ein notify.
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: Uli Zappe am 17 April 2013, 15:19:18
Mir ist schon klar, dass das Verhalten "as designed" ist.

Das Problem ist eben, dass sich damit Anwendungsfälle wie von mir beschrieben nicht abdecken lassen.

Du erinnerst Dich vielleicht noch an eine Diskussion von vor etwa einem Jahr, als ich ein eigenes Modul für die oben beschriebenen Aufgabenstellungen vorschlug (auch wenn sich die Diskussion damals hauptsächlich an der Namensgebung festbiss). Damals hieltest Du mir mit einem gewissen Recht vor, solch ein komplexes Modul widerspräche der modularen Anlage von FHEM; die Funktionalität sollte vielmehr durch eine Kombination enger gefasster Module realisiert werden (von denen damals PRESENCE noch fehlte).

Nun, das habe ich beherzigt und wie oben beschrieben umgesetzt, aber an genau diesem einen Punkt stoße ich damit eben an eine offenbar unüberwindbare Grenze, die ein eigenständiges komplexes Modul nicht hätte. Aber eine Statusanzeige, die sich im Gegensatz zu allen anderen (bei longpoll = 1) nicht von selbst aktualisiert, ist eben unnütz.

Natürlich darf setstate kein Event auslösen, das ist ja sein spezifischer Sinn. Aber was spräche denn dagegen, setstate bei longpoll explizit zu berücksichtigen? Wäre das einfach zu umständlich in den bestehenden Code zu integrieren, oder spräche vom Design her etwas dagegen?
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: rudolfkoenig am 17 April 2013, 19:07:57
> Aber eine Statusanzeige, die sich im Gegensatz zu allen anderen (bei longpoll = 1) nicht von selbst aktualisiert, ist eben unnütz...

...fuer Dich in der aktuellen Konfiguration. Viele andere ( haben damit kein Problem.


> Aber was spräche denn dagegen, setstate bei longpoll explizit zu berücksichtigen?

Die aktuelle Architektur von FHEM. Und meine Ueberzeugung, dass es nicht notwendig ist, da mit einem anderen Konfiguration dein Problem loesbar ist.
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: Uli Zappe am 17 April 2013, 19:13:01
Zitat von: rudolfkoenig schrieb am Mi, 17 April 2013 19:07Und meine Ueberzeugung, dass es nicht notwendig ist, da mit einem anderen Konfiguration dein Problem loesbar ist.
Könntest Du mir dann bitte einen Hinweis, Link o.ä. geben, welche andere Konfiguration mein Problem lösen könnte?

Ich komme selbst nicht darauf und habe bei entsprechenden Suchen auch nichts gefunden.
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: rudolfkoenig am 17 April 2013, 21:45:06
Tut mir leid, ich muss einsehen, dass mir keine andere funktionierende Konfiguration einfaellt.

Ich biete stattdessen zwei etwas unschoene Workarounds:

1. longpoll reagiert auf beliebige events: nach "setstate dev status" ein "trigger dev updateweb" durchfuehren, und in allen dazugehoerigen notifies nichts tun, falls ($EVENT eq "updateweb") ist.

2. statt "setstate dev status" folgendes durchfuehren: "attr ntfy disabled;; set dev status;; deleteattr ntfy disabled", wobei ntfy das dazugehoerige notify ist.

Ich sehe jetzt ein, dass longpoll setstate berucksichtigen sollte, ich weiss aber z.Zt nicht wie ich das ohne kompletten FHEM-Umbau oder haessliche shortcuts realisieren kann.
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: Johannes am 17 April 2013, 22:18:19
Polling ersetzen durch websockets ? :-) ich fänds super.
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: Uli Zappe am 18 April 2013, 00:19:12
Zitat von: rudolfkoenig schrieb am Mi, 17 April 2013 21:45Tut mir leid, ich muss einsehen, dass mir keine andere funktionierende Konfiguration einfaellt.
Gut, dann kann ich zumindest aufhören, an meinem Verstand zu zweifeln. ;-)

ZitatIch sehe jetzt ein, dass longpoll setstate berucksichtigen sollte, ich weiss aber z.Zt nicht wie ich das ohne kompletten FHEM-Umbau oder haessliche shortcuts realisieren kann.
Ja, das hatte ich schon befürchtet.

Aber vielen Dank für Deine beiden Workarounds! Klar, nicht schön, aber sie lösen erstmal mein Problem, und sind insofern voll OK. Die nicht aktualisierte Statusanzeige ist viel unschöner.
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: Uli Zappe am 18 April 2013, 02:16:49
Zitat von: rudolfkoenig schrieb am Mi, 17 April 2013 21:45Ich biete stattdessen zwei etwas unschoene Workarounds:
Ich habe jetzt Deine erste Methode erfolgreich implementiert.

Da meine notifies alle jeweils nur für einen bestimmten Status definiert sind (also z.B. define geraetOn notify geraet:on "/usr/local/bin/switchGeraetOn"), muss ich nicht einmal auf eine Bedingung à la

Zitat($EVENT eq "updateweb")
achten und sie ausschließen (weil dafür eben schlicht kein passendes notify definiert wurde), d.h. der ganze Workaround reduziert sich darauf, aus jedem

setstate geraet on[/font]

ein

setstate geraet on;; trigger geraet updateWebDummyAction[/color][/font]

zu machen. Das ist nun wirklich kein Problem und ein recht guter Workaround, wie ich finde. Funktioniert jedenfalls einwandfrei. :-) Also nochmals Danke!
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: rudolfkoenig am 18 April 2013, 07:48:01
>  Polling ersetzen durch websockets ? :-) ich fänds super.

Johannes, bitte nicht den Troll spielen, das Problem hat nichts mit der longpoll Technik zu tun, und wuerde bei Verwendung von websockets auch auftreten.

Btw. wenn ich das websockets SPEC verstehe, dann kann man es mit der FHEM telnet Schnittstelle ohne Probleme verwenden. Man muss nur dem Android Benutzer erklaeren, dass sein Browser es nicht unterstuetzt. FHEMWEB bleibt erstmal auf longpoll.
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: Johannes am 18 April 2013, 20:00:45
Naja, mich gleich als Troll bezeichnen halte ich für etwas überzogen :-). Es war ja nur eine Idee / Hinweis auf modernere Techniken, die in Rahmen von FHEM durchaus Sinn machen.
Das die vernünftige Integration in FHEM nicht ohne weiteres möglich ist, ist mir schon klar. Insgesamt wäre es aber eine für die Zukunft sicher sinnvolle Technik, wenn es um eine resourcen- bzw. trafficarme "Echtzeit" Darstellung von serverseitigen Daten in einer Webseite geht.
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: rudolfkoenig am 18 April 2013, 20:14:41
Das mag alles richtig sein, hat aber nichts mit dem Problem von Uli zu tun...
Titel: Aw: longpoll funktioniert nicht bei setstate :-(
Beitrag von: Uli Zappe am 18 Mai 2013, 07:20:19
Noch eine Ergänzung für diejenigen, die etwas Ähnliches wie ich realisieren wollen:

Zitat von: Uli Zappe schrieb am Do, 18 April 2013 02:16Das ist nun wirklich kein Problem und ein recht guter Workaround, wie ich finde. Funktioniert jedenfalls einwandfrei. :-)
Eine Komplikation gibt es, wie ich mittlerweile herausgefunden habe, wenn das "Schalt-Objekt" eine Logdatei besitzt.

Dann treten zwei Probleme auf:
PRESENCE (bei mir also jede Sekunde!) wird das updateWebDummyAction-Event in diese Logdatei geschrieben, die daher schnell eine riesige Größe erreicht.
  • Trotz der Größe ist der Gehalt der Logdatei gleich Null, schließlich steht stets nur updateWebDummyAction darin.[/list]
    Um diese beiden Probleme zu lösen, muss man wie folgt vorgehen:
    • Das
    "Status-Objekt" darf nur dann ein notify an das "Schalt-Objekt" senden, wenn eine Zustandsänderung eintritt.
  • Statt updateWebDummyAction sind für den trigger-Befehl je nach zu setzendem Status unterschiedliche und in der Logdatei gut lesbare Dummy-Aktionen anzugeben. Am konsequentesten im Sinne der Logdatei sind einfach on und off. Das sieht dann im Code zwar missverständlicherweise irgendwie nach "echtem" Befehl aus, aber de facto gibt es on und off natürlich nur als Parameter und nicht als Befehle, wie trigger sie auslöst; aus Sicht von trigger bleiben es also Dummy-Aktionen, und die Logdatei wird gut lesbar.[/list]
    Hier ein Beispiel-notify namens Geraet_PAIRon, das das "Status-Objekt" Geraet_STATE (vom Typ PRESENCE) mit dem "Schalt-Objekt" Geraet verbindet, falls Geraet ausgeschaltet war und eingeschaltet wird:

    define Geraet_PAIRon notify Geraet_STATE:present { if(Value("Geraet") eq "off") { fhem("setstate Geraet on;; trigger Geraet on") } }[/font]

    Und hier das Gegenstück in die andere Schaltrichtung:

    define Geraet_PAIRoff notify Geraet_STATE:absent { if(Value("Geraet") eq "on") { fhem("setstate Geraet off;; trigger Geraet off") } }[/font]

    Das führt dann zu einer ansehnlichen Logdatei:

    2013-05-18_06:32:57 Geraet on
    2013-05-18_06:34:13 Geraet off
    2013-05-18_06:37:57 Geraet on
    2013-05-18_06:38:36 Geraet off
    [/font]

    Uli
  • Titel: Aw: longpoll funktioniert nicht bei setstate :-(
    Beitrag von: rudolfkoenig am 18 Mai 2013, 08:50:36
    Oder man spezifiziert das FileLog regexp so, das es nur auf die gewuenschten Events passt.
    Titel: Aw: longpoll funktioniert nicht bei setstate :-(
    Beitrag von: Uli Zappe am 18 Mai 2013, 10:01:59
    Zitat von: rudolfkoenig schrieb am Sa, 18 Mai 2013 08:50Oder man spezifiziert das FileLog regexp so, das es nur auf die gewuenschten Events passt.
    Damit könnte man Problem 1 lösen (updateWebDummyAction via regexp unterdrücken), aber nicht Problem 2 (on und off sollen ja im Log auftauchen, aber eben nur bei einer Status-Änderung), weswegen ich die andere Variante genommen habe.