PRESENCE: Attribut für „GUI Feedback“?

Begonnen von Uli Zappe, 18 Juli 2016, 10:33:24

Vorheriges Thema - Nächstes Thema

Uli Zappe

Hallo Markus,

sorry, aber wenn Du die Nutzer Deines Moduls derart schnell und gut unterstützt, riskierst Du natürlich Feature Requests ...  ;D

Ich hätte da also folgende Idee bzw. Frage:

Ich nutze PRESENCE für das Aufwecken und Schlafenlegen etlicher Netzwerkgeräte (Computer und andere) mittels powerCmd.

Viele dieser Geräte reagieren mit erheblicher Verzögerung auf einen Weck- oder Schlafenlegbefehl; so kann es je nach Computer ziemlich lange dauern, bis nach dem Wake-On-LAN-Befehl das Gerät wirklich einsatzbereit ist und auf Pings (zur Statuskontrolle) reagiert.

In der Praxis ergibt sich daraus nach meiner Erfahrung bei fehlendem Sichtkontakt zu dem jeweiligen Gerät die missliche Lage, dass ich lange Zeit nicht sicher sein kann, ob ich mit meinem Wurstfinger auf meinem Smartphone die Schaltfläche zum Aufwecken überhaupt getroffen habe – denn die Reaktion in Form eines auf Ein wechselnden Icons kommt ja erst sehr viel später.

Ich dachte mir daher, es sei eine gute Idee, ein ,,GUI-Feedback" zu implementieren: Wenn ich z.B. das Gerät aufwecken will und die Schaltfläche mit dem Aus-Statusicon berühre, springt das Statusicon für einen kurzen Moment sofort auf Ein, um die Entgegennahme des Befehls zu bestätigen. Danach fällt es wieder auf Aus zurück, so lange, bis der Status-Check tatsächlich meldet, dass das Gerät present ist. (Und beim Schlafenlegen entsprechend umgekehrt.)

Ich habe das so implementiert, dass das powerCmd als erstes einen setreading-Befehl an die PRESENCE-Instanz sendet und den Status auf ON setzt, wofür in devStateIcon dann auch das Ein-Statusicon definiert ist. Der nächste (bei mir sekündlich stattfindende) Ping-Statustest setzt dann den Status zunächst wieder auf absent zurück, bis der Computer schließlich vollends erwacht ist.

Das funktioniert im Prinzip auch, zumindest auf meinem schwächlichen ARM-Rechnerchen aber mehr schlecht als recht:

  • Es gibt im Vergleich zu anderen Modulen wie dummy, einem FS20-Modul etc. eine deutliche Verzögerung zwischen dem Berühren der Schaltfläche und der kurzfristigen Änderung des Statusicons, d.h. das GUI-Feedback fühlt sich immer noch ,,zäh" an
  • Der Zeitraum bis zum Rückfall auf den tatsächlichen augenblicklichen presence-Status kann zufällig alles zwischen 0 und 1 Sekunde betragen und ist daher manchmal auf der Weboberfläche kaum zu sehen

Frage daher: wäre es mit (für Dich  ;)) vertretbarem Aufwand realisierbar, PRESENCE ein Attribut GUIFeedback (oder wie auch immer benannt) zu spendieren, das bei Auslösen des power-Befehls für eine definierte Zeitspanne den gewünschten Zielstatus als state setzt, bis wieder der aktuelle presence-Status ausschlaggebend für die Anzeige des Icons wird?

Als Parameter könnte 0 das Verhalten ausschalten, alle andern Werte wären dann die Dauer in Sekunden oder Millisekunden für die kurzfristige Statusänderung als Feedback.

Ich weiß nicht, ob es sinnvoll wäre, spezielle, getrennte Status für dieses Feedback zu benutzen (so wie ON und OFF in meiner provisorischen Implementation). Der Vorteil von getrennten Status wäre, dass man in devStateIcon dann z.B. gezielt dafür sorgen könnte, dass für diesen kurzen Moment ein weiterer Klick auf die Schaltfläche gar kein Kommando auslöst, was ich als sinnvoll erachte. Der Nachteil wäre, dass das Ganze für Nutzer dann nur korrekt funktionieren würde, wenn sie in ihrer devStateIcon-Definition diese Status auch definieren. Hmm, wenn ich das jetzt so schreibe, denke ich, der Vorteil überwiegt den Nachteil ...

justme1968

die ursprüngliche variante von powerCmd hat hierzu mal state auf setOn und setOff gesetzt. in verbindung mit den beiden threshold attributen und einer passenden internen logik die verhindert das der status schon nach einer sekunde wieder zurück gesetzt wird sollte das eigentlich für das gewünschte verhalten reichen.

@Uli Zappe: die verzögerung die du gegenüber einen dummy siehst verstehe ich aber nicht. das setreading sollte den dargestellten status genau so schnell ändern wie bei jedem anderen device. vorausgesetzt das das schalt kommando selber nicht blockiert sondern im hintergrund läuft.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Uli Zappe

Zitat von: justme1968 am 18 Juli 2016, 15:22:37
die verzögerung die du gegenüber einen dummy siehst verstehe ich aber nicht. das setreading sollte den dargestellten status genau so schnell ändern wie bei jedem anderen device.
Ich habe eine Test-Instanz von PRESENCE angelegt, deren lan-ping ins Leere läuft (unbelegte IP-Adresse) und somit den Normalzustand auf absent hält, und deren powerCmd nichts tut als setreading aufzurufen.

Ergebnis:

Bei
attr Test powerCmd setreading Test state ON
reagiert das Icon so schnell, wie es soll.

Bei
attr Test powerCmd {fhem("setreading Test state ON")}
dauert es merklich länger. (Vom Aufruf aus einem Shellskript ganz zu schweigen ...)

Will man aber bei einer tatsächlichen Implementation eine Perl-Subroutine benutzen, statt jedesmal das setreading auszubuchstabieren, landet man unweigerlich bei Variante 2. Das ist das Problem.

Daher meine Idee, die Funktionalität in das PRESENCE-Modul selbst zu integrieren. Das sollte die beste Performance erlauben.

justme1968

der unterschied zwischen den beiden varianten sollte so minimal sein das es nicht zu bemerken ist. auf was für einem rechner ist das?

du musst es nicht aus einem shellscript aufrufen. etwas in der art sollte gehen: attr Test powerCmd setreading Test state ON; "/tmp/myScript.sh"damit wird direkt das reading gesetzt und dann das shellscipt im hintergrund aufgerufen.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Markus Bloch

Hallo Uli,

dein Vorhaben ist mir zu speziell und sehe ich daher nicht im Modul selber sondern in deiner Konfiguration. Wie Andre schon erwähnt hat, ist das mit den vorhandenen Funktionalitäten auch zu machen.

Das das powerCmd als "setreading Test state ON" schneller ist als "{fhem("setreading Test state ON"}" ist normal, da bei der zweiten Variante etwas mehr Overhead durch den Perl-Ausdruck entsteht. Wenn das tatsächlich MERKLICH länger dauert, ist das für mich ein starkes Indiz gegen dein schwächliches ARM-Rechnerchen ;-) Der Unterschied ist bei mir absolut nicht spürbar und befindet sich im unteren Millisekundenberreich.

Gruß
Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Uli Zappe

Zitat von: justme1968 am 18 Juli 2016, 22:31:49
der unterschied zwischen den beiden varianten sollte so minimal sein das es nicht zu bemerken ist.
Ja, und das ist eben definitiv nicht der Fall bei mir.

Zitatauf was für einem rechner ist das?
Auf einem sehr schwachbrüstigen: 400 MHz ARM, 64 MB RAM (FOX Board G20)

Zitatdu musst es nicht aus einem shellscript aufrufen.
Das ist mir schon klar; ich wollte nur der Vollständigkeit halber erwähnen, dass fhem.pl 7072 "setreading Test state ON" noch viel langsamer wäre.

Zitatetwas in der art sollte gehen: attr Test powerCmd setreading Test state ON; "/tmp/myScript.sh"damit wird direkt das reading gesetzt und dann das shellscipt im hintergrund aufgerufen.
Ja, nur bei einer tatsächlichen Implementation wäre da ja kein simples setreading Test state ON, sondern eine IF-Bedingung für ON und OFF, dahinter dann das Shellskript, das diese Unterscheidung erneut treffen muss – da wird das Ganze dann sehr schnell ein sehr langes powerCmd. Du erinnerst Dich, dass es bei unserer ursprünglichen Diskussion auch um die Wartbarkeit des Codes ging – und an dieser Stelle wäre aus meiner Perspektive dann spätestens meine ursprüngliche Lösung mit einem zusätzlichen dummy die bessere Wahl.

Uli Zappe

Hallo Markus,

Zitat von: Markus Bloch am 18 Juli 2016, 22:40:58
dein Vorhaben ist mir zu speziell und sehe ich daher nicht im Modul selber sondern in deiner Konfiguration.
OK, alles klar, dann weiß ich Bescheid und bastle weiter ...  ;)

justme1968

nein. du brauchst kein if. du kannst es als parameter übergeben.

wenn dein rechner so langsam ist das du den unterschied zwischen beiden varianten bemerkst wäre es glaube ich erst recht gut so wenig devices (dummys) zu verwenden. die beeinflussen das system wie beschrieben an vielen stellen. das powerCmd aber nur in dem augenblick in dem auch wirklich geschaltet wird.

ein engzeiliges powerCmd in dem zwei parameter verwendet werden ist meiner meinung nach immer noch übersichtlicher als drei devices (PRESENCE, dummy und notify).

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Uli Zappe

#8
Zitat von: justme1968 am 18 Juli 2016, 22:56:50
nein. du brauchst kein if. du kannst es als parameter übergeben.
Das verstehe ich nicht.

Der Parameter (ich vermute, Du meinst $ARGUMENT) wäre doch on bzw. off. Wenn der Parameter z.B. on ist, dann muss setreading ON setzen. Würde es on setzen, gäbe es ja wieder eine Schleife. Also ist die IF-Bedingung (wenn on, dann ON) sehr wohl erforderlich – oder habe ich da einen Denkfehler?

EDIT: Du hast recht, geht auch mit on. Hatte ich wegen der befürchteten Schleife nie probiert ...

Aber egal, ich will ja sowieso eine Perl-Subroutine verwenden.

Uli Zappe

Zitat von: Markus Bloch am 18 Juli 2016, 22:40:58
[...] nicht im Modul selber sondern in deiner Konfiguration. Wie Andre schon erwähnt hat, ist das mit den vorhandenen Funktionalitäten auch zu machen.
Zitat von: justme1968 am 18 Juli 2016, 15:22:37
und einer passenden internen logik die verhindert das der status schon nach einer sekunde wieder zurück gesetzt wird
Letzteres in einer Konfiguration (statt im Modul selbst) umzusetzen, daran beiße ich mir jetzt aber doch die Zähne aus.

Das Problem ist, dass es ja nicht um eine generelle Verzögerung der Statusanzeige geht, sondern um eine nur für den Fall, dass soeben eine Schaltfläche geklickt wurde.

Es gibt aber, soweit ich sehe, keine Aktion in PRESENCE, um den Status-Check vorübergehend auszusetzen. Ich könnte nur Attribute hin und her ändern, und das würde die Weboberfläche jeweils als Konfigurationsänderung verbuchen und mit dem roten Fragezeichen zum Sichern auffordern – das geht also nicht.

justme1968

ja. das müsste tatsächlich noch ins modul. hier müsste dann state/presence nicht direkt überschrieben werden sondern erst nach dem threshold. bzw. der threshold muss mit einem power wieder zurückgesetzt werden.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Uli Zappe

Zitat von: justme1968 am 19 Juli 2016, 10:02:39
ja. das müsste tatsächlich noch ins modul.
OK, dann bleibt's wohl jetzt erstmal auf dem ,,provisorischen" Stand, den ich bis jetzt erreicht habe.

Markus Bloch

Zitat von: justme1968 am 19 Juli 2016, 10:02:39
bzw. der threshold muss mit einem power wieder zurückgesetzt werden.

Das liese sich machen, sofern sich daraus keine anderweitigen Probleme ergeben. Da bin ich mir noch etwas unschlüssig.

Gruß
Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Uli Zappe

Zitat von: justme1968 am 19 Juli 2016, 10:02:39
bzw. der threshold muss mit einem power wieder zurückgesetzt werden.
Öhm – ist es nicht genau umgekehrt?

Wäre in meinem Anwendungsszenario der Threshold nicht normalerweise 0, würde bei einem power-Ereignis erhöht und dann gleich wieder auf 0 zurückgesetzt?

Ich bin mir eh nicht sicher, ob der Threshold hier der geeignete Mechanismus wäre. Denn zumindest so, wie er im Moment implementiert ist, wird der Status doch nach wie vor verändert, nur eben nicht gleich auf present/absent, sondern nur auf maybe present/maybe absent. Aber wenn z.B. im Falle des Aufweckens das setreading auf on gesetzt wird, dann sollte der Status für eine gewisse Schonfrist ja eben weder auf absent noch auf maybe absent zurückfallen.

Ich befürchte, hier würde zu viel auf die Threshold-Funktion geladen. Ein eigenes set suppressCheck n (mit n = Sekunden, die der Check unterdrückt wird) wäre sauberer.