HM-Dis-WM55 Funk Statusanzeige: Unterschied zwischen den Versionen
Krikan (Diskussion | Beiträge) K (Kategorie Statusdisplay ergänzt / Gliederungsebenen angepasst) |
K (use POSIX; raus) |
||
(13 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 16: | Zeile 16: | ||
Die Funk-Statusanzeige hat 10 Kanäle (HM-Dis-WM55_Dis_01 bis HM-Dis-WM55_Dis_10). Jedem der Kanäle können 2 Texte zugewiesen werden. Kanal 1 und 2 kommt eine Doppelrolle zu. Sie enthalten sowohl Texte, sind aber auch die beiden Tasten. Und so wird auch die Ausgabe der Displayanzeige auf diese beiden Kanäle gegeben. | Die Funk-Statusanzeige hat 10 Kanäle (HM-Dis-WM55_Dis_01 bis HM-Dis-WM55_Dis_10). Jedem der Kanäle können 2 Texte zugewiesen werden. Kanal 1 und 2 kommt eine Doppelrolle zu. Sie enthalten sowohl Texte, sind aber auch die beiden Tasten. Und so wird auch die Ausgabe der Displayanzeige auf diese beiden Kanäle gegeben. | ||
Das Display hat 6 Zeilen zur Darstellung. | Das Display hat 6 Zeilen zur Darstellung von bis zu 12 Zeichen und einem Icon. | ||
Für die Texte in den Zeilen kann jeweils eine von 6 Anzeigefarben eingestellt werden. | |||
Die Zeilen können einzeln befüllt und getauscht werden, dies muss nicht in einem Rutsch passieren. | Die Zeilen können einzeln befüllt und getauscht werden, dies muss nicht in einem Rutsch passieren. | ||
== Probleme == | == Probleme == | ||
Es gibt hin und wieder Probleme die Register auszulesen. Abhilfe ist msgrepeat auf 3 zu | Es gibt hin und wieder Probleme die Register auszulesen. Abhilfe ist msgrepeat auf 3 zu setzen und hartnäckig bleiben. | ||
= Betrieb mit FHEM = | = Betrieb mit FHEM = | ||
Zeile 29: | Zeile 30: | ||
Die Kanäle 1 und 2 sollten mit FHEM gepeered (zusätzlich zum pairing) werden | Die Kanäle 1 und 2 sollten mit FHEM gepeered (zusätzlich zum pairing) werden | ||
set HM-Dis-WM55_Dis_01 peerBulk < | set HM-Dis-WM55_Dis_01 peerBulk <hmID>01 | ||
set HM-Dis-WM55_Dis_02 peerBulk < | set HM-Dis-WM55_Dis_02 peerBulk <hmID>01 | ||
Um einen Kanal mit Text zu befüllen dient der text Befehl auf einen Kanal. Es werden beide Texte in einen Kanal gleichzeitig geschrieben. Will ich einen Text tauschen muss ich den anderen mit neu setzten. Für ein Leerzeichen \_ einsetzten | Um einen Kanal mit Text zu befüllen dient der text Befehl auf einen Kanal. Es werden beide Texte in einen Kanal gleichzeitig geschrieben. Will ich einen Text tauschen muss ich den anderen mit neu setzten. Für ein Leerzeichen \_ einsetzten | ||
set HM-Dis-WM55_Dis_01 text Fenster\_auf Fenster\_zu | set HM-Dis-WM55_Dis_01 text Fenster\_auf Fenster\_zu | ||
Zum Übernehmen der Konfiguration den Config Taster auf der Rückseite nehmen und über das Menü übernehmen. | |||
Nun kann man z.B. mit einem notify die Information an den Schalter senden, wenn ein Fenster offen und oder zu ist: | Nun kann man z.B. mit einem notify die Information an den Schalter senden, wenn ein Fenster offen und oder zu ist: | ||
Zeile 46: | Zeile 47: | ||
kann eine Übersicht der gesetzten Texte angezeigt werden. Sowie der möglichen Farben und Icons. | kann eine Übersicht der gesetzten Texte angezeigt werden. Sowie der möglichen Farben und Icons. | ||
Folgende Farben | Folgende Farben gibt es: | ||
color is one white, red, orange, yellow, green, blue | color is one white, red, orange, yellow, green, blue | ||
Soll kein Text eingeblendet werden oder dieser nicht geändert werden kann man einfach nc schreiben Beispiel | Folgende Icons gibt es: | ||
{| class="wikitable" | |||
|- | |||
| closed || Schloss geschlossen | |||
|- | |||
| error || Kreuz rot | |||
|- | |||
| ic12 || Leersymbol | |||
|- | |||
| ic13 || Leersymbol | |||
|- | |||
| info ||"i" in blauem Kreis | |||
|- | |||
| newMsg || Briefkasten mit Flag | |||
|- | |||
| noIcon || nichts | |||
|- | |||
| off || Glühbirne aus | |||
|- | |||
| ok || Haken grün | |||
|- | |||
| on || Glühbirne an | |||
|- | |||
| open || Schloss geöffnet | |||
|- | |||
| serviceMsg || Mann mit Schraubenschlüssel | |||
|- | |||
| sigGreen || Leuchte grün | |||
|- | |||
| sigRed || Leuchte rot | |||
|- | |||
| sigYellow || Leuchte gelb | |||
|} | |||
Soll kein Text eingeblendet werden oder dieser nicht geändert werden, kann man einfach nc schreiben Beispiel | |||
set HM-Dis-WM55_Dis_01 displayWM short line2 nc nc error | set HM-Dis-WM55_Dis_01 displayWM short line2 nc nc error | ||
Dann wird nur das Icon getauscht oder eben nur jenes angezeigt. | Dann wird nur das Icon getauscht oder eben nur jenes angezeigt. | ||
== dynamische Ausgaben == | |||
Um das Display wirkungsvoll einzusetzen ist es angebracht, Texte dynamisch - abhängig von irgendwelchen Readings und Auswertungen- zu erzeugen. Dies ist möglich, bedarf bei strukturierten Einbau einiges an Installation - ist aber am Ende einfacher als es anfänglich scheint. Möglichkeiten, es zu realisieren gibt es einige - hier ein Beispiel über [[99_myUtils_anlegen|myUtils]]. | |||
=== fhemUser.cfg === | |||
Da im fhem.cfg kein set Kommando vorkommen soll/kann, sollte man ein separates File einbinden welches definiert nach Systeminitialisierung ausgeführt wird. Hierzu erzeugt man ein File fhem_user.cfg. Im normalen fhem.cfg baut man eine Zeile ein um es auszuführen: | |||
define userCfg notify global:INITIALIZED include fhem_user.cfg | |||
Wenn das File fhem_user.cfg mit der Oberfläche angelegt wurde (Edit file, Save as), liegt es im Unterverzeichnis ./FHEM und wird so eingebunden: | |||
define userCfg notify global:INITIALIZED include ./FHEM/fhem_user.cfg | |||
Im fhem_user.cfg stellt man nun für die beiden Buttons des display folgende Zeilen ein | |||
set dis_01 displayWM short line1 e:{myLineA(1,0)} | |||
set dis_01 displayWM short line2 e:{myLineA(2,0)} | |||
set dis_01 displayWM short line3 e:{myLineA(3,0)} | |||
set dis_01 displayWM short line4 e:{myLineA(4,0)} | |||
set dis_01 displayWM short line5 e:{myLineA(5,0)} | |||
set dis_01 displayWM short line6 e:{myLineA(6,0)} | |||
set dis_01 displayWM long line1 e:{myLineA(1,1)} | |||
set dis_01 displayWM long line2 e:{myLineA(2,1)} | |||
set dis_01 displayWM long line3 e:{myLineA(3,1)} | |||
set dis_01 displayWM long line4 e:{myLineA(4,1)} | |||
set dis_01 displayWM long line5 e:{myLineA(5,1)} | |||
set dis_01 displayWM long line6 e:{myLineA(6,1)} | |||
set dis_02 displayWM short line1 e:{myLineA(1,2)} | |||
set dis_02 displayWM short line2 e:{myLineA(2,2)} | |||
set dis_02 displayWM short line3 e:{myLineA(3,2)} | |||
set dis_02 displayWM short line4 e:{myLineA(4,2)} | |||
set dis_02 displayWM short line5 e:{myLineA(5,2)} | |||
set dis_02 displayWM short line6 e:{myLineA(6,2)} | |||
set dis_02 displayWM long line1 e:{myLineA(1,3)} | |||
set dis_02 displayWM long line2 e:{myLineA(2,3)} | |||
set dis_02 displayWM long line3 e:{myLineA(3,3)} | |||
set dis_02 displayWM long line4 e:{myLineA(4,3)} | |||
set dis_02 displayWM long line5 e:{myLineA(5,3)} | |||
set dis_02 displayWM long line6 e:{myLineA(6,3)} | |||
Nun wird beim Tastendruck die Funktion myLineA gesucht - diese werden wir in 99_myUtils definieren. | |||
=== 99_myUtils === | |||
Hat man evtl. schon - dann kann man es erweitern. Um es auszuführen muss es aufgerufen werden. Daher wird eine Entity in fhem.cfg definiert | |||
define mu myUtils | |||
nun das File 99_myUtils.pm. Die Instruktionen sind in den Kommentaren. Da es flexibel ist, ist es auch keine strikte Anleitung. | |||
<syntaxhighlight lang="perl"> | |||
############################################## | |||
# | |||
package main; | |||
use strict; | |||
use warnings; | |||
sub myLineA ($$); | |||
# define counter and counterlimit per press-type | |||
# presstype are 0: btn1 short | |||
# presstype are 1: btn1 long | |||
# presstype are 2: btn2 short | |||
# presstype are 3: btn2 long | |||
my @cnt ; #init one counter per press | |||
my @cntMax; #number of entries per press | |||
# structure per button/itteration/press | |||
# insert the function to be executes to fill the line with test, color and icon | |||
# Number of itterations can be extended as desired. At least one should be present. | |||
# obey the end of the line (is open) and the number of parameters you send to the funktion | |||
my %lineArr = (0 =>{#============Btn Type 0: Btn1 short | |||
0 =>{#-------itteration 0 | |||
1=>'{myTh("wz:","h_s_s2",' # line 1 | |||
,2=>'{myTh("os:","h_s_s1",' | |||
,3=>'{myTh("op:","h_s_aussen",' | |||
,4=>'{myPr("p:" ,"h_s_aussen",' | |||
,5=>'{myTx("","","",' | |||
,6=>'{myTx("","","",' | |||
} | |||
,1 =>{#-------itteration 1 | |||
1=>'{myTh("wz:","h_s_s2",' # line 1 | |||
,2=>'{myTh("os:","h_s_s1",' | |||
,3=>'{myTh("op:","h_s_aussen",' | |||
,4=>'{myPr("p:" ,"h_s_aussen",' | |||
,5=>'{myTx("","","",' | |||
,6=>'{myTx("","","",' | |||
} | |||
} | |||
,1 =>{#============Btn Type 0: Btn1 Long | |||
0 =>{#-------itteration 0 | |||
1=>'{myTx("Info","green" ,"info" ,' # line 1 | |||
,2=>'{myHm("act:","I_actTotal" ,"green",' | |||
,3=>'{myHm("bat:","I_sum_battery","green",' | |||
,4=>'{myHm("fl:" ,"I_fail" ,"green",' | |||
,5=>'{myTx("" ,"" ,"" ,' | |||
,6=>'{myTx("" ,"" ,"" ,' | |||
} | |||
,1 =>{#-------itteration 0 | |||
1=>'{myTx( "Error" ,"red","error",' # line 1 | |||
,2=>'{myHm("prt:" ,"ERR__protocol","red" ,' | |||
,3=>'{myHm("bat:" ,"ERR_battery" ,"yellow",' | |||
,4=>'{myHm("prt:" ,"W__protocol" ,"yellow",' | |||
,5=>'{myTx("" ,"" ,"",' | |||
,6=>'{myTx("" ,"" ,"",' | |||
} | |||
} | |||
,2 =>{#============Btn Type 2: Btn2 short | |||
0 =>{#-------itteration 0 | |||
1=>'{myRT("ca:","h.caro.Clima",'# line 1 | |||
,2=>'{myRT("lg:","h.lnge.Clima",' | |||
,3=>'{myRT("fh:","h.fsth.Clima",' | |||
,4=>'{myRT("du:","h.dact.Clima",' | |||
,5=>'{myRT("bs:","h.bad.Clima",' | |||
,6=>'{myTx("" ,"" ,"",' | |||
} | |||
} | |||
,3 =>{#============Btn Type 3: Btn2 Long | |||
0 =>{#-------itteration 0 | |||
1=>'{myLi("Fl:","LichtF" ,' | |||
,2=>'{myLi("Fh:","LichtFH" ,' | |||
,3=>'{myLi("L1:","LichtL" ,' | |||
,4=>'{myLi("Sl:","sw_Sw" ,' | |||
,5=>'{myLi("L2:","LichtL_Sw1_V_01",' | |||
,6=>'{myLi("L3:","LichtL_Sw1_V_02",' | |||
} | |||
,1 =>{#-------itteration 1 | |||
1=>'{myTx("off" ,"","off" ,' | |||
,2=>'{myTx("on" ,"","on" ,' | |||
,3=>'{myTx("open" ,"","open" ,' | |||
,4=>'{myTx("closed","","closed",' | |||
,5=>'{myTx("error" ,"","error" ,' | |||
,6=>'{myTx("ok" ,"","ok" ,' | |||
} | |||
,2 =>{#-------itteration 2 | |||
1=>'{myTx("info" ,"white" ,"info" ,' | |||
,2=>'{myTx("newMsg" ,"red" ,"newMsg" ,' | |||
,3=>'{myTx("serviceMsg","orange","serviceMsg",' | |||
,4=>'{myTx("sigGreen" ,"yellow","sigGreen" ,' | |||
,5=>'{myTx("sigYellow" ,"green" ,"sigYellow" ,' | |||
,6=>'{myTx("sigRed" ,"blue" ,"sigRed" ,' | |||
} | |||
} | |||
); | |||
sub myUtils_Initialize($$) { | |||
my ($hash) = @_; | |||
# Normal devices | |||
$hash->{DefFn} = "myUtil_Define"; | |||
$hash->{UndefFn} = "myUtil_Undef"; | |||
$hash->{AttrList}= $readingFnAttributes; | |||
@cntMax = (scalar keys %{$lineArr{0}} | |||
,scalar keys %{$lineArr{1}} | |||
,scalar keys %{$lineArr{2}} | |||
,scalar keys %{$lineArr{3}}); | |||
push @cnt,"0" foreach (keys %lineArr); | |||
} | |||
sub myUtil_Define($$) {######################################################## | |||
my ($hash, $def) = @_; | |||
return ; | |||
} | |||
sub myUtil_Undef($$) {######################################################### | |||
my ($hash, $arg) = @_; | |||
return undef; | |||
} | |||
sub myLineA($$){# main entry - do not change!!! | |||
my ($line,$type) = @_; | |||
$cnt[$type] = ($cnt[$type] +1)%$cntMax[$type] if ($line == 1); # rotate counter per type | |||
return (eval $lineArr{$type}{$cnt[$type]}{$line}.'"t")}' | |||
,eval $lineArr{$type}{$cnt[$type]}{$line}.'"c")}' | |||
,eval $lineArr{$type}{$cnt[$type]}{$line}.'"i")}' | |||
); | |||
} | |||
sub myRT($$$){ # function to return information of an RT. | |||
# line 't' calculates the text | |||
# line 'c' calculates the color | |||
# line 'i' calculates the icon | |||
my ($p,$e,$t) = @_; | |||
if($t eq "t"){return $p.ReadingsVal($e,"desired-temp","no")."-".ReadingsVal($e,"measured-temp","no"); } | |||
if($t eq "c"){return ReadingsVal($e,"measured-temp",0)>20 ? "red" : "blue" } | |||
if($t eq "i"){return ReadingsVal($e,"ValvePosition",0) ? "on" : "off" } | |||
return "nix"; | |||
} | |||
sub myTh($$$){#temp sensor | |||
my ($p,$e,$t) = @_; | |||
if($t eq "t"){return $p.ReadingsVal($e,"temperature","no")."-".ReadingsVal($e,"humidity",""); } | |||
if($t eq "c"){return ReadingsVal($e,"temperature",0)>20 ? "red" : "blue" } | |||
if($t eq "i"){return ReadingsVal($e,"battery",0) ? "ok" : "no" } | |||
return "nix"; | |||
} | |||
sub myPr($$$){#Sensor Pressure | |||
my ($p,$e,$t) = @_; | |||
if($t eq "t"){return $p.ReadingsVal($e,"pressure","no")."-".ReadingsVal($e,"luminosity","-"); } | |||
if($t eq "c"){return ReadingsVal($e,"luminosity",0)>1000 ? "green" : "red" } | |||
if($t eq "i"){return ReadingsVal($e,"battery",0) ? "ok" : "error" } | |||
return "nix"; | |||
} | |||
sub myLi($$$){#Light | |||
my ($p,$e,$t) = @_; | |||
if($t eq "t"){return $p.ReadingsVal($e,"state","xx"); } | |||
if($t eq "c"){return ReadingsVal($e,"timedOn",0) eq "off" ? "green" : "red" } | |||
if($t eq "i"){return ReadingsVal($e,"phyLevel",ReadingsVal($e,"level","1")) ? "on" : "off" } | |||
return "nix"; | |||
} | |||
sub myTx($$$$){#text only | |||
my ($p,$c,$icon,$t) = @_; | |||
if($t eq "t"){return $p; } | |||
if($t eq "c"){return ($c?$c:"white");} | |||
if($t eq "i"){return ($icon?$icon:"noIcon");} | |||
return $p; | |||
} | |||
sub myHm($$$$){#HMInfo readings | |||
my ($p,$e,$c,$t) = @_; | |||
if($t eq "t"){return $p.join(",", grep !/:0/ | |||
, map{s/^(.).*?:/$1:/;;$_;;} | |||
split "," | |||
, ReadingsVal("hm",$e,"-")) | |||
} | |||
if($t eq "c"){return ($c?$c:"white");} | |||
if($t eq "i"){return "noIcon";} | |||
return $p; | |||
} | |||
1; | |||
</syntaxhighlight> | |||
Die Definition, was angezeigt werden soll, wird nun in der Struktur %lineArr festgelegt. | |||
Die Typen der Ausgaben - z.B. Darstellung eines Werts eines RT - wird in der jeweiligen Funktion "myTh" festgelegt. Hier kann man so viele - nach den gleichen Regeln wie die Erste - definieren und in der Struktur nutzen. | |||
In der Struktur werden die Namen der auszuwertenden Entities eingetragen. | |||
Mit den Einträgen zur Itteration kann man erreichen dass beim Tastendruck der Text alterniert. Beim ersten Druck eine Seite, beim 2. eine weitere, nach der Letzten wieder die Erste. | |||
== Links == | == Links == |
Aktuelle Version vom 7. Februar 2022, 12:34 Uhr
HM-Dis-WM55
HomeMatic Funk-Statusanzeige WM55
Features
Technische Daten:
- Farbiges OLED-Display mit 128 x 128 RGB-Bildpunkten
- Frei programmierbar über HomeMatic-WebUI
- Dynamische Zuweisung von Anzeigeplätzen, Texten, Zustand von Systemvariablen, Symbolen
- In den Anzeigerahmen integrierte Taster für Anmeldung, Seitenfortschaltung und Auslösen von Zentralenprogrammen, z. B. Abfrage von Fensterzuständen bei Verlassen des Hauses
- Nur 19 mm flach, Schraub- oder Klebmontage, ortsunabhängiger Batteriebetrieb
- Lieferung mit weißem Rahmen, alternativ integrierbar in 55-mm-Installationsrahmen zahlreicher Installationsserien (Berker, ELSO, GIRA, merten, JUNG)
Allgemeines
Die Funk-Statusanzeige hat 10 Kanäle (HM-Dis-WM55_Dis_01 bis HM-Dis-WM55_Dis_10). Jedem der Kanäle können 2 Texte zugewiesen werden. Kanal 1 und 2 kommt eine Doppelrolle zu. Sie enthalten sowohl Texte, sind aber auch die beiden Tasten. Und so wird auch die Ausgabe der Displayanzeige auf diese beiden Kanäle gegeben.
Das Display hat 6 Zeilen zur Darstellung von bis zu 12 Zeichen und einem Icon. Für die Texte in den Zeilen kann jeweils eine von 6 Anzeigefarben eingestellt werden.
Die Zeilen können einzeln befüllt und getauscht werden, dies muss nicht in einem Rutsch passieren.
Probleme
Es gibt hin und wieder Probleme die Register auszulesen. Abhilfe ist msgrepeat auf 3 zu setzen und hartnäckig bleiben.
Betrieb mit FHEM
Das Gerät wird zur Zeit experimentell unterstützt. msgrepeat sollte auf 3 gestellt werden, sonst gibt es öfters Timeouts:
attr HM-Dis-WM55 msgRepeat 3
Die Kanäle 1 und 2 sollten mit FHEM gepeered (zusätzlich zum pairing) werden
set HM-Dis-WM55_Dis_01 peerBulk <hmID>01 set HM-Dis-WM55_Dis_02 peerBulk <hmID>01
Um einen Kanal mit Text zu befüllen dient der text Befehl auf einen Kanal. Es werden beide Texte in einen Kanal gleichzeitig geschrieben. Will ich einen Text tauschen muss ich den anderen mit neu setzten. Für ein Leerzeichen \_ einsetzten
set HM-Dis-WM55_Dis_01 text Fenster\_auf Fenster\_zu
Zum Übernehmen der Konfiguration den Config Taster auf der Rückseite nehmen und über das Menü übernehmen.
Nun kann man z.B. mit einem notify die Information an den Schalter senden, wenn ein Fenster offen und oder zu ist:
set HM-Dis-WM55_Dis_01 displayWM short line2 txt01_1 red error
short bedeutet bei einem kurzen Tastendruck (es geht auch long). line bezieht sich auf die Zeile in die es geschrieben wird. Anschließend folgt der Text, die Farbe in der der Text angezeigt werden soll, sowie das Icon.
Mit
set HM-Dis-WM55_Dis_01 displayWM help
kann eine Übersicht der gesetzten Texte angezeigt werden. Sowie der möglichen Farben und Icons.
Folgende Farben gibt es:
color is one white, red, orange, yellow, green, blue
Folgende Icons gibt es:
closed | Schloss geschlossen |
error | Kreuz rot |
ic12 | Leersymbol |
ic13 | Leersymbol |
info | "i" in blauem Kreis |
newMsg | Briefkasten mit Flag |
noIcon | nichts |
off | Glühbirne aus |
ok | Haken grün |
on | Glühbirne an |
open | Schloss geöffnet |
serviceMsg | Mann mit Schraubenschlüssel |
sigGreen | Leuchte grün |
sigRed | Leuchte rot |
sigYellow | Leuchte gelb |
Soll kein Text eingeblendet werden oder dieser nicht geändert werden, kann man einfach nc schreiben Beispiel
set HM-Dis-WM55_Dis_01 displayWM short line2 nc nc error
Dann wird nur das Icon getauscht oder eben nur jenes angezeigt.
dynamische Ausgaben
Um das Display wirkungsvoll einzusetzen ist es angebracht, Texte dynamisch - abhängig von irgendwelchen Readings und Auswertungen- zu erzeugen. Dies ist möglich, bedarf bei strukturierten Einbau einiges an Installation - ist aber am Ende einfacher als es anfänglich scheint. Möglichkeiten, es zu realisieren gibt es einige - hier ein Beispiel über myUtils.
fhemUser.cfg
Da im fhem.cfg kein set Kommando vorkommen soll/kann, sollte man ein separates File einbinden welches definiert nach Systeminitialisierung ausgeführt wird. Hierzu erzeugt man ein File fhem_user.cfg. Im normalen fhem.cfg baut man eine Zeile ein um es auszuführen:
define userCfg notify global:INITIALIZED include fhem_user.cfg
Wenn das File fhem_user.cfg mit der Oberfläche angelegt wurde (Edit file, Save as), liegt es im Unterverzeichnis ./FHEM und wird so eingebunden:
define userCfg notify global:INITIALIZED include ./FHEM/fhem_user.cfg
Im fhem_user.cfg stellt man nun für die beiden Buttons des display folgende Zeilen ein
set dis_01 displayWM short line1 e:{myLineA(1,0)} set dis_01 displayWM short line2 e:{myLineA(2,0)} set dis_01 displayWM short line3 e:{myLineA(3,0)} set dis_01 displayWM short line4 e:{myLineA(4,0)} set dis_01 displayWM short line5 e:{myLineA(5,0)} set dis_01 displayWM short line6 e:{myLineA(6,0)} set dis_01 displayWM long line1 e:{myLineA(1,1)} set dis_01 displayWM long line2 e:{myLineA(2,1)} set dis_01 displayWM long line3 e:{myLineA(3,1)} set dis_01 displayWM long line4 e:{myLineA(4,1)} set dis_01 displayWM long line5 e:{myLineA(5,1)} set dis_01 displayWM long line6 e:{myLineA(6,1)} set dis_02 displayWM short line1 e:{myLineA(1,2)} set dis_02 displayWM short line2 e:{myLineA(2,2)} set dis_02 displayWM short line3 e:{myLineA(3,2)} set dis_02 displayWM short line4 e:{myLineA(4,2)} set dis_02 displayWM short line5 e:{myLineA(5,2)} set dis_02 displayWM short line6 e:{myLineA(6,2)} set dis_02 displayWM long line1 e:{myLineA(1,3)} set dis_02 displayWM long line2 e:{myLineA(2,3)} set dis_02 displayWM long line3 e:{myLineA(3,3)} set dis_02 displayWM long line4 e:{myLineA(4,3)} set dis_02 displayWM long line5 e:{myLineA(5,3)} set dis_02 displayWM long line6 e:{myLineA(6,3)}
Nun wird beim Tastendruck die Funktion myLineA gesucht - diese werden wir in 99_myUtils definieren.
99_myUtils
Hat man evtl. schon - dann kann man es erweitern. Um es auszuführen muss es aufgerufen werden. Daher wird eine Entity in fhem.cfg definiert
define mu myUtils
nun das File 99_myUtils.pm. Die Instruktionen sind in den Kommentaren. Da es flexibel ist, ist es auch keine strikte Anleitung.
##############################################
#
package main;
use strict;
use warnings;
sub myLineA ($$);
# define counter and counterlimit per press-type
# presstype are 0: btn1 short
# presstype are 1: btn1 long
# presstype are 2: btn2 short
# presstype are 3: btn2 long
my @cnt ; #init one counter per press
my @cntMax; #number of entries per press
# structure per button/itteration/press
# insert the function to be executes to fill the line with test, color and icon
# Number of itterations can be extended as desired. At least one should be present.
# obey the end of the line (is open) and the number of parameters you send to the funktion
my %lineArr = (0 =>{#============Btn Type 0: Btn1 short
0 =>{#-------itteration 0
1=>'{myTh("wz:","h_s_s2",' # line 1
,2=>'{myTh("os:","h_s_s1",'
,3=>'{myTh("op:","h_s_aussen",'
,4=>'{myPr("p:" ,"h_s_aussen",'
,5=>'{myTx("","","",'
,6=>'{myTx("","","",'
}
,1 =>{#-------itteration 1
1=>'{myTh("wz:","h_s_s2",' # line 1
,2=>'{myTh("os:","h_s_s1",'
,3=>'{myTh("op:","h_s_aussen",'
,4=>'{myPr("p:" ,"h_s_aussen",'
,5=>'{myTx("","","",'
,6=>'{myTx("","","",'
}
}
,1 =>{#============Btn Type 0: Btn1 Long
0 =>{#-------itteration 0
1=>'{myTx("Info","green" ,"info" ,' # line 1
,2=>'{myHm("act:","I_actTotal" ,"green",'
,3=>'{myHm("bat:","I_sum_battery","green",'
,4=>'{myHm("fl:" ,"I_fail" ,"green",'
,5=>'{myTx("" ,"" ,"" ,'
,6=>'{myTx("" ,"" ,"" ,'
}
,1 =>{#-------itteration 0
1=>'{myTx( "Error" ,"red","error",' # line 1
,2=>'{myHm("prt:" ,"ERR__protocol","red" ,'
,3=>'{myHm("bat:" ,"ERR_battery" ,"yellow",'
,4=>'{myHm("prt:" ,"W__protocol" ,"yellow",'
,5=>'{myTx("" ,"" ,"",'
,6=>'{myTx("" ,"" ,"",'
}
}
,2 =>{#============Btn Type 2: Btn2 short
0 =>{#-------itteration 0
1=>'{myRT("ca:","h.caro.Clima",'# line 1
,2=>'{myRT("lg:","h.lnge.Clima",'
,3=>'{myRT("fh:","h.fsth.Clima",'
,4=>'{myRT("du:","h.dact.Clima",'
,5=>'{myRT("bs:","h.bad.Clima",'
,6=>'{myTx("" ,"" ,"",'
}
}
,3 =>{#============Btn Type 3: Btn2 Long
0 =>{#-------itteration 0
1=>'{myLi("Fl:","LichtF" ,'
,2=>'{myLi("Fh:","LichtFH" ,'
,3=>'{myLi("L1:","LichtL" ,'
,4=>'{myLi("Sl:","sw_Sw" ,'
,5=>'{myLi("L2:","LichtL_Sw1_V_01",'
,6=>'{myLi("L3:","LichtL_Sw1_V_02",'
}
,1 =>{#-------itteration 1
1=>'{myTx("off" ,"","off" ,'
,2=>'{myTx("on" ,"","on" ,'
,3=>'{myTx("open" ,"","open" ,'
,4=>'{myTx("closed","","closed",'
,5=>'{myTx("error" ,"","error" ,'
,6=>'{myTx("ok" ,"","ok" ,'
}
,2 =>{#-------itteration 2
1=>'{myTx("info" ,"white" ,"info" ,'
,2=>'{myTx("newMsg" ,"red" ,"newMsg" ,'
,3=>'{myTx("serviceMsg","orange","serviceMsg",'
,4=>'{myTx("sigGreen" ,"yellow","sigGreen" ,'
,5=>'{myTx("sigYellow" ,"green" ,"sigYellow" ,'
,6=>'{myTx("sigRed" ,"blue" ,"sigRed" ,'
}
}
);
sub myUtils_Initialize($$) {
my ($hash) = @_;
# Normal devices
$hash->{DefFn} = "myUtil_Define";
$hash->{UndefFn} = "myUtil_Undef";
$hash->{AttrList}= $readingFnAttributes;
@cntMax = (scalar keys %{$lineArr{0}}
,scalar keys %{$lineArr{1}}
,scalar keys %{$lineArr{2}}
,scalar keys %{$lineArr{3}});
push @cnt,"0" foreach (keys %lineArr);
}
sub myUtil_Define($$) {########################################################
my ($hash, $def) = @_;
return ;
}
sub myUtil_Undef($$) {#########################################################
my ($hash, $arg) = @_;
return undef;
}
sub myLineA($$){# main entry - do not change!!!
my ($line,$type) = @_;
$cnt[$type] = ($cnt[$type] +1)%$cntMax[$type] if ($line == 1); # rotate counter per type
return (eval $lineArr{$type}{$cnt[$type]}{$line}.'"t")}'
,eval $lineArr{$type}{$cnt[$type]}{$line}.'"c")}'
,eval $lineArr{$type}{$cnt[$type]}{$line}.'"i")}'
);
}
sub myRT($$$){ # function to return information of an RT.
# line 't' calculates the text
# line 'c' calculates the color
# line 'i' calculates the icon
my ($p,$e,$t) = @_;
if($t eq "t"){return $p.ReadingsVal($e,"desired-temp","no")."-".ReadingsVal($e,"measured-temp","no"); }
if($t eq "c"){return ReadingsVal($e,"measured-temp",0)>20 ? "red" : "blue" }
if($t eq "i"){return ReadingsVal($e,"ValvePosition",0) ? "on" : "off" }
return "nix";
}
sub myTh($$$){#temp sensor
my ($p,$e,$t) = @_;
if($t eq "t"){return $p.ReadingsVal($e,"temperature","no")."-".ReadingsVal($e,"humidity",""); }
if($t eq "c"){return ReadingsVal($e,"temperature",0)>20 ? "red" : "blue" }
if($t eq "i"){return ReadingsVal($e,"battery",0) ? "ok" : "no" }
return "nix";
}
sub myPr($$$){#Sensor Pressure
my ($p,$e,$t) = @_;
if($t eq "t"){return $p.ReadingsVal($e,"pressure","no")."-".ReadingsVal($e,"luminosity","-"); }
if($t eq "c"){return ReadingsVal($e,"luminosity",0)>1000 ? "green" : "red" }
if($t eq "i"){return ReadingsVal($e,"battery",0) ? "ok" : "error" }
return "nix";
}
sub myLi($$$){#Light
my ($p,$e,$t) = @_;
if($t eq "t"){return $p.ReadingsVal($e,"state","xx"); }
if($t eq "c"){return ReadingsVal($e,"timedOn",0) eq "off" ? "green" : "red" }
if($t eq "i"){return ReadingsVal($e,"phyLevel",ReadingsVal($e,"level","1")) ? "on" : "off" }
return "nix";
}
sub myTx($$$$){#text only
my ($p,$c,$icon,$t) = @_;
if($t eq "t"){return $p; }
if($t eq "c"){return ($c?$c:"white");}
if($t eq "i"){return ($icon?$icon:"noIcon");}
return $p;
}
sub myHm($$$$){#HMInfo readings
my ($p,$e,$c,$t) = @_;
if($t eq "t"){return $p.join(",", grep !/:0/
, map{s/^(.).*?:/$1:/;;$_;;}
split ","
, ReadingsVal("hm",$e,"-"))
}
if($t eq "c"){return ($c?$c:"white");}
if($t eq "i"){return "noIcon";}
return $p;
}
1;
Die Definition, was angezeigt werden soll, wird nun in der Struktur %lineArr festgelegt. Die Typen der Ausgaben - z.B. Darstellung eines Werts eines RT - wird in der jeweiligen Funktion "myTh" festgelegt. Hier kann man so viele - nach den gleichen Regeln wie die Erste - definieren und in der Struktur nutzen. In der Struktur werden die Namen der auszuwertenden Entities eingetragen. Mit den Einträgen zur Itteration kann man erreichen dass beim Tastendruck der Text alterniert. Beim ersten Druck eine Seite, beim 2. eine weitere, nach der Letzten wieder die Erste.