Widgets Label & Dynamik

Begonnen von rogerknop, 17 Dezember 2021, 09:36:18

Vorheriges Thema - Nächstes Thema

rogerknop

Hallo,

ich benutze sehr häufig die Widgets: https://wiki.fhem.de/wiki/FHEMWEB/Widgets

Da hätte ich 2 Fragen:

1. Würde ich gerne ein reines Label anzeigen. Es gibt ja textField (Label & Inputfeld) und textFieldNL (nur Inputfeld). Ich hätte jetzt gerne noch ein Label ohne Inputfeld. Gibt es dafür schon eine Lösung?

2. Angenommen ich hätte mehrere Devices mit einem User Attribut, die ich in Utils ermittle. Kann ich dann Dynamisch für jedes dieser Devices ein neues Widget generieren zur Laufzeit? Oder wie könnte man ein solches Problem lösen?

Danke & Grüße,
Roger

rudolfkoenig

1. Womoeglich hilft webCmdLabel: https://fhem.de/commandref_modular.html#webCmdLabel
2. Mir faellt z.Zt. nur die kuerzlich eingebaute SetExtensions-Erweiterung ein: wenn ein widget-spec den Regexp {[^ ]+} matcht, dann wird das evalueiert. Siehe auch: https://forum.fhem.de/index.php/topic,124505.msg1190832.html#msg1190832

TomLee

Zitat2. Mir faellt z.Zt. nur die kuerzlich eingebaute SetExtensions-Erweiterung ein: wenn ein widget-spec den Regexp {[^ ]+} matcht, dann wird das evalueiert.

Da komm ich nicht ganz mit, wie ich es verstanden habe greift die Änderung doch nur in setList eines MQTT2_DEVICE ?
Ein Test vor ein paar Tagen in setList bei einem dummy schlug zumindest fehl und zeigte das gleiche Verhalten wie immer ({my im Auswahlfeld).

rogerknop

Hallo Rudi,

WebCmdLabel ist ja nur für das Label zu einem Widget, wenn ich es richtig verstanden habe.
Ich möchte aber eigentlich ein eigenes Widget LABEL, um Readingswerte nur anzuzeigen.

Das mit den setExtensions hört sich spannend an. Allerdings geht es ja bei mir darum, dass ich eigentlich mehrere Widgets on-the-fly "generieren" möchte.

Grüße, Roger

rudolfkoenig

ZitatEin Test vor ein paar Tagen in setList bei einem dummy schlug zumindest fehl und zeigte das gleiche Verhalten wie immer ({my im Auswahlfeld).
Dummy ruft SetExtensions nur bei gesetzten useSetExtensions Attribut auf.


ZitatWebCmdLabel ist ja nur für das Label zu einem Widget, wenn ich es richtig verstanden habe.
Die Aufgabe ist schwammig genug beschrieben, so dass ich Faelle vorstellen kann, wo ein webCmdLabel (evtl. mit HTML Formatierung) sie loesen koennte.
Und was Anderes habe ich nicht gefunden :)

ZitatAllerdings geht es ja bei mir darum, dass ich eigentlich mehrere Widgets on-the-fly "generieren" möchte.
Ich will nicht behaupten, dass das Feature diese Aufgabe einfach und direkt loest.
Es ist nur das Einzige, was mir im Zusammenhang mit dynamischen Widget einfaellt.

Der Bereich der Befehle (webCmd & co) ist nicht so dynamisch, wie der Bereich der Statusanzeige, wo man mit devStateIcon (auch) beliebiges HTML generieren kann.

Der Fokus von FHEMWEB ist nicht ein beliebig konfigurierbares Bedienungs-Frontend (das koennen andere wie FUIP besser), sondern was out-of-the-box halbwegs Brauchbares, um die Automatisierung zu konfigurieren.

beaune

Als Widget für ein reines Label habe ich schon mal iconLabel verwendet. Gibt man da kein Icon an, wird der aktuelle Wert angezeigt. Hilft das vielleicht?

rogerknop

@Rudi: Das ist mir auch schon klar, dass es kein beliebig konfigurierbares UI ist. Allerdings gab es schon oft Lösungen, die ich selbst nicht direkt gesehen habe. Daher wollte ich nur nachfragen.

@beaune:
Das klingt genau nach so einer Lösung, die ich suche!
Ich habe im setList mal lastMsg:iconLabel hinzugefügt. In der Hoffnung dass dan ein Reading lastMsg angelegt wird, was ich mit einem bel. Text setzen kann.

Damian

#7
Hier ein Beispiel mit "voller" Dynamik, sowohl ein Label als auch ein FHEM-Widget werden durch das Ändern der entsprechenden Readings hier wochentag bzw. Tage dynamisch angepasst (die Definition muss nicht angepasst werden).

defmod di_set DOIF {}
attr di_set room test4
attr di_set uiTable {package ui_Table;;}\
[$SELF:wochentag]|widget([$SELF:wochentag],::ReadingsVal("$SELF","Tage",""))



Doku siehe: https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#FHEM-Widgets_mit_der_Funktion_widget

Edit: siehe Animation im Anhang
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rogerknop

Hallo Damian,

das kling ja echt interessant!

Habe schon einiges gelesen, bin aber noch nicht ganz durchgestiegen.
Gibte s eine Möglichkeit die Tabellendefinition mit den Zeilen und Spalten auch in eine Perl Funktion auszulagern?
Dass hier dann auch ein String mit der Definition zurückgeliefert wird?

Auf jeden Fall tolle Arbeit!

Danke & Grüße,
Roger

Damian

Warum willst du die Tabellendefinition in Perl auslagern? Die einzelnen Zellen sind weitgehend Perl, sie werden mit eval ausgewertet. Soll eine Zelle sich dynamisch ändern können, braucht sie einen Trigger - das sind die Angaben in eckigen Klammern - das versteht Perl nicht.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rogerknop

Ich habe mal einen einfachen Test gestartet:

fhem.cfg

define rokuiTable DOIF ##
setuuid rokuiTable 61bf6934-f33f-0fde-273d-3c170e694cf8b154
attr rokuiTable alias Meldungen
attr rokuiTable group Bewässerung Garten
attr rokuiTable room Bewässerung
attr rokuiTable uiTable ## keine Package-Definition im Perlblock\
\
## Tabellendefinition befindet sich im Package main\
\
## Funktionen aus dem main-Package können unmittelbar angegeben werden\
rokTable()


99_myUtils.pm

sub rokTable {
  my $table = "<table>";
  $table .= "<tr><td>R1S1</td><td>R1S2</td></tr>";
  $table .= "<tr><td>R2S1</td><td>R2S2</td></tr>";
  #my $wid = ui_table::WID([<device>:<reading>],<widget parameter>);
  $table .= "</table>";
  return ($table);
}


Das Ergebnis ist schon super!
Nur würde ich gerne noch in das HTML Widgets reingenerieren.
Da komme ich derzeit noch nicht weiter, wäre aber echt genial!
Dann kann man sich ja beliebig eine Ausgabe zusammenbasteln.

Danke & Grüße,
Roger


rogerknop

Zitat von: Damian am 19 Dezember 2021, 18:15:19
Warum willst du die Tabellendefinition in Perl auslagern? Die einzelnen Zellen sind weitgehend Perl, sie werden mit eval ausgewertet. Soll eine Zelle sich dynamisch ändern können, braucht sie einen Trigger - das sind die Angaben in eckigen Klammern - das versteht Perl nicht.

Ich möchte ja dynamisch auch die Zeilen generieren.
Aber ich glaub ich verstehe das Problem mit dem Trigger.
Das würde bedeuten, dass meine Anzeige sich bei Änderungen nicht Updaten würde - korrekt?
Und heisst das, dass ich bzgl. meiner vorherigen Frage keine Widgets mit reingenerieren kann?

Damian

#12
Zitat von: rogerknop am 19 Dezember 2021, 18:49:41
Ich möchte ja dynamisch auch die Zeilen generieren.
Aber ich glaub ich verstehe das Problem mit dem Trigger.
Das würde bedeuten, dass meine Anzeige sich bei Änderungen nicht Updaten würde - korrekt?
Und heisst das, dass ich bzgl. meiner vorherigen Frage keine Widgets mit reingenerieren kann?

So ist es. Die Idee hinter uiTable ist, dass man weitgehend von HTML/CSS-Syntax verschont wird. Natürlich kann man sich was in HTML bauen und in Funktionen verstecken, aber dann ist es statisch und ändert sich nur, wenn man die Seite aktualisiert. Soll eine Zelle sich automatisch ändern können, dann braucht sie halt einen Trigger. Es gibt auch Templates, damit lassen sich mit eine FOR-Schleife Tabellen mit vielen gleich aufgebauten Zeilen generieren. Allerdings ist die Größe der Tabelle selbst durch ihre Definition festgelegt. Soll sich die Anzahl von Spalten bzw. Zeilen ändern, dann muss die Definition geändert werden. Da aber eine Zelle einer Tabelle sich beliebig ändern kann, so kann man dort dynamisch eine Liste anzeigen, siehe https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Visualisierung:_offene_Fenster

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rogerknop

OK, aber könnte ich damit auch eine Liste von Devices erstellen, die ein bestimmten User Attribut haben?


[@as(<br>)"Fenster$":state:"open","keine"]


Hier so etwas wie: alleDevices mit UserAttribut ValveIP ?

Damian

Zitat von: rogerknop am 19 Dezember 2021, 19:14:47
OK, aber könnte ich damit auch eine Liste von Devices erstellen, die ein bestimmten User Attribut haben?


[@as(<br>)"Fenster$":state:"open","keine"]


Hier so etwas wie: alleDevices mit UserAttribut ValveIP ?

ja, siehe: https://fhem.de/commandref_DE.html#DOIF_aggregation
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rogerknop

Hallo Damian,

also ich habe jetzt mal jede Menge gelesen, aber um ehrlich zu sein bei Weitem noch keinen Durchblick.

Ich würde gerne als erstes Bespiel eine Liste aller Devices, die das Attribut ValveIP haben.
Die Alias Namen der Devices möchte ich in der ersten Spalte auflisten und das Widget Switch ON/OFF in der 2. Spalte.

Ich scheitere schon bei der Liste :-(


valveDevices:[@as(<br>)".*" and AttrVal($name,"ValveIP","") ne "", "keine"]


An dem uiTable Attribut bin ich noch gar nicht. Allerdings bin ich nicht sicher, ob ich den Ansatz mit dem generierten Reading valveDevices gehen soll, oder FOR nutzen soll oder AggrDoIf nutzen soll. Bin erschlagen... :-(

Wäre für weitere Tipps sehr dankbar!

Danke & Grüße,
Roger

Damian

Ja, der Funktionsumfang ist mittlerweile gut angewachsen, da kann man gerne schon den Überblick verlieren. Deswegen gibt es zu jedem Feature konkrete Beispiele.

Ausgehend von dem Beispiel aus der Commandref:

ZitatListe der Devices, deren state-Reading "on" ist und das Attribut disable nicht auf "1" gesetzt ist:

[@"":state:$_ eq "on" and AttrVal($name,"disable","") ne "1"]

Würde es dann für dich bedeuten:


[@as(<br>)"":state: AttrVal($name,"ValveIP","") ne "", "keine"]

Allerdings würde man aufgrund der fehlenden Trigger-Regex "":... auf alle Events im System reagieren. Dann würde die Funktion bei jedem Event das ganze System nach dem Attribut durchsuchen - das wäre ein richtiger Performance-Fresser, den man vermeiden sollte.

Dafür müsstest du die Trigger-Regex eingrenzen, damit die Funktion eben nicht bei allen Events die aufwändige Suche durchlaufen muss.

Wenn du deinen Ausdruck fertig hast, dann brauchst du den nur noch in uiTable angeben:

"meine Devices"|[@as(<br>)"<meine Regex>":state: AttrVal($name,"ValveIP","") ne "", "keine"]
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rogerknop

Hallo Damian1

1. Ich habe nun mal den Filter hinter DOIF gesetzt und hoffe damit weniger Last im FHEM zu produzieren - korrekt?

2. Dein Vorschlag für das uiTable hat sofort funktioniert für die Device Liste - sieht so einfach aus...

3. Nun möchte ich nicht nur den Alias des Devices sehen sondern in einer zusätzlichen Spalte noch ein weiteres Reading oder Attribut oder ein WID

Hier mein Define:

define rokuiTable2 DOIF [@"":state: AttrVal($name,"ValveIP","") ne ""]
setuuid rokuiTable2 61c0c56d-f33f-0fde-b1a8-320785841dad16d6
attr rokuiTable2 alias Meldungen
attr rokuiTable2 group Automatische Bewässerung
attr rokuiTable2 room Bewässerung
attr rokuiTable2 uiTable [@as(<br>)"":state: AttrVal($name,"ValveIP","") ne "", "keine"]|<<<READING oder ATTRIBUT von $_>>>\


Ich habe mir dann noch dein Beispiel mit FOR angeschaut: https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Eine_for-Schleife_mit_Hilfe_des_FOR-Befehls

Jedoch weiss ich nicht, wie ich meine AttrVal Bedingung mit dem AggrDoIf kombinieren kann?

Ich bin anstrengend... gell!?

DANKE, Roger



Damian

Wie hast du den Filter definiert? In deiner Definition sehe ich keinen Filter.

Das, was du vorhast, ist schon komplizierter, da muss man schon in Perl etwas mehr programmieren, der Ausdruck [...] kann ja nur Devicenamen liefern oder nur spezielle Berechnungen durchführen. Im Grunde muss man die Devicenamen mit einer Perl-for-Schleife durchlaufen und dann mit ReadingsVal oder sonst etwas Dinge bestimmen. Aber für sowas würde ich besser spezialisierte Module wie ReadingsGroup nehmen.


Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

rogerknop

Ich dache meine Regexp im define ist der Filter :-)
Führt das nicht dazu, dass nur Änderungen an den Devices mit dem Attribut ValveIP das DOIF triggern?

Und da schließt sich der Kreis mit dem Perl. Perl ist ok für mich. Ich habe viele Lösungen in meinem Utils.pm
Wenn ich nun ein Beispiel hätte für meine Anforderung und könnte einfach eine Perl Funktion aufrufen, die das Ergebnis liefer, dann wäre es ok für mich.

Damian

#20
Für die Tabelle selbst brauchst du in der Definition nichts anzugeben:

define rokuiTable2 DOIF {}
attr rokuiTable2 uiTable [@as(<br>)"<<< hier muss deine RegEx-Filter-Definition stehen >>>":state: AttrVal($name,"ValveIP","") ne "", "keine"]
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF