neues Attribut: uiTable - DOIF User Interface, neues Attribut: DOIF_Readings

Begonnen von Damian, 07 Oktober 2017, 23:29:48

Vorheriges Thema - Nächstes Thema

Damian

Features:

- pro DOIF eine beliebige UI-Tabelle definierbar
- alle FHEMWEB-Widgets nutzbar
- alle FHEM-Icons nutzbar
- DOIF-Syntax verwendbar
- alle Devices und Readings in FHEM direkt darstellbar und ansprechbar
- dynamische Styles (z. B. Temperaturfarbe abhängig vom Temperaturwert)
- es brauchen keine eigenen css- oder js-Datei definiert werden
- Template-Definitionen in Template-Dateien

Im Anhang: ein Statusbildschirm mit ein paar DOIFs, lässt sich gut als weitere WEB-Instanz ohne Logo, Raumauswahl und Eingabezeile auf einem Wandtablet/Smartphone darstellen und bedienen! Für Smartphone kann die Anzeige in der WEB-Instanz per Column-Attribut auf eine Spalte beschränkt werden.

Der Vorteil: einmalige Konfiguration/Pflege - mehrfache Nutzung auf verschiedenen Medien

Edit: letzte DOIF-Version und doif.js wurden eingecheckt
Edit: Statusbildschirm mit aktueller Uhrzeit und Datum
Edit: Statusbildschirm auf verschiedenen Ausgabegeräten
Edit: DOIF-Raw-Definitionen des Statusbildschirms, FHEMWEB-Tablet-RAW-Definition, Darksmallscreenstyle.css für Tablet und Smartphone
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

#1
Ich habe die erste Dokumentation verfasst. Sie wird im Laufe der Zeit bis zum Einchecken des Moduls hier verfeinert.

Doku

Mit dem Attribut uiTable kann innerhalb eines DOIF-Moduls ein WEB-UI in Form einer Tabelle erstellt werden. Die Definition der Tabelle wird mit Hilfe von Perl sowie FHEM-Widgets kombiniert mit DOIF-Syntax vorgenommen.

Features:

- pro DOIF eine beliebige UI-Tabelle definierbar
- alle FHEM-Widgets nutzbar
- alle FHEM-Icons nutzbar
- DOIF-Syntax verwendbar
- alle Devices und Readings in FHEM direkt darstellbar und ansprechbar
- dynamische Styles (z. B. Temperaturfarbe abhängig vom Temperaturwert)
- es brauchen keine eigenen css- oder js-Datei definiert werden
- Template-Definitionen in Template-Dateien

Die Definiton der Tabelle ist in zwei Bereiche unterteilt. Im ersten Bereich, in geschweiften Klammern, werden Tabellenformatierungen sowie Templates als Zeichenketten und eigene Perlfunktionen definiert. Dieser Bereich ist optional.

Im zweiten Bereich werden die Inhalte der Tabelle definiert. Optional können Template-Methoden zuvor definiert werden.

Beide Bereiche werden aufbereitet und anschließend vom Perlinterpreter übersetzt, daher sind die Definitionsmöglichkeiten sehr vielfältig.

Aufbau des uiTable-Attributs

{
<Definition von Template-Attributen und Zellenformatierungen>
}
<Template-Methoden>

<Tabellendefinition>


Die Tabellendefinition wird über die Definition von Zellen vorgenommen. Die Zellen werden mit | voneinander abgegrenzt.


<Zellendefinition erste Zeile erste Spalte>  | <Zellendefinition erste Zeile zweite Spalte  | ... # Definition der ersten Tabellenzeile
<Zellendefinition zweite Zeile erste Spalte> | <Zellendefinition zweite Zeile zweite Spalte | ... #Definition der zweiten Tabellenzeile
usw.



Die Zellendefinition kann sein:

1) <Perlausdruck mit [DOIF-Syntax]>

2) STY(<Perlausdruck mit [DOIF-Syntax]>,<Style-Definition mit [DOIF-Syntax]>)

3) WID([<DEVICE>:<READING>],<FHEM-Widget definition mit [DOIF-Syntax]>,"<set-/setreading-Kommando optional>")

Die oberen Definitionen können innerhalb einer Zelle mit Punkt bzw. Komma beliebig kombiniert werden. Beim Punkt werden die Ausdrücke aneinandergereiht, bei Komma werden die Ausdrücke mit Zeilenumbruch untereinander innerhalb einer Zelle angeordnet.

Zu 1)

Diese Definition wird verwendet für: Texte, Inhalte von Readings oder Rechenausdrücke. Angaben, die die Zelle aktualisieren sollen, müssen in gewohnte DOIF-Syntax angegeben werden.

Beispiele:

Einfacher Text:

"Status"

Reading:

[Aussen:temperatur]

Berechnung:

([Wohnzimmer:temperature]+[Kinerzimmer:temperature])/2

Perlfunktion:

min([Wohnzimmer:temperature],[Kinerzimmer:temperature])

Mehrere Angaben einer Zelle können mit einem Punkt, wie auch in Perl bei Zeichenketten üblich, konkateniert werden:

"Temperatur: ".[Aussen:temperatur]

"Die maximale Temperatur der Kinderzimmer beträgt: ".max([Kind1:temperature],[Kind2:temperature])

Zu 2)

Über die Funktion STY werden Angaben mit Formatierungen über das HTML-Style Attribut vorgenommen.

Beispiele:

Formatierter Text:

STY("Esszimmer","font-weight:bold;font-size:16pt;color:#0000FF")

Formatiertes Reading:

STY([kuehlschrank:temperature],"color:#0000FF")

Formatiertes Reading mit dynamischer Farbgebung abhängig von der Temperatur

STY([Keller:humidity],"color:".DOIF_hsv([Keller:humidity],50,75,40,264,60,90))

DOIF_hsv ist eine DOIF-Funktion, bei der man den Farbverlauf definieren kann.

Syntax für DOIF_hsv Funktion:

DOIF_hsv(<value>,<min_value>,<max_value>,<min_hsv>,<max_hsv>,<saturation>,<lightness>)

Es wird durch eine feste Vorgabe von saturation und lightness, linear ein Farbton für value errechnet, dabei entspricht min_value min_hsv und max_value max_hsv.

Die gewünschten Werte für <min_hsv>,<max_hsv>,<saturation>,<lightness> können mit Hilfe eines color-Pickers bestimmt werden.

Weiterhin lässt sich ebenfalls jede andere Perlfunktion verwenden, die eine beliebige HTML-Style-Formatierung vornimmt.

Zu 3)

Über die Funktion WID werden FHEM-Widgets definiert. Es können alle in FHEM vorhanden FHEM-Widgets verwendet werden

Beispiele:

Brennericon

WID([Brenner:state],"iconLabel,closed,sani_boiler_temp\@DarkOrange,open,sani_boiler_temp")

Die Widget-Definition entspricht der FHEM-Wigdet-Syntax, siehe: https://wiki.fhem.de/wiki/FHEMWEB/Widgets

Thermostatdefinition mit Hilfe des knob-Widgets:

WID([TH_Bad_HM:desired-temp],"knob,min:17,max:25,width:45,height:40,step:0.5,fgColor:DarkOrange,bgcolor:grey,anglearc:270,angleOffset:225,cursor:10,thickness:.3","set")

Definition von Template-Attributen, Zellenformatierungen und Perl-Funktionen

Im ersten Bereich werden sog. Template-Attribute als Variablen definiert, um wiederholende Zeichenketten in Kurzform anzugeben.

Template-Attribute werden intern als hash-Variablen abgelegt.

Die Syntax lautet

$TPL{<name>}=<Perlsyntax für Zeichenketten>

<name> ist beliebig wählbar.

Bsp.

$TPL{HKnob}="knob,min:17,max:25,width:45,height:40,step:0.5,fgColor:DarkOrange,bgcolor:grey,anglearc:270,angleOffset:225,cursor:10,thickness:.3";

Damit würde die obige Definition des Widgets wie folgt aussehen:

WID([TH_Bad_HM:desired-temp],$TPL{HKnob},"set")

Weiterhin können einzelne Zellen-, Zeilen- oder Spaltenformatierungen definiert werden, dazu werden folgende Bezeichner benutzt:

$TD{<Zellenbereich für Zeilen>}="<HTML-Formatierung der Zellen>"
$TC{<Zellenbereich für Spalten>}="<HTML-Formatierung der Spalten>"
$TR{Zeilenbereich}="<HTML-Formatierung von Zeilen>"


mit

<Zellen/Spalten/Zeilen-Bereich>: Zahl|kommagetrennte Aufzählung|Bereich von..bis

Es können ebenfalls beliebige Perl-Funktionen definiert werden, die innerhalb der Tabellendefinition genutzt werden können. Sie sollten mit FUNC_ beginnen. Damit wird sichergestellt, dass die Funktionen systemweit eindeutig sind.

Bsp. Funktion für temperaturabhängige Farbgebung

sub FUNC_temp
{
  my ($temp)=@_
    return ("font-weight:bold;font-size:12pt;color:".DOIF_hsv ($temp,15,35,210,360,60,90));
}


Template-Methoden

Bei komplizierteren Ausdrücken, die mehrfach verwendet werden sollen, können Template-Methoden vor der Tabellendefinition definiert werden:

Syntax

DEF TPL_<name>(<Definition mit Platzhaltern $1,$2 usw.>)

In der Tabellendefinition können die zuvor definierten Template-Methoden genutzt werden.

Beispiel

DEF TPL_Thermostat(WID($1,$TPL{HKnob},"set"))

Nutzung der Template-Methode in der Tabellendefinition:

"Bad" | TPL_Thermostat([TH_Bad_HM:desired-temp])
"Küche" | TPL_Thermostat([TH_Kueche_HM:desired-temp])
"Wohnzimmer" | TPL_Thermostat([TH_Wohnzimmer_HM:desired-temp])


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

Damian

#2
Die neue DOIF-Version ist im ersten Post angehängt.


Hier meine Beispielkonfiguration (das Layout ist im Anhang zu sehen), bei den Devices handelt es sich um HM-Thermostate und HM-Switche.

Das DOIF hat hier keine Steuerungsaufgabe (1), es demonstriert am Beispiel die Nutzung des uiTable-Attributes. Üblicherweise können DOIF-Definitionen mit ihren Steuerungsaufgaben, wie sie bisher genutzt wurden, mit dem uiTable-Attribut um ein User-Interface für das Darstellen oder Schalten eigener oder fremder Readings bzw. Devices ergänzt werden, um auf die Steuerung des DOIF-Moduls Einfluss zu nehmen.

define ui_Heizung DOIF (1)

attr ui_Heizung uiTable
{
$TPL{HKnob}="knob,min:17,max:25,width:45,height:40,step:0.5,fgColor:DarkOrange,bgcolor:grey,anglearc:270,angleOffset:225,cursor:10,thickness:.3";
$TPL{onoff}="iconLabel,on,control_standby\@DarkOrange,off,control_standby";
#$TPL{swonoff} =  "iconSwitch,on,control_standby,off,control_standby\@DarkOrange";
$TPL{swonoff} =  "iconSwitch,on,fa_off,off,fa_off\@DarkOrange";
$TC{last}="align='center'";
$TC{0}= "style='font-weight:bold;font-size:12pt;'";

sub FUNC_temp
{
  my ($temp)=@_;
    return ("font-weight:bold;font-size:12pt;color:".DOIF_hsv ($temp,15,35,210,360,60,90));
}

sub FUNC_hum
{
    my ($hum)=@_;
    return ("font-weight:bold;font-size:12pt;color:".DOIF_hsv ($hum,50,75,40,264,60,90));
}
}

"Status"|
WID([Brenner:state],"iconLabel,closed,sani_boiler_temp\@DarkOrange,open,sani_boiler_temp") |
WID([Zirkulation:state],"iconSwitch,off,sani_pump\@DarkOrange,on,sani_pump") |
WID([Therme:state],"iconSwitch,off,sani_floor_heating_neutral\@DarkOrange,on,sani_floor_heating_neutral") |
WID([Therme_230V:state],"iconLabel,on,message_socket_on_off\@DarkOrange,off,message_socket_on_off")

"Bad" |
STY([TH_Bad_HM:humidity]." %",FUNC_hum([TH_Bad_HM:humidity])) |
STY([TH_Bad_HM:measured-temp]."°",FUNC_temp([TH_Bad_HM:measured-temp])) |
WID([H_Bad:state],$TPL{swonoff}) |
WID([TH_Bad_HM:desired-temp],$TPL{HKnob},"set"),STY([TH_Bad_HM:measured-temp]."°","font-weight:bold;font-size:9pt;color:".DOIF_hsv ([TH_Bad_HM:measured-temp],15,35,210,360,60,90))

"Kinderz. ost"|
STY([TH_Kz_o_HM:humidity]." %",FUNC_hum([TH_Kz_o_HM:humidity]))|
STY([TH_Kz_o_HM:measured-temp]."°",FUNC_temp([TH_Kz_o_HM:measured-temp])) |
WID([H_Kinderzimmer_o:state],$TPL{swonoff}) |
WID([TH_Kz_o_HM:desired-temp],$TPL{HKnob},"set")

"Kinderz. west"|
STY([TH_Kz_w_HM:humidity]." %",FUNC_hum([TH_Kz_w_HM:humidity])) |
STY([TH_Kz_w_HM:measured-temp]."°",FUNC_temp([TH_Kz_w_HM:measured-temp])) |
WID([H_Kinderzimmer_w:state],$TPL{swonoff}) |
WID([TH_Kz_w_HM:desired-temp],$TPL{HKnob},"set")

"Keller"|
STY([TH_Keller_HM:humidity]." %",FUNC_hum([TH_Keller_HM:humidity])) |
STY([TH_Keller_HM:measured-temp]."°",FUNC_temp([TH_Keller_HM:measured-temp])) |
WID([H_Keller:state],$TPL{swonoff}) |
WID([TH_Keller_HM:desired-temp],$TPL{HKnob},"set")
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

SamNitro

Sieht sehr cool aus, wohin kommt die doif.js?

LG Patrick
(Intel-Nuc Proxmox) (Homematic) (EnOcean) (CUL868) (CUL433) (Zigbee2MQTT) (ESP8266) (Echo) (DUOFERN)

Damian

Zitat von: SamNitro am 20 Oktober 2017, 16:41:31
Sieht sehr cool aus, wohin kommt die doif.js?

LG Patrick

steht im ersten Post, ins fhem/www/pgm2 Verzeichnis
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

#5
Weiteres Bespiel für Statusanzeige:


attr sicherheit uiTable
"Status"|
WID([Alarm_scharf], "iconLabel,closed,building_security\@DarkOrange,open,building_security") |
WID([Anwesenheit], "iconLabel,on,status_available\@DarkOrange,off,status_away_2") |
WID([Garage], "iconLabel,geöffnet,fts_garage_door_10\@DarkOrange,geschlossen,fts_garage_door_100") |
WID([Offene_Fenster], "iconLabel,keine,fts_window_1w,.*,fts_window_1w_open\@DarkOrange")|STY([Offene_Fenster], ([Offene_Fenster] eq "keine" ? "color:white" : "color:DarkOrange"))


[Offene_Fenster] ist Status eines DOIF´s mit [@s(<br>)"Fenster$":state:"open","keine"]
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

the ratman

genial ...
jetzt noch mit drag&drop (jo, is a scherz ... oder doch ned?), und meine klicki/bunti welt hat an neuen helden *lach*
wobei a bisserl bös bin ich dir aber schon: immerhin krieg ich jetzt viel arbeit wegen rg-->doif umbaus *bg*
→do↑p!dnʇs↓shit←

Damian

Zitat von: the ratman am 22 Oktober 2017, 15:16:59
genial ...
jetzt noch mit drag&drop (jo, is a scherz ... oder doch ned?), und meine klicki/bunti welt hat an neuen helden *lach*
wobei a bisserl bös bin ich dir aber schon: immerhin krieg ich jetzt viel arbeit wegen rg-->doif umbaus *bg*

Als nächstes ist Beleuchtung und Beschattung dran ;)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

Hier mal Beleuchtung-Scene, diesmal mit DOIF-Steuerung:

defmod DI_Licht DOIF (([06:25-08:00|8] or [15:00-23:00]) and [Helligkeit] eq "off")\
  (set Lampeflur on, set Lampekueche on)\
DOELSEIF (([06:25-08:30|8] and [Helligkeit] eq "on") or [08:30] or [23:30])\
  (set Lampekueche off, set Lampeflur off)\

attr DI_Licht cmdState on|off
attr DI_Licht devStateIcon on:status_night off:scene_day
attr DI_Licht group Aktuell
attr DI_Licht icon fa_light_bulb
attr DI_Licht initialize initialized
attr DI_Licht room Licht,Status
attr DI_Licht uiTable WID([Helligkeit],"iconLabel,off,status_night\@DarkOrange,on,light_wall_2") |\
WID([Aussenbeleuchtung],"iconSwitch,off,light_wall_2\@DarkOrange,on,light_wall_2") |\
WID([Wandleuchten_W],"iconSwitch,off,light_wall_3\@DarkOrange,on,light_wall_3") |\
WID([FS20_Couchlampe_W],"iconSwitch,off,hue_room_living\@DarkOrange,on,hue_room_living") |\
#WID([Stehlampe_KZ_W],"iconSwitch,off,fa_light_bulb\@DarkOrange,on,fa_light_bulb") |\
WID([Lampeflur],"iconSwitch,off,hue_room_hallway\@DarkOrange,on,hue_room_hallway") |\
WID([Lampekueche],"iconSwitch,off,hue_room_kitchen\@DarkOrange,on,hue_room_kitchen")


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

Damian

Aktueller Status-Bildschirm siehe Anhang, Rollladen kommt nach dem Urlaub ;)

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

SamNitro

Schade Rollladen wären auch schon interessant.


Gesendet von iPhone mit Tapatalk
(Intel-Nuc Proxmox) (Homematic) (EnOcean) (CUL868) (CUL433) (Zigbee2MQTT) (ESP8266) (Echo) (DUOFERN)

Damian

Zitat von: SamNitro am 22 Oktober 2017, 20:30:58
Schade Rollladen wären auch schon interessant.


Gesendet von iPhone mit Tapatalk

Na gut, weil du es bist, hab´mal schnell gehackt ;)

defmod DI_Rollladen DOIF (([Dunkelheit] eq "off" and [06:25-09:00|8]) or [09:00|7]) \
  ((set R_W_S,R_W_W[1-3] on))\
DOELSEIF ([Dunkelheit] eq "on")\
  ((set R_W_S,R_W_W[1-3] off))\
\

attr DI_Rollladen cmdState oben|unten
attr DI_Rollladen devStateIcon unten:status_night oben:scene_day
attr DI_Rollladen do always
attr DI_Rollladen group Aktuell
attr DI_Rollladen initialize init
attr DI_Rollladen room Beschattung,Status
attr DI_Rollladen uiTable {\
  $TPL{shutter}="iconSelectRadio,darkorange,on,fts_shutter_10,30,fts_shutter_30,50,fts_shutter_50,80,fts_shutter_80,off,fts_shutter_100";;\
}\
\
\
"Dachboden"|WID([R_Dachboden],$TPL{shutter})\
"Bad"|WID([R_Bad],$TPL{shutter})\
"KInderz. ost"|WID([R_Kinderzimmer1_O],$TPL{shutter})\
"Kinderz. west1"|WID([R_Kinderzimmer2_W1],$TPL{shutter})\
"Kinderz. west2"|WID([R_Kinderzimmer2_W2],$TPL{shutter})\
"Wohnz. süd"|WID([R_W_S],$TPL{shutter})\
"Wohnz. west1"|WID([R_W_W1],$TPL{shutter})\
"Wohnz. west2"|WID([R_W_W2],$TPL{shutter})\
"Wohnz. west3"|WID([R_W_W3],$TPL{shutter})

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

SamNitro

(Intel-Nuc Proxmox) (Homematic) (EnOcean) (CUL868) (CUL433) (Zigbee2MQTT) (ESP8266) (Echo) (DUOFERN)

the ratman

#13
sag mal ... nur so als dumme idee = ich träume mal vor mich hin:

idee: zellen zusammenlegen, oder besser noch ne tabelle in der zelle einer anderen tabelle. also z.b. mehrere tabellen erstellen, eine haupttabelle und dann weitere tabellen mit namen. namen in eine zelle der haupttabelle, fatitsch is das wunderwerk. vielleicht sogar mit tabellen aus anderen doif's. <-- was für möglichkeiten das gäbe ... ich stell mir grad vor, ich kann tabellen wie alles andere behandeln ... also z.b. in zelle x tabelle a bei ereignis a, tabelle b bei ereignis b. so gingen ganze situationsabhängige interfaces zu basteln. von anzeigen über navigation, und und und ...

oder auch die möglichkeit tabellenränder/zellenränder sichtbar zu machen. <-- das dann nur mehr als fingerübung, damit dir ned zu langweilig wird ;o)
→do↑p!dnʇs↓shit←

Damian

Zitat von: the ratman am 22 Oktober 2017, 22:34:36
sag mal ... nur so als dumme idee = ich träume mal vor mich hin:

idee: zellen zusammenlegen, oder besser noch ne tabelle in der zelle einer anderen tabelle. also z.b. mehrere tabellen erstellen, eine haupttabelle und dann weitere tabellen mit namen. namen in eine zelle der haupttabelle, fatitsch is das wunderwerk. vielleicht sogar mit tabellen aus anderen doif's. <-- was für möglichkeiten das gäbe ...

oder auch die möglichkeit tabellenränder/zellenränder sichtbar zu machen. <-- das dann nur mehr als fingerübung, damit dir ned zu langweilg wird ;o)

Vieles davon geht jetzt schon, wenn man sich mit html/css auskennt. Du kannst in uiTable an beliebiger Stelle HTML-Elemente einbauen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF