[erledigt] uiTable - Widget per Auswahl anzeigen oder nicht

Begonnen von Sany, 26 Februar 2021, 13:05:50

Vorheriges Thema - Nächstes Thema

Sany

Hallo zusammen,

ich habe folgendes vor: ein DOIF ist zum "bedienen" eines HM-Wandthermostat bestimmt. Da ich einige dieser Thermostaten habe habe ich das ganze generalisiert, d.h. am Anfang wird per push dem DOIF der Devicename, Anzeigename und ein paar weitere Dinge "mitgeteilt", der Rest "entsteht" dann automatisch, also Steuerung und uiTable. Das funktioniert soweit wie gewünscht.
Nun wollte ich das noch so machen, dass je nach Bedarf Widgets angezeigt werden oder nicht. Es wird also beim push noch "admin" oder "user" mitgegeben und dann im attr uiTable ausgewertet. Prinzipiell geht das, per tenärem Operator, allerdings wenn ich ein Widget (WID()) je nach Auswahl anzeigen lassen möchte wird dieses nicht angezeigt. Im Log gibts auch keinen Fehler, lediglich im list sieht man an der Stelle:
Zitat'error Undefined subroutine &ui_Table::WID called at (eval 8020796) line 1.
in expression: ("admin" eq "admin")?(WID(::ReadingValDoIf($hash,'di_UI_WidgetTest','battery'),"uzsuToggle,ok,low")):"nix"'
             1          package ui_Table;::FW_makeImage("fts_window_2w\@green")

Hier mal ein Test-DOIF als RAW zum nachstellen:
defmod di_UI_WidgetTest DOIF subs{\
push (@{$_Dev},[qw(Device01 Name01 "admin")]);;\
push (@{$_Dev},[qw(Device02 Name02 "user")]);;\
}
attr di_UI_WidgetTest room UI
attr di_UI_WidgetTest uiTable {\
package ui_Table;; \
}\
\
FOR (@{$_Dev},""|"$_$2"|""|)""\
FOR (@{$_Dev},""|($_$3 eq "admin")?(WID([$SELF:battery],"uzsuToggle,ok,low")):"nix".::FW_makeImage("fts_window_2w\@green")|""|)""\
FOR (@{$_Dev},""|($_$3 eq "admin")?"admin":"user".::FW_makeImage("fts_window_2w\@green")|""|)""\
WID([$SELF:battery],"uzsuToggle,ok,low")

Ich hab da schon alle möglichen Kombinationen mit Klammern und Quotes ausprobiert, bekomme aber entweder Syntaxfehler oder eben etwas mit undefined subroutine.
Dass das Widget funktioniert sieht man an der letzten Zeile der uiTable, genau so sollte es auch in der ersten Spalte vor dem Icon angezeigt werden.

Kann das überhaupt funktionieren? Es scheint ja irgendwie nich das richtige aus dem ternären Operator rauszukommen?

Gruß

Sany
fhem als LXC auf Proxmox auf einem minix Z100 , weitere LXC mit ZigBee2MQTT, MariaDB und Grafana. Homematic, FS20, mySensors, MQTT2, Tasmota, Shelly, Z-Wave  ....

Damian

WID hat eine Sonderfunktion - es ist keine echte Perlfunktion. Es ist nicht mit den anderen ui_Table-Funktionen vergleichbar.

WID verhält sich statisch, es wird bei der Definition registriert und darf sich nicht zur Laufzeit ändern.

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

Sany

Hallo Damian,

es soll sich ja auch nicht später ändern, sondern nur beim Aufbau der uiTable. Aber vermutlich geht das dann so nicht. Allerdings auch wieder seltsam da die anderen Teile der uiTable ja schon je nach Inhalt des push-arrays aufgebaut werden. Daher kam ja der Gedanke, das es so auch gehen könnte.
fhem als LXC auf Proxmox auf einem minix Z100 , weitere LXC mit ZigBee2MQTT, MariaDB und Grafana. Homematic, FS20, mySensors, MQTT2, Tasmota, Shelly, Z-Wave  ....

Damian

OK. Dann habe ich da etwas vorgesehen:

https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Eigene_uiTable-Funktionen_programmieren

Widgets sind vom Typ 3 mit vier Rückgabe-Argumenten, siehe Beispiel für slider.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Sany

So, musste leider gestern meine Studien abbrechen, dafür ist es nun fertig und funktioniert. Damian vielen Dank für den Link zu den Funktionen.

Es läßt sich nun nicht nur DOIF-Perlcode automatisiert abhängig von einer Vorgabe realisieren, sondern auch die uiTable.
Bei den Widgets (WID) gibt es aber einen Unterschied, ob direkt oder per eigener Funktion in der uiTable erzeugt:
Wenn ich z.B.
WID([$SELF:battery],"uzsuToggle,ok,low") eintrage, bekomme ich sofort den Umschaltknopf angezeigt und kann ihn bedienen. Ein Reading battery entsteht automatisch und es werden events erzeugt. ReadingList ist nicht erforderlich.
Bei der Variante über die Funktion wird das Widget auch erzeugt und ist bedienbar, aber es passiert nix. Das Reading erscheint nicht. Es genügt dann ein attr ReadingList mit dem gewünschten Eintrag, dann ändert sich der Wert im Reading und events werden erzeugt. Aber auch das kann man automatisch machen.
Hier noch mal ein Beispiel als RAW:
defmod di_UI_WidgetTest DOIF subs{\
push (@{$_Dev},[qw(Device01 Name01 "user")]);;\
push (@{$_Dev},[qw(Device02 Name02 "admin")]);;\
\
if ($::init_done) {\
my $ReadLst = "";;\
for (my $i=0;;$i < @{$_Dev};;$i++) {\
$ReadLst = $ReadLst."thMode_$_Dev[$i][1]";;\
($i < @{$_Dev}-1)?$ReadLst = $ReadLst.",":"";;\
}\
\
fhem("attr $SELF readingList ".$ReadLst);;\
}\
} ## end subs\
\
## die Funktion iconRadio in der my_uiTable.tpl:\
###############################################\
## sub iconRadio {\
##    my ($value,$set)=@_;;\
##    $set="set" if (!defined $set);;\
## return ($value,                   ## Zahlenwert\
##            "",                       ## leer\
##            "iconRadio,use4icon\@$_colorBlueBright,auto,sani_heating_automatic\@$_colorGray,manual,sani_heating_manual\@$_colorGray",      ## FHEM-Widget\
##            $set                     ## set-Befehl des FHEM-Widgets\
##            );;\
###############################################\
}

attr di_UI_WidgetTest room UI
attr di_UI_WidgetTest uiTable {\
IMPORT ./FHEM/my_uiTable.tpl\
##package ui_Table;; \
\
}\
\
FOR (@{$_Dev},""|"$_$2"|""|)""\
FOR (@{$_Dev},""|($_$3 eq "admin")?iconRadio([$SELF:thMode_$_$2]):"nix".::FW_makeImage("fts_window_2w\@green")|""|)""\
FOR (@{$_Dev},""|($_$3 eq "admin")?"admin":"user".::FW_makeImage("fts_window_2w\@green")|""|)""\

ich habe extra die Zeile attr ReadingList .... entfernt, damit sie bei der Def neu erstellt wird.

Wozu das Ganze: bei mir als Bedienoberfläche für die Heizkörperthermostaten. Es soll nur nicht jeder alles können. Admin darf alles ändern (z.B. Solltemp,weekPrg, auto/manuell oder lock/unlock), ein "user" darf nur die Temperatur verändern.
Der Code steht nun in 9 DOIFs für die Thermostaten. Wenn ich etwas ändern möchte kann ich bis auf die push-Zeilen einfach alles überkopieren und muss nicht für jeden Thermostaten einzelne Zeilen "anfassen".
Lohnt sich vermutlich nur bei Dingen, die mehrfach aber im Prinzip gleich vorhanden sind, also Thermostaten oder Rollos.

Gruß

Sany
fhem als LXC auf Proxmox auf einem minix Z100 , weitere LXC mit ZigBee2MQTT, MariaDB und Grafana. Homematic, FS20, mySensors, MQTT2, Tasmota, Shelly, Z-Wave  ....

Damian

#5
Du brauchst ReadingList, wenn du per set-Befehl ein Reading ändern willst.

In dem Beispiel wurde default der Befehl "set" angegeben. Das setzt dann voraus, dass das Device den set-Befehl für das jeweilige Reading unterstützt.

$set="set" if (!defined $set);

Dieses Verhalten erreicht man mit ReadingList.

Wenn man dagegen in der Widget-Funktion (bei dir iconRadio) definiert:

$set="" if (!defined $set);

funktioniert das, wie bei WID, dann braucht man für das einfache Setzen eines Readings kein ReadingList (entsprechend setreading).

Ich habe jetzt die Wiki-Doku angepasst (ohne set-Kommando als default).

Zusammengefasst mit der obigen Anpassung ergeben sich dann folgende Möglichkeiten (entsprechend WID):

Setzen eines Readings ohne ReadingList (entspricht dem Befehl setreading): iconRadio ([<DEV>:<Reading>]) oder  iconRadio ([<DEV>:<Reading>],"")

Setzen eines Readings per set-Befehl (mit ReadingList oder wenn das Device set für das Reading unterstützt): iconRadio ([<DEV>:<Reading>],"set")

Wenn Reading und set-Befehl sich unterscheiden (mit ReadingList oder wenn das Device set für das Reading unterstützt): iconRadio ([<DEV>:<Reading>,"set <andere Angabe>"])

erforderlich z. B. beim THRESHOLD-Modul beim Setzen der desired-Temperatur, das Reading heißt dort desired_value, der set Befehl heißt aber set desired


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

Sany

Vielen Dank für die Erläuterungen. Damit kann man sich das attr setzen auch wieder sparen. Prima!
fhem als LXC auf Proxmox auf einem minix Z100 , weitere LXC mit ZigBee2MQTT, MariaDB und Grafana. Homematic, FS20, mySensors, MQTT2, Tasmota, Shelly, Z-Wave  ....

Damian

Zitat von: Sany am 27 Februar 2021, 18:13:47
Vielen Dank für die Erläuterungen. Damit kann man sich das attr setzen auch wieder sparen. Prima!

Ich werde noch eine Perl-Funktion namens widget definieren, die WID entspricht.

Für STY, habe ich bereits die Funktion style erstellt: https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Textformatierungen_mit_Hilfe_der_Funktion_style
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF