FHEM Forum

FHEM => Frontends => FHEMWEB => Thema gestartet von: pula am 22 Juli 2020, 13:09:50

Titel: devStateIcon und refresh
Beitrag von: pula am 22 Juli 2020, 13:09:50
Hi,

ich habe ein device, das Button-Clicks (per MQTT2) bekommt.
Es wird also ein click empfangen, wenn jemand einen Button drückt. Aber kein "unclick" (will damit sagen: es gibt kein Ereignis, wenn der Button losgelassen wird).
Ich würde gerne trotzdem den Status der Buttons visualisieren und habe dazu eine kleine Funktion in myUtils, die das Alter eines Readings in Sekunden zurückgibt.
Jetzt habe ich bei dem device folgendes devStateIcon:
{my $icon = readingAge($name,"STATE") lt "10"?"toggle-on\@red":"toggle-on\@grey";; "<div>" . FW_makeImage("$icon","Button") . "</div>"}
Das funktioniert zwar, aber nach den 10 Sekunden bleibt das Icon solange rot, bis ich im Browser refreshe.
Habe das mit flex und f18 getestet - das Verhalten ist bei beiden Styles gleich....
Hat jemand eine Idee, wie man das ändern kann, ohne das System heftig zu belasten?
Danke im voraus und cheers,
Pula
Titel: Antw:devStateIcon und refresh
Beitrag von: Beta-User am 22 Juli 2020, 13:35:22
Hmm, also irgendwie mag ich noch nicht glauben, dass das wirklich gut "funktioniert"...

- Wo kommt die Funktion "readingAge" her? Kenne nur ReadingsAge().
- Für Zugriff auf STATE braucht man aber nicht die "Readings.*"-Funktionen, denn das ist ein Internal.
- ReadingsAge() liefert eine Zahl zurück. Daher sollte der Vergleich nummerisch sein (< statt lt).

ABER: Damit devStateIcon ausgeführt wird, braucht man einen trigger, also irgendein READING, das sich an dem Device ändert. Wenn es das nicht gibt, müßtest du einen nachlaufenden Timer definieren (via at, z.B., wenn das "state"-Reading aktualisiert wird), der eben dann später ein (anderes) Reading setzt...

Insgesamt ist das aber mMn. insgesamt keine gute Lösung.
Titel: Antw:devStateIcon und refresh
Beitrag von: pula am 22 Juli 2020, 13:50:22
Danke für die rasche Antwort.
das readingAge ist eine kleine Funktion in meiner myUtils (hatte ich geschrieben).
Das mit dem Zugriff auf STATE funktioniert allerdings auch mit ReadingsVal (ist aber glaube ich das einzige Internal, mit dem das geht).
Danke für den Hinweis mit lt, das hatte ich übersehen und für den Tip mit dem Event.
Jetzt sieht das Ganze so aus:
{my $icon = readingAge($name,"STATE") < 10?"toggle-on\@red":"toggle-on\@grey";; "<div>" . FW_makeImage("$icon","Button") . " (" . ReadingsVal($name, "STATE", "") . " on " . ReadingsTimestamp($name, "STATE", "1970-01-01 01:00:01") . ")</div>"}

Du hast recht, die Lösung ist nicht SO gut. Hättest Du einen eleganteren Vorschlag? Ich _könnte_ natürlich in dem device, das die Nachricht schickt, ein "unclick" hinterherschicken, aber irgendwie gefällt mir das auch nicht so gut und was noch besseres ist mir bisher noch nicht eingefallen :-(
Cheers,
Pula
Titel: Antw:devStateIcon und refresh
Beitrag von: rudolfkoenig am 22 Juli 2020, 13:53:51
Ich wuerde sowas mit CSS animation/transition lösen.
Titel: Antw:devStateIcon und refresh
Beitrag von: pula am 22 Juli 2020, 14:07:02
Klingt interessant, aber leider fehlt es mir hier (noch) an Verständnis für den genauen Aufbau von fhemweb.
Wo würde man denn den css-code hier hinterlegen für einzelne Icons?
Titel: Antw:devStateIcon und refresh
Beitrag von: rudolfkoenig am 22 Juli 2020, 14:11:50
In der eigenen .css Datei (z.Bsp. www/fhemweb/mystyle.css), die man per cssFiles Attribut der FHEMWEB Instanz bekanntgibt.

Mit f18 kann man CSS-Anweisungen auch ueber Select-Style, Additional-CSS eintragen.
Titel: Antw:devStateIcon und refresh
Beitrag von: pula am 22 Juli 2020, 14:24:57
Super, danke! Das hilft weiter!
Titel: Antw:devStateIcon und refresh
Beitrag von: pula am 22 Juli 2020, 15:50:00
Nur, falls das mal jemand braucht.
Habe es aus Gründen der Faulheit jetzt anders gelöst.
Hab das toggle-on.svg kopiert auf toggle-button.svg und ein animate eingebaut:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="468pt" height="571pt" viewBox="0 0 576 512"
preserveAspectRatio="xMidYMid meet" id="toggle_button">
<g fill="#808080" stroke="none">
<path id="button" d="M384 64H192C86 64 0 150 0 256s86 192 192 192h192c106 0 192-86 192-192S490 64 384 64zm0 320c-70.8 0-128-57.3-128-128 0-70.8 57.3-128 128-128 70.8 0 128 57.3 128 128 0 70.8-57.3 128-128 128z"/>
<animate xlink:href="#button" attributeName="fill" from= "#ff0000" to="#808080" dur="10s" /></g>
</svg>

Das wird dann in devStateIcon wie weiter oben beschrieben gesetzt:
{my $icon = readingAge($name,"STATE") < 10?"toggle-button":"toggle-on\@grey";; "<div>" . FW_makeImage("$icon","Button") . " (" . ReadingsVal($name, "STATE", "") . " on " . ReadingsTimestamp($name, "STATE", "1970-01-01 01:00:01") . ")</div>"}
Da das Icon dann nach Ablauf der Animation genau dem zweiten Icon (toggle-on) entspricht, passt das Ergebnis optisch wieder, auch ohne refresh! Und hat zusätzlich den Vorteil, dass man wegen des blasser werdenden Rot auch erkennt, ob ein Button gerade gedrückt wurde oder schon vor ein paar Sekunden.
Danke auf jeden Fall für den Hinweis Richtung css, das hat mich daran erinnert, dass man so was auch direkt im svg machen kann!
Cheers,
Pula