http://wiki.fhem.de/w/api.php?action=feedcontributions&user=Andies&feedformat=atomFHEMWiki - Benutzerbeiträge [de]2024-03-28T21:36:55ZBenutzerbeiträgeMediaWiki 1.39.3http://wiki.fhem.de/w/index.php?title=SVG&diff=39184SVG2024-03-17T16:54:21Z<p>Andies: </p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Erstellung von Diagrammen aus Logdaten<br />
|ModType=h<br />
|ModForumArea=Frontends<br />
|ModTechName=98_SVG.pm <br />
|ModOwner=rudolfkoenig ({{Link2FU|8|Forum}} / [[Benutzer Diskussion:Rudolfkoenig|Wiki]])}}<br />
<br />
Das Modul [[SVG]] generiert Diagramme aus [[FileLog|Logdateien]] oder [[DbLog|-datenbanken]]. Alternativen sind [[Grafana]] sowie [https://forum.fhem.de/index.php?topic=137009.0 eCharts]; beide Möglichkeiten basieren jedoch auf JavaScript.<br />
<br />
Die Eigenschaften des zu erstellenden Diagrams werden in einer .gplot-Datei festgelegt.<br />
<br />
== Definition ==<br />
Die Definition <syntaxhighlight lang="perl"><br />
define <name> SVG <logDevice>:<gplotfile>:<logfile><br />
</syntaxhighlight>besteht lediglich in der Angabe einer Datenquelle, einer .gplot-File und der Angabe von entweder ''CURRENT'' (für LogFile-Quellen) bzw. ''HISTORY'' (für Datenbanken).<br />
<br />
Details zur Definition sind in der {{Link2CmdRef|Anker=SVG-define}} dargestellt.<br />
<br />
== Hintergründe ==<br />
Ursprünglich wurde für das Rendern von Diagrammen in FHEM das Programmpaket ''[http://gnuplot.sourceforge.net/ gnuplot]'' verwendet. Daher entspricht die Syntax der ''.gplot''-Files in großen Teilen derjenigen von ''gnuplot'' (z.B. zu den Linientypen und -farben oder zur Gestaltung des Hintergrundes). Allerdings eben nur in großen Teilen, denn das Modul ''SVG'' implementiert eigenständige Rendering-Routinen, so dass die grundlegenden Formatierungsvorgaben dort, wo dies über spezielle Attribute gesteuert werden kann (z.B. zur Zahl der Achsen), auch über die Attribute vorgenommen werden sollte. Weiter sollte man nicht davon ausgehen, dass alle eventuell von gnuplot her bekannten Funktionen unterstützt werden.<br />
Weitere Hinweise hierzu und zum Aufbau der ''.gplot''-Files sind in [[Plots_erzeugen#Individuell / Manuell|Plots erzeugen]] zu finden.<br />
{{Hinweis|Der Artikel [[Plots_erzeugen|Plots erzeugen]] enthält auch eine Darstellung des gplot-Editors. Dieser kann ein gutes Hilfsmittel sein, um ein grundlegendes Verständnis der Funktionsweise zu erhalten. Man erhält damit allerdings ''.gplot''-Dateien, die sämtliche Angaben hart vercodet beinhalten. Falls Sie beabsichtigen, eine ''.gplot''-File zur Verwendung mit mehreren gleichartigen Geräten anzulegen, empfiehlt es sich, die Dateien direkt zu bearbeiten und die Verweise auf die darzustellenden Daten über Attribute zu steuern, wie nachfolgend dargestellt.}}<br />
== Attribute ==<br />
Das wichtigste spezifische Attribut ist ''plotReplace'', das einige andere, ältere Attribute ersetzen kann. Durch dieses können Angaben in den .gplot-Dateien dynamisch ersetzt werden, wodurch es auf einfache Weise möglich ist, dieselbe .gplot-Datei zur Erstellung von mehreren Plots zu nutzen, die dann auch in einem Plot unterschiedliche Datenquellen verwenden können. Dabei ist zu beachten, dass die in ''plotReplace'' angegebenen Parameter-Wert-Paare in zwei Stufen ersetzt werden: <br />
<br />
Wird in der .gplot-Datei die Schreibweise ''%key%'' verwendet, wird der Parameter bereits ersetzt, bevor die Datenquelle ausgewertet wurde, in der Schreibweise ''<key>'' erfolgt die Auswertung erst danach. Dies ermöglicht es z.B. auch, Informationen aus unterschiedlichen FileLog-Dateien zu visualisieren, ohne die betreffende Datenquelle hart in der .gplot-Datei zu verankern.<br />
<br />
Weiter ist es über diesen Mechanismus möglich, auch angepaßten Perl-Code zur Datenauswertung und -formatierung zu verwenden.<br />
<br />
Siehe dazu insbesondere auch die nachfolgenden beiden Beispiele "Leistungsdaten einer Steckdose (FileLog)" und "Temperatur- und Heizungsdaten eines Zimmers" (DBLog).<br />
<br />
Weitere Details in der {{Link2CmdRef|Anker=SVG-attr}}.<br />
<br />
== Funktionen ==<br />
Details in der {{Link2CmdRef|Anker=SVG-attr-plotfunction}}.<br />
<br />
== Beispiele ==<br />
<br />
=== Leistungsdaten einer Steckdose (FileLog) ===<br />
<br />
* Inhalt der Datei '''SVG_PlugX.gplot'''<br />
{{Randnotiz|RNTyp=g|RNText=Gegebenenfalls sind die Feldnamen anzupassen}}<br />
<syntaxhighlight lang="Gnuplot"><br />
# Leistungsdaten einer Steckdose (FileLog)<br />
#<br />
# plotReplace-Parameter: DataDevice (von diesem Gerät stammen die Daten)<br />
# FileLogDevice (in diesem Gerät werden die Daten geloggt)<br />
# stateOFFvalue (y-Wert zur Darstellung von ausgeschaltetem Zustand)<br />
# stateONvalue (y-Wert zur Darstellung von eingeschaltetem Zustand)<br />
# stateUNKNOWNvalue (y-Wert zur Darstellung von unbekanntem Zustand)<br />
# title (in der Regel ein perl-Ausdruck zur Darstellung von Eckwerten in der Titelzeile)<br />
# yrange (Wertebereich für Darstellung in W vorgeben)<br />
# y2range (Wertebereich für Darstellung in mA vorgeben)<br />
<br />
set terminal png transparent size <SIZE> crop<br />
set output '<OUT>.png'<br />
set xdata time<br />
set timefmt "%Y-%m-%d_%H:%M:%S"<br />
set xlabel " "<br />
set title '<title>'<br />
set ytics <br />
set y2tics <br />
set grid ytics y2tics<br />
set ylabel "Leistung (W)"<br />
set y2label "Strom (mA)"<br />
set yrange %yrange%<br />
set y2range %y2range%<br />
<br />
#%FileLogDevice% 4:%DataDevice%.power\x3a:0:<br />
#%FileLogDevice% 4:%DataDevice%.current\x3a:"":($fld[3]*1000)<br />
#%FileLogDevice% 4:%DataDevice%.userRead_socket_state\x3a:"":($fld[3]=~"off"?%stateOFFvalue%:($fld[3]=~"on"?%stateONvalue%:%stateUNKNOWNvalue%))<br />
<br />
plot "<IN>" using 1:2 axes x1y1 title 'Leistung' ls l0 lw 1 with steps,\<br />
"<IN>" using 1:2 axes x1y2 title 'Strom' ls l1fill_stripe lw 1 with steps,\<br />
"<IN>" using 1:2 axes x1y1 title 'Schaltzustand' ls l3 lw 1 with steps<br />
</syntaxhighlight><br />
<br />
* Definition von SVG-Device '''SVG_Test'''<br />
{{Randnotiz|RNTyp=g|RNText=Alle Vorkommen von ...Data-Device... und ...FileLog-Device... sind zu ersetzen}}<br />
<syntaxhighlight lang="perl"><br />
defmod SVG_Test SVG ...FileLog-Device...:SVG_PlugX:CURRENT<br />
attr SVG_Test captionPos auto<br />
attr SVG_Test plotReplace DataDevice="...Data-Device..." FileLogDevice="...FileLog-Device..." stateOFFvalue="20" stateONvalue="30" stateUNKNOWNvalue="10" yrange="[0:75]" y2range="[0:300]" title={"Steckdose(Testgerät) --- W: $data{min1}...$data{max1} / $data{currval1} --- mA: $data{min2}...$data{max2} / $data{currval2}"}<br />
</syntaxhighlight><br />
<br />
* So sieht das resultierende Diagramm aus<br />
[[Datei:SVG Leistungsdaten einer Steckdose.png|thumb|left|300px]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
=== Temperatur- und Heizungsdaten eines Zimmers === <br />
Quelle: {{Link2Forum|Topic=104935|Message=1011527}}<br />
(Datenquelle ist ein DBLog-Device namens LogDB):<br />
<br />
[[Datei:PlotReplace Example DBLog.png|thumb|right|300px]]<br />
<syntaxhighlight lang="Gnuplot"><br />
# Created by FHEM/98_SVG.pm, 2020-01-06<br />
# to replace variables, use plotReplace like<br />
# plotReplace-Parameter: SPEC1=Thermostat (von diesem Gerät stammen die Thermostat-Daten)<br />
# DBLogDevice (in diesem Gerät werden die Daten geloggt)<br />
# Die übrigen plotReplace-Parameter sind selbsterklärend, Beispiel:<br />
# attr SVG_Thermostat plotReplace DBLogDevice=DBLog SPEC1=Thermostat TL="My example thermostat" EXTERNALTEMPDEVICE=MYSENSOR_97 EXTERNALTEMPREADING=temperature2 \<br />
# ROOMHUMIDITYDEVICE=HUEDevice3 EXTERNALHUMIDITYREADING=humidity ROOMTEMPDEVICE=HUEDevice4 ROOMTEMPREADING=temperature WINDOW1=Window1_MyRoom WINDOW2=Window2_MyRoom<br />
<br />
set terminal png transparent size <SIZE> crop<br />
set output '<OUT>.png'<br />
set xdata time<br />
set timefmt "%Y-%m-%d_%H:%M:%S"<br />
set xlabel " "<br />
set title '<TL>'<br />
set ytics<br />
set y2tics<br />
set grid<br />
set ylabel "Valve/Window"<br />
set y2label "Temperature"<br />
set yrange [-5:105]<br />
set y2range [-15:35]<br />
set isosample 20<br />
<br />
#%DBLogDevice% %SPEC1%:desired-temp::<br />
#%DBLogDevice% %SPEC1%:measured-temp:0:<br />
#%DBLogDevice% %EXTERNALTEMPDEVICE%:%EXTERNALTEMPREADING%::<br />
#%DBLogDevice% %SPEC1%:actuator:0:int<br />
#%DBLogDevice% %ROOMHUMIDITYDEVICE%:%EXTERNALHUMIDITYREADING%:0:<br />
#%DBLogDevice% %ROOMTEMPDEVICE%:%ROOMTEMPREADING%:0:<br />
#%DBLogDevice% %WINDOW1%:state:::$val=~s/(open|closed|tilted)(\d*).*/$1eq"open"?60:$1eq"tilted"?45:0/eg<br />
#%DBLogDevice% %WINDOW2%:state:::$val=~s/(open|closed|tilted)(\d*).*/$1eq"open"?60:$1eq"tilted"?45:0/eg<br />
<br />
<br />
plot "<IN>" using 1:2 axes x1y2 title 'Desired' ls l0 lw 1 with lines,\<br />
"<IN>" using 2:2 axes x1y2 title 'Measured actuator' ls l7 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Aussen' ls l1 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y1 y2title 'Valve' ls l5 lw 1 with steps,\<br />
"<IN>" using 1:2 axes x1y1 title 'Humidity' ls l2 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Measured roomsensor' ls l3 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y1 y2title '%WINDOW1%' ls l4fill lw 0.5 with steps,\<br />
"<IN>" using 1:2 axes x1y1 y2title '%WINDOW2%' ls l5fill lw 0.5 with steps<br />
</syntaxhighlight><br />
== Hinweise ==<br />
* Plot-Abrisse vermeiden<br />
Sind in den Quelldaten nicht genügend Datenpunkte vorhanden, kann es zu Lücken in der Darstellung kommen. Abhilfe kann man mit [[LogProxy]] schaffen oder, indem man zusätzliche Datenpunkte in den Datenquellen generiert, z.B. durch das Setzen von ''addLog''-Attributen an FileLog bzw. DBLog-Geräten. Weitere Hinweise sind in [[Plot-Abriss vermeiden]] zu finden.<br />
<br />
== Links ==<br />
* [[Plots erzeugen]]<br />
* [[Creating Plots]]<br />
<br />
<references /><br />
[[Kategorie:Logging]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=SVG&diff=39183SVG2024-03-17T16:53:35Z<p>Andies: </p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Erstellung von Diagrammen aus Logdaten<br />
|ModType=h<br />
|ModForumArea=Frontends<br />
|ModTechName=98_SVG.pm <br />
|ModOwner=rudolfkoenig ({{Link2FU|8|Forum}} / [[Benutzer Diskussion:Rudolfkoenig|Wiki]])}}<br />
<br />
Das Modul [[SVG]] generiert Diagramme aus [[FileLog|Logdateien]] oder [[DbLog|-datenbanken]]. Alternativen sind [[Grafana]] sowie [[https://forum.fhem.de/index.php?topic=137009.0|eCharts]]; beide Möglichkeiten basieren jedoch auf JavaScript.<br />
<br />
Die Eigenschaften des zu erstellenden Diagrams werden in einer .gplot-Datei festgelegt.<br />
<br />
== Definition ==<br />
Die Definition <syntaxhighlight lang="perl"><br />
define <name> SVG <logDevice>:<gplotfile>:<logfile><br />
</syntaxhighlight>besteht lediglich in der Angabe einer Datenquelle, einer .gplot-File und der Angabe von entweder ''CURRENT'' (für LogFile-Quellen) bzw. ''HISTORY'' (für Datenbanken).<br />
<br />
Details zur Definition sind in der {{Link2CmdRef|Anker=SVG-define}} dargestellt.<br />
<br />
== Hintergründe ==<br />
Ursprünglich wurde für das Rendern von Diagrammen in FHEM das Programmpaket ''[http://gnuplot.sourceforge.net/ gnuplot]'' verwendet. Daher entspricht die Syntax der ''.gplot''-Files in großen Teilen derjenigen von ''gnuplot'' (z.B. zu den Linientypen und -farben oder zur Gestaltung des Hintergrundes). Allerdings eben nur in großen Teilen, denn das Modul ''SVG'' implementiert eigenständige Rendering-Routinen, so dass die grundlegenden Formatierungsvorgaben dort, wo dies über spezielle Attribute gesteuert werden kann (z.B. zur Zahl der Achsen), auch über die Attribute vorgenommen werden sollte. Weiter sollte man nicht davon ausgehen, dass alle eventuell von gnuplot her bekannten Funktionen unterstützt werden.<br />
Weitere Hinweise hierzu und zum Aufbau der ''.gplot''-Files sind in [[Plots_erzeugen#Individuell / Manuell|Plots erzeugen]] zu finden.<br />
{{Hinweis|Der Artikel [[Plots_erzeugen|Plots erzeugen]] enthält auch eine Darstellung des gplot-Editors. Dieser kann ein gutes Hilfsmittel sein, um ein grundlegendes Verständnis der Funktionsweise zu erhalten. Man erhält damit allerdings ''.gplot''-Dateien, die sämtliche Angaben hart vercodet beinhalten. Falls Sie beabsichtigen, eine ''.gplot''-File zur Verwendung mit mehreren gleichartigen Geräten anzulegen, empfiehlt es sich, die Dateien direkt zu bearbeiten und die Verweise auf die darzustellenden Daten über Attribute zu steuern, wie nachfolgend dargestellt.}}<br />
== Attribute ==<br />
Das wichtigste spezifische Attribut ist ''plotReplace'', das einige andere, ältere Attribute ersetzen kann. Durch dieses können Angaben in den .gplot-Dateien dynamisch ersetzt werden, wodurch es auf einfache Weise möglich ist, dieselbe .gplot-Datei zur Erstellung von mehreren Plots zu nutzen, die dann auch in einem Plot unterschiedliche Datenquellen verwenden können. Dabei ist zu beachten, dass die in ''plotReplace'' angegebenen Parameter-Wert-Paare in zwei Stufen ersetzt werden: <br />
<br />
Wird in der .gplot-Datei die Schreibweise ''%key%'' verwendet, wird der Parameter bereits ersetzt, bevor die Datenquelle ausgewertet wurde, in der Schreibweise ''<key>'' erfolgt die Auswertung erst danach. Dies ermöglicht es z.B. auch, Informationen aus unterschiedlichen FileLog-Dateien zu visualisieren, ohne die betreffende Datenquelle hart in der .gplot-Datei zu verankern.<br />
<br />
Weiter ist es über diesen Mechanismus möglich, auch angepaßten Perl-Code zur Datenauswertung und -formatierung zu verwenden.<br />
<br />
Siehe dazu insbesondere auch die nachfolgenden beiden Beispiele "Leistungsdaten einer Steckdose (FileLog)" und "Temperatur- und Heizungsdaten eines Zimmers" (DBLog).<br />
<br />
Weitere Details in der {{Link2CmdRef|Anker=SVG-attr}}.<br />
<br />
== Funktionen ==<br />
Details in der {{Link2CmdRef|Anker=SVG-attr-plotfunction}}.<br />
<br />
== Beispiele ==<br />
<br />
=== Leistungsdaten einer Steckdose (FileLog) ===<br />
<br />
* Inhalt der Datei '''SVG_PlugX.gplot'''<br />
{{Randnotiz|RNTyp=g|RNText=Gegebenenfalls sind die Feldnamen anzupassen}}<br />
<syntaxhighlight lang="Gnuplot"><br />
# Leistungsdaten einer Steckdose (FileLog)<br />
#<br />
# plotReplace-Parameter: DataDevice (von diesem Gerät stammen die Daten)<br />
# FileLogDevice (in diesem Gerät werden die Daten geloggt)<br />
# stateOFFvalue (y-Wert zur Darstellung von ausgeschaltetem Zustand)<br />
# stateONvalue (y-Wert zur Darstellung von eingeschaltetem Zustand)<br />
# stateUNKNOWNvalue (y-Wert zur Darstellung von unbekanntem Zustand)<br />
# title (in der Regel ein perl-Ausdruck zur Darstellung von Eckwerten in der Titelzeile)<br />
# yrange (Wertebereich für Darstellung in W vorgeben)<br />
# y2range (Wertebereich für Darstellung in mA vorgeben)<br />
<br />
set terminal png transparent size <SIZE> crop<br />
set output '<OUT>.png'<br />
set xdata time<br />
set timefmt "%Y-%m-%d_%H:%M:%S"<br />
set xlabel " "<br />
set title '<title>'<br />
set ytics <br />
set y2tics <br />
set grid ytics y2tics<br />
set ylabel "Leistung (W)"<br />
set y2label "Strom (mA)"<br />
set yrange %yrange%<br />
set y2range %y2range%<br />
<br />
#%FileLogDevice% 4:%DataDevice%.power\x3a:0:<br />
#%FileLogDevice% 4:%DataDevice%.current\x3a:"":($fld[3]*1000)<br />
#%FileLogDevice% 4:%DataDevice%.userRead_socket_state\x3a:"":($fld[3]=~"off"?%stateOFFvalue%:($fld[3]=~"on"?%stateONvalue%:%stateUNKNOWNvalue%))<br />
<br />
plot "<IN>" using 1:2 axes x1y1 title 'Leistung' ls l0 lw 1 with steps,\<br />
"<IN>" using 1:2 axes x1y2 title 'Strom' ls l1fill_stripe lw 1 with steps,\<br />
"<IN>" using 1:2 axes x1y1 title 'Schaltzustand' ls l3 lw 1 with steps<br />
</syntaxhighlight><br />
<br />
* Definition von SVG-Device '''SVG_Test'''<br />
{{Randnotiz|RNTyp=g|RNText=Alle Vorkommen von ...Data-Device... und ...FileLog-Device... sind zu ersetzen}}<br />
<syntaxhighlight lang="perl"><br />
defmod SVG_Test SVG ...FileLog-Device...:SVG_PlugX:CURRENT<br />
attr SVG_Test captionPos auto<br />
attr SVG_Test plotReplace DataDevice="...Data-Device..." FileLogDevice="...FileLog-Device..." stateOFFvalue="20" stateONvalue="30" stateUNKNOWNvalue="10" yrange="[0:75]" y2range="[0:300]" title={"Steckdose(Testgerät) --- W: $data{min1}...$data{max1} / $data{currval1} --- mA: $data{min2}...$data{max2} / $data{currval2}"}<br />
</syntaxhighlight><br />
<br />
* So sieht das resultierende Diagramm aus<br />
[[Datei:SVG Leistungsdaten einer Steckdose.png|thumb|left|300px]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
=== Temperatur- und Heizungsdaten eines Zimmers === <br />
Quelle: {{Link2Forum|Topic=104935|Message=1011527}}<br />
(Datenquelle ist ein DBLog-Device namens LogDB):<br />
<br />
[[Datei:PlotReplace Example DBLog.png|thumb|right|300px]]<br />
<syntaxhighlight lang="Gnuplot"><br />
# Created by FHEM/98_SVG.pm, 2020-01-06<br />
# to replace variables, use plotReplace like<br />
# plotReplace-Parameter: SPEC1=Thermostat (von diesem Gerät stammen die Thermostat-Daten)<br />
# DBLogDevice (in diesem Gerät werden die Daten geloggt)<br />
# Die übrigen plotReplace-Parameter sind selbsterklärend, Beispiel:<br />
# attr SVG_Thermostat plotReplace DBLogDevice=DBLog SPEC1=Thermostat TL="My example thermostat" EXTERNALTEMPDEVICE=MYSENSOR_97 EXTERNALTEMPREADING=temperature2 \<br />
# ROOMHUMIDITYDEVICE=HUEDevice3 EXTERNALHUMIDITYREADING=humidity ROOMTEMPDEVICE=HUEDevice4 ROOMTEMPREADING=temperature WINDOW1=Window1_MyRoom WINDOW2=Window2_MyRoom<br />
<br />
set terminal png transparent size <SIZE> crop<br />
set output '<OUT>.png'<br />
set xdata time<br />
set timefmt "%Y-%m-%d_%H:%M:%S"<br />
set xlabel " "<br />
set title '<TL>'<br />
set ytics<br />
set y2tics<br />
set grid<br />
set ylabel "Valve/Window"<br />
set y2label "Temperature"<br />
set yrange [-5:105]<br />
set y2range [-15:35]<br />
set isosample 20<br />
<br />
#%DBLogDevice% %SPEC1%:desired-temp::<br />
#%DBLogDevice% %SPEC1%:measured-temp:0:<br />
#%DBLogDevice% %EXTERNALTEMPDEVICE%:%EXTERNALTEMPREADING%::<br />
#%DBLogDevice% %SPEC1%:actuator:0:int<br />
#%DBLogDevice% %ROOMHUMIDITYDEVICE%:%EXTERNALHUMIDITYREADING%:0:<br />
#%DBLogDevice% %ROOMTEMPDEVICE%:%ROOMTEMPREADING%:0:<br />
#%DBLogDevice% %WINDOW1%:state:::$val=~s/(open|closed|tilted)(\d*).*/$1eq"open"?60:$1eq"tilted"?45:0/eg<br />
#%DBLogDevice% %WINDOW2%:state:::$val=~s/(open|closed|tilted)(\d*).*/$1eq"open"?60:$1eq"tilted"?45:0/eg<br />
<br />
<br />
plot "<IN>" using 1:2 axes x1y2 title 'Desired' ls l0 lw 1 with lines,\<br />
"<IN>" using 2:2 axes x1y2 title 'Measured actuator' ls l7 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Aussen' ls l1 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y1 y2title 'Valve' ls l5 lw 1 with steps,\<br />
"<IN>" using 1:2 axes x1y1 title 'Humidity' ls l2 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Measured roomsensor' ls l3 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y1 y2title '%WINDOW1%' ls l4fill lw 0.5 with steps,\<br />
"<IN>" using 1:2 axes x1y1 y2title '%WINDOW2%' ls l5fill lw 0.5 with steps<br />
</syntaxhighlight><br />
== Hinweise ==<br />
* Plot-Abrisse vermeiden<br />
Sind in den Quelldaten nicht genügend Datenpunkte vorhanden, kann es zu Lücken in der Darstellung kommen. Abhilfe kann man mit [[LogProxy]] schaffen oder, indem man zusätzliche Datenpunkte in den Datenquellen generiert, z.B. durch das Setzen von ''addLog''-Attributen an FileLog bzw. DBLog-Geräten. Weitere Hinweise sind in [[Plot-Abriss vermeiden]] zu finden.<br />
<br />
== Links ==<br />
* [[Plots erzeugen]]<br />
* [[Creating Plots]]<br />
<br />
<references /><br />
[[Kategorie:Logging]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=SVG&diff=39182SVG2024-03-17T16:53:00Z<p>Andies: </p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Erstellung von Diagrammen aus Logdaten<br />
|ModType=h<br />
|ModForumArea=Frontends<br />
|ModTechName=98_SVG.pm <br />
|ModOwner=rudolfkoenig ({{Link2FU|8|Forum}} / [[Benutzer Diskussion:Rudolfkoenig|Wiki]])}}<br />
<br />
Das Modul [[SVG]] generiert Diagramme aus [[FileLog|Logdateien]] oder [[DbLog|-datenbanken]]. Alternativen sind [[Grafana]] sowie [[EChartshttps://forum.fhem.de/index.php?topic=137009.0|eCharts]]; beide Möglichkeiten basieren jedoch auf JavaScript.<br />
<br />
Die Eigenschaften des zu erstellenden Diagrams werden in einer .gplot-Datei festgelegt.<br />
<br />
== Definition ==<br />
Die Definition <syntaxhighlight lang="perl"><br />
define <name> SVG <logDevice>:<gplotfile>:<logfile><br />
</syntaxhighlight>besteht lediglich in der Angabe einer Datenquelle, einer .gplot-File und der Angabe von entweder ''CURRENT'' (für LogFile-Quellen) bzw. ''HISTORY'' (für Datenbanken).<br />
<br />
Details zur Definition sind in der {{Link2CmdRef|Anker=SVG-define}} dargestellt.<br />
<br />
== Hintergründe ==<br />
Ursprünglich wurde für das Rendern von Diagrammen in FHEM das Programmpaket ''[http://gnuplot.sourceforge.net/ gnuplot]'' verwendet. Daher entspricht die Syntax der ''.gplot''-Files in großen Teilen derjenigen von ''gnuplot'' (z.B. zu den Linientypen und -farben oder zur Gestaltung des Hintergrundes). Allerdings eben nur in großen Teilen, denn das Modul ''SVG'' implementiert eigenständige Rendering-Routinen, so dass die grundlegenden Formatierungsvorgaben dort, wo dies über spezielle Attribute gesteuert werden kann (z.B. zur Zahl der Achsen), auch über die Attribute vorgenommen werden sollte. Weiter sollte man nicht davon ausgehen, dass alle eventuell von gnuplot her bekannten Funktionen unterstützt werden.<br />
Weitere Hinweise hierzu und zum Aufbau der ''.gplot''-Files sind in [[Plots_erzeugen#Individuell / Manuell|Plots erzeugen]] zu finden.<br />
{{Hinweis|Der Artikel [[Plots_erzeugen|Plots erzeugen]] enthält auch eine Darstellung des gplot-Editors. Dieser kann ein gutes Hilfsmittel sein, um ein grundlegendes Verständnis der Funktionsweise zu erhalten. Man erhält damit allerdings ''.gplot''-Dateien, die sämtliche Angaben hart vercodet beinhalten. Falls Sie beabsichtigen, eine ''.gplot''-File zur Verwendung mit mehreren gleichartigen Geräten anzulegen, empfiehlt es sich, die Dateien direkt zu bearbeiten und die Verweise auf die darzustellenden Daten über Attribute zu steuern, wie nachfolgend dargestellt.}}<br />
== Attribute ==<br />
Das wichtigste spezifische Attribut ist ''plotReplace'', das einige andere, ältere Attribute ersetzen kann. Durch dieses können Angaben in den .gplot-Dateien dynamisch ersetzt werden, wodurch es auf einfache Weise möglich ist, dieselbe .gplot-Datei zur Erstellung von mehreren Plots zu nutzen, die dann auch in einem Plot unterschiedliche Datenquellen verwenden können. Dabei ist zu beachten, dass die in ''plotReplace'' angegebenen Parameter-Wert-Paare in zwei Stufen ersetzt werden: <br />
<br />
Wird in der .gplot-Datei die Schreibweise ''%key%'' verwendet, wird der Parameter bereits ersetzt, bevor die Datenquelle ausgewertet wurde, in der Schreibweise ''<key>'' erfolgt die Auswertung erst danach. Dies ermöglicht es z.B. auch, Informationen aus unterschiedlichen FileLog-Dateien zu visualisieren, ohne die betreffende Datenquelle hart in der .gplot-Datei zu verankern.<br />
<br />
Weiter ist es über diesen Mechanismus möglich, auch angepaßten Perl-Code zur Datenauswertung und -formatierung zu verwenden.<br />
<br />
Siehe dazu insbesondere auch die nachfolgenden beiden Beispiele "Leistungsdaten einer Steckdose (FileLog)" und "Temperatur- und Heizungsdaten eines Zimmers" (DBLog).<br />
<br />
Weitere Details in der {{Link2CmdRef|Anker=SVG-attr}}.<br />
<br />
== Funktionen ==<br />
Details in der {{Link2CmdRef|Anker=SVG-attr-plotfunction}}.<br />
<br />
== Beispiele ==<br />
<br />
=== Leistungsdaten einer Steckdose (FileLog) ===<br />
<br />
* Inhalt der Datei '''SVG_PlugX.gplot'''<br />
{{Randnotiz|RNTyp=g|RNText=Gegebenenfalls sind die Feldnamen anzupassen}}<br />
<syntaxhighlight lang="Gnuplot"><br />
# Leistungsdaten einer Steckdose (FileLog)<br />
#<br />
# plotReplace-Parameter: DataDevice (von diesem Gerät stammen die Daten)<br />
# FileLogDevice (in diesem Gerät werden die Daten geloggt)<br />
# stateOFFvalue (y-Wert zur Darstellung von ausgeschaltetem Zustand)<br />
# stateONvalue (y-Wert zur Darstellung von eingeschaltetem Zustand)<br />
# stateUNKNOWNvalue (y-Wert zur Darstellung von unbekanntem Zustand)<br />
# title (in der Regel ein perl-Ausdruck zur Darstellung von Eckwerten in der Titelzeile)<br />
# yrange (Wertebereich für Darstellung in W vorgeben)<br />
# y2range (Wertebereich für Darstellung in mA vorgeben)<br />
<br />
set terminal png transparent size <SIZE> crop<br />
set output '<OUT>.png'<br />
set xdata time<br />
set timefmt "%Y-%m-%d_%H:%M:%S"<br />
set xlabel " "<br />
set title '<title>'<br />
set ytics <br />
set y2tics <br />
set grid ytics y2tics<br />
set ylabel "Leistung (W)"<br />
set y2label "Strom (mA)"<br />
set yrange %yrange%<br />
set y2range %y2range%<br />
<br />
#%FileLogDevice% 4:%DataDevice%.power\x3a:0:<br />
#%FileLogDevice% 4:%DataDevice%.current\x3a:"":($fld[3]*1000)<br />
#%FileLogDevice% 4:%DataDevice%.userRead_socket_state\x3a:"":($fld[3]=~"off"?%stateOFFvalue%:($fld[3]=~"on"?%stateONvalue%:%stateUNKNOWNvalue%))<br />
<br />
plot "<IN>" using 1:2 axes x1y1 title 'Leistung' ls l0 lw 1 with steps,\<br />
"<IN>" using 1:2 axes x1y2 title 'Strom' ls l1fill_stripe lw 1 with steps,\<br />
"<IN>" using 1:2 axes x1y1 title 'Schaltzustand' ls l3 lw 1 with steps<br />
</syntaxhighlight><br />
<br />
* Definition von SVG-Device '''SVG_Test'''<br />
{{Randnotiz|RNTyp=g|RNText=Alle Vorkommen von ...Data-Device... und ...FileLog-Device... sind zu ersetzen}}<br />
<syntaxhighlight lang="perl"><br />
defmod SVG_Test SVG ...FileLog-Device...:SVG_PlugX:CURRENT<br />
attr SVG_Test captionPos auto<br />
attr SVG_Test plotReplace DataDevice="...Data-Device..." FileLogDevice="...FileLog-Device..." stateOFFvalue="20" stateONvalue="30" stateUNKNOWNvalue="10" yrange="[0:75]" y2range="[0:300]" title={"Steckdose(Testgerät) --- W: $data{min1}...$data{max1} / $data{currval1} --- mA: $data{min2}...$data{max2} / $data{currval2}"}<br />
</syntaxhighlight><br />
<br />
* So sieht das resultierende Diagramm aus<br />
[[Datei:SVG Leistungsdaten einer Steckdose.png|thumb|left|300px]]<br />
<br />
<br />
<br />
<br />
<br />
<br />
=== Temperatur- und Heizungsdaten eines Zimmers === <br />
Quelle: {{Link2Forum|Topic=104935|Message=1011527}}<br />
(Datenquelle ist ein DBLog-Device namens LogDB):<br />
<br />
[[Datei:PlotReplace Example DBLog.png|thumb|right|300px]]<br />
<syntaxhighlight lang="Gnuplot"><br />
# Created by FHEM/98_SVG.pm, 2020-01-06<br />
# to replace variables, use plotReplace like<br />
# plotReplace-Parameter: SPEC1=Thermostat (von diesem Gerät stammen die Thermostat-Daten)<br />
# DBLogDevice (in diesem Gerät werden die Daten geloggt)<br />
# Die übrigen plotReplace-Parameter sind selbsterklärend, Beispiel:<br />
# attr SVG_Thermostat plotReplace DBLogDevice=DBLog SPEC1=Thermostat TL="My example thermostat" EXTERNALTEMPDEVICE=MYSENSOR_97 EXTERNALTEMPREADING=temperature2 \<br />
# ROOMHUMIDITYDEVICE=HUEDevice3 EXTERNALHUMIDITYREADING=humidity ROOMTEMPDEVICE=HUEDevice4 ROOMTEMPREADING=temperature WINDOW1=Window1_MyRoom WINDOW2=Window2_MyRoom<br />
<br />
set terminal png transparent size <SIZE> crop<br />
set output '<OUT>.png'<br />
set xdata time<br />
set timefmt "%Y-%m-%d_%H:%M:%S"<br />
set xlabel " "<br />
set title '<TL>'<br />
set ytics<br />
set y2tics<br />
set grid<br />
set ylabel "Valve/Window"<br />
set y2label "Temperature"<br />
set yrange [-5:105]<br />
set y2range [-15:35]<br />
set isosample 20<br />
<br />
#%DBLogDevice% %SPEC1%:desired-temp::<br />
#%DBLogDevice% %SPEC1%:measured-temp:0:<br />
#%DBLogDevice% %EXTERNALTEMPDEVICE%:%EXTERNALTEMPREADING%::<br />
#%DBLogDevice% %SPEC1%:actuator:0:int<br />
#%DBLogDevice% %ROOMHUMIDITYDEVICE%:%EXTERNALHUMIDITYREADING%:0:<br />
#%DBLogDevice% %ROOMTEMPDEVICE%:%ROOMTEMPREADING%:0:<br />
#%DBLogDevice% %WINDOW1%:state:::$val=~s/(open|closed|tilted)(\d*).*/$1eq"open"?60:$1eq"tilted"?45:0/eg<br />
#%DBLogDevice% %WINDOW2%:state:::$val=~s/(open|closed|tilted)(\d*).*/$1eq"open"?60:$1eq"tilted"?45:0/eg<br />
<br />
<br />
plot "<IN>" using 1:2 axes x1y2 title 'Desired' ls l0 lw 1 with lines,\<br />
"<IN>" using 2:2 axes x1y2 title 'Measured actuator' ls l7 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Aussen' ls l1 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y1 y2title 'Valve' ls l5 lw 1 with steps,\<br />
"<IN>" using 1:2 axes x1y1 title 'Humidity' ls l2 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Measured roomsensor' ls l3 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y1 y2title '%WINDOW1%' ls l4fill lw 0.5 with steps,\<br />
"<IN>" using 1:2 axes x1y1 y2title '%WINDOW2%' ls l5fill lw 0.5 with steps<br />
</syntaxhighlight><br />
== Hinweise ==<br />
* Plot-Abrisse vermeiden<br />
Sind in den Quelldaten nicht genügend Datenpunkte vorhanden, kann es zu Lücken in der Darstellung kommen. Abhilfe kann man mit [[LogProxy]] schaffen oder, indem man zusätzliche Datenpunkte in den Datenquellen generiert, z.B. durch das Setzen von ''addLog''-Attributen an FileLog bzw. DBLog-Geräten. Weitere Hinweise sind in [[Plot-Abriss vermeiden]] zu finden.<br />
<br />
== Links ==<br />
* [[Plots erzeugen]]<br />
* [[Creating Plots]]<br />
<br />
<references /><br />
[[Kategorie:Logging]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Module_Shares_und_ShareMaster&diff=38358Module Shares und ShareMaster2023-05-09T17:28:48Z<p>Andies: /* Zusammenfassung der beiden Beispieldepots */ https://forum.fhem.de/index.php?msg=1275091</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Das Modul Shares dient zur Verwaltung eines Wertpapierdepots.<br />
|ModType=h<br />
|ModCmdRef=Shares<br />
|ModForumArea=Unterstuetzende Dienste<br />
|ModTechName=95_Shares.pm<br />
|ModOwner=Prof. Dr. Peter A. Henning<br />
}}<br />
{{Infobox Modul<br />
|ModPurpose=Das Modul ShareMaster fasst die Daten eines oder mehrer Wertpapierdepots in einer komfortablen Anzeige zusammen.<br />
|ModType=h<br />
|ModCmdRef=ShareMaster<br />
|ModForumArea=Unterstuetzende Dienste<br />
|ModTechName=95_ShareMaster.pm<br />
|ModOwner=Prof. Dr. Peter A. Henning<br />
}}<br />
[[Kategorie:Examples]]<br />
<br />
===Shares.pm===<br />
Das Modul 95_Shares.pm dient dazu, ein Wertpapierdepot zu verwalten. Dabei wurden wesentliche Bestandteile des Moduls 98_STOCKQUOTES.pm übernommen, aber strukturell so stark verändert, dass ein neuer Modulname sinnvoll war. vbs, dem Ersteller und Maintainer des Ursprungsmoduls sei an dieser Stelle gedankt. Die strukturellen Änderungen sind insbesondere:<br />
* separate Währungen für alle Wertpapiere im Depot und das Depot selbst (Attribute ''shareCurrency'' und ''depotCurrency''). Das ermöglicht, Wertpapiere in dieses Depot zu legen, die zwar für das eigene Depot in € gekauft werden, aber an ausländischen Börsen gehandelt und ggf. auch im Ausland verwahrt werden. <br />
* Angabe einer Kategorie (z.B. "Rohstoff" oder "Bio") für jedes Wertpapier.<br />
* deutliche Vereinfachung der Reading-Namen und Konfigurierbarkeit der angezeigten Werte.<br />
====Einrichtung====<br />
Das Modul benötigt das Perl-Modul Finance::Quote, das mit dem folgenden Kommandozeilenbefehl installiert wird<br />
apt install libfinance-quote-perl<br />
<br />
Die Definition des Depots ist dann einfach und benötigt keine Parameter<br />
define <Depotname> Shares<br />
Das Attribut ''stocks'' enthält eine (gerne mehrzeilige) Liste der Wertpapiere im Format<br />
<Symbol>:<Anzahl>:<Einstandswert>:<Kategorie><br />
Wichtig ist, dass der Einstandwert ''in Depotwährung'' angegeben wird.<br />
<br />
'''Achtung''': Offenbar ist dieses Package nicht ganz vollständig. Wenn es danach zu Fehlermeldungen kommt, etwa<br />
Can't locate object method "methods" via package "Finance::Quote::currency_rates" (perhaps you forgot to load "Finance::Quote::currency_rates"?)<br />
muss das Perl-Package von Hand repariert werden. Dazu auf der Kommandzeile eingeben<br />
cpan Finance::Quote<br />
und ggf. eine halbe Stunde Wartezeit einplanen.<br />
<br />
===ShareMaster.pm===<br />
Das Modul 95_ShareMaster.pm dient der komfortablen Anzeige der mit dem obigen Modul verwalteten Werte (siehe Beispiele). Dabei erfolgt die Anzeige je Unterdepot, aber auch eine Zusammenfassung nach Kategorien.<br />
<br />
[[Datei:Sharemaster.png|800px|]]<br />
====Einrichtung====<br />
Die Definition erhält als Parameter alle Unterdepots<br />
define <MasterDepotname> ShareMaster <Unterdepot1> [<Unterdepot2>]*<br />
<br />
==Beispiele==<br />
===Beispieldepot mit 4 deutschen Papieren===<br />
[[Datei:Shares.png|400px|]]<br />
<br />
Die Währungsattribute des Depots DepotY_EUR haben die Werte <br />
attr DepotY_EUR depotCurrency EUR<br />
attr DepotY_EUR shareCurrency EUR<br />
Das Attribut ''stocks'' des Depots DepotY_EUR bekommt den mehrzeiligen Wert<br />
BAS.DE:3:154:chemistry,<br />
FRA.DE:6:258.47:mobility,<br />
LIN.DE:1:212:chemistry,<br />
TKA.DE:10:72:tech,<br />
<br />
===Beispieldepot mit 2 kanadischen Papieren===<br />
Die Währungsattribute des Depots DepotY_CAD haben die Werte <br />
attr DepotY_CAD depotCurrency EUR<br />
attr DepotY_CAD shareCurrency CAD<br />
Das Attribut ''stocks'' des Depots DepotY_CAD bekommt den mehrzeiligen Wert<br />
PSLV.TO:10:73:commodity,<br />
BLDP.TO:5:76:h2<br />
<br />
===Zusammenfassung der beiden Beispieldepots===<br />
Die Definition erhält als Parameter die beiden oben definierten Depots<br />
define DepotY ShareMaster DepotY_EUR DepotY_CAD<br />
und führt zur Anzeige aus dem oberen Bild.<br />
<br />
==Änderungen in der yahoo API (Mai 2023)==<br />
Leider haben Änderungen in der Yahoo API dazu geführt, dass die Abrufe eventuell nicht mehr funktionieren. Ärgerlicherweise besteht zudem der Workaround derzeit darin, händisch in installierten Perl-Dateien Versionsnummern zu ändern - und niemand weiß, wie nachhaltig diese Anpassungen sein werden. Falls das angelegte Depot aus yahoo finance nur Nullen holt, sind folgende Schritte nötig: Zuerst sucht man eine Perl-Datei mit <br />
(sudo) find / -name YahooJSON.pm -print<br />
und erhält den Speicherort von YahooJSON.pm. Oft findet man die Datei unter /usr/share/perl5/Finance/Quote/YahooJSON.pm. Im nächsten Schritt sucht man in der Datei die Zeile<br />
my $YIND_URL_HEAD = 'https://query1.finance.yahoo.com/v7/finance/quote?symbols=';<br />
und ändert die v7 in v6. Danach sollte der Abruf (zumindest erstmal) gehen.</div>Andieshttp://wiki.fhem.de/w/index.php?title=Module_Shares_und_ShareMaster&diff=38357Module Shares und ShareMaster2023-05-09T17:24:50Z<p>Andies: /* Einrichtung */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Das Modul Shares dient zur Verwaltung eines Wertpapierdepots.<br />
|ModType=h<br />
|ModCmdRef=Shares<br />
|ModForumArea=Unterstuetzende Dienste<br />
|ModTechName=95_Shares.pm<br />
|ModOwner=Prof. Dr. Peter A. Henning<br />
}}<br />
{{Infobox Modul<br />
|ModPurpose=Das Modul ShareMaster fasst die Daten eines oder mehrer Wertpapierdepots in einer komfortablen Anzeige zusammen.<br />
|ModType=h<br />
|ModCmdRef=ShareMaster<br />
|ModForumArea=Unterstuetzende Dienste<br />
|ModTechName=95_ShareMaster.pm<br />
|ModOwner=Prof. Dr. Peter A. Henning<br />
}}<br />
[[Kategorie:Examples]]<br />
<br />
===Shares.pm===<br />
Das Modul 95_Shares.pm dient dazu, ein Wertpapierdepot zu verwalten. Dabei wurden wesentliche Bestandteile des Moduls 98_STOCKQUOTES.pm übernommen, aber strukturell so stark verändert, dass ein neuer Modulname sinnvoll war. vbs, dem Ersteller und Maintainer des Ursprungsmoduls sei an dieser Stelle gedankt. Die strukturellen Änderungen sind insbesondere:<br />
* separate Währungen für alle Wertpapiere im Depot und das Depot selbst (Attribute ''shareCurrency'' und ''depotCurrency''). Das ermöglicht, Wertpapiere in dieses Depot zu legen, die zwar für das eigene Depot in € gekauft werden, aber an ausländischen Börsen gehandelt und ggf. auch im Ausland verwahrt werden. <br />
* Angabe einer Kategorie (z.B. "Rohstoff" oder "Bio") für jedes Wertpapier.<br />
* deutliche Vereinfachung der Reading-Namen und Konfigurierbarkeit der angezeigten Werte.<br />
====Einrichtung====<br />
Das Modul benötigt das Perl-Modul Finance::Quote, das mit dem folgenden Kommandozeilenbefehl installiert wird<br />
apt install libfinance-quote-perl<br />
<br />
Die Definition des Depots ist dann einfach und benötigt keine Parameter<br />
define <Depotname> Shares<br />
Das Attribut ''stocks'' enthält eine (gerne mehrzeilige) Liste der Wertpapiere im Format<br />
<Symbol>:<Anzahl>:<Einstandswert>:<Kategorie><br />
Wichtig ist, dass der Einstandwert ''in Depotwährung'' angegeben wird.<br />
<br />
'''Achtung''': Offenbar ist dieses Package nicht ganz vollständig. Wenn es danach zu Fehlermeldungen kommt, etwa<br />
Can't locate object method "methods" via package "Finance::Quote::currency_rates" (perhaps you forgot to load "Finance::Quote::currency_rates"?)<br />
muss das Perl-Package von Hand repariert werden. Dazu auf der Kommandzeile eingeben<br />
cpan Finance::Quote<br />
und ggf. eine halbe Stunde Wartezeit einplanen.<br />
<br />
===ShareMaster.pm===<br />
Das Modul 95_ShareMaster.pm dient der komfortablen Anzeige der mit dem obigen Modul verwalteten Werte (siehe Beispiele). Dabei erfolgt die Anzeige je Unterdepot, aber auch eine Zusammenfassung nach Kategorien.<br />
<br />
[[Datei:Sharemaster.png|800px|]]<br />
====Einrichtung====<br />
Die Definition erhält als Parameter alle Unterdepots<br />
define <MasterDepotname> ShareMaster <Unterdepot1> [<Unterdepot2>]*<br />
<br />
==Beispiele==<br />
===Beispieldepot mit 4 deutschen Papieren===<br />
[[Datei:Shares.png|400px|]]<br />
<br />
Die Währungsattribute des Depots DepotY_EUR haben die Werte <br />
attr DepotY_EUR depotCurrency EUR<br />
attr DepotY_EUR shareCurrency EUR<br />
Das Attribut ''stocks'' des Depots DepotY_EUR bekommt den mehrzeiligen Wert<br />
BAS.DE:3:154:chemistry,<br />
FRA.DE:6:258.47:mobility,<br />
LIN.DE:1:212:chemistry,<br />
TKA.DE:10:72:tech,<br />
<br />
===Beispieldepot mit 2 kanadischen Papieren===<br />
Die Währungsattribute des Depots DepotY_CAD haben die Werte <br />
attr DepotY_CAD depotCurrency EUR<br />
attr DepotY_CAD shareCurrency CAD<br />
Das Attribut ''stocks'' des Depots DepotY_CAD bekommt den mehrzeiligen Wert<br />
PSLV.TO:10:73:commodity,<br />
BLDP.TO:5:76:h2<br />
<br />
===Zusammenfassung der beiden Beispieldepots===<br />
Die Definition erhält als Parameter die beiden oben definierten Depots<br />
define DepotY ShareMaster DepotY_EUR DepotY_CAD<br />
und führt zur Anzeige aus dem oberen Bild.</div>Andieshttp://wiki.fhem.de/w/index.php?title=DbLog&diff=37896DbLog2022-12-30T07:16:22Z<p>Andies: /* Links */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Protokolliert Ereignisse in einer Datenbank<br />
|ModType=h<br />
|ModForumArea=Automatisierung<br />
|ModTechName=93_DbLog.pm<br />
|ModOwner=tobiasfaust ({{Link2FU|118|Forum}}/[[Benutzer Diskussion:Tobias.faust|Wiki]])<br />DS_Starter ({{Link2FU|16933|Forum}}/[[Benutzer Diskussion:DS_Starter|Wiki]])<br />
}}<br />
== Einleitung ==<br />
Mit der Zeit entstehen in FHEM recht umfangreiche Log-Daten für die verschiedensten konfigurierten Devices. Die übliche Einstiegs-[[Konfiguration]] sieht vor, dass die Logs als {{Link2CmdRef|Lang=de|Anker=FileLog|Label=FileLog}} gespeichert werden - je nach Einstellung in wenigen sehr großen oder vielen kleineren Dateien. Der Datei-basierte Zugriff ist allerdings nicht wirklich performant und kann schnell zum Flaschenhals werden (z.B. bei der Darstellung von Graphen über einen längeren Zeitraum).<br />
<br />
Alternativ kann FHEM die Log-Daten mittels {{Link2CmdRef|Lang=de|Anker=DbLog|Label=DbLog}} in einer Datenbank speichern. Diese kann lokal als einfache SQLite- oder als zentrale Server-Datenbank (s.u.) gestaltet sein. Schon eine lokale einfache SQLite-Datenbank ist in der Regel deutlich performanter als File-basierte Logs.<br />
<br />
Damit eine Datenbank-Nutzung möglich ist, müssen folgende Anpassungen gemacht werden:<br />
# [[#Datenbank|Erstellen einer entsprechenden Datenbank]]<br />
# [[#Datenbank-Anbindung mittels db.conf|Konfiguration der Datenbank-Anbindung in FHEM]]<br />
# [[#Konfiguration als Device in fhem.cfg|Anpassen aller (oder einzelner) Konfigurationen von FileLog nach DbLog]]<br />
# [[#Anpassen der gplot-Konfigurationen|Ggf. Anpassen der gplot-Konfigurationen]]<br />
<br />
Eine weitere Alternative bietet das Modul [[InfluxDBLogger]].<br />
<br />
Reporting und Management von DbLog-Datenbankinhalten kann mit dem Modul [[DbRep - Reporting und Management von DbLog-Datenbankinhalten|DbRep]] stattfinden.<br />
<br />
== Konfiguration ==<br />
=== Datenbank-Anbindung mittels db.conf ===<br />
{{Randnotiz|RNTyp=y|RNText='''Anmerkung''': MariaDB10 nutzt nicht Port 3306 sondern 3307. Dies ist zum Beispiel bei Synology NAS der Fall.}}<br />
DbLog wird durch 2 verschiedene Einträge aktiviert/definiert. In einer Datei namens '''db.conf''' werden die Parameter für eine Verbindung zur Datenbank (host, username, password, etc.) hinterlegt. Diese Datei kann in einem beliebigen Verzeichnis angelegt werden. Für eine MySQL-Datenbank sieht die db.conf folgendermaßen aus:<br />
<br />
%dbconfig= (<br />
connection => "mysql:database=fhem;host=db;port=3306",<br />
user => "fhemuser",<br />
password => "fhempassword",<br />
);<br />
<br />
Im Verzeichnis '''contrib/dblog''' der FHEM-Installation befindet sich eine Beispielkonfiguration mit der Syntax für jeden unterstützen Datenbanktyp.<br />
Es wird empfohlen, diese Datei zu kopieren und erst dann entsprechend zu bearbeiten. Am Besten kopiert man diese Datei in das FHEM Home Directory /opt/fhem/ und achtet auf die entsprechenden Rechte!<br />
<syntaxhighlight lang="bash">chown fhem:dialout /opt/fhem/db.conf</syntaxhighlight><br />
<br />
=== Konfiguration als Device ===<br />
Das DbLog Device wird dann definiert mit<br />
:<code>define <name> DbLog <configfilename> <regexp> </code><br />
wobei ''<configfilename>'' dem Pfad zur zuvor angelegten db.conf entspricht.<br />
Ein Beispiel hierfür wäre:<br />
:<code>define logdb DbLog ./db.conf .*:.* </code><br />
Die Angabe von <code>.*:.*</code> bedeutet, dass sämtliche DeviceMessages (Messwerte, Batteriestatus, KeepAlives, etc.) in die Datenbank geschrieben werden. Dies führt u.U. dazu, dass die Datenbank auch mit vielen teils irrelevanten Werten gefüllt wird. Man kann daher die zu loggenden Werte einschränken, indem man genau angibt welche Werte übertragen werden sollen. Dies ist in [[#Finetuning des Loggings]] beschrieben.<br />
<br />
Unbedingt beachten: bei Verwendung des Moduls configdb wird die Konfigurationsdatei aus der '''''Datenbank''''' gelesen. Deshalb ist es erforderlich, die Datei mittels <code>configdb fileimport db.conf </code> vorher zu importieren !<br />
<br />
=== Finetuning des Loggings ===<br />
Bei der Konfiguration des Log-Devices werden die zu loggenden Daten definiert - in der einfachsten Form sieht das so aus: <code>define logdb DbLog ./db.conf .*:.* </code>. Die Angabe von <code>.*:.*</code> bedeutet, dass sämtliche DeviceMessages (Messwerte, Batteriestatus, KeepAlives, etc.) in die Datenbank geschrieben werden. Dies führt u.U. dazu, dass die Datenbank auch mit sehr vielen und teils nicht benötigten Werten gefüllt wird und schnell wächst. Die Datenbank ist zwar deutlich leistungsfähiger, was große Datenmengen angeht, Datensparsamkeit kann aber schnell sinnvoll werden...<br />
<br />
Um das Log-Aufkommen einzugrenzen gibt es mehrere Ansätze:<br />
* Einschränkung über den <code>define</code>-Eintrag<br />
* Einschränkung über DbLogExclude-Einträge der jeweiligen Devices<br />
* Einschränkung über DbLogInclude-Einträge des jeweiligen Devices<br />
* Ausschluß von Device/Reading-Kombinationen über das Attribut "excludeDevs". Es können {{Link2CmdRef|Anker=devspec|Lang=de|Label=devspec}} verwendet werden. <br />
<br />
==== Einschränkung über den zentralen <code>define</code>-Eintrag ====<br />
Man kann die zu loggenden Werte einschränken, indem man genau angibt welche Werte übertragen werden sollen. Die erste Wildcard, also das erste <code>.*</code>, entspricht dem in FHEM verwendeten Device-Namen. Die zweite Wildcard entspricht dem vom Device ausgegebenen zu loggenden Wert. Separiert werden beiden Angaben durch einen Doppelpunkt. <br />
<br />
Ein Beispiel, um zwar alle definierten Devices zu erfassen, aber nur die Werte Temperatur, Ventilposition und Luftfeuchte in die Datenbank zu schreiben wäre:<br />
:<code>define myDbLog DbLog ./db.conf .*:(temperature|valveposition|humidity).* </code><br />
<br />
==== Einschränkung über die jeweiligen Devices ====<br />
Man kann die zu loggenden Werte für einzelne Devices separat einschränken, ohne dies im zentralen define-Eintrag machen zu müssen. Dies kann interessant sein, wenn beispielsweise ein Device Fehlerwerte meldet, die uninteressant sind, oder es meldet unnötig häufig Werte - beides ist z.B. bei 1-wire-Temperatursensoren gerne der Fall.<br />
<br />
Um das einzuschränken gibt es 2 Stellparameter, die als Attribute direkt zum jeweiligen Device konfiguriert werden:<br />
* DbLogExclude - definiert Werte, die nicht geloggt werden sollen<br />
* DbLogInclude - definiert Werte, die geloggt werden sollen ( siehe attr DbLogSelectionMode )<br />
* event-min-interval, event-on-change-reading und event-on-update-reading beeinflussen, wie häufig Werte geloggt werden (vgl. {{Link2CmdRef|Lang=de|Anker=event-on-update-reading}})<br />
<br />
Eine konkrete Konfiguration für einen sehr gesprächigen 1-wire-Temperatursensor könnte wie folgt aussehen:<br />
<pre><br />
define EG_Balkon GPIO4 BUSMASTER<br />
attr EG_Balkon DbLogExclude failures,T,85 # logge keine "failures", "T"-Werte und "85"-Werte (default-Werte, wenn keine Temperatur gelesen werden kann)<br />
attr EG_Balkon event-on-change-reading state # logge nur, wenn sich ein Wert ändert (wenn sich die Temperatur nicht ändert, logge das nicht)<br />
attr EG_Balkon event-min-interval state:900 # logge spätestens alle 900sec = 15min<br />
attr EG_Balkon event-on-update-reading .* # logge alle Werte, die aktualisiert werden<br />
<br />
attr <1-Wire-Device vom Typ OWTHERM oder OWSWITCH> DbLogExclude data.* # verhindert das Logging der state-Eintragungen<br />
</pre><br />
<br />
Eine in diesem {{Link2Forum|Topic=33697|Message=264127}} vorgestellte Strategie zur Vermeidung unnötigen Loggings ist, dass bei der Definition von Devices durch das nachfolgende <code>notify</code> automatisch ein DbLogExclude für alle Werte (.*) des Devices zugewiesen wird und dies nur bei Interesse an geloggten Werten gelöscht bzw. angepasst wird:<br />
<code>define nDbLogExclude notify global:DEFINED.* attr $EVTPART1 DbLogExclude .*</code><br />
<br />
Ebenso ist es mittlerweile möglich, lediglich erwünschte Werte (Positiv-Liste) zu loggen und alle anderen zu verwerfen. Hierfür wird im LogDevice das attribut DbLogSelectionMode Include verwendet. Nun kann für jedes Device mit DbLogInclude <Reading1>,<Reading2>,... angegeben werden, welche Readings geloggt werden sollen. <br />
Integriert ist ebenfalls ein "min-interval", siehe {{Link2CmdRef}}.<br />
<br />
== Datenbank ==<br />
Unterstützte Datenbanksysteme (Auswahl):<br />
* Sqlite<br />
* MySQL<br />
* PostGreSql<br />
<br />
=== Tabellen ===<br />
Die Datenbank ist relativ simpel gestaltet und besteht lediglich aus den folgenden beiden Tabellen:<br />
* current<br />
* history<br />
<br />
DbLog ist auf eine feste Tabellenstruktur angewiesen. Man muss daher in seiner Datenbank eine Tabelle mit folgenden Spalten anlegen:<br />
{| class="wikitable"<br />
|-<br />
! Spalte<br />
! Beschreibung (en)<br />
! Beschreibung (de)<br />
! Beispiel<br />
|-<br />
| '''TIMESTAMP'''<br />
| timestamp of event<br />
| Zeitstempel<br />
| 2007-12-30 21:45:22 <br />
|-<br />
| '''DEVICE'''<br />
| device name<br />
| Device-Name<br />
| Wetterstation<br />
|-<br />
| '''TYPE'''<br />
| device type<br />
| Device-Typ<br />
| KS300<br />
|-<br />
| '''EVENT'''<br />
| event specification as full string<br />
| Eventspezifikation als Text<br />
| humidity: 71 (%)<br />
|-<br />
| '''READING'''<br />
| name of reading extracted from event<br />
| Bezeichnung des Readings<br />
| humidity<br />
|-<br />
| '''VALUE'''<br />
| actual reading extracted from event<br />
| Wert des Readings<br />
| 71<br />
|-<br />
| '''UNIT'''<br />
| unit extracted from event<br />
| Einheit des Readings<br />
| %<br />
|-<br />
|}<br />
<br />
Die Vorlagen zur Anlage von Tabellen und Indizes sind für jeden unterstützten Datenbanktyp im Verzeichnis '''contrib/dblog''' der FHEM-Installation, oder hier zu finden: [https://svn.fhem.de/trac/browser/trunk/fhem/contrib/dblog/ Link]. Das MySQL-Skript (db_create_mysql.sql) legt eine neue Datenbank, das PostGres-Skript (db_create_postgresql.sql) ein neues Schema mit Namen "fhem" an.<br />
<br />
==== current ====<br />
Die Tabelle current enthält für jedes zu loggende Device lediglich den letzten Wert. Falls noch kein Wert geloggt wurde, ist diese Tabelle leer. <br />
Falls der Inhalt gelöscht wird, bauen sich die Daten automatisch wieder auf. Es gehen durch das löschen der Tabelle current keine Log-Informationen verloren.<br />
Der Inhalt wird aber u.a. für die Dropdown-Felder beim Plot-Editor verwendet.<br />
<br />
Um doppelte Einträge in der Tabelle zu vermeiden, wurden die Möglichkeit geschaffen Primary Keys zu definieren. Da in der Spalte <code>READING</code> u.U. bei verschiedenen Geräten gleiche Namen vorkommen können, sollte der Primary Key um den Gerätenamen erweitert werden. Der Primary Key sollte also aus <code>DEVICE</code> und <code>READING</code> bestehen. Um in der Datenbank ''fhem'' diesen PK zu setzen, kann folgender SQL Code verwendet werden:<br />
<br />
<syntaxhighlight lang="sql"><br />
ALTER TABLE `fhem`.`current` <br />
CHANGE COLUMN `DEVICE` `DEVICE` VARCHAR(64) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL ,<br />
CHANGE COLUMN `READING` `READING` VARCHAR(64) CHARACTER SET 'utf8' COLLATE 'utf8_bin' NOT NULL ,<br />
ADD PRIMARY KEY (`DEVICE`, `READING`);<br />
</syntaxhighlight>Achtung: Die Tabelle "current" wird nur befüllt, wenn das Attribut DbLogType auf Current oder Current/History gesetzt ist.<br />
<br />
==== history ====<br />
Die Tabelle history enthält alle bisher geloggten Daten. Löschen in dieser Tabelle bedeutet automatisch Datenverlust (gewollt oder nicht ... )<br />
Der Inhalt dieser Tabelle wird verwendet, um die Plots zu zeichnen oder Auswertungen mit [[DbRep - Reporting und Management von DbLog-Datenbankinhalten|DbRep]] anzufertigen<br />
<br />
{{Todo|Ausbauen}}<br />
<br />
Um Problem beim Import von cacheFiles zu vermeiden, kann in der Datenbank ein PK angelegt werden, welcher Timestamp, Device und Reading umfasst. Dadurch werden doppelte Einträge wirksam verhindert.<br />
<br />
== Anpassen der gplot-Konfigurationen ==<br />
Die meisten gplot-Konfigurationen sind bisher lediglich auf FileLog-Konfigurationen ausgelegt. Deshalb müssen sie für die Verwendung mit DbLog angepasst werden. Glücklicherweise beschränkt sich dies auf die reinen FileLog-Zeilen - es müssen die DbLog-Äquivalente hinzugefügt werden. Die FileLog-Einträge müssen zwar nicht gelöscht werden, wenn man aber FileLog und DbLog parallel betreibt, sollte man getrennte gplot-Dateien für beide Logging-Typen haben um Auswertungsprobleme erkennen zu können.<br />
<br />
Für die fht.gplot Konfiguration sähe die Anpassung wie folgt aus (lediglich die vier DbLog-Zeilen wurden hinzugefügt):<br />
<syntaxhighlight lang="Perl"><br />
# Created by FHEM/98_SVG.pm, 2014-12-25 21:53:30<br />
set terminal png transparent size <SIZE> crop<br />
set output '<OUT>.png'<br />
set xdata time<br />
set timefmt "%Y-%m-%d_%H:%M:%S"<br />
set xlabel " "<br />
set title '<L1>'<br />
set ytics nomirror<br />
set y2tics <br />
set grid y2tics<br />
set ylabel "Actuator/Window (%)"<br />
set y2label "Temperature in C"<br />
set yrange 0:100<br />
set y2range 5:25<br />
<br />
#FileLog 4:.measured-temp\x3a:0:<br />
#FileLog 4:.actuator\x3a:0:int<br />
#FileLog 4:.desired-temp::<br />
#FileLog 4:.window\x3a::<br />
<br />
#DbLog <SPEC1>:.measured-temp:0:<br />
#DbLog <SPEC1>:.actuator:0:int<br />
#DbLog <SPEC1>:.desired-temp::<br />
#DbLog <SPEC1>:.window::<br />
<br />
plot "<IN>" using 1:2 axes x1y2 title 'Measured temperature' ls l0 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y1 title 'Actuator (%)' ls l1 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Desired Temperature' ls l2 lw 1 with steps,\<br />
"<IN>" using 1:2 axes x1y1 title 'Window' ls l3 lw 1 with steps<br />
</syntaxhighlight><br />
<br />
Des Weiteren ist zu beachten: <br />
<br />
On-Off-Plots<br />
<br />
EG_Bad:window:::$val=~s/(on|off)(\d*).*/$1eq"on"?1:0/eg<br />
<br />
unter Berücksichtigung von dim-Werten:<br />
<br />
EG_WoZi_Licht:value:::$val=~s/(on|off)(\d*).*/$1eq"on"?1:($1eq"dim"?$2*0.01:0)/eg<br />
<br />
== Beispiel: Anlegen und Nutzung einer SQLite-Datenbank ==<br />
Im folgenden wird eine lokale SQLite-Datenbank auf einen Ubuntu-System angelegt (nach Quelle: http://www.tatsch-it.de/fhem-dblog/)<br />
<ol><br />
<li>''Installation von SQLite:''<br />
<pre>sudo aptitude install sqlite3 libdbi-perl libdbd-sqlite3-perl</pre><br />
</li><br />
<li>''Anlegen der SQLite-Datenbank fhem.db'' (öffnet auch direkt eine SQL-Kommandozeile):<br />
<pre>sudo sqlite3 /opt/fhem/fhem.db</pre><br />
In der geöffneten SQL-Kommandozeile eingeben:<br />
<pre><br />
CREATE TABLE history (TIMESTAMP TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, DEVICE varchar(64), TYPE varchar(64), EVENT varchar(512), READING varchar(64), VALUE varchar(128), UNIT varchar(32));<br />
CREATE TABLE current (TIMESTAMP TIMESTAMP, DEVICE varchar(64), TYPE varchar(64), EVENT varchar(512), READING varchar(64), VALUE varchar(128), UNIT varchar(32));<br />
CREATE INDEX Search_Idx ON `history` (DEVICE, READING, TIMESTAMP);<br />
</pre><br />
Die Kommandozeile verlässt man mit <code>.exit</code>.<br />
</li><br />
<li>''Anpassen des Besitzers und der Rechte der Datenbank-Datei:''<br />
<pre><br />
sudo chown fhem /opt/fhem/fhem.db<br />
sudo chmod 600 /opt/fhem/fhem.db<br />
</pre><br />
</li><br />
<li>''Datenbank-Anbindung des FHEM konfigurieren:''<br />
<pre>sudo nano /opt/fhem/db.conf</pre><br />
Inhalt:<br />
<pre><br />
%dbconfig= (<br />
connection => "SQLite:dbname=/opt/fhem/fhem.db",<br />
user => "",<br />
password => ""<br />
);<br />
</pre><br />
</li><br />
<li>''Logging des FHEM auf die Datenbank konfigurieren:'' (hier sind nur die Anpassungen aufgeführt)<br />
<pre>sudo nano /opt/fhem/fhem.cfg</pre><br />
<pre><br />
...<br />
attr global userattr DbLogExclude ... # erlaubt es einzelne Einträge nicht zu loggen<br />
...<br />
define logdb DbLog ./db.conf .*:.* # logt alle(!) auflaufenden Events aller Konfigurationen<br />
...<br />
</pre><br />
Da durch diese <code>define</code>-Definition alle auflaufenden Events gelogt werden, müssen keine weiteren Anpassungen in der Konfiguration gemacht werden. Die FileLog-Einträge können bedenkenlos bestehen bleiben - dann wird in Datenbank und FileLog gelogt und man verliert keine Daten, falls etwas nicht klappt. Wenn alles wie geplant läuft, können die FileLog-Definitionen gelöscht werden (ebenso die Log-Dateien). Ebenso können die zu loggenden Daten später eingegrenzt werden (s. [[#Finetuning des Loggings]]).<br />
</li><br />
<li>''FHEM neu starten:''<br />
<pre><br />
sudo service fhem stop<br />
sudo service fhem start<br />
</pre><br />
</li><br />
<li>''Kontrollieren, ob Logs in die Datenbank geschrieben werden:''<br />
<pre>sudo sqlite3 /opt/fhem/fhem.db</pre><br />
In der geöffneten SQL-Kommandozeile eingeben:<br />
<pre><br />
select * from history order by TIMESTAMP; # dies gibt alle(!) Logs chronologisch aus (kann nach längerem Betrieb recht lange dauern)<br />
</pre><br />
Die Kommandozeile verlässt man mit <code>.exit</code>.<br />
</li><br />
<li>''Anpassung der glot-Dateien:'' siehe [[#Anpassen der gplot-Konfigurationen]]<br />
</li><br />
</ol><br />
<br />
== Beispiel: Anlegen und Nutzung einer Mysql-Datenbank ==<br />
Hierfür gibt es eine [[DbLog-MySQL|extra Seite]], die die Unterschiede und Feinheiten zwischen den verschiedenen Versionen berücksichtigt<br />
<br />
Anstatt nano kann jeder andere kompatible Editor verwendet werden. Weiterhin bitte beachten, dass die hier genannten Befehle teilweise root-Rechte voraussetzen. Entweder komplett als root arbeiten, oder mittels sudo.<br />
<br />
Unter Ubuntu/debian: <br />
apt-get update && apt-get install mysql-server mysql-client libdbd-mysql libdbd-mysql-perl<br />
<br />
<br />
Bei der Installation sollte man aus Sicherheitsgründen ein Passwort für den mysql-root vergeben, wenn man nicht sogar ganz den Login verbietet.<br />
<br />
Hinweis: im Folgenden ist "#" der normale Prompt und "mysql>" der prompt innerhalb mysql, dieser kann mit exit verlassen werden. <br />
<br />
Zum Test mal mit mysql verbinden:<br />
# mysql -p -u root<br />
Enter password:<br />
mysql> exit<br />
<br />
Jetzt die Tabellenstruktur anlegen. <br />
Hierfür kann die Datei /opt/fhem/contrib/dblog/db_create_mysql.sql als Vorlage verwendet und das Passwort und der Benutzername geändert werden. <br />
cd /opt/fhem/contrib/dblog/<br />
nano db_create_mysql.sql<br />
Dann wird die Datei eingelesen (root Passwort wird abgefragt): <br />
<br />
# mysql -u root -p < db_create_mysql.sql<br />
<br />
Jetzt kann man den Zugang testen: <br />
<br />
# mysql -p -u <fhemuser><br />
Enter password: <fhempassword><br />
mysql> show databases;<br />
<br />
Nun müsste eine Datenbank "fhem" angezeigt werden, die die Tabellen current und history enthält.<br />
<br />
Nun in der Datei db.conf den mysql-Block auskommentieren und ebenfalls Benutzername, Passwort UND HOST anpassen. Leider ist hier nicht standardmäßig localhost eingestellt.<br />
nano /opt/fhem/db.conf<br />
<br />
Jetzt kann unter FHEM ein DbLog-Device angelegt werden (mit dem beispiel wird alles geloggt: <br />
define logdb DbLog ./db.conf .*:.*<br />
Als State muss ein "connected" angezeigt werden. <br />
<br />
Ein rereadcfg in FHEM stellt sicher, dass die neue Konfiguration übernommen wird - ein Neustart ist nicht erforderlich.<br />
<br />
Nun kann die Funktion noch einmal überprüft werden: <br />
<syntaxhighlight lang="sql"><br />
# mysql -u <fhemuser> -p<br />
Enter password: <fhempassword><br />
mysql> use fhem;<br />
Database changed<br />
mysql> show tables;<br />
+----------------+<br />
| Tables_in_fhem |<br />
+----------------+<br />
| current |<br />
| history |<br />
+----------------+<br />
2 rows in set (0,00 sec)<br />
mysql> select * from history; # Achtung, kann sehr groß werden .... #<br />
</syntaxhighlight><br />
<br />
Anscheinend gibt es bei der neuen Version MariaDB (im Gegensatz zu mysql) ein neues Anmeldeverfahren, so dass in der Datenbank selbst Veränderungen vorgenommen werden müssen, damit der Zugriff durch FHEM funktioniert: https://kofler.info/root-login-problem-mit-mariadb/<br />
<br />
Die Daten im MySQL können auch für die längere Aufbewahrung partitioniert werden. Dabei wird pro Partition eine Datei erzeugt statt einer gemeinsamen Datei für alle Daten. Je nach Wunsch zum Beispiel partitioniert nach Jahr.<br />
<syntaxhighlight lang="sql"><br />
Alter table history PARTITION BY RANGE ( UNIX_TIMESTAMP(timestamp) ) (<br />
PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP('2019-01-01 00:00:00') ),<br />
PARTITION p1 VALUES LESS THAN ( UNIX_TIMESTAMP('2020-01-01 00:00:00') ),<br />
PARTITION p2 VALUES LESS THAN ( UNIX_TIMESTAMP('2021-01-01 00:00:00') ),<br />
PARTITION p3 VALUES LESS THAN ( UNIX_TIMESTAMP('2022-01-01 00:00:00') ),<br />
PARTITION p4 VALUES LESS THAN ( UNIX_TIMESTAMP('2023-01-01 00:00:00') ),<br />
PARTITION p5 VALUES LESS THAN ( UNIX_TIMESTAMP('2024-01-01 00:00:00') ),<br />
PARTITION p6 VALUES LESS THAN ( UNIX_TIMESTAMP('2025-01-01 00:00:00') ),<br />
PARTITION p7 VALUES LESS THAN (MAXVALUE) );<br />
</syntaxhighlight><br />
<br />
== Beispiel: Abfragescript PHP/MySQL ==<br />
Um eine schnelle Übersicht zu bekommen habe ich mir dieses Script geschrieben:<br />
<syntaxhighlight lang="php"><br />
<?php $pdo = new PDO('mysql:host=localhost;dbname=fhem', 'fhemuser', 'fhempasswort');<br />
echo '<h2>Tabelle Current</h1><br><table border="1">';<br />
echo "<tr><th>Anzahl</th><th>Name</th><th>Readings</th></tr>";<br />
$sql = "SELECT COUNT(*), DEVICE, GROUP_CONCAT(DISTINCT READING ORDER BY READING DESC SEPARATOR '</li><li>') FROM current GROUP BY DEVICE;"; foreach ($pdo->query($sql) as<br />
$row) {<br />
echo "<tr><td>" . $row[0] . "</td><td>" . $row[1] . "</td><td><ol><li>" . $row[2] . "</li></ol></td></tr>";<br />
}<br />
echo "</table>";<br />
<br />
<br />
echo '<h2>Tabelle History</h1><br><table border="1">';<br />
echo "<tr><th>Anzahl</th><th>Name</th></tr>";<br />
$sql = "SELECT COUNT(*), DEVICE FROM history GROUP BY DEVICE;"; foreach ($pdo->query($sql) as<br />
$row) {<br />
echo "<tr><td>" . $row[0] . "</td><td>" . $row[1] . "</td></tr>";<br />
}<br />
echo "</table>";<br />
?><br />
</syntaxhighlight><br />
<br />
Bitte passt ''fhemuser'' und ''fhempasswort'' an. Das Ganze kommt dann nach <code>/var/www/html/fhemdb.php</code> und ist mit <code><nowiki><IP>/fhemdb.php</nowiki></code> aufrufbar. Wenn ihr den zweiten Block für die history Tabelle ausklammert oder entfernt, läuft das Script viel schneller ab - klar die history Tabelle ist meist randvoll.<br />
<br />
== Integration von DBLog in eigene Module ==<br />
=== Bereitstellung der UNITS ===<br />
Mit der DbLog_splitFn kann der Modulautor selbst festlegen, wie die Events des Moduls in die Bestandteile Reading/Value/Unit zerlegt werden um ein korrektes Logging per DbLog zu gewährleisten.<br />
<br />
Dazu muss der Modulautor in der [[DevelopmentModuleIntro#X_Initialize|Initialize-Funktion]] eine <code>DbLog_splitFn</code> bereitstellen:<br />
<br />
<syntaxhighlight lang="perl"><br />
sub X_Initialize($)<br />
{<br />
my ($hash) = @_;<br />
...<br />
$hash->{DbLog_splitFn} = "X_DbLog_splitFn";<br />
}<br />
</syntaxhighlight><br />
<br />
Die genaue Aufrufsyntax und Funktionweise einer DbLog_split-Funktion findet man [[DevelopmentModuleIntro#X_DbLog_split|hier]].<br />
<br />
== Werte auslesen ==<br />
Manchmal möchte man Daten aus den Logs abrufen ohne händisch in der Datenbank herumzuwühlen (s.u.). Dies ist insbesondere auch dann hilfreich, wenn man eigene Funktionen, Notifys oder spezielle Plots entwirft, bei denen man auf Logdaten zugreifen möchte.<br />
<br />
Grundsätzlich beschrieben ist dies in der {{Link2CmdRef|Lang=de|Anker=DbLog}} und unterscheidet sich minimal (aber entscheidend) von der Struktur bei [[FileLog#Werte_auslesen|FileLogs]].<br />
<br />
Hier ein paar Beispiele, was man damit anstellen kann:<br />
<br />
* <code>get meineDB - - 2016-10-01 2016-10-03 meinSensor</code> alle Einträge des meinSensor vom 01.10.-03.10.2016<br />
* <code>get meineDB - - 2016-10-01_08:00:00 2016-10-01_16:00:00 meinSensor</code> alle Einträge des meinSensor von 8-16 Uhr am 01.10.2016<br />
* <code>get meineDB - - 2016-10-01_08:00:00 2016-10-01_16:00:00 meinSensor:temperature</code> nur die temperature Werte<br />
* <code>{ ReadingsTimestamp("meinSensor","state","0") }</code> Timestamp des aktuellen state des meinSensor<br />
* <code>{ OldTimestamp("meinSensor") }</code> Timestamp des letzten state des FHT_3a32<br />
* <code>{ time_str2num(OldTimestamp("meinSensor")) }</code> Timestamp in Sekunden des letzten state des meinSensor<br />
* ...<br />
<br />
== Bearbeitung von Datenbank-Einträgen ==<br />
{{Hinweis|Dieser Abschnitt soll lediglich eine kleine Einführung in die Datenbank-Bearbeitung liefern. Für vertiefende Informationen sollte man sich grundsätzlich mit SQL beschäftigen. Eine umfassende und gut verständliche Anleitung zu SQL bietet bspw. [http://www.w3schools.com/sql/default.asp w3schools].}}<br />
Irgendwann wird der Fall eintreten, dass in der Datenbank Einträge drinstehen, die geändert oder gelöscht werden sollen (zB. fehlerhafte Sensor-Rückmeldungen, umbenannte Readings). In klassischen Log-Dateien würde man diese einfach bearbeiten und löschen/anpassen (wobei man aber tunlichst zuvor FHEM stoppt, um Datenfehler zu vermeiden). Eine Datenbank kann bearbeitet werden, ohne FHEM stoppen zu müssen. <br />
<br />
Datenbanken kann man ohne weitere Hilfsmittel direkt von der Kommandozeile/Shell aus bearbeiten. Alternativ gibt es auch verschiedenste Tools (webbasiert oder als Applikation), die einen dabei unterstützen (Bsp. findet man u.a. [https://wiki.ubuntuusers.de/SQLite/#Grafische-Benutzeroberflaechen hier]). Für einfache Arbeiten reicht allerdings idR. Shell.<br />
<br />
=== SQLite-Datenbanken ===<br />
'''Öffnen der DB unter Linux:''' <br />
<br />
(Es werden Schreibrechte benötigt,ohne kann man die DB zwar öffnen, aber nichts machen)<br />
sudo sqlite3 fhem.db<br />
Dadurch öffnet sich ein SQL-Konsole, auf der alle weiteren Befehle ausgeführt werden.<br />
<br />
'''Schliessen der DB:'''<br />
<br />
sqlite> .exit<br />
<br />
<br />
'''Hilfe anzeigen:'''<br />
<br />
sqlite> .help<br />
<br />
<br />
'''Alle Tabellen anzeigen:'''<br />
<br />
sqlite> .tables<br />
<br />
<br />
'''Das Schema der DB anzeigen:''' <br />
<br />
(vgl. oben [[DbLog#Datenbanken]] und [[DbLog#Beispiel: Anlegen und Nutzung einer SQLite-Datenbank]])<br />
<br />
sqlite> .schema<br />
<br />
<br />
'''Alle Eintäge anzeigen:''' <br />
<br />
Die Einträge liegen alle in der Tabelle "History".<br />
<br />
'''Ganz wichtig''' ist immer das ";" am Ende Zeile (bei allen Kommandos, die nicht mit einem "." anfangen). Wenn es vergessen wurde zeigt die Konsole solange neue Zeilen bis ein ";" eingegeben wird. So kann ein Befehl auch bequem über mehrere Zeilen geschrieben werden.<br />
<br />
sqlite> select * from HISTORY;<br />
<br />
Dies kann sehr lange dauern und kann ggf. mit <code>STRG-C</code> abgebrochen werden.<br />
<br />
<br />
'''Alle Einträge eines Geräts anzeigen:'''<br />
<br />
In <code>where</code>-Statements werden Strings in einfache Anführungsstriche gesetzt, Zahlen nicht.<br />
<br />
sqlite> select * from HISTORY where DEVICE='Pollenflug';<br />
<br />
<br />
'''Alle Einträge eines Readings eines Geräts anzeigen:'''<br />
<br />
sqlite> select * from HISTORY where DEVICE='Pollenflug' and READING='Graeser';<br />
<br />
<br />
'''Alle Einträge eines bestimmten Wertes eines Readings eines Geräts anzeigen:'''<br />
<br />
sqlite> select * from HISTORY where DEVICE='Pollenflug' and READING='Graeser' and VALUE>1;<br />
<br />
<br />
'''LÖSCHEN aller Einträge eines bestimmten Wertes eines Readings eines Geräts anzeigen:'''<br />
<br />
'''Achtung:''' Löschen kann nicht rückgängig gemacht werden!! Also IMMER erst die entsprechenden SELECT-Statements solange verfeinern bis wirklich nur die gewünschten Einträge angezeigt werden. Dann das <code>select *</code> durch <code>delete</code> ersetzen.<br />
<br />
sqlite> delete from HISTORY where DEVICE='Pollenflug' and READING='Graeser' and VALUE>1;<br />
<br />
<br />
== Datenbank reparieren ==<br />
Es kann immer wieder mal vorkommen, dass Datenbanken Fehler enthalten. Das muss im Alltag garnicht auffallen und auch nicht immer schlimm enden. Wenn man auf der SQL-Konsole aber bspw. eine Meldung <code>Error: database disk image is malformed</code> erhält, sollte man ein Reparatur vornehmen.<br />
<br />
'''Hinweis:''' Ist ein DbRep-Device definiert, kann eine Reparatur einfach mit dem eingebauten Befehl '''set <name> repairSQlite''' ausgeführt werden.<br />
<br />
=== SQLite-Datenbanken ===<br />
Die folgenden Schritte beschreiben, wie man eine SQLite-DB reparieren kann (Quelle: [http://techblog.dorogin.com/2011/05/sqliteexception-database-disk-image-is.html]):<br />
<br />
<ol><br />
<li>DB öffnen:<br />
<pre>sudo sqlite3 fhem.db</pre><br />
</li><br />
<li>Integritäts-Check durchführen:<br />
<pre>sqlite> pragma integrity_check;</pre><br />
Kommt hier ein "ok" ist die DB gesund. Ansonsten erscheint etwas wie<br />
<pre><br />
*** in database main ***<br />
On tree page 118786 cell 1: Rowid 75 out of order (previous was 816660)<br />
On tree page 118786 cell 4: Rowid 815704 out of order (previous was 816727)<br />
Corruption detected in cell 0 on page 118786<br />
Multiple uses for byte 132 of page 118786<br />
...<br />
</pre><br />
</li><br />
<li>Datenbank-Dump erstellen (Export gesamten DB in die Datei "dump_all_20160516_1043.sql") und DB verlassen:<br />
<pre><br />
sqlite> .mode insert<br />
sqlite> .output dump_all_20160516_1043.sql<br />
sqlite> .dump<br />
sqlite> .exit<br />
</pre><br />
</li><br />
<li>Neue Datenbank erstellen und den Dump einlesen, Integritäts-Check machen und verlassen:<br />
<pre>sudo sqlite3 fhem-neu.db</pre><br />
<pre><br />
sqlite> .read dump_all_20160516_1043.sql<br />
sqlite> pragma integrity_check;<br />
ok<br />
sqlite> .exit<br />
</pre><br />
</li><br />
<li>Spätestens jetzt FHEM stoppen:<br />
<pre>sudo service fhem stop</pre><br />
</li><br />
<li>Alte DB sichern und neue aktivieren:<br />
<pre><br />
sudo mv fhem.db fhem.db.sv_20160516<br />
sudo mv fhem-neu.db fhem.db<br />
</pre><br />
</li><br />
<li>Kontrollieren, dass die neue DB die gleichen Rechte wie die alte DB hat (und ggf. korrigieren):<br />
<pre><br />
~/fhem$ ls -lha<br />
insgesamt 6,3G<br />
drwxr-xr-x 12 fhem root 4,0K Mai 16 11:07 .<br />
drwxr-xr-x 4 root root 4,0K Dez 25 17:50 ..<br />
...<br />
-rw-r--r-- 1 root root 1,4G Mai 16 11:04 fhem.db<br />
-rw-r--r-- 1 fhem root 2,6G Mai 16 10:59 fhem.db.sv_20160516<br />
...<br />
<br />
~/fhem$ sudo chown fhem:root fhem.db<br />
<br />
~/fhem$ ls -lha<br />
insgesamt 6,3G<br />
drwxr-xr-x 12 fhem root 4,0K Mai 16 11:07 .<br />
drwxr-xr-x 4 root root 4,0K Dez 25 17:50 ..<br />
...<br />
-rw-r--r-- 1 fhem root 1,4G Mai 16 11:04 fhem.db<br />
-rw-r--r-- 1 fhem root 2,6G Mai 16 10:59 fhem.db.sv_20160516<br />
...<br />
</pre><br />
</li><br />
<li>FHEM wieder starten (und natürlich kontrollieren):<br />
<pre>sudo service fhem start</pre><br />
</li><br />
</ol><br />
<br />
=== Hinweise für sehr große Datenbanken ===<br />
Wenn die SQLite-DB sehr groß wird, kann es sein, dass der oben beschriebene Weg nicht ohne manuelle Anpassungen funktioniert. Konkret war dies bei einem Nutzer für eine 15 GB große DB nicht möglich, der Prozess hat sich immer nach mehreren Stunden aufgehängt. Die Ursache liegt darin, dass ein Dump alle Daten in einer einzigen Transaktion einfügt. Das Problem kann man lösen, indem man den Dump in mehreren Transaktionen einfügt, also aufteilt. Konkret konnte eine 23GB große DB erfolgreich eingelesen und damit repariert werden, indem alle 10.000.000 Zeilen folgende 2 Zeilen eingefügt wurden:<br />
<pre>BEGIN TRANSACTION;<br />
COMMIT;<br />
</pre><br />
* Hinweis 1: Mit dem Editor joe kann man unter Linux auch sehr große Dateien flüssig bearbeiten, das Springen zu hohen Zeilennumer dauert trotzdem. <br />
* Hinweis 2: joe verwendet eine temporäre Kopie der Datei. Diese liegt per default unter /tmp. Der Ort kann aber auch durch <code>export TEMP=...</code> geändert werden. Falls also unter /tmp nicht Platz für eine Kopie des Datenbank-Dumps ist, sollte diese Variable vor dem Starten von joe entsprechend gesetzt werden. <br />
* Hinweis 3: Beim Speichern legt joe im gleichen Verzeichnis eine Sicherungskopie an, d.h. im Verzeichnis des Datenbank-Dumps sollte weiterer Platz in Höhe der Dateigröße frei sein. <br />
* Hinweis 4: Der reopen Mechanismus von DbLog kann verwendet werden, um eine manuelle Datenbankreparatur ohne Logunterbrechung durchzuführen (vor dem Wieder-Öffnen der DbLog Datei- und Verzeichnisrechte prüfen!). Damit kann man das harte Stoppen und Starten von FHEM in obiger Anleitung umgehen.<br />
* Letzter Hinweis: Weiter gilt: bei großen DbLog-Datenbanken sollte man immer darüber nachdenken,<br />
** Welche dieser Logdaten man wirklich braucht und im Zweifel per DbRep ausdünnen<br />
** Zu einer echten Datenbank wie MySQL/MariaDB zu wechseln.<br />
<br />
== Datenbank migrieren ==<br />
Eine schöne Anleitung zur Migration von SQLite zu MySQL/MariaDB mit Hilfe von [[DbRep - Reporting und Management von DbLog-Datenbankinhalten|DbRep]] findet sich hier: [https://demaya.de/fhem-umzug-sqlite-mysql-mariadb/].<br />
<br />
== Nützliche Codeschnipsel ==<br />
Anbei ein paar nützliche Codeschnipsel rund um DbLog<br />
<br />
<br />
=== Dateigrösse mitloggen ===<br />
Da die Datenbank ins Unermessliche wachsen kann, empfiehlt es sich - je nach Speicherplatz - ab einer bestimmten Grösse tätig zu werden. Dazu muss diese Grösse allerdings ermittelt werden. Diese geschieht mittels des Userreadings, welches man vorteilshafterweise mit im DbLog-device anlegt:<br />
<br />
<pre>attr myDbLog userReadings DbFileSize:reduceLogState.* { (split(' ',`du -m fhem.db`))[0] }</pre><br />
<br />
Mittels dieses Attributs wird die Grösse der .db-Datei immer nach dem Ausführen des ReduceLog in das Reading "DbFileSize" in ganzzahligen MByte abgelegt.<br />
<br />
Basierend auf diesem Reading können dann weitere Aktionen, beispielsweise ein Plot, erstellt werden.<br />
<br />
Die oben beschriebene Möglichkeit ist für SQLite verwendbar. Zur Ermittlung der DB-Größe andere DB-Typen (aber auch für SQLite nutzbar) kann wie [[DbRep_-_Reporting_und_Management_von_DbLog-Datenbankinhalten#Gr.C3.B6.C3.9Fe_der_FHEM-Datenbank_ermitteln | hier]] beschrieben vorgegangen werden.<br />
<br />
== Performance-Optimierung ==<br />
Auch eine Datenbank kann mit der Zeit langsamer werden. Dies hängt von mehreren Faktoren ab:<br />
* Menge der gelogten Daten (zB. > 4-5 GB)<br />
* Eingesetzte Hardware (zB. langsame SD-Karte vs. schnelle SSD)<br />
* Eingesetztes Datenbanksystem (zB. SQLite, MySQL)<br />
* Komplexität der Abfragen (zB. für aufwändige Graphen oder Berechnungen)<br />
<br />
Diese Punkte sollen im folgenden diskutiert werden:<br />
<br />
<br />
=== Komplexität der Abfragen ===<br />
Dies ist kein Problem der Datenbank, sondern rein der Abfrage. Dem entsprechend muss die Optimierung auch in der Abfrage oder im Skript gesucht werden. Dies ist nicht Ziel dieses Abschnittes und wird hier nicht weiter behandelt.<br />
<br />
<br />
=== Eingesetztes Datenbanksystem ===<br />
Welches Datenbanksystem eingesetzt wird (zB. SQLite oder MySQL) hat auf die Performance der Datenbank gar keinen so großen Einfluss, wie vielleicht zuerst gedacht. Selbst SQLite kann problemlos Datenbanken mit etlichen GB Größe performant verarbeiten. Der Flaschenhals ist hier viel mehr die darunter liegende Hardware (s.u.).<br />
<br />
Die Performance der Datenbank an sich, kann aber durch verschiedene Maßnahmen verbessert werden:<br />
* Pflegemaßnahmen bzgl. der Daten<br />
* '''Erstellung von Indizes'''<br />
<br />
<br />
==== Menge der Daten und Pflegemaßnahmen bzgl. der Daten ====<br />
Die Menge der geloggten Daten hat natürlich Einfluss auf die Geschwindigkeit von Abfragen - je mehr Daten vorhanden sind, desto mehr Daten müssen auch durchforstet werden um eine Abfrage zu bedienen. Die Reduzierung der geloggten Datenmenge hat also direkten Einfluss auf die Größe und damit auch die Geschwindigkeit der Datenbank. Die Menge der zu loggenden Daten lässt sich an zwei Stellen einschränken:<br />
* bei der Definition jedes Devices (s. Kapitel oben)<br />
* bei der Festlegung des FHEM-weiten Log-Levels (s. [[Loglevel]])<br />
<br />
Die Menge der bereits geloggten Daten kann zB. mit Hilfe von [[DbRep - Reporting und Management von DbLog-Datenbankinhalten|DbRep]] verringert und optimiert werden, bspw.<br />
* löschen unnötiger Daten<br />
* vacuum der Datenbank<br />
<br />
Insgesamt haben diese Maßnahmen aber nur einen eingeschränkten Effekt auf die Performance der DB. Deutlich effektiver ist die Erstellung eines Index (s.u.).<br />
<br />
<br />
==== Erstellung von Indizes ====<br />
Die Erstellung von Indizes hat mit Abstand den größten Einfluss auf die Performance einer Datenbank (auf unveränderter Hardware). Extrem zusammengefasst ist ein Index eine extrem optimiertes Nachschlageverzeichnis für einen bestimmten Typ Daten (ein Index wie im Buch halt). Eine wunderbare Einführung in Indizes bietet [[https://use-the-index-luke.com/de|https://use-the-index-luke.com]].<br />
<br />
In FHEM sind Indizes sogar sehr einfach einzurichten da die Datenbank-Nutzung sehr stark vorgegeben ist. Nahezu jede Abfrage folgt dem Schema ''Device -> Reading -> Datum -> Wert''. Ein Index kann genau diese Abfrage bedienen und beschleunigen. Ein Index nur über die Devices wäre ein erster Schritt, brächte aber noch keinen großen Gewinn (wie um Link oben gut beschrieben). Über die gesamten ersten drei Schritte erstellt (Device -> Reading -> Datum) bringt der Index aber sofort eine deutliche Geschwindigkeitssteigerung.<br />
<br />
Die Erstellung eines Index erfolgt direkt in der Datenbank (und nicht aus FHEM heraus), hier am Beispiel einer SQLite-DB:<br />
<br />
Öffnen der DB:<br />
<pre> sudo sqlite3 fhem.db </pre><br />
<br />
Erzeugen des Index auf der DB-Konsole (das Semikolon am Ende ist wichtig):<br />
<pre> create index idx_device_reading_timestamp on history (device, reading, timestamp); </pre><br />
<br />
Verlassen der DB:<br />
<pre> .exit </pre><br />
<br />
Einzig zu berücksichtigen ist, dass dieser Index die Datenbank um bis zu 1/3 vergrößert. Er kann aber bei Bedarf auch wieder entfernt werden. Bei meiner 15 GB SQLite-Datei (auf einem Mac Mini mit SSD) hat dies ca. 15 min gedauert (den FHEM hatte ich vorsichtshalber währenddessen deaktiviert).<br />
<br />
Sollte jemand spezielle Berechnungen oder Skripte ausführen, die nach einem anderen Abfrage-Schema arbeiten, könnte man dafür spezialisierte zusätzliche Indizes erstellen. Das sollte aber dann mit dem Wissen des obigen Links erarbeitet werden, da dann etwas mehr Hintergrundwissen sehr hilfreich ist.<br />
<br />
==== DB-Backup ====<br />
Ein anderer Aspekt, der eigentlich nichts mit der Performance der DB zu tun hat, ist der Einfluss aufs Backup. Wird bspw. ein Systembackup per RSYNC gemacht, muss bei SQLite immer die komplette ggf. riesige Datei gesynct werden - bei MySQL würden nur die veränderten DB-Elemente gesynct. Dies soll hier nicht weiter vertieft werden, sollte aber bei einer Gesamtstrategie bedacht werden.<br />
<br />
<br />
=== Eingesetzte Hardware ===<br />
FHEM hat grundsätzlich sehr viele kleine Datenzugriffe, unabhängig davon ob FileLog oder DbLog eingesetzt wird. Deshalb ist der absolut größte Performance-Gewinn durch den Einsatz schneller Festplatten zu erreichen - ganz einfache Aussage: ''je schneller desto besser ;-)''. Konkret bietet eine SSD mit mind. 250MB/s Datenzugriff eine ordentliche Basis für jedes datengestützte System, wie den FHEM.<br />
<br />
Wenn die Datenmenge größer und die Abfragen komplexer werden, müssen natürlich irgendwann auch die Prozessorleistung und der Arbeitsspeicher mit wachsen. Aber auch an einem Raspi wird eine SSD deutlich performanter sein, als eine einfache SD-Karte oder eine klassische rotierende Festplatte.<br />
<br />
== Links ==<br />
* [[Heizleistung_und_Gasverbrauch|Beispiel das DbLog-Daten für SVG-Plots verwendet]]<br />
* [[SVG-Plots von FileLog auf DbLog umstellen]]<br />
* Manchmal bereitet die Engine von mysql auf einem Raspberry Probleme: [https://forum.fhem.de/index.php/topic,131164.msg1253589.html#msg1253589|Link zum Forum]<br />
<br />
[[Kategorie:Logging]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=HM-CC-RT-DN_Funk-Heizk%C3%B6rperthermostat&diff=37823HM-CC-RT-DN Funk-Heizkörperthermostat2022-12-19T02:47:12Z<p>Andies: /* HM-CC-RT-DN spezifische Update Informationen */ siehe Forum</p>
<hr />
<div>{{Infobox Hardware<br />
|Bild=HM-CC-RT-DN.jpg<br />
|Bildbeschreibung=HM-CC-RT-DN an Heizkörper montiert<br />
|HWProtocol=[[HomeMatic]]<br />
|HWType=[[HomeMatic Type Thermostat|thermostat]]<br />
|HWCategory=[[:Kategorie:Heizungsventile|Heizungsventile]]<br />
|HWComm=868 MHz<br />
|HWChannels=6<br />
|HWVoltage=3&nbsp;V<br />
|HWPowerConsumption=180&nbsp;mA<br />
|HWPoweredBy=2x LR6/Mignon/AA<br />
|HWSize=54x65x93 mm (BxHxT)<br />
|HWDeviceFHEM=[[CUL_HM]]<br />
<!-- |ModOwner= --><br />
|HWManufacturer=ELV / eQ-3<br />
}}<br />
'''HM-CC-RT-DN''' (häufig einfach '''RT''' genannt) ist ein Funk-''Heizkörperthermostate'' mit integriertem ''Stellantrieb''. Das Thermostat ist seit September 2013 verfügbar und ist der Nachfolger des [[HM-CC-VD Funk-Stellantrieb]]s.<br />
<br />
== Vorbemerkungen ==<br />
: ''→ Einstellungen und Informationen, die alle [[HomeMatic]] Thermostate betreffen, sind unter [[HomeMatic Type Thermostat#Temperaturlisten|HomeMatic Type Thermostat]] zu finden.''<br />
<br />
Der HM-CC-RT-DN kann die Temperatur selbst messen (im Gegensatz zum [[HM-CC-VD Funk-Stellantrieb|Vorgänger]]) und verfügt über eine Fenster-Offen-Erkennung sowie eine Boost-Funktion. Der HM-CC-RT-DN ''kann'' von einem [[HM-TC-IT-WM-W-EU Funk-Wandthermostat AP]] gesteuert werden, das ist aber ''optional''.<br />
<br />
Das Gerät wird seit Anfang Oktober 2013 von FHEM unterstützt (siehe Diskussion im {{Link2Forum|Topic=14738|LinkText=Forum}}).<br />
<br />
Der HM-CC-RT-DN scheint das erste HomeMatic-Device zu sein, bei dem ein Update der Firmware auch vom Anwender durchgeführt werden kann. Ein Firmware-Update erfordert einen [[HM-CFG-USB_USB_Konfigurations-Adapter|USB Konfigurations-Adapter]] und eine auf der eQ-3 Webseite herunterladbare Firmwareupdate-Software. Weitere Details sind unter [[#Firmware Update|Firmware Update]] beschrieben.<br />
{{Hinweis|Die Solltemperaturen eines HM-CC-RT-DN lassen sich ''nicht'' durch einen [[HM-CC-TC Funk-Wandthermostat]] ''steuern''. Dieser kann nur die Ist-Temperatur an den HM-CC-RT-DN weitergeben, damit nicht die am HM-CC-RT-DN direkt gemessene Raumtemperatur zur Regelung verwendet wird.}}<br />
Mit einem HM-CC-RT-DN können maximal (neben der Zentrale/FHEM):<br />
* 7 HomeMatic Heizkörperthermostate<br />
* 8 HomeMatic Tür-Fensterkontakte / Fenster-Drehgriffkontakte<br />
* 8 Tastenpaare von HomeMatic Fernbedienungen bzw. Display-Wandtaster<br />
* 1 HomeMatic Innen-Temperatur-Sensor<br />
[[Peering (HomeMatic)|gepeert]] werden.<br />
<br />
{{Hinweis|Wird für Wartungs-/Umbaumaßnahmen das Wasser der Heizung abgelassen bzw. diese neubefüllt, sind alle Stellantriebe manuell dauerhaft auf '''on''' zu setzen: set <HM_Stellantrieb>_Clima controlManu on. Beim Einsatz eines Wandthermostaten ist der Wandthermostat entsprechend einzustellen.}}<br />
<br />
== Technische Daten ==<br />
* Betriebsspannung: 2 Stck. 1,5V LR6/Mignon/AA<br />
* Stromaufnahme: 180 mA max.<br />
* Abmessungen (B x H x T): 54 x 65 x 93 mm<br />
* Gewicht: 180 g (ohne Batterien)<br />
* Ventilanschluss: M30 x 1,5 mm<br />
<br />
Aktuelle Firmware: 1.5 (2020)<br />
<br />
== Betrieb mit FHEM ==<br />
Der Funk-Heizkörperthermostat muss zuerst mit FHEM [[Pairing (HomeMatic)|gepairt]] werden. Stellen Sie sicher, dass FHEM aktuell ist ([[update]] durchführen)<br />
<br />
Das Pairing sollte wie in [[HomeMatic Devices pairen]] beschrieben durchgeführt werden (mittlere Taste mindestens drei Sekunden drücken, um den Vorgang auszulösen). Vereinzelt muss mehrfach gepairt werden, es wurde auch berichtet, dass dabei die Batterie zwichendurch entfernt und neu eingelegt werden muss.<br />
<br />
=== Channels (Kanäle) ===<br />
==== Channel (Kanal) 01 _Weather ====<br />
<br />
Dieser Kanal dient zur Einspeisung der (gemessenen) ''Ist-Temperatur''. Als Sensor können zum Beispiel das [[HM-TC-IT-WM-W-EU Funk-Wandthermostat AP|HM-TC-IT-WM-W-EU Funk-Wandthermostat]] oder ein [[HM-WDS40-TH-I Funk-Temperatur-/Feuchtesensor innen (IT)|HM-WDS40-TH-I Funk-Temperatur-/Feuchtesensor]] dienen.<br />
<br />
Ein Temperatur-Sensor ''tempSensor'' kann mit dem ''_Weather''-Kanal wie folgt [[Peering (HomeMatic)|gepeert]] werden: <br />
<br />
set <HM-TC-IT-WM-W-EU>_Weather peerChan 0 <HM-CC-RT-DN>_Weather single set<br />
<br />
Beispiel:<br />
set EG_Buero_WANDTHERMOSTAT_Weather peerChan 0 EG_Buero_THERMOSTAT_Weather single set<br />
<br />
ACHTUNG: Das Wandthermostat sowie das Thermostat Ventil (Beispiel "EG_Buero_WANDTHERMOSTAT" und EG_Buero_THERMOSTAT) werden vorher in FHEM den Status "CMDs_done" anzeigen.<br />
Beim peerChan wird dann bei beiden "CMDs_pending" stehen. Wobei das Wandthermostat sehr schnell wieder auf CMDs_done zurück springt.<br />
Allerdings ist dringend darauf zu achten, dass das Thermostat Ventil auch wieder auf "CMDs_done" wechselt, bevor man den nächsten Befehl absendet.<br />
Das Heizkörper Ventil kann unter Umständen 3 bis 5 min benötigen bis wieder "CMDs_done" steht. Evtl. kann man dies durch die BOOST Taste beschleunigen. Da das Ventil etwa alle 3 min aufwacht, prüft und Daten sendet / empfängt. Sollte man mit dem Befehlen weiter gemacht haben, so kann es zu dem Problem führen, dass einer nicht mehr mit dem Pending aufhört. In dem Fall empfiehlt es sich beide Devices von FHEM abzumelden und auf Werkseinstellung zu resetten. <br />
<br />
Zum Test haucht man das Wandthermostat an oder hält es einige Zeit in der Hand bis die Temperatur steigt, nach etwa 3 Minuten sollte man auch am Thermostat Ventil einen Temperaturanstieg sehen.<br />
<br />
==== Channel (Kanal) 02 _Climate ====<br />
Dieser Kanal erlaubt es dem [[HM-TC-IT-WM-W-EU Funk-Wandthermostat AP|HM-TC-IT-WM-W-EU Funk-Wandthermostat]] den HM-CC-RT-DN zu steuern. Dazu müssen die beiden Geräte gepeert werden:<br />
<br />
set <HM-TC-IT-WM-W-EU>_Climate peerChan 0 <HM-CC-RT-DN>_Climate single set<br />
<br />
==== Channel (Kanal) 03 _WindowRec ====<br />
Mit diesem Kanal können Fensterkontakte ([[HM-SEC-SC Tür-Fensterkontakt|HM-SEC-SC]] und [[HM-Sec-RHS Funk-Fenster-Drehgriffkontakt|HM-SEC-RHS]]) ihren Fensterstatus (geöffnet / gekippt) an ein oder mehrere Thermostate senden. Die Thermostate stellen anschließend die entsprechende (konfigurierbare) Temperatur ein. Der Temperaturwert kann je Fenster-Sensor unterschiedlich definiert werden. Sind mehrere Fenster gleichzeitig geöffnet, so wird der Thermostat auf die Temperatur des Sensors mit dem geringsten Temperaturwert eingestellt. <br />
Ferner wird empfohlen, bei Einsatz von externen Sensoren, die interne „Fenster auf Erkennung“ zu deaktivieren (weitere Details sind im [[HM-CC-RT-DN Funk-Heizkörperthermostat#Channel .28Kanal.29 04 _Clima|Channel (Kanal) 04 _Clima]] beschrieben).<br />
<br />
Der Befehl zum Peeren lautet, wobei <fensterSensor> die FHEM-Kanalbezeichnung für den Fensterkontakt ist und <rt_WindowRec> die Kanalbezeichnung für den entsprechenden Kanal des Heizkörperthermostates (siehe {{Link2Forum|Topic=41541|LinkText=diesen Thread}}):<br />
set <fensterSensor> peerChan 0 <rt_WindowRec>_WindowRec single <br />
<br />
Zum Löschen (=unpeeren) dieser Kopplung:<br />
set <fensterSensor> peerChan 0 <rt_WindowRec>_WindowRec single unset<br />
<br />
'''Achtung''': Der Peer-(Lösch-)Vorgang muss erst am Fensterkontakt durch Drücken der Anlerntaste ausgelöst werden, und zwar auch dann, wenn der Fensterkontakt schon vorher mit FHEM gepairt wurde. Dann kann der oben genannte Befehl in FHEM abgesetzt werden. Wichtig scheint auch, dass der Fensterkontakt geschlossen ist wenn man die Anlerntaste drückt.<br />
<br />
Der Befehl zur Temperatureinstellung des Heizkörperthermostaten für den Zustand "Fenster offen" lautet, wobei <fensterSensor> die FHEM-Kanalbezeichnung für den Fensterkontakt ist und <rt_WindowRec> die Kanalbezeichnung für den entsprechenden Kanal des Heizkörperthermostates, sowie <Temp> die einzustellende Temperatur (ganzzahliger Wert):<br />
set <rt_WindowRec>_WindowRec regSet winOpnTemp <Temp> <fensterSensor><br />
<br />
Weitere Hinweise im Forum, siehe {{Link2Forum|Topic=41541|Message=348044|LinkText=FHEM Forum-Beitrag}}<br />
<br />
==== Channel (Kanal) 04 _Clima ====<br />
Dieser Kanal dient zum Einstellen der Betriebsparameter, auch [[#Temperaturlisten|Temperaturlisten]] sind hierauf zu übertragen.<br />
Mit dem Modul [[Weekprofile|Wochenplan / Weekprofile]] können die Wochenpläne komfortabel in FHEM erstellt und an die Thermostate übertragen werden.<br />
<br />
{{Hinweis|In älteren Versionen von FHEM wurde dieser Kanal durch ''autocreate'' als <code>_ClimRT_tr</code> angelegt. Der Hersteller hat hier offenbar die internen Bezeichnungen geändert, denn beim Vorläufermodell HM-CC-TC mussten Temperaturlisten auf den Kanal ''Climate'' übertragen werden.}}<br />
<br />
Die maximale Öffnung des Ventils kann mittels folgendem Befehl eingestellt werden (hier auf 80 %):<br />
set <HM-CC-RT-DN>_Clima regSet valveMaxPos 80<br />
<br />
Die interne "Fenster-auf"-Erkennung kann man wie folgt abschalten:<br />
set <HM-CC-RT-DN>_Clima regSet winOpnMode off<br />
<br />
==== Channel (Kanal) 05 _ClimaTeam ====<br />
Dieser Kanal erlaubt es mehrere HM-CC-RT-DN zu einem "Team" zu gruppieren. Ein Mitglied des Teams meldet<br />
* Änderungen der Temperatur am Handrad<br />
* Einschalten des Boost-Modus am Taster<br />
an seine "Teamkollegen" weiter. Folgende Änderungen werden '''nicht''' weitergegeben:<br />
* Status der Fensterkontakte<br />
* Temperaturlisten/Wochenplan und daraus folgende Änderungen<br />
* Änderungen durch Fernbedienungen<br />
* Änderungen durch eine HomeMatic-Zentrale<br />
<br />
Befehl zum Peeren, wobei ''<HM-CC-RT-DN#1>_ClimaTeam'', ''<HM-CC-RT-DN#2>_ClimaTeam'', ..., ''<HM-CC-RT-DN#8>_ClimaTeam'' die Kanalbezeichnungen der jeweiligen ClimaTeam-Kanäle sind:<br />
set <HM-CC-RT-DN#1>_ClimaTeam peerChan 0 <HM-CC-RT-DN#2>_ClimaTeam single<br />
set <HM-CC-RT-DN#1>_ClimaTeam peerChan 0 <HM-CC-RT-DN#3>_ClimaTeam single<br />
set <HM-CC-RT-DN#2>_ClimaTeam peerChan 0 <HM-CC-RT-DN#3>_ClimaTeam single<br />
...<br />
<br />
==== Channel (Kanal) 06 _remote ====<br />
Dieser Kanal kann an eine Fernbedienung gekoppelt werden. Per Tastendruck kann man einen bestimmten Mode und/oder eine bestimmte Temperatur wählen. Dabei kann die Reaktion auf einen langen oder kurzen Tastendruck gesondert eingestellt werden.<br />
<br />
Der Befehl zum Peeren lautet, wobei <button> die Kanalbezeichnung der Fernbedienung und <rt-remote> die Kanalbezeichnung des Heizkörperthermostates ist:<br />
set <nowiki><button> peerChan 0 <HM-CC-RT-DN>_remote single</nowiki><br />
<br />
=== Betriebsmodus Auto, Manu, Party (Urlaub) ===<br />
<br />
Der HM-CC-RT-DN verfügt über drei Betriebsmodus: Auto, Manu (Manuell) und Party (Urlaub). <br />
<br />
==== Modus Auto ====<br />
Das Gerät arbeitet gemäß des gespeicherten Wochenprogramms. Manuelle Änderungen sind möglich, werden aber beim nächsten Schaltpunkt überschrieben.<br />
<br />
==== Modus Manu ====<br />
Die Temperatur wird manuell eingestellt, das Wochenprogramm wird nicht abgearbeitet. "Manuell Einstellen" bedeutet entweder am Handrad oder durch Übermittlung eines "set desired temp"-Befehls von FHEM (oder equivalent von einer CCU).<br />
<br />
==== Modus Party (Urlaub) ====<br />
Die eingestellte Temperatur gilt bis zu einem gegebenen Endzeitpunkt, anschließend wechselt das Thermostat in den ''Auto''-Modus. <br />
<br />
==== Welchen Modus nutzen? ====<br />
Im Umfeld von FHEM sind alle drei Modi einsetzbar. Betrieb in "Auto" hat den Vorteil, dass bei Ausfall der FHEM-Instanz der Thermostat trotzdem noch die eingespeicherten Wochenprogramme abarbeitet. Nachteilig ist aber, dass die Steuerung komplexer wird, weil sowohl die Einstellungen am Thermostat als auch Schaltbefehle von FHEM das Verhalten beeinflussen. Vielfach wird daher im Umfeld von FHEM der Modus "Manu" benutzt, hier wird die Temperatur nur per einzelnem FHEM Schaltbefehl gesteuert, ausgelöst z.b. durch "at" Kommandos, Anwesenheitserkennung oder Bewegungsmelder. Sollte FHEM (oder die Funkverbindung) ausfallen, bleibt der Thermostat allerdings auf der letzten eingestellten Temperatur stehen.<br />
<br />
Denkbar ist auch, den Modus "Auto" zu verwenden und dann die Steuerung per FHEM dadurch durchzuführen, dass durch FHEM die Wochenprogramme verändert werden. Dies verbindet zwar die Vorteil der vorgenannten Methoden, ist aber am Aufwendigsten in der Programmierung und erzeugt die höchste Funklast.<br />
<br />
Auch der Urlaubsmodus ist einsetzbar, so kann beispielsweise bei Abwesenheit ein niedrigeres Temperaturprofil eingestellt werden, ohne dass eventuell vorhandene Temperaturlisten verändert werden müssen.<br />
<br />
set <HM-CC-RT-DN>_Clima controlParty 16 06.12.13 16:30 09.12.13 05:00<br />
<br />
Dadurch wird <br />
* von 06.12.2013, 16:30 Uhr<br />
* bis 09.12.2013, 05:00 Uhr <br />
* die gewünschte Raumtemperatur auf 16 °C eingestellt.<br />
<br />
{{Hinweis|<br />
* Der Befehl muss auf dem Kanal 4 ''(_Clima)'' erfolgen.<br />
* Es werden nur Uhrzeiten zu jeder vollen oder halben Stunde angenommen (Minuten also 00 oder 30).}}<br />
<br />
Mit der folgenden Funktion <code>Urlaub()</code> kann man eine ganze Wohnung (also mehrere RTs) mit nur einem Befehl in den Party-Modus versetzen. Im Beispiel werden zwei Heizkörper ("Treppenhaus" und "Kammer") angesteuert.<br />
<br />
Zu beachten sind folgende Dinge:<br />
# Aktuelle Dateien (z.B. <code>10_CUL_HM</code>) verwenden!<br />
# Bei dem ''controlParty''-Befehl ''kein'' Komma zwischen den Parametern.<br />
# Bei der Funktion die Parameterübergabe definieren <code>($$$$$)</code><br />
<br />
'''Aufruf:'''<br />
:<code>{Urlaub ("16", "06.12.13", "16:30", "09.12.13" ,"05:00")}</code><br />
<br />
'''Funktion:'''<br />
<syntaxhighlight lang="perl"><br />
my $Urlaub;<br />
sub<br />
Urlaub($$$$$)<br />
{<br />
my ($temp, $startDate, $startTime, $endDate, $endTime) = @_;<br />
<br />
# HM-CC-RT-DN akzeptiert nur Zeiten, die auf Minute 00 oder 30 enden.<br />
# Daher $startTime und $endTime abrunden<br />
$startTime =~ s/\:[0-2].$/:00/;<br />
$startTime =~ s/\:[3-5].$/:30/;<br />
$endTime =~ s/\:[0-2].$/:00/;<br />
$endTime =~ s/\:[3-5].$/:30/;<br />
<br />
# controlParty bei jedem HM-CC-RT-DN setzen.<br />
for my $rt (qw(Kammer Treppenhaus)) {<br />
fhem ("set $rt controlParty $temp $startDate $startTime $endDate $endTime");<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
=== Tastensperre ===<br />
<br />
Um zu verhindern, dass der Modus oder die Temperatur per Tasten bzw. Drehrad am HM-CC-RT-DN verändert wird, kann eine Tastensperre gesetzt werden. Dies erfolgt mittels des Befehls:<br />
<br />
set <HM-CC-RT-DN> regSet btnLock on<br />
<br />
Rückgängig machen geht per:<br />
<br />
set <HM-CC-RT-DN> regSet btnLock off<br />
<br />
Diese Tastensperre kann man aber am HM-CC-RT-DN durch eine Tastenkombination wieder zurücksetzen. Um sie nur per FHEM rücksetzen zu können, muss<br />
<br />
set <HM-CC-RT-DN> regSet globalBtnLock on<br />
<br />
eingegeben werden. Rückgängig geht wieder per:<br />
<br />
set <HM-CC-RT-DN> regSet globalBtnLock off<br />
<br />
Es gibt auch eine Tastensperre die nur das Umschalten des Modus (Auto, Manuell, Urlaub) am Gerät verhindert. Diese wird mit<br />
<br />
set <HM-CC-RT-DN> regSet modusBtnLock on<br />
<br />
eingeschaltet. Abschalten geht mit:<br />
<br />
set <HM-CC-RT-DN> regSet modusBtnLock off<br />
<br />
=== Burst-Modus ===<br />
Das ist ein '''Übertragungs'''modus für Nachrichten zwischen HM-Geräten und der Zentrale. Der RT erwacht alle 2,5 Minuten und dann überträgt die Zentrale die Kommandos. Wenn man einen Fensterkontakt oder eine Fernsteuerung nutzt, muss der RT sofort reagieren - dann muss man den Burst ''enablen''. Der RT kann in diesem Fall sofort aufgeweckt werden und bearbeitet die Anforderung (Request). Das kann man auch von der Zentrale aus nutzen (so man möchte). Das ist der '''Vorteil''' des eingeschalteten Burst-Modus.<br />
<br />
'''Nachteil:''' Der Burst-Modus benötigt mehr Leistung, das heißt die Batterien müssen häufiger gewechselt werden: Der RT muss den Receiver ständig empfangsbereit halten. Außerdem wachen bei jedem Burst ''alle'' Burst-Empfänger auf – egal an wen die Kommunikation gerichtet war.<br />
<br />
'''Burst – wie es funktioniert'''<br />
<br />
Schickt ein Sender eine burst Sequenz, wachen alle burst-Empfänger auf und prüfen die Message. <br />
Wenn sie betroffen sind bleiben sie eine Zeit lang wach, ansonsten schlafen sie wieder ein. <br />
Man beachte also, dass Senden eines Burst Energie in ALLEN burst-Empfängern verbraucht, egal ob sie angesprochen sind.<br />
<br />
'''HMLAN und burst'''<br />
<br />
[[HMLAN]] hat ein Sendebudget das über eine Stunde berechnet wird. Burst belastet dieses Konto deutlich - so können nicht mehr als 100 bursts /h gesendet werden - dann geht HMLAN in overload. Wenn zusätzliche Nachrichten gesendet werden sind es entsprechend weniger. <br />
Es ist nicht vorteilhaft, unnötig bursts zu senden.<br />
<br />
'''Burst devices'''<br />
<br />
Es gibt Devices, die immer auf burst reagieren und solche bei denen es abgeschaltet werden kann. So reagiert ein Rauchmelder immer auf Burst damit er seine Team-Kollegen hören kann. <br />
Ein TC oder RT hingegen hat diese Funktion abschaltbar. 'Per default ist dies ausgeschaltet um Batterie zu sparen'. Wenn ein VD gesteuert wird ist der TC ja selbst wach. Wird er aber mit einem Fensterkontakt gekoppelt muss es eingeschaltet werden – sonst verpasst er die Nachricht. <br />
<br />
'''ConditionalBurst devices'''<br />
<br />
Devices mit abschaltbarem Burst wie z.B. der ''HM-CC-RT-DN'' haben ein Register, ''burstRx'', mit dem das burst-Erwachen eingestellt werden kann. <br />
Sendern, die einen burst-Aktor erwecken sollen, muss man sagen, welcher Peer Burst benötigt. Hier kann ggf. das Register ''peerNeedsBurst'' nach dem Peeren gesetzt werden. FHEM versucht dies automatisch beim Peeren zu erledigen. Siehe [[HMInfo]] Befehl ''models'' um herauszufinden, welche Devices welchen Modus unterstützen.<br />
<br />
'''Attribut burstAccess''' <br />
<br />
Devices, die abschaltbaren burst haben kann man ein attribut burstAccess 1_auto setzen. Es wird beim Abschicken eines Kommandos versucht, das Device mit burst zu wecken. Sollte es nicht funktionieren wird gewartet, bis das Device aufwacht (meist reagieren solche Devices auch auf wakeup). Das Setzen des Attributs ist angenehm – es werden aber ggf. viele bursts gesendet.<br />
<br />
'''Kommando burstXmit'''<br />
<br />
Mit diesem Kommando, das bei Devices mit conditional-Burst zu Verfügung steht, wird der burst gezielt vom User angestoßen.<br />
<br />
Der User schickt erst seine Kommandos an das device. Die Kommandos werden im Command-stack gesammelt. <br />
<br />
Dann sendet der User ein set burstXmit.<br />
<br />
Es passiert das gleiche wie bei burstAccess.<br />
<br />
FHEM versucht mittels burst zu wecken und sendet bei Erfolg die Messages aus dem Kommandostack. <br />
<br />
Im Gegensatz zu burstAccess ist burstXmit gezielt einsetzbar und kann sparsamer verwendet werden.<br />
<br />
''' FHEM und burst devices'''<br />
<br />
FHEM sendet eine burst automatisch mit Kommandos zu Devices, die nur burst unterstützen.<br />
<br />
'''So aktiviert man den burst-Betrieb am HM-CC-RT-DN'''<br />
<br />
''Burst Mode einschalten'' (der Kanal 4 des Device WZ1 heisst hier WZ1_4)<br />
:<code>set WZ1_4 regSet burstRx on </code><br />
prüfen mit:<br />
:<code>get WZ1_4 reg burstRx </code><br />
''Nun in FHEM den Burst mode einschalten (sofern nicht burstXmit verwendet wird)''<br />
:<code>attr WZ1 burstAccess 1_auto</code><br />
<br />
Hinweis: Das Attribut im Device und nicht im Kanal setzen, ansonsten gibt es eine Fehlermeldung.<br />
<br />
=== Temperaturlisten ===<br />
Die Temperaturlisten des HM-CC-RT-DN werden identisch mit denen anderer HomeMatic Thermostate verwaltet (siehe [[HomeMatic Type Thermostat#Temperaturlisten|HomeMatic Type Thermostat]]). Beim HM-CC-RT-DN ist der Kanal 4 (_Clima) für die Temperaturlisten zuständig.<br />
<br />
==FHEM-Log==<br />
In den folgenden Logs heißt Kanal 4 noch "_ClimRT_tr". Inzwischen würde man dort "_Clima" sehen.<br />
<br />
=== Device-Log ===<br />
2013.10.10 20:03:24 3: CUL_HM Unknown device CUL_HM_HM_CC_RT_DN_2212BC, please define it<br />
2013.10.10 20:03:24 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC CUL_HM 2212BC A1A0184002212BC0000001000954B4551303531303031375900FFFF<br />
2013.10.10 20:03:24 3: Device CUL_HM_HM_CC_RT_DN_2212BC added to ActionDetector with 000:10 time<br />
2013.10.10 20:03:24 3: CUL_HM pair: CUL_HM_HM_CC_RT_DN_2212BC thermostat, model HM-CC-RT-DN serialNr KEQ0510017<br />
2013.10.10 20:03:24 3: LANCUL pairing (hmPairForSec) not enabled<br />
2013.10.10 20:03:24 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC-%Y.log CUL_HM_HM_CC_RT_DN_2212BC<br />
2013.10.10 20:03:24 3: Device Heizung_Wohnzimmer added to ActionDetector with 000:10 time<br />
2013.10.10 20:03:24 3: CUL_HM pair: Heizung_Wohnzimmer thermostat, model HM-CC-TC serialNr JEQ0044286<br />
2013.10.10 20:03:24 3: Device CUL_HM_HM_CC_RT_DN_2212BC added to ActionDetector with 000:10 time<br />
2013.10.10 20:03:24 3: CUL_HM pair: CUL_HM_HM_CC_RT_DN_2212BC thermostat, model HM-CC-RT-DN serialNr KEQ0510017<br />
2013.10.10 20:03:25 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_Weather CUL_HM 2212BC01<br />
2013.10.10 20:03:25 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_Weather FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_Weather-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_Weather<br />
2013.10.10 20:03:25 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_Weather FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_Weather-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_Weather<br />
2013.10.10 20:03:26 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_Climate CUL_HM 2212BC02<br />
2013.10.10 20:03:26 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_Climate FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_Climate-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_Climate<br />
2013.10.10 20:03:26 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_Climate FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_Climate-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_Climate<br />
2013.10.10 20:03:27 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_WindowRec CUL_HM 2212BC03<br />
2013.10.10 20:03:27 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_WindowRec FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_WindowRec-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_WindowRec<br />
2013.10.10 20:03:27 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_WindowRec FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_WindowRec-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_WindowRec<br />
2013.10.10 20:03:28 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr CUL_HM 2212BC04<br />
2013.10.10 20:03:28 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr<br />
2013.10.10 20:03:28 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr<br />
2013.10.10 20:03:29 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam CUL_HM 2212BC05<br />
2013.10.10 20:03:29 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam<br />
2013.10.10 20:03:29 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam<br />
2013.10.10 20:03:30 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_remote CUL_HM 2212BC06<br />
2013.10.10 20:03:30 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_remote FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_remote-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_remote<br />
2013.10.10 20:03:30 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_remote FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_remote-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_remote<br />
2013.10.10 20:03:35 3: Device CUL_HM_HM_CC_RT_DN_2212BC added to ActionDetector with 000:10 time<br />
2013.10.10 20:03:40 2: CUL_HM set CUL_HM_HM_CC_RT_DN_2212BC getSerial<br />
2013.10.10 20:03:40 2: CUL_HM set CUL_HM_HM_CC_RT_DN_2212BC getConfig<br />
2013.10.10 20:03:54 3: Device CUL_HM_HM_CC_RT_DN_2212BC added to ActionDetector with 000:10 time<br />
<br />
=== Event monitor ===<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr motorErr: ok<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr measured-temp: 18.4<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr desired-temp: 18<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr ValvePosition: 3 %<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr mode: manu<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr unknown0: 24<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr T: 18.4 desired: 18 valve: 3 %<br />
2013-10-12 12:05:35.646 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC battery: ok<br />
2013-10-12 12:05:35.646 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC batteryLevel: 3.1 V<br />
2013-10-12 12:05:35.646 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC measured-temp: 18.4<br />
2013-10-12 12:05:35.646 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC desired-temp: 18<br />
2013-10-12 12:05:35.646 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC actuator: 3 %<br />
<br />
== Firmware Update ==<br />
Seit 24.10.2014 gibt es für den HM-CC-RT-DN die neue Firmware Version 1.4. Diese kann von der eQ-3 Webseite heruntergeladen werden. Genauere Informationen gibt es unter [[HomeMatic Firmware Update]].<br />
<br />
=== HM-CC-RT-DN spezifische Update Informationen ===<br />
Durch gleichzeitiges Drücken der "Auto-/Manu"-Taste und der "Comfort-/Eco"-Taste am HM-CC-RT-DN während man die Batterien wieder einlegt wird der updatemodus gestartet. Während des Updates steht "FUP" im Display. Nach erfolgreichem Update erscheint "Ins" im Display und es muss eine erneute Adaptierfahrt durch Drücken der Boost-Taste ausgelöst werden. Anschließend sollte der HM-CC-RT-DN wieder normal funktionieren. Die eingestellten Parameter und das Pairing mit FHEM gehen beim Update nicht verloren. Sollte das Update fehlschlagen, erscheint "Err" bzw. "CrC" im Display.<br />
<br />
Normalerweise sollte dann durch erneutes Starten der Prozedur am PC und HM-CC-RT-DN das ganze erneut durchführbar sein.<br />
<br />
Es gibt einige Readings, die nicht durch ein einfaches ''getConfig'' aktualisiert werden, z.B. "battery"(nicht batteryLevel). Um diese Readings zu bekommen, ist ein <br />
:<code>set Device_Channel04 controlMode auto </code><br />
notwendig. Daraufhin werden die Readings übertragen/aktualisiert.<br />
<br />
Anscheinend ([https://forum.fhem.de/index.php?topic=93074.msg1252268#msg1252268]) benötigt man bei Firmware 1.5 ein weiteres Attribut,<syntaxhighlight><br />
attr <devicename> commStInChn off<br />
</syntaxhighlight><br />
<br />
== Simulation von Fensterkontakten und externen Temperatursensoren ==<br />
{{Randnotiz|RNTyp=r|RNText=Für jeden separat zu steuernden HM-CC-RT-DN kann nur je ein Kanal eines virtuellen Devices als Temperatur- bzw. Fensterkontakt genutzt werden. Insbesondere die virtuellen Kanäle der VCCU eignen sich nicht dazu, mehrere HM-CC-RT-DN unabhängig voneinander anzusteuern! Hat man mehrere unabhängig arbeitende RT's, muß für jeden auch ein '''eigenes virtuelles Gerät''' angelegt werden! <br />
<br />
Die folgenden Beispiele sind nicht für Anfänger und Unwissende geeignet! Es gibt zahlreiche Stolpersteine:<br />
# Die HMId für virtuelle Geräte muss einmalig im System sein. Sie muss selbst gewählt werden und es darf '''keine''' vorhandene ID verwendet werden!<br />
# Es kann vorkommen, das beim Anlegen eines virtual Gerätes kein attr IODev gesetzt wird. Das Attribute ist aber notwendig, sonst arbeitet das Gerät nicht! Bitte kontrollieren und gegebenenfalls per Hand setzen.<br />
}}<br />
Grober Ablauf:<br />
* erstelle ein virtuelles Device<br />
* erstelle dazu einen virtuellen Kanal (bzw. mehrere, wenn sowohl ein virtueller Fensterkontakt wie ein virtueller Temperaturkanal benötigt werden).<br />
* peere den Kanal mit dem RT (als Fenster-Kontakt oder als remote, wenn du willst)<br />
* sende ein postEvent / stelle die neue Temperatur im Kanal ein<br />
<br />
=== Fensterkontakte ===<br />
''Angelehnt an diese {{Link2Forum|Topic=31078|Message=236245|LinkText=Forenbeitrag}}''<br />
define virtKitchenSensors CUL_HM 221133<br />
Um das Device als virtuelles zu kennzeichnen benötigt man den folgenden Befehl (legt weitere Attribute an): <br />
attr virtKitchenSensors modelForce VIRTUAL<br />
<br />
Kanal bzw. Kanäle erstellen:<br />
set virtKitchenSensors virtual 1 <br />
oder (für das Anlegen je eines Kanals für einen Fenster- und Temperatur-Kanal):<br />
set virtKitchenSensors virtual 2 <br />
Als Zwischenergebnis sehen wir in der Detailansicht des ''virtKitchenSensors'' ein bzw. zwei weitere Devices mit Namen ''virtKitchenSensors_Btn1'' bzw. ''virtKitchenSensors_Btn2''. <br />
<br />
Umbenennen des 1. Kanals: <br />
rename virtKitchenSensors_Btn1 virtualKitchenDoor<br />
<br />
Danach sollte man das webCmd-Attribut wie folgt vergeben:<br />
attr virtualKitchenDoor webCmd postEvent open:postEvent closed <br />
<br />
Anschließend peeren und (wer weniger wie den default-Wert von 12°C einstellen möchte) Temperatur festlegen mit:<br />
set virtualKitchenDoor peerChan 0 <Thermostat_Window_Rec> single set<br />
set <Thermostat_Window_Rec> regSet winOpnTemp 5 virtualKitchenDoor<br />
<br />
Ggf noch interne "Fenster-auf" Erkennung abschalten<br />
set <HM-CC-RT-DN>_Clima regSet winOpnMode off<br />
<br />
Die virtuelle Tür wird dann entsprechend über ein Notify getriggert.<br />
Einfache Form (nur ein Fensterkontakt im Raum):<br />
define notify_virtualKitchenDoor notify Fensterkontakt_1:(open|closed) set virtualKitchenDoor postEvent $EVENT<br />
Komplexere Form (zwei Fensterkontakte):<br />
<nowiki>define notify_virtualKitchenDoor notify (Fensterkontakt_1|Fensterkontakt_2) {if($EVENT eq "open" and Value("virtualKitchenDoor") eq "set_postEvent closed"){fhem("set virtualKitchenDoor postEvent open")} elsif (Value("virtualKitchenDoor") eq "closed" && Value("Fensterkontakt_2") eq "closed") {fhem("set virtualKitchenDoor postEvent closed")}}</nowiki><br />
{{Hinweis|Die ''postEvent''-Anweisung wird unmittelbar an die Funkschnittstelle weitergegeben und löst einen ''burst'' aus.}}<br />
<br />
=== Temperatursensoren ===<br />
''Angelehnt an diesen {{Link2Forum|Topic=19686|Message=233788|LinkText=Forenbeitrag}}''<br />
<br />
1. Virtuelles HomeMatic Device mit eigener HM Id definieren, (s.o.), es kann auch ein weiterer Kanal des oben erstellten Devices genutzt werden<br />
<br />
2. Dem Device einen virtuellen Kanal (Default ist ein virtueller Button) hinzufügen, wieder mit <code>set virtKitchenSensors virtual 1</code> bzw. <code>set virtKitchenSensors virtual 2</code> (2 geht auch, wenn bereits ein erster Kanal vorhanden war).<br />
<br />
3. Es ist kein virtueller Button sondern ein virtueller Temperatursensor - darum rename:<br />
rename virtKitchenSensors_Btn1 Kitchen_vT_Sensor1<br />
bzw. <code>rename virtKitchenSensors_Btn2 Kitchen_vT_Sensor1</code><br />
<br />
4. Virtuellen Peer Sensor mit dem Weather Channel des RT-DN peeren:<br />
set Kitchen_vT_Sensor1 peerChan 0 <RT_DN>_Weather single<br />
<br />
5. Peering kontrollieren (Voraussetzung: Device ''hm'' vom Typ [[HMInfo]] existiert):<br />
:<code>set hm peerXref</code><br />
Beispiel-Ausgabe:<br />
peerXref done: <br />
x-ref list <br />
wz_Thermostat_Weather => Kitchen_vT_Sensor1 <br />
Kitchen_vT_Sensor1 => wz_Thermostat_Weather<br />
<br />
6. Gemessene Temperatur vom z.B. 1-Wire DS1820 dem virtuellen HM Sensor übergeben. Z.B. bei jeder Aktualisierung des Messwerts per notify:<br />
define at_Kitchen_vT notify myRealKitchenTempSensor:temperature:.* set Kitchen_vT_Sensor1 virtTemp $EVTPART1<br />
<br />
{{Hinweis|Die ''virtTemp''-Anweisung ändert zunächst nur den Wert im virtuellen Kanal. Diese wird zu bestimmten Zeiten als ''broadcast'' gesendet. Diese Zeiten kennt der RT und hält sich kurzfristig empfangsbereit.}}<br />
Sollte es Probleme geben, dass der RT des Öfteren wieder auf seine eigenen Messwerte wechselt, weil die von FHEM errechnete Sendezeit und die vom RT errechnete Empfangszeit zu weit auseinanderliegen, sollte das Attr cyclicMsgOffset im Virtuellen Kanal beachtet werden. Näheres dazu ist ca. ab {{Link2Forum|Topic=45735|Message=572806|LinkText=hier}} im Forum zu finden.<br />
<br />
7. Sicherstellen, dass nicht längerfristig veraltete Temperaturdaten berücksichtigt werden:<br />
Aufgrund des oben beschriebenen Verfahrens wird der im virtuellen Kanal vorhandene Wert solange immer wieder gesendet, wie dieser dort steht. Fällt z.B. der echte Sensor oder das Interface nicht nur vorübergehend aus, muß der Wert gelöscht werden. Hier ein Vorschlag für ein ''at'', das alle 15 Minuten alle virtuellen Temperaturwerte löscht, die älter als eine Stunde sind, und damit den Rückfall des jeweiligen RT auf seinen internen Sensor bewirkt:<br />
defmod a_delete_outdated_virtTemps at +*00:15 {\<br />
my @vTemps = devspec2array("TYPE=CUL_HM:FILTER=model=VIRTUAL:FILTER=temperature~.+");;\<br />
for my $vTemp (@vTemps) {\<br />
CommandDeleteReading(undef,"$vTemp temperature" ) if ReadingsAge($vTemp,"temperature",0) > HOURSECONDS ;;\<br />
}\<br />
}<br />
Erhält der RT eine gewisse Zeitlang (ca. 15 Minuten) keinen Wert von seinem (virtuellen) Peer, schaltet er auf den internen Temperatursensor zurück und signalisiert dies durch ein blinkendes Funksymbol im Display.<br />
<br />
=== Exkurs: HMCCUDEV ===<br />
{{Hinweis|Das Nachfolgende entspricht dem Stand Janaur 2020. Die HMCCU-Module sind jedoch derzeit in der Weiterentwicklung, so dass es sich ggf. empfiehlt, im Forum nachzufragen.}}<br />
Das Nutzen externer Sensoren scheint mit HMCCU nicht möglich zu sein, siehe {{Link2Forum|Topic=107134|LinkText=Forenbeitrag: RaspberryMatic (HMCCU) und LaCrosse Temperature als "Wandthermostat"}}, die Weitergabe eines externen Türkontakts ist eventuell möglich, siehe {{Link2Forum|Topic=106807|LinkText=Forenbeitrag: HMCCU mit Thermostat HM-CC-RT-DN und ZWave Türsensor}}, an anderer Stelle hat der Modulentwickler ausgeführt, es könnten nur {{Link2Forum|Topic=107501|Message=1015944|LinkText=HomeMatic Geräte}} als Sensoren verwendet werden.<br />
<br />
== Auflistung und Beschreibung der Readings ==<br />
Einige der Readings können via "regSet" parametriert werden.<br />
Wobei der Registername etwas anders geschrieben wird als der Reading Name (ohne R-).<br />
:<code>set <name> regSet <register> <value> </code><br />
Beispiel für Reading R-winOpnPeriod erhöhen auf 60 Minuten: <br />
:<code>set EG_Buero_THERMOSTAT_Clima regSet winOpnPeriod 60 </code><br />
<br />
Eine vollständige Liste erhält man auch, wenn man einen falschen Registernamen angibt.<br />
supported register are backOnTime boostPeriod boostPos btnLock btnNoBckLight burstRx cyclicInfoMsg cyclicInfoMsgDis dayTemp daylightSaveTime decalcTime decalcWeekday globalBtnLock localResDis lowBatLimitRT modePrioManu modePrioParty modusBtnLock nightTemp noMinMax4Manu pairCentral regAdaptive reguExtI reguExtP reguExtPstart reguIntI reguIntP reguIntPstart showInfo showWeekday sign tempMax tempMin tempOffset valveErrPos valveMaxPos valveOffsetRt winOpnBoost winOpnDetFall winOpnMode winOpnPeriod winOpnTempI<br />
<br />
<table cellspacing="0" border="0"><br />
<tr><br />
<td style="border-top: 2px solid #ffffff; border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#A6A6A6"><font face="Arial" size="2" color="#0D0D0D">Reading</font></td><br />
<td style="border-top: 2px solid #ffffff" align="left" valign="middle" bgcolor="#A6A6A6"><font face="Arial" size="2" color="#0D0D0D">Beispielwert</font></td><br />
<td style="border-top: 2px solid #ffffff" align="left" valign="middle" bgcolor="#A6A6A6"><font face="Arial" size="2" color="#0D0D0D">M&ouml;gliche Werte</font></td><br />
<td style="border-top: 2px solid #ffffff; border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#A6A6A6"><font face="Arial" size="2" color="#0D0D0D">Beschreibung</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">CommandAccepted</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">yes</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">yes; no</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Letztes Kommando akzeptiert (yes/ No)</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-boostPeriod</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">5 min</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">1 min bis x min</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Zeit wie lange das Ventil im Boost Modus sein soll.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-boostPos</font></td><br />
<td align="left" valign="middle" bgcolor="#111111" sdval="0.8" sdnum="1033;0;0%"><font face="Arial" size="2" color="#CCCCCC">80%</font></td><br />
<td align="left" valign="middle" bgcolor="#111111" sdnum="1033;0;0%"><font face="Arial" size="2" color="#CCCCCC">0 bis 100</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Ventilposition die im Boost Modus gesetzt wird.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-btnNoBckLight</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">off</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="35" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-dayTemp</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">21 C</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Siehe R-tempMin bis R-tempMax</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Solltemperatur die gesetzt werden soll, wenn das Sonnensymbol am Thermostat gedr&uuml;ckt wird. Ebenso wird bei dieser Solltemperatur das Sonnensymbol im Display angezeigt.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-daylightSaveTime</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">on</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-decalcTime</font></td><br />
<td align="left" valign="middle" bgcolor="#111111" sdval="0.458333333333333" sdnum="1033;1033;H:MM"><font face="Arial" size="2" color="#CCCCCC">11:00</font></td><br />
<td align="left" valign="middle" bgcolor="#111111" sdnum="1033;1033;H:MM"><font face="Arial" size="2" color="#CCCCCC">00:00 bis 23:59</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Uhrzeit wann die Entkalkungsfahrt durchgef&uuml;hrt werden soll. </font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-decalcWeekday</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Sat</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Mon; Tue; Wed; Thu; Fri; Sat; Sun</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Tag an dem die Entkalkungsfahrt durchgef&uuml;hrt werden soll.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-modePrioManu</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">all</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">all; ???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-modePrioParty</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">all</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">all; ???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="35" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-nightTemp</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">17 C</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Siehe R-tempMin bis R-tempMax</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Solltemperatur die gesetzt werden soll, wenn das Mondsymbol am Thermostat gedr&uuml;ckt wird. Ebenso wird bei dieser Solltemperatur das Mondsymbol im Display angezeigt.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-noMinMax4Manu</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">off</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-regAdaptive</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">on</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-reguExtI</font></td><br />
<td align="left" valign="middle" bgcolor="#333333" sdval="15" sdnum="1033;"><font face="Arial" size="2" color="#CCCCCC">15</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-reguExtP</font></td><br />
<td align="left" valign="middle" bgcolor="#111111" sdval="30" sdnum="1033;"><font face="Arial" size="2" color="#CCCCCC">30</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-reguExtPstart</font></td><br />
<td align="left" valign="middle" bgcolor="#333333" sdval="30" sdnum="1033;"><font face="Arial" size="2" color="#CCCCCC">30</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-reguIntI</font></td><br />
<td align="left" valign="middle" bgcolor="#111111" sdval="18" sdnum="1033;"><font face="Arial" size="2" color="#CCCCCC">18</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-reguIntP</font></td><br />
<td align="left" valign="middle" bgcolor="#333333" sdval="33" sdnum="1033;"><font face="Arial" size="2" color="#CCCCCC">33</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-reguIntPstart</font></td><br />
<td align="left" valign="middle" bgcolor="#111111" sdval="44" sdnum="1033;"><font face="Arial" size="2" color="#CCCCCC">44</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-showInfo</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">time</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">date; time</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Zeige Datum oder Uhrzeit im Display an</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-showWeekday</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">off</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Zeige den Wochentag im Display an</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-sign</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">off</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-tempMax</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">30.5 C</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Gr&ouml;&szlig;te einstellbare Temperatur</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-tempMin</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">4.5 C</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Kleinste einstellbare Temperatur</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-tempOffset</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">0.0K</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">0.0 bis ???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Temperaturabweichung gemessene Temperatur vs. realer Temperatur in Grad Kelvin. Angabe in 0.5-Schritten ohne Einheitenzeichen, z.B. 0.5 oder -1.0</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-valveErrPos</font></td><br />
<td align="left" valign="middle" bgcolor="#333333" sdval="0.15" sdnum="1033;0;0%"><font face="Arial" size="2" color="#CCCCCC">15%</font></td><br />
<td align="left" valign="middle" bgcolor="#333333" sdnum="1033;0;0%"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-valveMaxPos</font></td><br />
<td align="left" valign="middle" bgcolor="#111111" sdval="1" sdnum="1033;0;0%"><font face="Arial" size="2" color="#CCCCCC">100%</font></td><br />
<td align="left" valign="middle" bgcolor="#111111" sdnum="1033;0;0%"><font face="Arial" size="2" color="#CCCCCC">0 bis 100</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Maximale Ventilstellung die das Thermostat fahren darf.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-valveOffsetRt</font></td><br />
<td align="left" valign="middle" bgcolor="#333333" sdval="0" sdnum="1033;0;0%"><font face="Arial" size="2" color="#CCCCCC">0%</font></td><br />
<td align="left" valign="middle" bgcolor="#333333" sdnum="1033;0;0%"><font face="Arial" size="2" color="#CCCCCC">0 Bis 100</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="52" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-winOpnBoost</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">off</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Startet nach dem Fensterschlie&szlig;en die Boostfunktion um unabh&auml;ngig von der Raumtemperatur den Heizk&ouml;rper eine Zeit x aufzuheizen. (Siehe R-boostPeriod &amp; R-boostPos)</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-winOpnDetFall</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">1.4 K</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">0.5 bis 2.5</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Temperatur Sturz zwischen zwei Messungen, die als Fenster offen erkannt werden.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="35" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-winOpnMode</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">off</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Thermostat soll anhand eines schnellen Temperaturabfalls erkennen, dass das Fenster ge&ouml;ffnet ist.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R-winOpnPeriod</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">15 min</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">1 bis 60 Minuten</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Dauer bis das Signal Fenster offen wieder entfernt wird.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R-winOpnTemp</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">12 C</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Siehe R-tempMin bis R-tempMax</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Temperatur die eingestellt werden soll, wenn das Fenster als offen erkannt wird.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="104" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R_0_tempListSat</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">07:00 20.0 22:30 22.0 24:00 20.0</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">incomplete = Daten werden mit Thermostat abgeglichen<br><br>Zeit/Temperaturangaben siehe Beispiel</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Tages Solltemperaturen abh&auml;ngig von der Uhrzeit. <br>- Der Beginn um 00:00 ist nicht einzutragen. <br>- Es sind immer Paare einzutragen (Uhrzeit Temperatur). <br>- Der letzte Eintrag muss an jedem Tag 24:00 sein.<br>- Uhrzeiten sind auf halbe Stunden beschr&auml;nkt. Eintr&auml;ge 08:00 und 08:30 sind g&uuml;ltig. 08:20 ist ung&uuml;ltig.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R_1_tempListSun</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">07:00 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R_2_tempListMon</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">04:30 20.0 07:00 22.0 12:45 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R_3_tempListTue</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">04:30 20.0 07:00 22.0 12:45 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R_4_tempListWed</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">04:30 20.0 07:00 22.0 12:45 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R_5_tempListThu</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">04:30 20.0 07:00 22.0 12:45 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">R_6_tempListFri</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">04:30 20.0 07:00 22.0 12:45 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="35" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">R_tempList_State</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">verified</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">incomplete = Daten werden mit Thermostat abgeglichen<br>verified = Daten sind mit Thermostat abgeglichen</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Aktualisierungsstatus der Wochen Temperatur Einstellungen</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">ValvePosition</font></td><br />
<td align="left" valign="middle" bgcolor="#333333" sdval="36" sdnum="1033;"><font face="Arial" size="2" color="#CCCCCC">36</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">0 bis 100</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">aktuelle Ventilstellung</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="35" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">boostTime</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">-</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">-<br>1 min bis n min</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Zeit wie lange der Boostmodus noch aktiv ist.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="121" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">controlMode</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">auto</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">auto = Thermostat wird nach der TempListe gesteuert<br>manual = Die eingestellte Temperatur am Thermostat wird nicht ver&auml;ndert, au&szlig;er bei Verwendung von WinOpn; <br>boost = Thermostat wird in den Boost Modus gesetzt. Siehe R-boostPeriod/Pos<br>day = Thermostat wird auf die eingestellte Tag Temperatur gesetzt (R-dayTemp).<br>night = Thermostat wird auf die eingestellte Nacht Temperatur gesetzt (R-nightTemp).</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Setzt das Thermostat in einen bestimmten Modus</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">desired-temp</font></td><br />
<td align="left" valign="middle" bgcolor="#111111" sdval="22" sdnum="1033;"><font face="Arial" size="2" color="#CCCCCC">22</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">N/A</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Solltemperatur</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">measured-temp</font></td><br />
<td align="left" valign="middle" bgcolor="#333333" sdval="23.2" sdnum="1033;"><font face="Arial" size="2" color="#CCCCCC">23.2</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">N/A</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Isttemperatur</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">partyEnd</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">-</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Ende Datum/Zeit in dem die Party Temperatur (partyTemp) gesetzt sein soll.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">partyStart</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">-</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">Start Datum/Zeit in dem die Party Temperatur (partyTemp) gesetzt sein soll.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">partyTemp</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">-</font></td><br />
<td align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">-; 20.0</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Party Temperatur</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">recentStateType</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">ack</font></td><br />
<td align="left" valign="middle" bgcolor="#333333"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign="middle" bgcolor="#333333" sdnum="1033;1033;M/D/YYYY H:MM"><font face="Arial" size="2" color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-bottom: 2px solid #ffffff; border-left: 2px solid #ffffff" height="23" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">state</font></td><br />
<td style="border-bottom: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">T: 23.2 desired: 22.0 valve: 36</font></td><br />
<td style="border-bottom: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC"><br></font></td><br />
<td style="border-bottom: 2px solid #ffffff" align="left" valign="middle" bgcolor="#111111"><font face="Arial" size="2" color="#CCCCCC">Aktuelle Statusinformation</font></td><br />
</tr><br />
</table><br />
<br />
== Bekannte Probleme ==<br />
=== TempList: Bad format ... ===<br />
Wenn Sie beim Setzen einer Temperaturliste nach dem o.a. Schema ("SetTempList...") die Meldung<br />
<br />
Bad format, use HH:MM TEMP ......<br />
<br />
erhalten, sollten Sie zunächst ein [[update]] von FHEM durchführen.<br />
<br />
=== Der Thermostat heizt über die Solltemperatur hinaus ===<br />
In der Regel ist das ein ganz normales Verhalten, wenn der Thermostat nicht mit einem externen Temperaturfühler oder einem Wandthermostat gepeert ist. In dem Fall muss sich der Thermostat auf den eingebauten Temperatursensor verlassen, der sehr nahe an der Heizung selbst sitzt. Dadurch ist die gemessene Temperatur höher, als sie z.B. in der Raummitte wäre. Der Hersteller hat hier einen mehr oder weniger intelligenten Algorithmus eingebaut, um diesen Effekt zu kompensieren. Das sieht dann so aus, als ob der Thermostat nicht richtig regelt.<br />
Dieses Verhalten kann man im Prinzip nur verhindern, indem man einen externen Temperatursensor oder einen Wandthermostat peert. Wie das geht ist hier beschrieben: [[#Channel (Kanal) 01 _Weather]]. Normalerweise regelt der Thermostat dann genau auf die Solltemperatur. <br />
Ansonsten sollte man sich auch fragen, ob das gezeigte Verhalten vielleicht doch gut genug ist. Dazu platziert man irgendein Thermometer möglichst in der Mitte des Raums und beobachtet den Temperaturverlauf eine Weile. Wenn man dann noch eine Abweichung feststellt, kann es sinnvoll sein, diese mittels des Registers R-tempOffset zu beheben.<br />
<br />
=== Pairen bei Firmware 1.5 ===<br />
Das nachfolgende Vorgehen bietet sich ab Firmware 1.5 ab, da sonst das pairen nicht erfolgreich sein wird:<br />
# Pairing wie angegeben<br />
# '''''GetConfig''''' erst, nachdem die Zeit von '''''hmPairForSec''''' abgelaufen ist<br />
# burstXmit<br />
# set <gerät> reset<br />
# set <gerät> unpair <br />
# harten HW Reset nach Handbuch am Gerät<br />
# erneut pairen<br />
Der Tipp stammt aus [https://de.elv.com/forum/neue-firmware-1.5-an-fhem-uart-modul-hm-mod-rpi-pcb-mit-firmware-1.4.1-7481 diesem Beitrag] im ELV Forum. Dies Vorgang konnte teilweise auch für Geräte mit Firmware 1.4 bestätigt werden.<br />
<br />
=== Akkubetrieb ===<br />
Auch frisch geladenen NiMh-Akkus weisen nur eine Zellenspannung von nur ca. 1,2 Volt auf. Deshalb wird schnell die battery:low Warngrenze erreicht, die bei U < 2,4V liegt und mitunter unmittelbar nach dem Einsetzen mit der Kalibierungsfahrt unterschritten wird. Mit ''NiMh-Akkus mit geringer Selbstentladung'' (z.b. Panasonic Eneloop) ist ein Betrieb jedoch sinnvoll möglich, da der Spannungsabfall bei den sehr geringen Entladeströmen im Stellantrieb relativ lange oberhalb 1,3 Volt verläuft.<br />
<br />
== Links ==<br />
* [http://www.eq-3.de/produkt-detail-aktoren/items/homematic-funk-heizkoerperthermostat.html Produktinfo bei EQ-3]<br />
* [http://www.eq-3.de/Downloads/eq3/downloads_produktkatalog/homematic/bda/HM-CC-RT-DN_UM_GE_eQ-3_web.pdf Bedienungsanleitung bei EQ-3 (PDF)]<br />
* [http://www.eq-3.de/Downloads/eq3/downloads_produktkatalog/homematic/pdb/Funk-Heizkoerperthermostat_105155_Produktdatenblatt_V2.3.pdf Datenblatt bei EQ-3 (PDF)]<br />
* [http://www.eq-3.de/Downloads/eq3/downloads/Ventilkompatibilitaeten.pdf Ventil-Kompatibilitätsliste bei EQ-3 (zur Zeit nicht verfügbar)]<br />
* {{Link2Forum|Topic=14738|LinkText=Forenthema zum Thermostat}}<br />
* {{Link2Forum|Topic=64446|LinkText=Reparatur einer durch mechanischen Stoß von außen abgerissenen Lichtschranke}}<br />
<br />
[[Kategorie:HomeMatic Components]]<br />
[[Kategorie:Heizungsventile]]<br />
[[Kategorie:868MHz]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=SIGNALduino&diff=37741SIGNALduino2022-11-28T19:41:10Z<p>Andies: /* Das Logfile */ low high entspricht besser "Signal" und "Pause"</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Empfang und Verarbeitung von digitalen Signalen<br />
|ModType=d<br />
|ModFTopic=38402<br />
|ModCmdRef=SIGNALduino<br />
|ModForumArea=Sonstige Systeme<br />
|ModTechName=00_SIGNALduino.pm<br />
|ModOwner=Sidey ({{Link2FU|8018|Forum}}/[[Benutzer Diskussion:Sidey|Wiki]])<br />
}}<br />
<br />
== Einleitung ==<br />
=== Übersicht ===<br />
Unter den Namen SIGNALduino versteht man sowohl den Low-Cost Empfänger für digitale Signale (vergleichbar dem [[CUL]]) als auch das gleichnamige Modul mit dem Dateinamen 00_SIGNALduino.pm. Mit dem SIGNALduino kann man entweder 433 oder 868 MHz-Geräte auslesen und ansprechen. Der SIGNALduino funktioniert auch mit anderen Medien wie Infrarot oder direkter Kabelverbindung.<br />
<br />
Der SIGNALduino(-Stick) erkennt Signale anhand von Mustern und gibt sie (als maximal detaillierte Beschreibung einer Signalabfolge) dann schlicht sofort nur noch an FHEM zur Auswertung (Dekodierung) weiter. Auch nicht erkannte Signale werden an FHEM übergeben.<br />
Aufgabe des SIGNALduino (Firmware/Stick) ist es also nur, Signal-Aktivitäten zu erfassen und maximal präzise (als kurzer Text-String) zu beschreiben.<br />
Alles weitere (echte, finale Auswertung / Zuweisung dieser Signal-Daten) wird dann auf einer großen Box (z.B. Raspberry) gemacht.<br />
<br />
=== Vorteil gegenüber einem CUL/FHEMduino ===<br />
Der SIGNALduino hat den Vorteil einer sehr schnellen Demodulation des Funksignals. Sollen weitere Protokolle dekodiert werden, so muss dazu nur ein passendes FHEM Modul entwickelt oder ein universelles Modul erweitert werden (also auf flexibel direkt änderbarer/updatebarer Rechner-Seite!!). Änderungen am Arduino-Firmware-Code sind normalerweise nicht notwendig (sofern die grundsätzliche Signal-Klassifizierung auf Stick-Firmware-Seite korrekt funktioniert - leider nicht immer, z.B.: [https://github.com/RFD-FHEM/SIGNALDuino/issues/65 MU-Nachrichten werden z.T. als MC erkannt]).<br />
<br />
Ein großer Vorteil des SIGNALduino besteht darin, dass auch Geräte mit leicht abweichenden Frequenzen steuerbar sind; so empfangen die ''Somfy''-Rolladenmotoren beispielsweise auf 433.42 MHz und nicht, wie bei anderen Geräten sehr oft üblich, auf 433.92 MHz. Die Frequenzumstellung stellt für den SIGNALduino kein Problem dar.<br />
<br />
Ebenso kann man den SIGNALduino direkt an den Sendeausgang eines Sensors anbinden und die digitalen Signale empfangen, dabei bitte aber auf die passenden Spannungen achten, denn ein Arduino Nano verträgt nur 5V.<br />
<br />
<br />
=== Entwicklungsversion ===<br />
Der SIGNALduino wird derzeit aktiv weiterentwickelt. In FHEM existieren inzwischen zwei verschiedene Versionen: eine offizielle (Maintainer ist Sidey) und eine inoffizielle (Maintainer ist Ralf9). Die offizielle Version wird über den update-Prozess verteilt, wer die inoffizielle nutzen will, muss hier händisch eingreifen. Beide Versionen sind inzwischen so weit entwickelt, dass sie nicht mehr ohne Weiteres kompatibel sind. Man muss also eine Entscheidung treffen, welches das für einen geeignete Modul ist. Das betrifft inzwischen nicht nur das eigentliche SIGNALduino.pm-Modul, sondern auch die dazugehörige Firmware.<br />
<br />
==== Offizielles Modul (Sidey) ====<br />
Die offizielle Version wird in mehreren Forenbeiträgen beschrieben: [https://forum.fhem.de/index.php/topic,58397.0.html Erster Thread] (inzwischen geschlossen), {{Link2Forum|Topic=58396|LinkText=weiterer Thread}} sowie [https://forum.fhem.de/index.php/topic,60170.0.html noch ein Thread.] <br />
<br />
An einem weiteren Thread ([https://forum.fhem.de/index.php/topic,58396.0.html Link]) scheinen beide Autoren beteiligt zu sein.<br />
<br />
==== Inoffizielles Modul (Ralf9) ====<br />
Das Modul von Ralf9 wird [https://forum.fhem.de/index.php/topic,111653.0.html hier] beschrieben. Wer es installieren möchte, muss beim üblichen update-Prozess das Modul 00_SIGNALduino.pm vom update ausschließen oder nach jedem Update erneut Ralf9s-Modul herunterladen. Die Installation des Moduls wird im ersten Post beschrieben, Hilfe gibt es auch in diesem Thread. <br />
<br />
== Hardware ==<br />
=== Controller ===<br />
Der SIGNALduino (Hardware) wird über den USB Port angeschlossen, er kann aber auch mit zusätzlichen ESP Modulen über ein WLAN angebunden werden. Bei Einbindung via ESP muss man beachten, dass der ESP nach 5 Minuten Inaktivität seine TCP-Verbindung unterbricht (siehe [[ESP8266#Bekannte_Probleme|diesen Hinweis]]). Zu diesem Zweck gibt es einen Signalduino-eigenen Ping-Befehl ('get signalduino ping'), der diese Aktivität wieder aufbaut. Ping-Befehle sind auch auf Betriebssystemebene bekannt - allerdings beachte man, dass der ping-Befehl auf Betriebssystemebene ICMP verwendet, zum "Aufwachen" des ESP aber auf TCP-Ebene aktiviert werden muss (zum Unterschied siehe [https://www.tippscout.de/internet-was-sind-tcp-ip-udp-und-icmp_tipp_2268.html hier]) und man daher besser den Signalduino-eigenen Befehl und nicht das Betriebssystem verwendet.<br />
<br />
Der SIGNALduino basiert auf einem [http://arduino.cc/de/Main/ArduinoBoardNano Arduino Nano], die Schaltung entspricht dem [[Selbstbau CUL]] (eine frühere Version ist der nicht mehr weiterentwickelte [[FHEMduino]]):<br />
* Entweder wird ein Arduino mit einfachen Sende- und Empfangsmodulen verwendet, dann ist die Verkabelung identisch zum FHEMduino <br />
* Oder es wird ein CC1101 Transceiver verwendet, dann ist die Verkabelung identisch zum [[Selbstbau CUL]]. Dieser Aufbau wird derzeit empfohlen.<br />
* Zuletzt gibt es ein fertig konfektioniertes Modul von In-Circuit mit Radino CC1101 Varianten, Link zum [http://shop.in-circuit.de/index.php Hersteller]. <br />
<br />
Achten Sie beim Selbstbau auf die entsprechenden Sender-Empfänger. Der sehr preiswert angebotene XY-MK-5V hat sich als zu unzuverlässig erwiesen, während anscheinend beim CC1101 (insbesondere der "grünen Version") keine Probleme auftreten. <br />
<br />
Es stehen auch für den [https://www.arduino.cc/en/Main/arduinoBoardUno UNO] und [https://www.arduino.cc/en/Main/ArduinoBoardProMini PRO Mini] Firmware-Dateien zur Verfügung. Die ausgelieferte Firmware läuft nur auf Mikrocontrollern mit 16 MHz; wer einen Mikrocontroller mit 8 MHz verwenden möchte, muss die Firmware selbst compilieren. Die SW ist auf [https://github.com/RFD-FHEM/SIGNALDuino github]. Vorgesehen ist momentan (für ordentlich breiten Support müsste man wohl eine CMake-Build-Config hinzufügen - ich sollte hier mal in die Pötte kommen...) nur die Übersetzung unter Windows mit Visual Studio und dem Visual Micro Zusatz. Es gibt aber auch eine Anleitung, wie man mit der [[Arduino]] IDE oder einem Makefile [[SIGNALduino Compilieren]] kann.<br />
<br />
Es gibt auch eine Variante des SIGNALduino, die auf einem [[ESP8266]] nativ läuft, diese funktioniert seit Anfang 2018 annehmbar, allerdings befindet diese sich noch in einer Entwicklungsphase.<br />
<br />
An den "SIGNALESP" kann auch ein CC1101 via SPI angebunden werden:<br />
<br />
{| |<br />
!CC1101 Bezeichnung<br />
!ESP Pin<br />
|-<br />
|CLK||GPIO14<br />
|-<br />
|MOSI||GPIO13<br />
|-<br />
|MISO||GPIO12<br />
|-<br />
|CSN||GPIO15<br />
|-<br />
|GDO0||GPIO4<br />
|-<br />
|GDO2||GPIO5<br />
|}<br />
<br />
Wird eine einfache Empfänger / Sender Kombination verwendet, dann über die Pins:<br />
<br />
{| |<br />
! Bezeichnung <br />
! ESP Pin<br />
|-<br />
|Transmitter||GPIO4<br />
|-<br />
|Receiver||GPIO5<br />
|}<br />
<br />
=== Sendemodule ===<br />
{{Randnotiz|RNTyp=r|RNText=Viele user berichten über Empfangsprobleme bei Nutzung des XY-MK-5V; es wird ausdrücklich empfohlen, ein anderes Empfangsmodul zu nutzen!}}<br />
[[Datei:Fhemduino_schematic.png|200px|thumb|right|Beispielschaltplan SIGNAL(FHEM)duino]] <br />
<br />
Mit einem Arduino-Nano und folgenden, billigen Sende- und Empfangsmodulen können Sie einen SIGNALduino bauen:<br />
* FS1000A Dies ist das Sendemodul (TX) - es wird oft im Set mit dem billigen XY-MK-5V-Empfänger angeboten (etwa 5€). <br />
* RXB6 Das ist das empfohlene Empfangsmodul (RX), statt XY-MK-5V, etwa 5€ aus Deutschland.<br />
<br />
Die Verkabelung erfolgt analog zum [[FHEMduino]] und das bedeutet (Arduino -> Modul):<br />
* PIN D2 an DATA des RX-Moduls<br />
* PIN D11 an DATA des TX-Moduls (PIN links mit Beschriftung ATAD)<br />
<br />
Zusätzlich muss noch jeweils GND und 5V des Arduino mit dem GND bzw. VCC des Moduls verbunden werden.<br />
<br />
Jetzt fehlen noch die Antennen. Dafür braucht man ein 17,2 cm langes Stück Kupferdraht, das wird beim Anschluss "ANT" jeweils am Modul angelötet (anfängergeeignet).<br />
<br />
== Software ==<br />
<br />
=== USB-ID ermitteln ===<br />
Bevor der SIGNALduino mit dem FHEM Server (im Beispiel hier ein Raspberry PI) verbunden werden kann, muss die USB-Schnittstelle ermittelt werden. Hierzu bitte auf dem Terminal den Befehl<br />
<pre> ls -l /dev/serial/by-id </pre><br />
ausführen. Beispielhaft sieht das Ergebnis etwa so aus:<br />
<br />
''lrwxrwxrwx 1 root root 13 Jan 31 00:02 '''usb-FTDI_FT232R_USB_UART_A903N5T5-if00-port''' -> ../../ttyUSB0''<br />
<br />
Damit ist der Anschluss des SIGNALduino bestimmt und das Gerät kann wie im nächsten Abschnitt beschrieben definiert werden. Zuvor muss noch das Modul geladen werden.<br />
<br />
=== FHEM-Modul laden ===<br />
Die SIGNALduino Module werden über das FHEM [[update]] verteilt, sobald die Änderungen einen "stabilen" und alltagstauglichen Zustand haben. Aktuell wird dort die Version 3.5.2 seit 18.01.2022 verteilt.<br />
<br />
Mit Version 3.5.x ist die Unterstützung für Geräte mit FSK-Modulation integriert.<br />
<br />
Die aktuell in Entwicklung befindliche Version (3.5.3) kann über folgende Vorgehensweise installiert werden:<br />
<br />
* FHEM aktualisieren: <code>update</code> <br />
* SIGNALduino Modul aktualisieren: <code>update all https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/master<nowiki/>/controls_signalduino.txt</code> Durch das Update von FHEM wird sichergestellt, dass das Modul mit FHEM arbeitet.<code><nowiki/></code><br />
* Es empfiehlt sich, die Github-Quelle dauerhaft einzutragen: <code>update add https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/master/controls_signalduino.txt</code>, um weitere Entwicklungs-Updates zu bekommen, und damit das nächste Standard-<code>update</code> nicht die alte Version wieder einspielt.<br />
<br />
Das Gerät kann wie folgt definiert werden (die Spezifikation des USB-Anschlusses muss dabei an die aktuellen Gegebenheiten angepasst werden):<br />
:<code>define <eigener-SIGNALduino-Name> SIGNALduino /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A903N5T5-if00-port0@57600</code><br />
* Solltet Ihr einen SIGNALESP via IP einbinden wollen, ist die Syntax (ebenso wird auch vorgegangen wenn der SIGNALduino beispielsweise über ser2net freigeben wird):<br />
:<code>define <eigener-SIGNALESP-Name> SIGNALduino <ip-adresse>:23</code><br />
Nach dem Einbinden wird der SIGNALduino, falls er erkannt wird, im Status "Opened" angezeigt. Die Baudrate beim SIGNALduino beträgt 57600 - <br />
<br />
Verbindungsversuche via telnet müssen dieselbe Baudrate verwenden. <br />
<br />
Die nachfolgenden Beispiel-Befehle verwenden "sduino" als <eigener-SIGNALduino-Name>.<br />
<br />
==== Flashen des Arduino mit der SIGNALduino Firmware ====<br />
Falls avrdude noch nicht vorhanden ist, kann es mit folgendem Befehl installiert werden:<br />
:<code>sudo apt-get install avrdude</code><br />
<br />
In FHEM ist der SIGNALduino mit dem Status "Open" vorhanden. Jetzt müssen wir FHEM noch mitteilen, welche Hardware wir angeschlossen haben. Über das Attribut ''hardware'' lässt sich zwischen den mitgelieferten Firmware-Dateien wechseln. Solltet ihr einen Nano mit cc1101 Transceiver verwenden, so wählt bitte folgende Hardware<br />
:<code>attr sduino hardware nanoCC1101</code><br />
sonst üblicherweise<br />
:<code>attr sduino hardware nano328</code><br />
<br />
Dann muss mitgeteilt werden, welche Version man geladen haben will: stable oder testing. <br />
:<code>attr sduino updateChannelFW testing</code><br />
Nun wird die entsprechende Firmware heruntergeladen. Dies geschieht durch den Befehl<br />
:<code>get sduino availableFirmware</code><br />
Anschließend kann der ''flash'' Befehl abgesetzt werden: <br />
:<code>set sduino flash <und-dann-auswaehlen></code><br />
Dadurch wird der Arduino mit der gewählten Firmware geflasht. Das Ergebnis wird im Webinterface direkt angezeigt.<br />
<br />
Alternativ kann auch der Flash-Befehl mit einem Dateinamen aufgerufen werden. Diese Möglichkeit sollte jedoch nur verwendet werden, wenn die SIGNALduino Firmware selbst compiliert wurde und eine andere Hardware verwendet wird. Der Flash-Befehl wird wie folgt aufgerufen:<br />
:<code>set sduino flash FHEM/firmware/SIGNALduino_mega2560.hex</code><br />
(je nachdem wo und unter welchem Namen die .hex Datei abgelegt wurde)<br />
<br />
Wenn ein miniCUL geflasht werden soll, sind einige Besonderheiten zu beachten. Details dazu in {{Link2Forum|Topic=114413|LinkText=diesem Forenthema}}.<br />
<br />
==== Flashen einer Firmware über HTTP ====<br />
Die Firmware wird nicht mehr über den FHEM Update Mechanismus verteilt. <br />
Damit die passende Firmware auf den SIGNALduino geladen werden kann, wird diese dann über HTTP aus den Github Releases geladen.<br />
<br />
==== Vorabversion einer Firmware ====<br />
Die Firmware des SIGNALduino wird ebenso wie das FHEM Modul auch weiter entwickelt.<br />
Die Entwickler sind auf Tests und Rückmeldungen der Nutzer angewiesen, da leider nicht alle Sensoren vorher getestet werden können.<br />
<br />
Die Version 3.4 ist die aktuell stabile Version.<br />
<br />
Für die folgenden Microcontroller kann man die Firmware seit 21.02.2019 auch direkt downloaden und teilweise flashen. <br />
Dazu muss das Attribut <code>hardware</code> auf einen gültigen Wert angepasst werden!<br />
Über den GET Befehl <code>availableFirmware</code> werden dann für die hinterlegte Hardware die passenden Versionen gesucht. Über das Attribut <code>updateChannelFW</code> kann zwischen "stable" und "testing" definiert werden, welche Art von Firmware angeboten werden soll.<br />
<br />
Nachdem die Firmwareversion erfragt wurde, bietet der set flash Befehl eine Auswahlliste an. Wird ein Flash Befehl mit einer der Versionen ausgewählt, wird diese Version zunächst heruntergeladen und bei den AVR Versionen auch versucht diese mittels avrdude zu flashen.<br />
Die Firmware für den ESP8266 kann aktuell leider noch nicht über diesen Befehl aktualisiert werden.<br />
<br />
Alternativ funktioniert aber auch die Option, dem Flash Befehl eine URL zu übergeben. Dann wird die Datei aus der URL heruntergeladen und auch versucht diese zu Flashen. z.B.<br />
SIGNALDuino_nanocc1101.hex für einen Nano mit CC1101<br />
<br />
<code>set sduino flash </code>https://github.com/RFD-FHEM/SIGNALDuino/releases/download/3.3.1/SIGNALDuino_radinocc11013.3.1.hex<br />
<br />
oder<br />
SIGNALESP_.hex (mit cc1101) für einen ESP8266 <br />
<code>set ipduino flash </code>https://github.com/RFD-FHEM/SIGNALDuino/releases/download/3.3.1/SIGNALDuino_ESP8266cc11013.3.1.hex<br />
<br />
!Achtung, aktuell wird die Firmware für den ESP dadurch nur herunter geladen. Flashen müsst ihr leider immer noch über ein passendes Tool <br />
z.B. [https://github.com/nodemcu/nodemcu-flasher ESP8266Flasher.exe] oder Esptool und einer seriellen Konsole.<br />
Auch ist zu beachten, es handelt sich hierbei tatsächlich um ein Binary und nicht um ein Hex File. <br />
<br />
Nach dem Booten des ESPs spannt dieser ein eigenes WLAN auf. Habt ihr euch damit verbunden, könnt ihr den ESP mit eurem vorhandenen WLAN nach Eingabe der Daten verbinden.<br />
<br />
Die Hauptseite für Firmware-Releases findet sich unter https://github.com/RFD-FHEM/SIGNALDuino/releases/ .<br />
Dort kann auch eine Änderungshistorie eingesehen werden.<br />
==== Flashen eines radino Boards mit ATmega32U4 ====<br />
<br />
Diese Funktion steht seit 21.02.2019 nun auch in der via FHEM aktualisierten Version zur Verfügung:<br />
<br />
Auch sind Berichte bekannt, dass der Radino beim Neustart von FHEM nicht korrekt initialisiert wird.<br />
Weiterhin ist zu beachten, dass der Bootloader eine andere USB ID bekommt und diese im Attribut <code>flashCommand</code> hinterlegt werden muss.<br />
<br />
==== Fehler beim Flashen ====<br />
Sollte bei einem Flash Vorgang ein Fehler auftreten, solltet ihr zunächst im Logfile mit Verbose 5 nachsehen.<br />
<br />
Findet ihr dort keine Fehlermeldung, gibt es noch ein separates Flashlog, welches ihr über einen Browser aufrufen könnt. Dazu müsst ihr nur den folgenden Pfad an euren Servernamen anhängen:<br />
<code><br />
/fhem/FileLog_logWrapper?dev=Logfile&type=text&file=SIGNALduino-Flash.log<br />
</code><br />
<br />
=== Geräteerkennung ===<br />
==== Unterstützte Geräte ====<br />
Für die folgenden Geräte gibt es derzeit (2017) eine Unterstützung für den Betrieb mit FHEM. Die Geräte werden [[autocreate|automatisch erkannt]] und in der Konfiguration eingetragen, wenn der SIGNALduino läuft.<br />
Bitte Geräte mit sehr präzisen Referenzen hier listen (Produktnummer, Protokoll-Variantenname etc.), damit eine globale Suche/Verifikation maximal erfolgreich ist. In der detaillierten Liste [[Geprüfte Geräte]] lassen sich die Geräte näher identifizieren.<br />
{| class="wikitable"<br />
! style="text-align:left;" | Produkt <br />
! (E)mpfangen<br />(S)enden <br />
! Hinweise <br />
! Verwendetes Modul <br />
! Protokoll ID<br />
|-<br />
|Conrad Wetterstation KW9110||E S||Sensor: KW9010, neben Temperatur u. Luftfeuchte werden auch Trend, Batterie u. Kanal erfasst|| CUL_TCM97001 || 0.3<br />
|-<br />
|TCM Wetterstation (97001 und 21xxx Serie)||E|| || CUL_TCM97001 || 0<br />
|-<br />
|ABS Wetterstation (ABS 700)||E|| || CUL_TCM97001 || 0<br />
|-<br />
|Prologue Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|Rubicson Wetterstation ||E|| ||CUL_TCM97001 ||0 <br />
|-<br />
|NC_WS Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|[http://www.gt-support.de/ GT-WT-02 Wetterstation]||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|AURIOL Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|Mebus Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|Intertechno Funkschalter||E S|| ||IT || 3,4,5,17<br />
|-<br />
|<strike>Conrad RSL Funkschalter</strike>||E S|| Funktioniert aktuell nicht || SIGNALduino_RSL || <br />
|-<br />
|[http://global.oregonscientific.com/product_view.php?id=5 Oregon Scientific Wettersensoren]||E || Protokoll V2 & V3 implementiert || OREGON || 10<br />
|-<br />
|Bresser Temp/Hydro Sensor||E || || Hideki || 12<br />
|-<br />
|[https://de.hama.com/00104985/hama-aussensensor-ts33c-fuer-wetterstation Hama TS33C]||E || || Hideki || 12<br />
|-<br />
|TFA Temp/Hydro Sensor||E || || Hideki || 12<br />
|-<br />
|Lacrosse TX2/TX3 Sensoren||E || || CUL_TX || 8<br />
|-<br />
|TFA 30320902||E || || SD_WS07 || 7<br />
|-<br />
|Eurochron eas800z||E || || SD_WS07 || 7<br />
|-<br />
|Technoline WS6750/TX70DTH||E || || SD_WS07 || 7<br />
|-<br />
|FreeTec Außenmodul NC-7344||E || || SD_WS07 || 7<br />
|-<br />
|CTW600||E || || SD_WS09 || 9<br />
|-<br />
|CTW602||E ||neuere Version des CTW600 mit 868.35 MHz || SD_WS09 || 9<br />
|-<br />
|WH1080||E || || SD_WS09 || 9<br />
|-<br />
|Visivon remote pt4450||E || || none || 24<br />
|-<br />
|Einhell HS 434/6||E || || none || 21<br />
|-<br />
|Flamingo FA20RF / FA21RF / FA22RF Rauchmelder||E || || FLAMINGO || 13,13.1,13.2<br />
|-<br />
|mumbi m-FS300||E || || none || 26,27<br />
|-<br />
|TFA 30.3200||E || || none || 33<br />
|-<br />
|Livolo||E|| || none || 20<br />
|-<br />
|Smartwares RM174RF/2 (RM174RF-001CPR) 4500177571 ||E [S?]|| IT EV1527; TODO herausfinden: Alarmierung (wie Alarmton getriggered werden kann); Batterieinfo? || IT || 3<br />
|-<br />
|Smartwares SH5-TSO-A||E S|| || IT || ?<br />
|-<br />
|X10 Security Devices||E|| || || 39<br />
|-<br />
|[[Somfy_via_SIGNALduino|Somfy RTS]]||E S|| || SOMFY || 43<br />
|}<br />
Bei einigen ''Intertechno''-Funksteckdosen (''Brennenstuhl'') kann es zu Empfangsproblemen kommen. Hier muss die Taktrate, mit der gesendet wird, angepasst werden. Dazu muss für ''Funksteckdose'' (also sauber per-Client-Instanz-spezifisch, NICHT SIGNALduino-Transceiver-global) das Attribut <br />
:<code>attr <Funksteckdose> ITclock 300</code> <br />
gesetzt werden, der Standardwert ist 250.<br />
<br />
==== Mein Gerät wird in FHEM nicht erkannt ====<br />
1. Prüfen, ob vom Sensor die Signaldaten (<code>verbose</code> >=4) erkannt werden. Sobald ihr die empfangenen Signaldaten im Logfile zuordnen könnt, geht es weiter mit:<br />
<br />
2. Eröffnet ein Thema unter [https://github.com/RFD-FHEM/RFFHEM/issues/new?template=sensor---device-feature.md github]:<br />
<!-- <syntaxhighlight lang="md"> ... markdown lexer not yet available; use pre instead --><br />
<pre><br />
## Specifications for new sensor / switch / or other device ... <br />
<br />
- manufacturer:<br />
- model name:<br />
- pictures of the device / the board (very helpful)<br />
<br />
<br />
## Specifications <br />
<br />
- Microcontroller:<br />
- Version (Firmware):<br />
<br />
<!-- ( can be found here devicename -> Internals -> version ) --><br />
- Versionmodul (FHEM Module):<br />
</pre><br />
<br />
3. Auszug aus dem Logfile, welches zum Gerät gehört.<br />
:''Alles was ihr sonst noch über das Gerät und die übertragenen Daten wisst.''<br />
<br />
Im Forum solltet ihr solche Fragen besser nicht posten, wenn das Gerät noch nicht unterstützt wird, dazu ist Github besser geeignet. Inzwischen wurde im Wiki eine eigene Seite eröffnet, die sich mit der Erkennung unbekannter Protokolle beschäftigt: [[Unbekannte_Funkprotokolle#Ansatz_1_-_Versuchen|Unbekannte_Funkprotokolle]].<br />
<br />
==== Es wird ein Protokoll erkannt, Autocreate legt aber kein device an ====<br />
Im SIGNALduino sind >70 Protokolle implementiert. Jedoch gibt es nicht immer ein logisches Modul, welches diese Protokolle verarbeitet.<br />
Teilweise ist das auch nicht zwingend notwendig, um seine Anforderungen zu erfüllen. Insbesondere für Schalter bzw. Sensoren, die nur zwei Zustände kennen, geht es meist auch kurz und knapp manuell (also ohne Modul und automatisch angelegtem Gerät).<br />
<br />
Nehmen wir an, wir haben einen Schalter. Dieser kann einen oder zwei Zustände senden.<br />
Im FHEM Log (und, insbesondere, im FHEMWEB Event Monitor) tauchen Meldungen ähnlich dieser auf<br />
<br />
<code><br />
2015.11.15 15:52:23 4: SIGNALduino_unknown incomming msg: u85#FF8081<br />
</code><br />
<br />
Wir können mit Hilfe des Modules DOIF auf diese Nachricht eine Aktion ausführen:<br />
<br />
Entweder, wenn wir den Inhalt der Nachricht nur zu Teilen wissen, da er sich ändert:<br />
<br />
<code><br />
define mydoif DOIF ([sduino:&DMSG] =~ "u85#FF8081") (set Lamp on)<br />
attr mydoif do always<br />
</code><br />
<br />
Oder, wenn wir den Inhalt exakt kennen, dann auch als Vergleichsstring<br />
<br />
<code><br />
define mydoif DOIF ([sduino:&DMSG] eq "u85#FF8081") (set relais on)<br />
attr mydoif do always<br />
</code><br />
<br />
Der Teil u85#FF8081 muss individuell angepasst werden, der Name eures SIGNALduino möglicherweise auch.<br />
<br />
Als Alternative zu DOIF hier ein regex-verwendendes [[notify]]-Beispiel für einen Sender, der meint, zwei Codes alternierend senden zu müssen:<br />
<br />
<code><br />
define n_sender_trigger notify sduino:UNKNOWNCODE.*u41#(13B72253|163873B3) { my_sender_trigger_indicate();; }<br />
</code><br />
<br />
Selbstverständlich muss in diesem Moment auch eine <code>sub my_sender_trigger_indicate()</code> definiert werden (z.B. in <code>FHEM/99_myUtils.pm</code>), die dort z.B. als Test eine Log-Ausgabe (<code>Log3()</code>) machen kann.<br />
<br />
=== Das Logfile ===<br />
Im Logfile ab [[verbose]] 4 tauchen diverse Meldungen auf, deren Bedeutung kurz erläutert wird (<code>verbose</code> 3 unterdrückt diese Meldungen).<br />
<br />
UPDATE: der folgende Bereich ist von einem weniger erfahrenen Zeitgenossen früher nach Kräften erweitert/geschrieben worden. Mittlerweile existiert aber ein neuer Inhalt [[Unbekannte Funkprotokolle]] (siehe auch Erwähnung weiter oben), der als sehr gut beschrieben und unvergleichlich detailreicher bezeichnet werden muss ("endlich gibt es sowas!"). Der Bereich hier dürfte somit zwar für grundlegende Verdeutlichungen noch recht sinnvoll sein, der Inhalt sollte allerdings evt. in eine konsistente Dokumentation überarbeitet (verlagert/dedupliziert/reduziert) werden.<br />
<br />
Die Protokolle (von der SIGNALDuino-Firmware gesendete Signal-Beschreibungs-Strings) können wie folgt unterschieden werden:<br />
<br />
*MS - Nachricht mit Sync Puls: Hierzu ein Beispiel<br />
:<code>MS;P0=-108;P1=395;P2=-1033;P3=-547;P4=-19932;P5=-8916;P6=1368;D=151313131312131313131313131313131312121212121313131313131312131212132;CP=1;SP=5;</code> P0-P6 sind die Signalpegel (Dauer und Vorzeichen): Die Zahl gibt in Mikrosekunden die Zeitdauer an, das Vorzeichen bestimmt, ob es sich um eine gesendetes Signal gehandelt hat (positives Vorzeichen) oder ob das Signal gerade pausierte (negatives Vorzeichen). Insofern ist die Beschreibung "negatives Signal" irreführend - es gab in der Zeitspanne gerade kein Signal. Hinter D= befindet sich die Abfolge der Signale. Die ersten beiden Ziffern 15 in D sind wie folgt zu lesen. Zuerst wurde 395 Mikrosekunden (P1) ein Signal gesendet (weil P1='''+'''395), danach gab es 8916 Mikrosekunden kein Signal (Pause, wegen P5='''-'''8196). CP=1 ist die Referenz auf den Takt des Signales - der Basistakt ist in diesem Fall ~395 Mikrosekunden. SP=5 gibt die Referenz zum Syncpuls an, der das gesamte Signal einleitet. Welche Signalfolge nun eine binäre 1 bzw. 0 bedeutet, wird im SIGNALduino über die integrierte Protokoll Liste realisiert.<br />
<br />
*MC - Nachricht vom Typ Manchester: Manchesterkodierte Signale können bereits sehr einfach im Arduino in eine Binärform umgewandelt werden. Es wird hier nach IEEE 802.3 umgewandelt. In Manchester Signalen gibt es lange und kurze Pulse. Deren Durchschnittswert wird mit LL (long low), LH (long high), SL (short low) und SH (short high) übermittelt. Zusätzlich, um das Protokoll schneller erkennen zu können, wird die Taktfrequenz mit übermittelt (C=429 Mikrosekunden). Die Daten befinden sich hinter D= und werden in HEX Form übergeben.<br />
:<code>MC;LL=-1066;LH=904;SL=-562;SH=385;D=332B4B4D54D5554B552CD2D554B2B5354A;C=429;</code><br />
<br />
*MU - Message unsynced: Diese Art von Nachrichten sind nicht nach Manchester codiert und haben auch keinen erkennbaren Sync / Clock Signalpegel am Start der Nachricht. Bei diesen Nachrichtentypen ist es, im Vergleich zu den anderen, am wahrscheinlichsten, dass das übermittelte Signal unvollständig oder überhaupt kein Signal ist. Wie bei MS sind P0-P6 die Signalpegel und in D= wird die Abfolge der Signalpegel referenziert. CP=2 gibt auch hier die Referenz zum Takt an, allerdings muss dieser nicht korrekt erkannt worden sein.<br />
:<code>MU;P0=1372;P1=-580;P2=362;P3=-1047;D=01212321212321212121212121212123212123212321232121212121212321;CP=2;</code><br />
<br />
Es erscheinen viele Meldungen dieser Art:<br />
<br />
<pre><br />
Fingerprint for MU Protocol id xxxx -> yyy matches, trying to demodulate<br />
sduino: Starting demodulation at Position 1<br />
Fingerprint for MU Protocol id 28 -> IC Ledspot matches, trying to demodulate<br />
sduino: Starting demodulation at Position 1<br />
Fingerprint for MU Protocol id 29 -> HT12e remote matches, trying to demodulate<br />
</pre><br />
<br />
Dies sind nun Bemühungen, anhand der von der SIGNALDuino-Firmware gelieferten rohen aber detaillierten Signal-Strings eine Vor-Analyse / Fingerprinting vorzunehmen.<br />
Man könnte nun z.B. bei solchen Fingerprinting-Analysen erkennen:<br />
* dass der Basis-Takt-Wert innerhalb eines charakteristischen Zeit-Bereichs liegt<br />
* dass die Anzahl der Sync-Pulse eine präzise Zahl ist<br />
* dass Längen erkannter Puls-Typen innerhalb eines Bereichs liegen<br />
<br />
Mittels solcher Untersuchungen kann man also final hoffentlich hinreichend plausibel feststellen, "dass diese Aktivitäten offensichtlich(?) zu einer Funk-Komponente Rauchmelder von Hersteller XYZ gehören müssen, und man somit weiterleiten muss an ein (möglicherweise bereits existierendes) Userdaten-Dekodier-Modul für diese Herstellerkomponente".<br />
<br />
<br />
Bei einer dann erfolgenden Demodulation des noch rohen SIGNALDuino-Strings könnte man z.B. (hoffentlich richtigerweise) annehmen, dass eine Signalpegel-Typ-Folge "13" eine binäre 1 bedeuten soll, während eine Folge "12" eine binäre 0 bedeuten soll. Man erhält aus dem Gesamt-Puls-String also nach vollständiger Demodulation eine Abfolge von vielen 0/1 Bits, die insgesamt ein Datenwort darstellen, mit einer gewissen Länge von NN bits (diese Längen-Angabe könnte übrigens - neben Namenssuche nach Hersteller oder Produkt etc. - ein wichtiges Internet-Such-Merkmal sein, ob andere Frameworks tatsächlich bereits wissen, wie Daten dieser Funk-Komponente zu dekodieren sind!). Dieses demodulierte Datenwort ist nun das finale Datenwort, welches einen Container für die Funk-Komponenten-Informationen darstellt (in diesem Container also beispielsweise folgende Bits-Bereiche enthalten: Temperatur, Feuchte, Akku-Status, ID, Alarm, ... - zumindest wenn nicht dummerweise der ganze Daten-Container erst einmal CRC- oder Crypto-verschlüsselt ist...).<br />
<br />
Man muss an dieser Stelle unbedingt sagen, dass dieses Userdaten-Datenwort (einer bestimmten Hersteller-Funk-Komponente!) natürlich bei ''jeglichen'' Transceiver-Systemen ''immer'' gleich (identisch) erkannt werden ''muss'' - an dieser Stelle ist also ganz klar, dass diese Daten an ''allgemeine'' FHEM-Module weitergeleitet (Dispatched) werden müssen, die nach Übernahme von Daten von ''jeglichen'' Transceiver-Systemen diese Daten immer auf die gleiche Weise ('''''generisch/zentral''''') für die jeweilige Hersteller-Funk-Komponente erledigen.<br />
<br />
'''Die Abfolge ist also ganz klar:'''<br />
Funk-Aktivität --> Transceiver-Gerät/Firmware (SIGNALDuino) --> maximal detailreich beschreibender Rx-Analyse-Output-String --> Fingerprinting-Grobzuordnung des (SIGNALDuino-Firmware-)Outputs (durch 00_SIGNALduino.pm) auf gerätespezifisches Verhalten --> ''generische/zentrale'' Dekodierung des gerätespezifischen Protokoll-Datenworts, in zentralen Grundsatz-Modulen wie z.B. <code>14_SD_WS.pm</code>).<br />
<br />
Und wenn dann bei einer solchen Schritte-Abfolge irgendetwas noch fehlen/unpassend sein sollte, dann muss eben entsprechendes Development an gewissen Stellen erfolgen ;-)<br />
<br />
====Minimieren (whitelist/blacklist) von unerwünschter Kommunikations-Aktivität/Einträgen====<br />
<br />
"Unknown Code" bedeutet, dass der SIGNALduino Signaldaten empfangen und diese binär interpretiert hat. Diese Meldung soll uns nun aber mitteilen, dass es dann nicht weiter verarbeitet werden kann, da kein Modul existiert (oder kein Weiterleitungs-Dispatch zu einem bereits existierenden), welches diese Daten jetzt in ihre Bedeutung umwandeln kann. <br />
:<code>sduino: Unknown code u1FFFFF0, help me!</code><br />
<br />
Außerdem kommt es gehäuft zu Logmeldungen und auch Events in ähnlicher Form:<br />
:<code>SIGNALduino_unknown incomming msg: u85#FF8081</code><br />
<br />
Mittlerweile sind über 50 Protokolle für den SIGNALduino definiert. Dadurch kommt es vor, dass sich ein Signal mit mehr als einem Protokoll demodulieren lässt. Meist führt dies dann zu zusätzlichen "Unknown code"-Einträgen.<br />
<br />
Derartige Einträge können mit dem Attribut <code>WhitelistID</code> minimiert werden. Dabei werden die Geräte, die nach Daten-Empfang tatsächlich verarbeitet werden sollen (also welche Protokolle vom FHEM Modul berücksichtigt werden), mit ihrer Protokollnummer in die <code>WhitelistID</code> aufgenommen.<br />
Für Protokolle, die nicht berücksichtigt werden, gibt es weder Logeinträge noch Events. Diese werden im Programmablauf nicht berücksichtigt. Das spart zum einen Ressourcen und trägt auch zur Übersichtlichkeit bei. <br />
Die Protokollnummer kann der Tabelle [[#Unterstützte Geräte|Unterstützte Geräte]] entnommen werden (hilfreich ist es auch, wenn in den verwendeten Geräten im Internal <gerätename>_DMSG nachgesehen wird). So bedeutet beispielsweise ein Eintrag der Form <code>W50#FF553335FFBC</code> dass dann das Protokoll #50 in die Whitelist aufzunehmen wäre (<code>attr sduino whitelist_IDs 50</code>).<br />
{{Randnotiz|RNTyp=r|RNText=Achtung Schreibweise: Dokumentation oft als WhitelistID o.ä., aber Name ist whitelist_IDs!!<br />
}}<br />
Die Angabe erfolgt durch Komma getrennt: z.B.:<br />
:<code>1,2,5,10</code><br />
<br />
=== Senden mit dem SIGNALduino ===<br />
Der SIGNALduino kann etwas "raw senden", indem ihm das Signal so übermittelt wird, wie er es moduliert. Hierzu muss der Befehl wie folgt eingegeben werden:<br />
<br />
<code><br />
set sduino sendMsg P3#00111010#R4<br />
</code><br />
<br />
Dieser Befehl moduliert die Bitfolge 00111010 mittels Protokoll #3 und wiederholt die Nachricht 4x.<br />
Die Protokoll Nummer kann aus einer empfangenen Nachricht extrahiert werden. Ebenso die Bits.<br />
<code><br />
sduino: extracted data 00111010 (bin)<br />
sduino: Found Protocol id 3 <br />
</code><br />
<br />
Alternativ kann das Signal auch in einer "Rohform" angegeben werden. Dies ist manchmal in speziellen Fällen notwendig:<br />
<code><br />
set sduino raw SR;;R=3;;P0=4742;;P1=-1554;;P2=286;;P3=-786;;P4=649;;P5=-420;;D=0123234545234545452323232323454523234523454523232345454523232323452345234523452345;;<br />
</code><br />
<br />
R=3 bedeutet, das Signal wird 3x gesendet.<br />
Die Übertragung besteht aus den in D angegebenen Pulsen, welche in P0-P5 definiert werden.<br />
Die Daten kann man aus einer empfangenen MS oder MU Nachricht extrahieren.<br />
<br />
Alternativ kann ab Version 3.2 auch eine vereinfachte Form eingegeben werden.<br />
<br />
====Fehlersuche====<br />
(Zielgerät reagiert nicht, etc.)<br />
<br />
* Nachrichtenwiederholungsanzahl muss evt. für manche Geräte entsprechend groß eingestellt sein<br />
{{Randnotiz|RNTyp=r|RNText=VORSICHT blöder Schreibweisen-Mismatch ITClock vs. ITclock!!}}<br />
* Sende-Takt-Wert (Clock) passt evt. nicht ganz, siehe z.B. Thread-Antwort {{Link2Forum|Topic=58397|Message=775434|LinkText=Signalduino Version 3.3.1}}, wo für IT-Geräte ein Attribut anhand der CP= des Empfangsdaten-Logs modifiziert wird. ACHTUNG: dies kann entweder global das Internal-Attribut <code>ITClock</code> eines SIGNALduino-Transceiver-Devices sein, oder (viel besser da korrekt Geräte-Instanz-spezifische Konfiguration) das <code>ITclock</code> eines IT-Client-Devices.<br />
<br />
== Fehlerbehandlung ==<br />
<br />
=== Modul-Initialisierung ===<br />
<br />
==== Perl-Modul Digest::CRC fehlt ====<br />
<br />
Das FHEM-Log kann (bei Version ab 3.5.x) folgendes enthalten:<br />
<br />
<code>Can't locate Digest/CRC.pm in @INC (you may need to install the Digest::CRC module) (@INC contains: fhem.p/lib fhem.p/FHEM/lib ./FHEM/lib ./lib ./FHEM ./ /usr/local/FHEM/share/fhem/FHEM/lib /opt/fhem . /etc/perl /usr/local/lib/arm-linux-gnueabihf/perl/5.28.1 /usr/local/share/perl/5.28.1 /usr/lib/arm-linux-gnueabihf/perl5/5.28 /usr/share/perl5 /usr/lib/arm-linux-gnueabihf/perl/5.28 /usr/share/perl/5.28 /usr/local/lib/site_perl /usr/lib/arm-linux-gnueabihf/perl-base) at ./FHEM/00_SIGNALduino.pm line 28, <$fh> line 1870.<br />
BEGIN failed--compilation aborted at ./FHEM/00_SIGNALduino.pm line 28, <$fh> line 1870.</code><br />
<br />
In diesem Fall ist der Transceiver nicht funktionsfähig - es muss erst Perl-Modul <code>Digest::CRC</code> (Ubuntu und Debian: Package <code>libdigest-crc-perl</code>) installiert werden und fhem neu gestartet werden.<br />
<br />
=== Konfiguration von Firmware/Hardware (Reset usw.) ===<br />
Der SIGNALduino kann mit folgendem Befehl auf Werkseinstellungen zurückgesetzt werden:<br />
:<code>set raw e</code><br />
Ob ein solcher Reset nötig ist, erkennt man an dem Inhalt vom Reading <code>cc1101_config</code>, dort unsinnige Werte angezeigt werden oder dem Reading <code>config</code> welches durch den Befehl "get config" aktualisiert wird, was im Standard auf "MS=1;MU=1;MC=1" entspricht.<br />
<br />
In der Firmware sind diverse Befehle eingebaut, welche über einen <code>set raw</code> Befehl im Modul direkt ausgeführt werden können. Sofern möglich, sollte die Abfrage von Werten aus dem Modul allerdings mit den dafür vorgesehenen Kommandos erfolgen, da die Rückmeldungen des <code>set raw</code> Befehls nur im Logfile ab verbose 4 erscheinen. Die Befehle sind nützlich, wenn direkt auf den Microcontroller zugegriffen wird: <br />
<br />
:<code>C<reg></code> <reg> is a (two digit) hex number: return the value of the cc1101 register. <reg>=99 dumps the first 48 registers. Example: <code>set raw C35</code> führt ab verbose 4 zu einer Logausgabe folgender Art: <code>Read, msg: C35 = 0D</code><br />
:<code>e</code> EEPROM / factory reset. resets all eeprom values without reboot<br />
:<code>W<AA><XX></code> Write eeprom (schreibt einen Wert ins EEPROM und ins CC1101 Register. Die EEPROM Adresse hat einen Offset von 2. z.B W041D schreibt 1D ins Register 2 des CC1101)<br />
<br />
Die Sendeleistung lässt sich mit <br />
:<code>get sduino ccpatable</code> <br />
<br />
prüfen, wobei die Rückmeldung wie folgt zu lesen ist: <br />
"-10_dBm" => '34',<br />
"-5_dBm" => '68',<br />
"0_dBm" => '60',<br />
"5_dBm" => '84',<br />
"7_dBm" => 'C8',<br />
"10_dBm" => 'C0' <br />
Dabei wird die Sendeleistung dauerhaft mit dem Befehl<br />
:<code>set sduino cc1101_patable <value></code><br />
hochgeschaltet (<value> durch den Wert ersetzen).<br />
<br />
Weitere Firmware-Befehle sind im Thread-Beitrag {{Link2Forum|Topic=58396|Message=497921}} zu finden.<br />
<br />
== Foren Links ==<br />
* {{Link2Forum|Topic=38402|LinkText=Forenthread - Ankündigung}}<br />
* {{Link2Forum|Topic=58396|LinkText=SIGNALDuino Empfänger Firm- und Hardware}}<br />
* {{Link2Forum|Topic=82379|Message=1033374|LinkText=SIGNALDuino Schaltplan}}<br />
* {{Link2Forum|Topic=58397|LinkText=Signalduino Entwicklung Version 3.3.1 }}<br />
* [http://www.rflink.nl/blog2/wiring Beschreibung zu diversen Empfängern und Verbesserung der Empfangsleistung]<br />
* [[SIGNALduino in die Arduino Entwicklungsumgebung einbinden]]<br />
* [[Somfy via SIGNALduino]]<br />
<br />
[[Kategorie:Interfaces]]<br />
[[Kategorie:Arduino]]<br />
[[Kategorie:433MHz]]<br />
[[Kategorie:868MHz]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Color&diff=37632Color2022-11-03T09:01:00Z<p>Andies: /* Beispiele */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Hilfsfunktionen zur modulübergreifenden Benutzung von Farben.<br />
|ModType=h<br />
|ModCmdRef=intro <!-- no help section available --><br />
|ModForumArea=Sonstiges<br />
|ModTechName=Color.pm<br />
|ModOwner=Andre ([http://forum.fhem.de/index.php?action=profile;u=430 Forum] / [[Benutzer Diskussion:justme|Wiki]])}}<br />
<br />
[[Color]] soll modulübergreifend Funktionen bereitstellen, die die Interaktion mit farbigen Lampen erleichtern. Es wird zur Zeit von [[Hue|HUEDevice]] und dem [[panStamp#Section SWAP_0000002200000003|SWAP RGB Driver]] Modul sowie von FRM_RGB und PHTV und verwendet.<br />
<br />
== Benutzung ==<br />
Um die im Folgenden beschriebenen Funktionen zu nutzen, muss die Datei Color.pm eingebunden werden. Ein Modulautor kann das durch eine <br />
:<code>use Color;</code> <br />
Anweisung in seinem Modul tun. Ein Endanwender mit einem notify:<br />
:<code><nowiki>define colorInit notify global:INITIALIZED {use Color}</nowiki></code><br />
<br />
== Colorpicker ==<br />
[[Datei:SWAP_0000002200000003.png|thumb|Colorpicker und Presets]]<br />
Der colorpicker stellt ein FHEM-Web Widget bereit, das es ermöglicht, in der webCmd Liste interaktiv eine Farbe einzustellen oder fest definierte presets zur Auswahl zu stellen. Hierzu sind je nach reading folgende Schritte nötig:<br />
<br />
=== RGB Farbe ===<br />
* Ein entsprechendes Kommando, das den colorpicker verwendet, in der 'set ?' liste des Moduls vorsehen (oder eines mit widgetOverride überschreiben):<br />
:<code>... <rgb>:colorpicker,RGB ...</code><br />
<br />
Nun lässt sich das Kommando ''rgb'' auf zwei Arten in der webCmd Liste verwenden:<br />
* ohne Parameter: um ein interaktives Eingabefeld für einen RGB-Farbwert einzublenden <br />
* mit einem RGB-Wert als Parameter, um einen festen Preset einzublenden<br />
:<code>attr <device> webCmd rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:toggle:on:off</code><br />
<br />
Bei jedem Seitenaufbau wird der Wert zum Initialisieren des colorpicker aus dem Reading mit dem gleichen Namen wie das set-kommando geholt.<br />
<br />
=== RGB als HSV ===<br />
[[Datei:Colorpicker_HSV.png|mini|rechts|350px|Colorpicker im HSV Modus]]<br />
Eine RGB Farbe lässt sich alternativ auch über den HSV Mode einstellen. Hierbei werden untereinander jeweils ein Schieberegler für Farbton, Sättigung und Helligkeit dargestellt.<br />
... rgb:colorpicker,HSV ...<br />
attr <device> webCmd rgb<br />
<br />
Alternativ lässt sich als Mode statt <code>HSV</code> auch <code>HSVp</code> verwenden. Dann werden die Schieberegler bei einem Klick auf das Widget in einem Popup-Fenster eingeblendet.<br />
<br />
=== echtes HSV ===<br />
Wenn das Device kein RGB Reading und Kommando hat aber ein HSV Reading und drei Kommandos um Farbton, Sättigung und Helligkeit einzustellen lässt sich die folgende Variante verwenden:<br />
... hsv:colorpicker,HSV,hue,0,1,360,sat,0,1,100,bri,0,1,100 ...<br />
d.h. es wird nach dem <code>HSV</code> oder <code>HSVp</code> Schlüsselwort für jedes der drei Kommandos der Name und der wertebereich mit Komma getrennt angegeben. Falls es im Device das nötige Reading mit den aktuellen Werten nicht gibt lässt sich dieses mit einem user reading z.B. wie folgt erzeugen:<br />
attr <device> userReadings hsv {ReadingsVal($name,'hue','0').','.ReadingsVal($name,'sat','100').','.ReadingsVal($name,'bri','100')}<br />
<br />
=== Farbtemperatur ===<br />
Der colorpicker lässt sich auch für die Farbtemperatur (ct, in Kelvin oder Mired) verwenden. Hier ein Beispiel für die Set-Liste eines ct Kommandos mit erlaubten Werten von 2000 bis 6500 Kelvin und eine webCmd Definition mit ct slider und 4 ct Presets.<br />
... ct:colorpicker,CT,2000,10,6500 ...<br />
attr <device> webCmd ct:ct 2040:ct 2630:ct 3703:ct 6250:on:off<br />
<br />
=== Farbton ===<br />
[[Datei:Colorpicker_webCmd.png|mini|rechts|400px|Colorpicker im CT, HUE und RGB-Preset Modus]]<br />
<br />
In der aktuellen Version lässt sich der colorpicker auch für den Farbton (hue) verwenden (ab 11.03.2022 auch mit presets):<br />
<br />
<br />
... hue:colorpicker,HUE,0,1,359 ...<br />
attr <device> webCmd hue:rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:rgb ffffff:on:off<br />
<br />
=== Helligkeit ===<br />
[[Datei:Colorpicker_bri.png|mini|rechts|400px|Colorpicker im BRI Modus]]<br />
<br />
In der aktuellen Version lässt sich der colorpicker auch als Slider der mit einem Graukeil hinterlegt ist verwenden um z.b. die Helligkeit (bri,pct,...) einzustellen:<br />
... pct:colorpicker,BRI,0,1,100 ...<br />
attr <device> webCmd pct:toggle:on:off<br />
<br />
Die Slider für Farbtemperatur, Farbton und Helligkeit sind jeweils mit einem passenden Hintergrund hinterlegt.<br />
<br />
== Farbige Lampen Icons ==<br />
Die Funktion Color_devStateIcon($) erzeugt aus einem übergebenen RGB Wert in der Form "RRGGBB" einen devStateIcon String für farbige SVG Icons (die bunten Blobs werden noch nicht unterstützt). Der Aufruf kann z.B. so zum Setzen des devStateIcons verwendet werden:<br />
:<code>attr <device> devStateIcon {Color_devStateIcon(ReadingsVal($name,"rgb","000000"))}</code><br />
oder<br />
:<code>attr <device> devStateIcon {Color_devStateIcon(CommandGet(undef,"$name rgb"))}</code><br />
<br />
'''NEU:'''<br />
Im Namespace Color gibt es eine zweite, experimentelle Version einer devStateIcon Funktion. Diese unterstützt neben farbigen Lampen auch Dimmer und Schalter. Hier muss der Name (oder hash) des FHEM-Device, ein String der den Typ der Lampe festlegt und bis zu drei Namen von Readings, die den RGB-Wert, die aktuelle Helligkeit im Bereich 0-100 und den Ein/Aus Status enthalten. Also:<br />
:<code><nowiki>Color::devStateIcon( <name|hash>, <type>, <rgb reading>, <percent reading>, <on/off reading> );</nowiki></code><br />
<br />
In <code>type</code> kann zur Zeit <code>rgb</code>, <code>dimmer</code> oder <code>switch</code> übergeben werden. Im Reading für die Helligkeit wird neben den Werten 0-100 auch <code>on</code> und <code>off</code> verstanden.<br />
<br />
Ein Beispiel für eine Lampe, die im Reading <code>rgb</code> die aktuell eingestellte Farbe und im Reading <code>state</code> on oder off enthalten kann: <br />
:<code><nowiki>attr meineLampe devStateIcon {Color::devStateIcon($name,"rgb","rgb","state")}</nowiki></code><br />
<br />
Um z.B. einen WeekdayTimer, der eine Lampe steuert, mit einem passenden Icon zu versehen, könnte man folgendes verwenden:<br />
:<code><nowiki>attr FlurTimer devStateIcon {Color::devStateIcon($name,"dimmer",undef,"state")}</nowiki></code><br />
[[Datei:Colorpicker_devStateIcons.png|mini|rechts|400px|Beispiel mit Nutzung der unterschiedlichen Möglichkeiten]]<br />
Das Icon des WeekdayTimer stellt dann den Zustand dar, mit dem die Lampe aktuell über den Timer gesteuert wird. Nicht den aktuellen Zustand der Lampe, die ja auch anderweitig gesteuert werden kann.<br />
<br />
'''ToDo''': Bestimmen der Helligkeit über den RGB-Wert, wenn kein Reading dafür angeben ist.<br />
<br />
'''Fragen''': <br />
* Ist es für das Interface besser, jeweils direkt die Werte zu übergeben oder die Namen der Readings in denen die Werte zu finden sind?<br />
* Sollte angegeben werden können, welchen Wertebereich die Helligkeit haben kann?<br />
<br />
Zwei Beispiele für die Verwendung und Kombination der oben beschriebenen Routinen gibt es in der fhem.cfg.demo im Simulator für farbige Lanpen.<br />
<br />
== Routinen um zwischen Farbräumen und Darstellungen zu konvertieren ==<br />
Color::rgb2hsv<br />
Color::hsv2rgb<br />
Color::hsb2rgb<br />
Color::rgb2hsb<br />
Color::hex2hsv<br />
Color::hsv2hex<br />
Color::hex2hsb<br />
Color::hsb2hex<br />
Color::hex2rgb<br />
Color::rgb2hex<br />
Color::ct2rgb<br />
Color::xyY2rgb<br />
Color::xyY2hex<br />
<br />
== Farbskala mit Color::pahColor ==<br />
Das auf der Seite [[Temperaturfarbe]] beschriebene Verfahren ist über die Routine <code>Color::pahColor</code> verfügbar, siehe auch {{Link2Forum|Topic=30128|LinkText=diesem Beitrag im FHEM Forum}}.<br />
<br />
:<code><nowiki>Color::pahColor($starttemp,$midtemp,$endtemp,$temp,$colors,$opacity)</nowiki></code><br />
<br />
<code>$colors</code>: Mit [[Temperaturfarbe#Skala_0 | 0]], [[Temperaturfarbe#Skala_1 | 1]] oder [[Temperaturfarbe#Skala_2 | 2]] wird das verwendete [[Temperaturfarbe | Farbmodell]] ausgewählt. Ein selbst definiertes Farbmodell kann als array-ref übergeben werden.<br />
<br />
=== Beispiele ===<br />
Steuern einer Lampe in Abhängigkeit von einer Temperatur:<br />
define <n> notify mytemp:temperature.* {fhem("set lampe rgb ".substr(Color::pahColor(0,15,30,$EVTPART1,0,0),0,6))}<br />
<br />
Einfärben eines Temperaturwertes in einer [[readingsGroup]]:<br />
attr <rg> valueStyle { temperature => '{"style=\"color:\x23".substr(Color::pahColor(0,15,30,$VALUE,0),0,6)."\""}'}<br />
<br />
Einfärben eines Feuchte-Readings in einer readingsGroup:<br />
:<code><nowiki>attr <rg> valueStyle { humidity => '{style=\"color:\x23".substr(Color::pahColor(0,50,100,$VALUE,[255,255,0, 127,255,0, 0,255,0, 0,255,255, 0,127,255]),0,6)."\"}'}</nowiki></code><br />
Hier wird die folgende Farbzuordnung verwendet:[[Datei:color-humidity.png]]<br />
<br />
Anmerkung: {{Taste|\x23}} ist die hexadezimale Escapesequenz für das {{Taste|#}} Zeichen, das beim Einlesen der [[Konfiguration]] sonst als Kommentar interpretiert werden würde. Ist mit aktuellen FHEM Versionen nicht mehr nötig. Das {{Taste|#}} Zeichen kann direkt verwendet werden.<br />
<br />
Es gibt Fälle, in denen ein Farbverlauf für Warnungen/Fehler angezeigt werden soll. Hier bietet sich kein Temperaturähnlicher Verlauf an, weil die Farbfolge nicht von blau über grün zu gelb/rot gehen soll, sondern vielmehr die typische Anzeige schwarz ist, bei Warnungen gelb und bei Fehlern rot sein soll. Im Folgenden Beispiel sollen Zahlenwerte dann gefärbt werden, wenn sie vom Normwert abweichen. Als Beispiel diene eine Füllstandsanzeige (im konkreten Fall geht es um "noch betreibbare Zeit in Wochen"), die von etwa 7 bis 12 im Normbereich liegt (Anzeige schwarz), von etwa 3 bis 6 im Warnungsbereich (gelb) und zwischen 0 und 3 eine Fehlermeldung (rot) ergeben soll. Auch hier kann man pahColor verwenden. Die Farbpalette wird wie folgt erzeugt<syntaxhighlight lang="perl"><br />
sub Farbtester()<br />
{my $s = "";;<br />
my <br />
$farbe = substr(Color::pahColor(0,5,12,0,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>0 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,1,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>1 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,2,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>2 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,3,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>3 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,5,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>5 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,6,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>6 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,7,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>7 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,8,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>8 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,9,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>9 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,10,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>10 </span>";<br />
return $s}<br />
</syntaxhighlight>und das Ergebnis sieht dann wie im Bild unten aus.<br />
[[Datei:Farbpalette Schwarz bis Rot.png|mini|Farbpalette schwarz bis rot]]<br />
<br />
Ein konkretes Anwendungsbeispiel ist dann das folgende Gerät. Dieses Gerät liefert eine Anzeige, wie lange eine enthaltene Menge noch verwendet werden kann, das entsprechende Reading lautet "Wochen". "Wochen" geht von 12 bis 0, unter 7 soll die Anzeige nicht mehr in schwarz, sondern in Warnungsfarben erfolgen: 3 bis 6 in gelb, unter 3 in Richtung rot gehend. Das stateformat lautet dann<syntaxhighlight><br />
attr Salzmenge stateFormat {my $farbe = substr(Color::pahColor(0,5,12,ReadingsNum($name, "Wochen",0),[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
return "<span style='color:#$farbe'>".ReadingsVal($name, "Wochen", 0)." Wochen </span>" }<br />
</syntaxhighlight>Mit pahColor erzeugte Farbtabellen können mit [[DOIFtools#Farbtabellen_erzeugen|DOIFtools]] angezeigt werden.<br />
<br />
[[Kategorie:Development]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Color&diff=37631Color2022-11-03T09:00:38Z<p>Andies: /* Beispiele */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Hilfsfunktionen zur modulübergreifenden Benutzung von Farben.<br />
|ModType=h<br />
|ModCmdRef=intro <!-- no help section available --><br />
|ModForumArea=Sonstiges<br />
|ModTechName=Color.pm<br />
|ModOwner=Andre ([http://forum.fhem.de/index.php?action=profile;u=430 Forum] / [[Benutzer Diskussion:justme|Wiki]])}}<br />
<br />
[[Color]] soll modulübergreifend Funktionen bereitstellen, die die Interaktion mit farbigen Lampen erleichtern. Es wird zur Zeit von [[Hue|HUEDevice]] und dem [[panStamp#Section SWAP_0000002200000003|SWAP RGB Driver]] Modul sowie von FRM_RGB und PHTV und verwendet.<br />
<br />
== Benutzung ==<br />
Um die im Folgenden beschriebenen Funktionen zu nutzen, muss die Datei Color.pm eingebunden werden. Ein Modulautor kann das durch eine <br />
:<code>use Color;</code> <br />
Anweisung in seinem Modul tun. Ein Endanwender mit einem notify:<br />
:<code><nowiki>define colorInit notify global:INITIALIZED {use Color}</nowiki></code><br />
<br />
== Colorpicker ==<br />
[[Datei:SWAP_0000002200000003.png|thumb|Colorpicker und Presets]]<br />
Der colorpicker stellt ein FHEM-Web Widget bereit, das es ermöglicht, in der webCmd Liste interaktiv eine Farbe einzustellen oder fest definierte presets zur Auswahl zu stellen. Hierzu sind je nach reading folgende Schritte nötig:<br />
<br />
=== RGB Farbe ===<br />
* Ein entsprechendes Kommando, das den colorpicker verwendet, in der 'set ?' liste des Moduls vorsehen (oder eines mit widgetOverride überschreiben):<br />
:<code>... <rgb>:colorpicker,RGB ...</code><br />
<br />
Nun lässt sich das Kommando ''rgb'' auf zwei Arten in der webCmd Liste verwenden:<br />
* ohne Parameter: um ein interaktives Eingabefeld für einen RGB-Farbwert einzublenden <br />
* mit einem RGB-Wert als Parameter, um einen festen Preset einzublenden<br />
:<code>attr <device> webCmd rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:toggle:on:off</code><br />
<br />
Bei jedem Seitenaufbau wird der Wert zum Initialisieren des colorpicker aus dem Reading mit dem gleichen Namen wie das set-kommando geholt.<br />
<br />
=== RGB als HSV ===<br />
[[Datei:Colorpicker_HSV.png|mini|rechts|350px|Colorpicker im HSV Modus]]<br />
Eine RGB Farbe lässt sich alternativ auch über den HSV Mode einstellen. Hierbei werden untereinander jeweils ein Schieberegler für Farbton, Sättigung und Helligkeit dargestellt.<br />
... rgb:colorpicker,HSV ...<br />
attr <device> webCmd rgb<br />
<br />
Alternativ lässt sich als Mode statt <code>HSV</code> auch <code>HSVp</code> verwenden. Dann werden die Schieberegler bei einem Klick auf das Widget in einem Popup-Fenster eingeblendet.<br />
<br />
=== echtes HSV ===<br />
Wenn das Device kein RGB Reading und Kommando hat aber ein HSV Reading und drei Kommandos um Farbton, Sättigung und Helligkeit einzustellen lässt sich die folgende Variante verwenden:<br />
... hsv:colorpicker,HSV,hue,0,1,360,sat,0,1,100,bri,0,1,100 ...<br />
d.h. es wird nach dem <code>HSV</code> oder <code>HSVp</code> Schlüsselwort für jedes der drei Kommandos der Name und der wertebereich mit Komma getrennt angegeben. Falls es im Device das nötige Reading mit den aktuellen Werten nicht gibt lässt sich dieses mit einem user reading z.B. wie folgt erzeugen:<br />
attr <device> userReadings hsv {ReadingsVal($name,'hue','0').','.ReadingsVal($name,'sat','100').','.ReadingsVal($name,'bri','100')}<br />
<br />
=== Farbtemperatur ===<br />
Der colorpicker lässt sich auch für die Farbtemperatur (ct, in Kelvin oder Mired) verwenden. Hier ein Beispiel für die Set-Liste eines ct Kommandos mit erlaubten Werten von 2000 bis 6500 Kelvin und eine webCmd Definition mit ct slider und 4 ct Presets.<br />
... ct:colorpicker,CT,2000,10,6500 ...<br />
attr <device> webCmd ct:ct 2040:ct 2630:ct 3703:ct 6250:on:off<br />
<br />
=== Farbton ===<br />
[[Datei:Colorpicker_webCmd.png|mini|rechts|400px|Colorpicker im CT, HUE und RGB-Preset Modus]]<br />
<br />
In der aktuellen Version lässt sich der colorpicker auch für den Farbton (hue) verwenden (ab 11.03.2022 auch mit presets):<br />
<br />
<br />
... hue:colorpicker,HUE,0,1,359 ...<br />
attr <device> webCmd hue:rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:rgb ffffff:on:off<br />
<br />
=== Helligkeit ===<br />
[[Datei:Colorpicker_bri.png|mini|rechts|400px|Colorpicker im BRI Modus]]<br />
<br />
In der aktuellen Version lässt sich der colorpicker auch als Slider der mit einem Graukeil hinterlegt ist verwenden um z.b. die Helligkeit (bri,pct,...) einzustellen:<br />
... pct:colorpicker,BRI,0,1,100 ...<br />
attr <device> webCmd pct:toggle:on:off<br />
<br />
Die Slider für Farbtemperatur, Farbton und Helligkeit sind jeweils mit einem passenden Hintergrund hinterlegt.<br />
<br />
== Farbige Lampen Icons ==<br />
Die Funktion Color_devStateIcon($) erzeugt aus einem übergebenen RGB Wert in der Form "RRGGBB" einen devStateIcon String für farbige SVG Icons (die bunten Blobs werden noch nicht unterstützt). Der Aufruf kann z.B. so zum Setzen des devStateIcons verwendet werden:<br />
:<code>attr <device> devStateIcon {Color_devStateIcon(ReadingsVal($name,"rgb","000000"))}</code><br />
oder<br />
:<code>attr <device> devStateIcon {Color_devStateIcon(CommandGet(undef,"$name rgb"))}</code><br />
<br />
'''NEU:'''<br />
Im Namespace Color gibt es eine zweite, experimentelle Version einer devStateIcon Funktion. Diese unterstützt neben farbigen Lampen auch Dimmer und Schalter. Hier muss der Name (oder hash) des FHEM-Device, ein String der den Typ der Lampe festlegt und bis zu drei Namen von Readings, die den RGB-Wert, die aktuelle Helligkeit im Bereich 0-100 und den Ein/Aus Status enthalten. Also:<br />
:<code><nowiki>Color::devStateIcon( <name|hash>, <type>, <rgb reading>, <percent reading>, <on/off reading> );</nowiki></code><br />
<br />
In <code>type</code> kann zur Zeit <code>rgb</code>, <code>dimmer</code> oder <code>switch</code> übergeben werden. Im Reading für die Helligkeit wird neben den Werten 0-100 auch <code>on</code> und <code>off</code> verstanden.<br />
<br />
Ein Beispiel für eine Lampe, die im Reading <code>rgb</code> die aktuell eingestellte Farbe und im Reading <code>state</code> on oder off enthalten kann: <br />
:<code><nowiki>attr meineLampe devStateIcon {Color::devStateIcon($name,"rgb","rgb","state")}</nowiki></code><br />
<br />
Um z.B. einen WeekdayTimer, der eine Lampe steuert, mit einem passenden Icon zu versehen, könnte man folgendes verwenden:<br />
:<code><nowiki>attr FlurTimer devStateIcon {Color::devStateIcon($name,"dimmer",undef,"state")}</nowiki></code><br />
[[Datei:Colorpicker_devStateIcons.png|mini|rechts|400px|Beispiel mit Nutzung der unterschiedlichen Möglichkeiten]]<br />
Das Icon des WeekdayTimer stellt dann den Zustand dar, mit dem die Lampe aktuell über den Timer gesteuert wird. Nicht den aktuellen Zustand der Lampe, die ja auch anderweitig gesteuert werden kann.<br />
<br />
'''ToDo''': Bestimmen der Helligkeit über den RGB-Wert, wenn kein Reading dafür angeben ist.<br />
<br />
'''Fragen''': <br />
* Ist es für das Interface besser, jeweils direkt die Werte zu übergeben oder die Namen der Readings in denen die Werte zu finden sind?<br />
* Sollte angegeben werden können, welchen Wertebereich die Helligkeit haben kann?<br />
<br />
Zwei Beispiele für die Verwendung und Kombination der oben beschriebenen Routinen gibt es in der fhem.cfg.demo im Simulator für farbige Lanpen.<br />
<br />
== Routinen um zwischen Farbräumen und Darstellungen zu konvertieren ==<br />
Color::rgb2hsv<br />
Color::hsv2rgb<br />
Color::hsb2rgb<br />
Color::rgb2hsb<br />
Color::hex2hsv<br />
Color::hsv2hex<br />
Color::hex2hsb<br />
Color::hsb2hex<br />
Color::hex2rgb<br />
Color::rgb2hex<br />
Color::ct2rgb<br />
Color::xyY2rgb<br />
Color::xyY2hex<br />
<br />
== Farbskala mit Color::pahColor ==<br />
Das auf der Seite [[Temperaturfarbe]] beschriebene Verfahren ist über die Routine <code>Color::pahColor</code> verfügbar, siehe auch {{Link2Forum|Topic=30128|LinkText=diesem Beitrag im FHEM Forum}}.<br />
<br />
:<code><nowiki>Color::pahColor($starttemp,$midtemp,$endtemp,$temp,$colors,$opacity)</nowiki></code><br />
<br />
<code>$colors</code>: Mit [[Temperaturfarbe#Skala_0 | 0]], [[Temperaturfarbe#Skala_1 | 1]] oder [[Temperaturfarbe#Skala_2 | 2]] wird das verwendete [[Temperaturfarbe | Farbmodell]] ausgewählt. Ein selbst definiertes Farbmodell kann als array-ref übergeben werden.<br />
<br />
=== Beispiele ===<br />
Steuern einer Lampe in Abhängigkeit von einer Temperatur:<br />
define <n> notify mytemp:temperature.* {fhem("set lampe rgb ".substr(Color::pahColor(0,15,30,$EVTPART1,0,0),0,6))}<br />
<br />
Einfärben eines Temperaturwertes in einer [[readingsGroup]]:<br />
attr <rg> valueStyle { temperature => '{"style=\"color:\x23".substr(Color::pahColor(0,15,30,$VALUE,0),0,6)."\""}'}<br />
<br />
Einfärben eines Feuchte-Readings in einer readingsGroup:<br />
:<code><nowiki>attr <rg> valueStyle { humidity => '{style=\"color:\x23".substr(Color::pahColor(0,50,100,$VALUE,[255,255,0, 127,255,0, 0,255,0, 0,255,255, 0,127,255]),0,6)."\"}'}</nowiki></code><br />
Hier wird die folgende Farbzuordnung verwendet:[[Datei:color-humidity.png]]<br />
<br />
Anmerkung: {{Taste|\x23}} ist die hexadezimale Escapesequenz für das {{Taste|#}} Zeichen, das beim Einlesen der [[Konfiguration]] sonst als Kommentar interpretiert werden würde. Ist mit aktuellen FHEM Versionen nicht mehr nötig. Das {{Taste|#}} Zeichen kann direkt verwendet werden.<br />
<br />
Es gibt Fälle, in denen ein Farbverlauf für Warnungen/Fehler angezeigt werden soll. Hier bietet sich kein Temperaturähnlicher Verlauf an, weil die Farbfolge nicht von blau über grün zu gelb/rot gehen soll, sondern vielmehr die typische Anzeige schwarz ist, bei Warnungen gelb und bei Fehlern rot sein soll. Im Folgenden Beispiel sollen Zahlenwerte dann gefärbt werden, wenn sie vom Normwert abweichen. Als Beispiel diene eine Füllstandsanzeige (im konkreten Fall geht es um "noch betreibbare Zeit in Wochen"), die von etwa 7 bis 12 im Normbereich liegt (Anzeige schwarz), von etwa 3 bis 6 im Warnungsbereich (gelb) und zwischen 0 und 3 eine Fehlermeldung (rot) ergeben soll. Auch hier kann man pahColor verwenden. Die Farbpalette wird wie folgt erzeugt<syntaxhighlight lang="perl"><br />
sub Farbtester()<br />
{my $s = "";;<br />
my <br />
$farbe = substr(Color::pahColor(0,5,12,0,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>0 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,1,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>1 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,2,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>2 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,3,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>3 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,5,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>5 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,6,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>6 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,7,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>7 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,8,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>8 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,9,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>9 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,10,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>10 </span>";<br />
return $s}<br />
</syntaxhighlight>und das Ergebnis sieht dann wie im Bild unten aus.<br />
[[Datei:Farbpalette Schwarz bis Rot.png|mini|Farbpalette schwarz bis rot]]<br />
<br />
Ein konkretes Anwendungsbeispiel ist dann das folgende Gerät. Dieses Gerät liefert eine Anzeige, wie lange eine enthaltene Menge noch verwendet werden kann, das entsprechende Reading lautet "Wochen". "Wochen" geht von 12 bis 0, unter 7 soll die Anzeige nicht mehr in schwarz, sondern in Warnungsfarben erfolgen: 3 bis 6 in gelb, unter 3 in Richtung rot gehend. Das stateformat lautet dann<syntaxhighlight><br />
stateFormat {my $farbe = substr(Color::pahColor(0,5,12,ReadingsNum($name, "Wochen",0),[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
return "<span style='color:#$farbe'>".ReadingsVal($name, "Wochen", 0)." Wochen </span>" }<br />
</syntaxhighlight>Mit pahColor erzeugte Farbtabellen können mit [[DOIFtools#Farbtabellen_erzeugen|DOIFtools]] angezeigt werden.<br />
<br />
[[Kategorie:Development]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Color&diff=37630Color2022-11-03T08:59:24Z<p>Andies: /* Beispiele */ Beispiel</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Hilfsfunktionen zur modulübergreifenden Benutzung von Farben.<br />
|ModType=h<br />
|ModCmdRef=intro <!-- no help section available --><br />
|ModForumArea=Sonstiges<br />
|ModTechName=Color.pm<br />
|ModOwner=Andre ([http://forum.fhem.de/index.php?action=profile;u=430 Forum] / [[Benutzer Diskussion:justme|Wiki]])}}<br />
<br />
[[Color]] soll modulübergreifend Funktionen bereitstellen, die die Interaktion mit farbigen Lampen erleichtern. Es wird zur Zeit von [[Hue|HUEDevice]] und dem [[panStamp#Section SWAP_0000002200000003|SWAP RGB Driver]] Modul sowie von FRM_RGB und PHTV und verwendet.<br />
<br />
== Benutzung ==<br />
Um die im Folgenden beschriebenen Funktionen zu nutzen, muss die Datei Color.pm eingebunden werden. Ein Modulautor kann das durch eine <br />
:<code>use Color;</code> <br />
Anweisung in seinem Modul tun. Ein Endanwender mit einem notify:<br />
:<code><nowiki>define colorInit notify global:INITIALIZED {use Color}</nowiki></code><br />
<br />
== Colorpicker ==<br />
[[Datei:SWAP_0000002200000003.png|thumb|Colorpicker und Presets]]<br />
Der colorpicker stellt ein FHEM-Web Widget bereit, das es ermöglicht, in der webCmd Liste interaktiv eine Farbe einzustellen oder fest definierte presets zur Auswahl zu stellen. Hierzu sind je nach reading folgende Schritte nötig:<br />
<br />
=== RGB Farbe ===<br />
* Ein entsprechendes Kommando, das den colorpicker verwendet, in der 'set ?' liste des Moduls vorsehen (oder eines mit widgetOverride überschreiben):<br />
:<code>... <rgb>:colorpicker,RGB ...</code><br />
<br />
Nun lässt sich das Kommando ''rgb'' auf zwei Arten in der webCmd Liste verwenden:<br />
* ohne Parameter: um ein interaktives Eingabefeld für einen RGB-Farbwert einzublenden <br />
* mit einem RGB-Wert als Parameter, um einen festen Preset einzublenden<br />
:<code>attr <device> webCmd rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:toggle:on:off</code><br />
<br />
Bei jedem Seitenaufbau wird der Wert zum Initialisieren des colorpicker aus dem Reading mit dem gleichen Namen wie das set-kommando geholt.<br />
<br />
=== RGB als HSV ===<br />
[[Datei:Colorpicker_HSV.png|mini|rechts|350px|Colorpicker im HSV Modus]]<br />
Eine RGB Farbe lässt sich alternativ auch über den HSV Mode einstellen. Hierbei werden untereinander jeweils ein Schieberegler für Farbton, Sättigung und Helligkeit dargestellt.<br />
... rgb:colorpicker,HSV ...<br />
attr <device> webCmd rgb<br />
<br />
Alternativ lässt sich als Mode statt <code>HSV</code> auch <code>HSVp</code> verwenden. Dann werden die Schieberegler bei einem Klick auf das Widget in einem Popup-Fenster eingeblendet.<br />
<br />
=== echtes HSV ===<br />
Wenn das Device kein RGB Reading und Kommando hat aber ein HSV Reading und drei Kommandos um Farbton, Sättigung und Helligkeit einzustellen lässt sich die folgende Variante verwenden:<br />
... hsv:colorpicker,HSV,hue,0,1,360,sat,0,1,100,bri,0,1,100 ...<br />
d.h. es wird nach dem <code>HSV</code> oder <code>HSVp</code> Schlüsselwort für jedes der drei Kommandos der Name und der wertebereich mit Komma getrennt angegeben. Falls es im Device das nötige Reading mit den aktuellen Werten nicht gibt lässt sich dieses mit einem user reading z.B. wie folgt erzeugen:<br />
attr <device> userReadings hsv {ReadingsVal($name,'hue','0').','.ReadingsVal($name,'sat','100').','.ReadingsVal($name,'bri','100')}<br />
<br />
=== Farbtemperatur ===<br />
Der colorpicker lässt sich auch für die Farbtemperatur (ct, in Kelvin oder Mired) verwenden. Hier ein Beispiel für die Set-Liste eines ct Kommandos mit erlaubten Werten von 2000 bis 6500 Kelvin und eine webCmd Definition mit ct slider und 4 ct Presets.<br />
... ct:colorpicker,CT,2000,10,6500 ...<br />
attr <device> webCmd ct:ct 2040:ct 2630:ct 3703:ct 6250:on:off<br />
<br />
=== Farbton ===<br />
[[Datei:Colorpicker_webCmd.png|mini|rechts|400px|Colorpicker im CT, HUE und RGB-Preset Modus]]<br />
<br />
In der aktuellen Version lässt sich der colorpicker auch für den Farbton (hue) verwenden (ab 11.03.2022 auch mit presets):<br />
<br />
<br />
... hue:colorpicker,HUE,0,1,359 ...<br />
attr <device> webCmd hue:rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:rgb ffffff:on:off<br />
<br />
=== Helligkeit ===<br />
[[Datei:Colorpicker_bri.png|mini|rechts|400px|Colorpicker im BRI Modus]]<br />
<br />
In der aktuellen Version lässt sich der colorpicker auch als Slider der mit einem Graukeil hinterlegt ist verwenden um z.b. die Helligkeit (bri,pct,...) einzustellen:<br />
... pct:colorpicker,BRI,0,1,100 ...<br />
attr <device> webCmd pct:toggle:on:off<br />
<br />
Die Slider für Farbtemperatur, Farbton und Helligkeit sind jeweils mit einem passenden Hintergrund hinterlegt.<br />
<br />
== Farbige Lampen Icons ==<br />
Die Funktion Color_devStateIcon($) erzeugt aus einem übergebenen RGB Wert in der Form "RRGGBB" einen devStateIcon String für farbige SVG Icons (die bunten Blobs werden noch nicht unterstützt). Der Aufruf kann z.B. so zum Setzen des devStateIcons verwendet werden:<br />
:<code>attr <device> devStateIcon {Color_devStateIcon(ReadingsVal($name,"rgb","000000"))}</code><br />
oder<br />
:<code>attr <device> devStateIcon {Color_devStateIcon(CommandGet(undef,"$name rgb"))}</code><br />
<br />
'''NEU:'''<br />
Im Namespace Color gibt es eine zweite, experimentelle Version einer devStateIcon Funktion. Diese unterstützt neben farbigen Lampen auch Dimmer und Schalter. Hier muss der Name (oder hash) des FHEM-Device, ein String der den Typ der Lampe festlegt und bis zu drei Namen von Readings, die den RGB-Wert, die aktuelle Helligkeit im Bereich 0-100 und den Ein/Aus Status enthalten. Also:<br />
:<code><nowiki>Color::devStateIcon( <name|hash>, <type>, <rgb reading>, <percent reading>, <on/off reading> );</nowiki></code><br />
<br />
In <code>type</code> kann zur Zeit <code>rgb</code>, <code>dimmer</code> oder <code>switch</code> übergeben werden. Im Reading für die Helligkeit wird neben den Werten 0-100 auch <code>on</code> und <code>off</code> verstanden.<br />
<br />
Ein Beispiel für eine Lampe, die im Reading <code>rgb</code> die aktuell eingestellte Farbe und im Reading <code>state</code> on oder off enthalten kann: <br />
:<code><nowiki>attr meineLampe devStateIcon {Color::devStateIcon($name,"rgb","rgb","state")}</nowiki></code><br />
<br />
Um z.B. einen WeekdayTimer, der eine Lampe steuert, mit einem passenden Icon zu versehen, könnte man folgendes verwenden:<br />
:<code><nowiki>attr FlurTimer devStateIcon {Color::devStateIcon($name,"dimmer",undef,"state")}</nowiki></code><br />
[[Datei:Colorpicker_devStateIcons.png|mini|rechts|400px|Beispiel mit Nutzung der unterschiedlichen Möglichkeiten]]<br />
Das Icon des WeekdayTimer stellt dann den Zustand dar, mit dem die Lampe aktuell über den Timer gesteuert wird. Nicht den aktuellen Zustand der Lampe, die ja auch anderweitig gesteuert werden kann.<br />
<br />
'''ToDo''': Bestimmen der Helligkeit über den RGB-Wert, wenn kein Reading dafür angeben ist.<br />
<br />
'''Fragen''': <br />
* Ist es für das Interface besser, jeweils direkt die Werte zu übergeben oder die Namen der Readings in denen die Werte zu finden sind?<br />
* Sollte angegeben werden können, welchen Wertebereich die Helligkeit haben kann?<br />
<br />
Zwei Beispiele für die Verwendung und Kombination der oben beschriebenen Routinen gibt es in der fhem.cfg.demo im Simulator für farbige Lanpen.<br />
<br />
== Routinen um zwischen Farbräumen und Darstellungen zu konvertieren ==<br />
Color::rgb2hsv<br />
Color::hsv2rgb<br />
Color::hsb2rgb<br />
Color::rgb2hsb<br />
Color::hex2hsv<br />
Color::hsv2hex<br />
Color::hex2hsb<br />
Color::hsb2hex<br />
Color::hex2rgb<br />
Color::rgb2hex<br />
Color::ct2rgb<br />
Color::xyY2rgb<br />
Color::xyY2hex<br />
<br />
== Farbskala mit Color::pahColor ==<br />
Das auf der Seite [[Temperaturfarbe]] beschriebene Verfahren ist über die Routine <code>Color::pahColor</code> verfügbar, siehe auch {{Link2Forum|Topic=30128|LinkText=diesem Beitrag im FHEM Forum}}.<br />
<br />
:<code><nowiki>Color::pahColor($starttemp,$midtemp,$endtemp,$temp,$colors,$opacity)</nowiki></code><br />
<br />
<code>$colors</code>: Mit [[Temperaturfarbe#Skala_0 | 0]], [[Temperaturfarbe#Skala_1 | 1]] oder [[Temperaturfarbe#Skala_2 | 2]] wird das verwendete [[Temperaturfarbe | Farbmodell]] ausgewählt. Ein selbst definiertes Farbmodell kann als array-ref übergeben werden.<br />
<br />
=== Beispiele ===<br />
Steuern einer Lampe in Abhängigkeit von einer Temperatur:<br />
define <n> notify mytemp:temperature.* {fhem("set lampe rgb ".substr(Color::pahColor(0,15,30,$EVTPART1,0,0),0,6))}<br />
<br />
Einfärben eines Temperaturwertes in einer [[readingsGroup]]:<br />
attr <rg> valueStyle { temperature => '{"style=\"color:\x23".substr(Color::pahColor(0,15,30,$VALUE,0),0,6)."\""}'}<br />
<br />
Einfärben eines Feuchte-Readings in einer readingsGroup:<br />
:<code><nowiki>attr <rg> valueStyle { humidity => '{style=\"color:\x23".substr(Color::pahColor(0,50,100,$VALUE,[255,255,0, 127,255,0, 0,255,0, 0,255,255, 0,127,255]),0,6)."\"}'}</nowiki></code><br />
Hier wird die folgende Farbzuordnung verwendet:[[Datei:color-humidity.png]]<br />
<br />
Anmerkung: {{Taste|\x23}} ist die hexadezimale Escapesequenz für das {{Taste|#}} Zeichen, das beim Einlesen der [[Konfiguration]] sonst als Kommentar interpretiert werden würde. Ist mit aktuellen FHEM Versionen nicht mehr nötig. Das {{Taste|#}} Zeichen kann direkt verwendet werden.<br />
<br />
Es gibt Fälle, in denen ein Farbverlauf für Warnungen/Fehler angezeigt werden soll. Hier bietet sich kein Temperaturähnlicher Verlauf an, weil die Farbfolge nicht von blau über grün zu gelb/rot gehen soll, sondern vielmehr die typische Anzeige schwarz ist, bei Warnungen gelb und bei Fehlern rot sein soll. Im Folgenden Beispiel sollen Zahlenwerte dann gefärbt werden, wenn sie vom Normwert abweichen. Als Beispiel diene eine Füllstandsanzeige (im konkreten Fall geht es um "noch betreibbare Zeit in Wochen"), die von etwa 7 bis 12 im Normbereich liegt (Anzeige schwarz), von etwa 3 bis 6 im Warnungsbereich (gelb) und zwischen 0 und 3 eine Fehlermeldung (rot) ergeben soll. Auch hier kann man pahColor verwenden. Die Farbpalette wird wie folgt erzeugt<syntaxhighlight lang="perl"><br />
sub Farbtester()<br />
{my $s = "";;<br />
my <br />
$farbe = substr(Color::pahColor(0,5,12,0,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>0 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,1,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>1 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,2,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>2 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,3,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>3 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,5,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>5 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,6,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>6 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,7,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>7 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,8,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>8 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,9,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>9 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,10,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>10 </span>";<br />
return $s}<br />
</syntaxhighlight>und das Ergebnis sieht dann wie im Bild unten aus.<br />
[[Datei:Farbpalette Schwarz bis Rot.png|mini|Farbpalette schwarz bis rot]]<br />
<br />
Ein konkretes Anwendungsbeispiel ist dann das folgende Gerät. Dieses Gerät liefert eine Anzeige, wie lange eine enthaltene Menge noch verwendet werden kann, das entsprechende Reading lautet "Wochen". "Wochen" geht von 12 bis 0, unter 7 soll die Anzeige nicht mehr in schwarz, sondern in Warnungsfarben erfolgen: 3 bis 6 in gelb, unter 3 in Richtung rot gehend. Das stateformat lautet dann<syntaxhighlight lang="perl" line="1"><br />
{my $farbe = substr(Color::pahColor(0,5,12,ReadingsNum($name, "Wochen",0),[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
return "<span style='color:#$farbe'>".ReadingsVal($name, "Wochen", 0)." Wochen </span>" }<br />
</syntaxhighlight>Mit pahColor erzeugte Farbtabellen können mit [[DOIFtools#Farbtabellen_erzeugen|DOIFtools]] angezeigt werden.<br />
<br />
[[Kategorie:Development]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Color&diff=37629Color2022-11-03T08:56:07Z<p>Andies: /* Beispiele */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Hilfsfunktionen zur modulübergreifenden Benutzung von Farben.<br />
|ModType=h<br />
|ModCmdRef=intro <!-- no help section available --><br />
|ModForumArea=Sonstiges<br />
|ModTechName=Color.pm<br />
|ModOwner=Andre ([http://forum.fhem.de/index.php?action=profile;u=430 Forum] / [[Benutzer Diskussion:justme|Wiki]])}}<br />
<br />
[[Color]] soll modulübergreifend Funktionen bereitstellen, die die Interaktion mit farbigen Lampen erleichtern. Es wird zur Zeit von [[Hue|HUEDevice]] und dem [[panStamp#Section SWAP_0000002200000003|SWAP RGB Driver]] Modul sowie von FRM_RGB und PHTV und verwendet.<br />
<br />
== Benutzung ==<br />
Um die im Folgenden beschriebenen Funktionen zu nutzen, muss die Datei Color.pm eingebunden werden. Ein Modulautor kann das durch eine <br />
:<code>use Color;</code> <br />
Anweisung in seinem Modul tun. Ein Endanwender mit einem notify:<br />
:<code><nowiki>define colorInit notify global:INITIALIZED {use Color}</nowiki></code><br />
<br />
== Colorpicker ==<br />
[[Datei:SWAP_0000002200000003.png|thumb|Colorpicker und Presets]]<br />
Der colorpicker stellt ein FHEM-Web Widget bereit, das es ermöglicht, in der webCmd Liste interaktiv eine Farbe einzustellen oder fest definierte presets zur Auswahl zu stellen. Hierzu sind je nach reading folgende Schritte nötig:<br />
<br />
=== RGB Farbe ===<br />
* Ein entsprechendes Kommando, das den colorpicker verwendet, in der 'set ?' liste des Moduls vorsehen (oder eines mit widgetOverride überschreiben):<br />
:<code>... <rgb>:colorpicker,RGB ...</code><br />
<br />
Nun lässt sich das Kommando ''rgb'' auf zwei Arten in der webCmd Liste verwenden:<br />
* ohne Parameter: um ein interaktives Eingabefeld für einen RGB-Farbwert einzublenden <br />
* mit einem RGB-Wert als Parameter, um einen festen Preset einzublenden<br />
:<code>attr <device> webCmd rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:toggle:on:off</code><br />
<br />
Bei jedem Seitenaufbau wird der Wert zum Initialisieren des colorpicker aus dem Reading mit dem gleichen Namen wie das set-kommando geholt.<br />
<br />
=== RGB als HSV ===<br />
[[Datei:Colorpicker_HSV.png|mini|rechts|350px|Colorpicker im HSV Modus]]<br />
Eine RGB Farbe lässt sich alternativ auch über den HSV Mode einstellen. Hierbei werden untereinander jeweils ein Schieberegler für Farbton, Sättigung und Helligkeit dargestellt.<br />
... rgb:colorpicker,HSV ...<br />
attr <device> webCmd rgb<br />
<br />
Alternativ lässt sich als Mode statt <code>HSV</code> auch <code>HSVp</code> verwenden. Dann werden die Schieberegler bei einem Klick auf das Widget in einem Popup-Fenster eingeblendet.<br />
<br />
=== echtes HSV ===<br />
Wenn das Device kein RGB Reading und Kommando hat aber ein HSV Reading und drei Kommandos um Farbton, Sättigung und Helligkeit einzustellen lässt sich die folgende Variante verwenden:<br />
... hsv:colorpicker,HSV,hue,0,1,360,sat,0,1,100,bri,0,1,100 ...<br />
d.h. es wird nach dem <code>HSV</code> oder <code>HSVp</code> Schlüsselwort für jedes der drei Kommandos der Name und der wertebereich mit Komma getrennt angegeben. Falls es im Device das nötige Reading mit den aktuellen Werten nicht gibt lässt sich dieses mit einem user reading z.B. wie folgt erzeugen:<br />
attr <device> userReadings hsv {ReadingsVal($name,'hue','0').','.ReadingsVal($name,'sat','100').','.ReadingsVal($name,'bri','100')}<br />
<br />
=== Farbtemperatur ===<br />
Der colorpicker lässt sich auch für die Farbtemperatur (ct, in Kelvin oder Mired) verwenden. Hier ein Beispiel für die Set-Liste eines ct Kommandos mit erlaubten Werten von 2000 bis 6500 Kelvin und eine webCmd Definition mit ct slider und 4 ct Presets.<br />
... ct:colorpicker,CT,2000,10,6500 ...<br />
attr <device> webCmd ct:ct 2040:ct 2630:ct 3703:ct 6250:on:off<br />
<br />
=== Farbton ===<br />
[[Datei:Colorpicker_webCmd.png|mini|rechts|400px|Colorpicker im CT, HUE und RGB-Preset Modus]]<br />
<br />
In der aktuellen Version lässt sich der colorpicker auch für den Farbton (hue) verwenden (ab 11.03.2022 auch mit presets):<br />
<br />
<br />
... hue:colorpicker,HUE,0,1,359 ...<br />
attr <device> webCmd hue:rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:rgb ffffff:on:off<br />
<br />
=== Helligkeit ===<br />
[[Datei:Colorpicker_bri.png|mini|rechts|400px|Colorpicker im BRI Modus]]<br />
<br />
In der aktuellen Version lässt sich der colorpicker auch als Slider der mit einem Graukeil hinterlegt ist verwenden um z.b. die Helligkeit (bri,pct,...) einzustellen:<br />
... pct:colorpicker,BRI,0,1,100 ...<br />
attr <device> webCmd pct:toggle:on:off<br />
<br />
Die Slider für Farbtemperatur, Farbton und Helligkeit sind jeweils mit einem passenden Hintergrund hinterlegt.<br />
<br />
== Farbige Lampen Icons ==<br />
Die Funktion Color_devStateIcon($) erzeugt aus einem übergebenen RGB Wert in der Form "RRGGBB" einen devStateIcon String für farbige SVG Icons (die bunten Blobs werden noch nicht unterstützt). Der Aufruf kann z.B. so zum Setzen des devStateIcons verwendet werden:<br />
:<code>attr <device> devStateIcon {Color_devStateIcon(ReadingsVal($name,"rgb","000000"))}</code><br />
oder<br />
:<code>attr <device> devStateIcon {Color_devStateIcon(CommandGet(undef,"$name rgb"))}</code><br />
<br />
'''NEU:'''<br />
Im Namespace Color gibt es eine zweite, experimentelle Version einer devStateIcon Funktion. Diese unterstützt neben farbigen Lampen auch Dimmer und Schalter. Hier muss der Name (oder hash) des FHEM-Device, ein String der den Typ der Lampe festlegt und bis zu drei Namen von Readings, die den RGB-Wert, die aktuelle Helligkeit im Bereich 0-100 und den Ein/Aus Status enthalten. Also:<br />
:<code><nowiki>Color::devStateIcon( <name|hash>, <type>, <rgb reading>, <percent reading>, <on/off reading> );</nowiki></code><br />
<br />
In <code>type</code> kann zur Zeit <code>rgb</code>, <code>dimmer</code> oder <code>switch</code> übergeben werden. Im Reading für die Helligkeit wird neben den Werten 0-100 auch <code>on</code> und <code>off</code> verstanden.<br />
<br />
Ein Beispiel für eine Lampe, die im Reading <code>rgb</code> die aktuell eingestellte Farbe und im Reading <code>state</code> on oder off enthalten kann: <br />
:<code><nowiki>attr meineLampe devStateIcon {Color::devStateIcon($name,"rgb","rgb","state")}</nowiki></code><br />
<br />
Um z.B. einen WeekdayTimer, der eine Lampe steuert, mit einem passenden Icon zu versehen, könnte man folgendes verwenden:<br />
:<code><nowiki>attr FlurTimer devStateIcon {Color::devStateIcon($name,"dimmer",undef,"state")}</nowiki></code><br />
[[Datei:Colorpicker_devStateIcons.png|mini|rechts|400px|Beispiel mit Nutzung der unterschiedlichen Möglichkeiten]]<br />
Das Icon des WeekdayTimer stellt dann den Zustand dar, mit dem die Lampe aktuell über den Timer gesteuert wird. Nicht den aktuellen Zustand der Lampe, die ja auch anderweitig gesteuert werden kann.<br />
<br />
'''ToDo''': Bestimmen der Helligkeit über den RGB-Wert, wenn kein Reading dafür angeben ist.<br />
<br />
'''Fragen''': <br />
* Ist es für das Interface besser, jeweils direkt die Werte zu übergeben oder die Namen der Readings in denen die Werte zu finden sind?<br />
* Sollte angegeben werden können, welchen Wertebereich die Helligkeit haben kann?<br />
<br />
Zwei Beispiele für die Verwendung und Kombination der oben beschriebenen Routinen gibt es in der fhem.cfg.demo im Simulator für farbige Lanpen.<br />
<br />
== Routinen um zwischen Farbräumen und Darstellungen zu konvertieren ==<br />
Color::rgb2hsv<br />
Color::hsv2rgb<br />
Color::hsb2rgb<br />
Color::rgb2hsb<br />
Color::hex2hsv<br />
Color::hsv2hex<br />
Color::hex2hsb<br />
Color::hsb2hex<br />
Color::hex2rgb<br />
Color::rgb2hex<br />
Color::ct2rgb<br />
Color::xyY2rgb<br />
Color::xyY2hex<br />
<br />
== Farbskala mit Color::pahColor ==<br />
Das auf der Seite [[Temperaturfarbe]] beschriebene Verfahren ist über die Routine <code>Color::pahColor</code> verfügbar, siehe auch {{Link2Forum|Topic=30128|LinkText=diesem Beitrag im FHEM Forum}}.<br />
<br />
:<code><nowiki>Color::pahColor($starttemp,$midtemp,$endtemp,$temp,$colors,$opacity)</nowiki></code><br />
<br />
<code>$colors</code>: Mit [[Temperaturfarbe#Skala_0 | 0]], [[Temperaturfarbe#Skala_1 | 1]] oder [[Temperaturfarbe#Skala_2 | 2]] wird das verwendete [[Temperaturfarbe | Farbmodell]] ausgewählt. Ein selbst definiertes Farbmodell kann als array-ref übergeben werden.<br />
<br />
=== Beispiele ===<br />
Steuern einer Lampe in Abhängigkeit von einer Temperatur:<br />
define <n> notify mytemp:temperature.* {fhem("set lampe rgb ".substr(Color::pahColor(0,15,30,$EVTPART1,0,0),0,6))}<br />
<br />
Einfärben eines Temperaturwertes in einer [[readingsGroup]]:<br />
attr <rg> valueStyle { temperature => '{"style=\"color:\x23".substr(Color::pahColor(0,15,30,$VALUE,0),0,6)."\""}'}<br />
<br />
Einfärben eines Feuchte-Readings in einer readingsGroup:<br />
:<code><nowiki>attr <rg> valueStyle { humidity => '{style=\"color:\x23".substr(Color::pahColor(0,50,100,$VALUE,[255,255,0, 127,255,0, 0,255,0, 0,255,255, 0,127,255]),0,6)."\"}'}</nowiki></code><br />
Hier wird die folgende Farbzuordnung verwendet:[[Datei:color-humidity.png]]<br />
<br />
Anmerkung: {{Taste|\x23}} ist die hexadezimale Escapesequenz für das {{Taste|#}} Zeichen, das beim Einlesen der [[Konfiguration]] sonst als Kommentar interpretiert werden würde. Ist mit aktuellen FHEM Versionen nicht mehr nötig. Das {{Taste|#}} Zeichen kann direkt verwendet werden.<br />
<br />
Es gibt Fälle, in denen ein Farbverlauf für Warnungen/Fehler angezeigt werden soll. Hier bietet sich kein Temperaturähnlicher Verlauf an, weil die Farbfolge nicht von blau über grün zu gelb/rot gehen soll, sondern vielmehr die typische Anzeige schwarz ist, bei Warnungen gelb und bei Fehlern rot sein soll. Im Folgenden Beispiel sollen Zahlenwerte dann gefärbt werden, wenn sie vom Normwert abweichen. Als Beispiel diene eine Füllstandsanzeige (im konkreten Fall geht es um "noch betreibbare Zeit in Wochen"), die von etwa 7 bis 12 im Normbereich liegt (Anzeige schwarz), von etwa 3 bis 6 im Warnungsbereich (gelb) und zwischen 0 und 3 eine Fehlermeldung (rot) ergeben soll. Auch hier kann man pahColor verwenden. Die Farbpalette wird wie folgt erzeugt<syntaxhighlight lang="perl"><br />
sub Farbtester()<br />
{my $s = "";;<br />
my <br />
$farbe = substr(Color::pahColor(0,5,12,0,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>0 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,1,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>1 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,2,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>2 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,3,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>3 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,5,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>5 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,6,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>6 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,7,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>7 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,8,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>8 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,9,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>9 </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,10,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>10 </span>";<br />
return $s}<br />
</syntaxhighlight>und das Ergebnis sieht dann wie im Bild unten aus.<br />
[[Datei:Farbpalette Schwarz bis Rot.png|mini|Farbpalette schwarz bis rot]]<br />
<br />
Mit pahColor erzeugte Farbtabellen können mit [[DOIFtools#Farbtabellen_erzeugen|DOIFtools]] angezeigt werden.<br />
<br />
[[Kategorie:Development]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Color&diff=37628Color2022-11-03T08:55:08Z<p>Andies: /* Beispiele */ farbpalette schwarz bis rot</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Hilfsfunktionen zur modulübergreifenden Benutzung von Farben.<br />
|ModType=h<br />
|ModCmdRef=intro <!-- no help section available --><br />
|ModForumArea=Sonstiges<br />
|ModTechName=Color.pm<br />
|ModOwner=Andre ([http://forum.fhem.de/index.php?action=profile;u=430 Forum] / [[Benutzer Diskussion:justme|Wiki]])}}<br />
<br />
[[Color]] soll modulübergreifend Funktionen bereitstellen, die die Interaktion mit farbigen Lampen erleichtern. Es wird zur Zeit von [[Hue|HUEDevice]] und dem [[panStamp#Section SWAP_0000002200000003|SWAP RGB Driver]] Modul sowie von FRM_RGB und PHTV und verwendet.<br />
<br />
== Benutzung ==<br />
Um die im Folgenden beschriebenen Funktionen zu nutzen, muss die Datei Color.pm eingebunden werden. Ein Modulautor kann das durch eine <br />
:<code>use Color;</code> <br />
Anweisung in seinem Modul tun. Ein Endanwender mit einem notify:<br />
:<code><nowiki>define colorInit notify global:INITIALIZED {use Color}</nowiki></code><br />
<br />
== Colorpicker ==<br />
[[Datei:SWAP_0000002200000003.png|thumb|Colorpicker und Presets]]<br />
Der colorpicker stellt ein FHEM-Web Widget bereit, das es ermöglicht, in der webCmd Liste interaktiv eine Farbe einzustellen oder fest definierte presets zur Auswahl zu stellen. Hierzu sind je nach reading folgende Schritte nötig:<br />
<br />
=== RGB Farbe ===<br />
* Ein entsprechendes Kommando, das den colorpicker verwendet, in der 'set ?' liste des Moduls vorsehen (oder eines mit widgetOverride überschreiben):<br />
:<code>... <rgb>:colorpicker,RGB ...</code><br />
<br />
Nun lässt sich das Kommando ''rgb'' auf zwei Arten in der webCmd Liste verwenden:<br />
* ohne Parameter: um ein interaktives Eingabefeld für einen RGB-Farbwert einzublenden <br />
* mit einem RGB-Wert als Parameter, um einen festen Preset einzublenden<br />
:<code>attr <device> webCmd rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:toggle:on:off</code><br />
<br />
Bei jedem Seitenaufbau wird der Wert zum Initialisieren des colorpicker aus dem Reading mit dem gleichen Namen wie das set-kommando geholt.<br />
<br />
=== RGB als HSV ===<br />
[[Datei:Colorpicker_HSV.png|mini|rechts|350px|Colorpicker im HSV Modus]]<br />
Eine RGB Farbe lässt sich alternativ auch über den HSV Mode einstellen. Hierbei werden untereinander jeweils ein Schieberegler für Farbton, Sättigung und Helligkeit dargestellt.<br />
... rgb:colorpicker,HSV ...<br />
attr <device> webCmd rgb<br />
<br />
Alternativ lässt sich als Mode statt <code>HSV</code> auch <code>HSVp</code> verwenden. Dann werden die Schieberegler bei einem Klick auf das Widget in einem Popup-Fenster eingeblendet.<br />
<br />
=== echtes HSV ===<br />
Wenn das Device kein RGB Reading und Kommando hat aber ein HSV Reading und drei Kommandos um Farbton, Sättigung und Helligkeit einzustellen lässt sich die folgende Variante verwenden:<br />
... hsv:colorpicker,HSV,hue,0,1,360,sat,0,1,100,bri,0,1,100 ...<br />
d.h. es wird nach dem <code>HSV</code> oder <code>HSVp</code> Schlüsselwort für jedes der drei Kommandos der Name und der wertebereich mit Komma getrennt angegeben. Falls es im Device das nötige Reading mit den aktuellen Werten nicht gibt lässt sich dieses mit einem user reading z.B. wie folgt erzeugen:<br />
attr <device> userReadings hsv {ReadingsVal($name,'hue','0').','.ReadingsVal($name,'sat','100').','.ReadingsVal($name,'bri','100')}<br />
<br />
=== Farbtemperatur ===<br />
Der colorpicker lässt sich auch für die Farbtemperatur (ct, in Kelvin oder Mired) verwenden. Hier ein Beispiel für die Set-Liste eines ct Kommandos mit erlaubten Werten von 2000 bis 6500 Kelvin und eine webCmd Definition mit ct slider und 4 ct Presets.<br />
... ct:colorpicker,CT,2000,10,6500 ...<br />
attr <device> webCmd ct:ct 2040:ct 2630:ct 3703:ct 6250:on:off<br />
<br />
=== Farbton ===<br />
[[Datei:Colorpicker_webCmd.png|mini|rechts|400px|Colorpicker im CT, HUE und RGB-Preset Modus]]<br />
<br />
In der aktuellen Version lässt sich der colorpicker auch für den Farbton (hue) verwenden (ab 11.03.2022 auch mit presets):<br />
<br />
<br />
... hue:colorpicker,HUE,0,1,359 ...<br />
attr <device> webCmd hue:rgb:rgb ff0000:rgb 00ff00:rgb 0000ff:rgb ffffff:on:off<br />
<br />
=== Helligkeit ===<br />
[[Datei:Colorpicker_bri.png|mini|rechts|400px|Colorpicker im BRI Modus]]<br />
<br />
In der aktuellen Version lässt sich der colorpicker auch als Slider der mit einem Graukeil hinterlegt ist verwenden um z.b. die Helligkeit (bri,pct,...) einzustellen:<br />
... pct:colorpicker,BRI,0,1,100 ...<br />
attr <device> webCmd pct:toggle:on:off<br />
<br />
Die Slider für Farbtemperatur, Farbton und Helligkeit sind jeweils mit einem passenden Hintergrund hinterlegt.<br />
<br />
== Farbige Lampen Icons ==<br />
Die Funktion Color_devStateIcon($) erzeugt aus einem übergebenen RGB Wert in der Form "RRGGBB" einen devStateIcon String für farbige SVG Icons (die bunten Blobs werden noch nicht unterstützt). Der Aufruf kann z.B. so zum Setzen des devStateIcons verwendet werden:<br />
:<code>attr <device> devStateIcon {Color_devStateIcon(ReadingsVal($name,"rgb","000000"))}</code><br />
oder<br />
:<code>attr <device> devStateIcon {Color_devStateIcon(CommandGet(undef,"$name rgb"))}</code><br />
<br />
'''NEU:'''<br />
Im Namespace Color gibt es eine zweite, experimentelle Version einer devStateIcon Funktion. Diese unterstützt neben farbigen Lampen auch Dimmer und Schalter. Hier muss der Name (oder hash) des FHEM-Device, ein String der den Typ der Lampe festlegt und bis zu drei Namen von Readings, die den RGB-Wert, die aktuelle Helligkeit im Bereich 0-100 und den Ein/Aus Status enthalten. Also:<br />
:<code><nowiki>Color::devStateIcon( <name|hash>, <type>, <rgb reading>, <percent reading>, <on/off reading> );</nowiki></code><br />
<br />
In <code>type</code> kann zur Zeit <code>rgb</code>, <code>dimmer</code> oder <code>switch</code> übergeben werden. Im Reading für die Helligkeit wird neben den Werten 0-100 auch <code>on</code> und <code>off</code> verstanden.<br />
<br />
Ein Beispiel für eine Lampe, die im Reading <code>rgb</code> die aktuell eingestellte Farbe und im Reading <code>state</code> on oder off enthalten kann: <br />
:<code><nowiki>attr meineLampe devStateIcon {Color::devStateIcon($name,"rgb","rgb","state")}</nowiki></code><br />
<br />
Um z.B. einen WeekdayTimer, der eine Lampe steuert, mit einem passenden Icon zu versehen, könnte man folgendes verwenden:<br />
:<code><nowiki>attr FlurTimer devStateIcon {Color::devStateIcon($name,"dimmer",undef,"state")}</nowiki></code><br />
[[Datei:Colorpicker_devStateIcons.png|mini|rechts|400px|Beispiel mit Nutzung der unterschiedlichen Möglichkeiten]]<br />
Das Icon des WeekdayTimer stellt dann den Zustand dar, mit dem die Lampe aktuell über den Timer gesteuert wird. Nicht den aktuellen Zustand der Lampe, die ja auch anderweitig gesteuert werden kann.<br />
<br />
'''ToDo''': Bestimmen der Helligkeit über den RGB-Wert, wenn kein Reading dafür angeben ist.<br />
<br />
'''Fragen''': <br />
* Ist es für das Interface besser, jeweils direkt die Werte zu übergeben oder die Namen der Readings in denen die Werte zu finden sind?<br />
* Sollte angegeben werden können, welchen Wertebereich die Helligkeit haben kann?<br />
<br />
Zwei Beispiele für die Verwendung und Kombination der oben beschriebenen Routinen gibt es in der fhem.cfg.demo im Simulator für farbige Lanpen.<br />
<br />
== Routinen um zwischen Farbräumen und Darstellungen zu konvertieren ==<br />
Color::rgb2hsv<br />
Color::hsv2rgb<br />
Color::hsb2rgb<br />
Color::rgb2hsb<br />
Color::hex2hsv<br />
Color::hsv2hex<br />
Color::hex2hsb<br />
Color::hsb2hex<br />
Color::hex2rgb<br />
Color::rgb2hex<br />
Color::ct2rgb<br />
Color::xyY2rgb<br />
Color::xyY2hex<br />
<br />
== Farbskala mit Color::pahColor ==<br />
Das auf der Seite [[Temperaturfarbe]] beschriebene Verfahren ist über die Routine <code>Color::pahColor</code> verfügbar, siehe auch {{Link2Forum|Topic=30128|LinkText=diesem Beitrag im FHEM Forum}}.<br />
<br />
:<code><nowiki>Color::pahColor($starttemp,$midtemp,$endtemp,$temp,$colors,$opacity)</nowiki></code><br />
<br />
<code>$colors</code>: Mit [[Temperaturfarbe#Skala_0 | 0]], [[Temperaturfarbe#Skala_1 | 1]] oder [[Temperaturfarbe#Skala_2 | 2]] wird das verwendete [[Temperaturfarbe | Farbmodell]] ausgewählt. Ein selbst definiertes Farbmodell kann als array-ref übergeben werden.<br />
<br />
=== Beispiele ===<br />
Steuern einer Lampe in Abhängigkeit von einer Temperatur:<br />
define <n> notify mytemp:temperature.* {fhem("set lampe rgb ".substr(Color::pahColor(0,15,30,$EVTPART1,0,0),0,6))}<br />
<br />
Einfärben eines Temperaturwertes in einer [[readingsGroup]]:<br />
attr <rg> valueStyle { temperature => '{"style=\"color:\x23".substr(Color::pahColor(0,15,30,$VALUE,0),0,6)."\""}'}<br />
<br />
Einfärben eines Feuchte-Readings in einer readingsGroup:<br />
:<code><nowiki>attr <rg> valueStyle { humidity => '{style=\"color:\x23".substr(Color::pahColor(0,50,100,$VALUE,[255,255,0, 127,255,0, 0,255,0, 0,255,255, 0,127,255]),0,6)."\"}'}</nowiki></code><br />
Hier wird die folgende Farbzuordnung verwendet:[[Datei:color-humidity.png]]<br />
<br />
Anmerkung: {{Taste|\x23}} ist die hexadezimale Escapesequenz für das {{Taste|#}} Zeichen, das beim Einlesen der [[Konfiguration]] sonst als Kommentar interpretiert werden würde. Ist mit aktuellen FHEM Versionen nicht mehr nötig. Das {{Taste|#}} Zeichen kann direkt verwendet werden.<br />
<br />
Es gibt Fälle, in denen ein Farbverlauf für Warnungen/Fehler angezeigt werden soll. Hier bietet sich kein Temperaturähnlicher Verlauf an, weil die Farbfolge nicht von blau über grün zu gelb/rot gehen soll, sondern vielmehr die typische Anzeige schwarz ist, bei Warnungen gelb und bei Fehlern rot sein soll. Im Folgenden Beispiel sollen Zahlenwerte dann gefärbt werden, wenn sie vom Normwert abweichen. Als Beispiel diene eine Füllstandsanzeige (im konkreten Fall geht es um "noch betreibbare Zeit in Wochen"), die von etwa 7 bis 12 im Normbereich liegt (Anzeige schwarz), von etwa 3 bis 6 im Warnungsbereich (gelb) und zwischen 0 und 3 eine Fehlermeldung (rot) ergeben soll. Auch hier kann man pahColor verwenden. Die Farbpalette wird wie folgt erzeugt<syntaxhighlight lang="perl"><br />
sub Farbtester()<br />
{my $s = "";;<br />
my <br />
$farbe = substr(Color::pahColor(0,5,12,0,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>0 Wochen </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,1,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>1 Wochen </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,2,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>2 Wochen </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,3,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>3 Wochen </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,5,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>5 Wochen </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,6,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>6 Wochen </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,7,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>7 Wochen </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,8,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>8 Wochen </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,9,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6); <br />
$s.="<span style='color:#$farbe'>9 Wochen </span>";<br />
$farbe = substr(Color::pahColor(0,5,12,10,[220,50,50, 220,170,0, 220,170,0, 0,0,0, 0,0,0]),0,6);<br />
$s.="<span style='color:#$farbe'>10 Wochen </span>";<br />
return $s}<br />
</syntaxhighlight>und das Ergebnis sieht dann wie folgt aus<br />
[[Datei:Farbpalette Schwarz bis Rot.png|mini|Farbpalette schwarz bis rot]]<br />
<br />
Mit pahColor erzeugte Farbtabellen können mit [[DOIFtools#Farbtabellen_erzeugen|DOIFtools]] angezeigt werden.<br />
<br />
[[Kategorie:Development]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Datei:Farbpalette_Schwarz_bis_Rot.png&diff=37627Datei:Farbpalette Schwarz bis Rot.png2022-11-03T08:54:38Z<p>Andies: </p>
<hr />
<div>Farbpalette</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37613Event-aggregator2022-10-29T08:16:38Z<p>Andies: /* interval */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben. Dabei darf zwischen den Einträgen kein Leerzeichen stehen (siehe [https://forum.fhem.de/index.php/topic,114947.msg1091775.html#msg1091775]).<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Pro Reading kann es nur '''einen''' event-aggregator geben. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Reading zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Dieses Attribut dient dazu, nicht bei jedem Event den Aggregator erneut auszugeben: Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
'''Anmerkung.''' Diese Aussagen scheinen nicht zu stimmen: https://forum.fhem.de/index.php/topic,129920.msg1241897.html#msg1241897<br />
Vielmehr ist es so, dass nach interval Sekunden die gespeicherten Daten gelöscht werden und die Aggregation von Neuem beginnt (reset). Das ist etwas anderes als das unterdrücken von Events.<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem aktuellen Messwert multipliziert wird (zweckmäßig bei konstanten Größen)<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Durchschnitt aus aktuellem Messwert und vorangegangenem Messwert multipliziert wird (zweckmäßig bei linear veränderlichen Größen).<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
* Fragen mit konkretem Zahlenbeispiel in {{Link2Forum|Topic=129920|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37612Event-aggregator2022-10-29T08:16:14Z<p>Andies: /* interval */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben. Dabei darf zwischen den Einträgen kein Leerzeichen stehen (siehe [https://forum.fhem.de/index.php/topic,114947.msg1091775.html#msg1091775]).<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Pro Reading kann es nur '''einen''' event-aggregator geben. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Reading zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Dieses Attribut dient dazu, nicht bei jedem Event den Aggregator erneut auszugeben: Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
'''Anmerkung.''' Diese Aussagen scheinen nicht zu stimmen: https://forum.fhem.de/index.php/topic,129920.msg1241897.html#msg1241897<br />
Vielmehr ist es so, dass nach interval Sekunden die gespeicherten Daten gelöscht werden und die Aggregation von Neuem beginnt (reset). Das ist etwas anderes als das unterdrücken von Events.<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem aktuellen Messwert multipliziert wird (zweckmäßig bei konstanten Größen)<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Durchschnitt aus aktuellem Messwert und vorangegangenem Messwert multipliziert wird (zweckmäßig bei linear veränderlichen Größen).<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
* Fragen mit konkretem Zahlenbeispiel in {{Link2Forum|Topic=129920|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37608Event-aggregator2022-10-28T09:19:13Z<p>Andies: /* interval */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben. Dabei darf zwischen den Einträgen kein Leerzeichen stehen (siehe [https://forum.fhem.de/index.php/topic,114947.msg1091775.html#msg1091775]).<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Pro Reading kann es nur '''einen''' event-aggregator geben. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Reading zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Dieses Attribut dient dazu, nicht bei jedem Event den Aggregator erneut auszugeben: Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
'''Anmerkung.''' Diese Aussagen scheinen nicht zu stimmen: https://forum.fhem.de/index.php/topic,129920.msg1241897.html#msg1241897<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem aktuellen Messwert multipliziert wird (zweckmäßig bei konstanten Größen)<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Durchschnitt aus aktuellem Messwert und vorangegangenem Messwert multipliziert wird (zweckmäßig bei linear veränderlichen Größen).<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
* Fragen mit konkretem Zahlenbeispiel in {{Link2Forum|Topic=129920|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37607Event-aggregator2022-10-27T20:15:16Z<p>Andies: /* Syntax */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben. Dabei darf zwischen den Einträgen kein Leerzeichen stehen (siehe [https://forum.fhem.de/index.php/topic,114947.msg1091775.html#msg1091775]).<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Pro Reading kann es nur '''einen''' event-aggregator geben. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Reading zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Dieses Attribut dient dazu, nicht bei jedem Event den Aggregator erneut auszugeben: Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem aktuellen Messwert multipliziert wird (zweckmäßig bei konstanten Größen)<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Durchschnitt aus aktuellem Messwert und vorangegangenem Messwert multipliziert wird (zweckmäßig bei linear veränderlichen Größen).<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
* Fragen mit konkretem Zahlenbeispiel in {{Link2Forum|Topic=129920|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37606Event-aggregator2022-10-27T19:16:54Z<p>Andies: /* Links */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Pro Reading kann es nur '''einen''' event-aggregator geben. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Reading zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Dieses Attribut dient dazu, nicht bei jedem Event den Aggregator erneut auszugeben: Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem aktuellen Messwert multipliziert wird (zweckmäßig bei konstanten Größen)<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Durchschnitt aus aktuellem Messwert und vorangegangenem Messwert multipliziert wird (zweckmäßig bei linear veränderlichen Größen).<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
* Fragen mit konkretem Zahlenbeispiel in {{Link2Forum|Topic=129920|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37602Event-aggregator2022-10-24T12:29:37Z<p>Andies: /* interval */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Pro Reading kann es nur '''einen''' event-aggregator geben. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Reading zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Dieses Attribut dient dazu, nicht bei jedem Event den Aggregator erneut auszugeben: Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem aktuellen Messwert multipliziert wird (zweckmäßig bei konstanten Größen)<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Durchschnitt aus aktuellem Messwert und vorangegangenem Messwert multipliziert wird (zweckmäßig bei linear veränderlichen Größen).<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37601Event-aggregator2022-10-24T12:28:58Z<p>Andies: /* reading */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Pro Reading kann es nur '''einen''' event-aggregator geben. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Reading zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem aktuellen Messwert multipliziert wird (zweckmäßig bei konstanten Größen)<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Durchschnitt aus aktuellem Messwert und vorangegangenem Messwert multipliziert wird (zweckmäßig bei linear veränderlichen Größen).<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37600Event-aggregator2022-10-24T12:28:29Z<p>Andies: /* method */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Pro Reading kann es nur '''einen''' event-aggregator geben. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Readings zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem aktuellen Messwert multipliziert wird (zweckmäßig bei konstanten Größen)<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Durchschnitt aus aktuellem Messwert und vorangegangenem Messwert multipliziert wird (zweckmäßig bei linear veränderlichen Größen).<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37599Event-aggregator2022-10-24T12:27:23Z<p>Andies: /* reading */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Pro Reading kann es nur '''einen''' event-aggregator geben. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Readings zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem aktuellen Messwert multipliziert wird<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Durchschnitt aus aktuellem Messwert und vorangegangenem Messwert multipliziert wird.<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37588Event-aggregator2022-10-23T08:51:57Z<p>Andies: /* method */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Ein Reading kann nur von '''einem''' event-aggregator ausgewertet werden. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Readings zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem aktuellen Messwert multipliziert wird<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Durchschnitt aus aktuellem Messwert und vorangegangenem Messwert multipliziert wird.<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37587Event-aggregator2022-10-23T08:51:33Z<p>Andies: /* method */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Ein Reading kann nur von '''einem''' event-aggregator ausgewertet werden. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Readings zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Messwert multipliziert wird<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung die Länge des Zeitintervalls mit dem Durchschnitt aus jetzigem Messwert und vorangegangenem Messwert multipliziert wird.<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37586Event-aggregator2022-10-23T08:51:01Z<p>Andies: /* method */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Ein Reading kann nur von '''einem''' event-aggregator ausgewertet werden. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Readings zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
Bei kontinuierlichen Daten kann eine Gewichtung nach Zeitintervallen wichtig sein. Wenn kontinuierliche Daten vorliegen, können hier Ungenauigkeiten auftreten: Man weiß bei einer Messung ja nicht, wie lange der gemessene Wert tatsächlich außerhalb der diskreten Messpunkte noch so den gemessenen Wert widerspiegelt oder sich in Wirklichkeit bereits verändert hat. Dies kann durch die Methode berücksichtigt werden.<br />
<br />
Eine andere Methode als const spielt nur eine Rolle, wenn die Daten zeitlich gewichtet werden. Dabei wird wie folgt vorgegangen.<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: zeitliche Gewichtung, wobei bei der Gewichtung das Intervall mit dem Messwert multipliziert wird<br />
* <code>linear</code>: zeitliche Gewichtung, wobei bei der Gewichtung das Intervall mit dem Durchschnitt aus jetzigem Messwert und vorangegangenem Messwert multipliziert wird.<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37585Event-aggregator2022-10-23T08:41:54Z<p>Andies: /* holdTime */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Ein Reading kann nur von '''einem''' event-aggregator ausgewertet werden. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Readings zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
betrifft die Gewichtung nach Zeitintervallen<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: Annahme, dass zwischen den zwei Messpunkten keine Veränderung stattgefunden hat<br />
* <code>linear</code>: Annahme, dass der Wert sich zwischen zwei Messpunkten linear verändert hat.<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte intern gespeichert und verarbeitet werden, um das Aggregat zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37584Event-aggregator2022-10-23T08:41:17Z<p>Andies: /* interval */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Ein Reading kann nur von '''einem''' event-aggregator ausgewertet werden. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Readings zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events lösen für mindestens <interval> Sekunden keine Verarbeitung des Aggregats aus.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
betrifft die Gewichtung nach Zeitintervallen<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: Annahme, dass zwischen den zwei Messpunkten keine Veränderung stattgefunden hat<br />
* <code>linear</code>: Annahme, dass der Wert sich zwischen zwei Messpunkten linear verändert hat.<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte gehalten werden, um die Aggregatfunktion zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37583Event-aggregator2022-10-23T08:40:45Z<p>Andies: /* interval */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Ein Reading kann nur von '''einem''' event-aggregator ausgewertet werden. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Readings zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events werden für mindestens <interval> Sekunden nicht verarbeitet.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
betrifft die Gewichtung nach Zeitintervallen<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: Annahme, dass zwischen den zwei Messpunkten keine Veränderung stattgefunden hat<br />
* <code>linear</code>: Annahme, dass der Wert sich zwischen zwei Messpunkten linear verändert hat.<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte gehalten werden, um die Aggregatfunktion zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37582Event-aggregator2022-10-23T08:39:21Z<p>Andies: /* reading */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Ein Reading kann nur von '''einem''' event-aggregator ausgewertet werden. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Readings zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events werden für mindestens <interval> Sekunden unterdrückt.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
betrifft die Gewichtung nach Zeitintervallen<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: Annahme, dass zwischen den zwei Messpunkten keine Veränderung stattgefunden hat<br />
* <code>linear</code>: Annahme, dass der Wert sich zwischen zwei Messpunkten linear verändert hat.<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte gehalten werden, um die Aggregatfunktion zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37581Event-aggregator2022-10-23T08:38:50Z<p>Andies: /* reading */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Jedes Reading kann nur von '''einem''' event-aggregator ausgewertet werden. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Readings zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events werden für mindestens <interval> Sekunden unterdrückt.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
betrifft die Gewichtung nach Zeitintervallen<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: Annahme, dass zwischen den zwei Messpunkten keine Veränderung stattgefunden hat<br />
* <code>linear</code>: Annahme, dass der Wert sich zwischen zwei Messpunkten linear verändert hat.<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte gehalten werden, um die Aggregatfunktion zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37580Event-aggregator2022-10-23T08:38:29Z<p>Andies: /* reading */</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Die berechnete Größe wird dann (je nach Definition entweder das Minimum, das Maximum oder der Median der Werte) beim event-aggregator ausgegeben.<br />
<br />
'''Wichtig''': Jedes Reading kann nur von einem event-aggregator ausgewertet werden. Will man daher mehrere Werte (z.B. min, max und avg) von einem Reading ermitteln, muss man dieses Readings zuerst verdoppeln oder verdreifachen (z.B. mit userReadings oder [[notify]]) und dann für jedes Aggregat den entsprechenden event-aggregator anwenden. Der Aggregator kann als regulärer Ausdruck angegeben werden (beispielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events werden für mindestens <interval> Sekunden unterdrückt.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
betrifft die Gewichtung nach Zeitintervallen<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: Annahme, dass zwischen den zwei Messpunkten keine Veränderung stattgefunden hat<br />
* <code>linear</code>: Annahme, dass der Wert sich zwischen zwei Messpunkten linear verändert hat.<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte gehalten werden, um die Aggregatfunktion zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=37579Event-aggregator2022-10-23T08:34:56Z<p>Andies: https://forum.fhem.de/index.php/topic,129800.0.html</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<br />
Oft liegen kontinuierlich anfallende Daten vor, die in bestimmten Zeitabschnitten erfasst werden. Mit dem [[Attribut]] [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median dieser Daten berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
<br />
=== reading ===<br />
Das zu aggregierende [[Reading]] des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem [[Event]] in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Indem dann der event-aggregator auf dieses Reading angewandt wird, werden die erhaltenen Größen bearbeitet - je nach Installation wird dann also das Minimum, das Maximum oder der Median der Werte beim Reading ausgegeben.<br />
<br />
'''Wichtig''': Es kann immer nur einen event-aggregator pro Reading geben. Will man daher mehrere Werte (z.B. min, max, avg), muss man weitere Readings erzeugen (z.B. mit userReadings oder [[notify]]). Der Aggregator kann als regulärer Ausdruck angegeben werden (bspielsweise <code>.*_rain.*</code>)<br />
<br />
=== interval === <br />
Updates des <readings> werden ignoriert, Events werden für mindestens <interval> Sekunden unterdrückt.<br />
<br />
Nach der Interval-periode wird das reading mit einem Wert aktualisiert, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
betrifft die Gewichtung nach Zeitintervallen<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: Annahme, dass zwischen den zwei Messpunkten keine Veränderung stattgefunden hat<br />
* <code>linear</code>: Annahme, dass der Wert sich zwischen zwei Messpunkten linear verändert hat.<br />
<br />
=== function === <br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> arithmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für ''method'' <code>none</code> und gesetzte ''holdTime'') - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
Zeitfenster in Sekunden, für die die vergangenen Werte gehalten werden, um die Aggregatfunktion zu berechnen.<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden. In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch [[DOIF]]_Readings, event_Readings und userReadings verwendet werden:<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
<br />
=== DOIF_Readings ===<br />
TODO!<br />
:<code>original_reading:interval:method:function:holdTime</code><br />
Es gibt mittlerweile auch bei DOIF eine Funktion, die diverse Mittelwerte berechnet. Für alle, die mit event-aggregator hadern, ggf. eine Alternative.<br />
<br />
=== event_Readings ===<br />
:<code>attr DOIF-Device event_Readings original_reading:[<Device>:<Reading>], </code><br />
:<code>copy_1:[$SELF:original_reading], </code><br />
:<code><s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
<br />
=== userReadings ===<br />
:<code>attr DOIF-Device userReadings original_reading {ReadingsVal("<Device>","<Reading>",0)}, </code><br />
:<code>copy_1 {ReadingsVal($name,"original_reading",0)}, </code><br />
:<code>copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10} </code><br />
:<code>attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen (siehe {{Link2Forum|Topic=114947|Message=1091775|LinkText=diesen Forenbeitrag}}).<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
:<code>attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v:</code><br />
:<code>attr myBadSensor event-aggregator TEMP::none:median:300:</code><br />
:<code>attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Reparaturen&diff=37565Reparaturen2022-10-02T06:07:07Z<p>Andies: /* Homematic */</p>
<hr />
<div>Auf der folgenden Seite sollen Hinweise zu Reparaturen gesammelt werden, die FHEM-gesteuerte oder durch FHEM-betriebene Geräte betreffen.<br />
<br />
== Elkos ==<br />
Elektrolytkondensatoren sind klassische Schwachstellen eines elektronischen Gerätes. Im Privatbereich vorwiegend Aluminium-Elektrolykondensatoren mit Spezifikation 85°C und 110°C verkauft. Die Temperatur gibt dabei die Heiß-Lagerzeitprüfung an, je höher, desto hochwertiger ist der Elko. Oft sind 85°C-Elkos verbaut, die nach einigen Jahren ihre Kapazität verlieren. Es ist im Netz sehr viele Beiträge bekannt in denen beschrieben wird, das bereits der Tausch durch neue Elkos Geräte zum Leben wiedererweckt.<br />
<br />
== Homematic ==<br />
Die klassischen Homematic-Geräte leiden daran, das unter dem Elko C26 ein minderwertiger Elektrolyt-Kondensator verbaut wird. Dimmer und andere 230V-Schalter fallen aus und können durch den Tausch von C26 leicht repariert werden: [https://wiki.fhem.de/wiki/HM-LC-Sw1PBU-FM_Unterputz-Schaltaktor_1-fach#M.C3.B6gliche_Hardwaredefekte|Link]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Reparaturen&diff=37564Reparaturen2022-09-30T15:25:44Z<p>Andies: https://forum.fhem.de/index.php/topic,74920.msg1237243.html#msg1237243</p>
<hr />
<div>Auf der folgenden Seite sollen Hinweise zu Reparaturen gesammelt werden, die FHEM-gesteuerte oder durch FHEM-betriebene Geräte betreffen.<br />
<br />
== Elkos ==<br />
Elektrolytkondensatoren sind klassische Schwachstellen eines elektronischen Gerätes. Im Privatbereich vorwiegend Aluminium-Elektrolykondensatoren mit Spezifikation 85°C und 110°C verkauft. Die Temperatur gibt dabei die Heiß-Lagerzeitprüfung an, je höher, desto hochwertiger ist der Elko. Oft sind 85°C-Elkos verbaut, die nach einigen Jahren ihre Kapazität verlieren. Es ist im Netz sehr viele Beiträge bekannt in denen beschrieben wird, das bereits der Tausch durch neue Elkos Geräte zum Leben wiedererweckt.<br />
<br />
== Homematic ==<br />
Die klassischen Homematic-Geräte leiden daran, das unter dem Elko C26 ein minderwertiger Elektrolyt-Kondensator verbaut wird. Dimmer und andere 230V-Schalter fallen aus und können durch den Tausch von C26 leicht repariert werden.</div>Andieshttp://wiki.fhem.de/w/index.php?title=Raspberry_Pi&diff=37417Raspberry Pi2022-05-02T10:57:36Z<p>Andies: /* Bekannte Probleme */ Kabelprobleme hinzugefügt</p>
<hr />
<div>Beim [[Raspberry Pi]] handelt es sich um einen postkartengroßen Einplatinen-Computer, der von der Raspberry Pi Foundation entwickelt wird. Die Hardware basiert auf dem BCM 283x SoC (System-on-Chip) von Broadcom, einem ARM-Prozessor. Zu Hardwaredetails und den verschiedenen Modellen sowie Produktentwicklungen siehe [http://de.wikipedia.org/wiki/Raspberry_Pi#Hardware Wikipedia].<br />
Dank der kleinen Abmessungen, dem recht geringen Energieverbrauch (bis ca. 4 Watt) sowie der günstigen Anschaffungskosten (ca. 30€) ist der Raspberry Pi eine attraktive Hardware für die Heimautomatisierung mit FHEM. Er ist dank dem Linux-Betriebssystem vollständig kompatibel zur aktuell vorhandenen und von FHEM unterstützen Hardware. Das derzeit empfohlene Standard-Image zum Betrieb des Raspberry Pi ist die auf Debian basierende Raspberry Pi OS Distribution (ab Mitte 2019 ''Buster'').<br />
<br />
== Installation / Setup ==<br />
=== Betriebssystem ===<br />
====Vorbemerkung====<br />
Raspberry Pi OS ist direkt bei raspberrybi.org unter https://www.raspberrypi.org/downloads/raspberry-pi-os/ herunterladbar. Die folgende Anleitung gilt für die lite-Version ohne grafischen Desktop und für die Modelle für B, B+, B2, B3, B3+, Zero W. (Stand Juni 2018)<br />
<br />
Alle in diesem Abschnitt verwendeten Code Blöcke benötigen root Rechte. Deshalb bitte immer am Besten im Kontext <code>sudo su</code> ausführen. Man kann auch einzelne Befehle mit sudo davor ausführen, allerdings wird die Berechtigung bei Pipe Befehlen nicht durchgereicht. Einige dieser Kommandos funktionieren in der angegebenen Form nicht unter der Wheezy-Version [https://en.wikipedia.org/wiki/Raspberry_Pi_OS#Release_history] des RPi OS. Läuft der betreffende RPi noch unter Wheezy, ist ein Upgrade des RPi OS empfehlenswert.<br />
<br />
Alle Dateien müssen im Linux-Format (nur LF als Zeilenende) erzeugt/editiert werden! Unbedingt einen geeigneten Editor verwenden und auf das Format beim Speichern achten!<br />
<br />
====SD-Karte vorbereiten====<br />
Die heruntergeladene Datei muss entpackt und auf die Speicherkarte geschrieben werden. Es gibt dazu verschiedene Tools je nach Betriebssystem. Für Windows ist windisk32imager zu empfehlen, Projektseite [https://sourceforge.net/projects/win32diskimager/]. Für Mac OS gibt es den Pi Filler.<br />
<br />
Detaillierte Anleitungen zur Vorgehensweise finden sich für die Betriebssysteme Linux, Mac OS und Windows unter [https://www.raspberrypi.org/documentation/installation/installing-images/README.md Writing an image to the SD card]<br />
<br />
Die SD Card enthält nun zwei Partitionen/Laufwerke, wobei das erste Laufwerk unter alle Betriebssystemen lesbar ist. In diesem Laufwerk (/boot) müssen jetzt noch zwei Dateien erzeugt werden:<br />
* eine leere Datei mit dem Namen ssh, um den (headless) Zugriff per ssh zu ermöglichen (Pi Filler macht dies automatisch). Hinweis: Eine spätere Aktivierung von SSH ist mit <code>sudo raspi-config</code> (Punkt 5 "Interfacing Options", dann Punkt 2 SSH) möglich, erfordert dann aber Tastatur und Monitor am RPi.<br />
* eine Textdatei im Linux Format mit Namen wpa_supplicant.conf und folgendem Inhalt, wenn der Pi sofort mit WLAN starten soll.<br />
<br />
<pre>country=DE<br />
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev<br />
update_config=1<br />
network={<br />
ssid="FRITZ!Box 7490"<br />
psk="12345678901234567890" <br />
}<br />
</pre><br />
* SD Karte auswerfen.<br />
* SD Karte in Raspberry Pi stecken und booten.<br />
<br />
Alternativ kann auch Monitor und Tastatur verwendet werden.<br />
<br />
====Anmeldung und Grundkonfiguration====<br />
Default raspberrypi-os: Host raspberrypi, User pi, Passwort raspberry <br />
<br />
Default ubuntu: Host ubuntu, User ubuntu, Passwort ubuntu<br />
<br />
Anmeldung entweder lokal oder mit dem Befehl: ssh <user>@<hostname><br />
<br />
Das Passwort sollte geändert werden, dazu dem Sicherheitshinweis folgen und <code>passwd</code> eingeben.<br />
<br />
Alle unten genannten Befehle müssen mit erhöhten Rechten ausgeführt werden (z. B. sudo)!<br />
<br />
Als Erstes sollte: Zeitzone, Sprache und Hostname angepasst werden. <br />
Entweder Menügeführt mit <code>sudo raspi-config</code> <br />
oder per Script / Shell Befehle:<br />
<br />
<syntaxhighlight lang="bash"># Zeitzone einstellen & Zeitsynchronisierung über das Internet aktivieren<br />
timedatectl set-timezone Europe/Berlin<br />
timedatectl set-ntp true<br />
<br />
# Konfigurieren lokale Sprache deutsch<br />
sed -i -e 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/' /etc/locale.gen<br />
locale-gen<br />
localectl set-locale LANG=de_DE.UTF-8 LANGUAGE=de_DE<br />
<br />
# Hostname <br />
hostnamectl set-hostname mymachine<br />
<br />
# System aktualisieren <br />
apt-get update<br />
apt-get upgrade<br />
<br />
#Neustart<br />
reboot</syntaxhighlight><br />
<br />
Am Anfang sollte man Befehle nicht verketten, sondern immer auf die Ausgabe warten (es sei denn, man hat Erfahrung): also kein <code>apt-get update && apt-get upgrade </code>. Ebenso sollte man nicht mit automatischen Bestätigungen arbeiten, also kein upgrade mit "-y". Nach einer Installation ist ein aufräumen immer gut, also:<br />
<syntaxhighlight lang="bash"><br />
apt-get autoremove<br />
apt-get clean<br />
apt-get purge $(dpkg --get-selections | grep deinstall | cut -f1 | xargs)<br />
</syntaxhighlight><br />
<br />
====Verwendung UART für Zusatzmodule====<br />
Einige Aufsteckmodule (z.B. HM-MOD-RPI-PCB) für den GPIO Port verwenden die serielle Schnittstelle UART. Der Zugriff auf diese serielle Schnittstelle erfordert eine modellabhängige Konfiguration.<br />
<br />
Bei allen Modellen muss die Verwendung der seriellen Linux console an ttyAMA0 deaktiviert werden:<br />
<syntaxhighlight lang="bash"># seriell-getty Dienst für ttyAMA0 dauerhaft deaktivieren<br />
systemctl stop serial-getty@ttyAMA0.service<br />
systemctl disable serial-getty@ttyAMA0.service<br />
systemctl mask serial-getty@ttyAMA0.service<br />
</syntaxhighlight><br />
Bei den Modellen mit Bluetooth muss die UART aktiviert und umkonfiguriert werden. Hier ein bash Script, welches die Originaldatei entsprechend modifiziert:<br />
<syntaxhighlight lang="bash"><br />
# serielle Schnittstelle aktivieren und mit BT Schnittstelle tauschen<br />
# für Raspberry Pi OS<br />
config="/boot/config.txt"<br />
# für Ubuntu<br />
#config="/boot/firmware/usercfg.txt"<br />
<br />
bash -c "cat <<EOF >> $config<br />
enable_uart=1<br />
dtoverlay=miniuart-bt<br />
core_freq=250<br />
EOF"<br />
</syntaxhighlight><br />
Wer dem nicht traut, der editiert die Datei von Hand (Linux Editor!) und fügt am Ende die drei Zeilen aus dem Script ein, die vor EOF stehen.<br />
<br />
Die config Datei von ubuntu verwendet den Befehl include usercfg.txt. Mit Erscheinen des Pi 4 wurden die overlay Dateien umbenannt (Start mit Pi3- entfernt) die alten Namen funktionieren aber noch.<br />
<br />
Um die Konfiguration abzuschließen ist ein Neustart erforderlich<br />
<syntaxhighlight lang="bash">#Neustart erforderlich <br />
reboot</syntaxhighlight><br />
<br />
====Troubleshooting====<br />
'''Kontrolle der seriellen Schnittstelle'''<br />
<br />
Der Befehl <code>ls -l /dev/ttyAMA0</code> muss folgende Ausgabe liefern.<br />
crw-rw---- 1 root dialout 204, 64 Jun 7 22:56 /dev/ttyAMA0<br />
Sollte dies nicht der Fall sein, muss der Dienst serial-getty@ttyAMA0.service deaktiviert werden!<br />
<br />
Kontrolle der Verlinkung von /dev/serial*<br />
<br />
Der Befehl <code>ls -l /dev/serial*</code> muss folgende Ausgabe liefern.<br />
* Bei Modellen mit BT und richtiger Konfiguration (funktioniert nur unter Raspberry Pi OS)<br />
lrwxrwxrwx 1 root root 7 Jun 7 22:55 /dev/serial0 -> ttyAMA0<br />
lrwxrwxrwx 1 root root 5 Jun 7 22:55 /dev/serial1 -> ttyS0<br />
* Bei den Modellen ohne BT und richtiger Konfiguration<br />
lrwxrwxrwx 1 root root 7 Jun 8 18:30 /dev/serial0 -> ttyAMA0<br />
Sollte das nicht der Fall sein, sind die Einträge in der /boot/config.txt fehlerhaft. <br />
<br />
Sollte die serielle Schnittstelle unerwartet nicht funktionieren, kann auch andere Software daran Schuld sein, weil diese einfach versucht, alle Schnittstellen abzufragen / zu initialisieren. Für die Fehlersuche ist es also wichtig zu wissen, welche Software so installiert wurde, speziell wenn diese serielle Schnitttstellen (USB) verwendet / verwenden will. Ein Beispiel (deconz/conbee) wird in {{Link2Forum|Topic=116428|Message=1107317|LinkText=diesem Forenbeitrag}} behandelt. <br />
<br />
Bei einem Raspberry 4 stört unter Umständen die Temperaturkontrolle des Lüfters, siehe auch Abschnitt bekannte Probleme: [[HM-MOD-RPI-PCB HomeMatic Funkmodul für Raspberry Pi]]. <br />
<br />
'''Kontrolle Bluetooth'''<br />
<br />
Die Funktion von Bluetooth kann mit dem hcitool überprüft werden. Mit <code>hcitool dev</code> wird das interne BT Gerät mit MAC Adresse angezeigt. Mit <code>hcitool scan</code> bzw. <code>hcitool lescan</code> kann nach sichtbaren Geräten gesucht werden.<br />
<br />
Weitergehende Informationen zur Anpassung der Konfiguration von Raspberry Pi OS sind nachzulesen auf https://www.raspberrypi.org/documentation/configuration/.<br />
<br />
Sollte die Bluetooth Schnittstelle nach der Installation von FHEM nicht funktionieren, hilft es den Dienst abhängig zu starten, siehe diesen Wiki Artikel [[Fhem.service (systemd unit file)]] <br />
<br />
=== FHEM ===<br />
Die Installation von FHEM kann nach der Raspberry Pi OS Installation sehr einfach über das Debian-Repository [http://debian.fhem.de] erfolgen. <br />
* Es wird unbedingt empfohlen zur Grundinstallation zunächst keine Module, USB Sticks oder ähnliche Zusatzbaugruppen an den IO Ports des Raspberry gesteckt zu haben. <br />
* Dieser Abschnitt beschreibt nur die Grundinstallation von FHEM auf einem Raspberry Pi mit Raspberry Pi OS! <br />
* Weitere Installationsschritte sind je nach verwendeten FHEM-Modulen notwendig. <br />
** Informationen hierzu liefert üblicherweise die {{Link2CmdRef}} zum jeweiligen Modul.<br />
** Den weiteren Einstieg in FHEM findet man im Artikel [[Quick-Start]]<br />
<br />
==== Der einfache Weg zum aktuellen System ====<br />
Der folgende Befehlsblock ist die praktische Umsetzung der Beschreibung auf http://debian.fhem.de. Bitte unbedingt vor Installation rückversichern, ob es dort (insbesondere unter ''The easy way: use apt-get'') Aktualisierungen gab. <br />
* Dieser Befehlsblock erfordert erhöhte Rechte, also bitte als Erstes <code>sudo su</code> ausführen!<br />
* Beim Kopieren aufpassen! Jede Zeile muss einzeln ausgeführt werden!<br />
Dieser Befehlsblock gilt ab der Version ''debian buster'' als veraltet (es gibt Sicherheitsbedenken), muss aber bis einschließlich ''debian stretch'' eingesetzt werden.<br />
<syntaxhighlight lang="bash"><br />
# von debian.fhem.de installieren - siehe aktuelle Anleitung dort https://debian.fhem.de/<br />
wget -qO - https://debian.fhem.de/archive.key | apt-key add -<br />
echo "deb http://debian.fhem.de/nightly/ /" >> /etc/apt/sources.list<br />
apt-get update<br />
apt-get install fhem<br />
</syntaxhighlight><br />
Dieser Befehlsblock funktioniert erst ab ''debian buster'' (erfordert erhöhte Rechte <code>sudo su</code>)<br />
<syntaxhighlight lang="bash"><br />
# Bei manchen debian Distributionen fehlt das Paket gpg -> nachinstallieren<br />
apt update<br />
apt install gpg<br />
# von debian.fhem.de installieren - siehe aktuelle Anleitung dort https://debian.fhem.de/<br />
wget -O- https://debian.fhem.de/archive.key | gpg --dearmor > /usr/share/keyrings/debianfhemde-archive-keyring.gpg<br />
echo "deb [signed-by=/usr/share/keyrings/debianfhemde-archive-keyring.gpg] https://debian.fhem.de/nightly/ /" >> /etc/apt/sources.list<br />
apt update<br />
apt install fhem<br />
</syntaxhighlight><br />
<br />
==== Das offizielle Release ====<br />
Man kann FHEM mit dem Debian-Paket von [https://fhem.de/#Installation fhem.de] installieren. Dieser Weg führt zu einem offiziellen Release, welches aber unter Umständen erheblich vom aktuellen Versions- und Diskussionsstand im Forum abweicht. <br />
<br />
Alternativ kann man auch den manuellen Weg von https://debian.fhem.de/ wählen.<br />
<br />
==== Empfohlener Patch ====<br />
Da gerade auf dem Raspberry die automatische Erkennung der USB Schnittstellen zu 100% CPU Last führt (FHEM träge und reagiert nicht), wird empfohlen sofort nach der Installation noch diesen "Patch" auszuführen: FHEM starten, wenn alle USB-Geräte ausgesteckt sind. Dann <code>attr initialUsbCheck disable 1</code> in der Kommandozeile in FHEMWEB eingeben, <code>save</code> ausführen und FHEM anschließen wieder mit eingesteckten USB-Geräten neu starten.<br />
<br />
==== Deinstallation ====<br />
Man kann FHEM auch wieder spurlos vom System entfernen und ganz von vorn beginnen. Allerdings sollte man sich im Klaren sein, damit ensteht kein jungfräuliches System!<br />
<syntaxhighlight lang="bash"><br />
sudo apt-get purge fhem<br />
sudo apt-get autoremove<br />
</syntaxhighlight><br />
<br />
=== Zusatzpakete bei FHEM-Erst- und Zweitinstallation ===<br />
Nachdem der RPi eingerichtet ist, können weitere Pakete installiert werden. Keines davon ist zwingend erforderlich, um das Grundgerüst von FHEM betreiben zu können. Einige Pakete erhöhen aber den Bedienungskomfort, andere sind zur Nutzung bestimmter weiterer FHEM-Module (siehe {{Link2CmdRef}}) erforderlich. <br />
<br />
Hierzu wurden in letzter Zeit mehrere Hilfsmodule entwickelt, die insbesondere bei Wiederinstallation (etwa nach Absturz) wichtig sein können. So zeigt das Modul Installer die installierten Perl-Module an, siehe dazu {{Link2Forum|Topic=98381|LinkText=diesen Thread}}.<br />
<br />
Wenn man eine frühere Installation auf einer anderen SD-Karte installieren möchte und nicht mehr weiß, welche Zusatzpakete man auf der alten Karte installiert hatte, hilft (diese und nachfolgende Hinweise sind aus dem Blog [https://heinz-otto.blogspot.com/2019/07/infos-zur-installation-von-modulen-und.html])<br />
zcat $(ls -tr /var/log/apt/history.log.*.gz)|grep -A1 Start-Date<br />
weiter. Hier werden frühere Eingaben der Kommandozeile wiedergegeben. Es gibt einen analogen Befehl, um die mit CPAN installierten Pakete anzuzeigen. Dazu muss man das debian Paket perl-doc installiert haben und gibt dann ein<br />
for M in `perldoc -t perllocal|grep Module |sed -e 's/^.*" //'`; do V=`perldoc -t perllocal|awk "/$M/{y=1;next}y" |grep VERSION |head -n 1`; printf "%30s %s\n" "$M" "$V"; done |sort<br />
Ebenso kann man herausfinden, ob und durch welches debian-Paket das Perl-Paket installiert wurde. Die zweite Version sucht nur in Paketen die -perl im Namen tragen und läuft damit wesentlich schneller:<br />
s='Device::SerialPort' ## zu diesem Paket wird gesucht<br />
perl -M$s -e '' 2>/dev/null &&echo "Modul $s ist vorhanden"''<br />
for i in $(dpkg -l |grep ^ii| awk '{ print $2 }'|tr -d "\r"|tr "\n" " ");do if dpkg -L $i|grep $s &> /dev/null;then echo $i enthält $s;fi;done<br />
for i in $(dpkg -l |grep ^ii|grep '\-perl'| awk '{ print $2 }'|tr -d "\r"|tr "\n" " ");do if dpkg -L $i|grep $s &> /dev/null;then echo $i enthält $s;fi;done<br />
<br />
Es gibt gute Gründe, die Installation von Perl Modulen über debian-Pakete der Installation über cpan zu bevorzugen. Dazu zählt die Updatefähigkeit und die Geschwindigkeit. Man kann im Internet nach den Paketen suchen, man kann aber auch einfach die Verfügbarkeit für das lokale System testen. Dazu braucht man das Tool apt-file, welches man zuerst installieren muss. Der letzte Befehl lädt den Infocache lokal und dauert etwas:<br />
sudo apt-get update<br />
sudo apt-get install apt-file<br />
sudo apt-file update<br />
Die folgende Suche nutzt den Umstand, dass in der im Paket enthaltenen Liste der Dateien auch die Doku in der Form "/usr/share/man/man3/IO::File.3perl.gz" enthalten ist. Der search Befehl unten akzeptiert mehrere Modulnamen durch Zeilenumbruch getrennt. In dem Beispiel sind die Modulnamen in einem String durch Leerzeichen getrennt, die Trennung wird in Zeilenumbruch geändert, jede Zeile ergänzt und über stdin an den search Befehl von apt-file übergeben. Die Option -l bewirkt das nur die gefunden Pakete gelistet werden, werden mehrere der abgefragten Modulnamen in einem Paket gefunden, wird es nur einmal gelistet:<br />
s="IO::File Digest::MD5" ##Such-String<br />
echo $s|tr " " "\n"|sed 's/$/./;s/^/\//'|apt-file search -l -f -<br />
<br />
Zuletzt eine Übersicht diverser Zusatzpakete.<br />
{| class="wikitable"<br />
! style="width:10%" | Beschreibung<br />
! style="width:10%" | Paketname<br />
! style="width:50%" | Kontext<br />
! style="width:30%" | Installieren<br />
|-<br />
|Zeitserver<br />
|ntpdate<br />
|Setzt die Systemzeit bei Start des RPi. Wird für FHEM benötigt, da es sonst nicht startet.<br />
|<code>sudo apt-get install ntpdate<br />
sudo ntpdate -u de.pool.ntp.org</code><br />
|-<br />
|Perl JSON<br />
|JSON<br />
|Wird von einigen Modulen benötigt, z.B. harmony, iTunes<br />
|<code>sudo apt-get install libjson-perl</code><br />
|-<br />
|Samba-Server<br />
|samba<br />
|Mittels Samba kann man z.B. den Ordner /opt/fhem als Share freigeben. Dieser Share kann z.B. im Windows-Explorer als Laufwerk verbunden werden, so dass die Bearbeitung von config- und Programmdateien bequem möglich ist. Hier eine hilfreiche [https://www.elektronik-kompendium.de/sites/raspberry-pi/2007071.htm Kurzanleitung] aus der (wenn man auf einen speziellen user verzichtet) nur die Einträge für smb.conf gesetzt werden müssen.<br />
|<code>sudo apt-get install samba cifs-utils</code><br />
Danach muss der share definiert werden mittels<br />
<br />
<code>sudo nano /etc/samba/smb.conf</code><br />
|-<br />
|Mailversand<br />
|sendemail (alt: sendEmail)<br />
|Wird benötigt, um Mails versenden zu können, bspw. für Alarm-Benachrichtigungen.<br />
Nach Installation des Paketes benötigt man noch eine Routine in FHEM gemäß [[E-Mail senden#Raspberry Pi]]<br />
|<code>sudo apt-get install sendemail</code> bzw. <code>sudo apt-get install sendEmail</code><br />
|-<br />
|Wake-on-LAN<br />
|etherwake<br />
|Wird z.B. für das Modul WOL benötigt.<br />
|<code>sudo apt-get install etherwake</code><br />
|-<br />
|Perl Telnet<br />
|telnet<br />
|Wurde vor Fritz!OS 6.2x z.B. für das Modul [[FRITZBOX]] benötigt, da es eine im Netzwerk vorhandene Fritzbox über deren Telnet-Port ansprach. Mittlerweile wird TR-64 und SOAP verwendet.<br />
|<code>sudo apt-get install libnet-telnet-perl</code><br />
|-<br />
|Socat<br />
|socat<br />
|Kann verwendet werden, um auf anderen Rechnern im Netzwerk Linux-Befehle oder Skripts auszuführen. Auch können auf Slave-FHEM-Installationen Befehl ausgeführt werden, z.B. mit <br />
<br />
<code><nowiki>system("echo 'set lampe on' | /usr/bin/socat - TCP:1.2.3.4:7072");</nowiki></code><br />
<br />
1.2.3.4 muss natürlich durch die IP-Adresse des Zielrechners ersetzt werden.<br />
|<code>sudo apt-get install socat</code><br />
|-<br />
|Libcrypt<br />
|Libcrypt<br />
|Perl libcrypt, erforderlich falls Homematic-devices mit AES verwendet werden sollen.<br />
|<code>sudo apt-get install libcrypt-rijndael-perl</code><br />
|-<br />
|libdatetime<br />
|libdatetime<br />
|Perl libdatetime, erforderlich für das Weather-Modul.<br />
|<code>sudo apt-get install libdatetime-format-strptime-perl</code><br />
|-<br />
|EnOcean XML functions<br />
|libxml simple<br />
|Perl XML::SIMPLE, erforderlich für die XML Funktionen des ENOCEAN Moduls.<br />
|<code>sudo apt-get install libxml-simple-perl</code><br />
|-<br />
|EnOcean Cryptographic functions<br />
|libcrypt-random-source-perl<br />
|Perl Crypt::Random, erforderlich für die Cryptographic Funktionen des ENOCEAN Moduls.<br />
|<code>sudo /usr/bin/perl -MCPAN -e 'install Crypt::Random'</code><br />
|}<br />
<br />
== Bekannte Probleme ==<br />
=== Netzteil ===<br />
Der RPi verwendet ein USB Netzteil als Spannungsversorgung. Gemessen kann der RPi allein bereits um die 900mA Strom fordern. Das bringt kleine Netzteile, besonders wenn noch CULs oder WLAN Sticks an USB hängen schnell an die Grenze. Die Fehler die daraus resultieren sind Abstürze, Netzwerkprobleme uvm. Daher bitte ein ausreichend starkes Netzteil mit mind. 2000mA oder einen aktiven USB-HUB für die Periperie verwenden.<br />
<br />
=== Kabel (Micro-USB) ===<br />
Auch das verwendete Kabel kann einen (großen) Unterschied machen. Billige Kabel haben sehr dünne Kupferadern, die auf größeren Strecken (bereits ab 30cm!) einen Spannungsabfall verursachen können, der sonst nicht nachvollziehbare Probleme (Festplattenausfall, SD-Kartenausfall etc.) auslöst. Siehe beispielsweise diesen Thread mit einer Tabelle, die die Höhe des Spannungsabfalls explizit beschreibt: [https://forum.fhem.de/index.php/topic,127508.0.html Link zum Forum] <br />
<br />
=== Echtzeituhr ===<br />
Der RPi hat keine [http://de.wikipedia.org/wiki/Echtzeituhr Real-Time-Clock] (RTC), das heißt, dass er nach einem Neustart keine gültige (im Sinne von aktuell) Systemzeit hat, sondern ein Datum in der Vergangenheit. Dieses Problem wird sinnvollerweise mit einer [http://de.wikipedia.org/wiki/Network_Time_Protocol NTP-Konfiguration] oder durch [[Raspberry Pi: RTC Hat|Installation einer Echtzeituhr]] umgangen.<br />
<br />
Dabei muss Sorge getragen werden, dass der [http://wiki.debian.org/NTP ntpd] schon einen Datums-/Zeitabgleich gemacht hat, bevor FHEM gestartet wird. Geschieht der Abgleich nicht vorher, sondern erst nachdem FHEM schon läuft, stellt FHEM die Logs zwar auf das nun aktuelle Datum um (die "alten" Logs mit dem eigentlich ungültigen Datum werden natürlich behalten), aber irgendetwas scheint FHEM dabei so zu belasten, dass es eine Last von über 0.8 bis 0.9 erzeugt. Diese Last besteht auf Dauer und verschwindet erst, wenn man das Ganze sauber durchkonfiguriert und FHEM neu gestartet hat. Die hohe Systemauslastung zeigt sich auch in einem sehr trägen Laden der FHEM-Webseiten in einem beliebigen Browser. (siehe {{Link2Forum|Topic=70741}})<br />
<br />
=== Last durch Backup (während update) ===<br />
Bei einen [[Update]] von FHEM durch den Befehl <code>update</code> kann durch Setzen des Attributs "<code>attr global backup_before_update 1</code>" automatisch vorab ein [[Backup]] durchgeführt werden. Die (ggf. großen) Log-Dateien werden dabei ebenfalls archiviert. Während der Archivierung ist FHEM blockiert. Durch die beschränkte Leistungsfähigkeit des Raspberry Pi kann das Backup zudem lange dauern. Durch ein "<code>attr global updateInBackground 1</code>" wird ein Backup im Hintergrund ausgeführt (Quelle: {{Link2Forum|Topic=15729}}). <br />
<br />
Alternative Möglichkeiten: <br />
* Backup ausschalten und manuell durchführen <br />
* Backup-Befehl anpassen und so große Dateien bzw. Verzeichnisse (log/) nicht archivieren<br />
<br />
== Watchdog einrichten ==<br />
Man kann den RPi regelmäßig prüfen lassen, ob FHEM noch läuft und gegebenenfalls einen Neustart durchführen lassen. Eine mögliche Vorgehensweise ist in diesem {{Link2Forum|Topic=20553|LinkText=Forumsthema}} beschrieben.<br />
{{Hinweis|Statt des Einsatzes derartiger Methoden ist zu empfehlen, nach der eigentliche Fehlerursache zu forschen und diese abzustellen. Haben Sie dennoch einen solchen Watchdog eingerichtet, sollten Sie bei Fragen zu Ihnen seltsam erscheinenden Phänomänen im Forum darauf hinweisen, auch wenn die Symptome scheinbar nichts mit dem Watchdog zu tun haben sollten.}}<br />
<br />
== Interne Links ==<br />
* [[CUL am Raspberry Pi flashen]]<br />
* [[Raspberry Pi und 1-Wire]]<br />
<br />
== Externe Links ==<br />
* {{Link2Forum|Topic=33460|Message=264679}} zum Umzug von Raspberry B auf Raspberry Pi 2<br />
* [http://www.raspberrypi.org/ Offizielle Webseite der Raspberry Pi Foundation]<br />
* [http://www.raspberrypi.org/downloads Offizielle Downloads der Raspberry Pi Foundation]<br />
<br />
[[Kategorie:Raspberry Pi]]<br />
[[Kategorie:HOWTOS]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=DOIF/uiTable_Schnelleinstieg&diff=37170DOIF/uiTable Schnelleinstieg2022-01-30T11:34:01Z<p>Andies: /* Farbskalierte Anzeige eines Zahlenwertes mit Hilfe der universellen SVG-Funktion ring */</p>
<hr />
<div>[[Datei:UiTable state screen.png|700px|rechts|Webansicht bestehend aus mehreren DOIF/uiTable-Definitionen]]<br />
An dieser Stelle wird das DOIF-Web-Interface erklärt, welches über das DOIF-Attribut '''uiTable''' realisiert wurde. <br />
<br />
Abhängig von der Art der Funktion können in einer tabellarischen Darstellung FHEM-Geräte visualisiert und über die Web-Oberfläche bedient werden. Eventbasierte Änderungen visualisierter Readings werden unmittelbar in der Web-Ansicht aktualisiert. Eine erstellte Tabelle erscheint unterhalb der Statuszeile eines DOIF-Devices. Das uiTable-Attribut kann in bereits bestehenden DOIFs oder in funktionslosen DOIFs, wie in den unteren Beispielen, als reines WEB-Interface erstellt werden. In der Abbildung rechts ist ein Statusbildschirm aus vier Spalten mit mehreren DOIF/uiTable-Definitionen aufgebaut worden.<br><br />
<br />
Die Darstellungsmöglichkeiten werden anhand von Beispielen insb. mit Hilfe bereits im DOIF-Modul vordefinierter uiTable-Funktionen aufgezeigt. Diese Perlfunktionen sind in einem eigenen Package namens 'ui_Table' definiert worden. Mit Hilfe dieser Funktionen lassen sich recht einfach, ohne tiefere HTML/CSS-Kenntnisse, eigene Übersichten definieren. Im Anschluss werden typische '''[[DOIF/uiTable Schnelleinstieg#Anwendungsbeispiele|Anwendungsbeispiele]]''' aufgezeigt.<br />
<br />
Die folgenden Beispieldefinitionen arbeiten mit konkreten Geräten und Readings, sie können als RAW-Definition ins eigene System übernommen werden, dazu müssen die Gerätenamen, Readings, ggf. auch Icons den existierenden Namen des eigenen Systems angepasst werden. Zum Ausprobieren der Beispiele können statt echter Geräte auch Dummys benutzt werden. <br />
<br />
Es gibt im Perl-Modus des DOIF-Moduls ebenfalls das Attribut '''uiState''', welches die gleiche Syntax wie uiTable nutzt. Die definierte Tabelle erscheint im Gegensatz zu uiTable jedoch im Status des DOIF-Devices. uiState und uiTable können gleichzeitig in einem DOIF-Device definiert werden. <br />
<br />
== Aufbau des uiTable-Attributs ==<br />
Im uiTable-Attribut wird in erster Linie die zu visualisierende Tabelle definiert. Optional können zuvor ein Perlblock sowie Templates definiert werden.<br />
{{Randnotiz|RNText='''Aufbau des Attributs'''<br />
* das uiTable-Attribut besteht aus drei Bereichen:<br />
* [[DOIF/uiTable Schnelleinstieg#Der Perlblock|Perlblock]]<br />
* [[DOIF/uiTable Schnelleinstieg#uiTable-Templates|Templates-Definitionen]] <br />
* [[DOIF/uiTable Schnelleinstieg#Die Tabellendefinition|Tabellendefinition]]<br />
}}<br />
'''Aufbaustruktur''' <br />
<syntaxhighlight lang="perl"><br />
{<br />
<Perlblock, optional><br />
}<br />
<br />
<Templates-Definitionen, optional><br />
<br />
<Tabellendefinition><br />
</syntaxhighlight><br />
=== Der Perlblock ===<br />
Der Perlblock dient dazu, das Layout der Tabelle zu beeinflussen sowie eigene uiTable-Funktionen zu definieren. Hier wird insb. das Package definiert, welches für die Tabellendefinition gilt. Ebenfalls können CSS-Variablen sowie Steuerungsattribute gesetzt werden. Der Perlblock beginnt und endet mit einer geschweiften Klammer.<br />
<br />
==== CSS-Variablen und Steuerungsattribute ====<br />
Mit Hilfe von CSS-Variablen kann das Layout der Tabelle beeinflusst werden. Die Steuerungsattribute beeinflussen die Statuszeile sowie die Detailansicht des DOIF-Moduls.<br />
{{Randnotiz|RNText='''CSS-Variablen und Steuerungsattribute'''<br />
*Das Layout der gesamten Tabelle wird beeinflusst über die Variablendefinition: '''$TABLE="<CSS-Attribute der Tabelle>"'''<br />
*Spaltenformatierungen werden beeinflusst mit Hilfe der Variablendefinition: '''$TC{<Zellenbereich für Spalten>}="<CSS-Attribute der Spalten>"''' <br />
*Zeilenformatierungen werden beeinflusst mit Hilfe der Variablendefinition: '''$TR{Zeilenbereich}="<CSS-Attribute der Zeilen>"'''<br />
*einzelne Zellen werden beeinflusst mit Hilfe der Variablen: '''$TD{<Zellenbereich für Zeilen>}{<Zellenbereich für Spalten>}="<CSS-Attribute der Zellen>"'''<br />
*für Zellen-, Spalten- und Zeilen-Bereich gilt: '''<Zahl><nowiki>|</nowiki><kommagetrennte Aufzählung><nowiki>|</nowiki><Bereich von..bis>'''<br />
*Der Status in der Statuszeile des DOIFs wird ausgeblendet mit '''$SHOWNOSTATE=1'''<br />
*Die Gerätezeile des DOIFs wird ausgeblendet mit '''$SHOWNODEVICELINE = "<regex room>"'''<br />
*Die Tabelle des DOIFs wird ausgeblendet mit '''$SHOWNOUITABLE = "<regex room>"'''<br />
*Die Detailansicht wird umorganisiert mit '''$ATTRIBUTESFIRST=1'''<br />
}}<br />
'''Bespieldefinition'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_bsp_layout DOIF ##<br />
attr di_bsp_layout uiTable { ## Beginn des Perlblocks\<br />
## CSS-Variablen\<br />
\<br />
## Die Tabelle soll ein Hintergrundbild der Größe 300x300 Pixel haben\<br />
$TABLE = "width:300px;; height:300px;; background-image:url(/fhem/www/pgm2/images/Grundriss.png);; background-size: 300px 300px;;";;\<br />
\<br />
## die Zelle der ersten Zeile und der ersten Spalte soll rechts eine Rahmenlinie haben\<br />
$TD{0}{0} = "style='border-right-style:solid;; border-right-width:10px'";;\<br />
\<br />
## Die erste Zeile soll aus der Klasse 'odd' sein und fett-Schrift haben\<br />
$TR{0} = "class='odd' style='font-weight:bold'";;\<br />
\<br />
## die Spalten 2 bis 6 sollen zentriert sein\<br />
$TC{1..5} = "align='center'";;\<br />
\<br />
## die Spalten 2, 4 und 5 sollen zentriert sein\<br />
$TC{1,3,5} = "align='center'";;\<br />
\<br />
## die letzte Spalte der Tabelle soll fett sein\<br />
$TC{last} = "style='font-weight:bold'";;\<br />
\<br />
\## Steuerungsattribute\<br />
\<br />
\## Ausblenden des Status in der Statuszeile\<br />
$SHOWNOSTATE=1;;\<br />
\<br />
## Die Gerätezeile wird ausgeblendet in allen Räumen\<br />
$SHOWNODEVICELINE = ".*";;\<br />
\<br />
## Die Tabelle wird im Raum info ausgeblendet\<br />
$SHOWNOUITABLE = "^info$";;\<br />
\<br />
## Die Detailansicht wird umorganisiert, hilfreich beim Editieren längerer uiTable-Definitionen\<br />
$ATTRIBUTESFIRST = 1;;\<br />
} ## Ende des Perlblocks<br />
</syntaxhighlight><br />
<br />
=== Die Tabellendefinition ===<br />
==== Einfache Tabellendefinition ohne Funktionen ====<br />
{{Randnotiz|RNText='''Tabellendefinition'''<br />
* eine Tabelle wird aus Zellen zusammengebaut<br />
* mehrere Zellen werden mit <nowiki>|</nowiki> von einander getrennt, sie bilden eine Tabellenzeile<br />
* eine neue Tabellenzeile beginnt mit einer neuen Zeile in der Tabellendefinition<br />
* eine Tabellenzeile kann auch in mehreren Zeilen definiert werden, diese müssen dann mit <nowiki>|</nowiki> enden<br />
* Texte werden in Anführungszeichen angegeben<br />
* Readings werden in der Form [<device>:<reading>] angegeben<br />
* Kommentare beginnen mit ## und enden mit Zeilenende<br />
* Events eines definierten Readings, führen sofort zu Aktualisierung seines Inhalts in der visualisierten Tabelle<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod ui_Table_definition DOIF ##<br />
attr ui_Table_definition uiTable { ## Perlblock für globale Tabellendefinitionen\<br />
\<br />
$TC{1..2}="align='center'" ## zentrierte Ausrichtung der zweiten und dritten Spalte\<br />
\<br />
}\<br />
\<br />
## Tabellendefinition\<br />
\<br />
"Warmwasser"|"Vorlauf"|"Rücklauf" ## erste Tabellenzeile\<br />
## zweite Tabellenzeile\<br />
[T_Warmwasserspeicher:temperature]| ## Zeile wird fortgesetzt, da sie mit | endet\<br />
[T_Vorlauf:temperature]| ## Zeile wird fortgesetzt, da sie mit | endet\<br />
[T_Ruecklauf:temperature]<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable Definition.png|mini|ohne]]<br />
<br />
==== Tabellendefinition mit Berechnungen ====<br />
{{Randnotiz|RNText='''Zellenauswertung'''<br />
* jede Zelle der Tabelle wird über Perl ausgewertet<br />
* Readingangaben der Form [<device>:<reading>] werden in eine Perlfunktion übersetzt<br />
* das Ergebnis des ausgewerteten Perlausdrucks wird ausgegeben<br />
* in einer Zelle können beliebige Perlfunktionen genutzt werden<br />
* Texte oder Funktionen können mit Punkt aneinander gehängt werden<br />
* mit Komma werden Texte oder Werte untereinander dargestellt<br />
* wird eine Zeile mit < abgeschlossen, so wird die aktuelle Tabelle abgeschlossen, die nächste Zeile beginnt in einer neuen Tabelle<br />
* in einer Berechnung sollte ein Trigger in Form einer Readingangabe [<device>:<reading>] vorkommen, sonst wäre das Ergebnis statisch und würde sich nicht ändern <br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_calc DOIF ##<br />
attr di_uiTable_calc uiTable ## Tabellendefinition\<br />
"Differenz"|[T_Ruecklauf:temperature]-[T_Vorlauf:temperature]\<br />
"Minimum"|minNum([TH_WZ_HM:measured-temp],[TH_Keller_HM:measured-temp])\<br />
"Durchschnitt"|([T_Ruecklauf:temperature]+[T_Vorlauf:temperature])/2<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable calc.png|mini|ohne]]<br />
<br />
== Vordefinierte uiTable-Funktionen ==<br />
Typische Widgets bzw. Styles wurden als Perl-Funktionen im package ui_Table für eine einfache Tabellendefinition programmiert. Im folgenden wird näher auf die einzelnen uiTable-Funktionen eingegangen.<br />
<br />
=== FHEM-Widgets mit der Funktion '''widget''' ===<br />
Alle in FHEM vorhanden Widgets können mit Hilfe der Perlfunktion '''widget''' genutzt werden. Bei häufiger Nutzung eines bestimmten Widgets bietet sich alternativ die Definition einer uiTable-Funktion (Typ 3) mit dem jeweiligen Widget an, siehe: [[DOIF/uiTable Schnelleinstieg#Eigene uiTable-Funktionen programmieren|uiTable-Funktion]]<br />
{{Randnotiz|RNText=Funktion '''widget'''<br />
<syntaxhighlight lang="perl"><br />
widget(<Reading>,$fhem_widget,$set)<br />
<br />
Reading # [<device>:<reading>]<br />
$fhem_widget # Angabe des FHEM-Widgets<br />
$set # optional, undef zum Setzen beliebiger Readings (entspricht setreading), "set" wenn das Reading per set-Befehl gesetzt wird (siehe Attribut ReadingList), "set <Befehl>", wenn sich der Befehl vom Reading unterscheidet, default undef<br />
</syntaxhighlight><br />
<br />
'''nützliche Links'''<br />
* [[FHEMWEB/Widgets|Fhem-Widgets]]<br />
* Fhem-Widgets als [[DOIF/uiTable Schnelleinstieg#Eigene uiTable-Funktionen programmieren|uiTable-Funktion]]<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_widget DOIF ##<br />
attr di_uiTable_widget uiTable ## FHEM-Widgets mit Hilfe der WID-Funktion\<br />
{package ui_Table}\<br />
"Widget"\<br />
"Select"| widget([uhr:wochentag],"select,Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag,Sonntag")\<br />
"Selectnumbers"| widget([motor:spannung],"selectnumbers,0,0.5,12,1,lin")\<br />
"Slider"| widget([bla:wert],"slider,0,5,100,1")\<br />
"Colorpicker RGB"| widget([Lampe:farbe],"colorpicker,RGB")\<br />
"Colorpicker HSV"| widget([Lampe:farbe],"colorpicker,HSV")\<br />
"Colorpicker CT"| widget([Lampe:waerme],"colorpicker,CT,2000,10,6500")\<br />
"Colorpicker HUE"| widget([Lampe:farbe],"colorpicker,HUE,0,1,359")\<br />
"Colorpicker BRI"| widget([Lampe:helligkeit],"colorpicker,BRI,0,1,100")\<br />
"Time"| widget([start:zeit],"time")\<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable WID.png|mini|ohne]]<br />
<br />
=== SVG-uiTable-Funktionen ===<br />
SVG-uiTable-Funktionen sind skalierbare Widgets, die auf SVG-Elementen basieren. Bei allen SVG-Funktionen für Temperatur bzw. Feuchtigkeit wird die Einfärbung abhängig vom Temperatur- bzw. Feuchtigkeitswert mit Hilfe einer Zuordnungsfunktion bestimmt.<br />
<br />
==== '''ring'''-Funktionen ====<br />
===== Farbskalierte Temperaturanzeige mit Hilfe der SVG-Funktionen '''temp_ring/temp_mring''' =====<br />
Die Farbe der dargestellten Temperatur ist abhängig vom Temperaturwert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''temp_mring'''-SVG-Funktion wird der Ring einfarbig dargestellt.<br />
<br />
Farbskalierung der '''temp_ring'''-SVG-Funktion:<br />
[[Datei:Farbskalierung temp_ring_scaling.png|600px|ohne]]<br />
<br />
Farbskalierung der '''temp_mring'''-SVG-Funktion:<br />
[[Datei:Farbskalierung temp_mring_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''temp_ring/temp_mring'''<br />
<syntaxhighlight lang="perl"><br />
temp_ring/temp_mring ($temp_value,$temp_min,$temp_max,$sizeHalf, $lightring,$lightnumber,$decFont) <br />
<br />
$temp_value # Temperatur<br />
$temp_min, # minimale Temperatur, optional, default=-20<br />
$temp_max, # maximale Temperatur, optional, default=60<br />
$sizeHalf # "<size>,<half ring>" size: Größe der Grafik, optional, default = 80, half ring: 1 für Halbring<br />
$lightring, # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_temp_ring DOIF ##<br />
attr di_temp_ring uiTable {package ui_Table}\<br />
"außen (standard)"|temp_ring([Aussensensor:temperature])\<br />
"Warmwasser (größer,aufgehellt,Normalschrift)" |temp_mring([vaillant:WWSpeicher],15,70,110,90,100,"1,font-weight:normal")\<br />
"Vorlauf (größer)"| temp_mring([ESPEasy_ESP_Temp_Vorlauf:Temperature],15,45,100)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:temp_ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Feuchtigkeitsanzeige mit Hilfe der SVG-Funktionen '''hum_ring/hum_mring''' =====<br />
Die Farbe der dargestellten Feuchtigkeit ist abhängig vom Feuchtigkeitswert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''hum_mring'''-SVG-Funktion wird der Ring einfarbig dargestellt.<br />
<br />
Farbskalierung der '''hum_ring'''-SVG-Funktion: <br />
[[Datei:Farbskalierung hum_ring_scaling.png|600px|ohne]]<br />
<br />
Farbskalierung der '''hum_mring'''-SVG-Funktion:<br />
[[Datei:Farbskalierung hum_mring_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''hum_ring/hum_mring'''<br />
<syntaxhighlight lang="perl"><br />
hum_ring/hum_mring ($hum_value,$sizeHalf,$lightring,$lightnumber,$decFont) <br />
$hum_value # Feuchtigkeit<br />
$sizeHalf # "<size>,<half ring>" size: Größe der Grafik, optional, default = 80, half ring: 1 für Halbring<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_hum_ring DOIF ##<br />
attr di_hum_ring room test2<br />
attr di_hum_ring uiTable {package ui_Table}\<br />
"klein ohne Farbverlauf"|hum_mring([Aussensensor:humidity],60)\<br />
"normal groß mit Farbverlauf"|hum_ring([Aussensensor:humidity])\<br />
"groß ohne Farbverlauf aufgehellt"|hum_mring([Aussensensor:humidity],100,80)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:hum_ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige eines Zahlenwertes mit Hilfe der universellen SVG-Funktion '''ring''' =====<br />
Die Farbe des dargestellten Wertes kann abhängig vom Wert bestimmt werden. Dabei wird die Farbe mit Anleihen aus dem [https://de.wikipedia.org/wiki/HSV-Farbraum HSV-Farbraum] bestimmt. Dieser Farbraum benötigt eigentlich drei Werte, wobei die erste den Farbton (hue) bestimmt; hier wird nur dieser Wert verwendet (Sättigung und Hellwert sind nicht einstellbar). Der Farbton geht von rot (hue-Wert = 0) über gelb (hue-Wert = 60), dann grün (hue-Wert = 120) und blau (hue-Wert = 240) zurück zu rot (hue-Wert = 360), siehe dazu auch die [https://de.wikipedia.org/wiki/HSV-Farbraum#/media/Datei:HueScale.svg Farbtontafel] auf der Wikipedia-Seite.<br />
Die unten $colorRef genannte Funktion kann zum Beispiel in der Tabelle selbst definiert werden, beispielsweise kann man in dem device &onoff_hue verwenden, wenn man es vorab definiert (siehe [https://forum.fhem.de/index.php/topic,120088.msg1204341.html#msg1204341 Link zum Forum]):<blockquote><syntaxhighlight lang="perl"><br />
attr <ui device Name> {<br />
package ui_Table;<br />
sub onoff_hue {<br />
my($irgendeinVariablenname)=@_;<br />
return ($irgendeinVariablenname == 0 ? 240 : 0); <br />
}<br />
## Tabellendefinition<br />
...<br />
}<br />
</syntaxhighlight></blockquote>{{Randnotiz|RNText=SVG-uiTable-Funktion '''ring'''<br />
<syntaxhighlight lang="perl"><br />
ring ($value,$min,$max,$minColor,$maxColor,$unit, $sizeHalf,$colorRef,$decFont,$model,$lightness)<br />
<br />
$value # darzustellender Wert<br />
$min # minimaler Wert, optional, default=0<br />
$max # maximaler Wert, optional, default=100<br />
$minColor # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$sizeHalf # "<size>,<half ring>" size: Größe der Grafik, optional, default = 100, half ring: 1 für Halbring<br />
$colorRef # Referenz auf eine Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, oder eine Referenz auf eine Arrayliste mit Grenzwerten und Farben, optional, default = undef<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$model # '<Farbverlauf>,<Min/Max>,<Innenring>,<Zeigerstärke>,<Modus>',<br />
# Farbverlauf: 1 für monochrom, <br />
# Min/Max: Style-SVG-Attribute oder 1 zum Anzeigen der Min-/Maxwerte,<br />
# Innenring: Style-SVG-Attribute oder 1 zum Anzeigen des Innenringes, Zeigerstärke: in Pixel,<br />
# Zeigerstärke: Breite des Zeigers,<br />
# Modus: 0 Standard Min-Max, 1 Min-Null-Max, 2 Null-Min/Max,<br />
# alle Parameter sind optional, default keine Angaben: ',,,,,'<br />
$lightness # Helligkeit einzelner Elemente (0-100) "<ring>,<inner ring>,<minMax>,<unit>,<value>", optional, default: "50,50,50,40,50"<br />
</syntaxhighlight><br />
Wird '''$colorFunc''' nicht angegeben, so wird der Farbwert zwischen '''$minColor''' und '''$maxColor''' linear interpoliert<br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_ring DOIF (1)<br />
attr di_ring room test20,test5<br />
attr di_ring uiTable {package ui_Table;; \<br />
$SHOWNOSTATE=1}\<br />
## von 0 bis 20 in Farben von grün (hue:120) bis rot (hue:0)\<br />
"Umlaufmenge"|ring([heating:pump],0,20,120,0,"l/min",100)\<br />
\<br />
## von 0 bis 3 in Farben von rot (hue:0) bis türkis (hue:180), eine Nachkommastelle, Schriftgröße 170%\<br />
## Innenring mit Min-, Max-Beschriftung\<br />
"Wasserdruck"|ring([heating:pressure],0,3,0,180,"bar",100,undef,"1,font-size:170%,fill:silver;;font-size:50%","0,1,1")\<br />
\<br />
## Temperaturdarstellung, entspricht dem Funktionsaufruf:\<br />
## temp_ring ([outdoor:temperature],-20,60,100,"1,font-weight:normal;;font-size:140%")\<br />
## Eine Nachkommastelle, Normalschrift, Schriftgröße 140%\<br />
"Temperatur"|ring([outdoor:temperature,-20,60,undef,undef,"°C",100,\&temp_hue,"1,font-weight:normal;;font-size:140%")\<br />
\<br />
## Lufdruck als Halbring\<br />
"Luftdruck"|ring([weather:barometer],970,1045,30,90,"hPa","100,1",undef,0)\<br />
\<br />
## Co2 als Halbring, Farbgebung als Array mit drei Bereichen, Innenring mit Zeiger\<br />
"Co2"|ring([livingroom:co2],400,1200,undef,undef,'ppm',"100,1",[(600,120,1000,60,1200,0)],0,'0,0,1,5')<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Temperatur- und Feuchtigkeitsanzeige mit Hilfe der SVG-Funktion '''temp_hum_ring''' =====<br />
Die Farbe ist jeweils abhängig vom dargestellten Temperatur- bzw. Feuchtigkeitswert. Die Helligkeit der Farbgebung ist einstellbar:<br />
[[Datei:Farbskalierung temp_hum_ring_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''temp_hum_ring'''<br />
<syntaxhighlight lang="perl"><br />
temp_hum_ring ($temp_value,$hum_value,$temp_min,$temp_max,$size, $lightring,$lightnumber,$decFontTemp,$decFontHum)<br />
<br />
$temp_value # Temperatur<br />
$hum_value # Feuchtigkeit<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$size # Größe der Grafik, optional, default=90<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFontTemp # Temperatur: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$decFontHum # Feuchtigkeit: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_temp_hum_ring DOIF ##<br />
attr di_temp_hum_ring uiTable {package ui_Table}\<br />
\<br />
"klein"|temp_hum_ring([Aussensensor:temperature],[Aussensensor:humidity],undef,undef,60)\<br />
"normal"|temp_hum_ring([Aussensensor:temperature],[Aussensensor:humidity])\<br />
"größer, aufgehellt"|temp_hum_ring([Aussensensor:temperature],[Aussensensor:humidity],undef,undef,100,undef,80)\<br />
"größer, Ring aufgehellt, Normalschrift"|temp_hum_ring([Aussensensor:temperature],[Aussensensor:humidity],undef,undef,100,80,50,"1,font-weight:normal","0,font-weight:normal")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:temp_hum_ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige von zwei Temperaturwerten mit Hilfe der SVG-Funktion '''temp_temp_ring''' =====<br />
Die Farbe ist jeweils abhängig vom dargestellten Temperaturwert. Die Helligkeit der Farbgebung ist einstellbar:<br />
[[Datei:Farbskalierung temp_temp_ring_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''temp_temp_ring'''<br />
<syntaxhighlight lang="perl"><br />
temp_temp_ring ($temp1_value,$temp2_value,$temp_min,$temp_max,$size, $lightring,$lightnumber,$decFontTemp1,$decFontTemp2)<br />
<br />
$temp1_value # erster Temperaturwert<br />
$temp2_value # zweiter Temperaturwert<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$size # Größe der Grafik, optional, default=90<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFontTemp1 # Temperatur1: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$decFontTemp2 # Temperatur2: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_temp_temp_ring DOIF ##<br />
attr di_temp_temp_ring uiTable {package ui_Table}\<br />
"klein, Ring augehellt"|temp_temp_ring([Vorlauf:Temperature],[Ruecklauf:Temperature],15,60,60,80,50)\<br />
"normal"|temp_temp_ring([Vorlauf:Temperature],[Ruecklauf:Temperature],15,60)\<br />
"groß, Zahlen aufgehellt"|temp_temp_ring([Vorlauf:Temperature],[Ruecklauf:Temperature],15,60,100,undef,80)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:temp_hum_temp_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige von zwei Zahlenwerten mit Hilfe der universellen SVG-Funktion '''ring2''' =====<br />
Die Farbe der dargestellten Werte kann abhängig vom Wert bestimmt werden.<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''ring2'''<br />
<syntaxhighlight lang="perl"><br />
ring2 ($value1,$min1,$max1,$minColor1,$maxColor1,$unit1,$size,$colorFunc1,$decFont1,<br />
$value2,$min2,$max2,$minColor2,$maxColor2,$unit2,$colorFunc2,$decFont2,<br />
$lightness,$icon,$model)<br />
<br />
$value1 # darzustellender Wert1<br />
$min1 # minimaler Wert, optional, default=0<br />
$max1 # maximaler Wert, optional, default=100<br />
$minColor1 # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor1 # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit1 # Einheit des Wertes, optional, default = undef<br />
$size # Größe der Grafik, optional, default = 100<br />
$colorFunc1 # Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, optional, default = undef<br />
$decFont1 # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$value2 # darzustellender Wert2<br />
...<br />
$decFont2 # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$lightness # Helligkeit einzelner Elemente (0-100) "<ring>,<inner ring>,<minMax>,<unit>,<value>,<icon>", optional, default: "50,50,50,40,50,40"<br />
$model # '<color gradient>,<min/max>,<inner ring>,<pointer>,<mode>',<br />
# <color gradient>: 1 für monochrom<br />
# <min/max>: Style-SVG-Attribute oder 1 zum Anzeigen der Min-/Maxwerte<br />
# <inner ring>: Style-SVG-Attribute oder 1 zum Anzeigen des Innenringes<br />
# <pointer>: Breite des Zeigers in Pixel<br />
# <mode>: 0 Standard Min. - Max., 1 negativ - Null - positiv, 2 Null - negativ/positiv<br />
# alle Parameter sind optional, default keine Angaben: ',,,,,,'<br />
<br />
Argumente für den zweiten Wert entsprechend den Argumenten des ersten Wertes<br />
</syntaxhighlight><br />
Wird '''$colorFunc...''' nicht angegeben, so wird der Farbwert zwischen '''$minColor...''' und '''$maxColor...''' linear interpoliert<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_ring2 DOIF ##<br />
attr di_ring2 uiTable {package ui_Table;;}\<br />
## Leistungsaufnahme von 0 kW bis 3,6 kW in Farben von grün (hue:120) bis rot (hue:0)\<br />
## Kapazität von 0 % bis 100 % V in Farben von rot (hue:0) bis grün (hue:120)\<br />
"Wallbox"| ring2([tesla:Leistung],0,3.6,120,0,"kW",undef,undef,"1,font-weight:normal",[tesla:Kapazitaet],0,100,0,120,"%",undef,"0,font-weight:normal")\<br />
\<br />
## Stromstärke von 0 A bis 2 A in Farben von grün (hue:120) bis rot (hue:0)\<br />
## Spannung von 1 V bis 1.5 V in Farben von rot (hue:0) bis grün (hue:120)\<br />
## 3 Nachkommastellen, Normalschrift, Schriftgröße 80% \<br />
"Akku"| ring2([akku:Strom],0,2,120,0,"A",undef,undef,"3,font-weight:normal;;font-size:80%",[akku:Spannung],1,1.5,0,120,"V",undef,"3,font-weight:normal;;font-size:80%")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:ring2_bsp.png|ohne|mini]]<br />
<br />
'''<big>Beispieldefinition Innenring, Farb-Array, Ringmodi</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_solar DOIF {}<br />
attr di_solar uiTable {package ui_Table}\<br />
"Farb-Array, ringMode 1"|\<br />
ring2([zaehler:Produktion],-20,30,undef,undef,"PV kWh",130,[(-10,0,-0.001,30,10,60,30,90)],"2",[test:Bezug],-20,30,undef,undef,"Bezug",[(-10,0,-0.001,30,10,60,30,90)],"2",undef,undef,"0,1,1,0,1")\<br />
"Farbe linear, ringMode 1"|\<br />
ring2([zeahler:Produktion],-20,30,0,120,"PV kWh",130,undef,"2",[test:Bezug],-20,30,0,120,"Bezug",undef,"2",undef,undef,"0,1,1,0,1")\<br />
"Farbe linear, ringMode 2"|\<br />
ring2([zaehler:Produktion],0,30,60,120,"PV kWh",130,undef,"2",[test:Bezug],-20,0,0,120,"Bezug",undef,"2",undef,undef,"0,,,0,2")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:ring2_ringMode.png|ohne|mini]]<br />
<br />
<br clear="all"><br />
<br />
==== '''icon_ring'''-Funktionen ====<br />
===== Farbskalierte Temperaturanzeige mit einem Icon mit Hilfe der SVG-Funktionen '''icon_temp_ring/icon_temp_mring''' =====<br />
Diese Funktionen basieren auf den obigen temp_ring-Funktionen, zusätzlich wird ein SVG-Icon dargestellt. Die Farbe des Icons kann mit @ an den Iconnamen angehängt werden, ansonsten wird die Farbe der Temperatur für das Icon verwendet. Die Größe des Icons kann skaliert werden, ebenso kann die Positionen des Icons verschoben werden.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_temp_ring/icon_temp_mring'''<br />
<syntaxhighlight lang="perl"><br />
icon_temp_ring/icon_temp_mring ($icon,$temp_value,$temp_min,$temp_max,$size,$lightring,$lightnumber,$decFont) <br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation (0-360) sind optional<br />
$temp_value # Temperatur<br />
$temp_min, # minimale Temperatur, optional, default=-20<br />
$temp_max, # maximale Temperatur, optional, default=60<br />
$size, # Größe der Grafik, optional, default=80<br />
$lightring, # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_Heizung_temp DOIF ##<br />
attr di_Heizung_temp uiTable {\<br />
package ui_Table;;\<br />
}\<br />
\<br />
icon_temp_ring("temp_outside",[vaillant:Aussentemp],-15,40)|\<br />
icon_temp_mring(([vaillant:Flame] eq "off"?"sani_boiler_temp\@white":"sani_boiler_temp\@Darkorange"),[vaillant:Vorlauf],15,70)|\<br />
icon_temp_mring(([vaillant:Pumpenstatus] eq "4" ? "sani_buffer_temp_down\@Darkorange" : "sani_buffer_temp_down\@white"),[vaillant:WWSpeicher],15,70)|\<br />
icon_temp_mring(([Zirk] eq "off"?"sani_pump\@white":"sani_pump\@Darkorange"),[ESPEasy_ESP_Temp_Zirkulation:Temperature],15,70)|\<br />
icon_temp_mring(([vaillant:Pumpenstatus] eq "on" ? "sani_floor_heating\@Darkorange" : "sani_floor_heating_neutral\@white"),[ESPEasy_ESP_Temp_Vorlauf:Temperature],15,70)|\<br />
icon_temp_mring("sani_floor_heating_neutral\@white",[ESPEasy_ESP_Temp_Keller_Ruecklauf:Temperature],15,70)|""<br />
<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_temp_ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Feuchtigkeitsanzeige mit einem Icon mit Hilfe der SVG-Funktionen '''icon_hum_ring/icon_hum_mring''' =====<br />
Diese Funktionen basieren auf den obigen hum_ring-Funktionen, zusätzlich wird ein SVG-Icon dargestellt. Die Farbe des Icons kann mit @ an den Iconnamen angehängt werden, ansonsten wird die Farbe der Feuchtigkeit für das Icon verwendet. Die Größe des Icons kann skaliert werden, ebenso kann die Positionen des Icons verschoben werden. <br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_hum_ring/icon_hum_mring'''<br />
<syntaxhighlight lang="perl"><br />
icon_hum_ring/icon_hum_mring ($icon,$hum_value,$size,$lightring,$lightnumber,$decFont) <br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$hum_value # Feuchtigkeit<br />
$size # Größe der Grafik, optional, default=80<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_hum_ring DOIF ##<br />
attr di_icon_hum_ring room test5<br />
attr di_icon_hum_ring uiTable {package ui_Table}\<br />
"klein ohne Farbverlauf"|icon_hum_mring("weather_humidity",[Aussensensor:humidity],60)\<br />
"normal groß mit Farbverlauf"|icon_hum_ring("weather_humidity",[Aussensensor:humidity])\<br />
"groß ohne Farbverlauf aufgehellt"|icon_hum_mring("weather_humidity",[Aussensensor:humidity],100,80)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_hum_ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige eines Icons mit einem Zahlenwert mit Hilfe der universellen SVG-Funktion '''icon_ring/icon_mring/icon_uring''' =====<br />
Diese Funktionen basieren auf der universellen ring-Funktion. Die Farbe des dargestellten Icons und des Wertes kann abhängig vom Wert bestimmt werden. Die Funktion '''icon_ring''' stellt den Farbring mit Farbverlauf dar, die Funktion '''icon_mring''' stellt den Farbring einfarbig dar. Die universelle Funktion '''icon_uring''' kann über den Parameter '''$model''' das Erscheinungsbild der Grafik verändern.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_ring/icon_mring/icon_uring'''<br />
<syntaxhighlight lang="perl"><br />
icon_ring ($icon,$value,$min,$max,$minColor,$maxColor, $unit,$decFont,$size,$colorRef,$lightness,$model)<br />
<br />
icon_mring ($icon,$value,$min,$max,$minColor,$maxColor, $unit,$decFont,$size,$colorRef,$lightness)<br />
<br />
icon_uring ($model,$icon,$value,$min,$max,$minColor,$maxColor, $unit,$decFont,$size,$colorRef,$lightness)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$value # darzustellender Wert<br />
$min # minimaler Wert, optional, default=0<br />
$max # maximaler Wert, optional, default=100<br />
$minColor # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$decFont # "<Anzahl der Nachkommastellen>,<Style-SVG-Attribute Wert>,<Style-SVG-Attribute Einheit>", optional<br />
$size # Größe der Grafik, optional, default = 100<br />
$colorRef # Referenz auf eine Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, oder eine Referenz auf eine Arrayliste mit Grenzwerten und Farben, optional, default = undef<br />
$lightness # Helligkeit einzelner Elemente (0-100) "<ring>,<inner ring>,<minMax>,<unit>,<value>,<icon>", optional, default: "50,50,50,40,50,40"<br />
$model # '<color gradient>,<min/max>,<inner ring>,<pointer>,<mode>',<br />
# <color gradient>: 1 für monochrom<br />
# <min/max>: Style-SVG-Attribute oder 1 zum Anzeigen der Min-/Maxwerte<br />
# <inner ring>: Style-SVG-Attribute oder 1 zum Anzeigen des Innenringes<br />
# <pointer>: Breite des Zeigers in Pixel<br />
# <mode>: 0 Standard Min. - Max., 1 negativ - Null - positiv, 2 Null - negativ/positiv<br />
# alle Parameter sind optional, default keine Angaben: ',,,,,,'<br />
</syntaxhighlight><br />
Wird '''$colorRef''' nicht angegeben, so wird der Farbwert zwischen '''$minColor''' und '''$maxColor''' linear interpoliert<br />
}}<br />
<br />
<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_ring DOIF ##<br />
attr di_icon_ring uiTable {package ui_Table}\<br />
\<br />
icon_ring ('sani_floor_heating_neutral',[Heizenergie:Vortag_hc],0,150,120,0,'kWh')|\<br />
icon_mring ('fuel',[Tankstelle:Diesel],1.10,1.30,120,0,'€',2)|\<br />
icon_uring ('0,1,1',"air",[ESPEasy_Eingang_CO2:PPM],400,1200,undef,undef,'ppm',0,100,[(600,120,1000,60,1200,0)])|\<br />
icon_uring ('0,1','Zisterne',([Wasserzisterne]/3.4),0,100,0,120,'%',0)##/\<br />
\<br />
icon_uring ('1,1,0,8',"measure_water_meter",[Wasserverbrauch:heute],0,600,120,0,'l',0)|\<br />
icon_uring ('0,fill:white,opacity:0.4',([vaillant:Pumpenstatus] eq '4' ? 'sani_buffer_temp_down@Darkorange' : 'sani_buffer_temp_down@white'),[vaillant:Umlaufmenge],0,20,120,0,'l/min')|\<br />
icon_uring('0,1,1,4','weather_barometric_pressure',[vaillant:Wasserdruck],0,3,undef,undef,'bar',1,100,[(0.8,0,1,60,1.5,120,1.7,60,3,0)])|\<br />
icon_uring('0,opacity:0.8,1,6','sani_water_tap',[vaillant:HwcHours_hoursum2_value],0,2000,120,0,'h',0)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_ring_bsp.png|ohne|mini]]<br />
<br clear="all"><br />
<br />
===== Farbskalierte Temperatur- und Feuchtigkeitsanzeige mit einem Icon mit Hilfe der SVG-Funktion '''icon_temp_hum_ring''' =====<br />
Die Farbe ist jeweils abhängig vom dargestellten Temperatur- bzw. Feuchtigkeitswert. Die Helligkeit der Farbgebung ist einstellbar:<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_temp_hum_ring'''<br />
<syntaxhighlight lang="perl"><br />
icon_temp_hum_ring ($icon,$temp_value,$hum_value,$temp_min,$temp_max,$size, $lightring,$lightnumber,$decFontTemp,$decFontHum)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$temp_value # Temperatur<br />
$hum_value # Feuchtigkeit<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$size # Größe der Grafik, optional, default=90<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFontTemp # Temperatur: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$decFontHum # Feuchtigkeit: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_temp_hum_ring DOIF ##<br />
attr di_icon_temp_hum_ring uiTable {package ui_Table}\<br />
\<br />
"normal"|icon_temp_hum_ring("temp_outside",[Aussensensor:temperature],[Aussensensor:humidity])\<br />
"mit Normalschrift"|icon_temp_hum_ring("temp_outside",[Aussensensor:temperature],[Aussensensor:humidity], undef,undef,undef,undef,undef,"1,font-weight:normal","0,font-weight:normal")\<br />
"größer aufgehellt"|icon_temp_hum_ring("temp_outside",[Aussensensor:temperature],[Aussensensor:humidity], undef,undef,120,undef,80)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_temp_hum_ring.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige von zwei Temperaturwerten mit einem Icon mit Hilfe der SVG-Funktion '''icon_temp_temp_ring''' =====<br />
Die Farbe ist jeweils abhängig vom dargestellten Temperaturwert. Die Helligkeit der Farbgebung ist einstellbar:<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_temp_temp_ring'''<br />
<syntaxhighlight lang="perl"><br />
icon_temp_temp_ring ($icon,$temp1_value,$temp2_value,$temp_min,$temp_max,$size, $lightring,$lightnumber,$decFontTemp1,$decFontTemp2)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$temp1_value # erster Temperaturwert<br />
$temp2_value # zweiter Temperaturwert<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$size # Größe der Grafik, optional, default=90<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFontTemp1 # Temperatur1: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$decFontTemp2 # Temperatur2: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_temp_temp_ring DOIF ##<br />
attr di_icon_temp_temp_ring uiTable {package ui_Table}\<br />
## Größe 120%\<br />
"FB-Heizung"|icon_temp_temp_ring(([vaillant:Pumpenstatus] eq "on" ? "sani_floor_heating\@Darkorange" : "sani_floor_heating_neutral\@white"),[ESPEasy_ESP_Temp_Vorlauf:Temperature],[ESPEasy_ESP_Temp_Keller_Ruecklauf:Temperature],15,70,120)\<br />
\<br />
## Größe 120%, Normalschrift\<br />
"Temperatur","Taupunkt"|icon_temp_temp_ring("temp_outside",[Aussensensor:temperature],[Aussensensor:dewpoint],undef,undef,120,undef,undef,"1,font-weight:normal","1,font-weight:normal")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_temp_temp_ring.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige von zwei Zahlenwerten mit einem Icon mit Hilfe der universellen SVG-Funktion '''icon_ring2''' =====<br />
Die Farbe der dargestellten Werte kann abhängig vom Wert bestimmt werden.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_ring2'''<br />
<syntaxhighlight lang="perl"><br />
icon_ring2 ($icon,$value1,$min1,$max1,$minColor1,$maxColor1,$unit1,$size,$colorFunc1,$decFont1, $value2,$min2,$max2,$minColor2,$maxColor2,$unit2,$colorFunc2,$decFont2,$lightnesss,$model)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$value1 # darzustellender Wert1<br />
$min1 # minimaler Wert, optional, default=0<br />
$max1 # maximaler Wert, optional, default=100<br />
$minColor1 # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor1 # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit1 # Einheit des Wertes, optional, default = undef<br />
$size # Größe der Grafik, optional, default = 100<br />
$colorFunc1 # Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, optional, default = undef<br />
$decFont1 # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$value2 ## darzustellender Wert2<br />
...<br />
$unit2 # Einheit des Wertes, optional, default = undef<br />
$colorFunc2 # Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, optional, default = undef<br />
$decFont2 # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$lightness # Helligkeit einzelner Elemente (0-100) "<ring>,<inner ring>,<minMax>,<unit>,<value>,<icon>", optional, default: "50,50,50,40,50,40"<br />
$model # '<color gradient>,<min/max>,<inner ring>,<pointer>,<mode>',<br />
# <color gradient>: 1 für monochrom<br />
# <min/max>: Style-SVG-Attribute oder 1 zum Anzeigen der Min-/Maxwerte<br />
# <inner ring>: Style-SVG-Attribute oder 1 zum Anzeigen des Innenringes<br />
# <pointer>: Breite des Zeigers in Pixel<br />
# <mode>: 0 Standard Min. - Max., 1 negativ - Null - positiv, 2 Null - negativ/positiv<br />
# alle Parameter sind optional, default keine Angaben: ',,,,,,'<br />
<br />
Argumente für den zweiten Wert entsprechend den Argumenten des ersten Wertes<br />
</syntaxhighlight><br />
Wird '''$colorFunc...''' nicht angegeben, so wird der Farbwert zwischen '''$minColor...''' und '''$maxColor...''' linear interpoliert.<br />
<br />
Bei der Farbangabe des Icons beim Übergabeparameter $icon wird mit '''\@colorVal2''' das Icon mit der Farbe des zweiten Wertes eingefärbt. Bei keiner Farbangabe oder '''\@colorVal1''' wird das Icon mit der Farbe des ersten Wertes eingefärbt. Ansonsten gilt die allgemeine FHEM-Syntax für Farbgebung von Icons angehängt mit '''\@'''.<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_ring2 DOIF ##<br />
attr di_icon_ring2 uiTable {package ui_Table;;\<br />
\<br />
sub himmelsrichtung {\<br />
my ($richtung)=@_;;\<br />
my $element=int($richtung/22.5);;\##/<br />
my @h=(qw"N NNO NO ONO O OSO SO SSO S SSW SW WSW W WNW NW NNW");;\<br />
return($h[$element]);;\<br />
}\<br />
}\<br />
"Wallbox"| icon_ring2("car,1.5,0,-3",[tesla:Leistung],0,3.6,120,0,"kW",120,undef,"1,font-weight:normal",[tesla:Kapazitaet],0,100,0,120,"%",undef,"0,font-weight:normal")\<br />
\<br />
"Wind"|icon_ring2(([Wind:Geschwindigkeit]>0 ? "wind":"no_wind").",1,0,0,".[Wind:Richtung],[Wind:Geschwindigkeit],0,50,120,0,"km/h",120,undef,1,[Wind:Richtung],361,361,220,220,([Wind:Geschwindigkeit]>0?himmelsrichtung([Wind:Richtung]):"--"),undef,0)\<br />
\<br />
"Strom"|icon_ring2([zaehler:l-Produktion] > 0 ? "sani_solar\@colorVal1":"fa_bolt\@colorVal2",[zaehler:l-Produktion],0,3.6,20,120,"PV kW",150,undef,"1,,font-size:50%;fill:white",[zaehler:l-Bezug,0],0,2,120,0,"Netz kW",undef,"1,,font-size:50%;fill:white")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_ring2.png|ohne|mini]]<br />
<br />
==== '''bar'''-Funktionen ====<br />
===== Farbskalierte Anzeige der Temperatur in Balkenform mit Hilfe der SVG-Funktionen '''temp_bar/temp_mbar''' =====<br />
Die Farbe der dargestellten Temperatur ist abhängig vom Temperaturwert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''temp_mbar'''-SVG-Funktion wird der Balken einfarbig dargestellt.<br />
<br />
Farbskalierung der '''temp_bar'''-SVG-Funktion:<br />
[[Datei:Farbskalierung temp_bar_scaling.png|600px|ohne]]<br />
<br />
Farbskalierung der '''temp_mbar'''-SVG-Funktion:<br />
[[Datei:Farbskalierung temp_mbar_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''temp_bar/temp_mbar'''<br />
<syntaxhighlight lang="perl"><br />
temp_bar/temp_mbar ($temp_value,$temp_min,$temp_max, $header,$width,$height,$size, $light,$lightnumber,$decFont)<br />
<br />
$temp_value # Temperaturwert<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$header # Überschrift, optional, default= undef (keine)<br />
$width # Breite der Grafik, optional, default=63<br />
$height # Höhe der Grafik, optional, default=60<br />
$size # Größe der Grafik, optional, default=100<br />
$light # Helligkeit der Grafik (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 1<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_temp_bar DOIF ##<br />
attr di_temp_bar uiTable {package ui_Table}\<br />
"standard"|temp_bar([Aussensensor:temperature])\<br />
"heller"|temp_bar([Aussensensor:temperature],undef,undef,undef,undef,undef,undef,80)\<br />
"monochrom"|temp_mbar([Aussensensor:temperature])\<br />
"kleiner"|temp_bar([Aussensensor:temperature],undef,undef,undef,undef,undef,80)\<br />
"mit Überschrift"|temp_bar([Aussensensor:temperature],undef,undef,"Außen")\<br />
"hoch"|temp_bar([Aussensensor:temperature],undef,undef,undef,undef,100)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:temp_bar_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige der Feuchtigkeit in Balkenform mit Hilfe der SVG-Funktionen '''hum_bar/hum_mbar''' =====<br />
Die Farbe der dargestellten Feuchtigkeit ist abhängig vom Feuchtigkeitswert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''hum_mbar'''-SVG-Funktion wird der Balken einfarbig dargestellt.<br />
<br />
Farbskalierung der '''hum_bar'''-SVG-Funktion:<br />
[[Datei:Farbskalierung hum_bar_scaling.png|600px|ohne]]<br />
<br />
Farbskalierung der '''hum_mbar'''-SVG-Funktion:<br />
[[Datei:Farbskalierung hum_mbar_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''hum_bar/hum_mbar'''<br />
<syntaxhighlight lang="perl"><br />
hum_bar/hum_mbar ($hum_value,$header,$width,$height,$size, $light,$lightnumber,$decFont)<br />
<br />
$hum_value # Feuchtigkeitswert<br />
$header # Überschrift, optional, default = undef (keine)<br />
$width # Breite der Grafik, optional, default=63<br />
$height # Höhe der Grafik, optional, default=80<br />
$size # Größe der Grafik, optional, default=100<br />
$light # Helligkeit des der Grafik (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 0<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_hum_bar DOIF ##<br />
attr di_hum_bar uiTable {package ui_Table}\<br />
"standard"|hum_bar([Aussensensor:humidity])\<br />
"heller"|hum_bar([Aussensensor:humidity],undef,undef,undef,undef,80)\<br />
"monochrom"|hum_mbar([Aussensensor:humidity])\<br />
"kleiner"|hum_bar([Aussensensor:humidity],undef,undef,undef,80)\<br />
"mit Überschrift"|hum_bar([Aussensensor:humidity],"Außen")\<br />
"hoch"|hum_bar([Aussensensor:humidity],undef,undef,100)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:hum_bar_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige eines Zahlenwertes mit Hilfe der universellen SVG-Funktion '''bar''' =====<br />
Die Farbe des dargestellten Wertes kann abhängig vom Wert bestimmt werden.<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''bar'''<br />
<syntaxhighlight lang="perl"><br />
bar ($value,$min,$max,$header,$minColor,$maxColor,$unit,$width, $height,$size,$colorFunc,$decFont,$gradient,$light,$lightnumber)<br />
<br />
$value # darzustellender Wert<br />
$min # minimaler Wert, optional, default=0<br />
$max # maximaler Wert, optional, default=100<br />
$header # Überschrift, optional, default = undef (keine)<br />
$minColor # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$width # Breite der Grafik, optional, default = 63<br />
$height # Höhe der Grafik, optional, default = 60<br />
$size # Größe der Grafik, optional, default = 100<br />
$colorFunc # Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, optional, default = undef<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 1<br />
$gradient # Farbverlauf, optional, undef mit Farbverlauf, 1 ohne Farbverlauf, default = undef<br />
$light # Helligkeit der Grafik (light:0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (light:0-100), optional, default=50<br />
</syntaxhighlight><br />
Wird '''$colorFunc''' nicht angegeben, so wird der Farbwert zwischen '''$minColor''' und '''$maxColor''' linear interpoliert<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
{package ui_Table}<br />
defmod di_bar DOIF ##<br />
attr di_bar uiTable {package ui_Table}\<br />
## von 0 bis 20 in Farben von grün (hue:120) bis rot (hue:0)\<br />
"Umlaufmenge"|bar([heizung:Umlaufmenge],0,20,"Umlauf",120,0,"l/min")\<br />
\<br />
## von 0 bis 3 in Farben von rot (hue:0) bis türkis (hue:180)\<br />
"Wasserdruck"|bar([heizung:Wasserdruck],0,3,undef,0,180,"bar"undef,70,undef,undef,"1,font-size:130%;;font-weight:normal")\<br />
\<br />
## Temperaturdarstellung, entspricht dem Funktionsaufruf:\<br />
## temp_bar ([Aussensensor:temperature],-20,60)\<br />
"Temperatur"|bar([Aussensensor:temperature],-20,60,undef,undef,undef,"°C",undef,undef,undef,\&temp_hue)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:bar_bsp.png|ohne|mini]]<br />
<br />
==== '''icon_bar'''-Funktionen ====<br />
===== Farbskalierte Anzeige der Temperatur in Balkenform mit Hilfe der SVG-Funktion '''icon_temp_bar/icon_temp_mbar''' =====<br />
Die Farbe der dargestellten Temperatur ist abhängig vom Temperaturwert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''icon_temp_mbar'''-SVG-Funktion wird der Balken einfarbig dargestellt.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_temp_bar/icon_temp_mbar'''<br />
<syntaxhighlight lang="perl"><br />
icon_temp_bar/icon_temp_mbar ($icon,$temp_value,$temp_min,$temp_max, $header,$width,$height,$size,$light,$lightnumber,$decFont)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position", \@Farbe, Skalierungsfaktor, x-Position, y-Position sind optional<br />
$temp_value # Temperaturwert<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$header # Überschrift, optional, default= undef (keine)<br />
$width # Breite der Grafik, optional, default=63<br />
$height # Höhe der Grafik, optional, default=75<br />
$size # Größe der Grafik, optional, default=100<br />
$light # Helligkeit der Grafik (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 1<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_temp_bar DOIF ##<br />
attr di_icon_temp_bar room test10<br />
attr di_icon_temp_bar uiTable {package ui_Table}\<br />
"standard"|icon_temp_bar("temp_outside",[Aussensensor:temperature])\<br />
"heller"|icon_temp_bar("temp_outside",[Aussensensor:temperature],undef,undef,undef,undef,undef,undef,80)\<br />
"monochrom"|icon_temp_mbar("temp_outside",[Aussensensor:temperature])\<br />
"kleiner"|icon_temp_bar("temp_outside",[Aussensensor:temperature],undef,undef,undef,undef,undef,80)\<br />
"mit Überschrift"|icon_temp_bar("temp_outside",[Aussensensor:temperature],undef,undef,"Außen")\<br />
"hoch"|icon_temp_bar("temp_outside",[Aussensensor:temperature],undef,undef,undef,undef,100)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_temp_bar_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige der Feuchtigkeit in Balkenform mit Hilfe der SVG-Funktionen '''icon_hum_bar/icon_hum_mbar''' =====<br />
Die Farbe der dargestellten Feuchtigkeit ist abhängig vom Feuchtigkeitswert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''icon_hum_mbar'''-SVG-Funktion wird der Balken einfarbig dargestellt.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_hum_bar/icon_hum_mbar'''<br />
<syntaxhighlight lang="perl"><br />
icon_hum_bar/icon_hum_mbar ($icon,$hum_value,$header,$width,$height,$size, $light,$lightnumber,$decFont)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position", \@Farbe, Skalierungsfaktor, x-Position, y-Position sind optional<br />
$hum_value # Temperaturwert<br />
$header # Überschrift, optional, default = undef (keine)<br />
$width # Breite der Grafik, optional, default=63<br />
$height # Höhe der Grafik, optional, default=75<br />
$size # Größe der Grafik, optional, default=100<br />
$light # Helligkeit des der Grafik (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 1<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_hum_bar DOIF ##<br />
attr di_icon_hum_bar uiTable {package ui_Table}\<br />
"standard"|icon_hum_bar("temperature_humidity",[Aussensensor:humidity])\<br />
"heller"|icon_hum_bar("temperature_humidity",[Aussensensor:humidity],undef,undef,undef,undef,80)\<br />
"monochrom"|icon_hum_mbar("temperature_humidity",[Aussensensor:humidity])\<br />
"kleiner"|icon_hum_bar("temperature_humidity",[Aussensensor:humidity],undef,undef,undef,80)\<br />
"mit Überschrift"|icon_hum_bar("temperature_humidity",[Aussensensor:humidity],"Außen")\<br />
"hoch"|icon_hum_bar("temperature_humidity",[Aussensensor:humidity],undef,undef,100)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_hum_bar_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige eines Zahlenwertes mit Hilfe der universellen SVG-Funktionen '''icon_bar/icon_mbar''' =====<br />
Die Farbe des dargestellten Wertes und des Icons kann abhängig vom Wert bestimmt werden. Bei der '''icon_mbar'''-SVG-Funktion wird der Balken einfarbig dargestellt.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_bar/icon_mbar'''<br />
<syntaxhighlight lang="perl"><br />
icon_bar ($icon,$value,$min,$max,$minColor,$maxColor,$unit,$decfont,$header,$width,$height,$size, $colorFunc,$light,$lightnumber)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation (0-360) sind optional<br />
$value # darzustellender Wert<br />
$min # minimaler Wert, optional, default=0<br />
$max # maximaler Wert, optional, default=100<br />
$header # Überschrift, optional, default = undef (keine)<br />
$minColor # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 1<br />
$width # Breite der Grafik, optional, default = 63<br />
$height # Höhe der Grafik, optional, default = 75<br />
$size # Größe der Grafik, optional, default = 100<br />
$colorFunc # Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, optional, default = undef<br />
$light # Helligkeit der Grafik (light:0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (light:0-100), optional, default=50<br />
</syntaxhighlight><br />
Wird '''$colorFunc''' nicht angegeben, so wird der Farbwert zwischen '''$minColor''' und '''$maxColor''' linear interpoliert<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_bar_bsp DOIF ##<br />
attr di_icon_bar_bsp uiTable {package ui_Table;;\<br />
}\<br />
icon_bar ("fuel",[Tankstelle:Diesel],1.10,1.30,120,0,"€",2)|\<br />
icon_bar ("air",[ESPEasy_Eingang_CO2:PPM],400,1200,120,0,"ppm",0)|\<br />
icon_bar ("Zisterne",([Wasserzisterne]/3.4),0,100,0,120,"%",0)|\<br />
icon_bar (([vaillant:Pumpenstatus] eq "off" ? "sani_buffer_temp_down\@Darkorange" : "sani_buffer_temp_down\@white"),[vaillant:Umlaufmenge],0,20,120,0,"l/min")\<br />
icon_bar ("measure_water_meter",[Wasserverbrauch:heute],0,600,120,0,"l",0)|\<br />
icon_bar ("weather_barometric_pressure",[vaillant:Wasserdruck],0,3,0,180,"bar")|\<br />
icon_bar ("sani_water_tap",[vaillant:HwcHours_hoursum2_value],0,2000,120,0,"h",0)|\<br />
icon_bar ("sani_floor_heating_neutral",[Heizenergie:Vortag_hc],0,150,120,0,"kWh")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_bar_bsp.png|ohne|mini]]<br />
<br />
==== Anzeige eines Werteverlaufs und des aktuellen Wertes mit Hilfe der SVG-Funktion '''card''' ====<br />
Es wird der aktuelle Wert eines Readings, sein zeitlicher Verlauf sowie der maximale und minimale Wert in Form einer Informationskarte visualisiert. Das Erscheinungsbild kann über zahlreiche Parameter individualisiert werden. Die Besonderheit ist das Argument '''col<Anzahl><Zeitformat>''' bei der Angabe des Readings der Form '''[<Device>:<Reading>:col<Anzahl><Zeitformat>]'''. Dadurch werden Daten des Readings temporär im DOIF-Modul gesammelt und für die Erzeugung eines Graphen zur Verfügung gestellt - es sind keine weiteren Definitionen erforderlich. Dabei wird besonders sparsam mit der Datensammlung umgegangen, es werden maximal 72 Werte (in Timeslots) gespeichert, unabhängig davon wie lange die Zeitspanne ist und wie oft die Daten ankommen. Die Auflösung des Graphen nimmt mit der Zeitspanne ab - es werden immer maximal 72 Werte dargestellt. Daraus ergibt sich bei einer Stunde eine Auflösung von 3600/72 = 50 Sekunden/Eintrag, bei 6 Stunden sind es 6*60/72 = 5 Minuten/Eintrag, für eine Woche 7*24*60/72 = 140 Minuten/Eintrag usw. Die gesammelten Daten werden über den FHEM-Befehl '''save''' in versteckten Readings des jeweiligen DOIF-Moduls gespeichert.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''card'''<br />
<syntaxhighlight lang="perl"><br />
card ($collect,$header,$icon,$min,$max,$minColor,$maxColor, $unit,$colorRef,$decfont,$prop,$ringModel,$lightness, $collect2,$min2,$max2,$minColor2,$maxColor2,$unit2,$func2,$decfont2)<br />
<br />
$collect <br />
# Angabe eines Readings oder eines Arrays mit mehreren Readings der Form [<Device>:<Reading>:col<Anzahl><Zeitformat>], mit Hilfe des Argumentes col (von collect) wird das Modul angewiesen Daten des Readings über einen bestimmten Zeitraum zu sammeln<br />
<br />
col<number><timeformat> <br />
# <timeformat>: d Tage, w Wochen, ohne Angabe des Zeitformates wird <Anzahl> in Stunden interpretiert. <br />
# Beispiele: col (entspricht col24), col1, col12, col1d, col3d, col1w, col4w, col52w usw.<br />
<br />
$header # "<Überschrifttext,<Style-SVG-Text-Attribute>", optional<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$min # minimaler Wert, optional, default=0<br />
$max # maximaler Wert, optional, default=100<br />
$minColor # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = 0 (rot)<br />
$maxColor # Farbe (hue: 0-360) des maximalen Wertes, optional, default = 120 (grün)<br />
$unit <br />
# Einheit des Wertes, optional, default = undef, falls unter $collect ein Array für mehrere Readings angegeben wurde, so werden hier als Array die entsprechenden Einheiten angegeben, zusätzlich kann kommagetrennt pro Einheit Farbe des Graphen angegeben werden<br />
<br />
$colorRef <br />
# Referenz auf eine Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, oder eine Referenz auf eine Arrayliste mit Grenzwerten und Farben, optional, default = undef<br />
<br />
$decFont<br />
# "<Anzahl der Nachkommastellen>,<Style-SVG-Attribute Wert>,<Style-SVG-Attribute Einheit>", optional<br />
<br />
$prop <br />
# Eigenschaft von card: "<size>,<y-scaling>,<steps>,<noFooter>,<noColor>,<hring>,<width>", optional<br />
<br />
# <size>: Größe der der Karte, default = 130,<br />
# <y-scaling>: feste Y-Skalierung: 1, sonst automatische Skalierung,<br />
# <steps>: 1 für Stufen,<br />
# <noFooter>: 1 für keine Fußzeile,<br />
# <noColor>: 1 für graue y-Achsenbeschriftung, <br />
# <hring>: 1 für Halbringdarstellung, <br />
# <width>: Breite der Karte, default: 160<br />
<br />
$ringModel<br />
# '<color gradient>,<min/max>,<inner ring>,<pointer>,<mode>'<br />
<br />
# <color gradient>: 1 für monochrom<br />
# <min/max>: Style-SVG-Attribute oder 1 zum Anzeigen der Min-/Maxwerte<br />
# <inner ring>: Style-SVG-Attribute oder 1 zum Anzeigen des Innenringes<br />
# <pointer>: Breite des Zeigers in Pixel<br />
# <mode>: 0 Standard Min. - Max., 1 negativ - Null - positiv, 2 Null - negativ/positiv<br />
# alle Parameter sind optional, default keine Angaben: ',,,,,,'<br />
<br />
$lightness <br />
# Helligkeit einzelner Elemente (0-100) "<ring>,<inner ring>,<minMax>,<unit>,<value>,<icon>", optional, default: "50,50,50,40,50,40"<br />
<br />
$collect2 # optionale Angaben für ein zweites Reading (es ist hier nur eine Readingangabe erlaubt)<br />
$min # restliche Parameter<br />
$max # entsprechen der Syntax<br />
... # des ersten Sensors<br />
$decfonts2 # <br />
</syntaxhighlight><br />
Wird '''$colorRef''' nicht angegeben, so wird der Farbwert zwischen '''$minColor''' und '''$maxColor''' linear interpoliert<br />
Werden mehrere Readings angegeben, so müssen sie alle die gleiche Zeitspanne besitzen (Zeitangabe bei col)<br />
<br />
'''nützliche Links'''<br />
* Anwendungsbeispiel [[DOIF/uiTable_Schnelleinstieg#Visualisierung:_Wetterstation|Wetterstation]]<br />
* Anwendungsbeispiel [[DOIF/uiTable_Schnelleinstieg#Visualisierung:_aktueller_Spritpreis|Spritpreise]]<br />
* Anwendungsbeispiel [[DOIF/uiTable_Schnelleinstieg#Visualisierung_und_Steuerung:_Heiztherme|Heiztherme]]<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#Farbskalierte_Anzeige_eines_Icons_mit_einem_Zahlenwert_mit_Hilfe_der_universellen_SVG-Funktion_icon_ring.2Ficon_mring.2Ficon_uring|icon_ring]] <br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_collect DOIF ##<br />
attr di_collect uiTable {package ui_Table;;}\<br />
card([Aussensensor:temperature:col12],"Außen","temp_outside",-10,45,undef,undef,"°C",\&temp_hue,undef)|\<br />
card([Tankstelle:Diesel:col12],"Sprit,fill:darkorange","fuel","1.00","1.40",120,0,"Diesel €",undef,"2",",,1")\<br />
card([zaehler:l-Produktion:col12],undef,[zaehler:l-Produktion] > 0 ? "sani_solar\@colorVal1":"fa_bolt\@colorVal2",0,3.6,30,60,"PV kW",undef,"1,,font-size:50%")|\<br />
card([ESPEasy_Eingang_CO2:PPM:col12],undef,"air",400,1200,120,0,"ppm",[600,120,1000,60,1200,0],0,undef,'0,1,1',"50,35,45,35,50,35")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:svgcard.png|ohne|mini]]<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
<br />
defmod di_cards DOIF {}<br />
attr di_cards uiTable {package ui_Table;;}\<br />
"Standard"|\<br />
card([Aussensensor:temperature:col],undef,"temp_outside",-10,50,undef,undef,"°C",\&temp_hue,"1","130")\<br />
"mit Halbring"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,50,undef,undef,"°C",\&temp_hue,"1","130,,,,,1")\<br />
"mit Halbring","ohne Fußzeile","Breite 110"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,50,undef,undef,"°C",\&temp_hue,"1","130,,,1,,1,110")\<br />
"Standard","Breite 200"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,50,undef,undef,"°C",\&temp_hue,"1","130,,,,,,200")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:di_card_variations.png|ohne|mini]]<br />
<br />
<br />
'''<big>Beispieldefinition mit zwei Readings mit unterschiedlichen Einheiten</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_cards DOIF {}<br />
attr di_cards uiTable {package ui_Table;;}\<br />
"Standard"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,60,undef,undef,"°C",\&temp_hue,"1","130,,,,",undef,undef,[outsensor:humidity:col],0,100,undef,undef,"%",\&hum_hue,"0")\<br />
"ohne Header"|\<br />
card([Aussensensor:temperature:col],undef,"temp_outside",-10,60,undef,undef,"°C",\&temp_hue,"1","130,,,,",undef,undef,[outsensor:humidity:col],0,100,undef,undef,"%",\&hum_hue,"0")\<br />
"ohne Header","ohne Fußzeile"|card([Aussensensor:temperature:col],undef,"temp_outside",-10,60,undef,undef,"°C",\&temp_hue,"1","130,,,1,",undef,undef,[outsensor:humidity:col],0,100,undef,undef,"%",\&hum_hue,"0")\<br />
"Als Halbring"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,60,undef,undef,"°C",\&temp_hue,"1","130,,,,,1",undef,undef,[outsensor:humidity:col],0,100,undef,undef,"%",\&hum_hue,"0")\<br />
"ohne Fußzeile"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,60,undef,undef,"°C",\&temp_hue,"1","130,,,1,,1",undef,undef,[outsensor:humidity:col],0,100,undef,undef,"%",\&hum_hue,"0")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:di_card_collect2.png|ohne|mini]]<br />
<br />
'''<big>Beispieldefinitionen mit mehreren Readings mit gleicher Einheit</big>'''<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod Sprit DOIF ##<br />
attr Sprit uiTable {package ui_Table;;}\<br />
card([[Tankstelle:SuperE5:col24],[Tankstelle:Diesel:col24]],"Sprit","fuel","1.20","1.60",120,0,["E5","Diesel"],undef,"2",",,1")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:di_Sprit2.png|ohne|mini]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod PV DOIF {}<br />
attr PV DOIF_Readings l_Eigenv: [zaehler:l-Produktion]-[zaehler:l-Lieferung],\<br />
Eigenv:[zaehler:Produktion]-[zaehler:Lieferung],\<br />
l_Verbrauch: [zaehler:l-Bezug,0]+[$SELF:l_Eigenv,0],\<br />
Verbrauch:[zaehler:Bezug]+[$SELF:Eigenv],\<br />
l_Bezug:-[zaehler:l-Bezug]<br />
attr PV uiTable {\<br />
package ui_Table;;\<br />
$SHOWNOSTATE=1;;\<br />
}\<br />
card([[zaehler:l-Produktion:col],[$SELF:l_Eigenv:col],[$SELF:l_Bezug:col]],"kW","fa_bolt\@silver",-3.6,3.6,0,90,["Solar","Eigen.","Bezug"],[(-1,0,0,30,1,60,3.6,90)],"2","167,,1,,,1",",,1,6")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:di_card_energie.png|ohne|mini]]<br />
<br />
'''<big>Beispieldefinition mit mehreren Readings mit einfarbigen Graphen</big>'''<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_heating DOIF {}<br />
attr di_heating uiTable {\<br />
package ui_Table;;\<br />
}\<br />
card([[ESPEasy_ESP_Temp_Vorlauf:Temperature:col],[ESPEasy_ESP_Temp_Keller_Ruecklauf:Temperature:col]],"Umwälzpumpe",([vaillant:Pumpenstatus] eq "on" ? "sani_floor_heating\@Darkorange" : "sani_floor_heating_neutral\@white"),15,70,undef,undef,["Vor. °C,red","Rück. °C,#287afc"],\&temp_hue,undef,",,1,,1")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:di_card_pump.png|ohne|mini]]<br />
<br />
==== 3d-Balkendarstellung mehrerer Zahlenwerten mit Hilfe der universellen SVG-Funktion '''cylinder''' ====<br />
Es können mehrere Zahlenwerte mit Legende farbig in Balkenform visualisiert werden. Negative Werte werden als Balken nach unten dargestellt, positive nach oben, der Nullpunkt wird automatisch berechnet.<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''cylinder'''<br />
<syntaxhighlight lang="perl"><br />
cylinder ($header,$min,$max,$unit,$width,$height,$size,$dec,($value1,$color1,$text1),($value2,$color2,$text2),...<br />
<br />
$header # Überschrift<br />
$min # minimaler Wert, optional, default = 0<br />
$max # maximaler Wert, optional, default = 100<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$width # Breite der Grafik, optional, default = wird bei Beschriftungen automatisch angepasst<br />
$height # Höhe der Grafik, optional, default = wird automatisch berechnet<br />
$size # Größe der Grafik, optional, default = 100<br />
$dec # Anzahl der Nachkommastellen, optional, default=1<br />
$value1 # erster Zahlenwert<br />
$color1 # HSL-Farbe des ersten Balkens: "<hue>.<saturation>.<lightness>" (hue:0-360,saturation:0-100,lightness:0-100), saturation (default:100) und lightness (default:50) sind optional<br />
$text1 # Beschriftung des Zahlenwertes in der Legende, optional, default = undef<br />
$value2 # zweiter Zahlenwert, optional<br />
$color2 # HSL-Farbe des zweiten Balkens: "<hue>.<saturation>.<lightness>" (hue:0-360,saturation:0-100,lightness:0-100), saturation (default:100) und lightness (default:50) sind optional<br />
$text2 # Beschriftung des Zahlenwertes in der Legende, optional, default = undef<br />
...<br />
Es können weitere Zahlenwerte jeweils mit Farbe und Beschriftung optional angegeben werden <br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_cylinder DOIF ##<br />
attr di_cylinder room Test,wiki<br />
attr di_cylinder uiTable {package ui_Table}\<br />
"normal"|cylinder("",0,100,"%",80,undef,undef,0,[Wasserzisterne:state],200,undef)\<br />
\<br />
"mit Überschrift"|cylinder("Zisterne",0,100,"%",80,undef,undef,0,[Wasserzisterne:state],200,undef)\<br />
\<br />
"kleiner"|cylinder("Zisterne",0,100,"%",80,undef,80,0,[Wasserzisterne:state],200,undef)\<br />
\<br />
"hoch"|cylinder("Zisterne",0,100,"%",undef,100,undef,0,[Wasserzisterne:state],200,undef)\<br />
\<br />
"mit Beschriftung"|cylinder("Zisterne",0,100,"%",undef,100,undef,0,[Wasserzisterne:state],200,"Wasserstand")\<br />
\<br />
"mit mehreren Informationen"|cylinder("Energie",-20,30,"kWh",undef,undef,undef,1,[zaehler:Bezug],0,"Bezug",[zaehler:Produktion],60,"Produktion",[zaehler:Eigenverbrauch],30,"Eigenverbrauch")\<br />
\<br />
"mit hellen Farben"| cylinder("Tag",0,100,"kWh",undef,undef,undef,1,[Heizenergie:Tagesverbrauch_hc]/100000,"30.100.70","letzter",[Heizenergie:heute_hc]/100000,"60.100.70","aktuell")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:cylinder_bsp.png|ohne|mini]]<br />
<br />
==== Balkendarstellung mehrerer Zahlenwerte mit Hilfe der universellen SVG-Funktion '''cylinder_bars''' ====<br />
Es können mehrere Zahlenwerte mit Legende farbig in Balkenform visualisiert werden. Negative Werte werden als Balken nach unten dargestellt, positive nach oben, der Nullpunkt wird automatisch berechnet. Die '''cylinder_bars'''-SVG-Funkton besitzt die gleichen Argumente, wie die obige '''cylinder'''-SVG-Funktion, mehrerer Balken werden jedoch nicht übereinander, sondern nebeneinander dargestellt.<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''cylinder_bars'''<br />
<syntaxhighlight lang="perl"><br />
cylinder_bars ($header,$min,$max,$unit,$width,$height,$size,$dec,($value1,$color1,$text1),($value2,$color2,$text2),...<br />
<br />
$header # Überschrift<br />
$min # minimaler Wert, optional, default = 0<br />
$max # maximaler Wert, optional, default = 100<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$width # Breite der Grafik, optional, default = wird bei Beschriftungen automatisch angepasst<br />
$height # Höhe der Grafik, optional, default = wird automatisch berechnet<br />
$size # Größe der Grafik, optional, default = 100<br />
$dec # Anzahl der Nachkommastellen, optional, default=1<br />
$value1 # erster Zahlenwert<br />
$color1 # HSL-Farbe des ersten Balkens: "<hue>.<saturation>.<lightness>" (hue:0-360,saturation:0-100,lightness:0-100), saturation (default:100) und lightness (default:50) sind optional<br />
$text1 # Beschriftung des Zahlenwertes in der Legende, optional, default = undef<br />
$value2 # zweiter Zahlenwert, optional<br />
$color2 # HSL-Farbe des zweiten Balkens: "<hue>.<saturation>.<lightness>" (hue:0-360,saturation:0-100,lightness:0-100), saturation (default:100) und lightness (default:50) sind optional<br />
$text2 # Beschriftung des Zahlenwertes in der Legende, optional, default = undef<br />
...<br />
Es können weitere Zahlenwerte jeweils mit Farbe und Beschriftung optional angegeben werden <br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_wasserverbrauch DOIF ##<br />
attr di_wasserverbrauch uiTable {package ui_Table;;}\<br />
cylinder_bars("Monat",0,15,"m³",undef,undef,undef,1,[Wasserverbrauch:monatsdurchschnitt],30,"Durchschnitt",[Wasserverbrauch:monatsverbrauch]/1000,220,"letzter",[Wasserverbrauch:monat]/1000,180,"aktuell")\<br />
\<br />
cylinder_bars("Monat",0,15,"m³",undef,undef,undef,1,[Wasserverbrauch:jan],30,"Januar",[Wasserverbrauch:feb],220,"Februar",[Wasserverbrauch:mrz],180,"März",[Wasserverbrauch:apr],30,"April",[Wasserverbrauch:mai],220,"Mai",[Wasserverbrauch:jun],180,"Juni",[Wasserverbrauch:jul],30,"Juli",[Wasserverbrauch:aug],220,"August",[Wasserverbrauch:sep],180,"September",[Wasserverbrauch:okt],30,"Oktober",[Wasserverbrauch:nov],220,"November",[Wasserverbrauch:dez],180,"Dezember")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:cylinder_bars_bsp.png|ohne|mini]]<br />
<br />
=== Farbskalierte Temperaturanzeige mit Hilfe der Funktion '''temp''' ===<br />
Die Farbe der dargestellten Temperatur ist abhängig vom Temperaturwert:<br />
[[Datei:Farbskalierung temp.png|600px|ohne]]<br />
{{Randnotiz|RNText=uiTable-Funktion '''temp'''<br />
<syntaxhighlight lang="perl"><br />
temp ($temp,$size,$icon)<br />
<br />
$temp # Temperatur<br />
$size # Schriftgröße in Pixel (pt), optional<br />
$icon # Icon, welches vorangestellt wird, optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_temp DOIF ##<br />
attr di_uiTable_temp uiTable {\<br />
package ui_Table;; ## Package für uiTable-Funktionen\<br />
$TC{0..2}="align='center'";; ## zentrierte Darstellung aller Tabellenspalten\<br />
}\<br />
## Tabellendefinition\<br />
\<br />
"Aussen"|"Bad"|"Warmwasser" ## mit | werden Tabellenzellen voneinander getrennt \<br />
temp([Aussensensor:temperature])| ## Anzeige des Readings 'temperature' des Gerätes 'Aussensensor' \<br />
temp([TH_Bad_HM:measured-temp],24,"temp_temperature")| ## Schriftgröße 24pt, mit Icon namens temp_temperature\<br />
temp([T_Warmwasserspeicher:temperature:d1],20) ## Schriftgröße 20pt<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Temp.png|ohne|mini]]<br />
<br />
=== Farbskalierte Feuchtigkeitsanzeige mit Hilfe der Funktion '''hum''' ===<br />
Die Farbe der dargestellten Feuchtigkeit ist abhängig vom Feuchtigkeitswert:<br />
[[Datei:Farbskalierung hum.png|350px|ohne]]<br />
{{Randnotiz|RNText=uiTable-Funktion '''hum'''<br />
<syntaxhighlight lang="perl"><br />
hum ($hum,$size,$icon)<br />
<br />
$hum # Feuchtigkeit<br />
$size # Schriftgröße in Pixel (pt), optional<br />
$icon # Icon, welches vorangestellt wird, optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_hum DOIF ##<br />
attr di_uiTable_hum uiTable {\<br />
package ui_Table;;\<br />
$TC{1}="align='center'";; ## zweite Spalte der Tabelle zentriert\<br />
}\<br />
## Tabellendefinition \<br />
\<br />
## Anzeige des Readings 'humidity' des Thermostats 'TH_Bad_HM' \<br />
"Bad"|hum ([TH_Bad_HM:humidity])\<br />
\<br />
## Feuchtigkeit in Größe 10pt mit Temperatur in einer Tabellenzelle\<br />
"Aussen"|temp ([Aussensensor:temperature]),hum ([Aussensensor:humidity],10)\<br />
\<br />
## Feuchtigkeit in Größe 26pt mit Icon namens 'temperature_humidity'\<br />
"Keller"|hum ([TH_Keller_HM:humidity],26,"temperature_humidity")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable Funktion hum.png|ohne|mini]]<br />
<br />
=== Textformatierungen mit Hilfe der Funktion '''style''' ===<br />
Texte werden in Farbe, Größe und Schriftart statisch oder dynamisch formatiert.<br />
{{Randnotiz|RNText=uiTable-Funktion '''style'''<br />
<syntaxhighlight lang="perl"><br />
style ($text,$color,$font_size,$font_weight)<br />
<br />
$text # anzuzeigender Text<br />
$color # CSS color, optional<br />
$font_size # Schriftgröße in Pixel (pt), optional<br />
$font_weight # CSS Schriftart, optional<br />
</syntaxhighlight><br />
Mögliche Werte für '''''color''''' und '''''font_weight''''' können in einschlägiger Dokumentation zu CSS nachgeschlagen werden<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_style DOIF ##<br />
attr di_uiTable_style uiTable {\<br />
package ui_Table;;\<br />
}\<br />
## Tabellendefinition\<br />
\<br />
## statische Farbgebung, Größe, Schriftart \<br />
style("Montag","orange")\<br />
style("Dienstag","red",14)\<br />
style("Mittwoch","#00FFFF",20)\<br />
style("Donnerstag","blue",23,"bold")\<br />
\<br />
## dynamische Farbgebung abhängig vom Zustand des Gerätes 'Alarm'\<br />
style("Alarm",([Alarm:state] eq "on" ? "red":"green"))\<br />
\<br />
## dynamische Farbgebung des Zustands des Gerätes 'Alarm'\<br />
style([Alarm:state],([Alarm:state] eq "on" ? "red":"green"))\<br />
\<br />
## variabler Text abhängig vom Zustand des Gerätes 'Alarm'\<br />
style(([Alarm:state] eq "on" ? "Alarm aktiv":"Alarm deaktiviert"),"red")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Style.png|ohne|mini]]<br />
<br />
=== Icon-Darstellung mit Hilfe der Funktion '''ICON''' ===<br />
Mit Hilfe der Funktion '''ICON''' kann ein FHEM-Icon dargestellt werden<br />
{{Randnotiz|RNText=uiTable-Funktion '''ICON'''<br />
<syntaxhighlight lang="perl"><br />
ICON ($icon)<br />
<br />
$icon # Icon mit Farbgebung<br />
</syntaxhighlight><br />
<br />
'''ICON''' benutzt die Funktion [[DevelopmentFHEMWEB-API#FW_makeImage|FW_makeImage]]<br />
<br />
'''nützliche Links'''<br />
* [[DOIF/uiTable Schnelleinstieg#hsv-Funktion für Farbskalierungen|hsv-Funktion]]<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_Table_ICON DOIF ##<br />
attr di_Table_ICON uiTable {\<br />
package ui_Table;;\<br />
}\<br />
## Tabellendefinition\<br />
ICON("temp_frost") | ## Icon ohne Einfärbung\<br />
ICON("temp_frost\@blue") | ## Icon in CSS-Farbe blau\<br />
ICON("temp_frost\@#8A2BE2") | ## Icon in CSS-Farbe #8A2BE2\<br />
ICON("temp_frost\@".([Aussensensor:temperature] > 0 ? "orange":"blue"))| ## Icon in CSS-Farbe orange über Null Grad, sonst in CSS-Farbe blau\<br />
ICON("temp_frost\@".hsv ([Aussensensor:temperature],-20,40,320,0)) ## Icon in Farbskalierung von violett (-20 °C) bis rot (40 °C) mit Hilfe der Funktion hsv<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable_IC.png|mini|ohne]]<br />
<br />
=== Icon-Darstellung mit Text mit Hilfe der Funktion '''icon_label''' ===<br />
Mit Hilfe der Funktion '''icon_label''' kann ein FHEM-Icon mit einem angehängten Text/Wert dargestellt werden.<br />
{{Randnotiz|RNText=uiTable-Funktion '''icon_label'''<br />
<syntaxhighlight lang="perl"><br />
icon_label ($icon,$text,$color,$color_bg,$pos_left,$pos_top)<br />
$icon # FHEM-Icon mit Farboption<br />
$text # dargestellter Text<br />
$color # Farbe des Textes, optional<br />
$color # Hintergrundfarbe des Textes, optional<br />
$pos_left # horizontale Position des Textes in px, default -5, optional<br />
$pos_top # vertikale Position des Textes in px, default -8, optional<br />
</syntaxhighlight><br />
<br />
'''Anwendungsbeispiele'''<br />
* [[DOIF/uiTable Schnelleinstieg#Anzahl der Tage bis zur Abfall-Entsorgung|Abfall]]<br />
* [[DOIF/uiTable Schnelleinstieg#Visualisierung: aktueller Spritpreis|Sprit]]<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_icon_label DOIF ##<br />
attr di_uiTable_icon_label uiTable { package ui_Table;;\<br />
}\<br />
\<br />
icon_label("fuel",[Tankstelle:Diesel])|\<br />
icon_label("fuel",[Tankstelle:Diesel],"red")|\<br />
icon_label("fuel\@blue",[Tankstelle:Diesel],"blue","#999999")|\<br />
icon_label("fuel\@red",[Tankstelle:Diesel],"red","white",-10)|\<br />
icon_label("fuel",[Tankstelle:Diesel],"white","red",-5,8)\<br />
<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable_icon_label.png|mini|ohne]]<br />
<br />
=== Visualisierung eines Gerätes mit Hilfe der Funktion '''icon''' ===<br />
Der Zustand eines Gerätes/Readings wird mit Hilfe eines Icons dargestellt.<br />
{{Randnotiz|RNText=uiTable-Funktion '''icon'''<br />
<syntaxhighlight lang="perl"><br />
icon ($value,$icon_off,$icon_on,$state_off,$state_on)<br />
<br />
$value # Wert <br />
$icon_off # Icon für den Wert off, default "off"<br />
$icon_on # Icon für den Wert on, default Icon für Wert 'off' in Farbe 'DarkOrange', sonst Icon 'on', wenn $icon_off nicht definiert ist<br />
$state_off # Wert zugehörig zum Icon off, default "off"<br />
$state_on # Wert zugehörig zum Icon on, default "on"<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_icon DOIF ##<br />
attr di_uiTable_icon uiTable {\<br />
package ui_Table;;\<br />
}\<br />
## Tabellendefinition\<br />
\<br />
## Standard-Icon off/on für Standardwert off/on \<br />
"Lampe"|icon([Lampe:state]) ## entspricht icon([Lampe:state],"off","on","off","on")\<br />
\<br />
## Icon für Zustand 'off' ist 'hue_room_hallway', für Zustand 'on' 'hue_room_hallway\@DarkOrange'\<br />
"Flur"|icon([Lampeflur:state],"hue_room_hallway") ## entspricht icon([Lampeflur:state],"hue_room_hallway","hue_room_hallway\DarkOrange","off","on")\<br />
\<br />
## Icon für Zustand 'off' ist 'status_away_2', für Zustand 'on' 'status_available\@DarkOrange'\<br />
"Anwesenheit"|icon([Anwesenheit:state],"status_away_2","status_available\@DarkOrange") \<br />
\<br />
## Icon für Zustand 'closed' ist "status_locked", für Zustand 'open' 'status_open\@DarkOrange'\<br />
"Haus"|icon([Schloss:state],"status_locked","status_open\@DarkOrange","closed","open") <br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable icon.png|mini|ohne]]<br />
<br />
=== Schaltbares Icon mit Hilfe der Funktion '''switch''' ===<br />
Der Zustand eines Gerätes/Readings wird mit Hilfe eines Icons dargestellt, er kann über die WEB-Oberfläche durch Anklicken geschaltet werden. Damit der Zustand des Gerätes geschaltet werden kann, muss das Gerät den set-Befehl unterstützen.<br />
<br />
{{Randnotiz|RNText=uiTable-Funktion '''switch'''<br />
<syntaxhighlight lang="perl"><br />
switch ($value,$icon_off,$icon_on,$state_off,$state_on)<br />
<br />
$value # [<device>:<reading>] <br />
$icon_off # Icon für den Wert off, default "off"<br />
$icon_on # Icon für den Wert on, default Icon für Wert 'off' in Farbe 'DarkOrange', sonst Icon 'on', wenn $icon_off nicht definiert ist<br />
$state_off # Wert zugehörig zum Icon off, default "off"<br />
$state_on # Wert zugehörig zum Icon on, default "on"<br />
</syntaxhighlight><br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_switch DOIF ##<br />
attr di_uiTable_switch uiTable {\<br />
package ui_Table;;\<br />
}\<br />
## schaltbares Icons in der Webansicht \<br />
switch([Lampe:state]) | \<br />
switch([Lampeflur:state],"hue_room_hallway") |\<br />
switch([Anwesenheit:state],"status_away_2","status_available\@DarkOrange")|\<br />
switch([Haus:state],"status_locked","status_open\@DarkOrange","closed","open")\<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable switch.png|mini|ohne]]<br />
<br />
=== Rollladen: Visualisierung und Steuerung mit Hilfe der Funktion '''shutter''' ===<br />
Die aktuelle Position des Rollladens (0 % - 100 %) wird über Icons visualisiert. Das Anklicken eines Symbols steuert den Rollladen auf die entsprechende Position. Prozentwerte zwischen zwei Icon-Werten werden dem nächsthöheren Icon-Wert zugeordnet.<br />
{{Randnotiz|RNText=uiTable-Funktion '''shutter'''<br />
<syntaxhighlight lang="perl"><br />
shutter ($value,$color,$type)<br />
<br />
$value # [<device>:<reading>] <br />
$color # Farbe der aktuellen Rollladenposition, vorangestelltes @ verändert die Farbe des Icons, ohne @ wird der Hintergrund des Icons eingefärbt, default ist @DarkOrange<br />
$type # optional, Anzahl der Symbole 2 bis 6, 3 ist default<br />
</syntaxhighlight><br />
<br />
* [[DOIF/uiTable Schnelleinstieg#Visualisierung und Steuerung von Rollläden|Anwendungsbeispiel]]<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod ui_Table_shutter DOIF ##<br />
attr ui_Table_shutter uiTable {\<br />
package ui_Table;;\<br />
}\<br />
shutter([R_Keller:pct],"\@yellow",2) ## zwei Symbole für 0 % und 100 %\<br />
shutter([R_Wohnzimmer_S:pct]) ## entspricht shutter ([R_Wohnzimmer_S:pct],"\@DarkOrange",3) \<br />
shutter([R_Wohnzimmer_W1:pct],"blue",4) ## vier Symbole \<br />
shutter([R_Wohnzimmer_W2:pct],"\@red",5) ## fünf Symbole\<br />
shutter([R_Wohnzimmer_W3:pct],"red",6 ## sechs Symbole)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable shutter.png|mini|ohne]]<br />
<br />
=== Helligkeit: Visualisierung und Steuerung mit Hilfe der Funktion '''dimmer''' ===<br />
Die aktuelle Helligkeit (0 % - 100 %) wird über Icons visualisiert. Das Anklicken eines Icons bestimmt die Helligkeit der Leuchte. Prozentwerte zwischen zwei Icon-Werten werden dem nächsthöheren Icon-Wert zugeordnet.<br />
{{Randnotiz|RNText=uiTable-Funktion '''dimmer'''<br />
<syntaxhighlight lang="perl"><br />
dimmer ($value,$color,$type)<br />
<br />
$value # [<device>:<reading>] <br />
$color # Farbe der aktuellen Helligkeit, vorangestelltes @ verändert die Farbe des Icons, ohne @ wird der Hintergrund des Icons eingefärbt, default ist @DarkOrange<br />
$type # Anzahl der Symbole 2 bis 7, 3 ist default<br />
</syntaxhighlight><br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_dimmer DOIF ##<br />
attr di_uiTable_dimmer uiTable {\<br />
package ui_Table;;\<br />
}\<br />
dimmer([Strauch3:pct],"\@yellow",2)\<br />
dimmer([Strauch3:pct]) ## entspricht dimmer([Strauch3:pct],"\@DarkOrange",3) \<br />
dimmer([Strauch3:pct],"blue",4)\<br />
dimmer([Strauch3:pct],"\@red",5)\<br />
dimmer([Strauch3:pct],"red",6)\<br />
dimmer([Strauch3:pct],"DarkOrange",7)<br />
<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable dimmer.png|mini|ohne]]<br />
<br />
=== Vorgabetemperatur eines Thermostats mit Hilfe der Funktion '''temp_knob''' ===<br />
Die aktuelle Vorgabetemperatur eines Thermostats wird über ein Icons visualisiert. Durch Anklicken des Ringes wird die Vorgabetemperatur verändert.<br />
{{Randnotiz|RNText=uiTable-Funktion '''temp_knob'''<br />
<syntaxhighlight lang="perl"><br />
temp_knob ($value,$color,$set)<br />
<br />
$value # [<device>:<reading>] <br />
$color # Farbe der voreingestellten Temperatur, default "Darkorange"<br />
$set # set-Befehl, default "set", sonst muss "set <Readingname>" angegeben werden, falls sich das Reading vom set-Befehl vom angezeigten Reading unterscheidet, wie beim THRESHOLD-Modul<br />
</syntaxhighlight><br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod ui_Table_temp_knob DOIF ##<br />
attr ui_Table_temp_knob uiTable {\<br />
package ui_Table;;\<br />
}\<br />
\<br />
## HM-EU-Thermostat, angezeigt wird das Reading "desired-temp", geschaltet wird über "set desired-temp" \<br />
"Dachgeschoss"|temp_knob([TH_DG_HM:desired-temp]) ## entspricht temp_knob([TH_DG_HM:desired-temp],"Darkorange","set") \<br />
\<br />
## HM-EU-Thermostat Temperaturanzeige in gelb \ <br />
"Wohnzimmer"|temp_knob([TH_WZ_HM:desired-temp],"yellow") \<br />
\<br />
## Beim THRESHOLD-Modul wird das Reading "desired_value" angezeigt, geändert wird die Temperatur per "set desired" \<br />
"Küche"|temp_knob([TH_Kueche:desired_value],"red","set desired")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable temp knob.png|mini|ohne]]<br />
<br />
== uiTable-'''Templates''' ==<br />
Die Definition einer oder mehrere Zellen kann zu einem Template zusammengefasst werden. Durch die Nutzung von Templates kann die Definition einer Tabelle erheblich vereinfacht werden. Insb. bei gleichartigen Zellen/Zeilen für verschiedene Geräte/Readings braucht eine aufwendige Definition nicht immer wieder wiederholt werden, sondern kann jeweils mit dem Aufruf eines zuvor definierten Templates realisiert werden.<br />
{{Randnotiz|RNText='''Templates'''<br />
* Die Definition von Templates muss vor der Tabellendefinition vorgenommen werden<br />
* Eine Template-Definition beginnt mit dem Schlüsselwort '''DEF'''<br />
* Der Template-Name muss mit '''TPL_''' beginnen<br />
* '''Template-Definition'''-Syntax<br />
<syntaxhighlight lang="perl"><br />
DEF TPL_<Template-Name>(<Zellendefinition mit Platzhaltern: $1,$2,...>)<br />
</syntaxhighlight><br />
* Templates-Definitionen können in externe Dateien ausgelagert werden<br />
* Templates-Definitionen können per IMPORT-Befehl aus externen Dateien importiert werden<br />
* '''Template-Import'''-Syntax<br />
<syntaxhighlight lang="perl"><br />
IMPORT <Pfad mit Dateinamen><br />
</syntaxhighlight><br />
* Innerhalb einer Tabellendefinition können zuvor definierte oder importierte Templates mehrfach genutzt werden<br />
* '''Template-Aufruf'''-Syntax<br />
<syntaxhighlight lang="perl"><br />
TPL_<Template-Name>(<Übergabeparameter für $1>,<Übergabeparameter für $2>,...)<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod ui_Table_Template DOIF ##<br />
attr ui_Table_Template uiTable {\<br />
package ui_Table;;\<br />
$TC{1..3}="align='center'";; ## Spalten 1 bis 3 werden zentriert\<br />
}\<br />
\<br />
## Template-Definitionen beginnen vor der Tabellendefinition\<br />
\<br />
## Das Template TPL_raum stellt eine Tabellenzeile dar, die mit Hilfe von uiTable-Funktionen mehrere Tabellenzellen definiert\<br />
DEF TPL_raum ("$1" | temp([TH_$2_HM:measured-temp]),hum([TH_$2_HM:humidity]) | switch([H_$2:state],"fa_off") | temp_knob([TH_$2_HM:desired-temp]))\<br />
\<br />
## Tabellendefinition\<br />
\<br />
## pro Tabellenzeile wird ein Raum mit Hilfe des oben definierten Templates "TPL_raum" dargestellt\<br />
"Raum"|"Temp./Feuchte"|"Ventil"|"Vorgabetemp."\<br />
TPL_raum (Dachgeschoss,DG) ## der Übergabeparameter "Dachgeschoss" wird im Template "TPL_raum" anstelle von $1 eingesetzt, "DG" wird anstelle von $2 eingesetzt\<br />
TPL_raum (Bad,Bad)\<br />
TPL_raum (Kinderzimmer ost,Kz_o)\<br />
TPL_raum (Kinderzimmer west,Kz_w)\<br />
TPL_raum (Wohnzimmer,WZ)\<br />
TPL_raum (Keller,Keller)<br />
<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable Templates.png|mini|ohne]]<br />
<br />
== Eigene uiTable-Funktionen programmieren ==<br />
Für die eigenen Bedürfnisse können eigene uiTable-Funktionen programmiert werden. In der Datei [https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DOIF/uiTable.tpl contrib/DOIF/uiTable.tpl] befinden sich alle intern definierten uiTable-Funktion aus dem package ui_Table als Kopie. Diese Funktionen können als Inspiration für eigene Entwicklung dienen. <br />
{{Randnotiz|RNText='''uiTable-Funktionen'''<br />
* Es gibt drei Arten von uiTable-Funktionen, sie werden intern anhand der Rückgabewerte unterschieden<br />
* uiTable-Funktionen vom Typ 1: '''HTML''', ein Rückgabewert<br />
<syntaxhighlight lang="perl"><br />
return(<HTML-code>)<br />
</syntaxhighlight><br />
* uiTable-Funktionen vom Typ 2: '''Style''' (entspricht der '''STY'''-Funktion), zwei Rückgabewerte<br />
<syntaxhighlight lang="perl"><br />
return(<value>,<CSS-style>)<br />
</syntaxhighlight><br />
* uiTable-Funktionen vom Typ 3: '''Widget''' (entspricht der '''WID'''-Funktion), vier Rückgabewerte<br />
<syntaxhighlight lang="perl"><br />
return (<value>,<>,<FHEM-widget>,<set-command: "" or "set" or "set <Readingname>">)<br />
</syntaxhighlight><br />
* uiTable-Funktionen sind reine Perlfunktionen<br />
* uiTable-Funktionen sollten im eigenen Package definiert werden, sonst könnten bestehende Perlfunktionen im System überschrieben werden<br />
* uiTable-Funktionen können in Template-Dateien ausgelagert werden und über IMPORT-Befehl importiert werden, siehe Templates<br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_function DOIF ##<br />
attr di_uiTable_function uiTable {\<br />
package my_uiTable;; ## eigenes Package mit selbstdefinierten Funktionen\<br />
\<br />
## uiTable-Funktion vom Typ "HTML", Rückgabewert: (HTML-code)\<br />
\<br />
sub clock { ## Anzeige aktueller Uhrzeit mit Datum\<br />
## Voraussetzung: contrib/DOIF/doifclock.js muss ins www/pgm2-Verzeichnis kopiert werden\<br />
## Attribut setzen in der Webinstanz: attr <WEB-Instanz> JavaScripts pgm2/doifclock.js \<br />
my ($color,$size)=@_;;\<br />
$color="darkorange" if (!defined ($color));; ## $color ist optional, default Darkorange\<br />
$size="20" if (!defined ($size));; ## $size ist optional, default 20pt\<br />
return("<div class='doifclock'style='font-weight:bold;;font-size:".$size."pt;;color:".$color.";;'>error</div>")\<br />
}\<br />
\<br />
## uiTable-Funktion vom Typ Style, Rückgabewerte (Wert,CSS-style)\<br />
\<br />
sub red_green { ## Farbige Skalierung von Zahlen mit Hilfe der DOIF_hsv-Funktion: von 0 - rot bis 10 - grün\<br />
my ($value)=@_;;\<br />
return ($value." KW", ## Wert/Text\<br />
"font-weight:bold;;color:".::DOIF_hsv ($value,0,10,0,120,70,100) ## CSS-Style\<br />
);;\<br />
} \<br />
\<br />
## uiTable-Funktion vom Typ Widget, Rückgabewerte (Wert,Leer,FHEM-Widget,set-Befehl)\<br />
\<br />
sub slider { ## FHEM-Widget Slider, weitere FHEM-Widgets siehe: https://wiki.fhem.de/wiki/FHEMWEB/Widgets\<br />
my ($value,$set)=@_;;\<br />
$set="" if (!defined $set);;\<br />
return ($value, ## Zahlenwert\<br />
"", ## leer\<br />
"slider,0,0.5,100,1", ## FHEM-Widget\<br />
$set ## set-Befehl des FHEM-Widgets\<br />
) \<br />
}\<br />
\<br />
}\<br />
\<br />
## Tabellendefinition\<br />
\<br />
"Uhrzeit/Datum"\<br />
clock("yellow",30) ## obige Funktion clock\<br />
"Dimmer"\<br />
slider([Wohnzimmer:pct]) ## obige Funktion slider\<br />
"Leistung"\<br />
red_green([Leistung:state]) ## obige Funktion red_green<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-functions.png|mini|ohne]]<br />
<br />
== Package-Konzept, Auslagerung eigener Funktionen, der '''IMPORT'''-Befehl==<br />
uiTable arbeitet mit Packages. In einem Package sind definierte Funktionen gekapselt, sie kollidieren nicht mit bereits definierten Funktionen in FHEM.<br />
{{Randnotiz|RNText='''Package'''<br />
* das für die Definition der Tabelle gültige Package wird im Perlblock des uiTable-Attributes angegeben<br />
* interne uiTable-Funktionen befinden sich im Package '''ui_Table'''<br />
* ohne eine Angabe eines Package befindet man sich im Package '''main'''<br />
* Funktionen außerhalb des gültigen Package müssen mit <package-Name>::<Funktion> angegeben werden<br />
* externe uiTable-Funktionen können per IMPORT-Befehl importiert werden<br />
}} <br />
=== Tabellendefinition im Package main ===<br />
<syntaxhighlight lang="perl"><br />
defmod beispiel1 DOIF ##<br />
attr beispiel1 uiTable ## keine Package-Definition im Perlblock\<br />
\<br />
## Tabellendefinition befindet sich im Package main\<br />
\<br />
## Funktionen aus dem main-Package können unmittelbar angegeben werden\<br />
FW_makeImage("scene_day")\<br />
\<br />
## Funktionen aus dem ui_Table-Package müssen mit vorangestelltem Package angegeben werden\<br />
ui_Table::temp ([Aussensensor:tempaerature])<br />
</syntaxhighlight><br />
<br />
=== Tabellendefinition im Package ui_Table ===<br />
<syntaxhighlight lang="perl"><br />
defmod beispiel2 DOIF ##<br />
attr beispiel2 uiTable {\<br />
package ui_Table; ## Package-Angabe im Perlblock\<br />
}\<br />
\<br />
## Tabellendefinition befindet sich im Package ui_Table\<br />
\<br />
## Funktionen aus dem main-Package müssen mit vorangestelltem package angegeben werden, der Name main kann weggelassen werden\<br />
::FW_makeImage("scene_day")\<br />
\<br />
## Funktionen aus dem ui_Table-Package können direkt angegeben werden\<br />
temp ([Aussensensor:temperature])<br />
</syntaxhighlight><br />
<br />
=== Eigene uiTable-Funktionen im eigenen Package ===<br />
Diese Art der Definition bietet sich dann an, wenn man eine eigene uiTable-Funktion nur in einem DOIF nutzen möchte.<br />
<syntaxhighlight lang="perl"><br />
defmod beispiel3 DOIF ##<br />
attr beispiel3 uiTable {\<br />
package $SELF;; ## Package-Name ist der Name des DOIF-Moduls, dadurch ist der Package-Name eindeutig\<br />
sub scene_day { ## eigene Funktion befindet sich im eigenen Package beispiel3\<br />
return (::FW_makeImage("scene_day"));;\<br />
}\<br />
}\<br />
## Tabellendefinition befindet sich im Package beispiel3\<br />
\<br />
## Funktionen aus dem main-Package müssen mit vorangestelltem Package angegeben werden (der Name main kann weggelassen werden)\<br />
::FW_makeImage("scene_day")\<br />
\<br />
## interne Funktionen aus dem ui_Table-Package müssen mit vorangestelltem Package ui_Table angegeben werden\<br />
ui_Table::temp ([Aussensensor:temperature])\<br />
\<br />
## eigene Funktionen können direkt angegeben werden\<br />
scene_day()<br />
</syntaxhighlight><br />
<br />
=== Eigene ausgelagerte uiTable-Funktionen ===<br />
Möchte man das ui_Table-Package um eigene Funktionen erweitern, die man in verschiedenen DOIFs nutzen möchte, so sollte man diese in eine eigene Datei auslagern, die man mit dem IMPORT-Befehl vor der Definition der Tabelle importieren kann.<br />
<br />
Ausgelagerte Funktion in einer eigenen Datei z. B. my_uiTable.tpl:<br />
<br />
<syntaxhighlight lang="perl"><br />
{ ## Inhalt der Datei my_uiTable.tpl<br />
package ui_Table; ## das aktuelle Package ist ui_Table<br />
sub scene_day { ## eigene Funktion wird zum Package ui_Table hinzugefügt <br />
return (::FW_makeImage("scene_day"));<br />
}<br />
## die Datei kann alle Funktionen beinhalten, die man in diversen DOIFs nutzen möchte<br />
}<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="perl"><br />
defmod beispiel4 DOIF ##<br />
attr beispiel4 uiTable ##\<br />
\<br />
IMPORT ./contrib/DOIF/my_uiTable.tpl ## nach dem Import befindet man sich in Package ui_Table erweitert um eigene Funktionen\<br />
\<br />
## Tabellendefinition befindet sich im Package ui_Table\<br />
\<br />
## Funktionen aus dem main-Package müssen mit vorangestelltem Package angegeben werden (der Name main kann weggelassen werden)\<br />
::FW_makeImage("scene_day")\<br />
\<br />
## interne uiTable-Funktionen aus dem ui_Table-Package können direkt angegeben werden\<br />
temp ([Aussensensor:temperature])\<br />
\<br />
## eigene Funktionen können direkt angegeben werden, da man sich bereits im Package uiTable befinden\<br />
scene_day()\<br />
</syntaxhighlight><br />
<br />
== '''hsv'''-Funktion für Farbskalierungen==<br />
Mit Hilfe der hsv-Funktion können Texte, Werte oder Icons abhängig vom Wert eingefärbt werden. Es wird durch Vorgabe von Farbsättigung (saturation) und Helligkeit (lightness), linear ein Farbton für einen bestimmten Wert errechnet. Den Farbwert HUE (0 - 360) für den kleinsten sowie größten Wert kann man mit Hilfe eines Color-Pickers bestimmen. Der Rückgabewert ist ein Farbwert in der CSS-Notation.<br />
{{Randnotiz|RNText='''hsv-Funktion für Farbskalierungen'''<br />
<syntaxhighlight lang="perl"><br />
hsv ($value,$min_value,$max_value,$min_hue,$max_hue,$saturation,$lightness)<br />
$value # Wert, Reading<br />
$min_value # der kleinste Wert, dieser entspricht dem Farbwert $min_hue<br />
$max_value # der größte Wert, dieser entspricht dem Farbwert $max_hue<br />
$min_hue # Farbwert für den kleinsten Wert $min_value<br />
$max_hue # Farbwert für den größten Wert $max_value<br />
$saturation # Farbsättigung, default 100, optional<br />
$lightness # Farbhelligkeit, default 100, optional<br />
</syntaxhighlight><br />
Die Funktion befindet sich im ui_Table-Package<br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_hsv DOIF ##<br />
attr di_uiTable_hsv uiTable {\<br />
package ui_Table;;\<br />
## eigene uiTable-Funktionen vom Typ 1 mit einem Rückgabewert als HTML-Code\<br />
\<br />
sub bat_icon { ## färbt das Icon 'measure_battery_100' abhängig vom Wert mit Hilfe der Funktion hsv \<br />
my ($value)=@_;;\<br />
return(ICON("measure_battery_100\@".hsv($value,0,100,0,120,100,100)))\<br />
}\<br />
\<br />
sub bat_icon2 {## zusätzlich zum Farbwert wird ein entsprechendes Icon bestimmt\<br />
my($val)=@_;;\<br />
my $icon;;\<br />
if ($val==0) {\<br />
$icon="measure_battery_0";;\<br />
} elsif ($val<=25) {\<br />
$icon="measure_battery_25";;\<br />
} elsif ($val<=50) {\<br />
$icon="measure_battery_50";;\<br />
} elsif ($val<=75) {\<br />
$icon="measure_battery_75";;\<br />
} else {\<br />
$icon="measure_battery_100";;\<br />
}\<br />
\<br />
my $output=ICON("$icon\@".hsv ($val,0,100,0,120,90,100));;\<br />
return($output);;\<br />
}\<br />
}\<br />
\<br />
## Tabellendefinition\<br />
\<br />
## eingefärbtes Icon 0 % entspricht rot (HSV-Wert 0), 100 % entspricht grün (HSV-Wert 120) mit Direktangabe\<br />
1|ICON("measure_battery_100\@".hsv([bat:level],0,100,0,120,100,100))\<br />
\<br />
## gleiche Funktionalität mit Hilfe der oben definierten Funktion bat_icon \<br />
2|bat_icon([bat:level])\<br />
\<br />
## Icon mit Hilfe der oben definierten Funktion bat_icon2\<br />
3|bat_icon2([bat:level])\<br />
\<br />
## Beispiel für die Farbskaliereung von 0 bis 100 % mit der obigen Funktion bat_icon\<br />
4|bat_icon(0)|bat_icon(10)|bat_icon(20)|bat_icon(30)|bat_icon(40)|bat_icon(50)|bat_icon(60)|bat_icon(70)|bat_icon(80)|bat_icon(90)|bat_icon(100)\<br />
\<br />
## Beispiel für die Farbskaliereung von 0 bis 100 % mit der obigen Funktion bat_icon2\<br />
5|bat_icon2(0)|bat_icon2(10)|bat_icon2(20)|bat_icon2(30)|bat_icon2(40)|bat_icon2(50)|bat_icon2(60)|bat_icon2(70)|bat_icon2(80)|bat_icon2(90)|bat_icon2(100)<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable DOIF hsv.png|mini|ohne]]<br />
<br />
== Eine for-Schleife mit Hilfe des '''FOR'''-Befehls ==<br />
Mit Hilfe des '''FOR'''-Befehls können über eine Schleife aus einer Liste mit Elementen mehrere Tabellenzellen definiert werden. Die Elementenliste (Array) kann über eine Funktion bestimmt werden. Auf diese Weise kann z. B. eine Tabelle für mehrere Geräte einfach definiert werden.<br />
{{Randnotiz|RNText='''FOR-Befehl'''<br />
* Der FOR-Befehl entspricht einer foreach-Schleife in Perl<br />
* Syntax: '''FOR (<Array>,<Zellendefinitionen>)'''<br>'''<Array>''' eine gültige Angabe eines Arrays oder eine Perlfunktion, die ein Array liefert<br>'''<Zellendefinitionen>''' Definition einer oder mehrerer Zellen, die Angabe $_ wird durch das jeweilige Element des Arrays ersetzt<br />
*'''nützliche Links'''<br />
**{{Link2CmdRef|Anker=DOIF_aggregation|Lang=de|Label=DOIF Aggregationsfunktionen mit Perlfunktion AggrDoIf}}<br />
**[[DevelopmentModuleAPI#devspec2array|devspec2array]]<br />
}}<br />
'''<big>Beispieldefinitionen</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## Temperaturen aller Geräte, die mit 'T' beginnen und ein Reading 'temperature' haben, sollen in einer Tabelle visualisiert werden\<br />
FOR(::AggrDoIf('@','^T_','temperature'),"$_"|temp([$_:temperature:d2]))<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR-temperature.png|200px|ohne]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## Anzeige des Batteriestatus aller Geräte, bei denen das Wort 'Fenster' vorkommt, die das Readings 'battery' haben\ <br />
FOR(::AggrDoIf('@','Fenster','battery'),"$_"|bat([$_:battery]))<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR-battery.png|200px|ohne]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## Anzeige des Status aller Geräte im System vom Typ 'HMS'\<br />
FOR(::devspec2array("TYPE=HMS"),"$_"|[$_])<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR-HMS.png|300px|ohne]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## Elemente einer kommagetrennten Liste sollen jeweils in einer Tabellenzelle in einer Tabellenzeile angezeigt werden\<br />
FOR(split(",","Mo,Di,Mi,Do,Fr,Sa,So"),ui_Table::style("$_","Darkorange")|)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR-split.png|300px|ohne]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## Durch Leerzeichen getrennte Zeichenketten sollen jeweils in einer Tabellenzelle in einer Tabellenzeile angezeigt werden\<br />
FOR(qw/Montag Dienstag Mittwoch Donnerstag Freitag/,"$_"|)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR-qw.png|300px|ohne]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## das Templates TPL_raum, soll vier mal aufgerufen werden: TPL_raum(1), TPL_raum(2)...\<br />
## das Templates TPL_raum muss vorher definiert worden sein\<br />
FOR(1..4,TPL_raum($_))<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR TPL raum.png|600px|ohne]]<br />
<br />
== '''Anwendungsbeispiele''' ==<br />
=== '' Visualisierung und Steuerung von '''Rollläden''''' ===<br />
Im folgenden Beispiel werden Rollläden morgens hochgefahren, ebenso wird die Position aller Rollläden visualisiert. Durch Anklicken eines Icons wird der Rollladen auf die entsprechende Position bewegt. <br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* {{Link2CmdRef|Anker=DOIF_Zeitsteuerung_mit_Zeitintervallen|Lang=de|Label=Zeitsteuerung}}<br />
* uiTable-Funktion [[DOIF/uiTable Schnelleinstieg#Rollladen: Visualisierung und Steuerung mit Hilfe der Funktion shutter|shutter]]<br />
* uiTable-Funktion [[DOIF/uiTable Schnelleinstieg#Textformatierungen mit Hilfe der Funktion style|style]]<br />
* [[DOIF/uiTable Schnelleinstieg#uiTable-Templates|Templates]]<br />
}}<br />
<syntaxhighlight lang="perl"><br />
defmod DI_Rollladen DOIF (([Dunkelheit] eq "off" and [06:25-09:00|8]) or [09:00|7]) \<br />
((set R_W_S,R_W_W[1-3] on)) ## Hochfahren der Rollläden im Erdgeschoss morgens\<br />
DOELSEIF ([Dunkelheit] eq "on")<br />
attr DI_Rollladen cmdState oben|unten<br />
attr DI_Rollladen devStateIcon unten:status_night oben:scene_day<br />
attr DI_Rollladen icon fts_shutter_automatic<br />
attr DI_Rollladen uiTable {\<br />
package ui_Table;;\<br />
}\<br />
\<br />
## Template für ein Fenster\<br />
DEF TPL_shutter("$1"|shutter([$1:pct]))\<br />
\<br />
## Tabellendefinition\<br />
\<br />
style("Dachgeschoss","Darkorange")|""\<br />
TPL_shutter(R_Dachboden)\<br />
style("erstes Geschoss","Darkorange")|""\<br />
TPL_shutter(R_Bad)\<br />
TPL_shutter(R_Kinderzimmer1_O)\<br />
TPL_shutter(R_Kinderzimmer1_S)\<br />
TPL_shutter(R_Kinderzimmer2_S)\<br />
TPL_shutter(R_Kinderzimmer2_W1)\<br />
TPL_shutter(R_Kinderzimmer2_W2)\<br />
style("Erdgeschoss","Darkorange")|""\<br />
TPL_shutter(R_Kueche)\<br />
TPL_shutter(R_W_S)\<br />
TPL_shutter(R_W_W1)\<br />
TPL_shutter(R_W_W2)\<br />
TPL_shutter(R_W_W3)\<br />
style("Keller","Darkorange")|""\<br />
TPL_shutter(R_Keller)\<br />
</syntaxhighlight><br />
''Ergebnis des Anwendungsbeispiels in der Webansicht:''<br />
[[Datei:UiTable Rollladen.png|mini|ohne]]<br />
<br />
=== ''Anzahl der Tage bis zur '''Abfall-Entsorgung''''' ===<br />
Mit Hilfe des Kalender-Moduls werden die verbleibenden Tage bis zur Abfall-Entsorgung der jeweiligen Tonne berechnet und mit Hilfe von uiTable visualisiert. Wenn der Tag der Entsorgung bevorsteht, wird er farbig gekennzeichnet. Vorausgesetzt wird die Definition des Kalenders namens 'cal' mit Hilfe des Moduls [[Calendar]]. Dieser muss die Termine der Abfallentsorgung der Tonnen beinhalten. Im Beispiel wird nach Stichwörtern: "Altpapier", "Restmüll", "Bio", "Gelber" und "Grünschnitt" im Kalender gesucht. <br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* FHEM-Modul [[Calendar]]<br />
* ui_Table Funktion [[DOIF/uiTable Schnelleinstieg#Icon-Darstellung mit Text mit Hilfe der Funktion icon_label|icon_label]]<br />
}}<br />
<syntaxhighlight lang="perl"><br />
defmod Abfall DOIF subs {\<br />
## Die Funktion 'days' sucht nach dem Ereignis $event im Kalender und berechnet die Anzahl der verbleibenden Tage und legt sie im entsprechendem Reading $reading des DOIF-Moduls ab\<br />
sub days \<br />
{\<br />
my ($event,$reading)=@_;;\<br />
set_Reading($reading,fhem('get cal events timeFormat:"%j" filter:field(summary)=~"'.$event.'" limit:count=1,from=0 format:custom="$T1"')-::strftime ('%j', localtime()),1)\<br />
}\<br />
## Die Funktion 'update' bestimmt die verbleibenden Tage mit Hilfe der obigen Funktion 'days' für die jeweiligen Tonnen\<br />
sub update\<br />
{\<br />
days("Altpapier","altpapier");;days("Restmüll","restmuell");;days("Bio","bio");;days("Gelber","gelbe_tonne");;days("Grünschnitt","gruenschnitt");;\<br />
}\<br />
}\<br />
## Beim Start, um 02:00 Uhr und 08:00 Uhr wird zeitverzögert die obige Funktion 'update' aufgerufen\<br />
init {[02:00];;[08:00];;set_Exec("Timer",60,'update()');;\<br />
}<br />
attr Abfall uiTable {\<br />
package ui_Table;;\<br />
$TC{0..4}="align='center'";;\<br />
$SHOWNOSTATE=1;;\<br />
\<br />
## die Funktion 'ic' benutzt die Funktion 'icon_label' für die Darstellung des Icons, abhängig von der Anzahl der Tage wird die Anzahl in grün bzw. rot eingefärbt \<br />
sub ic\<br />
{\<br />
my ($icon,$days)=@_;;\<br />
icon_label($icon,$days,"white",$days > 1 ? "green":"red")\<br />
}\<br />
}\<br />
## Tabellendefinition, die einzelnen Tonnen werden mit Hilfe der obigen Funkton 'ic' dargestellt\<br />
\<br />
ic ("Abfalltonne-Recycling-Logo\@yellow",[$SELF:gelbe_tonne])|\<br />
ic ("Abfalltonne-Recycling-Logo\@blue",[$SELF:altpapier])|\<br />
ic ("Abfalltonne\@gray",[$SELF:restmuell])|\<br />
ic ("Abfalltonne-Recycling-Logo\@green",[$SELF:bio])|\<br />
ic ("Gartenabfall\@green",[$SELF:gruenschnitt])<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Anwendungsbeispiel Abfall.png|mini|ohne]]<br />
<br />
=== ''Visualisierung: '''offene Fenster''''' ===<br />
Alle offenen Fenster werden aufgelistet und mit entsprechendem Icon visualisiert.<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* Attribut {{Link2CmdRef|Anker=DOIF_DOIF_Readings|Lang=de|Label=DOIF_Readings}}<br />
* DOIF-{{Link2CmdRef|Anker=DOIF_aggregation|Lang=de|Label=Aggregationsfunktionen}}<br />
* uiTable-Funktion [[DOIF/uiTable Schnelleinstieg#Icon-Darstellung mit Hilfe der Funktion icon|icon]]<br />
}}<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_windows DOIF ## Visualisierung offener Fenster, Fenster-Devices enden mit "Fenster" im Namen<br />
attr di_uiTable_windows DOIF_Readings windows:[@as(<br>)"Fenster$":state:"open","keine"]<br />
attr di_uiTable_windows uiTable {package ui_Table;;}\<br />
icon([$SELF:windows],"fts_window_1w_open\@DarkOrange","fts_window_1w",".*","keine")|[$SELF:windows]<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable windows closed.png|mini|ohne]]<br />
[[Datei:UiTable windows open.png|mini|ohne]]<br />
<br />
=== ''Visualisierung: '''aktuelle Wetterlage''''' ===<br />
Regenrader animiert, aktuelle Temperatur und Feuchte vom Sensor, aktuelle Wetterlage sowie Wettervorhersage der nächsten Tage. Über entsprechende Weblinks werden Bilder aus dem WWW in der Tabelle visualisiert. Im Gegensatz zu lokalen Sensoren, muss für die Aktualisierung der WWW-Elemente in der jeweiligen Webinstanz (FHEMWEB) das refresh-Attribut gesetzt werden. <br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* DWD [https://www.dwd.de/DE/Home/home_node.html Homepage]<br />
* Regenradar [https://www.dwd.de/DE/wetter/wetterundklima_vorort/_node.html Radarfilm BRD]<br />
* aktuelles Wetter [https://www.dwd.de/DE/wetter/wetterundklima_vorort/nordrhein-westfalen/nrw_node.html NRW]<br />
* Wetteronline [https://www.wetteronline.de/wetter-widget eignes Widget]<br />
* <br />
}}<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_wetter DOIF ##<br />
attr di_uiTable_wetter uiTable {\<br />
package ui_Table;;\<br />
$TC{1}="align='center'";;\<br />
}\<br />
## das Attribut 'refresh' der Webinstanz für ein Wandtablet wurde auf 900 gesetzt, damit die Bilder alle 15 Minuten aktualisiert werden \<br />
## Tabellendefinition\<br />
\<br />
## Regenradar BRD\<br />
'<img src="https://www.dwd.de/DWD/wetter/radar/radfilm_brd_akt.gif" height="365px" width="365px">'|\<br />
\<br />
## Aktuelle Temperatur und Feuchtigkeit vom lokalen sensor\<br />
temp([Aussensensor:temperature],40),hum ([Aussensensor:humidity],30),\<br />
\<br />
## aktuelle Wetterlage NRW\<br />
"<img src ='https://www.dwd.de/DE/wetter/wetterundklima_vorort/nordrhein-westfalen/_functions/bildgalerie/wetter_aktuell.jpg?view=nasImage&nn=561200' height='255px' width='255px'>"|\<br />
\<br />
## Wettervorhersage\<br />
"<iframe marginheight='0' marginwidth='0' scrolling='no' width='300' height='365' name='FC3' style='border:1px solid;;border-color:#00537f;;' src='https://api.wetteronline.de/wetterwidget?gid=x0677&modeid=FC3&seourl=juelich&locationname=Jülich&lang=de'></iframe>"\<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable wetter.png|600px|links]]<br />
<br clear="all"><br />
<br />
=== ''Visualisierung: '''Wetterstation''''' ===<br />
Die vorgestellte Lösung funktioniert ohne Anmeldung beim Wetterdienst und ohne Nutzung von API.<br />
Über den Wetterdienst: https://www.wunderground.com/ werden sehr viele private Wifi-Wetterstationen eingebunden. Das kann man sich zunutze machen, indem man zunächst in seiner Umgebung nach Wetterstationen des Dienstes sucht - oft findet man im Umkreis von wenigen Kilometern schon einige Stationen, die rege Wetterdaten liefern. Danach definiert man über HTTPMOD seine Station und visualisiert diese anschließend.<br />
<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* Wunderground [https://wunderground.com/ Homepage]<br />
* svg-Funktion [https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Anzeige_eines_Werteverlaufs_und_des_aktuellen_Wertes_mit_Hilfe_der_SVG-Funktion_card card]<br />
* svg-Funktionen [https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#icon_ring-Funktionen icon_ring]<br />
}}<br />
Definition einer Station in der Nachbarschaft. <StationsID> muss gegen die korrekte Stationsnummer ersetzt werden.<br />
<syntaxhighlight lang="perl"><br />
defmod Wetter HTTPMOD https://www.wunderground.com/dashboard/pws/<StationsID><br />
attr Wetter enableControlSet 1<br />
attr Wetter reading01Name Wind<br />
attr Wetter reading01Regex wu-unit .{109}>(\d+\.\d)<br />
attr Wetter reading02Name Windboeen<br />
attr Wetter reading02Regex wu-unit-speed .{109}>(\d+\.\d)<br />
attr Wetter reading03Name Windrichtung<br />
attr Wetter reading03Regex (\d+)deg\).{84}Wind-Marker<br />
attr Wetter reading04Name Regen<br />
attr Wetter reading04Regex wu-unit-rainRate .{109}>(\d+\.\d\d)<br />
attr Wetter reading05Name RegenGesamt<br />
attr Wetter reading05Regex wu-unit-rain .{109}>(\d+\.\d\d)<br />
attr Wetter reading06Name Temperatur<br />
attr Wetter reading06Regex wu-unit-temperature .{127}>(\d+.\d)<br />
attr Wetter reading07Name Feuchtigkeit<br />
attr Wetter reading07Regex wu-unit-humidity .{109}>(\d\d)<br />
attr Wetter reading08Name UV<br />
attr Wetter reading08Regex UV<.{268}>(\d)<br />
attr Wetter reading09Name Luftdruck<br />
attr Wetter reading09Regex PRESSURE<.{285}>(\d+.\d+)<br />
attr Wetter reading10Name TemperaturGefuehlt<br />
attr Wetter reading10Regex wu-unit is-degree-visible .{109}>(\d+.\d)<br />
attr Wetter reading11Name TaupunktTemp<br />
attr Wetter reading11Regex DEWPOINT.{306}>(\d+.\d)<br />
attr Wetter reading12Name Sonnenstrahlung<br />
attr Wetter reading12Regex Solar radiation<.{549}>(\d+.\d+)<br />
attr Wetter timeout 10<br />
attr Wetter userReadings WindKm {sprintf("%1.1f",ReadingsVal($name,"Wind",0)*1.60934)},\<br />
WindboeenKm {sprintf("%1.1f",ReadingsVal($name,"Windboeen",0)*1.60934)},\<br />
WindrichtungGrad {ReadingsVal($name,"Windrichtung",0)-180},\<br />
RegenMm {ReadingsVal($name,"Regen",0)*25.4},\<br />
RegenGesamtMm {ReadingsVal($name,"RegenGesamt",0)*25.4},\<br />
TemperaturC {sprintf("%1.1f",(ReadingsVal($name,"Temperatur",0)-32)*5/9)},\<br />
TaupunktTempC {sprintf("%1.1f",(ReadingsVal($name,"TaupunktTemp",0)-32)*5/9)},\<br />
LuftdruckHpa {sprintf("%d",ReadingsVal($name,"Luftdruck",0)*33.8639)},\<br />
TemperaturGefuehltC {sprintf("%1.1f",(ReadingsVal($name,"TemperaturGefuehlt",0)-32)*5/9)}<br />
</syntaxhighlight><br />
<br />
Nun erfolgt die Visualisierung der Daten.<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_Wetter_ring DOIF ##<br />
attr di_Wetter_ring uiTable {package ui_Table;;}\<br />
\<br />
icon_temp_hum_ring("temp_outside",[Wetter:TemperaturC],[Wetter:Feuchtigkeit],undef,undef,150)|\<br />
icon_temp_ring ("temp_windchill",[Wetter:TemperaturGefuehltC],undef,undef,150) |\<br />
icon_temp_ring ("temperature_humidity",[Wetter:TaupunktTempC],undef,undef,150) |\<br />
icon_ring2([Wetter:WindKm] > 0 ? "wind".",1,0,0,".[Wetter:WindrichtungGrad]:"no_wind",[Wetter:WindKm],0,50,120,0,"km/h",150,undef,1,[Wetter:WindboeenKm],0,50,120,0,"km/h",undef,1) |\<br />
icon_ring2("weather_rain_gauge",[Wetter:RegenMm],0,10,180,270,"mm/h",150,undef,1,[Wetter:RegenGesamtMm],0,50,180,270,"mm",undef,1)|\<br />
icon_ring2("sani_solar",[Wetter:UV],0,10,100,30,"UV",150,undef,0,[Wetter:Sonnenstrahlung],0,1000,100,30,"Watt/m²",undef,0)|\<br />
icon_ring ("weather_barometric_pressure",[Wetter:LuftdruckHpa],980,1047,0,120,"hPa",0,150)<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable ringwetter.png|600px|links]]<br />
<br clear="all"><br />
<br />
Hier ein Beispiel der Visualisierung mit Verlauf der letzten drei Tage mit Hilfe der svg-Funktion '''card''':<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_Wetter DOIF ##<br />
attr di_Wetter icon weather_wind<br />
attr di_Wetter uiTable {package ui_Table;;}\<br />
## card ($collect,$header,$icon,$min,$max,$minColor,$maxColor,$unit,$func,$decfont,$size,$model,$lightness)\<br />
\<br />
card([Wetter:TemperaturC:col3d],"Außentemperatur","temp_outside",-10,60,undef,undef,"°C",\&temp_hue)|\<br />
card([Wetter:TemperaturGefuehltC:col3d],"gefühlte Temperatur","temp_windchill",-10,60,undef,undef,"°C",\&temp_hue)|\<br />
card([Wetter:TaupunktTempC:col3d],"Taupunkttemperatur","temperature_humidity",-10,60,undef,undef,"°C",\&temp_hue)|\<br />
card([Wetter:Feuchtigkeit:col3d],"Außenfeuchtigkeit","temperature_humidity",0,100,undef,undef,"%",\&hum_hue)|\<br />
card([Wetter:WindKm:col3d],"Wind",[Wetter:WindKm] > 0 ? "wind".",1,0,0,".[Wetter:WindrichtungGrad]:"no_wind",0,30,90,30,"km/h",undef,1)\<br />
card([Wetter:WindboeenKm:col3d],"Windböen","weather_wind",0,30,90,30,"km/h",undef,1)|\<br />
card([Wetter:RegenMm:col3d],"Regen","weather_rain_gauge",0,10,180,270,"mm/h")|\<br />
card([Wetter:RegenGesamtMm:col3d],"Regengesamt","weather_rain_gauge",0,50,180,270,"mm")|\<br />
##card([Wetter:UV:col3d],"UV-Strahlung","sani_solar",0,7,100,30,"UV",undef,0)|\<br />
card([Wetter:Sonnenstrahlung:col3d],"Sonnenstrahlung","sani_solar",0,1000,30,90,"Watt/m²",undef,0)|\<br />
card([Wetter:LuftdruckHpa:col3d],"Luftdruck","weather_barometric_pressure",980,1047,30,90,"hPa",undef,0)<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable svgwetter.png|600px|links]]<br />
<br clear="all"><br />
<br />
Ohne Angabe der Überschrift (undef für $header setzen) lässt sich eine kompaktere Darstellung erzielen:<br />
<br />
[[Datei:UiTable svgwetteroh.png|600px|links]]<br />
<br />
<br clear="all"><br />
<br />
=== ''Visualisierung: '''aktueller Spritpreis''''' ===<br />
Der aktuelle Spritpreis einer Tankstelle wird ermittelt und mit seinem zeitlichen Verlauf visualisiert.<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#ring-Funktionen|ring]]<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#Anzeige_eines_Werteverlaufs_und_des_aktuellen_Wertes_mit_Hilfe_der_SVG-Funktion_card|card]]<br />
* Tankstelle bestimmen [https://www.clever-tanken.de/ Clever tanken]<br />
* Modul [[HTTPMOD]]<br />
}}<br />
<br />
Zunächst wird ein HTTPMOD-Modul für den aktuellen Spritpreis definiert, dabei ist <Stations-ID> durch die ID der Tankstelle zu ersetzen.<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod Tankstelle HTTPMOD http://www.clever-tanken.de/tankstelle_details/<Stations-ID> 300<br />
attr Tankstelle devStateIcon {ui_Table::ring(ReadingsVal("$name","Diesel",0),1.00,1.40,120,0,"Diesel",90,undef,2)." ".ui_Table::ring(ReadingsVal("$name","SuperE5",0),1.10,1.60,120,0,"E5",90,undef,2)}<br />
attr Tankstelle enableControlSet 1<br />
attr Tankstelle event-on-change-reading .*<br />
attr Tankstelle group Spritpreise<br />
attr Tankstelle reading01Name Diesel<br />
attr Tankstelle reading01Regex "current-price-1">(\d.\d{2})<br />
attr Tankstelle reading02Name SuperE5<br />
attr Tankstelle reading02Regex "current-price-2">(\d.\d{2})<br />
attr Tankstelle room Spritpreise<br />
attr Tankstelle timeout 10<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Di uiTable Tankstelle.png|ohne|mini]]<br />
<br />
Visualisierung der Preisentwicklung der letzten 24 Stunden: <br />
<br />
<syntaxhighlight lang="perl"><br />
defmod sprit DOIF ##<br />
attr sprit uiTable {package ui_Table;;}\<br />
card([Tankstelle:Diesel:col24],"Diesel","fuel","1.00","1.40",120,0,"Diesel €",undef,"2",",,1")\<br />
card([Tankstelle:SuperE5:col24],"Super E5","fuel","1.10","1.60",120,0,"Super €",undef,"2",",,1")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Di uiTable sprit.png|ohne|mini]]<br />
<br />
=== ''Visualisierung: '''aktuelle Corona-7-Tage-Inzidenz''''' ===<br />
Die aktuellen Inzidenzwerte werden vom RKI ausgelesen und deren Verlauf visualisiert.<br />
<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#ring-Funktionen|ring]]<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#Anzeige_eines_Werteverlaufs_und_des_aktuellen_Wertes_mit_Hilfe_der_SVG-Funktion_card|card]]<br />
* Modul [[JsonMod]]<br />
}}<br />
<br />
Zunächst wird ein JsonMod Device für das Auslesen der Inzidenzzahlen definiert. Die gewünschten Regionen müssen für eigene Bedürfnisse angepasst werden.<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod RKI7 JsonMod https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_Landkreisdaten/FeatureServer/0/query?where=1%3D1&outFields=last_update,cases7_per_100k,BEZ,BEM,GEN,BL,county&returnGeometry=false&outSR=4326&f=json<br />
attr RKI7 readingList multi(jsonPath("\$.features[?(\@.attributes.GEN in ['Städteregion Aachen', 'Düren', 'Heinsberg'])]"), property('attributes.GEN'), sprintf('%.1f', property('attributes.cases7_per_100k')));;<br />
</syntaxhighlight><br />
<br />
Visualisierung der Inzidenzzahlen der letzten sieben Tage: <br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_corona DOIF ##<br />
attr di_corona uiTable {package ui_Table}\<br />
card([RKI7:Duren:col1w],"Düren","coronavirus",0,200,120,0,"Fälle")|\<br />
card([RKI7:Heinsberg:col1w],"Heinsberg","coronavirus",0,200,120,0,"Fälle")|\<br />
card([RKI7:Stadteregion_Aachen:col1w],"Aachen","coronavirus",0,200,120,0,"Fälle")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:uiTable_Inzidenz.png|600px|links]]<br />
<br />
<br clear="all"><br />
<br />
=== '' Visualisierung und Steuerung: '''Heiztherme''''' ===<br />
Im folgenden Beispiel wurde eine Heiztherme über einen ebus-Adapter in FHEM eingebunden. Die Heizungsdaten werden über MQTT ausgelesen und anschließend visualisiert. Die vorgestellten Visualisierungsbeispiele können ebenso im funktionslosen DOIF mit Hilfe des uiTable-Attriutes auf bereits existierende Readings des eigenen Systems angewendet werden. <br />
<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#icon_ring-Funktionen|icon_ring]]<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#Anzeige_eines_Werteverlaufs_und_des_aktuellen_Wertes_mit_Hilfe_der_SVG-Funktion_card|card]]<br />
* Commandref [https://fhem.de/commandref_DE.html#DOIF_Perl_Modus DOIF Perl-Modus]<br />
* ebus-Adapter [https://ebusd.de/ ebusd]<br />
* ebus-Wiki [[EBUS|ebus]]<br />
}}<br />
<br />
Definition eines MQTT2-Devices für die Kommunikation mit der Therme über einen ebus-Adapter.<br />
<br />
Im diesem Fall wurde eine Vaillanttherme eingebunden, die meisten Readings wurden automatisch vom MQTT2-Server angelegt. Die Anbindung ist gerätespezifisch und unterscheidet sich je nach Gerättyp.<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod vaillant MQTT2_DEVICE ebusd_bai<br />
attr vaillant IODev MQTT2_FHEM_Server<br />
attr vaillant devStateStyle style="text-align:left"<br />
attr vaillant event-on-change-reading .*<br />
attr vaillant group Ebus<br />
attr vaillant icon sani_boiler_temp<br />
attr vaillant jsonMap Status01_0_value:Vorlauf Status01_0_name:0\<br />
Status01_1_value:Ruecklauf Status01_1_name:0\<br />
Status01_2_value:Aussentemp Status01_2_name:0\<br />
Status01_3_value:Warmwasser Status01_3_name:0\<br />
Status01_4_value:WWSpeicher Status01_4_name:0\<br />
Status01_5_value:Pumpenstatus Status01_5_name:0\<br />
Flame_0_value:Flame Flame_0_name:0\<br />
Storageloadpump_percent0_value:Storageloadpump\<br />
FlowTempDesired_temp_value:VorlaufSoll\<br />
Hc1HeatCurve_0_value:HeizKennlinie Hc1HeatCurve_0_name:0\<br />
HolidayEndPeriod_hto_value:FerienEnde\<br />
HolidayStartPeriod_hfrom_value:FerienBeginn\<br />
PumpPower_0_value:PumpenLeistung PumpPower_0_name:0\<br />
PrimaryCircuitFlowrate_uin100_value:Umlaufmenge\<br />
z1DayTemp_tempv_value:TagSolltemp\<br />
z1NightTemp_tempv_value:NachtSolltemp\<br />
FanSpeed_0_value:LuefterDrehzahl FanSpeed_0_name:0\<br />
WaterPressure_pressv_value:Wasserdruck\<br />
z1OpMode_opmode_value:Heizmodus<br />
attr vaillant model eBus_bai_jsonmap<br />
attr vaillant readingList ebusd/bai/PumpHours:.* { json2nameValue($EVENT, 'PumpHours_', $JSONMAP) }\<br />
ebusd/bai/WPPostrunTime:.* { json2nameValue($EVENT, 'WPPostrunTime_', $JSONMAP) }\<br />
ebusd/bai/PowerValue:.* { json2nameValue($EVENT, 'PowerValue_', $JSONMAP) }\<br />
ebusd/bai/StorageExitTemp:.* { json2nameValue($EVENT, 'StorageExitTemp_', $JSONMAP) }\<br />
ebusd/global/version:.* version\<br />
ebusd/global/running:.* running\<br />
ebusd/scan\x5c\x2e08/:.* { json2nameValue($EVENT, 'scan.08_', $JSONMAP) }\<br />
ebusd/scan\x5c\x2e08/id:.* { json2nameValue($EVENT, 'id_', $JSONMAP) }\<br />
ebusd/global/uptime:.* uptime\<br />
ebusd/global/signal:.* signal\<br />
ebusd/scan\x5c\x2e15/:.* { json2nameValue($EVENT, 'scan.15_', $JSONMAP) }\<br />
ebusd/scan\x5c\x2e15/id:.* { json2nameValue($EVENT, 'id_', $JSONMAP) }\<br />
ebusd/bai/FanSpeed:.* { json2nameValue($EVENT, 'FanSpeed_', $JSONMAP) }\<br />
ebusd/bai/PumpPower:.* { json2nameValue($EVENT, 'PumpPower_', $JSONMAP) }\<br />
ebusd/broadcast/vdatetime:.* { json2nameValue($EVENT, 'vdatetime_', $JSONMAP) }\<br />
ebusd/broadcast/outsidetemp:.* { json2nameValue($EVENT, 'outsidetemp_', $JSONMAP) }\<br />
ebusd/bai/DateTime:.* { json2nameValue($EVENT, 'DateTime_', $JSONMAP) }\<br />
ebusd/global/updatecheck:.* updatecheck\<br />
ebusd/bai/DCFTimeDate:.* { json2nameValue($EVENT, 'DCFTimeDate_', $JSONMAP) }\<br />
ebusd/bai/PumpPowerDesired:.* { json2nameValue($EVENT, 'PumpPowerDesired_', $JSONMAP) }\<br />
ebusd/bai/HwcImpellorSwitch:.* { json2nameValue($EVENT, 'HwcImpellorSwitch_', $JSONMAP) }\<br />
ebusd/bai/ReturnTemp:.* { json2nameValue($EVENT, 'ReturnTemp_', $JSONMAP) }\<br />
ebusd/700/HwcStorageTempBottom:.* { json2nameValue($EVENT, 'HwcStorageTempBottom_', $JSONMAP) }\<br />
ebusd/700/HwcTempDesired:.* { json2nameValue($EVENT, 'HwcTempDesired_', $JSONMAP) }\<br />
ebusd/bai/FanPWMSum:.* { json2nameValue($EVENT, 'FanPWMSum_', $JSONMAP) }\<br />
ebusd/bai/HcHours:.* { json2nameValue($EVENT, 'HcHours_', $JSONMAP) }\<br />
ebusd/bai/HoursTillService:.* { json2nameValue($EVENT, 'HoursTillService_', $JSONMAP) }\<br />
ebusd/bai/PumpHwcFlowNumber:.* { json2nameValue($EVENT, 'PumpHwcFlowNumber_', $JSONMAP) }\<br />
ebusd/bai/WP:.* { json2nameValue($EVENT, 'WP_', $JSONMAP) }\<br />
ebusd/700/WaterPressure:.* { json2nameValue($EVENT, 'WaterPressure_', $JSONMAP) }\<br />
ebusd/bai/PrimaryCircuitFlowrate:.* { json2nameValue($EVENT, 'PrimaryCircuitFlowrate_', $JSONMAP) }\<br />
ebusd/bai/Flame:.* { json2nameValue($EVENT, 'Flame_', $JSONMAP) }\<br />
ebusd/bai/Storageloadpump:.* { json2nameValue($EVENT, 'Storageloadpump_', $JSONMAP) }\<br />
ebusd/bai/Status01:.* { json2nameValue($EVENT, 'Status01_', $JSONMAP) }\<br />
ebusd/bai/FlowTempDesired:.* { json2nameValue($EVENT, 'FlowTempDesired_', $JSONMAP) }\<br />
ebusd/700/FrostOverRideTime:.* { json2nameValue($EVENT, 'FrostOverRideTime_', $JSONMAP) }\<br />
ebusd/700/Hc1ActualFlowTempDesired:.* { json2nameValue($EVENT, 'Hc1ActualFlowTempDesired_', $JSONMAP) }\<br />
ebusd/700/Hc1AutoOffMode:.* { json2nameValue($EVENT, 'Hc1AutoOffMode_', $JSONMAP) }\<br />
ebusd/700/Hc1CircuitType:.* { json2nameValue($EVENT, 'Hc1CircuitType_', $JSONMAP) }\<br />
ebusd/700/Hc1HeatCurve:.* { json2nameValue($EVENT, 'Hc1HeatCurve_', $JSONMAP) }\<br />
ebusd/700/HcStorageTempBottom:.* { json2nameValue($EVENT, 'HcStorageTempBottom_', $JSONMAP) }\<br />
ebusd/700/HcStorageTempTop:.* { json2nameValue($EVENT, 'HcStorageTempTop_', $JSONMAP) }\<br />
ebusd/700/HolidayTemp:.* { json2nameValue($EVENT, 'HolidayTemp_', $JSONMAP) }\<br />
ebusd/700/OpMode:.* { json2nameValue($EVENT, 'OpMode_', $JSONMAP) }\<br />
ebusd/700/z1RoomTemp:.* { json2nameValue($EVENT, 'z1RoomTemp_', $JSONMAP) }\<br />
ebusd/700/z1SFMode:.* { json2nameValue($EVENT, 'z1SFMode_', $JSONMAP) }\<br />
ebusd/700/z1OpMode:.* { json2nameValue($EVENT, 'z1OpMode_', $JSONMAP) }\<br />
ebusd/700/Time:.* { json2nameValue($EVENT, 'Time_', $JSONMAP) }\<br />
ebusd/bai/EbusVoltage:.* { json2nameValue($EVENT, 'EbusVoltage_', $JSONMAP) }\<br />
ebusd/bai/extWP:.* { json2nameValue($EVENT, 'extWP_', $JSONMAP) }\<br />
ebusd/bai/FanStarts:.* { json2nameValue($EVENT, 'FanStarts_', $JSONMAP) }\<br />
ebusd/700/z1NightTemp:.* { json2nameValue($EVENT, 'z1NightTemp_', $JSONMAP) }\<br />
ebusd/700/z1DayTemp:.* { json2nameValue($EVENT, 'z1DayTemp_', $JSONMAP) }\<br />
ebusd/700/HolidayStartPeriod:.* { json2nameValue($EVENT, 'HolidayStartPeriod_', $JSONMAP) }\<br />
ebusd/700/HolidayEndPeriod:.* { json2nameValue($EVENT, 'HolidayEndPeriod_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Monday:.* { json2nameValue($EVENT, 'z1Timer.Monday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Tuesday:.* { json2nameValue($EVENT, 'z1Timer.Tuesday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Wednesday:.* { json2nameValue($EVENT, 'z1Timer.Wednesday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Thursday:.* { json2nameValue($EVENT, 'z1Timer.Thursday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Friday:.* { json2nameValue($EVENT, 'z1Timer.Friday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Sunday:.* { json2nameValue($EVENT, 'z1Timer.Sunday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Saturday:.* { json2nameValue($EVENT, 'z1Timer.Saturday_', $JSONMAP) }\<br />
ebusd/bai/PrEnergyCountHc1:.* { json2nameValue($EVENT, 'PrEnergyCountHc1_', $JSONMAP) }\<br />
ebusd/bai/PrEnergyCountHwc1:.* { json2nameValue($EVENT, 'PrEnergyCountHwc1_', $JSONMAP) }\<br />
ebusd/bai/PrEnergySumHc1:.* { json2nameValue($EVENT, 'PrEnergySumHc1_', $JSONMAP) }\<br />
ebusd/bai/PrEnergySumHwc1:.* { json2nameValue($EVENT, 'PrEnergySumHwc1_', $JSONMAP) }\<br />
ebusd/bai/FanHours:.* { json2nameValue($EVENT, 'FanHours_', $JSONMAP) }\<br />
ebusd/bai/HcHours:.* { json2nameValue($EVENT, 'HcHours_', $JSONMAP) }\<br />
ebusd/bai/HwcHours:.* { json2nameValue($EVENT, 'HwcHours_', $JSONMAP) }\<br />
ebusd/bai/HcStarts:.* { json2nameValue($EVENT, 'HcStarts_', $JSONMAP) }\<br />
ebusd/bai/HwcStarts:.* { json2nameValue($EVENT, 'HwcStarts_', $JSONMAP) }<br />
attr vaillant setList HeizKennlinie:selectnumbers,0,.1,2,1,lin ebusd/700/Hc1HeatCurve/set $EVTPART1\<br />
TagSolltemp:selectnumbers,15,1,25,1,lin ebusd/700/z1DayTemp/set $EVTPART1\<br />
NachtSolltemp:selectnumbers,15,1,25,1,lin ebusd/700/z1NightTemp/set $EVTPART1<br />
</syntaxhighlight><br />
<br />
Definition eines DOIF-Devices zur Steuerung der Therme und Visualisierung der Daten. Es werden Readings und Befehle genutzt, die durch den MQTT2-Server der obigen Definition zur Verfügung gestellt werden. Einzelne Heizungswerte werden in bestimmten Intervallen über den publish-Befehl ausgelesen. Die Temperaturen der Zirkulation, des Vorlaufs und des Rücklaufs werden außerhalb der Therme mit 1-wire-Temperatursensoren über WLAN-ESP-Easy ausgelesen. Die Definition des Layouts über das Attribut uiTable ist unabhängig vom Auslesen der Werte, sie bezieht sich lediglich auf vorhandene Readings, die visualisiert werden sollen. Das Layout kann ebenso auf Readings aus anderen Devices der eigenen FHEM-Umgebung anpasst werden.<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_vaillant DOIF ##{[+00:01];;foreach (qw(FanSpeed Flame PumpPower Storageloadpump PrimaryCircuitFlowrate FlowTempDesired PumpHours HcHours HcPumpStarts)) {fhem_set("MQTT2_FHEM_Server publish ebusd/bai/$_/get")}}\<br />
\<br />
{[+[1]:01];;foreach (qw(PrEnergySumHc1 PrEnergySumHwc1 HcHours HwcHours z1OpMode WaterPressure z1NightTemp z1DayTemp Hc1HeatCurve HwcLockTime HolidayStartPeriod HolidayEndPeriod)) {fhem_set("MQTT2_FHEM_Server publish ebusd/bai/$_/get")}\<br />
}\<br />
\<br />
{[+00:00:30];;foreach (qw(Flame PrimaryCircuitFlowrate)) {fhem_set("MQTT2_FHEM_Server publish ebusd/bai/$_/get")}}\<br />
\<br />
{[00:01];;foreach (qw(FanHours HcStarts HwcStarts )) {fhem_set("MQTT2_FHEM_Server publish ebusd/bai/$_/get")}\<br />
set_Reading("gesamt_hc",int([?vaillant:PrEnergySumHc1_0_value]/10000)/10,0);;\<br />
set_Reading("gesamt_hwc",int([?vaillant:PrEnergySumHwc1_0_value]/10000)/10,0);;\<br />
set_Reading("diff_hc",0,1);;\<br />
set_Reading("diff_hwc",0,1);;\<br />
set_Reading("diff_h",0,1)\<br />
}\<br />
\<br />
{if ([00:05|WE]) {fhem_set("MQTT2_FHEM_Server publish ebusd/700/BankHolidayStartPeriod/set $mday.$month.$year");;fhem_set("MQTT2_FHEM_Server publish ebusd/700/BankHolidayEndPeriod/set $mday.$month.$year")}}\<br />
\<br />
Timer {\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Monday/set 04:00;;09:00;;13:00;;22:00;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Tuesday/set 04:00;;09:00;;13:00;;22:00;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Wednesday/set 04:00;;09:00;;13:00;;22:00;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Thursday/set 04:00;;09:00;;13:00;;22:00;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Friday/set 04:00;;09:00;;13:00;;22:00;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Sunday/set 05:00;;10:00;;12:00;;22:30;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Saturday/set 05:00;;10:00;;12:00;;22:30;;-:-;;-:-"\<br />
}\<br />
\<br />
diff {\<br />
set_Reading("diff_hc",int(([vaillant:PrEnergySumHc1_0_value]/100000-get_Reading("gesamt_hc",0))*10)/10,1);;\<br />
set_Reading("diff_hwc",int(([vaillant:PrEnergySumHwc1_0_value]/100000-get_Reading("gesamt_hwc",0))*10)/10,1);;\<br />
set_Reading("diff_h",get_Reading("diff_hc")+get_Reading("diff_hwc"),1);;\<br />
}\<br />
\<br />
<br />
attr di_vaillant event-on-change-reading .*<br />
attr di_vaillant room Ebus<br />
attr di_vaillant uiTable {\<br />
package ui_Table;;\<br />
$TABLE='text-align:center;;';;\<br />
$SHOWNODEVICELINE = "test9|Damian";;\<br />
}\<br />
icon_temp_ring("temp_outside",[vaillant:Aussentemp],-15,40,130)|\<br />
icon_temp_mring(([vaillant:Flame] eq "off"?"sani_boiler_temp\@white":"sani_boiler_temp\@Darkorange"),[vaillant:Vorlauf],15,70,130)|\<br />
icon_temp_mring(([vaillant:Pumpenstatus] eq "4" ? "sani_buffer_temp_down\@Darkorange" : "sani_buffer_temp_down\@white"),[vaillant:WWSpeicher],15,70,130)|\<br />
icon_uring("0,0,1","weather_barometric_pressure",[vaillant:Wasserdruck],0,3,undef,undef,"bar",1,130,[(0.8,0,1,60,1.5,120,1.7,60,3,0)],"50,35")|\<br />
icon_ring("sani_floor_heating_neutral",[vaillant:HcHours_hoursum2_value],0,10000,120,0,"h",0,130)|\<br />
icon_ring("sani_water_tap",[vaillant:HwcHours_hoursum2_value],0,2000,120,0,"h",0,130)|\<br />
\<br />
icon_ring("time_graph",[vaillant:HeizKennlinie],0.4,1,120,0,"HK",1,130)|\<br />
icon_temp_mring("scene_day\@yellow",[vaillant:TagSolltemp],undef,undef,130)|\<br />
icon_temp_mring("scene_night\@#3464eb",[vaillant:NachtSolltemp],undef,undef,130)\<br />
""|""|""|""|""|""|widget([vaillant:HeizKennlinie],"selectnumbers,0.4,.1,1,1,lin","set")|widget([vaillant:TagSolltemp],"selectnumbers,15,1,25,1,lin","set")|widget([vaillant:NachtSolltemp],"selectnumbers,15,1,25,1,lin","set")<\<br />
\<br />
card([vaillant:Aussentemp:col],"Außentemperatur","temp_outside",-15,35,undef,undef,"°C",\&temp_hue)|\<br />
card([vaillant:WWSpeicher:col],"WW-Speicher",([vaillant:Pumpenstatus] eq "4" ? "sani_buffer_temp_down\@Darkorange" : "sani_buffer_temp_down\@white"),15,70,undef,undef,"°C",\&temp_hue)|\<br />
card([ESPEasy_ESP_Temp_Vorlauf:Temperature:col],"Vorlauf",([vaillant:Pumpenstatus] eq "on" ? "sani_floor_heating\@Darkorange" : "sani_floor_heating_neutral\@white"),15,70,undef,undef,"°C",\&temp_hue)|\<br />
card([$SELF:diff_hc:col],"Energie Heizung","sani_floor_heating_neutral",0,100,120,0,"kWh",undef,1)\<br />
card([vaillant:Umlaufmenge:col],"Umlaufmenge","sani_pump",0,20,120,0,"l/min")|\<br />
card([ESPEasy_ESP_Temp_Zirkulation:Temperature:col],"Zirkulation",([Zirk] eq "off"?"sani_pump\@white":"sani_pump\@Darkorange"),15,70,undef,undef,"°C",\&temp_hue)|\<br />
card([ESPEasy_ESP_Temp_Keller_Ruecklauf:Temperature:col],"Rücklauf","sani_floor_heating_neutral\@wite",15,70,undef,undef,"°C",\&temp_hue)|\<br />
card([$SELF:diff_hwc:col],"Energie Warmwasser","sani_water_tap",0,15,120,0,"kWh",undef,1)<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Di uiTable Heizung.png|600px|links]]<br />
<br />
<br clear="all"><br />
<br />
=== ''Visualisierung: '''Anwesenheitsstatus''''' ===<br />
Die aktuelle Anwesenheit von Heimbewohnern wird visualisiert.<br><br><br />
Zunächst wird mit Hilfe des Moduls [[FRITZBOX]] ein Device namens ''FritzBox'' erstellt. Dort werden die eingebuchten Smartphones der Bewohner mit Ihren MAC-Adressen in Readings abgelegt. Die folgende Definition wertet aus, ob die angegebenen MAC-Adressen als Readings vorhanden sind und erstellt für jeden Bewohner ein Reading mit den Zuständen on/off. Diese Readings werden dann über das Attribut uiTable visualisiert. Die anwesenden Personen werden farblich markiert. Die Namen der Personen sowie die MAC-Adressen sind fiktiv und müssen den eigenen Angaben entsprechend angepasst werden.<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* [[FRITZBOX|FritzBox-Modul]]<br />
* ui_Table Funktion [[DOIF/uiTable Schnelleinstieg#Icon-Darstellung mit Text mit Hilfe der Funktion icon_label|icon_label]]<br />
*[[DOIF/uiTable Schnelleinstieg#uiTable-Templates|uiTable-Templates]]<br />
}}<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod myHome DOIF {\<br />
set_Reading_Begin;;\<br />
set_Reading_Update("Ernie",[FritzBox:mac_12_34_E0_00_CD_E4] ? "on":"off");;\<br />
set_Reading_Update("Bert", [FritzBox:mac_02_08_02_07_30_E3] ? "on":"off");;\<br />
set_Reading_Update("Grobi", [FritzBox:mac_00_08_01_0B_00_E7] ? "on":"off");; \<br />
set_Reading_Update("Kermit", [FritzBox:mac_01_30_A9_72_02_E3] ? "on":"off");; \<br />
set_Reading_End(1);;\<br />
}<br />
attr myHome checkReadingEvent 0<br />
attr myHome uiTable {\<br />
package ui_Table;;\<br />
$SHOWNOSTATE=1;;\<br />
$TC{0..4}="align='center'";;\<br />
}\<br />
## Template-Definition für die Visualisierung eines Bewohners mit Hilfe des Icons fa__508\<br />
DEF TPL_person (icon_label([$SELF:$1] eq "on" ? "fa__508\@DarkOrange":"fa__508","$1","#e67e00","white",-10))\<br />
\<br />
## Darstellung der Bewohner mit Hilfe des obigen Templates\<br />
TPL_person(Ernie)|TPL_person(Bert)|TPL_person(Grobi)|TPL_person(Kermit)<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable myHome.png|ohne|mini]]<br />
<br />
=== Weitere Anwendungsbeispiele zur Automatisierung ===<br />
* siehe [[DOIF/Automatisierung]]<br />
<br />
== Weiterführende Links ==<br />
* Weitere Beispiele für Fortgeschrittene, siehe "[[DOIF/uiTable|uiTable mit FHEM-Widgets und Styles]]"<br />
<br />
[[Kategorie:HOWTOS]]<br />
[[Kategorie:Code Snippets]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=DOIF/uiTable_Schnelleinstieg&diff=37169DOIF/uiTable Schnelleinstieg2022-01-30T11:32:39Z<p>Andies: /* Farbskalierte Anzeige eines Zahlenwertes mit Hilfe der universellen SVG-Funktion ring */ crossRef erläutert, Forum verlinkt</p>
<hr />
<div>[[Datei:UiTable state screen.png|700px|rechts|Webansicht bestehend aus mehreren DOIF/uiTable-Definitionen]]<br />
An dieser Stelle wird das DOIF-Web-Interface erklärt, welches über das DOIF-Attribut '''uiTable''' realisiert wurde. <br />
<br />
Abhängig von der Art der Funktion können in einer tabellarischen Darstellung FHEM-Geräte visualisiert und über die Web-Oberfläche bedient werden. Eventbasierte Änderungen visualisierter Readings werden unmittelbar in der Web-Ansicht aktualisiert. Eine erstellte Tabelle erscheint unterhalb der Statuszeile eines DOIF-Devices. Das uiTable-Attribut kann in bereits bestehenden DOIFs oder in funktionslosen DOIFs, wie in den unteren Beispielen, als reines WEB-Interface erstellt werden. In der Abbildung rechts ist ein Statusbildschirm aus vier Spalten mit mehreren DOIF/uiTable-Definitionen aufgebaut worden.<br><br />
<br />
Die Darstellungsmöglichkeiten werden anhand von Beispielen insb. mit Hilfe bereits im DOIF-Modul vordefinierter uiTable-Funktionen aufgezeigt. Diese Perlfunktionen sind in einem eigenen Package namens 'ui_Table' definiert worden. Mit Hilfe dieser Funktionen lassen sich recht einfach, ohne tiefere HTML/CSS-Kenntnisse, eigene Übersichten definieren. Im Anschluss werden typische '''[[DOIF/uiTable Schnelleinstieg#Anwendungsbeispiele|Anwendungsbeispiele]]''' aufgezeigt.<br />
<br />
Die folgenden Beispieldefinitionen arbeiten mit konkreten Geräten und Readings, sie können als RAW-Definition ins eigene System übernommen werden, dazu müssen die Gerätenamen, Readings, ggf. auch Icons den existierenden Namen des eigenen Systems angepasst werden. Zum Ausprobieren der Beispiele können statt echter Geräte auch Dummys benutzt werden. <br />
<br />
Es gibt im Perl-Modus des DOIF-Moduls ebenfalls das Attribut '''uiState''', welches die gleiche Syntax wie uiTable nutzt. Die definierte Tabelle erscheint im Gegensatz zu uiTable jedoch im Status des DOIF-Devices. uiState und uiTable können gleichzeitig in einem DOIF-Device definiert werden. <br />
<br />
== Aufbau des uiTable-Attributs ==<br />
Im uiTable-Attribut wird in erster Linie die zu visualisierende Tabelle definiert. Optional können zuvor ein Perlblock sowie Templates definiert werden.<br />
{{Randnotiz|RNText='''Aufbau des Attributs'''<br />
* das uiTable-Attribut besteht aus drei Bereichen:<br />
* [[DOIF/uiTable Schnelleinstieg#Der Perlblock|Perlblock]]<br />
* [[DOIF/uiTable Schnelleinstieg#uiTable-Templates|Templates-Definitionen]] <br />
* [[DOIF/uiTable Schnelleinstieg#Die Tabellendefinition|Tabellendefinition]]<br />
}}<br />
'''Aufbaustruktur''' <br />
<syntaxhighlight lang="perl"><br />
{<br />
<Perlblock, optional><br />
}<br />
<br />
<Templates-Definitionen, optional><br />
<br />
<Tabellendefinition><br />
</syntaxhighlight><br />
=== Der Perlblock ===<br />
Der Perlblock dient dazu, das Layout der Tabelle zu beeinflussen sowie eigene uiTable-Funktionen zu definieren. Hier wird insb. das Package definiert, welches für die Tabellendefinition gilt. Ebenfalls können CSS-Variablen sowie Steuerungsattribute gesetzt werden. Der Perlblock beginnt und endet mit einer geschweiften Klammer.<br />
<br />
==== CSS-Variablen und Steuerungsattribute ====<br />
Mit Hilfe von CSS-Variablen kann das Layout der Tabelle beeinflusst werden. Die Steuerungsattribute beeinflussen die Statuszeile sowie die Detailansicht des DOIF-Moduls.<br />
{{Randnotiz|RNText='''CSS-Variablen und Steuerungsattribute'''<br />
*Das Layout der gesamten Tabelle wird beeinflusst über die Variablendefinition: '''$TABLE="<CSS-Attribute der Tabelle>"'''<br />
*Spaltenformatierungen werden beeinflusst mit Hilfe der Variablendefinition: '''$TC{<Zellenbereich für Spalten>}="<CSS-Attribute der Spalten>"''' <br />
*Zeilenformatierungen werden beeinflusst mit Hilfe der Variablendefinition: '''$TR{Zeilenbereich}="<CSS-Attribute der Zeilen>"'''<br />
*einzelne Zellen werden beeinflusst mit Hilfe der Variablen: '''$TD{<Zellenbereich für Zeilen>}{<Zellenbereich für Spalten>}="<CSS-Attribute der Zellen>"'''<br />
*für Zellen-, Spalten- und Zeilen-Bereich gilt: '''<Zahl><nowiki>|</nowiki><kommagetrennte Aufzählung><nowiki>|</nowiki><Bereich von..bis>'''<br />
*Der Status in der Statuszeile des DOIFs wird ausgeblendet mit '''$SHOWNOSTATE=1'''<br />
*Die Gerätezeile des DOIFs wird ausgeblendet mit '''$SHOWNODEVICELINE = "<regex room>"'''<br />
*Die Tabelle des DOIFs wird ausgeblendet mit '''$SHOWNOUITABLE = "<regex room>"'''<br />
*Die Detailansicht wird umorganisiert mit '''$ATTRIBUTESFIRST=1'''<br />
}}<br />
'''Bespieldefinition'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_bsp_layout DOIF ##<br />
attr di_bsp_layout uiTable { ## Beginn des Perlblocks\<br />
## CSS-Variablen\<br />
\<br />
## Die Tabelle soll ein Hintergrundbild der Größe 300x300 Pixel haben\<br />
$TABLE = "width:300px;; height:300px;; background-image:url(/fhem/www/pgm2/images/Grundriss.png);; background-size: 300px 300px;;";;\<br />
\<br />
## die Zelle der ersten Zeile und der ersten Spalte soll rechts eine Rahmenlinie haben\<br />
$TD{0}{0} = "style='border-right-style:solid;; border-right-width:10px'";;\<br />
\<br />
## Die erste Zeile soll aus der Klasse 'odd' sein und fett-Schrift haben\<br />
$TR{0} = "class='odd' style='font-weight:bold'";;\<br />
\<br />
## die Spalten 2 bis 6 sollen zentriert sein\<br />
$TC{1..5} = "align='center'";;\<br />
\<br />
## die Spalten 2, 4 und 5 sollen zentriert sein\<br />
$TC{1,3,5} = "align='center'";;\<br />
\<br />
## die letzte Spalte der Tabelle soll fett sein\<br />
$TC{last} = "style='font-weight:bold'";;\<br />
\<br />
\## Steuerungsattribute\<br />
\<br />
\## Ausblenden des Status in der Statuszeile\<br />
$SHOWNOSTATE=1;;\<br />
\<br />
## Die Gerätezeile wird ausgeblendet in allen Räumen\<br />
$SHOWNODEVICELINE = ".*";;\<br />
\<br />
## Die Tabelle wird im Raum info ausgeblendet\<br />
$SHOWNOUITABLE = "^info$";;\<br />
\<br />
## Die Detailansicht wird umorganisiert, hilfreich beim Editieren längerer uiTable-Definitionen\<br />
$ATTRIBUTESFIRST = 1;;\<br />
} ## Ende des Perlblocks<br />
</syntaxhighlight><br />
<br />
=== Die Tabellendefinition ===<br />
==== Einfache Tabellendefinition ohne Funktionen ====<br />
{{Randnotiz|RNText='''Tabellendefinition'''<br />
* eine Tabelle wird aus Zellen zusammengebaut<br />
* mehrere Zellen werden mit <nowiki>|</nowiki> von einander getrennt, sie bilden eine Tabellenzeile<br />
* eine neue Tabellenzeile beginnt mit einer neuen Zeile in der Tabellendefinition<br />
* eine Tabellenzeile kann auch in mehreren Zeilen definiert werden, diese müssen dann mit <nowiki>|</nowiki> enden<br />
* Texte werden in Anführungszeichen angegeben<br />
* Readings werden in der Form [<device>:<reading>] angegeben<br />
* Kommentare beginnen mit ## und enden mit Zeilenende<br />
* Events eines definierten Readings, führen sofort zu Aktualisierung seines Inhalts in der visualisierten Tabelle<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod ui_Table_definition DOIF ##<br />
attr ui_Table_definition uiTable { ## Perlblock für globale Tabellendefinitionen\<br />
\<br />
$TC{1..2}="align='center'" ## zentrierte Ausrichtung der zweiten und dritten Spalte\<br />
\<br />
}\<br />
\<br />
## Tabellendefinition\<br />
\<br />
"Warmwasser"|"Vorlauf"|"Rücklauf" ## erste Tabellenzeile\<br />
## zweite Tabellenzeile\<br />
[T_Warmwasserspeicher:temperature]| ## Zeile wird fortgesetzt, da sie mit | endet\<br />
[T_Vorlauf:temperature]| ## Zeile wird fortgesetzt, da sie mit | endet\<br />
[T_Ruecklauf:temperature]<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable Definition.png|mini|ohne]]<br />
<br />
==== Tabellendefinition mit Berechnungen ====<br />
{{Randnotiz|RNText='''Zellenauswertung'''<br />
* jede Zelle der Tabelle wird über Perl ausgewertet<br />
* Readingangaben der Form [<device>:<reading>] werden in eine Perlfunktion übersetzt<br />
* das Ergebnis des ausgewerteten Perlausdrucks wird ausgegeben<br />
* in einer Zelle können beliebige Perlfunktionen genutzt werden<br />
* Texte oder Funktionen können mit Punkt aneinander gehängt werden<br />
* mit Komma werden Texte oder Werte untereinander dargestellt<br />
* wird eine Zeile mit < abgeschlossen, so wird die aktuelle Tabelle abgeschlossen, die nächste Zeile beginnt in einer neuen Tabelle<br />
* in einer Berechnung sollte ein Trigger in Form einer Readingangabe [<device>:<reading>] vorkommen, sonst wäre das Ergebnis statisch und würde sich nicht ändern <br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_calc DOIF ##<br />
attr di_uiTable_calc uiTable ## Tabellendefinition\<br />
"Differenz"|[T_Ruecklauf:temperature]-[T_Vorlauf:temperature]\<br />
"Minimum"|minNum([TH_WZ_HM:measured-temp],[TH_Keller_HM:measured-temp])\<br />
"Durchschnitt"|([T_Ruecklauf:temperature]+[T_Vorlauf:temperature])/2<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable calc.png|mini|ohne]]<br />
<br />
== Vordefinierte uiTable-Funktionen ==<br />
Typische Widgets bzw. Styles wurden als Perl-Funktionen im package ui_Table für eine einfache Tabellendefinition programmiert. Im folgenden wird näher auf die einzelnen uiTable-Funktionen eingegangen.<br />
<br />
=== FHEM-Widgets mit der Funktion '''widget''' ===<br />
Alle in FHEM vorhanden Widgets können mit Hilfe der Perlfunktion '''widget''' genutzt werden. Bei häufiger Nutzung eines bestimmten Widgets bietet sich alternativ die Definition einer uiTable-Funktion (Typ 3) mit dem jeweiligen Widget an, siehe: [[DOIF/uiTable Schnelleinstieg#Eigene uiTable-Funktionen programmieren|uiTable-Funktion]]<br />
{{Randnotiz|RNText=Funktion '''widget'''<br />
<syntaxhighlight lang="perl"><br />
widget(<Reading>,$fhem_widget,$set)<br />
<br />
Reading # [<device>:<reading>]<br />
$fhem_widget # Angabe des FHEM-Widgets<br />
$set # optional, undef zum Setzen beliebiger Readings (entspricht setreading), "set" wenn das Reading per set-Befehl gesetzt wird (siehe Attribut ReadingList), "set <Befehl>", wenn sich der Befehl vom Reading unterscheidet, default undef<br />
</syntaxhighlight><br />
<br />
'''nützliche Links'''<br />
* [[FHEMWEB/Widgets|Fhem-Widgets]]<br />
* Fhem-Widgets als [[DOIF/uiTable Schnelleinstieg#Eigene uiTable-Funktionen programmieren|uiTable-Funktion]]<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_widget DOIF ##<br />
attr di_uiTable_widget uiTable ## FHEM-Widgets mit Hilfe der WID-Funktion\<br />
{package ui_Table}\<br />
"Widget"\<br />
"Select"| widget([uhr:wochentag],"select,Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag,Sonntag")\<br />
"Selectnumbers"| widget([motor:spannung],"selectnumbers,0,0.5,12,1,lin")\<br />
"Slider"| widget([bla:wert],"slider,0,5,100,1")\<br />
"Colorpicker RGB"| widget([Lampe:farbe],"colorpicker,RGB")\<br />
"Colorpicker HSV"| widget([Lampe:farbe],"colorpicker,HSV")\<br />
"Colorpicker CT"| widget([Lampe:waerme],"colorpicker,CT,2000,10,6500")\<br />
"Colorpicker HUE"| widget([Lampe:farbe],"colorpicker,HUE,0,1,359")\<br />
"Colorpicker BRI"| widget([Lampe:helligkeit],"colorpicker,BRI,0,1,100")\<br />
"Time"| widget([start:zeit],"time")\<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable WID.png|mini|ohne]]<br />
<br />
=== SVG-uiTable-Funktionen ===<br />
SVG-uiTable-Funktionen sind skalierbare Widgets, die auf SVG-Elementen basieren. Bei allen SVG-Funktionen für Temperatur bzw. Feuchtigkeit wird die Einfärbung abhängig vom Temperatur- bzw. Feuchtigkeitswert mit Hilfe einer Zuordnungsfunktion bestimmt.<br />
<br />
==== '''ring'''-Funktionen ====<br />
===== Farbskalierte Temperaturanzeige mit Hilfe der SVG-Funktionen '''temp_ring/temp_mring''' =====<br />
Die Farbe der dargestellten Temperatur ist abhängig vom Temperaturwert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''temp_mring'''-SVG-Funktion wird der Ring einfarbig dargestellt.<br />
<br />
Farbskalierung der '''temp_ring'''-SVG-Funktion:<br />
[[Datei:Farbskalierung temp_ring_scaling.png|600px|ohne]]<br />
<br />
Farbskalierung der '''temp_mring'''-SVG-Funktion:<br />
[[Datei:Farbskalierung temp_mring_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''temp_ring/temp_mring'''<br />
<syntaxhighlight lang="perl"><br />
temp_ring/temp_mring ($temp_value,$temp_min,$temp_max,$sizeHalf, $lightring,$lightnumber,$decFont) <br />
<br />
$temp_value # Temperatur<br />
$temp_min, # minimale Temperatur, optional, default=-20<br />
$temp_max, # maximale Temperatur, optional, default=60<br />
$sizeHalf # "<size>,<half ring>" size: Größe der Grafik, optional, default = 80, half ring: 1 für Halbring<br />
$lightring, # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_temp_ring DOIF ##<br />
attr di_temp_ring uiTable {package ui_Table}\<br />
"außen (standard)"|temp_ring([Aussensensor:temperature])\<br />
"Warmwasser (größer,aufgehellt,Normalschrift)" |temp_mring([vaillant:WWSpeicher],15,70,110,90,100,"1,font-weight:normal")\<br />
"Vorlauf (größer)"| temp_mring([ESPEasy_ESP_Temp_Vorlauf:Temperature],15,45,100)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:temp_ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Feuchtigkeitsanzeige mit Hilfe der SVG-Funktionen '''hum_ring/hum_mring''' =====<br />
Die Farbe der dargestellten Feuchtigkeit ist abhängig vom Feuchtigkeitswert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''hum_mring'''-SVG-Funktion wird der Ring einfarbig dargestellt.<br />
<br />
Farbskalierung der '''hum_ring'''-SVG-Funktion: <br />
[[Datei:Farbskalierung hum_ring_scaling.png|600px|ohne]]<br />
<br />
Farbskalierung der '''hum_mring'''-SVG-Funktion:<br />
[[Datei:Farbskalierung hum_mring_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''hum_ring/hum_mring'''<br />
<syntaxhighlight lang="perl"><br />
hum_ring/hum_mring ($hum_value,$sizeHalf,$lightring,$lightnumber,$decFont) <br />
$hum_value # Feuchtigkeit<br />
$sizeHalf # "<size>,<half ring>" size: Größe der Grafik, optional, default = 80, half ring: 1 für Halbring<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_hum_ring DOIF ##<br />
attr di_hum_ring room test2<br />
attr di_hum_ring uiTable {package ui_Table}\<br />
"klein ohne Farbverlauf"|hum_mring([Aussensensor:humidity],60)\<br />
"normal groß mit Farbverlauf"|hum_ring([Aussensensor:humidity])\<br />
"groß ohne Farbverlauf aufgehellt"|hum_mring([Aussensensor:humidity],100,80)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:hum_ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige eines Zahlenwertes mit Hilfe der universellen SVG-Funktion '''ring''' =====<br />
Die Farbe des dargestellten Wertes kann abhängig vom Wert bestimmt werden. Dabei wird die Farbe mit Anleihen aus dem [https://de.wikipedia.org/wiki/HSV-Farbraum HSV-Farbraum] bestimmt. Dieser Farbraum benötigt eigentlich drei Werte, wobei die erste den Farbton (hue) bestimmt; hier wird nur dieser Wert verwendet (Sättigung und Hellwert sind nicht einstellbar). Der Farbton geht von rot (hue-Wert = 0) über gelb (hue-Wert = 60), dann grün (hue-Wert = 120) und blau (hue-Wert = 240) zurück zu rot (hue-Wert = 360), siehe dazu auch die [https://de.wikipedia.org/wiki/HSV-Farbraum#/media/Datei:HueScale.svg Farbtontafel] auf der Wikipedia-Seite.<br />
Die unten $colorRef genannte Funktion kann zum Beispiel in der Tabelle selbst definiert werden, beispielsweise kann man in dem device &onoff_hue verwenden, wenn man es vorab definiert (siehe [https://forum.fhem.de/index.php/topic,120088.msg1204341.html#msg1204341 Link zum Forum]):<blockquote><syntaxhighlight lang="perl"><br />
attr <ui device Name> {<br />
package ui_Table;<br />
sub onoff_hue {<br />
my($redblue)=@_;<br />
return ($redblue == 0 ? 240 : 0); <br />
}<br />
## Tabellendefinition<br />
...<br />
}<br />
</syntaxhighlight></blockquote>{{Randnotiz|RNText=SVG-uiTable-Funktion '''ring'''<br />
<syntaxhighlight lang="perl"><br />
ring ($value,$min,$max,$minColor,$maxColor,$unit, $sizeHalf,$colorRef,$decFont,$model,$lightness)<br />
<br />
$value # darzustellender Wert<br />
$min # minimaler Wert, optional, default=0<br />
$max # maximaler Wert, optional, default=100<br />
$minColor # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$sizeHalf # "<size>,<half ring>" size: Größe der Grafik, optional, default = 100, half ring: 1 für Halbring<br />
$colorRef # Referenz auf eine Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, oder eine Referenz auf eine Arrayliste mit Grenzwerten und Farben, optional, default = undef<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$model # '<Farbverlauf>,<Min/Max>,<Innenring>,<Zeigerstärke>,<Modus>',<br />
# Farbverlauf: 1 für monochrom, <br />
# Min/Max: Style-SVG-Attribute oder 1 zum Anzeigen der Min-/Maxwerte,<br />
# Innenring: Style-SVG-Attribute oder 1 zum Anzeigen des Innenringes, Zeigerstärke: in Pixel,<br />
# Zeigerstärke: Breite des Zeigers,<br />
# Modus: 0 Standard Min-Max, 1 Min-Null-Max, 2 Null-Min/Max,<br />
# alle Parameter sind optional, default keine Angaben: ',,,,,'<br />
$lightness # Helligkeit einzelner Elemente (0-100) "<ring>,<inner ring>,<minMax>,<unit>,<value>", optional, default: "50,50,50,40,50"<br />
</syntaxhighlight><br />
Wird '''$colorFunc''' nicht angegeben, so wird der Farbwert zwischen '''$minColor''' und '''$maxColor''' linear interpoliert<br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_ring DOIF (1)<br />
attr di_ring room test20,test5<br />
attr di_ring uiTable {package ui_Table;; \<br />
$SHOWNOSTATE=1}\<br />
## von 0 bis 20 in Farben von grün (hue:120) bis rot (hue:0)\<br />
"Umlaufmenge"|ring([heating:pump],0,20,120,0,"l/min",100)\<br />
\<br />
## von 0 bis 3 in Farben von rot (hue:0) bis türkis (hue:180), eine Nachkommastelle, Schriftgröße 170%\<br />
## Innenring mit Min-, Max-Beschriftung\<br />
"Wasserdruck"|ring([heating:pressure],0,3,0,180,"bar",100,undef,"1,font-size:170%,fill:silver;;font-size:50%","0,1,1")\<br />
\<br />
## Temperaturdarstellung, entspricht dem Funktionsaufruf:\<br />
## temp_ring ([outdoor:temperature],-20,60,100,"1,font-weight:normal;;font-size:140%")\<br />
## Eine Nachkommastelle, Normalschrift, Schriftgröße 140%\<br />
"Temperatur"|ring([outdoor:temperature,-20,60,undef,undef,"°C",100,\&temp_hue,"1,font-weight:normal;;font-size:140%")\<br />
\<br />
## Lufdruck als Halbring\<br />
"Luftdruck"|ring([weather:barometer],970,1045,30,90,"hPa","100,1",undef,0)\<br />
\<br />
## Co2 als Halbring, Farbgebung als Array mit drei Bereichen, Innenring mit Zeiger\<br />
"Co2"|ring([livingroom:co2],400,1200,undef,undef,'ppm',"100,1",[(600,120,1000,60,1200,0)],0,'0,0,1,5')<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Temperatur- und Feuchtigkeitsanzeige mit Hilfe der SVG-Funktion '''temp_hum_ring''' =====<br />
Die Farbe ist jeweils abhängig vom dargestellten Temperatur- bzw. Feuchtigkeitswert. Die Helligkeit der Farbgebung ist einstellbar:<br />
[[Datei:Farbskalierung temp_hum_ring_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''temp_hum_ring'''<br />
<syntaxhighlight lang="perl"><br />
temp_hum_ring ($temp_value,$hum_value,$temp_min,$temp_max,$size, $lightring,$lightnumber,$decFontTemp,$decFontHum)<br />
<br />
$temp_value # Temperatur<br />
$hum_value # Feuchtigkeit<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$size # Größe der Grafik, optional, default=90<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFontTemp # Temperatur: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$decFontHum # Feuchtigkeit: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_temp_hum_ring DOIF ##<br />
attr di_temp_hum_ring uiTable {package ui_Table}\<br />
\<br />
"klein"|temp_hum_ring([Aussensensor:temperature],[Aussensensor:humidity],undef,undef,60)\<br />
"normal"|temp_hum_ring([Aussensensor:temperature],[Aussensensor:humidity])\<br />
"größer, aufgehellt"|temp_hum_ring([Aussensensor:temperature],[Aussensensor:humidity],undef,undef,100,undef,80)\<br />
"größer, Ring aufgehellt, Normalschrift"|temp_hum_ring([Aussensensor:temperature],[Aussensensor:humidity],undef,undef,100,80,50,"1,font-weight:normal","0,font-weight:normal")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:temp_hum_ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige von zwei Temperaturwerten mit Hilfe der SVG-Funktion '''temp_temp_ring''' =====<br />
Die Farbe ist jeweils abhängig vom dargestellten Temperaturwert. Die Helligkeit der Farbgebung ist einstellbar:<br />
[[Datei:Farbskalierung temp_temp_ring_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''temp_temp_ring'''<br />
<syntaxhighlight lang="perl"><br />
temp_temp_ring ($temp1_value,$temp2_value,$temp_min,$temp_max,$size, $lightring,$lightnumber,$decFontTemp1,$decFontTemp2)<br />
<br />
$temp1_value # erster Temperaturwert<br />
$temp2_value # zweiter Temperaturwert<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$size # Größe der Grafik, optional, default=90<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFontTemp1 # Temperatur1: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$decFontTemp2 # Temperatur2: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_temp_temp_ring DOIF ##<br />
attr di_temp_temp_ring uiTable {package ui_Table}\<br />
"klein, Ring augehellt"|temp_temp_ring([Vorlauf:Temperature],[Ruecklauf:Temperature],15,60,60,80,50)\<br />
"normal"|temp_temp_ring([Vorlauf:Temperature],[Ruecklauf:Temperature],15,60)\<br />
"groß, Zahlen aufgehellt"|temp_temp_ring([Vorlauf:Temperature],[Ruecklauf:Temperature],15,60,100,undef,80)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:temp_hum_temp_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige von zwei Zahlenwerten mit Hilfe der universellen SVG-Funktion '''ring2''' =====<br />
Die Farbe der dargestellten Werte kann abhängig vom Wert bestimmt werden.<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''ring2'''<br />
<syntaxhighlight lang="perl"><br />
ring2 ($value1,$min1,$max1,$minColor1,$maxColor1,$unit1,$size,$colorFunc1,$decFont1,<br />
$value2,$min2,$max2,$minColor2,$maxColor2,$unit2,$colorFunc2,$decFont2,<br />
$lightness,$icon,$model)<br />
<br />
$value1 # darzustellender Wert1<br />
$min1 # minimaler Wert, optional, default=0<br />
$max1 # maximaler Wert, optional, default=100<br />
$minColor1 # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor1 # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit1 # Einheit des Wertes, optional, default = undef<br />
$size # Größe der Grafik, optional, default = 100<br />
$colorFunc1 # Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, optional, default = undef<br />
$decFont1 # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$value2 # darzustellender Wert2<br />
...<br />
$decFont2 # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$lightness # Helligkeit einzelner Elemente (0-100) "<ring>,<inner ring>,<minMax>,<unit>,<value>,<icon>", optional, default: "50,50,50,40,50,40"<br />
$model # '<color gradient>,<min/max>,<inner ring>,<pointer>,<mode>',<br />
# <color gradient>: 1 für monochrom<br />
# <min/max>: Style-SVG-Attribute oder 1 zum Anzeigen der Min-/Maxwerte<br />
# <inner ring>: Style-SVG-Attribute oder 1 zum Anzeigen des Innenringes<br />
# <pointer>: Breite des Zeigers in Pixel<br />
# <mode>: 0 Standard Min. - Max., 1 negativ - Null - positiv, 2 Null - negativ/positiv<br />
# alle Parameter sind optional, default keine Angaben: ',,,,,,'<br />
<br />
Argumente für den zweiten Wert entsprechend den Argumenten des ersten Wertes<br />
</syntaxhighlight><br />
Wird '''$colorFunc...''' nicht angegeben, so wird der Farbwert zwischen '''$minColor...''' und '''$maxColor...''' linear interpoliert<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_ring2 DOIF ##<br />
attr di_ring2 uiTable {package ui_Table;;}\<br />
## Leistungsaufnahme von 0 kW bis 3,6 kW in Farben von grün (hue:120) bis rot (hue:0)\<br />
## Kapazität von 0 % bis 100 % V in Farben von rot (hue:0) bis grün (hue:120)\<br />
"Wallbox"| ring2([tesla:Leistung],0,3.6,120,0,"kW",undef,undef,"1,font-weight:normal",[tesla:Kapazitaet],0,100,0,120,"%",undef,"0,font-weight:normal")\<br />
\<br />
## Stromstärke von 0 A bis 2 A in Farben von grün (hue:120) bis rot (hue:0)\<br />
## Spannung von 1 V bis 1.5 V in Farben von rot (hue:0) bis grün (hue:120)\<br />
## 3 Nachkommastellen, Normalschrift, Schriftgröße 80% \<br />
"Akku"| ring2([akku:Strom],0,2,120,0,"A",undef,undef,"3,font-weight:normal;;font-size:80%",[akku:Spannung],1,1.5,0,120,"V",undef,"3,font-weight:normal;;font-size:80%")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:ring2_bsp.png|ohne|mini]]<br />
<br />
'''<big>Beispieldefinition Innenring, Farb-Array, Ringmodi</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_solar DOIF {}<br />
attr di_solar uiTable {package ui_Table}\<br />
"Farb-Array, ringMode 1"|\<br />
ring2([zaehler:Produktion],-20,30,undef,undef,"PV kWh",130,[(-10,0,-0.001,30,10,60,30,90)],"2",[test:Bezug],-20,30,undef,undef,"Bezug",[(-10,0,-0.001,30,10,60,30,90)],"2",undef,undef,"0,1,1,0,1")\<br />
"Farbe linear, ringMode 1"|\<br />
ring2([zeahler:Produktion],-20,30,0,120,"PV kWh",130,undef,"2",[test:Bezug],-20,30,0,120,"Bezug",undef,"2",undef,undef,"0,1,1,0,1")\<br />
"Farbe linear, ringMode 2"|\<br />
ring2([zaehler:Produktion],0,30,60,120,"PV kWh",130,undef,"2",[test:Bezug],-20,0,0,120,"Bezug",undef,"2",undef,undef,"0,,,0,2")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:ring2_ringMode.png|ohne|mini]]<br />
<br />
<br clear="all"><br />
<br />
==== '''icon_ring'''-Funktionen ====<br />
===== Farbskalierte Temperaturanzeige mit einem Icon mit Hilfe der SVG-Funktionen '''icon_temp_ring/icon_temp_mring''' =====<br />
Diese Funktionen basieren auf den obigen temp_ring-Funktionen, zusätzlich wird ein SVG-Icon dargestellt. Die Farbe des Icons kann mit @ an den Iconnamen angehängt werden, ansonsten wird die Farbe der Temperatur für das Icon verwendet. Die Größe des Icons kann skaliert werden, ebenso kann die Positionen des Icons verschoben werden.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_temp_ring/icon_temp_mring'''<br />
<syntaxhighlight lang="perl"><br />
icon_temp_ring/icon_temp_mring ($icon,$temp_value,$temp_min,$temp_max,$size,$lightring,$lightnumber,$decFont) <br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation (0-360) sind optional<br />
$temp_value # Temperatur<br />
$temp_min, # minimale Temperatur, optional, default=-20<br />
$temp_max, # maximale Temperatur, optional, default=60<br />
$size, # Größe der Grafik, optional, default=80<br />
$lightring, # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_Heizung_temp DOIF ##<br />
attr di_Heizung_temp uiTable {\<br />
package ui_Table;;\<br />
}\<br />
\<br />
icon_temp_ring("temp_outside",[vaillant:Aussentemp],-15,40)|\<br />
icon_temp_mring(([vaillant:Flame] eq "off"?"sani_boiler_temp\@white":"sani_boiler_temp\@Darkorange"),[vaillant:Vorlauf],15,70)|\<br />
icon_temp_mring(([vaillant:Pumpenstatus] eq "4" ? "sani_buffer_temp_down\@Darkorange" : "sani_buffer_temp_down\@white"),[vaillant:WWSpeicher],15,70)|\<br />
icon_temp_mring(([Zirk] eq "off"?"sani_pump\@white":"sani_pump\@Darkorange"),[ESPEasy_ESP_Temp_Zirkulation:Temperature],15,70)|\<br />
icon_temp_mring(([vaillant:Pumpenstatus] eq "on" ? "sani_floor_heating\@Darkorange" : "sani_floor_heating_neutral\@white"),[ESPEasy_ESP_Temp_Vorlauf:Temperature],15,70)|\<br />
icon_temp_mring("sani_floor_heating_neutral\@white",[ESPEasy_ESP_Temp_Keller_Ruecklauf:Temperature],15,70)|""<br />
<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_temp_ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Feuchtigkeitsanzeige mit einem Icon mit Hilfe der SVG-Funktionen '''icon_hum_ring/icon_hum_mring''' =====<br />
Diese Funktionen basieren auf den obigen hum_ring-Funktionen, zusätzlich wird ein SVG-Icon dargestellt. Die Farbe des Icons kann mit @ an den Iconnamen angehängt werden, ansonsten wird die Farbe der Feuchtigkeit für das Icon verwendet. Die Größe des Icons kann skaliert werden, ebenso kann die Positionen des Icons verschoben werden. <br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_hum_ring/icon_hum_mring'''<br />
<syntaxhighlight lang="perl"><br />
icon_hum_ring/icon_hum_mring ($icon,$hum_value,$size,$lightring,$lightnumber,$decFont) <br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$hum_value # Feuchtigkeit<br />
$size # Größe der Grafik, optional, default=80<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_hum_ring DOIF ##<br />
attr di_icon_hum_ring room test5<br />
attr di_icon_hum_ring uiTable {package ui_Table}\<br />
"klein ohne Farbverlauf"|icon_hum_mring("weather_humidity",[Aussensensor:humidity],60)\<br />
"normal groß mit Farbverlauf"|icon_hum_ring("weather_humidity",[Aussensensor:humidity])\<br />
"groß ohne Farbverlauf aufgehellt"|icon_hum_mring("weather_humidity",[Aussensensor:humidity],100,80)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_hum_ring_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige eines Icons mit einem Zahlenwert mit Hilfe der universellen SVG-Funktion '''icon_ring/icon_mring/icon_uring''' =====<br />
Diese Funktionen basieren auf der universellen ring-Funktion. Die Farbe des dargestellten Icons und des Wertes kann abhängig vom Wert bestimmt werden. Die Funktion '''icon_ring''' stellt den Farbring mit Farbverlauf dar, die Funktion '''icon_mring''' stellt den Farbring einfarbig dar. Die universelle Funktion '''icon_uring''' kann über den Parameter '''$model''' das Erscheinungsbild der Grafik verändern.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_ring/icon_mring/icon_uring'''<br />
<syntaxhighlight lang="perl"><br />
icon_ring ($icon,$value,$min,$max,$minColor,$maxColor, $unit,$decFont,$size,$colorRef,$lightness,$model)<br />
<br />
icon_mring ($icon,$value,$min,$max,$minColor,$maxColor, $unit,$decFont,$size,$colorRef,$lightness)<br />
<br />
icon_uring ($model,$icon,$value,$min,$max,$minColor,$maxColor, $unit,$decFont,$size,$colorRef,$lightness)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$value # darzustellender Wert<br />
$min # minimaler Wert, optional, default=0<br />
$max # maximaler Wert, optional, default=100<br />
$minColor # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$decFont # "<Anzahl der Nachkommastellen>,<Style-SVG-Attribute Wert>,<Style-SVG-Attribute Einheit>", optional<br />
$size # Größe der Grafik, optional, default = 100<br />
$colorRef # Referenz auf eine Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, oder eine Referenz auf eine Arrayliste mit Grenzwerten und Farben, optional, default = undef<br />
$lightness # Helligkeit einzelner Elemente (0-100) "<ring>,<inner ring>,<minMax>,<unit>,<value>,<icon>", optional, default: "50,50,50,40,50,40"<br />
$model # '<color gradient>,<min/max>,<inner ring>,<pointer>,<mode>',<br />
# <color gradient>: 1 für monochrom<br />
# <min/max>: Style-SVG-Attribute oder 1 zum Anzeigen der Min-/Maxwerte<br />
# <inner ring>: Style-SVG-Attribute oder 1 zum Anzeigen des Innenringes<br />
# <pointer>: Breite des Zeigers in Pixel<br />
# <mode>: 0 Standard Min. - Max., 1 negativ - Null - positiv, 2 Null - negativ/positiv<br />
# alle Parameter sind optional, default keine Angaben: ',,,,,,'<br />
</syntaxhighlight><br />
Wird '''$colorRef''' nicht angegeben, so wird der Farbwert zwischen '''$minColor''' und '''$maxColor''' linear interpoliert<br />
}}<br />
<br />
<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_ring DOIF ##<br />
attr di_icon_ring uiTable {package ui_Table}\<br />
\<br />
icon_ring ('sani_floor_heating_neutral',[Heizenergie:Vortag_hc],0,150,120,0,'kWh')|\<br />
icon_mring ('fuel',[Tankstelle:Diesel],1.10,1.30,120,0,'€',2)|\<br />
icon_uring ('0,1,1',"air",[ESPEasy_Eingang_CO2:PPM],400,1200,undef,undef,'ppm',0,100,[(600,120,1000,60,1200,0)])|\<br />
icon_uring ('0,1','Zisterne',([Wasserzisterne]/3.4),0,100,0,120,'%',0)##/\<br />
\<br />
icon_uring ('1,1,0,8',"measure_water_meter",[Wasserverbrauch:heute],0,600,120,0,'l',0)|\<br />
icon_uring ('0,fill:white,opacity:0.4',([vaillant:Pumpenstatus] eq '4' ? 'sani_buffer_temp_down@Darkorange' : 'sani_buffer_temp_down@white'),[vaillant:Umlaufmenge],0,20,120,0,'l/min')|\<br />
icon_uring('0,1,1,4','weather_barometric_pressure',[vaillant:Wasserdruck],0,3,undef,undef,'bar',1,100,[(0.8,0,1,60,1.5,120,1.7,60,3,0)])|\<br />
icon_uring('0,opacity:0.8,1,6','sani_water_tap',[vaillant:HwcHours_hoursum2_value],0,2000,120,0,'h',0)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_ring_bsp.png|ohne|mini]]<br />
<br clear="all"><br />
<br />
===== Farbskalierte Temperatur- und Feuchtigkeitsanzeige mit einem Icon mit Hilfe der SVG-Funktion '''icon_temp_hum_ring''' =====<br />
Die Farbe ist jeweils abhängig vom dargestellten Temperatur- bzw. Feuchtigkeitswert. Die Helligkeit der Farbgebung ist einstellbar:<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_temp_hum_ring'''<br />
<syntaxhighlight lang="perl"><br />
icon_temp_hum_ring ($icon,$temp_value,$hum_value,$temp_min,$temp_max,$size, $lightring,$lightnumber,$decFontTemp,$decFontHum)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$temp_value # Temperatur<br />
$hum_value # Feuchtigkeit<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$size # Größe der Grafik, optional, default=90<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFontTemp # Temperatur: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$decFontHum # Feuchtigkeit: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_temp_hum_ring DOIF ##<br />
attr di_icon_temp_hum_ring uiTable {package ui_Table}\<br />
\<br />
"normal"|icon_temp_hum_ring("temp_outside",[Aussensensor:temperature],[Aussensensor:humidity])\<br />
"mit Normalschrift"|icon_temp_hum_ring("temp_outside",[Aussensensor:temperature],[Aussensensor:humidity], undef,undef,undef,undef,undef,"1,font-weight:normal","0,font-weight:normal")\<br />
"größer aufgehellt"|icon_temp_hum_ring("temp_outside",[Aussensensor:temperature],[Aussensensor:humidity], undef,undef,120,undef,80)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_temp_hum_ring.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige von zwei Temperaturwerten mit einem Icon mit Hilfe der SVG-Funktion '''icon_temp_temp_ring''' =====<br />
Die Farbe ist jeweils abhängig vom dargestellten Temperaturwert. Die Helligkeit der Farbgebung ist einstellbar:<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_temp_temp_ring'''<br />
<syntaxhighlight lang="perl"><br />
icon_temp_temp_ring ($icon,$temp1_value,$temp2_value,$temp_min,$temp_max,$size, $lightring,$lightnumber,$decFontTemp1,$decFontTemp2)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$temp1_value # erster Temperaturwert<br />
$temp2_value # zweiter Temperaturwert<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$size # Größe der Grafik, optional, default=90<br />
$lightring # Helligkeit des Ringes (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFontTemp1 # Temperatur1: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$decFontTemp2 # Temperatur2: "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_temp_temp_ring DOIF ##<br />
attr di_icon_temp_temp_ring uiTable {package ui_Table}\<br />
## Größe 120%\<br />
"FB-Heizung"|icon_temp_temp_ring(([vaillant:Pumpenstatus] eq "on" ? "sani_floor_heating\@Darkorange" : "sani_floor_heating_neutral\@white"),[ESPEasy_ESP_Temp_Vorlauf:Temperature],[ESPEasy_ESP_Temp_Keller_Ruecklauf:Temperature],15,70,120)\<br />
\<br />
## Größe 120%, Normalschrift\<br />
"Temperatur","Taupunkt"|icon_temp_temp_ring("temp_outside",[Aussensensor:temperature],[Aussensensor:dewpoint],undef,undef,120,undef,undef,"1,font-weight:normal","1,font-weight:normal")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_temp_temp_ring.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige von zwei Zahlenwerten mit einem Icon mit Hilfe der universellen SVG-Funktion '''icon_ring2''' =====<br />
Die Farbe der dargestellten Werte kann abhängig vom Wert bestimmt werden.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_ring2'''<br />
<syntaxhighlight lang="perl"><br />
icon_ring2 ($icon,$value1,$min1,$max1,$minColor1,$maxColor1,$unit1,$size,$colorFunc1,$decFont1, $value2,$min2,$max2,$minColor2,$maxColor2,$unit2,$colorFunc2,$decFont2,$lightnesss,$model)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$value1 # darzustellender Wert1<br />
$min1 # minimaler Wert, optional, default=0<br />
$max1 # maximaler Wert, optional, default=100<br />
$minColor1 # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor1 # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit1 # Einheit des Wertes, optional, default = undef<br />
$size # Größe der Grafik, optional, default = 100<br />
$colorFunc1 # Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, optional, default = undef<br />
$decFont1 # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$value2 ## darzustellender Wert2<br />
...<br />
$unit2 # Einheit des Wertes, optional, default = undef<br />
$colorFunc2 # Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, optional, default = undef<br />
$decFont2 # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional<br />
$lightness # Helligkeit einzelner Elemente (0-100) "<ring>,<inner ring>,<minMax>,<unit>,<value>,<icon>", optional, default: "50,50,50,40,50,40"<br />
$model # '<color gradient>,<min/max>,<inner ring>,<pointer>,<mode>',<br />
# <color gradient>: 1 für monochrom<br />
# <min/max>: Style-SVG-Attribute oder 1 zum Anzeigen der Min-/Maxwerte<br />
# <inner ring>: Style-SVG-Attribute oder 1 zum Anzeigen des Innenringes<br />
# <pointer>: Breite des Zeigers in Pixel<br />
# <mode>: 0 Standard Min. - Max., 1 negativ - Null - positiv, 2 Null - negativ/positiv<br />
# alle Parameter sind optional, default keine Angaben: ',,,,,,'<br />
<br />
Argumente für den zweiten Wert entsprechend den Argumenten des ersten Wertes<br />
</syntaxhighlight><br />
Wird '''$colorFunc...''' nicht angegeben, so wird der Farbwert zwischen '''$minColor...''' und '''$maxColor...''' linear interpoliert.<br />
<br />
Bei der Farbangabe des Icons beim Übergabeparameter $icon wird mit '''\@colorVal2''' das Icon mit der Farbe des zweiten Wertes eingefärbt. Bei keiner Farbangabe oder '''\@colorVal1''' wird das Icon mit der Farbe des ersten Wertes eingefärbt. Ansonsten gilt die allgemeine FHEM-Syntax für Farbgebung von Icons angehängt mit '''\@'''.<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_ring2 DOIF ##<br />
attr di_icon_ring2 uiTable {package ui_Table;;\<br />
\<br />
sub himmelsrichtung {\<br />
my ($richtung)=@_;;\<br />
my $element=int($richtung/22.5);;\##/<br />
my @h=(qw"N NNO NO ONO O OSO SO SSO S SSW SW WSW W WNW NW NNW");;\<br />
return($h[$element]);;\<br />
}\<br />
}\<br />
"Wallbox"| icon_ring2("car,1.5,0,-3",[tesla:Leistung],0,3.6,120,0,"kW",120,undef,"1,font-weight:normal",[tesla:Kapazitaet],0,100,0,120,"%",undef,"0,font-weight:normal")\<br />
\<br />
"Wind"|icon_ring2(([Wind:Geschwindigkeit]>0 ? "wind":"no_wind").",1,0,0,".[Wind:Richtung],[Wind:Geschwindigkeit],0,50,120,0,"km/h",120,undef,1,[Wind:Richtung],361,361,220,220,([Wind:Geschwindigkeit]>0?himmelsrichtung([Wind:Richtung]):"--"),undef,0)\<br />
\<br />
"Strom"|icon_ring2([zaehler:l-Produktion] > 0 ? "sani_solar\@colorVal1":"fa_bolt\@colorVal2",[zaehler:l-Produktion],0,3.6,20,120,"PV kW",150,undef,"1,,font-size:50%;fill:white",[zaehler:l-Bezug,0],0,2,120,0,"Netz kW",undef,"1,,font-size:50%;fill:white")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_ring2.png|ohne|mini]]<br />
<br />
==== '''bar'''-Funktionen ====<br />
===== Farbskalierte Anzeige der Temperatur in Balkenform mit Hilfe der SVG-Funktionen '''temp_bar/temp_mbar''' =====<br />
Die Farbe der dargestellten Temperatur ist abhängig vom Temperaturwert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''temp_mbar'''-SVG-Funktion wird der Balken einfarbig dargestellt.<br />
<br />
Farbskalierung der '''temp_bar'''-SVG-Funktion:<br />
[[Datei:Farbskalierung temp_bar_scaling.png|600px|ohne]]<br />
<br />
Farbskalierung der '''temp_mbar'''-SVG-Funktion:<br />
[[Datei:Farbskalierung temp_mbar_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''temp_bar/temp_mbar'''<br />
<syntaxhighlight lang="perl"><br />
temp_bar/temp_mbar ($temp_value,$temp_min,$temp_max, $header,$width,$height,$size, $light,$lightnumber,$decFont)<br />
<br />
$temp_value # Temperaturwert<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$header # Überschrift, optional, default= undef (keine)<br />
$width # Breite der Grafik, optional, default=63<br />
$height # Höhe der Grafik, optional, default=60<br />
$size # Größe der Grafik, optional, default=100<br />
$light # Helligkeit der Grafik (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 1<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_temp_bar DOIF ##<br />
attr di_temp_bar uiTable {package ui_Table}\<br />
"standard"|temp_bar([Aussensensor:temperature])\<br />
"heller"|temp_bar([Aussensensor:temperature],undef,undef,undef,undef,undef,undef,80)\<br />
"monochrom"|temp_mbar([Aussensensor:temperature])\<br />
"kleiner"|temp_bar([Aussensensor:temperature],undef,undef,undef,undef,undef,80)\<br />
"mit Überschrift"|temp_bar([Aussensensor:temperature],undef,undef,"Außen")\<br />
"hoch"|temp_bar([Aussensensor:temperature],undef,undef,undef,undef,100)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:temp_bar_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige der Feuchtigkeit in Balkenform mit Hilfe der SVG-Funktionen '''hum_bar/hum_mbar''' =====<br />
Die Farbe der dargestellten Feuchtigkeit ist abhängig vom Feuchtigkeitswert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''hum_mbar'''-SVG-Funktion wird der Balken einfarbig dargestellt.<br />
<br />
Farbskalierung der '''hum_bar'''-SVG-Funktion:<br />
[[Datei:Farbskalierung hum_bar_scaling.png|600px|ohne]]<br />
<br />
Farbskalierung der '''hum_mbar'''-SVG-Funktion:<br />
[[Datei:Farbskalierung hum_mbar_scaling.png|600px|ohne]]<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''hum_bar/hum_mbar'''<br />
<syntaxhighlight lang="perl"><br />
hum_bar/hum_mbar ($hum_value,$header,$width,$height,$size, $light,$lightnumber,$decFont)<br />
<br />
$hum_value # Feuchtigkeitswert<br />
$header # Überschrift, optional, default = undef (keine)<br />
$width # Breite der Grafik, optional, default=63<br />
$height # Höhe der Grafik, optional, default=80<br />
$size # Größe der Grafik, optional, default=100<br />
$light # Helligkeit des der Grafik (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 0<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_hum_bar DOIF ##<br />
attr di_hum_bar uiTable {package ui_Table}\<br />
"standard"|hum_bar([Aussensensor:humidity])\<br />
"heller"|hum_bar([Aussensensor:humidity],undef,undef,undef,undef,80)\<br />
"monochrom"|hum_mbar([Aussensensor:humidity])\<br />
"kleiner"|hum_bar([Aussensensor:humidity],undef,undef,undef,80)\<br />
"mit Überschrift"|hum_bar([Aussensensor:humidity],"Außen")\<br />
"hoch"|hum_bar([Aussensensor:humidity],undef,undef,100)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:hum_bar_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige eines Zahlenwertes mit Hilfe der universellen SVG-Funktion '''bar''' =====<br />
Die Farbe des dargestellten Wertes kann abhängig vom Wert bestimmt werden.<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''bar'''<br />
<syntaxhighlight lang="perl"><br />
bar ($value,$min,$max,$header,$minColor,$maxColor,$unit,$width, $height,$size,$colorFunc,$decFont,$gradient,$light,$lightnumber)<br />
<br />
$value # darzustellender Wert<br />
$min # minimaler Wert, optional, default=0<br />
$max # maximaler Wert, optional, default=100<br />
$header # Überschrift, optional, default = undef (keine)<br />
$minColor # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$width # Breite der Grafik, optional, default = 63<br />
$height # Höhe der Grafik, optional, default = 60<br />
$size # Größe der Grafik, optional, default = 100<br />
$colorFunc # Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, optional, default = undef<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 1<br />
$gradient # Farbverlauf, optional, undef mit Farbverlauf, 1 ohne Farbverlauf, default = undef<br />
$light # Helligkeit der Grafik (light:0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (light:0-100), optional, default=50<br />
</syntaxhighlight><br />
Wird '''$colorFunc''' nicht angegeben, so wird der Farbwert zwischen '''$minColor''' und '''$maxColor''' linear interpoliert<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
{package ui_Table}<br />
defmod di_bar DOIF ##<br />
attr di_bar uiTable {package ui_Table}\<br />
## von 0 bis 20 in Farben von grün (hue:120) bis rot (hue:0)\<br />
"Umlaufmenge"|bar([heizung:Umlaufmenge],0,20,"Umlauf",120,0,"l/min")\<br />
\<br />
## von 0 bis 3 in Farben von rot (hue:0) bis türkis (hue:180)\<br />
"Wasserdruck"|bar([heizung:Wasserdruck],0,3,undef,0,180,"bar"undef,70,undef,undef,"1,font-size:130%;;font-weight:normal")\<br />
\<br />
## Temperaturdarstellung, entspricht dem Funktionsaufruf:\<br />
## temp_bar ([Aussensensor:temperature],-20,60)\<br />
"Temperatur"|bar([Aussensensor:temperature],-20,60,undef,undef,undef,"°C",undef,undef,undef,\&temp_hue)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:bar_bsp.png|ohne|mini]]<br />
<br />
==== '''icon_bar'''-Funktionen ====<br />
===== Farbskalierte Anzeige der Temperatur in Balkenform mit Hilfe der SVG-Funktion '''icon_temp_bar/icon_temp_mbar''' =====<br />
Die Farbe der dargestellten Temperatur ist abhängig vom Temperaturwert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''icon_temp_mbar'''-SVG-Funktion wird der Balken einfarbig dargestellt.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_temp_bar/icon_temp_mbar'''<br />
<syntaxhighlight lang="perl"><br />
icon_temp_bar/icon_temp_mbar ($icon,$temp_value,$temp_min,$temp_max, $header,$width,$height,$size,$light,$lightnumber,$decFont)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position", \@Farbe, Skalierungsfaktor, x-Position, y-Position sind optional<br />
$temp_value # Temperaturwert<br />
$temp_min # minimale Temperatur, optional, default=-20<br />
$temp_max # maximale Temperatur, optional, default=60<br />
$header # Überschrift, optional, default= undef (keine)<br />
$width # Breite der Grafik, optional, default=63<br />
$height # Höhe der Grafik, optional, default=75<br />
$size # Größe der Grafik, optional, default=100<br />
$light # Helligkeit der Grafik (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 1<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_temp_bar DOIF ##<br />
attr di_icon_temp_bar room test10<br />
attr di_icon_temp_bar uiTable {package ui_Table}\<br />
"standard"|icon_temp_bar("temp_outside",[Aussensensor:temperature])\<br />
"heller"|icon_temp_bar("temp_outside",[Aussensensor:temperature],undef,undef,undef,undef,undef,undef,80)\<br />
"monochrom"|icon_temp_mbar("temp_outside",[Aussensensor:temperature])\<br />
"kleiner"|icon_temp_bar("temp_outside",[Aussensensor:temperature],undef,undef,undef,undef,undef,80)\<br />
"mit Überschrift"|icon_temp_bar("temp_outside",[Aussensensor:temperature],undef,undef,"Außen")\<br />
"hoch"|icon_temp_bar("temp_outside",[Aussensensor:temperature],undef,undef,undef,undef,100)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_temp_bar_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige der Feuchtigkeit in Balkenform mit Hilfe der SVG-Funktionen '''icon_hum_bar/icon_hum_mbar''' =====<br />
Die Farbe der dargestellten Feuchtigkeit ist abhängig vom Feuchtigkeitswert. Die Helligkeit der Farbgebung ist einstellbar. Bei der '''icon_hum_mbar'''-SVG-Funktion wird der Balken einfarbig dargestellt.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_hum_bar/icon_hum_mbar'''<br />
<syntaxhighlight lang="perl"><br />
icon_hum_bar/icon_hum_mbar ($icon,$hum_value,$header,$width,$height,$size, $light,$lightnumber,$decFont)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position", \@Farbe, Skalierungsfaktor, x-Position, y-Position sind optional<br />
$hum_value # Temperaturwert<br />
$header # Überschrift, optional, default = undef (keine)<br />
$width # Breite der Grafik, optional, default=63<br />
$height # Höhe der Grafik, optional, default=75<br />
$size # Größe der Grafik, optional, default=100<br />
$light # Helligkeit des der Grafik (0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (0-100), optional, default=50<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 1<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_hum_bar DOIF ##<br />
attr di_icon_hum_bar uiTable {package ui_Table}\<br />
"standard"|icon_hum_bar("temperature_humidity",[Aussensensor:humidity])\<br />
"heller"|icon_hum_bar("temperature_humidity",[Aussensensor:humidity],undef,undef,undef,undef,80)\<br />
"monochrom"|icon_hum_mbar("temperature_humidity",[Aussensensor:humidity])\<br />
"kleiner"|icon_hum_bar("temperature_humidity",[Aussensensor:humidity],undef,undef,undef,80)\<br />
"mit Überschrift"|icon_hum_bar("temperature_humidity",[Aussensensor:humidity],"Außen")\<br />
"hoch"|icon_hum_bar("temperature_humidity",[Aussensensor:humidity],undef,undef,100)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_hum_bar_bsp.png|ohne|mini]]<br />
<br />
===== Farbskalierte Anzeige eines Zahlenwertes mit Hilfe der universellen SVG-Funktionen '''icon_bar/icon_mbar''' =====<br />
Die Farbe des dargestellten Wertes und des Icons kann abhängig vom Wert bestimmt werden. Bei der '''icon_mbar'''-SVG-Funktion wird der Balken einfarbig dargestellt.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''icon_bar/icon_mbar'''<br />
<syntaxhighlight lang="perl"><br />
icon_bar ($icon,$value,$min,$max,$minColor,$maxColor,$unit,$decfont,$header,$width,$height,$size, $colorFunc,$light,$lightnumber)<br />
<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation (0-360) sind optional<br />
$value # darzustellender Wert<br />
$min # minimaler Wert, optional, default=0<br />
$max # maximaler Wert, optional, default=100<br />
$header # Überschrift, optional, default = undef (keine)<br />
$minColor # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = undef<br />
$maxColor # Farbe (hue: 0-360) des maximalen Wertes, optional, default = undef<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$decFont # "<Anzahl der Nachkommastellen>,<Schrift-SVG-Attribute Wert>,<Schrift-SVG-Attribute Einheit>", optional, default = 1<br />
$width # Breite der Grafik, optional, default = 63<br />
$height # Höhe der Grafik, optional, default = 75<br />
$size # Größe der Grafik, optional, default = 100<br />
$colorFunc # Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, optional, default = undef<br />
$light # Helligkeit der Grafik (light:0-100), optional, default=50<br />
$lightnumber # Helligkeit der Zahl (light:0-100), optional, default=50<br />
</syntaxhighlight><br />
Wird '''$colorFunc''' nicht angegeben, so wird der Farbwert zwischen '''$minColor''' und '''$maxColor''' linear interpoliert<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_icon_bar_bsp DOIF ##<br />
attr di_icon_bar_bsp uiTable {package ui_Table;;\<br />
}\<br />
icon_bar ("fuel",[Tankstelle:Diesel],1.10,1.30,120,0,"€",2)|\<br />
icon_bar ("air",[ESPEasy_Eingang_CO2:PPM],400,1200,120,0,"ppm",0)|\<br />
icon_bar ("Zisterne",([Wasserzisterne]/3.4),0,100,0,120,"%",0)|\<br />
icon_bar (([vaillant:Pumpenstatus] eq "off" ? "sani_buffer_temp_down\@Darkorange" : "sani_buffer_temp_down\@white"),[vaillant:Umlaufmenge],0,20,120,0,"l/min")\<br />
icon_bar ("measure_water_meter",[Wasserverbrauch:heute],0,600,120,0,"l",0)|\<br />
icon_bar ("weather_barometric_pressure",[vaillant:Wasserdruck],0,3,0,180,"bar")|\<br />
icon_bar ("sani_water_tap",[vaillant:HwcHours_hoursum2_value],0,2000,120,0,"h",0)|\<br />
icon_bar ("sani_floor_heating_neutral",[Heizenergie:Vortag_hc],0,150,120,0,"kWh")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:icon_bar_bsp.png|ohne|mini]]<br />
<br />
==== Anzeige eines Werteverlaufs und des aktuellen Wertes mit Hilfe der SVG-Funktion '''card''' ====<br />
Es wird der aktuelle Wert eines Readings, sein zeitlicher Verlauf sowie der maximale und minimale Wert in Form einer Informationskarte visualisiert. Das Erscheinungsbild kann über zahlreiche Parameter individualisiert werden. Die Besonderheit ist das Argument '''col<Anzahl><Zeitformat>''' bei der Angabe des Readings der Form '''[<Device>:<Reading>:col<Anzahl><Zeitformat>]'''. Dadurch werden Daten des Readings temporär im DOIF-Modul gesammelt und für die Erzeugung eines Graphen zur Verfügung gestellt - es sind keine weiteren Definitionen erforderlich. Dabei wird besonders sparsam mit der Datensammlung umgegangen, es werden maximal 72 Werte (in Timeslots) gespeichert, unabhängig davon wie lange die Zeitspanne ist und wie oft die Daten ankommen. Die Auflösung des Graphen nimmt mit der Zeitspanne ab - es werden immer maximal 72 Werte dargestellt. Daraus ergibt sich bei einer Stunde eine Auflösung von 3600/72 = 50 Sekunden/Eintrag, bei 6 Stunden sind es 6*60/72 = 5 Minuten/Eintrag, für eine Woche 7*24*60/72 = 140 Minuten/Eintrag usw. Die gesammelten Daten werden über den FHEM-Befehl '''save''' in versteckten Readings des jeweiligen DOIF-Moduls gespeichert.<br />
<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''card'''<br />
<syntaxhighlight lang="perl"><br />
card ($collect,$header,$icon,$min,$max,$minColor,$maxColor, $unit,$colorRef,$decfont,$prop,$ringModel,$lightness, $collect2,$min2,$max2,$minColor2,$maxColor2,$unit2,$func2,$decfont2)<br />
<br />
$collect <br />
# Angabe eines Readings oder eines Arrays mit mehreren Readings der Form [<Device>:<Reading>:col<Anzahl><Zeitformat>], mit Hilfe des Argumentes col (von collect) wird das Modul angewiesen Daten des Readings über einen bestimmten Zeitraum zu sammeln<br />
<br />
col<number><timeformat> <br />
# <timeformat>: d Tage, w Wochen, ohne Angabe des Zeitformates wird <Anzahl> in Stunden interpretiert. <br />
# Beispiele: col (entspricht col24), col1, col12, col1d, col3d, col1w, col4w, col52w usw.<br />
<br />
$header # "<Überschrifttext,<Style-SVG-Text-Attribute>", optional<br />
$icon # "Iconname\@Farbe,Skalierungsfaktor,x-Position,y-Position,Rotation", \@Farbe, Skalierungsfaktor, x-Position, y-Position, Rotation sind optional<br />
$min # minimaler Wert, optional, default=0<br />
$max # maximaler Wert, optional, default=100<br />
$minColor # Farbe (hue: 0-360) des kleinsten Wertes, optional, default = 0 (rot)<br />
$maxColor # Farbe (hue: 0-360) des maximalen Wertes, optional, default = 120 (grün)<br />
$unit <br />
# Einheit des Wertes, optional, default = undef, falls unter $collect ein Array für mehrere Readings angegeben wurde, so werden hier als Array die entsprechenden Einheiten angegeben, zusätzlich kann kommagetrennt pro Einheit Farbe des Graphen angegeben werden<br />
<br />
$colorRef <br />
# Referenz auf eine Funktion, die zu einem Wert einen Farbwert (hue: 0-360) bestimmt, oder eine Referenz auf eine Arrayliste mit Grenzwerten und Farben, optional, default = undef<br />
<br />
$decFont<br />
# "<Anzahl der Nachkommastellen>,<Style-SVG-Attribute Wert>,<Style-SVG-Attribute Einheit>", optional<br />
<br />
$prop <br />
# Eigenschaft von card: "<size>,<y-scaling>,<steps>,<noFooter>,<noColor>,<hring>,<width>", optional<br />
<br />
# <size>: Größe der der Karte, default = 130,<br />
# <y-scaling>: feste Y-Skalierung: 1, sonst automatische Skalierung,<br />
# <steps>: 1 für Stufen,<br />
# <noFooter>: 1 für keine Fußzeile,<br />
# <noColor>: 1 für graue y-Achsenbeschriftung, <br />
# <hring>: 1 für Halbringdarstellung, <br />
# <width>: Breite der Karte, default: 160<br />
<br />
$ringModel<br />
# '<color gradient>,<min/max>,<inner ring>,<pointer>,<mode>'<br />
<br />
# <color gradient>: 1 für monochrom<br />
# <min/max>: Style-SVG-Attribute oder 1 zum Anzeigen der Min-/Maxwerte<br />
# <inner ring>: Style-SVG-Attribute oder 1 zum Anzeigen des Innenringes<br />
# <pointer>: Breite des Zeigers in Pixel<br />
# <mode>: 0 Standard Min. - Max., 1 negativ - Null - positiv, 2 Null - negativ/positiv<br />
# alle Parameter sind optional, default keine Angaben: ',,,,,,'<br />
<br />
$lightness <br />
# Helligkeit einzelner Elemente (0-100) "<ring>,<inner ring>,<minMax>,<unit>,<value>,<icon>", optional, default: "50,50,50,40,50,40"<br />
<br />
$collect2 # optionale Angaben für ein zweites Reading (es ist hier nur eine Readingangabe erlaubt)<br />
$min # restliche Parameter<br />
$max # entsprechen der Syntax<br />
... # des ersten Sensors<br />
$decfonts2 # <br />
</syntaxhighlight><br />
Wird '''$colorRef''' nicht angegeben, so wird der Farbwert zwischen '''$minColor''' und '''$maxColor''' linear interpoliert<br />
Werden mehrere Readings angegeben, so müssen sie alle die gleiche Zeitspanne besitzen (Zeitangabe bei col)<br />
<br />
'''nützliche Links'''<br />
* Anwendungsbeispiel [[DOIF/uiTable_Schnelleinstieg#Visualisierung:_Wetterstation|Wetterstation]]<br />
* Anwendungsbeispiel [[DOIF/uiTable_Schnelleinstieg#Visualisierung:_aktueller_Spritpreis|Spritpreise]]<br />
* Anwendungsbeispiel [[DOIF/uiTable_Schnelleinstieg#Visualisierung_und_Steuerung:_Heiztherme|Heiztherme]]<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#Farbskalierte_Anzeige_eines_Icons_mit_einem_Zahlenwert_mit_Hilfe_der_universellen_SVG-Funktion_icon_ring.2Ficon_mring.2Ficon_uring|icon_ring]] <br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_collect DOIF ##<br />
attr di_collect uiTable {package ui_Table;;}\<br />
card([Aussensensor:temperature:col12],"Außen","temp_outside",-10,45,undef,undef,"°C",\&temp_hue,undef)|\<br />
card([Tankstelle:Diesel:col12],"Sprit,fill:darkorange","fuel","1.00","1.40",120,0,"Diesel €",undef,"2",",,1")\<br />
card([zaehler:l-Produktion:col12],undef,[zaehler:l-Produktion] > 0 ? "sani_solar\@colorVal1":"fa_bolt\@colorVal2",0,3.6,30,60,"PV kW",undef,"1,,font-size:50%")|\<br />
card([ESPEasy_Eingang_CO2:PPM:col12],undef,"air",400,1200,120,0,"ppm",[600,120,1000,60,1200,0],0,undef,'0,1,1',"50,35,45,35,50,35")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:svgcard.png|ohne|mini]]<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
<br />
defmod di_cards DOIF {}<br />
attr di_cards uiTable {package ui_Table;;}\<br />
"Standard"|\<br />
card([Aussensensor:temperature:col],undef,"temp_outside",-10,50,undef,undef,"°C",\&temp_hue,"1","130")\<br />
"mit Halbring"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,50,undef,undef,"°C",\&temp_hue,"1","130,,,,,1")\<br />
"mit Halbring","ohne Fußzeile","Breite 110"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,50,undef,undef,"°C",\&temp_hue,"1","130,,,1,,1,110")\<br />
"Standard","Breite 200"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,50,undef,undef,"°C",\&temp_hue,"1","130,,,,,,200")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:di_card_variations.png|ohne|mini]]<br />
<br />
<br />
'''<big>Beispieldefinition mit zwei Readings mit unterschiedlichen Einheiten</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_cards DOIF {}<br />
attr di_cards uiTable {package ui_Table;;}\<br />
"Standard"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,60,undef,undef,"°C",\&temp_hue,"1","130,,,,",undef,undef,[outsensor:humidity:col],0,100,undef,undef,"%",\&hum_hue,"0")\<br />
"ohne Header"|\<br />
card([Aussensensor:temperature:col],undef,"temp_outside",-10,60,undef,undef,"°C",\&temp_hue,"1","130,,,,",undef,undef,[outsensor:humidity:col],0,100,undef,undef,"%",\&hum_hue,"0")\<br />
"ohne Header","ohne Fußzeile"|card([Aussensensor:temperature:col],undef,"temp_outside",-10,60,undef,undef,"°C",\&temp_hue,"1","130,,,1,",undef,undef,[outsensor:humidity:col],0,100,undef,undef,"%",\&hum_hue,"0")\<br />
"Als Halbring"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,60,undef,undef,"°C",\&temp_hue,"1","130,,,,,1",undef,undef,[outsensor:humidity:col],0,100,undef,undef,"%",\&hum_hue,"0")\<br />
"ohne Fußzeile"|\<br />
card([Aussensensor:temperature:col],"Außen","temp_outside",-10,60,undef,undef,"°C",\&temp_hue,"1","130,,,1,,1",undef,undef,[outsensor:humidity:col],0,100,undef,undef,"%",\&hum_hue,"0")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:di_card_collect2.png|ohne|mini]]<br />
<br />
'''<big>Beispieldefinitionen mit mehreren Readings mit gleicher Einheit</big>'''<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod Sprit DOIF ##<br />
attr Sprit uiTable {package ui_Table;;}\<br />
card([[Tankstelle:SuperE5:col24],[Tankstelle:Diesel:col24]],"Sprit","fuel","1.20","1.60",120,0,["E5","Diesel"],undef,"2",",,1")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:di_Sprit2.png|ohne|mini]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod PV DOIF {}<br />
attr PV DOIF_Readings l_Eigenv: [zaehler:l-Produktion]-[zaehler:l-Lieferung],\<br />
Eigenv:[zaehler:Produktion]-[zaehler:Lieferung],\<br />
l_Verbrauch: [zaehler:l-Bezug,0]+[$SELF:l_Eigenv,0],\<br />
Verbrauch:[zaehler:Bezug]+[$SELF:Eigenv],\<br />
l_Bezug:-[zaehler:l-Bezug]<br />
attr PV uiTable {\<br />
package ui_Table;;\<br />
$SHOWNOSTATE=1;;\<br />
}\<br />
card([[zaehler:l-Produktion:col],[$SELF:l_Eigenv:col],[$SELF:l_Bezug:col]],"kW","fa_bolt\@silver",-3.6,3.6,0,90,["Solar","Eigen.","Bezug"],[(-1,0,0,30,1,60,3.6,90)],"2","167,,1,,,1",",,1,6")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:di_card_energie.png|ohne|mini]]<br />
<br />
'''<big>Beispieldefinition mit mehreren Readings mit einfarbigen Graphen</big>'''<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_heating DOIF {}<br />
attr di_heating uiTable {\<br />
package ui_Table;;\<br />
}\<br />
card([[ESPEasy_ESP_Temp_Vorlauf:Temperature:col],[ESPEasy_ESP_Temp_Keller_Ruecklauf:Temperature:col]],"Umwälzpumpe",([vaillant:Pumpenstatus] eq "on" ? "sani_floor_heating\@Darkorange" : "sani_floor_heating_neutral\@white"),15,70,undef,undef,["Vor. °C,red","Rück. °C,#287afc"],\&temp_hue,undef,",,1,,1")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:di_card_pump.png|ohne|mini]]<br />
<br />
==== 3d-Balkendarstellung mehrerer Zahlenwerten mit Hilfe der universellen SVG-Funktion '''cylinder''' ====<br />
Es können mehrere Zahlenwerte mit Legende farbig in Balkenform visualisiert werden. Negative Werte werden als Balken nach unten dargestellt, positive nach oben, der Nullpunkt wird automatisch berechnet.<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''cylinder'''<br />
<syntaxhighlight lang="perl"><br />
cylinder ($header,$min,$max,$unit,$width,$height,$size,$dec,($value1,$color1,$text1),($value2,$color2,$text2),...<br />
<br />
$header # Überschrift<br />
$min # minimaler Wert, optional, default = 0<br />
$max # maximaler Wert, optional, default = 100<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$width # Breite der Grafik, optional, default = wird bei Beschriftungen automatisch angepasst<br />
$height # Höhe der Grafik, optional, default = wird automatisch berechnet<br />
$size # Größe der Grafik, optional, default = 100<br />
$dec # Anzahl der Nachkommastellen, optional, default=1<br />
$value1 # erster Zahlenwert<br />
$color1 # HSL-Farbe des ersten Balkens: "<hue>.<saturation>.<lightness>" (hue:0-360,saturation:0-100,lightness:0-100), saturation (default:100) und lightness (default:50) sind optional<br />
$text1 # Beschriftung des Zahlenwertes in der Legende, optional, default = undef<br />
$value2 # zweiter Zahlenwert, optional<br />
$color2 # HSL-Farbe des zweiten Balkens: "<hue>.<saturation>.<lightness>" (hue:0-360,saturation:0-100,lightness:0-100), saturation (default:100) und lightness (default:50) sind optional<br />
$text2 # Beschriftung des Zahlenwertes in der Legende, optional, default = undef<br />
...<br />
Es können weitere Zahlenwerte jeweils mit Farbe und Beschriftung optional angegeben werden <br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_cylinder DOIF ##<br />
attr di_cylinder room Test,wiki<br />
attr di_cylinder uiTable {package ui_Table}\<br />
"normal"|cylinder("",0,100,"%",80,undef,undef,0,[Wasserzisterne:state],200,undef)\<br />
\<br />
"mit Überschrift"|cylinder("Zisterne",0,100,"%",80,undef,undef,0,[Wasserzisterne:state],200,undef)\<br />
\<br />
"kleiner"|cylinder("Zisterne",0,100,"%",80,undef,80,0,[Wasserzisterne:state],200,undef)\<br />
\<br />
"hoch"|cylinder("Zisterne",0,100,"%",undef,100,undef,0,[Wasserzisterne:state],200,undef)\<br />
\<br />
"mit Beschriftung"|cylinder("Zisterne",0,100,"%",undef,100,undef,0,[Wasserzisterne:state],200,"Wasserstand")\<br />
\<br />
"mit mehreren Informationen"|cylinder("Energie",-20,30,"kWh",undef,undef,undef,1,[zaehler:Bezug],0,"Bezug",[zaehler:Produktion],60,"Produktion",[zaehler:Eigenverbrauch],30,"Eigenverbrauch")\<br />
\<br />
"mit hellen Farben"| cylinder("Tag",0,100,"kWh",undef,undef,undef,1,[Heizenergie:Tagesverbrauch_hc]/100000,"30.100.70","letzter",[Heizenergie:heute_hc]/100000,"60.100.70","aktuell")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:cylinder_bsp.png|ohne|mini]]<br />
<br />
==== Balkendarstellung mehrerer Zahlenwerte mit Hilfe der universellen SVG-Funktion '''cylinder_bars''' ====<br />
Es können mehrere Zahlenwerte mit Legende farbig in Balkenform visualisiert werden. Negative Werte werden als Balken nach unten dargestellt, positive nach oben, der Nullpunkt wird automatisch berechnet. Die '''cylinder_bars'''-SVG-Funkton besitzt die gleichen Argumente, wie die obige '''cylinder'''-SVG-Funktion, mehrerer Balken werden jedoch nicht übereinander, sondern nebeneinander dargestellt.<br />
{{Randnotiz|RNText=SVG-uiTable-Funktion '''cylinder_bars'''<br />
<syntaxhighlight lang="perl"><br />
cylinder_bars ($header,$min,$max,$unit,$width,$height,$size,$dec,($value1,$color1,$text1),($value2,$color2,$text2),...<br />
<br />
$header # Überschrift<br />
$min # minimaler Wert, optional, default = 0<br />
$max # maximaler Wert, optional, default = 100<br />
$unit # Einheit des Wertes, optional, default = undef<br />
$width # Breite der Grafik, optional, default = wird bei Beschriftungen automatisch angepasst<br />
$height # Höhe der Grafik, optional, default = wird automatisch berechnet<br />
$size # Größe der Grafik, optional, default = 100<br />
$dec # Anzahl der Nachkommastellen, optional, default=1<br />
$value1 # erster Zahlenwert<br />
$color1 # HSL-Farbe des ersten Balkens: "<hue>.<saturation>.<lightness>" (hue:0-360,saturation:0-100,lightness:0-100), saturation (default:100) und lightness (default:50) sind optional<br />
$text1 # Beschriftung des Zahlenwertes in der Legende, optional, default = undef<br />
$value2 # zweiter Zahlenwert, optional<br />
$color2 # HSL-Farbe des zweiten Balkens: "<hue>.<saturation>.<lightness>" (hue:0-360,saturation:0-100,lightness:0-100), saturation (default:100) und lightness (default:50) sind optional<br />
$text2 # Beschriftung des Zahlenwertes in der Legende, optional, default = undef<br />
...<br />
Es können weitere Zahlenwerte jeweils mit Farbe und Beschriftung optional angegeben werden <br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_wasserverbrauch DOIF ##<br />
attr di_wasserverbrauch uiTable {package ui_Table;;}\<br />
cylinder_bars("Monat",0,15,"m³",undef,undef,undef,1,[Wasserverbrauch:monatsdurchschnitt],30,"Durchschnitt",[Wasserverbrauch:monatsverbrauch]/1000,220,"letzter",[Wasserverbrauch:monat]/1000,180,"aktuell")\<br />
\<br />
cylinder_bars("Monat",0,15,"m³",undef,undef,undef,1,[Wasserverbrauch:jan],30,"Januar",[Wasserverbrauch:feb],220,"Februar",[Wasserverbrauch:mrz],180,"März",[Wasserverbrauch:apr],30,"April",[Wasserverbrauch:mai],220,"Mai",[Wasserverbrauch:jun],180,"Juni",[Wasserverbrauch:jul],30,"Juli",[Wasserverbrauch:aug],220,"August",[Wasserverbrauch:sep],180,"September",[Wasserverbrauch:okt],30,"Oktober",[Wasserverbrauch:nov],220,"November",[Wasserverbrauch:dez],180,"Dezember")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:cylinder_bars_bsp.png|ohne|mini]]<br />
<br />
=== Farbskalierte Temperaturanzeige mit Hilfe der Funktion '''temp''' ===<br />
Die Farbe der dargestellten Temperatur ist abhängig vom Temperaturwert:<br />
[[Datei:Farbskalierung temp.png|600px|ohne]]<br />
{{Randnotiz|RNText=uiTable-Funktion '''temp'''<br />
<syntaxhighlight lang="perl"><br />
temp ($temp,$size,$icon)<br />
<br />
$temp # Temperatur<br />
$size # Schriftgröße in Pixel (pt), optional<br />
$icon # Icon, welches vorangestellt wird, optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_temp DOIF ##<br />
attr di_uiTable_temp uiTable {\<br />
package ui_Table;; ## Package für uiTable-Funktionen\<br />
$TC{0..2}="align='center'";; ## zentrierte Darstellung aller Tabellenspalten\<br />
}\<br />
## Tabellendefinition\<br />
\<br />
"Aussen"|"Bad"|"Warmwasser" ## mit | werden Tabellenzellen voneinander getrennt \<br />
temp([Aussensensor:temperature])| ## Anzeige des Readings 'temperature' des Gerätes 'Aussensensor' \<br />
temp([TH_Bad_HM:measured-temp],24,"temp_temperature")| ## Schriftgröße 24pt, mit Icon namens temp_temperature\<br />
temp([T_Warmwasserspeicher:temperature:d1],20) ## Schriftgröße 20pt<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Temp.png|ohne|mini]]<br />
<br />
=== Farbskalierte Feuchtigkeitsanzeige mit Hilfe der Funktion '''hum''' ===<br />
Die Farbe der dargestellten Feuchtigkeit ist abhängig vom Feuchtigkeitswert:<br />
[[Datei:Farbskalierung hum.png|350px|ohne]]<br />
{{Randnotiz|RNText=uiTable-Funktion '''hum'''<br />
<syntaxhighlight lang="perl"><br />
hum ($hum,$size,$icon)<br />
<br />
$hum # Feuchtigkeit<br />
$size # Schriftgröße in Pixel (pt), optional<br />
$icon # Icon, welches vorangestellt wird, optional<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_hum DOIF ##<br />
attr di_uiTable_hum uiTable {\<br />
package ui_Table;;\<br />
$TC{1}="align='center'";; ## zweite Spalte der Tabelle zentriert\<br />
}\<br />
## Tabellendefinition \<br />
\<br />
## Anzeige des Readings 'humidity' des Thermostats 'TH_Bad_HM' \<br />
"Bad"|hum ([TH_Bad_HM:humidity])\<br />
\<br />
## Feuchtigkeit in Größe 10pt mit Temperatur in einer Tabellenzelle\<br />
"Aussen"|temp ([Aussensensor:temperature]),hum ([Aussensensor:humidity],10)\<br />
\<br />
## Feuchtigkeit in Größe 26pt mit Icon namens 'temperature_humidity'\<br />
"Keller"|hum ([TH_Keller_HM:humidity],26,"temperature_humidity")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable Funktion hum.png|ohne|mini]]<br />
<br />
=== Textformatierungen mit Hilfe der Funktion '''style''' ===<br />
Texte werden in Farbe, Größe und Schriftart statisch oder dynamisch formatiert.<br />
{{Randnotiz|RNText=uiTable-Funktion '''style'''<br />
<syntaxhighlight lang="perl"><br />
style ($text,$color,$font_size,$font_weight)<br />
<br />
$text # anzuzeigender Text<br />
$color # CSS color, optional<br />
$font_size # Schriftgröße in Pixel (pt), optional<br />
$font_weight # CSS Schriftart, optional<br />
</syntaxhighlight><br />
Mögliche Werte für '''''color''''' und '''''font_weight''''' können in einschlägiger Dokumentation zu CSS nachgeschlagen werden<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_style DOIF ##<br />
attr di_uiTable_style uiTable {\<br />
package ui_Table;;\<br />
}\<br />
## Tabellendefinition\<br />
\<br />
## statische Farbgebung, Größe, Schriftart \<br />
style("Montag","orange")\<br />
style("Dienstag","red",14)\<br />
style("Mittwoch","#00FFFF",20)\<br />
style("Donnerstag","blue",23,"bold")\<br />
\<br />
## dynamische Farbgebung abhängig vom Zustand des Gerätes 'Alarm'\<br />
style("Alarm",([Alarm:state] eq "on" ? "red":"green"))\<br />
\<br />
## dynamische Farbgebung des Zustands des Gerätes 'Alarm'\<br />
style([Alarm:state],([Alarm:state] eq "on" ? "red":"green"))\<br />
\<br />
## variabler Text abhängig vom Zustand des Gerätes 'Alarm'\<br />
style(([Alarm:state] eq "on" ? "Alarm aktiv":"Alarm deaktiviert"),"red")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Style.png|ohne|mini]]<br />
<br />
=== Icon-Darstellung mit Hilfe der Funktion '''ICON''' ===<br />
Mit Hilfe der Funktion '''ICON''' kann ein FHEM-Icon dargestellt werden<br />
{{Randnotiz|RNText=uiTable-Funktion '''ICON'''<br />
<syntaxhighlight lang="perl"><br />
ICON ($icon)<br />
<br />
$icon # Icon mit Farbgebung<br />
</syntaxhighlight><br />
<br />
'''ICON''' benutzt die Funktion [[DevelopmentFHEMWEB-API#FW_makeImage|FW_makeImage]]<br />
<br />
'''nützliche Links'''<br />
* [[DOIF/uiTable Schnelleinstieg#hsv-Funktion für Farbskalierungen|hsv-Funktion]]<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_Table_ICON DOIF ##<br />
attr di_Table_ICON uiTable {\<br />
package ui_Table;;\<br />
}\<br />
## Tabellendefinition\<br />
ICON("temp_frost") | ## Icon ohne Einfärbung\<br />
ICON("temp_frost\@blue") | ## Icon in CSS-Farbe blau\<br />
ICON("temp_frost\@#8A2BE2") | ## Icon in CSS-Farbe #8A2BE2\<br />
ICON("temp_frost\@".([Aussensensor:temperature] > 0 ? "orange":"blue"))| ## Icon in CSS-Farbe orange über Null Grad, sonst in CSS-Farbe blau\<br />
ICON("temp_frost\@".hsv ([Aussensensor:temperature],-20,40,320,0)) ## Icon in Farbskalierung von violett (-20 °C) bis rot (40 °C) mit Hilfe der Funktion hsv<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable_IC.png|mini|ohne]]<br />
<br />
=== Icon-Darstellung mit Text mit Hilfe der Funktion '''icon_label''' ===<br />
Mit Hilfe der Funktion '''icon_label''' kann ein FHEM-Icon mit einem angehängten Text/Wert dargestellt werden.<br />
{{Randnotiz|RNText=uiTable-Funktion '''icon_label'''<br />
<syntaxhighlight lang="perl"><br />
icon_label ($icon,$text,$color,$color_bg,$pos_left,$pos_top)<br />
$icon # FHEM-Icon mit Farboption<br />
$text # dargestellter Text<br />
$color # Farbe des Textes, optional<br />
$color # Hintergrundfarbe des Textes, optional<br />
$pos_left # horizontale Position des Textes in px, default -5, optional<br />
$pos_top # vertikale Position des Textes in px, default -8, optional<br />
</syntaxhighlight><br />
<br />
'''Anwendungsbeispiele'''<br />
* [[DOIF/uiTable Schnelleinstieg#Anzahl der Tage bis zur Abfall-Entsorgung|Abfall]]<br />
* [[DOIF/uiTable Schnelleinstieg#Visualisierung: aktueller Spritpreis|Sprit]]<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_icon_label DOIF ##<br />
attr di_uiTable_icon_label uiTable { package ui_Table;;\<br />
}\<br />
\<br />
icon_label("fuel",[Tankstelle:Diesel])|\<br />
icon_label("fuel",[Tankstelle:Diesel],"red")|\<br />
icon_label("fuel\@blue",[Tankstelle:Diesel],"blue","#999999")|\<br />
icon_label("fuel\@red",[Tankstelle:Diesel],"red","white",-10)|\<br />
icon_label("fuel",[Tankstelle:Diesel],"white","red",-5,8)\<br />
<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable_icon_label.png|mini|ohne]]<br />
<br />
=== Visualisierung eines Gerätes mit Hilfe der Funktion '''icon''' ===<br />
Der Zustand eines Gerätes/Readings wird mit Hilfe eines Icons dargestellt.<br />
{{Randnotiz|RNText=uiTable-Funktion '''icon'''<br />
<syntaxhighlight lang="perl"><br />
icon ($value,$icon_off,$icon_on,$state_off,$state_on)<br />
<br />
$value # Wert <br />
$icon_off # Icon für den Wert off, default "off"<br />
$icon_on # Icon für den Wert on, default Icon für Wert 'off' in Farbe 'DarkOrange', sonst Icon 'on', wenn $icon_off nicht definiert ist<br />
$state_off # Wert zugehörig zum Icon off, default "off"<br />
$state_on # Wert zugehörig zum Icon on, default "on"<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_icon DOIF ##<br />
attr di_uiTable_icon uiTable {\<br />
package ui_Table;;\<br />
}\<br />
## Tabellendefinition\<br />
\<br />
## Standard-Icon off/on für Standardwert off/on \<br />
"Lampe"|icon([Lampe:state]) ## entspricht icon([Lampe:state],"off","on","off","on")\<br />
\<br />
## Icon für Zustand 'off' ist 'hue_room_hallway', für Zustand 'on' 'hue_room_hallway\@DarkOrange'\<br />
"Flur"|icon([Lampeflur:state],"hue_room_hallway") ## entspricht icon([Lampeflur:state],"hue_room_hallway","hue_room_hallway\DarkOrange","off","on")\<br />
\<br />
## Icon für Zustand 'off' ist 'status_away_2', für Zustand 'on' 'status_available\@DarkOrange'\<br />
"Anwesenheit"|icon([Anwesenheit:state],"status_away_2","status_available\@DarkOrange") \<br />
\<br />
## Icon für Zustand 'closed' ist "status_locked", für Zustand 'open' 'status_open\@DarkOrange'\<br />
"Haus"|icon([Schloss:state],"status_locked","status_open\@DarkOrange","closed","open") <br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable icon.png|mini|ohne]]<br />
<br />
=== Schaltbares Icon mit Hilfe der Funktion '''switch''' ===<br />
Der Zustand eines Gerätes/Readings wird mit Hilfe eines Icons dargestellt, er kann über die WEB-Oberfläche durch Anklicken geschaltet werden. Damit der Zustand des Gerätes geschaltet werden kann, muss das Gerät den set-Befehl unterstützen.<br />
<br />
{{Randnotiz|RNText=uiTable-Funktion '''switch'''<br />
<syntaxhighlight lang="perl"><br />
switch ($value,$icon_off,$icon_on,$state_off,$state_on)<br />
<br />
$value # [<device>:<reading>] <br />
$icon_off # Icon für den Wert off, default "off"<br />
$icon_on # Icon für den Wert on, default Icon für Wert 'off' in Farbe 'DarkOrange', sonst Icon 'on', wenn $icon_off nicht definiert ist<br />
$state_off # Wert zugehörig zum Icon off, default "off"<br />
$state_on # Wert zugehörig zum Icon on, default "on"<br />
</syntaxhighlight><br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_switch DOIF ##<br />
attr di_uiTable_switch uiTable {\<br />
package ui_Table;;\<br />
}\<br />
## schaltbares Icons in der Webansicht \<br />
switch([Lampe:state]) | \<br />
switch([Lampeflur:state],"hue_room_hallway") |\<br />
switch([Anwesenheit:state],"status_away_2","status_available\@DarkOrange")|\<br />
switch([Haus:state],"status_locked","status_open\@DarkOrange","closed","open")\<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable switch.png|mini|ohne]]<br />
<br />
=== Rollladen: Visualisierung und Steuerung mit Hilfe der Funktion '''shutter''' ===<br />
Die aktuelle Position des Rollladens (0 % - 100 %) wird über Icons visualisiert. Das Anklicken eines Symbols steuert den Rollladen auf die entsprechende Position. Prozentwerte zwischen zwei Icon-Werten werden dem nächsthöheren Icon-Wert zugeordnet.<br />
{{Randnotiz|RNText=uiTable-Funktion '''shutter'''<br />
<syntaxhighlight lang="perl"><br />
shutter ($value,$color,$type)<br />
<br />
$value # [<device>:<reading>] <br />
$color # Farbe der aktuellen Rollladenposition, vorangestelltes @ verändert die Farbe des Icons, ohne @ wird der Hintergrund des Icons eingefärbt, default ist @DarkOrange<br />
$type # optional, Anzahl der Symbole 2 bis 6, 3 ist default<br />
</syntaxhighlight><br />
<br />
* [[DOIF/uiTable Schnelleinstieg#Visualisierung und Steuerung von Rollläden|Anwendungsbeispiel]]<br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod ui_Table_shutter DOIF ##<br />
attr ui_Table_shutter uiTable {\<br />
package ui_Table;;\<br />
}\<br />
shutter([R_Keller:pct],"\@yellow",2) ## zwei Symbole für 0 % und 100 %\<br />
shutter([R_Wohnzimmer_S:pct]) ## entspricht shutter ([R_Wohnzimmer_S:pct],"\@DarkOrange",3) \<br />
shutter([R_Wohnzimmer_W1:pct],"blue",4) ## vier Symbole \<br />
shutter([R_Wohnzimmer_W2:pct],"\@red",5) ## fünf Symbole\<br />
shutter([R_Wohnzimmer_W3:pct],"red",6 ## sechs Symbole)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable shutter.png|mini|ohne]]<br />
<br />
=== Helligkeit: Visualisierung und Steuerung mit Hilfe der Funktion '''dimmer''' ===<br />
Die aktuelle Helligkeit (0 % - 100 %) wird über Icons visualisiert. Das Anklicken eines Icons bestimmt die Helligkeit der Leuchte. Prozentwerte zwischen zwei Icon-Werten werden dem nächsthöheren Icon-Wert zugeordnet.<br />
{{Randnotiz|RNText=uiTable-Funktion '''dimmer'''<br />
<syntaxhighlight lang="perl"><br />
dimmer ($value,$color,$type)<br />
<br />
$value # [<device>:<reading>] <br />
$color # Farbe der aktuellen Helligkeit, vorangestelltes @ verändert die Farbe des Icons, ohne @ wird der Hintergrund des Icons eingefärbt, default ist @DarkOrange<br />
$type # Anzahl der Symbole 2 bis 7, 3 ist default<br />
</syntaxhighlight><br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_dimmer DOIF ##<br />
attr di_uiTable_dimmer uiTable {\<br />
package ui_Table;;\<br />
}\<br />
dimmer([Strauch3:pct],"\@yellow",2)\<br />
dimmer([Strauch3:pct]) ## entspricht dimmer([Strauch3:pct],"\@DarkOrange",3) \<br />
dimmer([Strauch3:pct],"blue",4)\<br />
dimmer([Strauch3:pct],"\@red",5)\<br />
dimmer([Strauch3:pct],"red",6)\<br />
dimmer([Strauch3:pct],"DarkOrange",7)<br />
<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable dimmer.png|mini|ohne]]<br />
<br />
=== Vorgabetemperatur eines Thermostats mit Hilfe der Funktion '''temp_knob''' ===<br />
Die aktuelle Vorgabetemperatur eines Thermostats wird über ein Icons visualisiert. Durch Anklicken des Ringes wird die Vorgabetemperatur verändert.<br />
{{Randnotiz|RNText=uiTable-Funktion '''temp_knob'''<br />
<syntaxhighlight lang="perl"><br />
temp_knob ($value,$color,$set)<br />
<br />
$value # [<device>:<reading>] <br />
$color # Farbe der voreingestellten Temperatur, default "Darkorange"<br />
$set # set-Befehl, default "set", sonst muss "set <Readingname>" angegeben werden, falls sich das Reading vom set-Befehl vom angezeigten Reading unterscheidet, wie beim THRESHOLD-Modul<br />
</syntaxhighlight><br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod ui_Table_temp_knob DOIF ##<br />
attr ui_Table_temp_knob uiTable {\<br />
package ui_Table;;\<br />
}\<br />
\<br />
## HM-EU-Thermostat, angezeigt wird das Reading "desired-temp", geschaltet wird über "set desired-temp" \<br />
"Dachgeschoss"|temp_knob([TH_DG_HM:desired-temp]) ## entspricht temp_knob([TH_DG_HM:desired-temp],"Darkorange","set") \<br />
\<br />
## HM-EU-Thermostat Temperaturanzeige in gelb \ <br />
"Wohnzimmer"|temp_knob([TH_WZ_HM:desired-temp],"yellow") \<br />
\<br />
## Beim THRESHOLD-Modul wird das Reading "desired_value" angezeigt, geändert wird die Temperatur per "set desired" \<br />
"Küche"|temp_knob([TH_Kueche:desired_value],"red","set desired")<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable temp knob.png|mini|ohne]]<br />
<br />
== uiTable-'''Templates''' ==<br />
Die Definition einer oder mehrere Zellen kann zu einem Template zusammengefasst werden. Durch die Nutzung von Templates kann die Definition einer Tabelle erheblich vereinfacht werden. Insb. bei gleichartigen Zellen/Zeilen für verschiedene Geräte/Readings braucht eine aufwendige Definition nicht immer wieder wiederholt werden, sondern kann jeweils mit dem Aufruf eines zuvor definierten Templates realisiert werden.<br />
{{Randnotiz|RNText='''Templates'''<br />
* Die Definition von Templates muss vor der Tabellendefinition vorgenommen werden<br />
* Eine Template-Definition beginnt mit dem Schlüsselwort '''DEF'''<br />
* Der Template-Name muss mit '''TPL_''' beginnen<br />
* '''Template-Definition'''-Syntax<br />
<syntaxhighlight lang="perl"><br />
DEF TPL_<Template-Name>(<Zellendefinition mit Platzhaltern: $1,$2,...>)<br />
</syntaxhighlight><br />
* Templates-Definitionen können in externe Dateien ausgelagert werden<br />
* Templates-Definitionen können per IMPORT-Befehl aus externen Dateien importiert werden<br />
* '''Template-Import'''-Syntax<br />
<syntaxhighlight lang="perl"><br />
IMPORT <Pfad mit Dateinamen><br />
</syntaxhighlight><br />
* Innerhalb einer Tabellendefinition können zuvor definierte oder importierte Templates mehrfach genutzt werden<br />
* '''Template-Aufruf'''-Syntax<br />
<syntaxhighlight lang="perl"><br />
TPL_<Template-Name>(<Übergabeparameter für $1>,<Übergabeparameter für $2>,...)<br />
</syntaxhighlight><br />
}}<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod ui_Table_Template DOIF ##<br />
attr ui_Table_Template uiTable {\<br />
package ui_Table;;\<br />
$TC{1..3}="align='center'";; ## Spalten 1 bis 3 werden zentriert\<br />
}\<br />
\<br />
## Template-Definitionen beginnen vor der Tabellendefinition\<br />
\<br />
## Das Template TPL_raum stellt eine Tabellenzeile dar, die mit Hilfe von uiTable-Funktionen mehrere Tabellenzellen definiert\<br />
DEF TPL_raum ("$1" | temp([TH_$2_HM:measured-temp]),hum([TH_$2_HM:humidity]) | switch([H_$2:state],"fa_off") | temp_knob([TH_$2_HM:desired-temp]))\<br />
\<br />
## Tabellendefinition\<br />
\<br />
## pro Tabellenzeile wird ein Raum mit Hilfe des oben definierten Templates "TPL_raum" dargestellt\<br />
"Raum"|"Temp./Feuchte"|"Ventil"|"Vorgabetemp."\<br />
TPL_raum (Dachgeschoss,DG) ## der Übergabeparameter "Dachgeschoss" wird im Template "TPL_raum" anstelle von $1 eingesetzt, "DG" wird anstelle von $2 eingesetzt\<br />
TPL_raum (Bad,Bad)\<br />
TPL_raum (Kinderzimmer ost,Kz_o)\<br />
TPL_raum (Kinderzimmer west,Kz_w)\<br />
TPL_raum (Wohnzimmer,WZ)\<br />
TPL_raum (Keller,Keller)<br />
<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable Templates.png|mini|ohne]]<br />
<br />
== Eigene uiTable-Funktionen programmieren ==<br />
Für die eigenen Bedürfnisse können eigene uiTable-Funktionen programmiert werden. In der Datei [https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DOIF/uiTable.tpl contrib/DOIF/uiTable.tpl] befinden sich alle intern definierten uiTable-Funktion aus dem package ui_Table als Kopie. Diese Funktionen können als Inspiration für eigene Entwicklung dienen. <br />
{{Randnotiz|RNText='''uiTable-Funktionen'''<br />
* Es gibt drei Arten von uiTable-Funktionen, sie werden intern anhand der Rückgabewerte unterschieden<br />
* uiTable-Funktionen vom Typ 1: '''HTML''', ein Rückgabewert<br />
<syntaxhighlight lang="perl"><br />
return(<HTML-code>)<br />
</syntaxhighlight><br />
* uiTable-Funktionen vom Typ 2: '''Style''' (entspricht der '''STY'''-Funktion), zwei Rückgabewerte<br />
<syntaxhighlight lang="perl"><br />
return(<value>,<CSS-style>)<br />
</syntaxhighlight><br />
* uiTable-Funktionen vom Typ 3: '''Widget''' (entspricht der '''WID'''-Funktion), vier Rückgabewerte<br />
<syntaxhighlight lang="perl"><br />
return (<value>,<>,<FHEM-widget>,<set-command: "" or "set" or "set <Readingname>">)<br />
</syntaxhighlight><br />
* uiTable-Funktionen sind reine Perlfunktionen<br />
* uiTable-Funktionen sollten im eigenen Package definiert werden, sonst könnten bestehende Perlfunktionen im System überschrieben werden<br />
* uiTable-Funktionen können in Template-Dateien ausgelagert werden und über IMPORT-Befehl importiert werden, siehe Templates<br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_function DOIF ##<br />
attr di_uiTable_function uiTable {\<br />
package my_uiTable;; ## eigenes Package mit selbstdefinierten Funktionen\<br />
\<br />
## uiTable-Funktion vom Typ "HTML", Rückgabewert: (HTML-code)\<br />
\<br />
sub clock { ## Anzeige aktueller Uhrzeit mit Datum\<br />
## Voraussetzung: contrib/DOIF/doifclock.js muss ins www/pgm2-Verzeichnis kopiert werden\<br />
## Attribut setzen in der Webinstanz: attr <WEB-Instanz> JavaScripts pgm2/doifclock.js \<br />
my ($color,$size)=@_;;\<br />
$color="darkorange" if (!defined ($color));; ## $color ist optional, default Darkorange\<br />
$size="20" if (!defined ($size));; ## $size ist optional, default 20pt\<br />
return("<div class='doifclock'style='font-weight:bold;;font-size:".$size."pt;;color:".$color.";;'>error</div>")\<br />
}\<br />
\<br />
## uiTable-Funktion vom Typ Style, Rückgabewerte (Wert,CSS-style)\<br />
\<br />
sub red_green { ## Farbige Skalierung von Zahlen mit Hilfe der DOIF_hsv-Funktion: von 0 - rot bis 10 - grün\<br />
my ($value)=@_;;\<br />
return ($value." KW", ## Wert/Text\<br />
"font-weight:bold;;color:".::DOIF_hsv ($value,0,10,0,120,70,100) ## CSS-Style\<br />
);;\<br />
} \<br />
\<br />
## uiTable-Funktion vom Typ Widget, Rückgabewerte (Wert,Leer,FHEM-Widget,set-Befehl)\<br />
\<br />
sub slider { ## FHEM-Widget Slider, weitere FHEM-Widgets siehe: https://wiki.fhem.de/wiki/FHEMWEB/Widgets\<br />
my ($value,$set)=@_;;\<br />
$set="" if (!defined $set);;\<br />
return ($value, ## Zahlenwert\<br />
"", ## leer\<br />
"slider,0,0.5,100,1", ## FHEM-Widget\<br />
$set ## set-Befehl des FHEM-Widgets\<br />
) \<br />
}\<br />
\<br />
}\<br />
\<br />
## Tabellendefinition\<br />
\<br />
"Uhrzeit/Datum"\<br />
clock("yellow",30) ## obige Funktion clock\<br />
"Dimmer"\<br />
slider([Wohnzimmer:pct]) ## obige Funktion slider\<br />
"Leistung"\<br />
red_green([Leistung:state]) ## obige Funktion red_green<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-functions.png|mini|ohne]]<br />
<br />
== Package-Konzept, Auslagerung eigener Funktionen, der '''IMPORT'''-Befehl==<br />
uiTable arbeitet mit Packages. In einem Package sind definierte Funktionen gekapselt, sie kollidieren nicht mit bereits definierten Funktionen in FHEM.<br />
{{Randnotiz|RNText='''Package'''<br />
* das für die Definition der Tabelle gültige Package wird im Perlblock des uiTable-Attributes angegeben<br />
* interne uiTable-Funktionen befinden sich im Package '''ui_Table'''<br />
* ohne eine Angabe eines Package befindet man sich im Package '''main'''<br />
* Funktionen außerhalb des gültigen Package müssen mit <package-Name>::<Funktion> angegeben werden<br />
* externe uiTable-Funktionen können per IMPORT-Befehl importiert werden<br />
}} <br />
=== Tabellendefinition im Package main ===<br />
<syntaxhighlight lang="perl"><br />
defmod beispiel1 DOIF ##<br />
attr beispiel1 uiTable ## keine Package-Definition im Perlblock\<br />
\<br />
## Tabellendefinition befindet sich im Package main\<br />
\<br />
## Funktionen aus dem main-Package können unmittelbar angegeben werden\<br />
FW_makeImage("scene_day")\<br />
\<br />
## Funktionen aus dem ui_Table-Package müssen mit vorangestelltem Package angegeben werden\<br />
ui_Table::temp ([Aussensensor:tempaerature])<br />
</syntaxhighlight><br />
<br />
=== Tabellendefinition im Package ui_Table ===<br />
<syntaxhighlight lang="perl"><br />
defmod beispiel2 DOIF ##<br />
attr beispiel2 uiTable {\<br />
package ui_Table; ## Package-Angabe im Perlblock\<br />
}\<br />
\<br />
## Tabellendefinition befindet sich im Package ui_Table\<br />
\<br />
## Funktionen aus dem main-Package müssen mit vorangestelltem package angegeben werden, der Name main kann weggelassen werden\<br />
::FW_makeImage("scene_day")\<br />
\<br />
## Funktionen aus dem ui_Table-Package können direkt angegeben werden\<br />
temp ([Aussensensor:temperature])<br />
</syntaxhighlight><br />
<br />
=== Eigene uiTable-Funktionen im eigenen Package ===<br />
Diese Art der Definition bietet sich dann an, wenn man eine eigene uiTable-Funktion nur in einem DOIF nutzen möchte.<br />
<syntaxhighlight lang="perl"><br />
defmod beispiel3 DOIF ##<br />
attr beispiel3 uiTable {\<br />
package $SELF;; ## Package-Name ist der Name des DOIF-Moduls, dadurch ist der Package-Name eindeutig\<br />
sub scene_day { ## eigene Funktion befindet sich im eigenen Package beispiel3\<br />
return (::FW_makeImage("scene_day"));;\<br />
}\<br />
}\<br />
## Tabellendefinition befindet sich im Package beispiel3\<br />
\<br />
## Funktionen aus dem main-Package müssen mit vorangestelltem Package angegeben werden (der Name main kann weggelassen werden)\<br />
::FW_makeImage("scene_day")\<br />
\<br />
## interne Funktionen aus dem ui_Table-Package müssen mit vorangestelltem Package ui_Table angegeben werden\<br />
ui_Table::temp ([Aussensensor:temperature])\<br />
\<br />
## eigene Funktionen können direkt angegeben werden\<br />
scene_day()<br />
</syntaxhighlight><br />
<br />
=== Eigene ausgelagerte uiTable-Funktionen ===<br />
Möchte man das ui_Table-Package um eigene Funktionen erweitern, die man in verschiedenen DOIFs nutzen möchte, so sollte man diese in eine eigene Datei auslagern, die man mit dem IMPORT-Befehl vor der Definition der Tabelle importieren kann.<br />
<br />
Ausgelagerte Funktion in einer eigenen Datei z. B. my_uiTable.tpl:<br />
<br />
<syntaxhighlight lang="perl"><br />
{ ## Inhalt der Datei my_uiTable.tpl<br />
package ui_Table; ## das aktuelle Package ist ui_Table<br />
sub scene_day { ## eigene Funktion wird zum Package ui_Table hinzugefügt <br />
return (::FW_makeImage("scene_day"));<br />
}<br />
## die Datei kann alle Funktionen beinhalten, die man in diversen DOIFs nutzen möchte<br />
}<br />
</syntaxhighlight><br />
<br />
<syntaxhighlight lang="perl"><br />
defmod beispiel4 DOIF ##<br />
attr beispiel4 uiTable ##\<br />
\<br />
IMPORT ./contrib/DOIF/my_uiTable.tpl ## nach dem Import befindet man sich in Package ui_Table erweitert um eigene Funktionen\<br />
\<br />
## Tabellendefinition befindet sich im Package ui_Table\<br />
\<br />
## Funktionen aus dem main-Package müssen mit vorangestelltem Package angegeben werden (der Name main kann weggelassen werden)\<br />
::FW_makeImage("scene_day")\<br />
\<br />
## interne uiTable-Funktionen aus dem ui_Table-Package können direkt angegeben werden\<br />
temp ([Aussensensor:temperature])\<br />
\<br />
## eigene Funktionen können direkt angegeben werden, da man sich bereits im Package uiTable befinden\<br />
scene_day()\<br />
</syntaxhighlight><br />
<br />
== '''hsv'''-Funktion für Farbskalierungen==<br />
Mit Hilfe der hsv-Funktion können Texte, Werte oder Icons abhängig vom Wert eingefärbt werden. Es wird durch Vorgabe von Farbsättigung (saturation) und Helligkeit (lightness), linear ein Farbton für einen bestimmten Wert errechnet. Den Farbwert HUE (0 - 360) für den kleinsten sowie größten Wert kann man mit Hilfe eines Color-Pickers bestimmen. Der Rückgabewert ist ein Farbwert in der CSS-Notation.<br />
{{Randnotiz|RNText='''hsv-Funktion für Farbskalierungen'''<br />
<syntaxhighlight lang="perl"><br />
hsv ($value,$min_value,$max_value,$min_hue,$max_hue,$saturation,$lightness)<br />
$value # Wert, Reading<br />
$min_value # der kleinste Wert, dieser entspricht dem Farbwert $min_hue<br />
$max_value # der größte Wert, dieser entspricht dem Farbwert $max_hue<br />
$min_hue # Farbwert für den kleinsten Wert $min_value<br />
$max_hue # Farbwert für den größten Wert $max_value<br />
$saturation # Farbsättigung, default 100, optional<br />
$lightness # Farbhelligkeit, default 100, optional<br />
</syntaxhighlight><br />
Die Funktion befindet sich im ui_Table-Package<br />
}}<br />
<br />
'''<big>Beispieldefinition</big>'''<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_hsv DOIF ##<br />
attr di_uiTable_hsv uiTable {\<br />
package ui_Table;;\<br />
## eigene uiTable-Funktionen vom Typ 1 mit einem Rückgabewert als HTML-Code\<br />
\<br />
sub bat_icon { ## färbt das Icon 'measure_battery_100' abhängig vom Wert mit Hilfe der Funktion hsv \<br />
my ($value)=@_;;\<br />
return(ICON("measure_battery_100\@".hsv($value,0,100,0,120,100,100)))\<br />
}\<br />
\<br />
sub bat_icon2 {## zusätzlich zum Farbwert wird ein entsprechendes Icon bestimmt\<br />
my($val)=@_;;\<br />
my $icon;;\<br />
if ($val==0) {\<br />
$icon="measure_battery_0";;\<br />
} elsif ($val<=25) {\<br />
$icon="measure_battery_25";;\<br />
} elsif ($val<=50) {\<br />
$icon="measure_battery_50";;\<br />
} elsif ($val<=75) {\<br />
$icon="measure_battery_75";;\<br />
} else {\<br />
$icon="measure_battery_100";;\<br />
}\<br />
\<br />
my $output=ICON("$icon\@".hsv ($val,0,100,0,120,90,100));;\<br />
return($output);;\<br />
}\<br />
}\<br />
\<br />
## Tabellendefinition\<br />
\<br />
## eingefärbtes Icon 0 % entspricht rot (HSV-Wert 0), 100 % entspricht grün (HSV-Wert 120) mit Direktangabe\<br />
1|ICON("measure_battery_100\@".hsv([bat:level],0,100,0,120,100,100))\<br />
\<br />
## gleiche Funktionalität mit Hilfe der oben definierten Funktion bat_icon \<br />
2|bat_icon([bat:level])\<br />
\<br />
## Icon mit Hilfe der oben definierten Funktion bat_icon2\<br />
3|bat_icon2([bat:level])\<br />
\<br />
## Beispiel für die Farbskaliereung von 0 bis 100 % mit der obigen Funktion bat_icon\<br />
4|bat_icon(0)|bat_icon(10)|bat_icon(20)|bat_icon(30)|bat_icon(40)|bat_icon(50)|bat_icon(60)|bat_icon(70)|bat_icon(80)|bat_icon(90)|bat_icon(100)\<br />
\<br />
## Beispiel für die Farbskaliereung von 0 bis 100 % mit der obigen Funktion bat_icon2\<br />
5|bat_icon2(0)|bat_icon2(10)|bat_icon2(20)|bat_icon2(30)|bat_icon2(40)|bat_icon2(50)|bat_icon2(60)|bat_icon2(70)|bat_icon2(80)|bat_icon2(90)|bat_icon2(100)<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable DOIF hsv.png|mini|ohne]]<br />
<br />
== Eine for-Schleife mit Hilfe des '''FOR'''-Befehls ==<br />
Mit Hilfe des '''FOR'''-Befehls können über eine Schleife aus einer Liste mit Elementen mehrere Tabellenzellen definiert werden. Die Elementenliste (Array) kann über eine Funktion bestimmt werden. Auf diese Weise kann z. B. eine Tabelle für mehrere Geräte einfach definiert werden.<br />
{{Randnotiz|RNText='''FOR-Befehl'''<br />
* Der FOR-Befehl entspricht einer foreach-Schleife in Perl<br />
* Syntax: '''FOR (<Array>,<Zellendefinitionen>)'''<br>'''<Array>''' eine gültige Angabe eines Arrays oder eine Perlfunktion, die ein Array liefert<br>'''<Zellendefinitionen>''' Definition einer oder mehrerer Zellen, die Angabe $_ wird durch das jeweilige Element des Arrays ersetzt<br />
*'''nützliche Links'''<br />
**{{Link2CmdRef|Anker=DOIF_aggregation|Lang=de|Label=DOIF Aggregationsfunktionen mit Perlfunktion AggrDoIf}}<br />
**[[DevelopmentModuleAPI#devspec2array|devspec2array]]<br />
}}<br />
'''<big>Beispieldefinitionen</big>'''<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## Temperaturen aller Geräte, die mit 'T' beginnen und ein Reading 'temperature' haben, sollen in einer Tabelle visualisiert werden\<br />
FOR(::AggrDoIf('@','^T_','temperature'),"$_"|temp([$_:temperature:d2]))<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR-temperature.png|200px|ohne]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## Anzeige des Batteriestatus aller Geräte, bei denen das Wort 'Fenster' vorkommt, die das Readings 'battery' haben\ <br />
FOR(::AggrDoIf('@','Fenster','battery'),"$_"|bat([$_:battery]))<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR-battery.png|200px|ohne]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## Anzeige des Status aller Geräte im System vom Typ 'HMS'\<br />
FOR(::devspec2array("TYPE=HMS"),"$_"|[$_])<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR-HMS.png|300px|ohne]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## Elemente einer kommagetrennten Liste sollen jeweils in einer Tabellenzelle in einer Tabellenzeile angezeigt werden\<br />
FOR(split(",","Mo,Di,Mi,Do,Fr,Sa,So"),ui_Table::style("$_","Darkorange")|)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR-split.png|300px|ohne]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## Durch Leerzeichen getrennte Zeichenketten sollen jeweils in einer Tabellenzelle in einer Tabellenzeile angezeigt werden\<br />
FOR(qw/Montag Dienstag Mittwoch Donnerstag Freitag/,"$_"|)<br />
</syntaxhighlight><br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR-qw.png|300px|ohne]]<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_for DOIF ##<br />
attr di_for uiTable \<br />
## das Templates TPL_raum, soll vier mal aufgerufen werden: TPL_raum(1), TPL_raum(2)...\<br />
## das Templates TPL_raum muss vorher definiert worden sein\<br />
FOR(1..4,TPL_raum($_))<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable-FOR TPL raum.png|600px|ohne]]<br />
<br />
== '''Anwendungsbeispiele''' ==<br />
=== '' Visualisierung und Steuerung von '''Rollläden''''' ===<br />
Im folgenden Beispiel werden Rollläden morgens hochgefahren, ebenso wird die Position aller Rollläden visualisiert. Durch Anklicken eines Icons wird der Rollladen auf die entsprechende Position bewegt. <br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* {{Link2CmdRef|Anker=DOIF_Zeitsteuerung_mit_Zeitintervallen|Lang=de|Label=Zeitsteuerung}}<br />
* uiTable-Funktion [[DOIF/uiTable Schnelleinstieg#Rollladen: Visualisierung und Steuerung mit Hilfe der Funktion shutter|shutter]]<br />
* uiTable-Funktion [[DOIF/uiTable Schnelleinstieg#Textformatierungen mit Hilfe der Funktion style|style]]<br />
* [[DOIF/uiTable Schnelleinstieg#uiTable-Templates|Templates]]<br />
}}<br />
<syntaxhighlight lang="perl"><br />
defmod DI_Rollladen DOIF (([Dunkelheit] eq "off" and [06:25-09:00|8]) or [09:00|7]) \<br />
((set R_W_S,R_W_W[1-3] on)) ## Hochfahren der Rollläden im Erdgeschoss morgens\<br />
DOELSEIF ([Dunkelheit] eq "on")<br />
attr DI_Rollladen cmdState oben|unten<br />
attr DI_Rollladen devStateIcon unten:status_night oben:scene_day<br />
attr DI_Rollladen icon fts_shutter_automatic<br />
attr DI_Rollladen uiTable {\<br />
package ui_Table;;\<br />
}\<br />
\<br />
## Template für ein Fenster\<br />
DEF TPL_shutter("$1"|shutter([$1:pct]))\<br />
\<br />
## Tabellendefinition\<br />
\<br />
style("Dachgeschoss","Darkorange")|""\<br />
TPL_shutter(R_Dachboden)\<br />
style("erstes Geschoss","Darkorange")|""\<br />
TPL_shutter(R_Bad)\<br />
TPL_shutter(R_Kinderzimmer1_O)\<br />
TPL_shutter(R_Kinderzimmer1_S)\<br />
TPL_shutter(R_Kinderzimmer2_S)\<br />
TPL_shutter(R_Kinderzimmer2_W1)\<br />
TPL_shutter(R_Kinderzimmer2_W2)\<br />
style("Erdgeschoss","Darkorange")|""\<br />
TPL_shutter(R_Kueche)\<br />
TPL_shutter(R_W_S)\<br />
TPL_shutter(R_W_W1)\<br />
TPL_shutter(R_W_W2)\<br />
TPL_shutter(R_W_W3)\<br />
style("Keller","Darkorange")|""\<br />
TPL_shutter(R_Keller)\<br />
</syntaxhighlight><br />
''Ergebnis des Anwendungsbeispiels in der Webansicht:''<br />
[[Datei:UiTable Rollladen.png|mini|ohne]]<br />
<br />
=== ''Anzahl der Tage bis zur '''Abfall-Entsorgung''''' ===<br />
Mit Hilfe des Kalender-Moduls werden die verbleibenden Tage bis zur Abfall-Entsorgung der jeweiligen Tonne berechnet und mit Hilfe von uiTable visualisiert. Wenn der Tag der Entsorgung bevorsteht, wird er farbig gekennzeichnet. Vorausgesetzt wird die Definition des Kalenders namens 'cal' mit Hilfe des Moduls [[Calendar]]. Dieser muss die Termine der Abfallentsorgung der Tonnen beinhalten. Im Beispiel wird nach Stichwörtern: "Altpapier", "Restmüll", "Bio", "Gelber" und "Grünschnitt" im Kalender gesucht. <br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* FHEM-Modul [[Calendar]]<br />
* ui_Table Funktion [[DOIF/uiTable Schnelleinstieg#Icon-Darstellung mit Text mit Hilfe der Funktion icon_label|icon_label]]<br />
}}<br />
<syntaxhighlight lang="perl"><br />
defmod Abfall DOIF subs {\<br />
## Die Funktion 'days' sucht nach dem Ereignis $event im Kalender und berechnet die Anzahl der verbleibenden Tage und legt sie im entsprechendem Reading $reading des DOIF-Moduls ab\<br />
sub days \<br />
{\<br />
my ($event,$reading)=@_;;\<br />
set_Reading($reading,fhem('get cal events timeFormat:"%j" filter:field(summary)=~"'.$event.'" limit:count=1,from=0 format:custom="$T1"')-::strftime ('%j', localtime()),1)\<br />
}\<br />
## Die Funktion 'update' bestimmt die verbleibenden Tage mit Hilfe der obigen Funktion 'days' für die jeweiligen Tonnen\<br />
sub update\<br />
{\<br />
days("Altpapier","altpapier");;days("Restmüll","restmuell");;days("Bio","bio");;days("Gelber","gelbe_tonne");;days("Grünschnitt","gruenschnitt");;\<br />
}\<br />
}\<br />
## Beim Start, um 02:00 Uhr und 08:00 Uhr wird zeitverzögert die obige Funktion 'update' aufgerufen\<br />
init {[02:00];;[08:00];;set_Exec("Timer",60,'update()');;\<br />
}<br />
attr Abfall uiTable {\<br />
package ui_Table;;\<br />
$TC{0..4}="align='center'";;\<br />
$SHOWNOSTATE=1;;\<br />
\<br />
## die Funktion 'ic' benutzt die Funktion 'icon_label' für die Darstellung des Icons, abhängig von der Anzahl der Tage wird die Anzahl in grün bzw. rot eingefärbt \<br />
sub ic\<br />
{\<br />
my ($icon,$days)=@_;;\<br />
icon_label($icon,$days,"white",$days > 1 ? "green":"red")\<br />
}\<br />
}\<br />
## Tabellendefinition, die einzelnen Tonnen werden mit Hilfe der obigen Funkton 'ic' dargestellt\<br />
\<br />
ic ("Abfalltonne-Recycling-Logo\@yellow",[$SELF:gelbe_tonne])|\<br />
ic ("Abfalltonne-Recycling-Logo\@blue",[$SELF:altpapier])|\<br />
ic ("Abfalltonne\@gray",[$SELF:restmuell])|\<br />
ic ("Abfalltonne-Recycling-Logo\@green",[$SELF:bio])|\<br />
ic ("Gartenabfall\@green",[$SELF:gruenschnitt])<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Anwendungsbeispiel Abfall.png|mini|ohne]]<br />
<br />
=== ''Visualisierung: '''offene Fenster''''' ===<br />
Alle offenen Fenster werden aufgelistet und mit entsprechendem Icon visualisiert.<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* Attribut {{Link2CmdRef|Anker=DOIF_DOIF_Readings|Lang=de|Label=DOIF_Readings}}<br />
* DOIF-{{Link2CmdRef|Anker=DOIF_aggregation|Lang=de|Label=Aggregationsfunktionen}}<br />
* uiTable-Funktion [[DOIF/uiTable Schnelleinstieg#Icon-Darstellung mit Hilfe der Funktion icon|icon]]<br />
}}<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_windows DOIF ## Visualisierung offener Fenster, Fenster-Devices enden mit "Fenster" im Namen<br />
attr di_uiTable_windows DOIF_Readings windows:[@as(<br>)"Fenster$":state:"open","keine"]<br />
attr di_uiTable_windows uiTable {package ui_Table;;}\<br />
icon([$SELF:windows],"fts_window_1w_open\@DarkOrange","fts_window_1w",".*","keine")|[$SELF:windows]<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable windows closed.png|mini|ohne]]<br />
[[Datei:UiTable windows open.png|mini|ohne]]<br />
<br />
=== ''Visualisierung: '''aktuelle Wetterlage''''' ===<br />
Regenrader animiert, aktuelle Temperatur und Feuchte vom Sensor, aktuelle Wetterlage sowie Wettervorhersage der nächsten Tage. Über entsprechende Weblinks werden Bilder aus dem WWW in der Tabelle visualisiert. Im Gegensatz zu lokalen Sensoren, muss für die Aktualisierung der WWW-Elemente in der jeweiligen Webinstanz (FHEMWEB) das refresh-Attribut gesetzt werden. <br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* DWD [https://www.dwd.de/DE/Home/home_node.html Homepage]<br />
* Regenradar [https://www.dwd.de/DE/wetter/wetterundklima_vorort/_node.html Radarfilm BRD]<br />
* aktuelles Wetter [https://www.dwd.de/DE/wetter/wetterundklima_vorort/nordrhein-westfalen/nrw_node.html NRW]<br />
* Wetteronline [https://www.wetteronline.de/wetter-widget eignes Widget]<br />
* <br />
}}<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_uiTable_wetter DOIF ##<br />
attr di_uiTable_wetter uiTable {\<br />
package ui_Table;;\<br />
$TC{1}="align='center'";;\<br />
}\<br />
## das Attribut 'refresh' der Webinstanz für ein Wandtablet wurde auf 900 gesetzt, damit die Bilder alle 15 Minuten aktualisiert werden \<br />
## Tabellendefinition\<br />
\<br />
## Regenradar BRD\<br />
'<img src="https://www.dwd.de/DWD/wetter/radar/radfilm_brd_akt.gif" height="365px" width="365px">'|\<br />
\<br />
## Aktuelle Temperatur und Feuchtigkeit vom lokalen sensor\<br />
temp([Aussensensor:temperature],40),hum ([Aussensensor:humidity],30),\<br />
\<br />
## aktuelle Wetterlage NRW\<br />
"<img src ='https://www.dwd.de/DE/wetter/wetterundklima_vorort/nordrhein-westfalen/_functions/bildgalerie/wetter_aktuell.jpg?view=nasImage&nn=561200' height='255px' width='255px'>"|\<br />
\<br />
## Wettervorhersage\<br />
"<iframe marginheight='0' marginwidth='0' scrolling='no' width='300' height='365' name='FC3' style='border:1px solid;;border-color:#00537f;;' src='https://api.wetteronline.de/wetterwidget?gid=x0677&modeid=FC3&seourl=juelich&locationname=Jülich&lang=de'></iframe>"\<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable wetter.png|600px|links]]<br />
<br clear="all"><br />
<br />
=== ''Visualisierung: '''Wetterstation''''' ===<br />
Die vorgestellte Lösung funktioniert ohne Anmeldung beim Wetterdienst und ohne Nutzung von API.<br />
Über den Wetterdienst: https://www.wunderground.com/ werden sehr viele private Wifi-Wetterstationen eingebunden. Das kann man sich zunutze machen, indem man zunächst in seiner Umgebung nach Wetterstationen des Dienstes sucht - oft findet man im Umkreis von wenigen Kilometern schon einige Stationen, die rege Wetterdaten liefern. Danach definiert man über HTTPMOD seine Station und visualisiert diese anschließend.<br />
<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* Wunderground [https://wunderground.com/ Homepage]<br />
* svg-Funktion [https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#Anzeige_eines_Werteverlaufs_und_des_aktuellen_Wertes_mit_Hilfe_der_SVG-Funktion_card card]<br />
* svg-Funktionen [https://wiki.fhem.de/wiki/DOIF/uiTable_Schnelleinstieg#icon_ring-Funktionen icon_ring]<br />
}}<br />
Definition einer Station in der Nachbarschaft. <StationsID> muss gegen die korrekte Stationsnummer ersetzt werden.<br />
<syntaxhighlight lang="perl"><br />
defmod Wetter HTTPMOD https://www.wunderground.com/dashboard/pws/<StationsID><br />
attr Wetter enableControlSet 1<br />
attr Wetter reading01Name Wind<br />
attr Wetter reading01Regex wu-unit .{109}>(\d+\.\d)<br />
attr Wetter reading02Name Windboeen<br />
attr Wetter reading02Regex wu-unit-speed .{109}>(\d+\.\d)<br />
attr Wetter reading03Name Windrichtung<br />
attr Wetter reading03Regex (\d+)deg\).{84}Wind-Marker<br />
attr Wetter reading04Name Regen<br />
attr Wetter reading04Regex wu-unit-rainRate .{109}>(\d+\.\d\d)<br />
attr Wetter reading05Name RegenGesamt<br />
attr Wetter reading05Regex wu-unit-rain .{109}>(\d+\.\d\d)<br />
attr Wetter reading06Name Temperatur<br />
attr Wetter reading06Regex wu-unit-temperature .{127}>(\d+.\d)<br />
attr Wetter reading07Name Feuchtigkeit<br />
attr Wetter reading07Regex wu-unit-humidity .{109}>(\d\d)<br />
attr Wetter reading08Name UV<br />
attr Wetter reading08Regex UV<.{268}>(\d)<br />
attr Wetter reading09Name Luftdruck<br />
attr Wetter reading09Regex PRESSURE<.{285}>(\d+.\d+)<br />
attr Wetter reading10Name TemperaturGefuehlt<br />
attr Wetter reading10Regex wu-unit is-degree-visible .{109}>(\d+.\d)<br />
attr Wetter reading11Name TaupunktTemp<br />
attr Wetter reading11Regex DEWPOINT.{306}>(\d+.\d)<br />
attr Wetter reading12Name Sonnenstrahlung<br />
attr Wetter reading12Regex Solar radiation<.{549}>(\d+.\d+)<br />
attr Wetter timeout 10<br />
attr Wetter userReadings WindKm {sprintf("%1.1f",ReadingsVal($name,"Wind",0)*1.60934)},\<br />
WindboeenKm {sprintf("%1.1f",ReadingsVal($name,"Windboeen",0)*1.60934)},\<br />
WindrichtungGrad {ReadingsVal($name,"Windrichtung",0)-180},\<br />
RegenMm {ReadingsVal($name,"Regen",0)*25.4},\<br />
RegenGesamtMm {ReadingsVal($name,"RegenGesamt",0)*25.4},\<br />
TemperaturC {sprintf("%1.1f",(ReadingsVal($name,"Temperatur",0)-32)*5/9)},\<br />
TaupunktTempC {sprintf("%1.1f",(ReadingsVal($name,"TaupunktTemp",0)-32)*5/9)},\<br />
LuftdruckHpa {sprintf("%d",ReadingsVal($name,"Luftdruck",0)*33.8639)},\<br />
TemperaturGefuehltC {sprintf("%1.1f",(ReadingsVal($name,"TemperaturGefuehlt",0)-32)*5/9)}<br />
</syntaxhighlight><br />
<br />
Nun erfolgt die Visualisierung der Daten.<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_Wetter_ring DOIF ##<br />
attr di_Wetter_ring uiTable {package ui_Table;;}\<br />
\<br />
icon_temp_hum_ring("temp_outside",[Wetter:TemperaturC],[Wetter:Feuchtigkeit],undef,undef,150)|\<br />
icon_temp_ring ("temp_windchill",[Wetter:TemperaturGefuehltC],undef,undef,150) |\<br />
icon_temp_ring ("temperature_humidity",[Wetter:TaupunktTempC],undef,undef,150) |\<br />
icon_ring2([Wetter:WindKm] > 0 ? "wind".",1,0,0,".[Wetter:WindrichtungGrad]:"no_wind",[Wetter:WindKm],0,50,120,0,"km/h",150,undef,1,[Wetter:WindboeenKm],0,50,120,0,"km/h",undef,1) |\<br />
icon_ring2("weather_rain_gauge",[Wetter:RegenMm],0,10,180,270,"mm/h",150,undef,1,[Wetter:RegenGesamtMm],0,50,180,270,"mm",undef,1)|\<br />
icon_ring2("sani_solar",[Wetter:UV],0,10,100,30,"UV",150,undef,0,[Wetter:Sonnenstrahlung],0,1000,100,30,"Watt/m²",undef,0)|\<br />
icon_ring ("weather_barometric_pressure",[Wetter:LuftdruckHpa],980,1047,0,120,"hPa",0,150)<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable ringwetter.png|600px|links]]<br />
<br clear="all"><br />
<br />
Hier ein Beispiel der Visualisierung mit Verlauf der letzten drei Tage mit Hilfe der svg-Funktion '''card''':<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_Wetter DOIF ##<br />
attr di_Wetter icon weather_wind<br />
attr di_Wetter uiTable {package ui_Table;;}\<br />
## card ($collect,$header,$icon,$min,$max,$minColor,$maxColor,$unit,$func,$decfont,$size,$model,$lightness)\<br />
\<br />
card([Wetter:TemperaturC:col3d],"Außentemperatur","temp_outside",-10,60,undef,undef,"°C",\&temp_hue)|\<br />
card([Wetter:TemperaturGefuehltC:col3d],"gefühlte Temperatur","temp_windchill",-10,60,undef,undef,"°C",\&temp_hue)|\<br />
card([Wetter:TaupunktTempC:col3d],"Taupunkttemperatur","temperature_humidity",-10,60,undef,undef,"°C",\&temp_hue)|\<br />
card([Wetter:Feuchtigkeit:col3d],"Außenfeuchtigkeit","temperature_humidity",0,100,undef,undef,"%",\&hum_hue)|\<br />
card([Wetter:WindKm:col3d],"Wind",[Wetter:WindKm] > 0 ? "wind".",1,0,0,".[Wetter:WindrichtungGrad]:"no_wind",0,30,90,30,"km/h",undef,1)\<br />
card([Wetter:WindboeenKm:col3d],"Windböen","weather_wind",0,30,90,30,"km/h",undef,1)|\<br />
card([Wetter:RegenMm:col3d],"Regen","weather_rain_gauge",0,10,180,270,"mm/h")|\<br />
card([Wetter:RegenGesamtMm:col3d],"Regengesamt","weather_rain_gauge",0,50,180,270,"mm")|\<br />
##card([Wetter:UV:col3d],"UV-Strahlung","sani_solar",0,7,100,30,"UV",undef,0)|\<br />
card([Wetter:Sonnenstrahlung:col3d],"Sonnenstrahlung","sani_solar",0,1000,30,90,"Watt/m²",undef,0)|\<br />
card([Wetter:LuftdruckHpa:col3d],"Luftdruck","weather_barometric_pressure",980,1047,30,90,"hPa",undef,0)<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable svgwetter.png|600px|links]]<br />
<br clear="all"><br />
<br />
Ohne Angabe der Überschrift (undef für $header setzen) lässt sich eine kompaktere Darstellung erzielen:<br />
<br />
[[Datei:UiTable svgwetteroh.png|600px|links]]<br />
<br />
<br clear="all"><br />
<br />
=== ''Visualisierung: '''aktueller Spritpreis''''' ===<br />
Der aktuelle Spritpreis einer Tankstelle wird ermittelt und mit seinem zeitlichen Verlauf visualisiert.<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#ring-Funktionen|ring]]<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#Anzeige_eines_Werteverlaufs_und_des_aktuellen_Wertes_mit_Hilfe_der_SVG-Funktion_card|card]]<br />
* Tankstelle bestimmen [https://www.clever-tanken.de/ Clever tanken]<br />
* Modul [[HTTPMOD]]<br />
}}<br />
<br />
Zunächst wird ein HTTPMOD-Modul für den aktuellen Spritpreis definiert, dabei ist <Stations-ID> durch die ID der Tankstelle zu ersetzen.<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod Tankstelle HTTPMOD http://www.clever-tanken.de/tankstelle_details/<Stations-ID> 300<br />
attr Tankstelle devStateIcon {ui_Table::ring(ReadingsVal("$name","Diesel",0),1.00,1.40,120,0,"Diesel",90,undef,2)." ".ui_Table::ring(ReadingsVal("$name","SuperE5",0),1.10,1.60,120,0,"E5",90,undef,2)}<br />
attr Tankstelle enableControlSet 1<br />
attr Tankstelle event-on-change-reading .*<br />
attr Tankstelle group Spritpreise<br />
attr Tankstelle reading01Name Diesel<br />
attr Tankstelle reading01Regex "current-price-1">(\d.\d{2})<br />
attr Tankstelle reading02Name SuperE5<br />
attr Tankstelle reading02Regex "current-price-2">(\d.\d{2})<br />
attr Tankstelle room Spritpreise<br />
attr Tankstelle timeout 10<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Di uiTable Tankstelle.png|ohne|mini]]<br />
<br />
Visualisierung der Preisentwicklung der letzten 24 Stunden: <br />
<br />
<syntaxhighlight lang="perl"><br />
defmod sprit DOIF ##<br />
attr sprit uiTable {package ui_Table;;}\<br />
card([Tankstelle:Diesel:col24],"Diesel","fuel","1.00","1.40",120,0,"Diesel €",undef,"2",",,1")\<br />
card([Tankstelle:SuperE5:col24],"Super E5","fuel","1.10","1.60",120,0,"Super €",undef,"2",",,1")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Di uiTable sprit.png|ohne|mini]]<br />
<br />
=== ''Visualisierung: '''aktuelle Corona-7-Tage-Inzidenz''''' ===<br />
Die aktuellen Inzidenzwerte werden vom RKI ausgelesen und deren Verlauf visualisiert.<br />
<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#ring-Funktionen|ring]]<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#Anzeige_eines_Werteverlaufs_und_des_aktuellen_Wertes_mit_Hilfe_der_SVG-Funktion_card|card]]<br />
* Modul [[JsonMod]]<br />
}}<br />
<br />
Zunächst wird ein JsonMod Device für das Auslesen der Inzidenzzahlen definiert. Die gewünschten Regionen müssen für eigene Bedürfnisse angepasst werden.<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod RKI7 JsonMod https://services7.arcgis.com/mOBPykOjAyBO2ZKk/arcgis/rest/services/RKI_Landkreisdaten/FeatureServer/0/query?where=1%3D1&outFields=last_update,cases7_per_100k,BEZ,BEM,GEN,BL,county&returnGeometry=false&outSR=4326&f=json<br />
attr RKI7 readingList multi(jsonPath("\$.features[?(\@.attributes.GEN in ['Städteregion Aachen', 'Düren', 'Heinsberg'])]"), property('attributes.GEN'), sprintf('%.1f', property('attributes.cases7_per_100k')));;<br />
</syntaxhighlight><br />
<br />
Visualisierung der Inzidenzzahlen der letzten sieben Tage: <br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_corona DOIF ##<br />
attr di_corona uiTable {package ui_Table}\<br />
card([RKI7:Duren:col1w],"Düren","coronavirus",0,200,120,0,"Fälle")|\<br />
card([RKI7:Heinsberg:col1w],"Heinsberg","coronavirus",0,200,120,0,"Fälle")|\<br />
card([RKI7:Stadteregion_Aachen:col1w],"Aachen","coronavirus",0,200,120,0,"Fälle")<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:uiTable_Inzidenz.png|600px|links]]<br />
<br />
<br clear="all"><br />
<br />
=== '' Visualisierung und Steuerung: '''Heiztherme''''' ===<br />
Im folgenden Beispiel wurde eine Heiztherme über einen ebus-Adapter in FHEM eingebunden. Die Heizungsdaten werden über MQTT ausgelesen und anschließend visualisiert. Die vorgestellten Visualisierungsbeispiele können ebenso im funktionslosen DOIF mit Hilfe des uiTable-Attriutes auf bereits existierende Readings des eigenen Systems angewendet werden. <br />
<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#icon_ring-Funktionen|icon_ring]]<br />
* svg-Funktion [[DOIF/uiTable_Schnelleinstieg#Anzeige_eines_Werteverlaufs_und_des_aktuellen_Wertes_mit_Hilfe_der_SVG-Funktion_card|card]]<br />
* Commandref [https://fhem.de/commandref_DE.html#DOIF_Perl_Modus DOIF Perl-Modus]<br />
* ebus-Adapter [https://ebusd.de/ ebusd]<br />
* ebus-Wiki [[EBUS|ebus]]<br />
}}<br />
<br />
Definition eines MQTT2-Devices für die Kommunikation mit der Therme über einen ebus-Adapter.<br />
<br />
Im diesem Fall wurde eine Vaillanttherme eingebunden, die meisten Readings wurden automatisch vom MQTT2-Server angelegt. Die Anbindung ist gerätespezifisch und unterscheidet sich je nach Gerättyp.<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod vaillant MQTT2_DEVICE ebusd_bai<br />
attr vaillant IODev MQTT2_FHEM_Server<br />
attr vaillant devStateStyle style="text-align:left"<br />
attr vaillant event-on-change-reading .*<br />
attr vaillant group Ebus<br />
attr vaillant icon sani_boiler_temp<br />
attr vaillant jsonMap Status01_0_value:Vorlauf Status01_0_name:0\<br />
Status01_1_value:Ruecklauf Status01_1_name:0\<br />
Status01_2_value:Aussentemp Status01_2_name:0\<br />
Status01_3_value:Warmwasser Status01_3_name:0\<br />
Status01_4_value:WWSpeicher Status01_4_name:0\<br />
Status01_5_value:Pumpenstatus Status01_5_name:0\<br />
Flame_0_value:Flame Flame_0_name:0\<br />
Storageloadpump_percent0_value:Storageloadpump\<br />
FlowTempDesired_temp_value:VorlaufSoll\<br />
Hc1HeatCurve_0_value:HeizKennlinie Hc1HeatCurve_0_name:0\<br />
HolidayEndPeriod_hto_value:FerienEnde\<br />
HolidayStartPeriod_hfrom_value:FerienBeginn\<br />
PumpPower_0_value:PumpenLeistung PumpPower_0_name:0\<br />
PrimaryCircuitFlowrate_uin100_value:Umlaufmenge\<br />
z1DayTemp_tempv_value:TagSolltemp\<br />
z1NightTemp_tempv_value:NachtSolltemp\<br />
FanSpeed_0_value:LuefterDrehzahl FanSpeed_0_name:0\<br />
WaterPressure_pressv_value:Wasserdruck\<br />
z1OpMode_opmode_value:Heizmodus<br />
attr vaillant model eBus_bai_jsonmap<br />
attr vaillant readingList ebusd/bai/PumpHours:.* { json2nameValue($EVENT, 'PumpHours_', $JSONMAP) }\<br />
ebusd/bai/WPPostrunTime:.* { json2nameValue($EVENT, 'WPPostrunTime_', $JSONMAP) }\<br />
ebusd/bai/PowerValue:.* { json2nameValue($EVENT, 'PowerValue_', $JSONMAP) }\<br />
ebusd/bai/StorageExitTemp:.* { json2nameValue($EVENT, 'StorageExitTemp_', $JSONMAP) }\<br />
ebusd/global/version:.* version\<br />
ebusd/global/running:.* running\<br />
ebusd/scan\x5c\x2e08/:.* { json2nameValue($EVENT, 'scan.08_', $JSONMAP) }\<br />
ebusd/scan\x5c\x2e08/id:.* { json2nameValue($EVENT, 'id_', $JSONMAP) }\<br />
ebusd/global/uptime:.* uptime\<br />
ebusd/global/signal:.* signal\<br />
ebusd/scan\x5c\x2e15/:.* { json2nameValue($EVENT, 'scan.15_', $JSONMAP) }\<br />
ebusd/scan\x5c\x2e15/id:.* { json2nameValue($EVENT, 'id_', $JSONMAP) }\<br />
ebusd/bai/FanSpeed:.* { json2nameValue($EVENT, 'FanSpeed_', $JSONMAP) }\<br />
ebusd/bai/PumpPower:.* { json2nameValue($EVENT, 'PumpPower_', $JSONMAP) }\<br />
ebusd/broadcast/vdatetime:.* { json2nameValue($EVENT, 'vdatetime_', $JSONMAP) }\<br />
ebusd/broadcast/outsidetemp:.* { json2nameValue($EVENT, 'outsidetemp_', $JSONMAP) }\<br />
ebusd/bai/DateTime:.* { json2nameValue($EVENT, 'DateTime_', $JSONMAP) }\<br />
ebusd/global/updatecheck:.* updatecheck\<br />
ebusd/bai/DCFTimeDate:.* { json2nameValue($EVENT, 'DCFTimeDate_', $JSONMAP) }\<br />
ebusd/bai/PumpPowerDesired:.* { json2nameValue($EVENT, 'PumpPowerDesired_', $JSONMAP) }\<br />
ebusd/bai/HwcImpellorSwitch:.* { json2nameValue($EVENT, 'HwcImpellorSwitch_', $JSONMAP) }\<br />
ebusd/bai/ReturnTemp:.* { json2nameValue($EVENT, 'ReturnTemp_', $JSONMAP) }\<br />
ebusd/700/HwcStorageTempBottom:.* { json2nameValue($EVENT, 'HwcStorageTempBottom_', $JSONMAP) }\<br />
ebusd/700/HwcTempDesired:.* { json2nameValue($EVENT, 'HwcTempDesired_', $JSONMAP) }\<br />
ebusd/bai/FanPWMSum:.* { json2nameValue($EVENT, 'FanPWMSum_', $JSONMAP) }\<br />
ebusd/bai/HcHours:.* { json2nameValue($EVENT, 'HcHours_', $JSONMAP) }\<br />
ebusd/bai/HoursTillService:.* { json2nameValue($EVENT, 'HoursTillService_', $JSONMAP) }\<br />
ebusd/bai/PumpHwcFlowNumber:.* { json2nameValue($EVENT, 'PumpHwcFlowNumber_', $JSONMAP) }\<br />
ebusd/bai/WP:.* { json2nameValue($EVENT, 'WP_', $JSONMAP) }\<br />
ebusd/700/WaterPressure:.* { json2nameValue($EVENT, 'WaterPressure_', $JSONMAP) }\<br />
ebusd/bai/PrimaryCircuitFlowrate:.* { json2nameValue($EVENT, 'PrimaryCircuitFlowrate_', $JSONMAP) }\<br />
ebusd/bai/Flame:.* { json2nameValue($EVENT, 'Flame_', $JSONMAP) }\<br />
ebusd/bai/Storageloadpump:.* { json2nameValue($EVENT, 'Storageloadpump_', $JSONMAP) }\<br />
ebusd/bai/Status01:.* { json2nameValue($EVENT, 'Status01_', $JSONMAP) }\<br />
ebusd/bai/FlowTempDesired:.* { json2nameValue($EVENT, 'FlowTempDesired_', $JSONMAP) }\<br />
ebusd/700/FrostOverRideTime:.* { json2nameValue($EVENT, 'FrostOverRideTime_', $JSONMAP) }\<br />
ebusd/700/Hc1ActualFlowTempDesired:.* { json2nameValue($EVENT, 'Hc1ActualFlowTempDesired_', $JSONMAP) }\<br />
ebusd/700/Hc1AutoOffMode:.* { json2nameValue($EVENT, 'Hc1AutoOffMode_', $JSONMAP) }\<br />
ebusd/700/Hc1CircuitType:.* { json2nameValue($EVENT, 'Hc1CircuitType_', $JSONMAP) }\<br />
ebusd/700/Hc1HeatCurve:.* { json2nameValue($EVENT, 'Hc1HeatCurve_', $JSONMAP) }\<br />
ebusd/700/HcStorageTempBottom:.* { json2nameValue($EVENT, 'HcStorageTempBottom_', $JSONMAP) }\<br />
ebusd/700/HcStorageTempTop:.* { json2nameValue($EVENT, 'HcStorageTempTop_', $JSONMAP) }\<br />
ebusd/700/HolidayTemp:.* { json2nameValue($EVENT, 'HolidayTemp_', $JSONMAP) }\<br />
ebusd/700/OpMode:.* { json2nameValue($EVENT, 'OpMode_', $JSONMAP) }\<br />
ebusd/700/z1RoomTemp:.* { json2nameValue($EVENT, 'z1RoomTemp_', $JSONMAP) }\<br />
ebusd/700/z1SFMode:.* { json2nameValue($EVENT, 'z1SFMode_', $JSONMAP) }\<br />
ebusd/700/z1OpMode:.* { json2nameValue($EVENT, 'z1OpMode_', $JSONMAP) }\<br />
ebusd/700/Time:.* { json2nameValue($EVENT, 'Time_', $JSONMAP) }\<br />
ebusd/bai/EbusVoltage:.* { json2nameValue($EVENT, 'EbusVoltage_', $JSONMAP) }\<br />
ebusd/bai/extWP:.* { json2nameValue($EVENT, 'extWP_', $JSONMAP) }\<br />
ebusd/bai/FanStarts:.* { json2nameValue($EVENT, 'FanStarts_', $JSONMAP) }\<br />
ebusd/700/z1NightTemp:.* { json2nameValue($EVENT, 'z1NightTemp_', $JSONMAP) }\<br />
ebusd/700/z1DayTemp:.* { json2nameValue($EVENT, 'z1DayTemp_', $JSONMAP) }\<br />
ebusd/700/HolidayStartPeriod:.* { json2nameValue($EVENT, 'HolidayStartPeriod_', $JSONMAP) }\<br />
ebusd/700/HolidayEndPeriod:.* { json2nameValue($EVENT, 'HolidayEndPeriod_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Monday:.* { json2nameValue($EVENT, 'z1Timer.Monday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Tuesday:.* { json2nameValue($EVENT, 'z1Timer.Tuesday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Wednesday:.* { json2nameValue($EVENT, 'z1Timer.Wednesday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Thursday:.* { json2nameValue($EVENT, 'z1Timer.Thursday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Friday:.* { json2nameValue($EVENT, 'z1Timer.Friday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Sunday:.* { json2nameValue($EVENT, 'z1Timer.Sunday_', $JSONMAP) }\<br />
ebusd/700/z1Timer.Saturday:.* { json2nameValue($EVENT, 'z1Timer.Saturday_', $JSONMAP) }\<br />
ebusd/bai/PrEnergyCountHc1:.* { json2nameValue($EVENT, 'PrEnergyCountHc1_', $JSONMAP) }\<br />
ebusd/bai/PrEnergyCountHwc1:.* { json2nameValue($EVENT, 'PrEnergyCountHwc1_', $JSONMAP) }\<br />
ebusd/bai/PrEnergySumHc1:.* { json2nameValue($EVENT, 'PrEnergySumHc1_', $JSONMAP) }\<br />
ebusd/bai/PrEnergySumHwc1:.* { json2nameValue($EVENT, 'PrEnergySumHwc1_', $JSONMAP) }\<br />
ebusd/bai/FanHours:.* { json2nameValue($EVENT, 'FanHours_', $JSONMAP) }\<br />
ebusd/bai/HcHours:.* { json2nameValue($EVENT, 'HcHours_', $JSONMAP) }\<br />
ebusd/bai/HwcHours:.* { json2nameValue($EVENT, 'HwcHours_', $JSONMAP) }\<br />
ebusd/bai/HcStarts:.* { json2nameValue($EVENT, 'HcStarts_', $JSONMAP) }\<br />
ebusd/bai/HwcStarts:.* { json2nameValue($EVENT, 'HwcStarts_', $JSONMAP) }<br />
attr vaillant setList HeizKennlinie:selectnumbers,0,.1,2,1,lin ebusd/700/Hc1HeatCurve/set $EVTPART1\<br />
TagSolltemp:selectnumbers,15,1,25,1,lin ebusd/700/z1DayTemp/set $EVTPART1\<br />
NachtSolltemp:selectnumbers,15,1,25,1,lin ebusd/700/z1NightTemp/set $EVTPART1<br />
</syntaxhighlight><br />
<br />
Definition eines DOIF-Devices zur Steuerung der Therme und Visualisierung der Daten. Es werden Readings und Befehle genutzt, die durch den MQTT2-Server der obigen Definition zur Verfügung gestellt werden. Einzelne Heizungswerte werden in bestimmten Intervallen über den publish-Befehl ausgelesen. Die Temperaturen der Zirkulation, des Vorlaufs und des Rücklaufs werden außerhalb der Therme mit 1-wire-Temperatursensoren über WLAN-ESP-Easy ausgelesen. Die Definition des Layouts über das Attribut uiTable ist unabhängig vom Auslesen der Werte, sie bezieht sich lediglich auf vorhandene Readings, die visualisiert werden sollen. Das Layout kann ebenso auf Readings aus anderen Devices der eigenen FHEM-Umgebung anpasst werden.<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod di_vaillant DOIF ##{[+00:01];;foreach (qw(FanSpeed Flame PumpPower Storageloadpump PrimaryCircuitFlowrate FlowTempDesired PumpHours HcHours HcPumpStarts)) {fhem_set("MQTT2_FHEM_Server publish ebusd/bai/$_/get")}}\<br />
\<br />
{[+[1]:01];;foreach (qw(PrEnergySumHc1 PrEnergySumHwc1 HcHours HwcHours z1OpMode WaterPressure z1NightTemp z1DayTemp Hc1HeatCurve HwcLockTime HolidayStartPeriod HolidayEndPeriod)) {fhem_set("MQTT2_FHEM_Server publish ebusd/bai/$_/get")}\<br />
}\<br />
\<br />
{[+00:00:30];;foreach (qw(Flame PrimaryCircuitFlowrate)) {fhem_set("MQTT2_FHEM_Server publish ebusd/bai/$_/get")}}\<br />
\<br />
{[00:01];;foreach (qw(FanHours HcStarts HwcStarts )) {fhem_set("MQTT2_FHEM_Server publish ebusd/bai/$_/get")}\<br />
set_Reading("gesamt_hc",int([?vaillant:PrEnergySumHc1_0_value]/10000)/10,0);;\<br />
set_Reading("gesamt_hwc",int([?vaillant:PrEnergySumHwc1_0_value]/10000)/10,0);;\<br />
set_Reading("diff_hc",0,1);;\<br />
set_Reading("diff_hwc",0,1);;\<br />
set_Reading("diff_h",0,1)\<br />
}\<br />
\<br />
{if ([00:05|WE]) {fhem_set("MQTT2_FHEM_Server publish ebusd/700/BankHolidayStartPeriod/set $mday.$month.$year");;fhem_set("MQTT2_FHEM_Server publish ebusd/700/BankHolidayEndPeriod/set $mday.$month.$year")}}\<br />
\<br />
Timer {\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Monday/set 04:00;;09:00;;13:00;;22:00;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Tuesday/set 04:00;;09:00;;13:00;;22:00;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Wednesday/set 04:00;;09:00;;13:00;;22:00;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Thursday/set 04:00;;09:00;;13:00;;22:00;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Friday/set 04:00;;09:00;;13:00;;22:00;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Sunday/set 05:00;;10:00;;12:00;;22:30;;-:-;;-:-"\<br />
fhem_set "MQTT2_FHEM_Server publish ebusd/700/z1Timer.Saturday/set 05:00;;10:00;;12:00;;22:30;;-:-;;-:-"\<br />
}\<br />
\<br />
diff {\<br />
set_Reading("diff_hc",int(([vaillant:PrEnergySumHc1_0_value]/100000-get_Reading("gesamt_hc",0))*10)/10,1);;\<br />
set_Reading("diff_hwc",int(([vaillant:PrEnergySumHwc1_0_value]/100000-get_Reading("gesamt_hwc",0))*10)/10,1);;\<br />
set_Reading("diff_h",get_Reading("diff_hc")+get_Reading("diff_hwc"),1);;\<br />
}\<br />
\<br />
<br />
attr di_vaillant event-on-change-reading .*<br />
attr di_vaillant room Ebus<br />
attr di_vaillant uiTable {\<br />
package ui_Table;;\<br />
$TABLE='text-align:center;;';;\<br />
$SHOWNODEVICELINE = "test9|Damian";;\<br />
}\<br />
icon_temp_ring("temp_outside",[vaillant:Aussentemp],-15,40,130)|\<br />
icon_temp_mring(([vaillant:Flame] eq "off"?"sani_boiler_temp\@white":"sani_boiler_temp\@Darkorange"),[vaillant:Vorlauf],15,70,130)|\<br />
icon_temp_mring(([vaillant:Pumpenstatus] eq "4" ? "sani_buffer_temp_down\@Darkorange" : "sani_buffer_temp_down\@white"),[vaillant:WWSpeicher],15,70,130)|\<br />
icon_uring("0,0,1","weather_barometric_pressure",[vaillant:Wasserdruck],0,3,undef,undef,"bar",1,130,[(0.8,0,1,60,1.5,120,1.7,60,3,0)],"50,35")|\<br />
icon_ring("sani_floor_heating_neutral",[vaillant:HcHours_hoursum2_value],0,10000,120,0,"h",0,130)|\<br />
icon_ring("sani_water_tap",[vaillant:HwcHours_hoursum2_value],0,2000,120,0,"h",0,130)|\<br />
\<br />
icon_ring("time_graph",[vaillant:HeizKennlinie],0.4,1,120,0,"HK",1,130)|\<br />
icon_temp_mring("scene_day\@yellow",[vaillant:TagSolltemp],undef,undef,130)|\<br />
icon_temp_mring("scene_night\@#3464eb",[vaillant:NachtSolltemp],undef,undef,130)\<br />
""|""|""|""|""|""|widget([vaillant:HeizKennlinie],"selectnumbers,0.4,.1,1,1,lin","set")|widget([vaillant:TagSolltemp],"selectnumbers,15,1,25,1,lin","set")|widget([vaillant:NachtSolltemp],"selectnumbers,15,1,25,1,lin","set")<\<br />
\<br />
card([vaillant:Aussentemp:col],"Außentemperatur","temp_outside",-15,35,undef,undef,"°C",\&temp_hue)|\<br />
card([vaillant:WWSpeicher:col],"WW-Speicher",([vaillant:Pumpenstatus] eq "4" ? "sani_buffer_temp_down\@Darkorange" : "sani_buffer_temp_down\@white"),15,70,undef,undef,"°C",\&temp_hue)|\<br />
card([ESPEasy_ESP_Temp_Vorlauf:Temperature:col],"Vorlauf",([vaillant:Pumpenstatus] eq "on" ? "sani_floor_heating\@Darkorange" : "sani_floor_heating_neutral\@white"),15,70,undef,undef,"°C",\&temp_hue)|\<br />
card([$SELF:diff_hc:col],"Energie Heizung","sani_floor_heating_neutral",0,100,120,0,"kWh",undef,1)\<br />
card([vaillant:Umlaufmenge:col],"Umlaufmenge","sani_pump",0,20,120,0,"l/min")|\<br />
card([ESPEasy_ESP_Temp_Zirkulation:Temperature:col],"Zirkulation",([Zirk] eq "off"?"sani_pump\@white":"sani_pump\@Darkorange"),15,70,undef,undef,"°C",\&temp_hue)|\<br />
card([ESPEasy_ESP_Temp_Keller_Ruecklauf:Temperature:col],"Rücklauf","sani_floor_heating_neutral\@wite",15,70,undef,undef,"°C",\&temp_hue)|\<br />
card([$SELF:diff_hwc:col],"Energie Warmwasser","sani_water_tap",0,15,120,0,"kWh",undef,1)<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:Di uiTable Heizung.png|600px|links]]<br />
<br />
<br clear="all"><br />
<br />
=== ''Visualisierung: '''Anwesenheitsstatus''''' ===<br />
Die aktuelle Anwesenheit von Heimbewohnern wird visualisiert.<br><br><br />
Zunächst wird mit Hilfe des Moduls [[FRITZBOX]] ein Device namens ''FritzBox'' erstellt. Dort werden die eingebuchten Smartphones der Bewohner mit Ihren MAC-Adressen in Readings abgelegt. Die folgende Definition wertet aus, ob die angegebenen MAC-Adressen als Readings vorhanden sind und erstellt für jeden Bewohner ein Reading mit den Zuständen on/off. Diese Readings werden dann über das Attribut uiTable visualisiert. Die anwesenden Personen werden farblich markiert. Die Namen der Personen sowie die MAC-Adressen sind fiktiv und müssen den eigenen Angaben entsprechend angepasst werden.<br />
{{Randnotiz|RNText='''nützliche Links'''<br />
* [[FRITZBOX|FritzBox-Modul]]<br />
* ui_Table Funktion [[DOIF/uiTable Schnelleinstieg#Icon-Darstellung mit Text mit Hilfe der Funktion icon_label|icon_label]]<br />
*[[DOIF/uiTable Schnelleinstieg#uiTable-Templates|uiTable-Templates]]<br />
}}<br />
<br />
<syntaxhighlight lang="perl"><br />
defmod myHome DOIF {\<br />
set_Reading_Begin;;\<br />
set_Reading_Update("Ernie",[FritzBox:mac_12_34_E0_00_CD_E4] ? "on":"off");;\<br />
set_Reading_Update("Bert", [FritzBox:mac_02_08_02_07_30_E3] ? "on":"off");;\<br />
set_Reading_Update("Grobi", [FritzBox:mac_00_08_01_0B_00_E7] ? "on":"off");; \<br />
set_Reading_Update("Kermit", [FritzBox:mac_01_30_A9_72_02_E3] ? "on":"off");; \<br />
set_Reading_End(1);;\<br />
}<br />
attr myHome checkReadingEvent 0<br />
attr myHome uiTable {\<br />
package ui_Table;;\<br />
$SHOWNOSTATE=1;;\<br />
$TC{0..4}="align='center'";;\<br />
}\<br />
## Template-Definition für die Visualisierung eines Bewohners mit Hilfe des Icons fa__508\<br />
DEF TPL_person (icon_label([$SELF:$1] eq "on" ? "fa__508\@DarkOrange":"fa__508","$1","#e67e00","white",-10))\<br />
\<br />
## Darstellung der Bewohner mit Hilfe des obigen Templates\<br />
TPL_person(Ernie)|TPL_person(Bert)|TPL_person(Grobi)|TPL_person(Kermit)<br />
</syntaxhighlight><br />
<br />
''Ergebnis der Beispieldefinition in der Webansicht:''<br />
[[Datei:UiTable myHome.png|ohne|mini]]<br />
<br />
=== Weitere Anwendungsbeispiele zur Automatisierung ===<br />
* siehe [[DOIF/Automatisierung]]<br />
<br />
== Weiterführende Links ==<br />
* Weitere Beispiele für Fortgeschrittene, siehe "[[DOIF/uiTable|uiTable mit FHEM-Widgets und Styles]]"<br />
<br />
[[Kategorie:HOWTOS]]<br />
[[Kategorie:Code Snippets]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=SIGNALduino&diff=37168SIGNALduino2022-01-30T11:14:25Z<p>Andies: /* Entwicklungsversion */ Unterscheidung offizielles Modul (Sidey) und inoffizielles Modul (Ralf9), da es deshalb viel Verwirrung im Forum gab.</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Empfang und Verarbeitung von digitalen Signalen<br />
|ModType=d<br />
|ModFTopic=38402<br />
|ModCmdRef=SIGNALduino<br />
|ModForumArea=Sonstige Systeme<br />
|ModTechName=00_SIGNALduino.pm<br />
|ModOwner=Sidey ({{Link2FU|8018|Forum}}/[[Benutzer Diskussion:Sidey|Wiki]])<br />
}}<br />
<br />
== Einleitung ==<br />
=== Übersicht ===<br />
Unter den Namen SIGNALduino versteht man sowohl den Low-Cost Empfänger für digitale Signale (vergleichbar dem [[CUL]]) als auch das gleichnamige Modul mit dem Dateinamen 00_SIGNALduino.pm. Mit dem SIGNALduino kann man entweder 433 oder 868 MHz-Geräte auslesen und ansprechen. Der SIGNALduino funktioniert auch mit anderen Medien wie Infrarot oder direkter Kabelverbindung.<br />
<br />
Der SIGNALduino(-Stick) erkennt Signale anhand von Mustern und gibt sie (als maximal detaillierte Beschreibung einer Signalabfolge) dann schlicht sofort nur noch an FHEM zur Auswertung (Dekodierung) weiter. Auch nicht erkannte Signale werden an FHEM übergeben.<br />
Aufgabe des SIGNALduino (Firmware/Stick) ist es also nur, Signal-Aktivitäten zu erfassen und maximal präzise (als kurzer Text-String) zu beschreiben.<br />
Alles weitere (echte, finale Auswertung / Zuweisung dieser Signal-Daten) wird dann auf einer großen Box (z.B. Raspberry) gemacht.<br />
<br />
=== Vorteil gegenüber einem CUL/FHEMduino ===<br />
Der SIGNALduino hat den Vorteil einer sehr schnellen Demodulation des Funksignals. Sollen weitere Protokolle dekodiert werden, so muss dazu nur ein passendes FHEM Modul entwickelt oder ein universelles Modul erweitert werden (also auf flexibel direkt änderbarer/updatebarer Rechner-Seite!!). Änderungen am Arduino-Firmware-Code sind normalerweise nicht notwendig (sofern die grundsätzliche Signal-Klassifizierung auf Stick-Firmware-Seite korrekt funktioniert - leider nicht immer, z.B.: [https://github.com/RFD-FHEM/SIGNALDuino/issues/65 MU-Nachrichten werden z.T. als MC erkannt]).<br />
<br />
Ein großer Vorteil des SIGNALduino besteht darin, dass auch Geräte mit leicht abweichenden Frequenzen steuerbar sind; so empfangen die ''Somfy''-Rolladenmotoren beispielsweise auf 433.42 MHz und nicht, wie bei anderen Geräten sehr oft üblich, auf 433.92 MHz. Die Frequenzumstellung stellt für den SIGNALduino kein Problem dar.<br />
<br />
Ebenso kann man den SIGNALduino direkt an den Sendeausgang eines Sensors anbinden und die digitalen Signale empfangen, dabei bitte aber auf die passenden Spannungen achten, denn ein Arduino Nano verträgt nur 5V.<br />
<br />
<br />
=== Entwicklungsversion ===<br />
Der SIGNALduino wird derzeit aktiv weiterentwickelt. In FHEM existieren inzwischen zwei verschiedene Versionen: eine offizielle (Maintainer ist Sidey) und eine inoffizielle (Maintainer ist Ralf9). Die offizielle Version wird über den update-Prozess verteilt, wer die inoffizielle nutzen will, muss hier händisch eingreifen. Beide Versionen sind inzwischen so weit entwickelt, dass sie nicht mehr ohne Weiteres kompatibel sind. Man muss also eine Entscheidung treffen, welches das für einen geeignete Modul ist. Das betrifft inzwischen nicht nur das eigentliche SIGNALduino.pm-Modul, sondern auch die dazugehörige Firmware.<br />
<br />
==== Offizielles Modul (Sidey) ====<br />
Die offizielle Version wird in mehreren Forenbeiträgen beschrieben: [https://forum.fhem.de/index.php/topic,58397.0.html Erster Thread] (inzwischen geschlossen), {{Link2Forum|Topic=58396|LinkText=weiterer Thread}} sowie [https://forum.fhem.de/index.php/topic,60170.0.html noch ein Thread.] <br />
<br />
An einem weiteren Thread ([https://forum.fhem.de/index.php/topic,58396.0.html Link]) scheinen beide Autoren beteiligt zu sein.<br />
<br />
==== Inoffizielles Modul (Ralf9) ====<br />
Das Modul von Ralf9 wird [https://forum.fhem.de/index.php/topic,111653.0.html hier] beschrieben. Wer es installieren möchte, muss beim üblichen update-Prozess das Modul 00_SIGNALduino.pm vom update ausschließen oder nach jedem Update erneut Ralf9s-Modul herunterladen. Die Installation des Moduls wird im ersten Post beschrieben, Hilfe gibt es auch in diesem Thread. <br />
<br />
== Hardware ==<br />
=== Controller ===<br />
Der SIGNALduino (Hardware) wird über den USB Port angeschlossen, er kann aber auch mit zusätzlichen ESP Modulen über ein WLAN angebunden werden. Bei Einbindung via ESP muss man beachten, dass der ESP nach 5 Minuten Inaktivität seine TCP-Verbindung unterbricht (siehe [[ESP8266#Bekannte_Probleme|diesen Hinweis]]). Zu diesem Zweck gibt es einen Signalduino-eigenen Ping-Befehl ('get signalduino ping'), der diese Aktivität wieder aufbaut. Ping-Befehle sind auch auf Betriebssystemebene bekannt - allerdings beachte man, dass der ping-Befehl auf Betriebssystemebene ICMP verwendet, zum "Aufwachen" des ESP aber auf TCP-Ebene aktiviert werden muss (zum Unterschied siehe [https://www.tippscout.de/internet-was-sind-tcp-ip-udp-und-icmp_tipp_2268.html hier]) und man daher besser den Signalduino-eigenen Befehl und nicht das Betriebssystem verwendet.<br />
<br />
Der SIGNALduino basiert auf einem [http://arduino.cc/de/Main/ArduinoBoardNano Arduino Nano], die Schaltung entspricht dem [[Selbstbau CUL]] (eine frühere Version ist der nicht mehr weiterentwickelte [[FHEMduino]]):<br />
* Entweder wird ein Arduino mit einfachen Sende- und Empfangsmodulen verwendet, dann ist die Verkabelung identisch zum FHEMduino <br />
* Oder es wird ein CC1101 Transceiver verwendet, dann ist die Verkabelung identisch zum [[Selbstbau CUL]]. Dieser Aufbau wird derzeit empfohlen.<br />
* Zuletzt gibt es ein fertig konfektioniertes Modul von In-Circuit mit Radino CC1101 Varianten, Link zum [http://shop.in-circuit.de/index.php Hersteller]. <br />
<br />
Achten Sie beim Selbstbau auf die entsprechenden Sender-Empfänger. Der sehr preiswert angebotene XY-MK-5V hat sich als zu unzuverlässig erwiesen, während anscheinend beim CC1101 (insbesondere der "grünen Version") keine Probleme auftreten. <br />
<br />
Es stehen auch für den [https://www.arduino.cc/en/Main/arduinoBoardUno UNO] und [https://www.arduino.cc/en/Main/ArduinoBoardProMini PRO Mini] Firmware-Dateien zur Verfügung. Die ausgelieferte Firmware läuft nur auf Mikrocontrollern mit 16 MHz; wer einen Mikrocontroller mit 8 MHz verwenden möchte, muss die Firmware selbst compilieren. Die SW ist auf [https://github.com/RFD-FHEM/SIGNALDuino github]. Vorgesehen ist momentan (für ordentlich breiten Support müsste man wohl eine CMake-Build-Config hinzufügen - ich sollte hier mal in die Pötte kommen...) nur die Übersetzung unter Windows mit Visual Studio und dem Visual Micro Zusatz. Es gibt aber auch eine Anleitung, wie man mit der [[Arduino]] IDE oder einem Makefile [[SIGNALduino Compilieren]] kann.<br />
<br />
Es gibt auch eine Variante des SIGNALduino, die auf einem [[ESP8266]] nativ läuft, diese funktioniert seit Anfang 2018 annehmbar, allerdings befindet diese sich noch in einer Entwicklungsphase.<br />
<br />
An den "SIGNALESP" kann auch ein CC1101 via SPI angebunden werden:<br />
<br />
{| |<br />
!CC1101 Bezeichnung<br />
!ESP Pin<br />
|-<br />
|CLK||GPIO14<br />
|-<br />
|MOSI||GPIO13<br />
|-<br />
|MISO||GPIO12<br />
|-<br />
|CSN||GPIO15<br />
|-<br />
|GDO0||GPIO4<br />
|-<br />
|GDO2||GPIO5<br />
|}<br />
<br />
Wird eine einfache Empfänger / Sender Kombination verwendet, dann über die Pins:<br />
<br />
{| |<br />
! Bezeichnung <br />
! ESP Pin<br />
|-<br />
|Transmitter||GPIO4<br />
|-<br />
|Receiver||GPIO5<br />
|}<br />
<br />
=== Sendemodule ===<br />
{{Randnotiz|RNTyp=r|RNText=Viele user berichten über Empfangsprobleme bei Nutzung des XY-MK-5V; es wird ausdrücklich empfohlen, ein anderes Empfangsmodul zu nutzen!}}<br />
[[Datei:Fhemduino_schematic.png|200px|thumb|right|Beispielschaltplan SIGNAL(FHEM)duino]] <br />
<br />
Mit einem Arduino-Nano und folgenden, billigen Sende- und Empfangsmodulen können Sie einen SIGNALduino bauen:<br />
* FS1000A Dies ist das Sendemodul (TX) - es wird oft im Set mit dem billigen XY-MK-5V-Empfänger angeboten (etwa 5€). <br />
* RXB6 Das ist das empfohlene Empfangsmodul (RX), statt XY-MK-5V, etwa 5€ aus Deutschland.<br />
<br />
Die Verkabelung erfolgt analog zum [[FHEMduino]] und das bedeutet (Arduino -> Modul):<br />
* PIN D2 an DATA des RX-Moduls<br />
* PIN D11 an DATA des TX-Moduls (PIN links mit Beschriftung ATAD)<br />
<br />
Zusätzlich muss noch jeweils GND und 5V des Arduino mit dem GND bzw. VCC des Moduls verbunden werden.<br />
<br />
Jetzt fehlen noch die Antennen. Dafür braucht man ein 17,2 cm langes Stück Kupferdraht, das wird beim Anschluss "ANT" jeweils am Modul angelötet (anfängergeeignet).<br />
<br />
== Software ==<br />
<br />
=== USB-ID ermitteln ===<br />
Bevor der SIGNALduino mit dem FHEM Server (im Beispiel hier ein Raspberry PI) verbunden werden kann, muss die USB-Schnittstelle ermittelt werden. Hierzu bitte auf dem Terminal den Befehl<br />
<pre> ls -l /dev/serial/by-id </pre><br />
ausführen. Beispielhaft sieht das Ergebnis etwa so aus:<br />
<br />
''lrwxrwxrwx 1 root root 13 Jan 31 00:02 '''usb-FTDI_FT232R_USB_UART_A903N5T5-if00-port''' -> ../../ttyUSB0''<br />
<br />
Damit ist der Anschluss des SIGNALduino bestimmt und das Gerät kann wie im nächsten Abschnitt beschrieben definiert werden. Zuvor muss noch das Modul geladen werden.<br />
<br />
=== FHEM-Modul laden ===<br />
Die SIGNALduino Module werden über das FHEM [[update]] verteilt, sobald die Änderungen einen "stabilen" und alltagstauglichen Zustand haben. Aktuell wird dort die Version 3.5.2 seit 18.01.2022 verteilt.<br />
<br />
Mit Version 3.5.x ist die Unterstützung für Geräte mit FSK-Modulation integriert.<br />
<br />
Die aktuell in Entwicklung befindlichen Version (3.5.3) kann über folgende Vorgehensweise installiert werden:<br />
<br />
* FHEM aktualisieren: <code>update</code> <br />
* SIGNALduino Modul aktualisieren: <code>update all https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/master<nowiki/>/controls_signalduino.txt</code> Durch das Update von FHEM wird sichergestellt, dass das Modul mit FHEM arbeitet.<code><nowiki/></code><br />
* Es empfiehlt sich, die Github-Quelle dauerhaft einzutragen: <code>update add https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/master/controls_signalduino.txt</code>, um weitere Entwicklungs-Updates zu bekommen, und damit das nächste Standard-<code>update</code> nicht die alte Version wieder einspielt.<br />
<br />
Das Gerät kann wie folgt definiert werden (die Spezifikation des USB-Anschlusses muss dabei an die aktuellen Gegebenheiten angepasst werden):<br />
:<code>define <eigener-SIGNALduino-Name> SIGNALduino /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A903N5T5-if00-port0@57600</code><br />
* Solltet Ihr einen SIGNALESP via IP einbinden wollen, ist die Syntax (ebenso wird auch vorgegangen wenn der SIGNALduino beispielsweise über ser2net freigeben wird):<br />
:<code>define <eigener-SIGNALESP-Name> SIGNALduino <ip-adresse>:23</code><br />
Nach dem Einbinden wird der SIGNALduino, falls er erkannt wird, im Status "Opened" angezeigt. Die Baudrate beim SIGNALduino beträgt 57600 - <br />
<br />
Verbindungsversuche via telnet müssen dieselbe Baudrate verwenden. <br />
<br />
Die nachfolgenden Beispiel-Befehle verwenden "sduino" als <eigener-SIGNALduino-Name>.<br />
<br />
==== Flashen des Arduino mit der SIGNALduino Firmware ====<br />
Falls avrdude noch nicht vorhanden ist, kann es mit folgendem Befehl installiert werden:<br />
:<code>sudo apt-get install avrdude</code><br />
<br />
In FHEM ist der SIGNALduino mit dem Status "Open" vorhanden. Jetzt müssen wir FHEM noch mitteilen, welche Hardware wir angeschlossen haben. Über das Attribut ''hardware'' lässt sich zwischen den mitgelieferten Firmware-Dateien wechseln. Solltet ihr einen Nano mit cc1101 Transceiver verwenden, so wählt bitte folgende Hardware<br />
:<code>attr sduino hardware nanoCC1101</code><br />
sonst üblicherweise<br />
:<code>attr sduino hardware nano328</code><br />
<br />
Dann muss mitgeteilt werden, welche Version man geladen haben will: stable oder testing. <br />
:<code>attr sduino updateChannelFW testing</code><br />
Nun wird die entsprechende Firmware heruntergeladen. Dies geschieht durch den Befehl<br />
:<code>get sduino availableFirmware</code><br />
Anschließend kann der ''flash'' Befehl abgesetzt werden: <br />
:<code>set sduino flash <und-dann-auswaehlen></code><br />
Dadurch wird der Arduino mit der gewählten Firmware geflasht. Das Ergebnis wird im Webinterface direkt angezeigt.<br />
<br />
Alternativ kann auch der Flash-Befehl mit einem Dateinamen aufgerufen werden. Diese Möglichkeit sollte jedoch nur verwendet werden, wenn die SIGNALduino Firmware selbst compiliert wurde und eine andere Hardware verwendet wird. Der Flash-Befehl wird wie folgt aufgerufen:<br />
:<code>set sduino flash FHEM/firmware/SIGNALduino_mega2560.hex</code><br />
(je nachdem wo und unter welchem Namen die .hex Datei abgelegt wurde)<br />
<br />
Wenn ein miniCUL geflasht werden soll, sind einige Besonderheiten zu beachten. Details dazu in {{Link2Forum|Topic=114413|LinkText=diesem Forenthema}}.<br />
<br />
==== Flashen einer Firmware über HTTP ====<br />
Die Firmware wird nicht mehr über den FHEM Update Mechanismus verteilt. <br />
Damit die passende Firmware auf den SIGNALduino geladen werden kann, wird diese dann über HTTP aus den Github Releases geladen.<br />
<br />
==== Vorabversion einer Firmware ====<br />
Die Firmware des SIGNALduino wird ebenso wie das FHEM Modul auch weiter entwickelt.<br />
Die Entwickler sind auf Tests und Rückmeldungen der Nutzer angewiesen, da leider nicht alle Sensoren vorher getestet werden können.<br />
<br />
Die Version 3.4 ist die aktuell stabile Version.<br />
<br />
Für die folgenden Microcontroller kann man die Firmware seit 21.02.2019 auch direkt downloaden und teilweise flashen. <br />
Dazu muss das Attribut <code>hardware</code> auf einen gültigen Wert angepasst werden!<br />
Über den GET Befehl <code>availableFirmware</code> werden dann für die hinterlegte Hardware die passenden Versionen gesucht. Über das Attribut <code>updateChannelFW</code> kann zwischen "stable" und "testing" definiert werden, welche Art von Firmware angeboten werden soll.<br />
<br />
Nachdem die Firmwareversion erfragt wurde, bietet der set flash Befehl eine Auswahlliste an. Wird ein Flash Befehl mit einer der Versionen ausgewählt, wird diese Version zunächst heruntergeladen und bei den AVR Versionen auch versucht diese mittels avrdude zu flashen.<br />
Die Firmware für den ESP8266 kann aktuell leider noch nicht über diesen Befehl aktualisiert werden.<br />
<br />
Alternativ funktioniert aber auch die Option, dem Flash Befehl eine URL zu übergeben. Dann wird die Datei aus der URL heruntergeladen und auch versucht diese zu Flashen. z.B.<br />
SIGNALDuino_nanocc1101.hex für einen Nano mit CC1101<br />
<br />
<code>set sduino flash </code>https://github.com/RFD-FHEM/SIGNALDuino/releases/download/3.3.1/SIGNALDuino_radinocc11013.3.1.hex<br />
<br />
oder<br />
SIGNALESP_.hex (mit cc1101) für einen ESP8266 <br />
<code>set ipduino flash </code>https://github.com/RFD-FHEM/SIGNALDuino/releases/download/3.3.1/SIGNALDuino_ESP8266cc11013.3.1.hex<br />
<br />
!Achtung, aktuell wird die Firmware für den ESP dadurch nur herunter geladen. Flashen müsst ihr leider immer noch über ein passendes Tool <br />
z.B. [https://github.com/nodemcu/nodemcu-flasher ESP8266Flasher.exe] oder Esptool und einer seriellen Konsole.<br />
Auch ist zu beachten, es handelt sich hierbei tatsächlich um ein Binary und nicht um ein Hex File. <br />
<br />
Nach dem Booten des ESPs spannt dieser ein eigenes WLAN auf. Habt ihr euch damit verbunden, könnt ihr den ESP mit eurem vorhandenen WLAN nach Eingabe der Daten verbinden.<br />
<br />
Die Hauptseite für Firmware-Releases findet sich unter https://github.com/RFD-FHEM/SIGNALDuino/releases/ .<br />
Dort kann auch eine Änderungshistorie eingesehen werden.<br />
==== Flashen eines radino Boards mit ATmega32U4 ====<br />
<br />
Diese Funktion steht seit 21.02.2019 nun auch in der via FHEM aktualisierten Version zur Verfügung:<br />
<br />
Auch sind Berichte bekannt, dass der Radino beim Neustart von FHEM nicht korrekt initialisiert wird.<br />
Weiterhin ist zu beachten, dass der Bootloader eine andere USB ID bekommt und diese im Attribut <code>flashCommand</code> hinterlegt werden muss.<br />
<br />
==== Fehler beim Flashen ====<br />
Sollte bei einem Flash Vorgang ein Fehler auftreten, solltet ihr zunächst im Logfile mit Verbose 5 nachsehen.<br />
<br />
Findet ihr dort keine Fehlermeldung, gibt es noch ein separates Flashlog, welches ihr über einen Browser aufrufen könnt. Dazu müsst ihr nur den folgenden Pfad an euren Servernamen anhängen:<br />
<code><br />
/fhem/FileLog_logWrapper?dev=Logfile&type=text&file=SIGNALduino-Flash.log<br />
</code><br />
<br />
=== Geräteerkennung ===<br />
==== Unterstützte Geräte ====<br />
Für die folgenden Geräte gibt es derzeit (2017) eine Unterstützung für den Betrieb mit FHEM. Die Geräte werden [[autocreate|automatisch erkannt]] und in der Konfiguration eingetragen, wenn der SIGNALduino läuft.<br />
Bitte Geräte mit sehr präzisen Referenzen hier listen (Produktnummer, Protokoll-Variantenname etc.), damit eine globale Suche/Verifikation maximal erfolgreich ist. In der detaillierten Liste [[Geprüfte Geräte]] lassen sich die Geräte näher identifizieren.<br />
{| class="wikitable"<br />
! style="text-align:left;" | Produkt <br />
! (E)mpfangen<br />(S)enden <br />
! Hinweise <br />
! Verwendetes Modul <br />
! Protokoll ID<br />
|-<br />
|Conrad Wetterstation KW9110||E S||Sensor: KW9010, neben Temperatur u. Luftfeuchte werden auch Trend, Batterie u. Kanal erfasst|| CUL_TCM97001 || 0.3<br />
|-<br />
|TCM Wetterstation (97001 und 21xxx Serie)||E|| || CUL_TCM97001 || 0<br />
|-<br />
|ABS Wetterstation (ABS 700)||E|| || CUL_TCM97001 || 0<br />
|-<br />
|Prologue Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|Rubicson Wetterstation ||E|| ||CUL_TCM97001 ||0 <br />
|-<br />
|NC_WS Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|[http://www.gt-support.de/ GT-WT-02 Wetterstation]||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|AURIOL Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|Mebus Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|Intertechno Funkschalter||E S|| ||IT || 3,4,5,17<br />
|-<br />
|<strike>Conrad RSL Funkschalter</strike>||E S|| Funktioniert aktuell nicht || SIGNALduino_RSL || <br />
|-<br />
|[http://global.oregonscientific.com/product_view.php?id=5 Oregon Scientific Wettersensoren]||E || Protokoll V2 & V3 implementiert || OREGON || 10<br />
|-<br />
|Bresser Temp/Hydro Sensor||E || || Hideki || 12<br />
|-<br />
|[https://de.hama.com/00104985/hama-aussensensor-ts33c-fuer-wetterstation Hama TS33C]||E || || Hideki || 12<br />
|-<br />
|TFA Temp/Hydro Sensor||E || || Hideki || 12<br />
|-<br />
|Lacrosse TX2/TX3 Sensoren||E || || CUL_TX || 8<br />
|-<br />
|TFA 30320902||E || || SD_WS07 || 7<br />
|-<br />
|Eurochron eas800z||E || || SD_WS07 || 7<br />
|-<br />
|Technoline WS6750/TX70DTH||E || || SD_WS07 || 7<br />
|-<br />
|FreeTec Außenmodul NC-7344||E || || SD_WS07 || 7<br />
|-<br />
|CTW600||E || || SD_WS09 || 9<br />
|-<br />
|CTW602||E ||neuere Version des CTW600 mit 868.35 MHz || SD_WS09 || 9<br />
|-<br />
|WH1080||E || || SD_WS09 || 9<br />
|-<br />
|Visivon remote pt4450||E || || none || 24<br />
|-<br />
|Einhell HS 434/6||E || || none || 21<br />
|-<br />
|Flamingo FA20RF / FA21RF / FA22RF Rauchmelder||E || || FLAMINGO || 13,13.1,13.2<br />
|-<br />
|mumbi m-FS300||E || || none || 26,27<br />
|-<br />
|TFA 30.3200||E || || none || 33<br />
|-<br />
|Livolo||E|| || none || 20<br />
|-<br />
|Smartwares RM174RF/2 (RM174RF-001CPR) 4500177571 ||E [S?]|| IT EV1527; TODO herausfinden: Alarmierung (wie Alarmton getriggered werden kann); Batterieinfo? || IT || 3<br />
|-<br />
|Smartwares SH5-TSO-A||E S|| || IT || ?<br />
|-<br />
|X10 Security Devices||E|| || || 39<br />
|-<br />
|[[Somfy_via_SIGNALduino|Somfy RTS]]||E S|| || SOMFY || 43<br />
|}<br />
Bei einigen ''Intertechno''-Funksteckdosen (''Brennenstuhl'') kann es zu Empfangsproblemen kommen. Hier muss die Taktrate, mit der gesendet wird, angepasst werden. Dazu muss für ''Funksteckdose'' (also sauber per-Client-Instanz-spezifisch, NICHT SIGNALduino-Transceiver-global) das Attribut <br />
:<code>attr <Funksteckdose> ITclock 300</code> <br />
gesetzt werden, der Standardwert ist 250.<br />
<br />
==== Mein Gerät wird in FHEM nicht erkannt ====<br />
1. Prüfen, ob vom Sensor die Signaldaten (<code>verbose</code> >=4) erkannt werden. Sobald ihr die empfangenen Signaldaten im Logfile zuordnen könnt, geht es weiter mit:<br />
<br />
2. Eröffnet ein Thema unter [https://github.com/RFD-FHEM/RFFHEM/issues/new?template=sensor---device-feature.md github]:<br />
<!-- <syntaxhighlight lang="md"> ... markdown lexer not yet available; use pre instead --><br />
<pre><br />
## Specifications for new sensor / switch / or other device ... <br />
<br />
- manufacturer:<br />
- model name:<br />
- pictures of the device / the board (very helpful)<br />
<br />
<br />
## Specifications <br />
<br />
- Microcontroller:<br />
- Version (Firmware):<br />
<br />
<!-- ( can be found here devicename -> Internals -> version ) --><br />
- Versionmodul (FHEM Module):<br />
</pre><br />
<br />
3. Auszug aus dem Logfile, welches zum Gerät gehört.<br />
:''Alles was ihr sonst noch über das Gerät und die übertragenen Daten wisst.''<br />
<br />
Im Forum solltet ihr solche Fragen besser nicht posten, wenn das Gerät noch nicht unterstützt wird, dazu ist Github besser geeignet. Inzwischen wurde im Wiki eine eigene Seite eröffnet, die sich mit der Erkennung unbekannter Protokolle beschäftigt: [[Unbekannte_Funkprotokolle#Ansatz_1_-_Versuchen|Unbekannte_Funkprotokolle]].<br />
<br />
==== Es wird ein Protokoll erkannt, Autocreate legt aber kein device an ====<br />
Im SIGNALduino sind >70 Protokolle implementiert. Jedoch gibt es nicht immer ein logisches Modul, welches diese Protokolle verarbeitet.<br />
Teilweise ist das auch nicht zwingend notwendig, um seine Anforderungen zu erfüllen. Insbesondere für Schalter bzw. Sensoren, die nur zwei Zustände kennen, geht es meist auch kurz und knapp manuell (also ohne Modul und automatisch angelegtem Gerät).<br />
<br />
Nehmen wir an, wir haben einen Schalter. Dieser kann einen oder zwei Zustände senden.<br />
Im FHEM Log (und, insbesondere, im FHEMWEB Event Monitor) tauchen Meldungen ähnlich dieser auf<br />
<br />
<code><br />
2015.11.15 15:52:23 4: SIGNALduino_unknown incomming msg: u85#FF8081<br />
</code><br />
<br />
Wir können mit Hilfe des Modules DOIF auf diese Nachricht eine Aktion ausführen:<br />
<br />
Entweder, wenn wir den Inhalt der Nachricht nur zu Teilen wissen, da er sich ändert:<br />
<br />
<code><br />
define mydoif DOIF ([sduino:&DMSG] =~ "u85#FF8081") (set Lamp on)<br />
attr mydoif do always<br />
</code><br />
<br />
Oder, wenn wir den Inhalt exakt kennen, dann auch als Vergleichsstring<br />
<br />
<code><br />
define mydoif DOIF ([sduino:&DMSG] eq "u85#FF8081") (set relais on)<br />
attr mydoif do always<br />
</code><br />
<br />
Der Teil u85#FF8081 muss individuell angepasst werden, der Name eures SIGNALduino möglicherweise auch.<br />
<br />
Als Alternative zu DOIF hier ein regex-verwendendes [[notify]]-Beispiel für einen Sender, der meint, zwei Codes alternierend senden zu müssen:<br />
<br />
<code><br />
define n_sender_trigger notify sduino:UNKNOWNCODE.*u41#(13B72253|163873B3) { my_sender_trigger_indicate();; }<br />
</code><br />
<br />
Selbstverständlich muss in diesem Moment auch eine <code>sub my_sender_trigger_indicate()</code> definiert werden (z.B. in <code>FHEM/99_myUtils.pm</code>), die dort z.B. als Test eine Log-Ausgabe (<code>Log3()</code>) machen kann.<br />
<br />
=== Das Logfile ===<br />
Im Logfile ab [[verbose]] 4 tauchen diverse Meldungen auf, deren Bedeutung kurz erläutert wird (<code>verbose</code> 3 unterdrückt diese Meldungen).<br />
<br />
UPDATE: der folgende Bereich ist von einem weniger erfahrenen Zeitgenossen früher nach Kräften erweitert/geschrieben worden. Mittlerweile existiert aber ein neuer Inhalt [[Unbekannte Funkprotokolle]] (siehe auch Erwähnung weiter oben), der als sehr gut beschrieben und unvergleichlich detailreicher bezeichnet werden muss ("endlich gibt es sowas!"). Der Bereich hier dürfte somit zwar für grundlegende Verdeutlichungen noch recht sinnvoll sein, der Inhalt sollte allerdings evt. in eine konsistente Dokumentation überarbeitet (verlagert/dedupliziert/reduziert) werden.<br />
<br />
Die Protokolle (von der SIGNALDuino-Firmware gesendete Signal-Beschreibungs-Strings) können wie folgt unterschieden werden:<br />
<br />
*MS - Nachricht mit Sync Puls: Hierzu ein Beispiel<br />
:<code>MS;P0=-108;P1=395;P2=-1033;P3=-547;P4=-19932;P5=-8916;P6=1368;D=151313131312131313131313131313131312121212121313131313131312131212132;CP=1;SP=5;</code> P0-P6 sind die Signalpegel (Dauer und positiv/negativ). Hinter D= befindet sich die Abfolge der Signale. Die ersten beiden Ziffern 15 in D sind wie folgt zu lesen. Zuerst wurde ein Signal "1" also P1 mit 395 Mikrosekunden high (die Zeitdauer ergibt sich aufgrund der Mitteilung "P1=395") und anschließend ein Signal "5" also P5 mit 8916 Mikrosekunden low (die Zeitdauer ergibt sich aufgrund der Mitteilung "P5=-8916") gemessen. CP=1 ist die Referenz auf den Takt des Signales - der Basistakt ist in diesem Fall ~395 Mikrosekunden. SP=5 gibt die Referenz zum Syncpuls an, der das gesamte Signal einleitet. Welche Signalfolge nun eine binäre 1 bzw. 0 bedeutet, wird im SIGNALduino über die integrierte Protokoll Liste realisiert.<br />
<br />
*MC - Nachricht vom Typ Manchester: Manchesterkodierte Signale können bereits sehr einfach im Arduino in eine Binärform umgewandelt werden. Es wird hier nach IEEE 802.3 umgewandelt. In Manchester Signalen gibt es lange und kurze Pulse. Deren Durchschnittswert wird mit LL (long low), LH (long high), SL (short low) und SH (short high) übermittelt. Zusätzlich, um das Protokoll schneller erkennen zu können, wird die Taktfrequenz mit übermittelt (C=429 Mikrosekunden). Die Daten befinden sich hinter D= und werden in HEX Form übergeben.<br />
:<code>MC;LL=-1066;LH=904;SL=-562;SH=385;D=332B4B4D54D5554B552CD2D554B2B5354A;C=429;</code><br />
<br />
*MU - Message unsynced: Diese Art von Nachrichten sind nicht nach Manchester codiert und haben auch keinen erkennbaren Sync / Clock Signalpegel am Start der Nachricht. Bei diesen Nachrichtentypen ist es, im Vergleich zu den anderen, am wahrscheinlichsten, dass das übermittelte Signal unvollständig oder überhaupt kein Signal ist. Wie bei MS sind P0-P6 die Signalpegel und in D= wird die Abfolge der Signalpegel referenziert. CP=2 gibt auch hier die Referenz zum Takt an, allerdings muss dieser nicht korrekt erkannt worden sein.<br />
:<code>MU;P0=1372;P1=-580;P2=362;P3=-1047;D=01212321212321212121212121212123212123212321232121212121212321;CP=2;</code><br />
<br />
Es erscheinen viele Meldungen dieser Art:<br />
<br />
<pre><br />
Fingerprint for MU Protocol id xxxx -> yyy matches, trying to demodulate<br />
sduino: Starting demodulation at Position 1<br />
Fingerprint for MU Protocol id 28 -> IC Ledspot matches, trying to demodulate<br />
sduino: Starting demodulation at Position 1<br />
Fingerprint for MU Protocol id 29 -> HT12e remote matches, trying to demodulate<br />
</pre><br />
<br />
Dies sind nun Bemühungen, anhand der von der SIGNALDuino-Firmware gelieferten rohen aber detaillierten Signal-Strings eine Vor-Analyse / Fingerprinting vorzunehmen.<br />
Man könnte nun z.B. bei solchen Fingerprinting-Analysen erkennen:<br />
* dass der Basis-Takt-Wert innerhalb eines charakteristischen Zeit-Bereichs liegt<br />
* dass die Anzahl der Sync-Pulse eine präzise Zahl ist<br />
* dass Längen erkannter Puls-Typen innerhalb eines Bereichs liegen<br />
<br />
Mittels solcher Untersuchungen kann man also final hoffentlich hinreichend plausibel feststellen, "dass diese Aktivitäten offensichtlich(?) zu einer Funk-Komponente Rauchmelder von Hersteller XYZ gehören müssen, und man somit weiterleiten muss an ein (möglicherweise bereits existierendes) Userdaten-Dekodier-Modul für diese Herstellerkomponente".<br />
<br />
<br />
Bei einer dann erfolgenden Demodulation des noch rohen SIGNALDuino-Strings könnte man z.B. (hoffentlich richtigerweise) annehmen, dass eine Signalpegel-Typ-Folge "13" eine binäre 1 bedeuten soll, während eine Folge "12" eine binäre 0 bedeuten soll. Man erhält aus dem Gesamt-Puls-String also nach vollständiger Demodulation eine Abfolge von vielen 0/1 Bits, die insgesamt ein Datenwort darstellen, mit einer gewissen Länge von NN bits (diese Längen-Angabe könnte übrigens - neben Namenssuche nach Hersteller oder Produkt etc. - ein wichtiges Internet-Such-Merkmal sein, ob andere Frameworks tatsächlich bereits wissen, wie Daten dieser Funk-Komponente zu dekodieren sind!). Dieses demodulierte Datenwort ist nun das finale Datenwort, welches einen Container für die Funk-Komponenten-Informationen darstellt (in diesem Container also beispielsweise folgende Bits-Bereiche enthalten: Temperatur, Feuchte, Akku-Status, ID, Alarm, ... - zumindest wenn nicht dummerweise der ganze Daten-Container erst einmal CRC- oder Crypto-verschlüsselt ist...).<br />
<br />
Man muss an dieser Stelle unbedingt sagen, dass dieses Userdaten-Datenwort (einer bestimmten Hersteller-Funk-Komponente!) natürlich bei ''jeglichen'' Transceiver-Systemen ''immer'' gleich (identisch) erkannt werden ''muss'' - an dieser Stelle ist also ganz klar, dass diese Daten an ''allgemeine'' FHEM-Module weitergeleitet (Dispatched) werden müssen, die nach Übernahme von Daten von ''jeglichen'' Transceiver-Systemen diese Daten immer auf die gleiche Weise ('''''generisch/zentral''''') für die jeweilige Hersteller-Funk-Komponente erledigen.<br />
<br />
'''Die Abfolge ist also ganz klar:'''<br />
Funk-Aktivität --> Transceiver-Gerät/Firmware (SIGNALDuino) --> maximal detailreich beschreibender Rx-Analyse-Output-String --> Fingerprinting-Grobzuordnung des (SIGNALDuino-Firmware-)Outputs (durch 00_SIGNALduino.pm) auf gerätespezifisches Verhalten --> ''generische/zentrale'' Dekodierung des gerätespezifischen Protokoll-Datenworts, in zentralen Grundsatz-Modulen wie z.B. <code>14_SD_WS.pm</code>).<br />
<br />
Und wenn dann bei einer solchen Schritte-Abfolge irgendetwas noch fehlen/unpassend sein sollte, dann muss eben entsprechendes Development an gewissen Stellen erfolgen ;-)<br />
<br />
====Minimieren (whitelist/blacklist) von unerwünschter Kommunikations-Aktivität/Einträgen====<br />
<br />
"Unknown Code" bedeutet, dass der SIGNALduino Signaldaten empfangen und diese binär interpretiert hat. Diese Meldung soll uns nun aber mitteilen, dass es dann nicht weiter verarbeitet werden kann, da kein Modul existiert (oder kein Weiterleitungs-Dispatch zu einem bereits existierenden), welches diese Daten jetzt in ihre Bedeutung umwandeln kann. <br />
:<code>sduino: Unknown code u1FFFFF0, help me!</code><br />
<br />
Außerdem kommt es gehäuft zu Logmeldungen und auch Events in ähnlicher Form:<br />
:<code>SIGNALduino_unknown incomming msg: u85#FF8081</code><br />
<br />
Mittlerweile sind über 50 Protokolle für den SIGNALduino definiert. Dadurch kommt es vor, dass sich ein Signal mit mehr als einem Protokoll demodulieren lässt. Meist führt dies dann zu zusätzlichen "Unknown code"-Einträgen.<br />
<br />
Derartige Einträge können mit dem Attribut <code>WhitelistID</code> minimiert werden. Dabei werden die Geräte, die nach Daten-Empfang tatsächlich verarbeitet werden sollen (also welche Protokolle vom FHEM Modul berücksichtigt werden), mit ihrer Protokollnummer in die <code>WhitelistID</code> aufgenommen.<br />
Für Protokolle, die nicht berücksichtigt werden, gibt es weder Logeinträge noch Events. Diese werden im Programmablauf nicht berücksichtigt. Das spart zum einen Ressourcen und trägt auch zur Übersichtlichkeit bei. <br />
Die Protokollnummer kann der Tabelle [[#Unterstützte Geräte|Unterstützte Geräte]] entnommen werden (hilfreich ist es auch, wenn in den verwendeten Geräten im Internal <gerätename>_DMSG nachgesehen wird). So bedeutet beispielsweise ein Eintrag der Form <code>W50#FF553335FFBC</code> dass dann das Protokoll #50 in die Whitelist aufzunehmen wäre (<code>attr sduino whitelist_IDs 50</code>).<br />
{{Randnotiz|RNTyp=r|RNText=Achtung Schreibweise: Dokumentation oft als WhitelistID o.ä., aber Name ist whitelist_IDs!!<br />
}}<br />
Die Angabe erfolgt durch Komma getrennt: z.B.:<br />
:<code>1,2,5,10</code><br />
<br />
=== Senden mit dem SIGNALduino ===<br />
Der SIGNALduino kann etwas "raw senden", indem ihm das Signal so übermittelt wird, wie er es moduliert. Hierzu muss der Befehl wie folgt eingegeben werden:<br />
<br />
<code><br />
set sduino sendMsg P3#00111010#R4<br />
</code><br />
<br />
Dieser Befehl moduliert die Bitfolge 00111010 mittels Protokoll #3 und wiederholt die Nachricht 4x.<br />
Die Protokoll Nummer kann aus einer empfangenen Nachricht extrahiert werden. Ebenso die Bits.<br />
<code><br />
sduino: extracted data 00111010 (bin)<br />
sduino: Found Protocol id 3 <br />
</code><br />
<br />
Alternativ kann das Signal auch in einer "Rohform" angegeben werden. Dies ist manchmal in speziellen Fällen notwendig:<br />
<code><br />
set sduino raw SR;;R=3;;P0=4742;;P1=-1554;;P2=286;;P3=-786;;P4=649;;P5=-420;;D=0123234545234545452323232323454523234523454523232345454523232323452345234523452345;;<br />
</code><br />
<br />
R=3 bedeutet, das Signal wird 3x gesendet.<br />
Die Übertragung besteht aus den in D angegebenen Pulsen, welche in P0-P5 definiert werden.<br />
Die Daten kann man aus einer empfangenen MS oder MU Nachricht extrahieren.<br />
<br />
Alternativ kann ab Version 3.2 auch eine vereinfachte Form eingegeben werden.<br />
<br />
====Fehlersuche====<br />
(Zielgerät reagiert nicht, etc.)<br />
<br />
* Nachrichtenwiederholungsanzahl muss evt. für manche Geräte entsprechend groß eingestellt sein<br />
{{Randnotiz|RNTyp=r|RNText=VORSICHT blöder Schreibweisen-Mismatch ITClock vs. ITclock!!}}<br />
* Sende-Takt-Wert (Clock) passt evt. nicht ganz, siehe z.B. Thread-Antwort {{Link2Forum|Topic=58397|Message=775434|LinkText=Signalduino Version 3.3.1}}, wo für IT-Geräte ein Attribut anhand der CP= des Empfangsdaten-Logs modifiziert wird. ACHTUNG: dies kann entweder global das Internal-Attribut <code>ITClock</code> eines SIGNALduino-Transceiver-Devices sein, oder (viel besser da korrekt Geräte-Instanz-spezifische Konfiguration) das <code>ITclock</code> eines IT-Client-Devices.<br />
<br />
== Fehlerbehandlung ==<br />
<br />
=== Modul-Initialisierung ===<br />
<br />
==== Perl-Modul Digest::CRC fehlt ====<br />
<br />
Das FHEM-Log kann (bei ab Version 3.5.x ) folgendes enthalten:<br />
<br />
<code>Can't locate Digest/CRC.pm in @INC (you may need to install the Digest::CRC module) (@INC contains: fhem.p/lib fhem.p/FHEM/lib ./FHEM/lib ./lib ./FHEM ./ /usr/local/FHEM/share/fhem/FHEM/lib /opt/fhem . /etc/perl /usr/local/lib/arm-linux-gnueabihf/perl/5.28.1 /usr/local/share/perl/5.28.1 /usr/lib/arm-linux-gnueabihf/perl5/5.28 /usr/share/perl5 /usr/lib/arm-linux-gnueabihf/perl/5.28 /usr/share/perl/5.28 /usr/local/lib/site_perl /usr/lib/arm-linux-gnueabihf/perl-base) at ./FHEM/00_SIGNALduino.pm line 28, <$fh> line 1870.<br />
BEGIN failed--compilation aborted at ./FHEM/00_SIGNALduino.pm line 28, <$fh> line 1870.</code><br />
<br />
In diesem Fall ist der Transceiver nicht funktionsfähig - es muss erst Perl-Modul <code>Digest::CRC</code> (Ubuntu und Debian: Package <code>libdigest-crc-perl</code>) installiert werden und fhem neu gestartet werden.<br />
<br />
=== Konfiguration von Firmware/Hardware (Reset usw.) ===<br />
Der SIGNALduino kann mit folgendem Befehl auf Werkseinstellungen zurückgesetzt werden:<br />
:<code>set raw e</code><br />
Ob ein solcher Reset nötig ist, erkennt man an dem Inhalt vom Reading <code>cc1101_config</code>, dort unsinnige Werte angezeigt werden oder dem Reading <code>config</code> welches durch den Befehl "get config" aktualisiert wird, was im Standard auf "MS=1;MU=1;MC=1" entspricht.<br />
<br />
In der Firmware sind diverse Befehle eingebaut, welche über einen <code>set raw</code> Befehl im Modul direkt ausgeführt werden können. Sofern möglich, sollte die Abfrage von Werten aus dem Modul allerdings mit den dafür vorgesehenen Kommandos erfolgen, da die Rückmeldungen des <code>set raw</code> Befehls nur im Logfile ab verbose 4 erscheinen. Die Befehle sind nützlich, wenn direkt auf den Microcontroller zugegriffen wird: <br />
<br />
:<code>C<reg></code> <reg> is a (two digit) hex number: return the value of the cc1101 register. <reg>=99 dumps the first 48 registers. Example: <code>set raw C35</code> führt ab verbose 4 zu einer Logausgabe folgender Art: <code>Read, msg: C35 = 0D</code><br />
:<code>e</code> EEPROM / factory reset. resets all eeprom values without reboot<br />
:<code>W<AA><XX></code> Write eeprom (schreibt einen Wert ins EEPROM und ins CC1101 Register. Die EEPROM Adresse hat einen Offset von 2. z.B W041D schreibt 1D ins Register 2 des CC1101)<br />
<br />
Die Sendeleistung lässt sich mit <br />
:<code>get sduino ccpatable</code> <br />
<br />
prüfen, wobei die Rückmeldung wie folgt zu lesen ist: <br />
"-10_dBm" => '34',<br />
"-5_dBm" => '68',<br />
"0_dBm" => '60',<br />
"5_dBm" => '84',<br />
"7_dBm" => 'C8',<br />
"10_dBm" => 'C0' <br />
Dabei wird die Sendeleistung dauerhaft mit dem Befehl<br />
:<code>set sduino cc1101_patable <value></code><br />
hochgeschaltet (<value> durch den Wert ersetzen).<br />
<br />
Weitere Firmware-Befehle sind im Thread-Beitrag {{Link2Forum|Topic=58396|Message=497921}} zu finden.<br />
<br />
== Foren Links ==<br />
* {{Link2Forum|Topic=38402|LinkText=Forenthread - Ankündigung}}<br />
* {{Link2Forum|Topic=58396|LinkText=SIGNALDuino Empfänger Firm- und Hardware}}<br />
* {{Link2Forum|Topic=82379|Message=1033374|LinkText=SIGNALDuino Schaltplan}}<br />
* {{Link2Forum|Topic=58397|LinkText=Signalduino Entwicklung Version 3.3.1 }}<br />
* [http://www.rflink.nl/blog2/wiring Beschreibung zu diversen Empfängern und Verbesserung der Empfangsleistung]<br />
* [[SIGNALduino in die Arduino Entwicklungsumgebung einbinden]]<br />
* [[Somfy via SIGNALduino]]<br />
<br />
[[Kategorie:Interfaces]]<br />
[[Kategorie:Arduino]]<br />
[[Kategorie:433MHz]]<br />
[[Kategorie:868MHz]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Sonoff&diff=35942Sonoff2021-08-01T14:21:50Z<p>Andies: /* Flashen mit Arends Sketch */ ebbasiert flashen, wenn USB verbindung vorliegt</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Ankopplung der Sonoff Module an FHEM<br />
|ModType=<br />
|ModForumArea=ESP8266<br />
|ModTechName=Sonoff<br />
|ModOwner=Reinhart <br />
}}<br />
<br />
'''Einleitung'''<br />
<br />
Die [https://www.itead.cc/sonoff-wifi-wireless-switch.html Fa. Itead] bietet kostengünstige "Sonoff" Produkte an, die den [http://dl.itead.cc/IM151116002/0A-ESP8266_Specifications_v4.1.pdf ESP8266 Chip] On Board haben und somit die ideale Grundlage für [http://www.esp8266.nu/index.php/Main_Page ESPEasy] und für FHEM<ref>Foren-Board: {{Link2Forum|Area=Sonstiges}}</ref> darstellen. Unverändert nutzen diese Geräte allerdings eine in China basierende Cloudlösung und müssen für die Benutzung in FHEM umgeflasht werden. Dieser Artikel beschreibt die Ankopplung der Sonoff Module an FHEM mit ESPEasy oder [[MQTT Einführung|MQTT]] mit Tasmota ('''T'''heo '''A'''rends '''S'''onoff '''M'''QTT '''O'''ver '''T'''he '''A'''ir - einer offenen Firmware von [https://github.com/arendst arendst]). Hierbei sind Grundkenntnisse beim Arduino (um die Firmware neu zu flashen) sowie im Umgang mit 230V notwendig.<br />
<br />
'''Bitte unbedingt die elektrotechnischen Sicherheitsrichtlinien beachten und einhalten!'''<br />
[[Datei:sonoff_sw_15.jpg|thumb|left|alt=Warnung Netzspannung]]<br />
<div style="clear:both;"></div><br />
'''Achtung: An dem Modul liegt Netzspannung an, die lebensgefährlich ist. Es dürfen nur entsprechend ausgebildete Personen dieses Modul in Betrieb nehmen. Zum Umbau und zur Softwareaktualisierung darf keine Netzspannung angeschlossen sein'''<br />
<br />
Wie gefährlich das hantieren mit Netzspannung sein kann, zeigt das Beispiel eines [http://mysku.ru/blog/china-stores/45762.html russischen Anwenders]. Er hat beim Flashen die Netzspannung am Modul gelassen und somit (über die Verbindung mit dem Netzteil des Laptops) lebensgefährliche Spannung auf die FTDI Schnittstelle gebracht. Das Modul ist dabei abgeraucht!<br />
<br />
<br />
'''Links des Herstellers'''<br />
<br />
[https://www.itead.cc/blog/user-guide-for-sonoff-slampher User Manual von Itead]<br />
<br />
[https://www.itead.cc/wiki/images/6/6b/Sonoff_schmatic.pdf Sonoff Schaltplan]<br />
<div style="clear:both;"></div><br />
<br />
<br />
==Modelle (mit Produktübersicht) ==<br />
<br />
Eine Übersichtliste der verschiedenen Produkte mit technischen Kurzangaben.<br />
<br />
{| class="wikitable" style="text-align:right"<br />
! Produkt Name !! Beschreibung !! Spannungsversorgung !! Imax !! Pmax !! Frequenz !! Schaltplan !! Link<br />
|-<br />
| Sonoff || WWW-Schalter || 90~250V AC || 10A || 2200W || 2.4Ghz || [http://wiki.iteadstudio.com/Sonoff Plan] || [https://www.itead.cc/smart-home/sonoff-wifi-wireless-switch.html Link] <br />
|-<br />
| Sonoff RF || 433 MHz Fernbed. || 90~250V AC || 10A || 2200W || 2.4Ghz || [http://wiki.iteadstudio.com/Sonoff_RF Plan] || [https://www.itead.cc/smart-home/im151116003.html Link] <br />
|-<br />
| Sonoff SV || Niederspannungsschalter|| 5~24V DC || 10A || 240W DC || 2.4Ghz || [http://wiki.iteadstudio.com/Sonoff_SV Plan] || [https://www.itead.cc/smart-home/sonoff-sv.html Link] <br />
|-<br />
| Sonoff TH10/TH16 || WWW-Schalter mit Temp.&Luftf. || 90~250V AC || 10A/16A || 2200W(10A)/3500W(16A) || 2.4Ghz || [http://wiki.iteadstudio.com/Sonoff_TH_10/16 Plan] || [https://www.itead.cc/smart-home/sonoff-th.html Link] <br />
|-<br />
| Sonoff Dual || Doppel-WWW-Schalter || 90~250V AC || 16A || 3500W || 2.4Ghz || [https://www.itead.cc/wiki/Sonoff_Dual Plan] || [https://www.itead.cc/sonoff-dual.html Link] <br />
|-<br />
| Sonoff Pow || WWW-Schalter und Strommessgerät || 90~250V AC || 16A || 3500W || 2.4Ghz || [https://www.itead.cc/wiki/Sonoff_Pow Plan] || [https://www.itead.cc/sonoff-pow.html Link] <br />
|-<br />
| Sonoff LED || WWW-LED-Dimmer || 180~265V AC || 0.3-0.6A || 42W || 2.4Ghz || kein || [https://www.itead.cc/sonoff-led.html Link] <br />
|-<br />
| Sonoff Touch || WWW-Wandschalter || 90~250V AC || 2A || 400W || 2.4Ghz || kein || [https://www.itead.cc/sonoff-touch.html Link] <br />
|-<br />
| Slampher || WWW-433MHz-Lichtfassung || 90~250V AC || 2A || 200W || 2.4Ghz || [http://wiki.iteadstudio.com/Slampher Plan] || [https://www.itead.cc/smart-home/slampher-wifi-wireless-light-holder.html Link] <br />
|-<br />
| S20 Smart Socket || Smart socket || 90~250V AC || 10A || 2000W || 2.4Ghz || kein || [https://www.itead.cc/smart-home/smart-socket-eu.html EU-Stecker] <br />
|-<br />
| iFan || Smart Lüfter || 185~264V AC ||﹤1A || 60W || 2.4Ghz || kein || [https://www.itead.cc/smart-home/smart-socket-eu.html EU-Stecker] <br />
|-<br />
| Motor/Pump Control Switch || clockwise/anticlockwise running || 5V/7~32V DC || 10A || 50~320W || 2.4Ghz || kein || [https://www.itead.cc/smart-home/motor-reversing-wifi-wireless-switch.html Link] <br />
|-<br />
| 1 Chnl Inching/self-locking Switch || Access control || 5V/12V DC || 10A || 50/120W || 2.4Ghz || kein || [https://www.itead.cc/smart-home/inching-self-locking-wifi-wireless-switch.html Link] <br />
|-<br />
| 4 Chnl Inching/self-locking/inter-locking Switch || Access control, rolling door control || 5V/5~32V DC/90~250V AC || 10A || 50~320W/2500W || 2.4Ghz || kein || [https://www.itead.cc/ifan.html Link] <br />
|-<br />
| &nbsp; || || || || || || ||<br />
|-<br />
|}<br />
<br />
<div style="clear:both;"></div><br />
<br />
<br />
===Model IM151116002: Erstes Modell===<br />
Link zum Hersteller: [https://www.itead.cc/sonoff-wifi-wireless-switch.html Sonoff WiFi Wireless Smart Switch for MQTT COAP Smart Home]<br />
[[Datei:sonoff_sw_0.jpg|thumb|left|alt=sonoff Switch]]<br />
<br />
Das Sonoff Modul ist in einem zweckmäßigen Gehäuse verbaut.<br />
<div style="clear:both;"></div><br />
<br />
[[Datei:sonoff_sw_1.jpg|thumb|left|alt=sonoff Switch von vorne]]<br />
<br />
Die Platine ist sehr übersichtlich aufgebaut und der Hersteller hat zudem Vorbereitungen zum Flashen einer alternativen Software vorgesehen (über serielle Schnittstelle via FTDI-Modul). Mit einer alternativen Software wie ESPEasy kann '''Sonoff''' an FHEM leicht angebunden werden.<br />
<div style="clear:both;"></div><br />
<br />
[[Datei:sonoff_sw_3.jpg|thumb|left|alt=sonoff Switch von hinten]]<br />
Die stromführenden Leitungen wurden mit Lötzinn vom Hersteller verstärkt um die angegebenen Stromstärken mit geringer Hitzeentwicklung zu transportieren.<br />
<br />
'''Achtung: Bitte vor den Arbeiten kontrollieren, dass an der Platine keine Netzspannung angeschlossen ist, LEBENSGEFAHR!'''<br />
<div style="clear:both;"></div><br />
<br />
<div style="clear:both;"></div><br />
<br />
===Model IM160712005: TH 10A/16A ===<br />
Link zum Hersteller: [https://www.itead.cc/sonoff-th.html Sonoff TH 10A/16A WiFi Smart Switch]<br />
<br />
[[Datei:Sonoff_TH_10A-16A_kleiner.jpg|thumb|left|alt=TH10 / TH16 weitere GPIO zugänglich machen]]<br />
Der Hersteller hat eine Platine für eine weitere Stiftleiste vorbereitet, die jedoch bestückt werden muss. Die nicht beschalteten Stifte können dann genutzt werden, um die "verdeckten" GPIO zugänglich zu machen. Die Verdrahtung kann dem Bild entnommen werden.<br><br />
'''Achtung: Bitte vor den Arbeiten kontrollieren, dass an der Platine keine Netzspannung angeschlossen ist, LEBENSGEFAHR!'''<br />
<div style="clear:both;"></div><br />
<br />
<div style="clear:both;"></div><br />
<br />
===Model IM160811001: Sonoff Dual ===<br />
Link zum Hersteller: [https://www.itead.cc/sonoff-dual.html Sonoff Dual WiFi Wireless Smart Swtich] (sic!)<br />
<br />
<div style="clear:both;"></div><br />
<br />
<div style="clear:both;"></div><br />
<br />
===Model IM160810001: Sonoff Pow ===<br />
Link zum Hersteller: [https://www.itead.cc/sonoff-pow.html Sonoff POW WiFi Switch with Power Consumption Measurement]<br />
[[Datei:sonoff_sw_30.jpg|thumb|left|alt=SONOFF POW]]Ein sehr interessantes und kostengünstiges Modul zur Messung der aktuellen Leistung. Das Modul kann via MQTT in FHEM angebunden werden. Ein Beispiel zur Einbindung ist [http://www.fhemwiki.de/wiki/Sonoff#Sonoff_POW_einrichten unten] im Wiki beschrieben.<br />
<br />
<div style="clear:both;"></div><br />
===weitere Modelle===<br />
Weitere Modelle finden sich auf der [https://www.itead.cc/search/result/?cat=&q=sonoff Homepage des Hersstellers]<br />
<br />
=Neuprogrammierung der Sonoff-Modelle=<br />
==Einleitung: Welche Firmware? ==<br />
===Übersicht===<br />
Vorab: Es gibt derzeit (August 2018) drei Möglichkeiten, die Geräte von Sonoff mit eigener Firmware zu versehen. Entweder man verwendet MQTT gemeinsam mit TASMOTA oder man verwendet ESPEasy. Beide Firmware-Produkte werden derzeit weiterentwickelt und müssen geflasht werden. Es scheint so zu sein, dass bei den POW-Geräten die Sensoren nicht korrekt erkannt werden und sich dort MQTT anbietet. Jedoch sollte in den Foren geprüft werden, ob diese eindeutige Präferenz durch Weiterentwicklung noch aufrecht erhalten werden kann. <br />
<br />
Ein dritter Weg zum Flashen ist erst kürzlich entdeckt worden und wird auf der Webseite [https://github.com/mirko/SonOTA/wiki] beschrieben, in diesem Wiki fehlen noch entsprechende Erläuterungen. Er beruht darauf, dass Sonoff regelmäßig nach einer neuen Firmware fragt und dazu einen Server in China kontaktiert. Per DNS-Spoofing lenkt man diese Anfrage auf einen heimischen Rechner, auf dem ein Skript läuft. Dieses Skript bedient die Anfrage und überträgt ein erstes Image. In einem zweiten Schritt verbindet man sich dann mit dem Rechner zu der SSID, welche Sonoff aufmacht und die Zielfirmware wird geladen. Die Schritte sollte kann man sich unter der genannten Adresse beim verlinkten Issue #20 anschauen.<br />
<br />
Link frühere Software: [https://github.com/arendst/Sonoff-MQTT-OTA-Arduino Sonoff-MQTT-OTA-Arduino]<br />
<br />
===Stromversorgung===<br />
<br />
Während des Flashvorganges benötigt das Sonoff-Modul eine Stromversorgung. Dabei darf unter keinen Umständen die Netzspannung von 230V verwendet werden. Selbst die 5V aus einem USB-Anschluss sind zu hoch, da das Modul sonst Gefahr läuft unbrauchbar zu werden. Es sind ausschließlich 3.3V zu verwenden. <br />
<br />
Der FTDI Chip kann laut Datenblatt höchstens 50 mA liefern, das ESP Modul zieht aber bis zu 300 mA Spitzenstrom und verbraucht schon im normalen Modus ca. 50-70 mA. Einige Anwender haben gute Erfahrungen mit einfachen USB-TTL-Konvertern gemacht, andere beschreiben unverständliche Fehlermeldungen. Auch kann es sein, dass der Flashvorgang ohne Fehler läuft, der Flash aber anschließend korrupt ist und das Modul unklares Verhalten zeigt. In dem Fall die Spannungsversorgung 3.3 Volt prüfen! Auch das USB Kabel kann eine Fehlerursache sein.<br />
<br />
'''Sollte der Flashvorgang mit einem USB-TTL-Konverter nicht funktionieren, ist zuerst eine stabile 3.3V-Versorgung auszuprobieren''' (beispielsweise durch einen Arduino). RxTx werden nach wie vor mit dem USB-TTL-Adapter verbunden (gekreuzt). Zum Flashen sind dann GND vom Arduino und vom USB-TTL-Adapter zu verbinden.<br />
<br />
<div style="clear:both;"></div><br />
<br />
===Schnittstelle ===<br />
[[Datei:sonoff_sw_2.jpg|thumb|left|alt=serielle Schnittstelle]]<br />
<br />
Die abgebildete Platine zeigt die benötigten Signale für ein FTDI Modul (Model: IM151116002).<br />
<br />
Pin5 = vorbereitet für GPIO<br />
Pin4 = Masse<br />
Pin3 = TxD<br />
Pin2 = RxD<br />
Pin1 = 3.3V<br />
<br />
Siehe dazu auch den {{Link2Forum|Topic=55036|LinkText=Link aus dem Forum}}:<br />
<div style="clear:both;"></div><br />
<br />
[[Datei:sonoff_sw_4.jpg|thumb|left|alt=Platine mit Stiftleiste bestücken]]<br />
Der Hersteller hat zwar die Platine vorbereitet, diese muss jedoch mit einer Stiftleiste bestückt werden, um das FTDI Modul bequem verbinden zu können. Die Stiftleiste muss allerdings selber nachgerüstet werden. Nachdem das ESPEasy zum ersten Mal geflasht wurde, kann es in Zukunft via WEB (OTA) geflasht werden und die Stiftleiste ist dann eigentlich nicht mehr erforderlich. <br><br />
Für die Module TH10/TH16 sind die Lötpunkte für die Stiftleiste schon beschriftet. <br />
<div style="clear:both;"></div><br />
'''''Achtung: Bitte vor den Arbeiten kontrollieren, dass an der Platine keine Netzspannung angeschlossen ist, LEBENSGEFAHR!'''''<br />
<div style="clear:both;"></div><br />
<br />
===Arduino als USB-TTL ===<br />
<br />
Sollte kein USB-TTL-Adapter vorhanden sein, kann man zum Flashen auch einen Arduino "missbrauchen". Dazu wird RESET und GND verbunden, siehe [http://www.instructables.com/id/Turn-Arduino-into-USB-to-TTL-Adapter-with-1-wire/ diese Webseite]. Der Vorteil dieser Lösung besteht darin, dass die PINS für 5V und 3.3V deutlich voneinander getrennt sind.<br />
<br />
===Erfolgs- und Fehlermeldungen ===<br />
<br />
[[Datei:FehlersucheHochladen.png|thumb|left|alt=Fehlersuche aktivieren]]<br />
Eine sehr typische Fehlermeldung während des Flashvorganges ist <br />
warning: espcomm_sync failed<br />
error: espcomm_open failed<br />
error: espcomm_upload_mem failed<br />
Das Tückische an dieser Fehlermeldung ist, dass sie nahezu keine Hinweise darauf gibt, weshalb der Upload fehlgeschlagen ist. In sehr vielen Fällen können die Fehler auf ganz klassische Probleme zurückgeführt werden: so wurde Tx beim Chip nicht mit Rx, sondern wieder Tx beim Arduino verbunden oder es wurde der falsche COM-Port ausgewählt, der falsche Uploader, die Stromversorgung war zu gering (siehe oben) etc. pp. Die Arduino-IDE erlaubt es, genaue Angaben beim Hochladen auszulesen (siehe Screenshot oben, Haken bei "Hochladen"). Ohne diese Angaben ist eine Fehlersuche typischerweise aussichtslos.<br />
<br />
Im Erfolgsfall erscheint in der Arduino IDE in etwa der folgende Text (hier bei einem Sonoff S20):<br />
<br />
/Applications/Arduino.app/Contents/Java/arduino-builder -dump-prefs -logger=machine -hardware <br />
*** danach folgt sehr viel Text zum kompilieren *** <br />
esptool v0.4.9 - (c) 2014 Ch. Klippel <ck@atelier-klippel.de><br />
setting board to ck<br />
setting baudrate from 115200 to 115200<br />
setting port from /dev/tty.usbserial to /dev/cu.SLAB_USBtoUART<br />
setting address from 0x00000000 to 0x00000000<br />
espcomm_upload_file<br />
espcomm_upload_mem<br />
opening port /dev/cu.SLAB_USBtoUART at 115200<br />
tcgetattr<br />
tcsetattr<br />
serial open<br />
opening bootloader<br />
resetting board<br />
trying to connect<br />
espcomm_send_command: sending command header<br />
espcomm_send_command: sending command payload<br />
trying to connect<br />
espcomm_send_command: sending command header<br />
espcomm_send_command: sending command payload<br />
espcomm_send_command: receiving 2 bytes of data<br />
espcomm_send_command: receiving 2 bytes of data<br />
espcomm_send_command: receiving 2 bytes of data<br />
espcomm_send_command: receiving 2 bytes of data<br />
espcomm_send_command: receiving 2 bytes of data<br />
espcomm_send_command: receiving 2 bytes of data<br />
espcomm_send_command: receiving 2 bytes of data<br />
espcomm_send_command: receiving 2 bytes of data<br />
Uploading 487120 bytes from /var/folders/l6/myrckv8d12z9_06fl49fm36h0000gn/T/arduino_build_558323/sonoff.ino.bin to flash at 0x00000000<br />
erasing flash<br />
size: 076ed0 address: 000000<br />
first_sector_index: 0<br />
total_sector_count: 119<br />
head_sector_count: 16<br />
adjusted_sector_count: 103<br />
erase_size: 067000<br />
espcomm_send_command: sending command header<br />
espcomm_send_command: sending command payload<br />
setting timeout 15000<br />
setting timeout 100<br />
espcomm_send_command: receiving 2 bytes of data<br />
writing flash<br />
................................................................................ [ 16% ]<br />
................................................................................ [ 33% ]<br />
................................................................................ [ 50% ]<br />
................................................................................ [ 67% ]<br />
................................................................................ [ 84% ]<br />
............................................................................ [ 100% ]<br />
starting app without reboot<br />
espcomm_send_command: sending command header<br />
espcomm_send_command: sending command payload<br />
espcomm_send_command: receiving 2 bytes of data<br />
closing bootloader<br />
<br />
<br />
=== Vorsicht: Umflashen, Updates und Upgrades ===<br />
Es kann Situationen geben, in denen man von einer Firmware auf eine andere umsteigen möchte. Dies ist nicht unproblematisch!<br />
<br />
Sowohl ESPEasy als auch TASMOTA bieten normalerweise einen eigenen OTA (over-the-air) Zugang an. Dort muss das Modul nicht ausgebaut werden, damit man an der seriellen Schnittstelle Kabel anbringt, sondern man lädt die neue Firmware über einen Browser hoch. Ein solches update kann dann ferngesteuert erfolgen, während der Sonoff weiter eingebaut bleibt.<br />
<br />
Will man dagegen grundsätzliche Änderungen an der Firmware vornehmen (Umstieg von TASMOTA zu ESPEasy oder anders herum) sollte der Flashspeicher vollständig geleeert werden. Anderenfalls sind dubiose, schwer erklärbare Fehlermeldungen die Folge. Ein vollständiges Löschen des Flashspeichers kann nicht OTA erfolgen, hierzu muss man an die serielle Schnittstelle gelangen.<br />
<br />
Das Programm esptool (zu den Programmoptionen [[http://manpages.ubuntu.com/manpages/bionic/man1/esptool.1.html]]) erlaubt ein solches Löschen in zwei Schritten. Dazu sei angenommen, dass es sich um einen schwarzen ESP-01 mit 1MB Speicher handelt (mehr über die verschiedenen Hardware-Varianten auf [[https://www.letscontrolit.com/wiki/index.php/ESP_Hardware]]). Dann lautet der erste Befehl, mit dem der Flashspeicher gelöscht wird, wie folgt<br />
./esptool -vv -cd none -bm dout -bz 1M -cb 57600 -cp /dev/cu.SL_USBtoUART -ce<br />
Allerdings setzt dies voraus, dass der Flashspeicher 1 MB groß ist und man eine entsprechende leere 1MB Datei besitzt. Man sollte danach ein weiteres Mal den Flashspeicher mit einer leeren Datei überschreiben, die beispielsweise von ESPEasy bereitgestellt wird:<br />
./esptool -vv -cd none -bm dout -bz 1M -cb 57600 -cp /dev/cu.SL_USBtoUART -ca 0x00000 -cf ./blank_1MB.bin<br />
In beiden Fällen wurde angenommen, dass der Flashprogrammer ein USB-2-UART Stick ist, der an dem konkreten Rechner unter dem Verzeichnis /dev/cu.SL_USBtoUART zu finden ist. Hier muss man nachschauen, wie das Verzeichnis auf dem eigenen Rechner lautet.<br />
<br />
Angeblich ist auch der folgende Befehl <br />
./esptool.py erase_flash<br />
erfolgreich. Dies erfordert das Tool [https://github.com/espressif/esptool esptool.py]<br />
<br />
Es wird berichtet, dass auch das Betriebssystem Einfluss auf das Ergebnis hat (was eigentlich nicht sein kann), siehe dazu [https://github.com/arendst/Sonoff-Tasmota/issues/3385 Eintrag von arendst commented on 2 Aug 2018]. <br />
<br />
Bei Sonoff-Devices ab Februar 2018 erfordert die Programmierung das Flash-Tool aus diesem [http://www.letscontrolit.com/forum/viewtopic.php?f=5&t=3386&hilit=Same+problems+using+the+flashtool+from+letscontrolit&start=10#p18240 Forumsbeitrag].<br />
<br />
Bei der Programmierung ist wie folgt vorzugehen: <br />
* Interface-Adapter (z.B. FTDI232) anschließen<br />
* Button am Device drücken und gedrückt halten<br />
* USB-Stecker des FTDI232 am PC einstecken, den Button weiterhin gedrückt halten (so wird das Device in den Programmiermodus versetzt)<br />
* Flash-Tool wie im Forumsbeitrag angegeben einsetzen, um ESPEasy aufzuspielen und Fertigmeldung abwarten<br />
* Button loslassen<br />
* USB-Stecker kurz aus- und wieder einstecken<br />
* Dann sollte sich das Device nach kurzer Zeit als Access Point ESP_Easy_0 anbieten<br />
<br />
==MQTT und TASMOTA==<br />
<br />
TASMOTA ist neben ESPEasy eine der beiden Firmwares, mit denen Sonoff Gerät gut in FHEM integriert werden können. Während TASMOTA stärker Wert auf Weboberflächen und gute Handhabbarkeit legt und typischerweise sofort einsetzbar ist, liegt der Schwerpunkt bei ESPEasy eher auf einer weiten Einbindung möglicher Sensoren und bedarf (wenige) Anpassungen. Beide Firmwares werden stetig ausgebaut und es ist nicht einfach, hier einen klaren Vorzug zu geben. TASMOTA scheint unter FHEM-Nutzern etwas verbreiterter zu sein.<br />
<br />
TASMOTA kommuniziert mit FHEM via MQTT. Hier gibt es zwei Möglichkeiten.<br />
# Man kann einen separaten Broker installieren und FHEM kommuniziert mit diesem Broker. Üblicherweise verwendet man hier mosquitto und die FHEM-Module mit dem Namen MQTT. Auf der Webseite [https://waschto.eu/sonoff-funkschalter-auf-esp8266-basis] ist die Installation inklusive des MQTT-Brokers sehr ausführlich beschrieben - bis hin zum Flashen des Sonoff-Gerätes. Insbesondere die Einrichtung der Arduino-Umgebung und das Flashen selbst setzt einige Grundkenntnisse in Linux und Arduino-Programmierung voraus, da sich mit den neuen Updates Verzeichnis- und Dateinamen geändert haben und diverse Dateien verschoben und umbenannt werden müssen. <br />
# Man kann FHEM als Broker nutzen. Hier sind die Module mit dem Namen MQTT2 zu verwenden.<br />
<br />
Generell kann man sagen, dass bei einer Neuinstallation dem zweiten Weg der Vorzug gegeben werden sollte. Wer dagegen bereits eine Installation besitzt, wird vielleicht weiterhin MQTT in der klassischen Variante nutzen wollen. Mehr dazu in dem Forenthemen {{Link2Forum|Topic=93151|LinkText="Frage zu MQTT und MQTT2"}} und {{Link2Forum|Topic=94768|LinkText="Lohnt sich der Umstieg von mosquitto zu MQTT2?"}}. Hier wird nur die Einrichtung von MQTT beschrieben, weil diese um einiges aufwendiger als MQTT2 ist. MQTT2 ist durch [[MQTT2-Module - Praxisbeispiele#attrTemplate|attrTemplate]] nahezu selbsterklärend.<br />
<br />
In diesem Wiki befindet sich eine Kurzeinführung zur Installation eines MQTT-Brokers auf der Wiki-Seite von [[MQTT_Einf%C3%BChrung]]. <br />
<br />
Link: [https://github.com/arendst/Sonoff-Tasmota Tasmota]<br />
<br />
<div style="clear:both;"></div><br />
<br />
===Flashen mit Arends Sketch===<br />
Die Einrichtung des Arduino-Sketches ist keine leichte Fingerübung, da sich diverse Dateinamen und Speicherorte mit Updates gegenüber den hier und in anderen Beschreibungen genannten geändert haben können (und werden...). Es wird auf die sehr [https://waschto.eu/sonoff-funkschalter-auf-esp8266-basis umfangreiche Erläuterung von waschto.eu] verwiesen, wobei einige weitere (kleinere) Änderungen auch dort nicht dokumentiert sind, sich aber aus dem Sinnzusammenhang der Fehlermeldungen erschließen lassen. Alle hier gezeigten Bildschirmfotos und Beispiele beziehen sich auf Basis der Version Tasmota (Stand 22.02.2017).<br />
<br />
Der Sketch kann hier [https://github.com/arendst/Sonoff-Tasmota.git geladen werden.]<br />
<br />
[https://github.com/arendst/Sonoff-Tasmota Arends Tasmota Github] Wenn nur der ESP mit tasmota geflasht werden soll (keine Verwendung des arduinos), dann kann man eine webbasierte Lösung verwenden. Zu diesem Zweck muss aber der ESP8266 eine USB-Verbindung mit dem PC aufweisen: <nowiki>https://arendst.github.io/Tasmota/</nowiki><br />
<br />
[[Datei:sonoff_bv_01.jpg|thumb|left|alt=Arduino Boardverwalter]]<br />
In der Arduino IDE unter Datei / Voreinstellungen im Feld "Zusätzliche Boardverwalter-URLs:" den Link: http://arduino.esp8266.com/stable/package_esp8266com_index.json einfügen. <br />
<br />
Dann unter '''Werkzeuge / Board / Boardverwalter''' ganz am Ende der Liste die Librarys für "esp8266 by ESP8266 Community" die letzte Version zu installieren. {{Link2Forum|Topic=46205|Message=534707|LinkText=Link zum Board}}.<br />
Im Tasmota Verzeichnis \lib werden auch die zum compilieren benötigten Librarys zur Verfügung gestellt.<br />
<br />
Das gesamte Sonoff Verzeichnis aus [https://github.com/arendst/Sonoff-Tasmota/archive/master.zip Arendts Sketch] entpacken (ist wie hier verlinkt ein Zipfile) und dann aus diesem Verzeichnis die sonoff.ino öffnen. Es können dann alle zu dem Sketch zugehörigen Dateien angesehen/editiert werden.<br />
<br />
<div style="clear:both;"></div><br />
Anschließend sollte noch die Datei '''user_config.h''' (im Unterverzeichnis "sonoff") editiert werden. Die Abschnitte <br />
<br />
// Wifi<br />
// Syslog<br />
// Ota<br />
// MQTT<br />
<br />
müssen mit der eigenen "'''Ip-Adresse-Server'''", "'''SSID'''" und "'''password'''" angepasst werden, das erleichtert den ersten Connect mit dem Modul. Seit der Version 2.1.2 können die WIFI Einstellungen 2-fach angegeben werden, somit wechselt das Device automatisch auf den 2. Wifi Hotspot wenn der erste nicht erreicht wird.<br />
<br />
#define STA_SSID "SSID" // Wifi SSID<br />
#define STA_PASS "password" // Wifi password<br />
#define WIFI_HOSTNAME "%s-%04d" // Expands to <MQTT_TOPIC>-<last 4 decimal chars of MAC address><br />
#define WIFI_CONFIG_TOOL WIFI_WPSCONFIG // Default tool if wifi fails to connect (WIFI_SMARTCONFIG, WIFI_MANAGER or WIFI_WPSCONFIG)<br />
<br />
// Syslog<br />
#define SYS_LOG_HOST "Ip-Adresse-Server"<br />
#define SYS_LOG_PORT 514<br />
#define SYS_LOG_LEVEL LOG_LEVEL_NONE<br />
#define SERIAL_LOG_LEVEL LOG_LEVEL_INFO<br />
#define WEB_LOG_LEVEL LOG_LEVEL_INFO<br />
<br />
// Ota<br />
#if (ARDUINO >= 168)<br />
#define OTA_URL "http://Ip-Adresse-Server:80/api/arduino/" PROJECT ".ino.bin"<br />
#else<br />
#define OTA_URL "http://Ip-Adresse-Server:80/api/arduino/" PROJECT ".cpp.bin"<br />
#endif<br />
<br />
// MQTT<br />
#define MQTT_HOST "Ip-Adresse-Server"<br />
#define MQTT_PORT 1883<br />
<br />
<br />
'''Wichtig:''' Im Userprofile des Arduino Compilers (%userprofile%\Documents\Arduino\libraries\pubsubclient\src\PubSubClient.h) die Max Packet Size auf 512 erhöht werden!<br />
<br />
#define MQTT_MAX_PACKET_SIZE 512<br />
#define MQTT_KEEPALIVE 120<br />
Anpassung der max. Packet Size auf 512 und das Keepalive auf 120<br />
<br />
<br />
Im Anschluss wird der Sketch mit der Arduino IDE (getestet mit 1.6.12) compiliert und die Binary dann exportiert (Sketch / compilierte Binärdatei exportieren). Die erzeugte .bin Datei dann mit dem Tool "ESP8266Flasher.exe" flashen, so wie auch bei ESPEasy. Sehr gut funktioniert auch das ESPtool. Wer nicht compilieren will, kann auch im Unterverzeichnis ./api/arduino/ die fertige Binary ( sonoff.ino ) benutzen, aber dann ohne Voreinstellung der lokalen IPs.<br />
<div style="clear:both;"></div><br />
<br />
[[Datei:sonoff_sw_22.jpg|thumb|left|alt=Arends Menü]]<br />
<br />
'''Achtung:''' sollten Probleme mit dem ersten Login im Webinterface auftreten, hat der Autor vorgesorgt und mit speziellem wiederholten Tastendruck können verschiedene Modi aufgerufen werden: zB: <br />
<br />
<br />
'''3 x Taste kurz drücken''' und eine Smartconfig wird gestartet und die '''SSID''' und das '''Passwort''' kann über diese [https://play.google.com/store/apps/details?id=com.cmmakerclub.iot.esptouch Android App] eingegeben werden.<br />
<br />
<br />
'''4 x Taste kurz drücken''' und man bringt den Device in den '''Access Point Mode''' mit der IP-Adresse '''192.168.4.1'''.<br />
<br />
<br />
Bis zu 7 verschiedene Modi sind möglich, mehr dazu in Arends Wiki.<br />
<br />
[https://github.com/arendst/Sonoff-Tasmota/wiki/Button-usage Link zum Wiki Arends, Button]<br />
<div style="clear:both;"></div><br />
<br />
===MQTT testen===<br />
[[Datei:sonoff_sw_20.jpg|thumb|left|alt=Arends Menü]]<br />
<br />
<br />
Nach erfolgtem Flash des Moduls kann das Webinterface des Moduls zum ersten Mal aufgerufen werden (im Router nach der IP des Moduls suchen).<br />
<br />
Es bieten sich hier mehrere Möglichkeiten die die weitere Einrichtung des Moduls unterstützen. Einfach die Menüpunkte durchprobieren, sie erklären sich von selbst. Für erste Tests empfiehlt sich die lokale Konsole um die Ereignisse aus Sicht des Moduls mit verfolgen zu können. Alles was hier gesendet wird, sollte ebenfalls am Server mitgeloggt werden können. Wenn bis hierher alles funktioniert, kann dann mir der Konfiguration in FHEM beginnen.<br />
<br />
Der Name des Moduls kann unter "Configuration" -> "Configure MQTT" -> "Topic (sonoff)" nachgeschaut und geändert werden. In FHEM wird beim definieren des Moduls dieser Name in den subscribeReadings bzw. publishSets eingegeben um die Verbindung zum Modul herzustellen.<br />
<div style="clear:both;"></div><br />
<br />
Am Server jetzt eine Konsole öffnen und folgende Topic (alle) einstellen.<br />
<br />
mosquitto_sub -d -v -t \# <br />
Mit dieser Einstellung werden alle Topics geloggt! <br />
<br />
<nowiki>pi@raspberry ~ $ mosquitto_sub -d -v -t \#<br />
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoff_dht/DHT/TEMPERATURE', ... (6 bytes))<br />
tele/sonoff_dht/DHT/TEMPERATURE 21.8 C<br />
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoff_dht/DHT/HUMIDITY', ... (6 bytes))<br />
tele/sonoff_dht/DHT/HUMIDITY 41.7 %<br />
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoff_dht/TIME', ... (19 bytes))<br />
tele/sonoff_dht/TIME 2017-02-22T16:05:43<br />
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoffpow3/STATE', ... (104 bytes))<br />
tele/sonoffpow3/STATE {"Time":"2017-02-22T16:05:44", "Uptime":100, "LIGHT":"ON", "Wifi":{"AP":2, "SSID":"Pergola", "RSSI":96}}<br />
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoffpow3/ENERGY', ... (134 bytes))<br />
tele/sonoffpow3/ENERGY {"Time":"2017-02-22T16:05:44", "Yesterday":0.083, "Today":0.055, "Period":0, "Power":0, "Factor":0.00, "Voltage":229, "Current":0.000}<br />
Received PUBLISH (d0, q0, r0, m0, 'stat/TestSwitch/RESULT', ... (14 bytes))<br />
stat/TestSwitch/RESULT {"POWER":"ON"}<br />
Received PUBLISH (d0, q0, r0, m0, 'stat/TestSwitch/POWER', ... (2 bytes))<br />
stat/TestSwitch/POWER ON<br />
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoffpow3/STATE', ... (104 bytes))<br />
tele/sonoffpow3/STATE {"Time":"2017-02-22T16:07:14", "Uptime":100, "LIGHT":"ON", "Wifi":{"AP":2, "SSID":"Pergola", "RSSI":96}}<br />
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoffpow3/ENERGY', ... (134 bytes))<br />
tele/sonoffpow3/ENERGY {"Time":"2017-02-22T16:07:14", "Yesterday":0.083, "Today":0.055, "Period":0, "Power":3, "Factor":0.20, "Voltage":227, "Current":0.072}<br />
Received PUBLISH (d0, q0, r0, m0, 'stat/TestSwitch/RESULT', ... (15 bytes))<br />
stat/TestSwitch/RESULT {"POWER":"OFF"}<br />
Received PUBLISH (d0, q0, r0, m0, 'stat/TestSwitch/POWER', ... (3 bytes))<br />
stat/TestSwitch/POWER OFF</nowiki><br />
<br />
<br />
Interessant sind für uns nun diese Einträge "stat/TestSwitch/POWER ON" , dazu am Taster des Sonoff manuell umschalten. Dies entspricht genau der Syntax wie sie im Anschluss in FHEM dann zu verwenden ist.<br />
<br />
Mit diesen Einstellungen können dann entweder nach Telemetriedaten oder nach Statusmeldungen gefiltert werden. Dies ist jedoch nur notwendig wenn bereits andere MQTT Devices am Broker hängen und es sonst zu unübersichtlich wird.<br />
mosquitto_sub -h localhost -t tele/sonoff/# = Telemetriedaten<br />
mosquitto_sub -h localhost -t stat/sonoff/# = Statusmeldungen<br />
<div style="clear:both;"></div><br />
<br />
[[Datei:sonoff_sw_21.jpg|thumb|left|alt=Arends Log]]<br />
Sehr nützlich das lokale Log zur Fehlersuche und Inbetriebnahme.<br />
<br />
<div style="clear:both;"></div><br />
<br />
===Anbindung FHEM===<br />
[[Datei:sonoff_sw_24.jpg|thumb|left|alt=FHEM sonoff Schalter]]<br />
Dieser einfache Schalter kommuniziert bidirektional mit dem Sonoff Device.<br />
<div style="clear:both;"></div><br />
<br />
[[Datei:sonoff_sw_25.jpg|thumb|left|alt=FHEM sonoff Schalter]]<br />
Die Readings in diesem verwendeten Beispiel zeigen sich wie in FHEM gewohnt.<br />
<div style="clear:both;"></div><br />
<br />
Die Einrichtung in FHEM wird von den Modulen 00_MQTT.pm, 10_MQTT_BRIDGE und 10_MQTT_DEVICE.pm unterstützt.<br />
Ebenso wird das Modul 98_expandJSON.pm benötigt um den {{Link2Forum|Topic=66761|LinkText=JSON String zu filtern}}.<br />
<br />
Alternativ kann eine Einbindung über die [[MQTT#FHEM als MQTT-Server|MQTT2-Modulfamilie]] erfolgen. In diesem Fall benötigt man keinen eigenen Broker und FHEM stellt die Verbindung selbständig her. Mehr Informationen findet man auf der Seite [[MQTT2-Module - Praxisbeispiele]]. Hier wird jetzt die frühere Einbindung via [[MQTT (Modul)|MQTT]] vorgestellt.<br />
<br />
* siehe: {{Link2Forum|Topic=27532|LinkText="neues Modul MQTT - Bridge zwischen mqtt und fhem"}}<br />
<br />
### 1. Broker anlegen ###<br />
define myBroker MQTT 10.0.0.5:1883<br />
<br />
### 2. FHEM Device mit MQTT verbinden ###<br />
define Sonoff_Switch MQTT_DEVICE<br />
attr Sonoff_Switch IODev myBroker<br />
attr Sonoff_Switch devStateIcon ON:rc_GREEN:OFF OFF:rc_RED:ON<br />
attr Sonoff_Switch icon hue_filled_br30<br />
attr Sonoff_Switch publishSet ON OFF cmnd/TestSwitch/POWER1<br />
attr Sonoff_Switch room MQTT<br />
attr Sonoff_Switch subscribeReading_Licht stat/Sonoff_Switch/POWER1<br />
attr Sonoff_Switch subscribeReading_Sensor tele/Sonoff_Switch/SENSOR<br />
attr Sonoff_Switch subscribeReading_Status stat/Sonoff_Switch/STATUS<br />
attr Sonoff_Switch webCmd ON:OFF<br />
Der hier dargestellte Beispielcode realisiert die Kommunikation zwischen FHEM und dem Sonoff Modul via MQTT Broker. Zu beachten ist hier, dass '''subscribeReading_Licht''' und '''subscribeReading_state''' unterschiedliche Syntax des Topic Strings haben!<br />
<div style="clear:both;"></div><br />
<br />
==ESPEasy==<br />
ESPEasy ist neben TASMOTA eine der beiden Firmwares, mit denen Sonoff Gerät gut in FHEM integriert werden können. Während TASMOTA stärker Wert auf Weboberflächen und gute Handhabbarkeit legt, liegt der Schwerpunkt bei ESPEasy eher auf einer weiten Einbindung möglicher Sensoren. Beide Firmwares werden stetig ausgebaut und es ist nicht einfach, hier einen klaren Vorzug zu geben. TASMOTA scheint unter FHEM-Nutzern etwas verbreiterter zu sein. <br />
<br />
===ESPEasy flashen===<br />
[[Datei:sonoff_sw_6.jpg|thumb|left|alt=sonoff mit angestecktem FDTI Adapter]]<br />
Die Spannungsversorgung des Sonoff Moduls wird hier vom FTDI Konverter mit 3.3V über die Verbindungskabel zum Pfostenstecker durchgeführt. Siehe obigen Hinweis: [[Sonoff#internal|Vorbereitungen zum Flashen]] Anmerkung: In diesem Bild wurde die Stromversorgung durch den einfachen FTDI-Chip vorgenommen. Sollte dies zu unverständlichen Problemen führen, muss man die Spannungsversorgung prüfen (siehe [https://wiki.fhem.de/wiki/Sonoff#Stromversorgung oben]).<br />
<br />
Der FTDI Adapter wird dann mit der USB Schnittstelle mit dem Computer verbunden.<br />
<br />
Zum Compilieren wird in der Arduino Umgebung auch die Arduino Json Library 5.6.4+ benötigt. Eine genaue Anleitung kann {{Link2Forum|Topic=55728|Message=473220|LinkText=hier}} nachgelesen werden. Es sollte stets die aktuelle Version der Arduino Umgebung verwendet werden, bzw. die Librarys auf Aktuellen Stand gehalten werden. <br />
<div style="clear:both;"></div><br />
<br />
===mit Arduino compilieren===<br />
[[Datei:sonoff_sw_10.jpg|thumb|left|alt=Einstellung Arduino IDE]]<br />
Wer selber mit der Arduino IDE compilieren will, bitte folgende Einstellungen beachten. Die Sketche befinden sich [https://github.com/arendst/Sonoff-MQTT-OTA-Arduino hier]. Die anschließenden Arbeiten sind dann gleich wie bei Abschnitt '''fertige Binary'''.<br />
<br />
Unbedingt die neueste [https://github.com/bblanchon/ArduinoJson Arduino Json Library] benutzen (siehe oben). Es gibt zwar keine Compiler Fehler, aber es kommt anschließend zu Fehlfunktionen in der ESP Bridge! Die Installation der entsprechenden Arduino-Bibliotheken kann man [https://arduino-hannover.de/2015/04/08/arduino-ide-mit-dem-esp8266/ hier] nachlesen. <br />
<br />
Bitte beachten: einige neue Slampher-Module haben den ESP8285 verbaut - demzufolge muss dann dieser Chip ausgewählt werden.<br />
<br />
<div style="clear:both;"></div><br />
Generic ESP8266 Module<br />
Flash Mode: QIO<br />
Flash Frequency: 40 MHz<br />
CPU Frequency: 80 MHz<br />
Flash Size: 1M (64K SPIFFS)<br />
Debug Port: disabled<br />
Debug Level: none<br />
Reset Mode: ck<br />
Upload Speed: 115200<br />
<div style="clear:both;"></div><br />
<br />
===fertige Binary flashen===<br />
[[Datei:sonoff_sw_7.jpg|thumb|left|alt=NodeMCU Firmware Flasher]]<br />
Es empfiehlt sich eine fertige Binary von ESPEasy aufzuspielen. In diesem Wiki wurde R140 verwendet.<br />
<br />
Siehe dazu auch den [http://www.esp8266.nu/index.php/Main_Page Link von ESPEasy] und das [https://learn.adafruit.com/building-and-running-micropython-on-the-esp8266/flash-firmware Handbuch] für den Flasher.<br />
<br />
In manchen Versionen von ESPEasy (zB.R120) ist auch ein Flasher beigelegt, welcher zwar keine grafische Oberfläche hat aber hervorragend funktioniert. Wenn andere versagen, geht es mit diesem Flasher immer noch, einfach probieren!<br />
<br />
<div style="clear:both;"></div><br />
Netzspannung darf 'NICHT' angeschlossen sein!!!<br />
Taster am Sonoff gedrückt halten<br />
FTDI Adapter verbinden<br />
Taster am Sonoff los lassen<br />
Sketch übertragen<br />
Sonoff vom FTDI trennen<br />
<div style="clear:both;"></div><br />
Wenn einmal die Firmware auf das Sonoff Modul geflasht worden ist, kann in Zukunft ESPEasy direkt unter Tools via HTTP dies durchführen. Es muss dazu kein FTDI Konverter mehr verwendet werden.<br />
<br />
===ESPEasy einstellen===<br />
[[Datei:sonoff_sw_11.jpg|thumb|left|alt=ESPEasy Devices]]<br />
Wenn das Modul fertig geflasht ist und die Verbindung zum Modul hergestellt ist, können die Einstellungen in ESPEasy durchgeführt werden.<br />
Dazu am Webinterface anmelden und zunächst die zwei Devices definieren.<br />
<br />
Der Hersteller hat für das '''Relaise GPIO 12''' und für die '''grüne Led GPIO 13''' vorgesehen. Der '''Taster ist an GPIO 0''' angeschlossen.<br />
<div style="clear:both;"></div><br />
<br />
===Device Schalter===<br />
[[Datei:sonoff_sw_12.jpg|thumb|left|alt=Device Relais]]<br />
Bei den Devices sollten die hier dargestellte Einstellungen beachtet werden. Der Switch (PUMP) sollte auf Input gestellt werden, sodass die anschließenden und benötigten Rules aktiviert werden können.<br />
<br />
Da beide Devicenamen gleich benannt wurden (PUMP) wird in FHEM nur ein Device angelegt! Die dazugehörenden Valuenames sind unterschiedlich (Relay, Key).<br />
<br />
<div style="clear:both;"></div><br />
<br />
===Device Taster===<br />
[[Datei:sonoff_sw_13.jpg|thumb|left|alt=Device Key]]<br />
Der Taste muss natürlich nur konfiguriert werden, wenn auch händisch am Modul geschaltet werden soll. Wird dies nicht benötigt, können auch die Rules geändert bzw. angepasst werden. Doch alleine zu Testzwecken ist es eine nützliche Sache.<br />
<div style="clear:both;"></div><br />
<br />
===Rules===<br />
[[Datei:sonoff_sw_14.jpg|thumb|left|alt=Rules]]<br />
Damit der Sonoff unabhängig von FHEM schaltet, kann festgelegt werden, wie er sich intern verhält. Ein solches Gerät wird zB von CreationX angeboten: Dort wird der Sonoff zwischen die Zuleitung zur Lampe gelegt. Liegt in der Zuleitung Spannung an (weil jemand einen klassischen Lichtschalter gedrückt hat), signalisiert ein Spannungswandler ein Signal. Dieses Signal wiederum wird genutzt, um GPIO0 auf LOW (GND) oder HIGH zu legen. <br />
<br />
Intern regel nun eine rule, dass bei einem solchen Signal das Sonoff-Relais schaltet bzw freigegeben wird. Wenn man nun die Lampe an das Sonoff-Relais schaltet, verhält sich der Lichtschalter so wie ohne Sonoff: Wird geschaltet, geht das Licht an. Der Vorteil des Sonoff besteht darin, dass neben den klassischen Lichtschaltern nun auch via FHEM geschaltet werden kann. <br />
<br />
Die rule ist dabei wie folgt zu definieren. Dabei wird angenommen, dass an GPIO0 das Signal anliegen wird. Dazu muss ein ''device'' in ESPEasy definiert werden, dass dieses Signal empfängt. Das device ist dabei ein Switch (nach dem Schaltvorgang bleibt der Schaltzustand erhalten) oder ein Taster (nach dem Schaltvorgang kehrt man in den ursprünglichen Schaltzustand zurück). Das device in ESPEasy kennt drei Bezeichnungen: ''device'' (das ist der Typ oder die Art und Weise des devices, es sind beispielsweise auch Sensoren als devices möglich), ''name'' (damit wird das device angesprochen) sowie ''value'' (das ist dann der Schaltzustand). Will man auf den Schaltzustand zugreifen, erfolgt dies mit der Syntax name#value. Weitere Details zu den Programmierung von rules findet man auf der Webseite von letscontrolit: [[https://www.letscontrolit.com/wiki/index.php/Tutorial_Rules]] <br />
<br />
Da das Sonoff Modul auch einen eingebauten Taster hat und somit auch lokal bedient werden kann, sollte man zunächst unter '''Tools / Advanced das Häkchen Rules''' aktivieren, erst dann wird der Tab sichtbar und es können Rules erstellt werden.<br />
<div style="clear:both;"></div><br />
<br />
on PUMP#Key do<br />
if [PUMP#Relay]=1<br />
gpio,12,0<br />
else<br />
gpio,12,1<br />
endif<br />
endon<br />
on PUMP#Relay do<br />
if [PUMP#Relay]=1 <br />
gpio,13,0<br />
else<br />
gpio,13,1<br />
endif<br />
endon<br />
Diese Rules ermöglichen, dass bei lokaler Bedienung durch den Taster auch die '''Led''' richtig geschaltet wird.<br />
Mit 'on PUMP#Key do' wird geprüft ob die Taste gedrückt ist und schaltet dann entsprechend die Led. Mit den Rules können auch Timer oder sonstige Spielereien realisiert werden. Siehe dazu das [http://www.esp8266.nu/index.php/Tutorial_Rules Tutorial] von ESPeasy.<br />
<div style="clear:both;"></div><br />
<br />
===Anbindung FHEM===<br />
[[Datei:sonoff_sw_9.jpg|thumb|left|alt=FHEM Konfiguration]]<br />
Dies ist eine einfache Darstellung wie FHEM automatisch den Device erstellt.<br />
<br />
Damit FHEM mit ESPEasy und dem Sonoff Modul kommunizieren kann, muss in der fhem.cfg vorerst nur die EspBridge mit dem hier dargestellten Eintrag aktiviert werden.<br />
<div style="clear:both;"></div><br />
define espBridge ESPEasy bridge 8383<br />
Dies ist eigentlich die einzige Zeile die in fhem.cfg angelegt werden muss. Die restliche Konfiguration wird von FHEM automatisch generiert. <br />
<br />
<br />
##########################################<br />
### ESPEASY ####<br />
##########################################<br />
<br />
define ESPEasy_sonoff_1_PUMP ESPEasy 10.0.0.37 80 espBridge sonoff_1_PUMP<br />
attr ESPEasy_sonoff_1_PUMP IODev espBridge<br />
attr ESPEasy_sonoff_1_PUMP devStateIcon on:rc_GREEN:off off:rc_RED:on absent:rc_BLUE:off gpio:rc_YELLOW:off<br />
attr ESPEasy_sonoff_1_PUMP eventMap /gpio 12 on:on/gpio 12 off:off/gpio 12 gpio:off/gpio 12 output:off/<br />
attr ESPEasy_sonoff_1_PUMP group ESPEasy Device<br />
attr ESPEasy_sonoff_1_PUMP icon hue_filled_outlet<br />
attr ESPEasy_sonoff_1_PUMP room ESPEasy<br />
attr ESPEasy_sonoff_1_PUMP setState 0<br />
attr ESPEasy_sonoff_1_PUMP stateFormat {ReadingsVal($name,"presence","") eq "absent" ? "absent" : ReadingsVal($name,"Relay","")}<br />
attr ESPEasy_sonoff_1_PUMP webCmd :<br />
<br />
hier ein Beispiel wie es auch manuell leicht modifiziert werden kann.<br />
<br />
<br />
[[Datei:sonoff_sw_8.jpg|thumb|left|alt=Sonoff Readings]]<br />
<br />
Die Readings werden durch die Bridge (Modul ESPEasy) automatisch angelegt.<br />
<br />
Es besteht hier noch genug Spielraum um z.B. auch noch Temperatursensoren an das Modul anzuschließen und ebenfalls in FHEM darzustellen.<br />
<div style="clear:both;"></div><br />
<br />
=Beispiele=<br />
==Einrichtung Sonoff POW==<br />
[[Datei:sonoff_sw_31.jpg|thumb|left|alt=Sonoff POW]]<br />
'''Bei einer Charge des Sonoff POW gibt es Kontaktprobleme beim Sicherungshalter. ITAED hat deshalb eine Rückrufaktion gestartet: [https://www.itead.cc/blog/sonoff-th16-and-pow-recall-notice Link zur Rückrufaktion]. Bitte unbedingt die Kontaktierung des Sicherungshalter überprüfen bzw. neuen Sicherungshalter einsetzen!'''<br />
<br />
Das Modul kommt in gewohnter ITAED Qualität, eine derart kostengünstige Energiemessung wird bei Smart Home Anwendern gerne eingesetzt. Die Originalsoftware habe ich nicht einmal getestet, da damit eine Anbindung an FHEM leider nicht möglich ist (wer will schon die Steuerbefehle seiner Schalter an eine nicht dokumentierte chinesische Cloud senden).<br />
<br />
<div style="clear:both;"></div><br />
[[Datei:sonoff_sw_33.jpg|thumb|left|alt=Sonoff POW]]<br />
Bitte auf keinen Fall das Modul während der Arbeiten an die Netzspannung anschließen. Zum Flashen genügt (und nur diese) die Versorgungsspannung des USB-TTL Konverters. Wie auf dem Foto gut erkennbar, wurde dieses Modul ohne Einlöten einer Pfostensteckerleiste geflasht. Die Steckverbindung wird einfach in die Lötaugen gesteckt und mit einem Gummiring fixiert, da ja spätere Flashvorgänge im Webif des Models funktionieren und so die Arbeit eingespart werden kann. Es steht jedoch nichts im Wege die Pfostensteckerleiste einzulöten.<br />
<div style="clear:both;"></div><br />
Die Anschlüsse am Modul sind wie folgt belegt.<br />
o GND<br />
o TxD<br />
o RxD<br />
o VDD<br />
<br />
Für den Flashvorgang gelten die selben Regeln wie schon beim Sonoff Switch oben erwähnt (3,3V!).<br />
<div style="clear:both;"></div><br />
<br />
<br />
===Software===<br />
[[Datei:sonoff_sw_35.jpg|thumb|left|alt=Sonoff POW FHEM]]<br />
Als Software steht im Augenblick nur der Sketch von Arends zur Verfügung, liefert aber alles was das Herz begehrt und ist ist einfach zu handhaben. Hier eine eine einfache Darstellung mit der aktuellen Leistung und dem Tagesverbrauch. Zusätzlich besteht auch noch die Möglichkeit den angeschlossenen Verbraucher Ein- oder Auszuschalten. <br />
<div style="clear:both;"></div><br />
[[Datei:sonoff_pow_02.jpg|thumb|left|alt=Sonoff POW Webif]]<br />
Seit Version 2.0.19a ist auch die Leistungsanzeige im WEBIF wie im Bild links integriert. Auch der Energieverbrauch des Vortages wird mit angezeigt. Alle hier angezeigten Daten werden auch zyklisch im MQTT String an FHEM übergeben.<br />
<br />
Zusätzlich kann im Sketch auch das Feature "'''Power_Limit'''" aktiviert werden. Mit dem Power_Limit wird eine zusätzliche Nachricht erzeugt, wenn ein bestimmter einstellbarer Grenzwert über- oder unterschritten wird. <br />
<br />
Es lassen sich dadurch Meldungen wie "Waschmaschine fertig" oder ähnliches ohne weitere Schwellwert Überwachungen in FHEM ableiten. Die Meldungen kommen in MQTT mit "'''POWER_LOW ON'''" bzw. "'''POWER_LOW OFF'''".<br />
<div style="clear:both;"></div><br />
<br />
Bei erstmaligen Start des Moduls muss der Typ des Modules von "SONOFF" auf "'''SONOFF_Pow'''" geändert werden, damit die Software weiß mit welchem Modul es zu tun hat und kann dann die entsprechenden Berechnungen durchführen. Die Leistungsdaten kommen ja in Form einer Frequenz aus dem Baustein und müssen im Sketch (xsns_hlw8102.ino) umgerechnet werden.<br />
<br />
<div style="clear:both;"></div><br />
[[Datei:sonoff_sw_36.jpg|thumb|left|alt=Sonoff POW Attribute]]<br />
Dieses Bild zeigt die Attribute die vom Modul via MQTT an FHEM geliefert werden.<br />
<div style="clear:both;"></div><br />
aktuell gelieferter JSON String vom Sketch der alle Messdaten beinhaltet.<br />
{"Time":"2017-02-22T16:38:47", "Yesterday":"2.286", "Today":"1.593", "Period":9, "Power":231, "Factor":"1.00", "Voltage":231, "Current":"0.866"}<br />
und hier das zugehörige Reading.<br />
tele/sonoffpow/ENERGY <br />
<br />
<br />
Hier ein Mitschnitt des Datenverkehrs zum Broker zwecks Kontrolle der korrekten Funktion der Module und der Software.<br />
<nowiki>Received PUBLISH (d0, q0, r0, m0, 'tele/sonoffpow/STATE', ... (103 bytes))<br />
tele/sonoffpow/STATE {"Time":"2017-02-22T16:39:15", "Uptime":79, "LIGHT":"OFF", "Wifi":{"AP":2, "SSID":"Liwest", "RSSI":54}}<br />
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoffpow/ENERGY', ... (140 bytes))<br />
tele/sonoffpow/ENERGY {"Time":"2017-02-22T16:39:15", "Yesterday":"1.391", "Today":"1.191", "Period":0, "Power":0, "Factor":"0.00", "Voltage":0, "Current":"0.000"}<br />
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoff_wall1/STATE', ... (105 bytes))<br />
tele/sonoff_wall1/STATE {"Time":"2017-02-22T16:39:15", "Uptime":96, "POWER":"OFF", "Wifi":{"AP":2, "SSID":"Pergola", "RSSI":100}}<br />
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoffpow3/STATE', ... (104 bytes))<br />
tele/sonoffpow3/STATE {"Time":"2017-02-22T16:39:20", "Uptime":100, "LIGHT":"ON", "Wifi":{"AP":2, "SSID":"Pergola", "RSSI":96}}<br />
Received PUBLISH (d0, q0, r0, m0, 'tele/sonoffpow3/ENERGY', ... (134 bytes))<br />
tele/sonoffpow3/ENERGY {"Time":"2017-02-22T16:39:20", "Yesterday":0.083, "Today":0.057, "Period":0, "Power":0, "Factor":0.00, "Voltage":230, "Current":0.000}</nowiki><br />
<br />
<br />
<br />
Die Einstellungen können mit folgender Syntax angefordert werden (zwei Terminalfenster öffnen, eines zum protokollieren und eines zum senden der Befehle).<br />
mosquitto_sub -d -v -t \# MQTT Datenverkehr protokolieren<br />
mosquitto_pub -q 2 -t cmnd/sonoffpow/status/set -m "8" = SonoffPOW Status jetzt auslesen<br />
mosquitto_pub -q 2 -t cmnd/sonoffpow/TelePeriod/set -m "60" = Timer setzen, alle 60 Sekunden Daten senden <br />
Die Kommandos können direkt am Broker (Terminalfenster Putty etc.) abgesetzt werden.<br />
<br />
<div style="clear:both;"></div><br />
<br />
=== Kalibrieren und Genauigkeit ===<br />
Ab Version 2.0.11 kann nun auch der POW kalibriert werden.<br />
Dazu kann man 2 Konsolenfenster öffnen, im ersten aktiviert man das Protokoll für den Datenverkehr<br />
mosquitto_sub -d -v -t \# MQTT Datenverkehr protokollieren<br />
<br />
Dann kann mit folgenden Befehlen die HLW Referenz Pulsfrequenz gesetzt werden.<br />
mosquitto_pub -q 2 -t cmnd/sonoffpow/HLWUCAL/set -m "2100" default = 1950<br />
mosquitto_pub -q 2 -t cmnd/sonoffpow/HLWICAL/set -m "2450" default = 3500<br />
mosquitto_pub -q 2 -t cmnd/sonoffpow/HLWPCAL/set -m "13500" default = 12345 <br />
Entweder man hat eine definierte Last zur Verfügung oder besser man misst mit einem Leistungsmesser nach. Die Spannung kann man mit einem Multimeter nachmessen (sollte 230 V sein) und der Strom wird errechnet (bei 100 Watt I = P / U ) = 100/230 = 0,4347.<br />
Die Referenzwerte solange geringfügig ändern bis die Ausgabe passt. Für die Ausgabe wird einfach eine Statusabfrage durchgeführt.<br />
<br />
mosquitto_pub -q 2 -t cmnd/sonoffpow/status/set -m "8"<br />
Befehl für die Statusabfrage<br />
<br />
cmnd/sonoffpow/status/set 8<br />
Received PUBLISH (d0, q0, r0, m0, 'stat/sonoffpow/STATUS', ... (103 bytes))<br />
stat/sonoffpow/STATUS PWR: Voltage 225 V, Current 0.427 A, Current Power 98 W, Total Power Today 0.080 kWh, Power Factor 1.00<br />
Ergebnis der Statusabfrage mit Spannung, Strom und Leistung.<br />
<br />
<div style="clear:both;"></div><br />
<br />
Bei sehr kleinen Watt Zahlen (unterhalb von 10 W) ist der POW etwas ungenau. Es empfiehlt sich hier, nicht die Größe Power zu verwenden, sondern die Veränderung der Größe Total zu betrachten. Wird diese über mehrere Perioden gemittelt, so kann auch für einstellige Watt Werte ein relativ genaues Ergebnis erzielt werden. Um dies zu erreichen, sind mehrere Schritte nötig.<br />
<br />
* Zuerst muss die Übertragungsfrequenz des Sonoff eingestellt werden. Hier ist Probieren angesagt, in einem Beispiel wurde eine Frequenz von 90s pro Datensatz verwendet. Hierzu ruft man beispielsweise die Seite<br />
http://<ip-Adresse-des-Sonoff>/cm?cmnd=Teleperiod%2090<br />
auf. Die nach dem Leerzeichen %20 stehende 90 steht für 90s. Ein Aufruf ohne Zeit liefert die gegenwärtige Telemetry-Periode zurück.<br />
<br />
* Danach ist die Genauigkeit der Leistungsmessung am Sonoff auf die höchstmögliche Größe einzustellen (siehe auch [https://github.com/arendst/Sonoff-Tasmota/wiki/Commands den Wiki von TASMOTA]). Dies geschieht durch <br />
http://<ip-Adresse-des-Sonoff>/cm?cmnd=WattRes%201<br />
sowie <br />
http://<ip-Adresse-des-Sonoff>/cm?cmnd=EnergyRes%205 <br />
<br />
* Im nächsten Schritt muss ein Reading für die Veränderung des Total-Wertes definiert werden. Die geschieht beispielsweise durch<br />
attr <device_name_des_Sonoff_pow> userReadings myPower:Time.* difference { 1000*ReadingsVal("Sonoff_pow1","Total",0);;;;}, myPower.av:Time.* {movingAverage("Sonoff_pow1","myPower",360)}<br />
<br />
* Hierbei wird gleichzeitig neben dem Reading myPower auch eine Reading myPower.av für den gleitenden Mittelwert definiert. Der Differenzwert wird mit 1000 multipliziert, damit die Anzeige in Wh und nicht kWh erfolgt. Der Mittelwert wird dabei über 360s gestreckt. Sowohl die 90s oben als auch die 360s müssen durch probieren der konkreten Situation angepasst werden. Die Funktion movingAverage selbst muss in 99_myUtils.pm definiert werden, siehe dazu [https://wiki.fhem.de/wiki/Gleitende_Mittelwerte_berechnen_und_loggen diesen Wikieintrag]. Weiterführende Hinweise in diesem {{Link2Forum|Topic=100758|Message=75443|LinkText=Forenthema}}. <br />
<br />
===FHEM Anbindung===<br />
Ein Beispiel einer einfachen Anbindung via JSON an FHEM. MQTT von Arends ist insofern notwendig, da in der Software ESPEasy und der Bridge noch keine Implementierung der Frequenzumrechnung enthalten ist.<br />
<br />
define Sonoff_Pow MQTT_DEVICE<br />
attr Sonoff_Pow IODev myBroker<br />
attr Sonoff_Pow icon measure_power<br />
attr Sonoff_Pow publishSet ON OFF cmnd/sonoffpow/POWER<br />
attr Sonoff_Pow stateFormat {sprintf("aktuell: %.1f W Tag: %.2f Kw/h", ReadingsVal($name,"Power",undef), ReadingsVal($name,"Today",undef))}<br />
attr Sonoff_Pow subscribeReading_ENERGY tele/sonoffpow/ENERGY<br />
attr Sonoff_Pow subscribeReading_POWER stat/sonoffpow/POWER<br />
attr Sonoff_Pow subscribeReading_state cmnd/sonoffpow/POWER<br />
attr Sonoff_Pow webCmd ON:OFF<br />
Zusätzlich kann hier noch das Relais mit "ON" und "OFF" ein- ausgeschaltet werden.<br />
<br />
Ebenso notwendig ist das Setzen der Regexp für den JSON Konverter.<br />
define ej3 expandJSON Sonoff.*:.*:.[{].*}<br />
hier wird alles was mit dem Namen Sonoff beginnt gefiltert und automatisch alle darin enthaltenen Readings erstellt.<br />
<br />
define ej3 expandJSON Sonoff.*:ENERGY.*:.[{].*} (Power|Yesterday|Today)<br />
oder so, da werden nur die Readings Power, Yesterday und Today erstellt.<br />
Somit ist auch klar, dass in FHEM auch JSON installiert sein muss. Ebenso können die verschiedenen Regexp im [https://github.com/ddtlabs/expandJSON Wiki] nachgelesen werden.<br />
<br />
* siehe: {{Link2Forum|Topic=66761|LinkText=siehe Foren-Thema}}.<br />
<br />
'''Source Reading:'''<br />
device:reading:.{.*} <br />
.*WifiIOT.*:sensor.*:.{.*} <br />
sonoff_.*:.*:.{.*} <br />
dev.*:(sensor1|sensor2|teleme.*):.{.*} <br />
(dev.*|[Dd]evice.*):json:.{.*} <br />
(devX:jsonX:.{.*}|devY.*:jsonY:.{.*Wifi.*{.*SSID.*}.*}) <br />
<br />
'''Target Reading:'''<br />
.*power.* <br />
(Current|Voltage|Wifi.*) <br />
<br />
'''Komplette Definition des Filters:'''<br />
define ej1 expandJSON device:sourceReading:.\{.*} targetReading <br />
define ej3 expandJSON .*\.SEN\..*:.*:.\{.*} <br />
define ej3 expandJSON sonoff_.*:sensor.*:.\{.*} (power.*|current|voltage)<br />
define ej3 expandJSON Sonoff.*:.*:.\{.*} (Power|Current|Voltage|Yesterday|Today|Total|AnalogInput0|RSSI|.*Humidity|.*Temperature|Counter1|Period)<br />
letzteres Filter definiert so ziemlich alle wichtigen Sonoff Messdaten<br />
<br />
===Netz-Anschluss===<br />
[[Datei:sonoff_sw_34.jpg|thumb|left|alt=Sonoff POW Netzanschluss]]<br />
Erst wenn alle Arbeiten an der Hard- und Software abgeschlossen sind, kann man das Modul an die Netzspannung anschließen. Wer es sich einfach machen will, nimmt eine Industriell gefertigte 230 V Verlängerung (zwischen 1,5 - 3 Meter) und schneidet sie in der Mitte durch. Nach dem ab-isolieren der flexiblen Drähte sollte diese '''mit Aderendhülsen''' versehen werden (müssen aber exakt passen, da hier kaum Platz in den Klemmen ist). <br />
Mit einem kleinen Schraubendreher kann man die Feder der Klemmen niederdrücken und das verzinnte Drahtende tief ich die Öffnung stecken. Es dürfen keine Drahtlitzen aus den Öffnungen sichtbar sein, Kurzschlussgefahr! Ebenso sollte eine Zugprobe durchgeführt werden ob die Klemme auch richtig eingerastet ist.<br />
<br />
'''ACHTUNG: diese Arbeiten müssen von einem ausgebildeten Fachpersonal (Elektriker) durchgeführt werden, Lebensgefahr!'''<br />
<div style="clear:both;"></div><br />
<br />
===ReadingsGroup mit Schaltmöglichkeit===<br />
[[Datei:sonoff_pow_03.jpg|thumb|left|alt=readingsGroup mit Schalter]]<br />
Die ReadingsGroup kann auch gleich mit einem Schalter versehen werden um den POW Ein- oder Aus schalten zu können. Dazu ist aber eine andere Einstellung im Sketch erforderlich.<br />
<div style="clear:both;"></div><br />
<br />
In der "'''user_config.h'''" muss an dieser Stelle auch die "'''PUB_PREFIX'''" auf die gleiche Topic wie "PUB_PREFIX2" eingestellt werden. Durch diese Maßnahme wird erreicht, dass sofort nach dem Knopfdruck auch der Status mit der Topic "tele" übertragen wird. Würde der weiterhin mit "stat" übertragen, kann er in der Readingsgroup nur sehr umständlich weiter behandelt werden. Dadurch wird erreicht, dass der Schalter sofort nach dem Schaltvorgang und der Rückmeldung (Status) auch seine Farbe ändert. Wird dieser Eintrag vergessen, ändert der Schalter erst nach Eintreffen der nächsten zyklischen Abfrage seinen Status/Farbe.<br />
<br />
#define SUB_PREFIX "cmnd" // Sonoff devices subscribe to:- SUB_PREFIX/MQTT_TOPIC and SUB_PREFIX/MQTT_GRPTOPIC<br />
#define PUB_PREFIX "tele" // Sonoff devices publish to:- PUB_PREFIX/MQTT_TOPIC<br />
#define PUB_PREFIX2 "tele" // Sonoff devices publish telemetry data to:- PUB_PREFIX2/MQTT_TOPIC/UPTIME, POWER/LIGHT and TIME<br />
hier die PUB_PREFIX mit der geänderten Topic "tele" anstatt "stat" <br />
<br />
<br />
<nowiki>define SonoffPows readingsGroup <%measure_power>,<aktuell>,<Tag>,<Gestern>,<Strom>,<Durchschnitt>,<max.P>,<Zyklus>,<Faktor>,<Status>,< hr > .*(Sonoff_Pow|Sonoff_Pow2|Sonoff_Pow3|Sonoff_Pow4):Power,Today,Yesterday,Current,Power_avg_day,Power_max_day,Period,Factor,LIGHT<br />
attr SonoffPows commands {'LIGHT.ON' => 'set $DEVICE OFF','LIGHT.OFF' => 'set $DEVICE ON'}<br />
attr SonoffPows mapping %ALIAS<br />
attr SonoffPows nameStyle style="color:yellow"<br />
attr SonoffPows room Energie,MQTT<br />
attr SonoffPows valueFormat {'Power' =>"%.0f W", 'Today' =>"%.2f Kw",'Yesterday' =>"%.2f Kw", 'CURRENT' =>"%.2f A",'Power_max_day' => "%.0f W",'Power_avg_day' => "%.2f W",'Power'=>"%.0f W",'Factor' => "%.2f "}<br />
attr SonoffPows valueIcon {'LIGHT.ON' => 'rc_GREEN@green', 'LIGHT.OFF' => 'rc_RED@red'}<br />
attr SonoffPows valueStyle { if($READING eq "Power" && $VALUE >= 0 && $VALUE <= 100){ 'style="color:green;;text-align:right"' }elsif( $READING eq "Power" && $VALUE > 100 && $VALUE < 200){ 'style="color:orange;;text-align:right"' }elsif( $READING eq "Power" && $VALUE >= 200){ 'style="color:red;;text-align:right"' }elsif( $READING eq "Today" && $VALUE >= 4.8){ 'style="color:red;;text-align:right"' }elsif( $READING eq "Today" && $VALUE <= 2.5){ 'style="color:green;;text-align:right"' }elsif( $READING eq "Today" && $VALUE > 2.5 && $VALUE < 4.8 ){ 'style="color:orange;;text-align:right"' }elsif( $READING eq "Yesterday" && $VALUE <= 2.5){ 'style="color:green;;text-align:right"' }elsif( $READING eq "Yesterday" && $VALUE > 2.5 && $VALUE < 4.8 ){ 'style="color:orange;;text-align:right"' }elsif( $READING eq "Yesterday" && $VALUE >= 4.8){ 'style="color:red;;text-align:right"' }elsif( $READING eq "Current" && $VALUE <= 0.45){'style="color:green;;text-align:right"'}elsif( $READING eq "Current" && $VALUE > 0.45 && $VALUE < 0.87 ){'style="color:orange;;text-align:right"' }elsif( $READING eq "Current" && $VALUE >= 0.87){ 'style="color:red;;text-align:right"' }elsif( $READING eq "Power_avg_day" && $VALUE <= 100){ 'style="color:lightgreen;;text-align:right"' }elsif( $READING eq "Power_avg_day" && $VALUE > 100 && $VALUE < 200 ){ 'style="color:orange;;text-align:right"' }elsif( $READING eq "Power_avg_day" && $VALUE >= 200){ 'style="color:red;;text-align:right"' }elsif( $READING eq "Period" && $VALUE <= 10){ 'style="color:lightgreen;;text-align:right"' }elsif( $READING eq "Period" && $VALUE > 10 && $VALUE < 15 ){ 'style="color:orange;;text-align:right"' }elsif( $READING eq "Period" && $VALUE >= 15){ 'style="color:red;;text-align:right"' }elsif( $READING eq "Power_max_day" && $VALUE <= 100){ 'style="color:lightgreen;;text-align:right"' }elsif( $READING eq "Power_max_day" && $VALUE > 100 && $VALUE < 200 ){ 'style="color:orange;;text-align:right"' }elsif( $READING eq "Power_max_day" && $VALUE >= 200){ 'style="color:red;;text-align:right"'}}</nowiki><br />
Dieses Beispiel ist für '''Tasmota mit JSON''' ausgelegt und benötigt ebenso wie oben die Erweiterung "average".<br />
<br />
define Sonoff_Pow_CURRENT_POWER average Sonoff_Pow:Power.*<br />
damit werden der Durchschnitt und min max für Tasmota mit JSON erzeugt.<br />
<div style="clear:both;"></div><br />
<br />
===FTUI===<br />
[[Datei:sonoff_pow_energy.JPG|thumb|left|alt=Tablett FTUI]]<br />
Wer möchte kann die Energieanzeigen auch mit der {{Link2Forum|Topic=34233|LinkText=Tablett UI}} für eine Tablet Ansicht gestalten. Mit dieser stehen viele Möglichkeiten zu einer attraktiven Darstellung zur Verfügung.<br />
Hier ein Beispiel welches mit den Widget "[http://www.fhemwiki.de/wiki/FHEM_Tablet_UI#Widget_THERMOSTAT thermostat]" dargestellt ist.<br />
<div style="clear:both;"></div><br />
<br />
==Sonoff Slampher==<br />
Anmerkung: Seit April 2017 ist eine neue Version des Slampher im Umlauf (v 2.0 2017-04-14, deutlich auf der Platine zu erkennen), die etwas anders geflasht werden muss. Siehe hierzu [http://homeautomation.proboards.com/thread/259/program-slampher-socket-esp8285-esp8266 diesen Blogeintrag.] Zum einen ist der ESP8285 statt des ESP8266 verbaut; zum anderen muss unten nicht der rechte Pin des R20, sondern der linke Pin des R9 mit GND verbunden werden. <br />
<br />
[[Datei:sonoff_sl_53.jpg|thumb|left|alt=Sonoff SLAMPHER]]<br />
<br />
Dieses Modul ist eine Besonderheit was das Flashen betrifft, denn mit Hilfe des Tasters kann der ESP8266 NICHT in den Flashmode gebracht werden. Der Taster ist intern anderweitig verdrahtet und somit für diesen Zweck nicht zu gebrauchen. Wie hier links im Bild zu sehen ist, muss der rechte Pin des R20 (oben im Bild) während des Anschlusses der Spannung Vcc auf Masse gelegt werden. Eine Möglichkeit ist, ein Stückchen Draht anzulöten und diesen dann beim Einstecken auf den Masse-Pin des USB-Konverters zu legen.<br />
<br />
Pinbelegung des Steckers von oben nach unten:<br />
o - GND<br />
o - TxD<br />
o - RxD<br />
'''o''' - Vdd<br />
<br />
<div style="clear:both;"></div><br />
<br />
[[Datei:sonoff_sl_51.jpg|thumb|left|alt=Sonoff SLAMPHER R20]]<br />
{{Randnotiz|RNTyp=[g|Info]|RNText=Hier ist genau ersichtlich, wo der R20 auf der Platine platziert ist. }}<br />
Hier noch einmal schön zu sehen wo der R20 (der ist nicht eingelötet sondern leer) exakt auf der Platine liegt, gemeint ist der rechte Pin. Hier kann auch leicht gelötet werden, da keine empfindlichen Bauteile in der Nähe sind und auch genug Platz vorhanden ist. (Achtung: Beim Slampher v2.0 muss der linke Pin des R9 auf Masse gelegt werden, siehe oben!).<br />
<br />
<div style="clear:both;"></div><br />
[[Datei:sonoff_sl_50.jpg|thumb|left|alt=Sonoff SLAMPHER R20]]<br />
{{Randnotiz|RNTyp=[g|Info]|RNText=Hier ist genau ersichtlich, wo der Draht am R20 aufgelötet wurde }}<br />
Hier ist ein kleines Stück Schaltdraht auf den Pin bereits aufgelötet und bereit zum flashen!<br />
<br />
In diesem Beispiel wurde keine Pfostensteckerleiste auf die Platine aufgelötet, sondern nur durchgesteckt und mit einem Gummiring zum Relais fixiert, das erspart den Lötvorgang, weil in Zukunft dann ohnehin OTA geflasht werden kann.<br />
<br />
Also Pin20 auf Masse legen und USB-Konverter an den PC einstecken, dann den Draht von der Masse entfernen. Der ESP8266 sollte jetzt im Flashmodus bereit stehen und kann wie bereits oben beschrieben geflasht werden.<br />
<br />
<div style="clear:both;"></div><br />
<br />
===Sonoff Slampher Software===<br />
[[Datei:sonoff_sl_54.jpg|thumb|left|alt=Sonoff SLAMPHER FHEM]]<br />
<br />
Als Software wird Arends Sketch installiert (Kommunikation über MQTT), da zum derzeitigen Zeitpunkt ESPEasy das Modul noch nicht integriert hat und somit auch nicht ansteuern kann.<br />
<div style="clear:both;"></div><br />
<br />
define Sonoff_SL MQTT_DEVICE<br />
attr Sonoff_SL IODev myBroker<br />
attr Sonoff_SL devStateIcon ON:rc_GREEN:OFF OFF:rc_RED:ON<br />
attr Sonoff_SL icon hue_filled_br30<br />
attr Sonoff_SL publishSet ON OFF cmnd/sonoffsl/POWER1<br />
attr Sonoff_SL room Bewegung,_Sonoff<br />
attr Sonoff_SL stateFormat Licht<br />
attr Sonoff_SL subscribeReading_Licht tele/sonoffsl/POWER1<br />
attr Sonoff_SL subscribeReading_state cmnd/sonoffsl/POWER1<br />
attr Sonoff_SL webCmd ON:OFF<br />
<br />
Hier ein Beispiel wie in FHEM der Slampher eingebunden werden kann. In diesem Beispiel wird davon ausgegangen, dass im Modul die Topic "sonoffsl" benannt wurde. Wer einen anderen Namen haben möchte, muss dies dann auch in FHEM entsprechend anpassen.<br />
<br />
<div style="clear:both;"></div><br />
<br />
==Sonoff Th10/16 ==<br />
[[Datei:sonoff_th_01.jpg|thumb|left|alt=Sonoff TH10]]<br />
Das Modul kann durch Drücken des Tasters während dem Einstecken des USB-Konverters in den Flashmodus gebracht werden.<br />
Der Th10/16 kann mit zwei unterschiedlichen Typen von Sensoren bestückt werden, hier im Beispiel mit dem externen Temperaturfühler DS18B20.<br />
<br />
Wie im Bild klar zu sehen ist, kann das Webif auch zur Darstellung via Mobile verwendet werden. Mit "Toggle" wird Ein- oder Aus geschaltet und darunter ist die aktuelle Temperatur ersichtlich. Für diese Ansicht muss keine MQTT Verbindung eingerichtet werden, da die Kommunikation hier rein über HTTP erfolgt.<br />
<br />
Die unten dargestellten Beispiele für FHEM beziehen sich auf Arends Sketch, also über MQTT. Dieses Modul kann aber genauso leicht über ESPEasy und der ESPEasy-Bridge eingebunden werden.<br />
<br />
<div style="clear:both;"></div><br />
Pinbelegung des Steckers von oben nach unten:<br />
o - GND<br />
o - TxD<br />
o - RxD<br />
'''o''' - Vdd<br />
<br />
<div style="clear:both;"></div><br />
[[Datei:sonoff_th_02.jpg|thumb|left|alt=Sonoff TH10]]<br />
{{Randnotiz|RNTyp=[g|Info]|RNText=Einbindung in FHEM via MQTT! }}<br />
<div style="clear:both;"></div><br />
<br />
### Temperatur und Luftfeuchte vom Sonoff Switch ###<br />
define Sonoff_Temp MQTT_DEVICE<br />
attr Sonoff_Temp IODev myBroker<br />
attr Sonoff_Temp alias Pool Wasser<br />
attr Sonoff_Temp eventMap ON:on OFF:off<br />
attr Sonoff_Temp icon temperature_humidity<br />
attr Sonoff_Temp publishSet ON OFF cmnd/sonoffth/POWER1<br />
attr Sonoff_Temp room _Sonoff<br />
attr Sonoff_Temp stateFormat {sprintf("Temperatur: %.1f Grad", ReadingsVal($name,"temperature",0))}<br />
attr Sonoff_Temp subscribeReading_SENSOR tele/sonoffth/SENSOR<br />
attr Sonoff_Temp subscribeReading_state cmnd/sonoffth/POWER1<br />
Beispiel für FHEM mit Temperaturanzeige mit DS18B20<br />
<br />
define Sonoff_Switch MQTT_DEVICE<br />
attr Sonoff_Switch IODev myBroker<br />
attr Sonoff_Switch alias Pool Licht<br />
attr Sonoff_Switch devStateIcon on:rc_GREEN:off off:rc_RED:on<br />
attr Sonoff_Switch eventMap ON:on OFF:off<br />
attr Sonoff_Switch icon light_ceiling<br />
attr Sonoff_Switch publishSet ON OFF cmnd/sonoffth/POWER1<br />
attr Sonoff_Switch room _Sonoff<br />
attr Sonoff_Switch stateFormat Licht<br />
attr Sonoff_Switch subscribeReading_Licht tele/sonoffth/POWER1<br />
attr Sonoff_Switch subscribeReading_state cmnd/sonoffth/POWER1<br />
attr Sonoff_Switch webCmd ON:OFF<br />
Der Schalter nochmals separat dargestellt, je nach Geschmack.<br />
<br />
<div style="clear:both;"></div><br />
<br />
==Sonoff 4CH 4-Kanal Schaltmodul==<br />
===Besonderheiten ===<br />
[[Datei:sonoff_ch4_1.jpg|thumb|left|alt=Sonoff CH4]]<br />
{{Randnotiz|RNTyp=[g|Info]|RNText=Achtung andere Einstellungen der Arduino IDE: Select Board "Generic ESP8285 Module" (=Flash Mode "DOUT") and Flash Size "1M (64K SPIFFS)"n! }}<br />
<br />
Der Sonoff 4CH ist mit seinen 4 Kanälen ein sehr preiswertes Modul im Gehäuse und für Hutschienenmontage. Anstatt des üblichen ESP8266 besitzt dieses Modul schon den moderneren '''ESP8285'''. Es müssen daher in der Arduino IDE andere Einstellungen vorgenommen werden. Unter Board wird hier das "'''Generic 8285 Module'''" mit '''1M und 64K Spiffs''' angewählt. Der Flashmode "'''DOUT'''" wird dann automatisch eingestellt, bzw. ausgeblendet.<br />
<br />
'''Es ist daher unbedingt notwendig den Sketch mit den geänderten Einstellungen selbst zu compilieren, ansonsten stürzt das Modul nach Auswahl des Typs ab und wird nicht mehr rebooten können!'''<br />
<br />
<br />
Das Modul ist etwas größer als die anderen Sonoff Produkte und besitzt mit 14,5 x 9 cm schon beachtliche Einbau Maße.<br />
<div style="clear:both;"></div><br />
[[Datei:sonoff_ch4_2.jpg|thumb|left|alt=Sonoff 4CH FDTI]]<br />
Als weitere Besonderheit sei hier erwähnt, dass die Signale '''RxD auf RxD und TxD auf TxD''' des FTDI Konverters zu verbinden sind. Wie bei allen Sonoff Modulen darf man '''zum flashen keine Netzspannung anschließen''', sondern nur über die Versorgungsspannung des FDTI Konverters mit 3,3 V versorgen (Jumper richtig setzen). Die Stiftleiste für den FTDI Anschluss ist hier schon eingelötet.<br />
<br />
In den Flashmodus gelangt man durch Drücken der '''Taste FW/IO0''' während des Einstecken des USB Anschlusses.<br />
<div style="clear:both;"></div><br />
[[Datei:sonoff_ch4_3.jpg|thumb|left|alt=Sonoff 4CH Arends]]<br />
Hier die Ansicht des Webinterface des Arends Sketches!<br />
Bei der Software sei erwähnt, dass die getestete Version 3.1.16 nur bei Kanal 1 den Modus "PulseTime" beherrscht. Wer also gepulste Ausgänge (zB: elektrische Garage/Toröffner) benötigt muss diese per Software nachbilden oder mit dem Kanal 1 auskommen. Eine "Pulsetime 10" ist ein guter Wert dafür (etwa 1 Sekunde). <br />
<br />
Als Alternative kann mit dieser HTML Seite des Webservers am Modul des CH4 schon mit jedem Browser fähigen Handy (Android, iPhone, Windows) aufgerufen werden und somit alle Funktionen gesteuert werden.<br />
<div style="clear:both;"></div><br />
[[Datei:sonoff_ch4_4.jpg|thumb|left|alt=Sonoff CH4 Software APP]]<br />
Hier dargestellt die Original Software die Sonoff zum Modul liefert (EWeLink) und über ihre Cloud verbindet. Leider kann hier keine gepulste Ausgabe erfolgen. Mit einem Countdown kann zwar der Ausgang wieder abgeschaltet werden, die kleinste Zeiteinheit ist aber 1 Minute und somit für einen Impuls leider nicht zu gebrauchen. Ebenso kann mit dieser Software keine Einbindung in FHEM erfolgen, obwohl es eine nette anschauliche Darstellung ist.<br />
<div style="clear:both;"></div><br />
<br />
=== Anbindung FHEM===<br />
Beispiel zur Anbindung in FHEM für den 4CH, hier werden einfach 4 einzelne Schalter definiert!<br />
define Sonoff_ch1 MQTT_DEVICE<br />
attr Sonoff_ch1 IODev myBroker<br />
attr Sonoff_ch1 alias Sonoff CH1<br />
attr Sonoff_ch1 devStateIcon on:rc_GREEN:off off:rc_RED:on<br />
attr Sonoff_ch1 eventMap ON:on OFF:off ON:Ein OFF:Aus<br />
attr Sonoff_ch1 group Toröffner<br />
attr Sonoff_ch1 icon light_ceiling<br />
attr Sonoff_ch1 publishSet ON OFF cmnd/sonoffch4/POWER1<br />
attr Sonoff_ch1 stateFormat Power<br />
attr Sonoff_ch1 subscribeReading_Power tele/sonoffch4/POWER1<br />
attr Sonoff_ch1 subscribeReading_state cmnd/sonoffch4/POWER1<br />
attr Sonoff_ch1 webCmd Ein:Aus<br />
<br />
define Sonoff_ch2 MQTT_DEVICE<br />
attr Sonoff_ch2 IODev myBroker<br />
attr Sonoff_ch2 alias Sonoff CH2<br />
attr Sonoff_ch2 devStateIcon on:rc_GREEN:off off:rc_RED:on<br />
attr Sonoff_ch2 eventMap ON:on OFF:off ON:Ein OFF:Aus<br />
attr Sonoff_ch2 group Toröffner<br />
attr Sonoff_ch2 icon light_ceiling<br />
attr Sonoff_ch2 publishSet ON OFF cmnd/sonoffch4/POWER2<br />
attr Sonoff_ch2 stateFormat Power<br />
attr Sonoff_ch2 subscribeReading_Power tele/sonoffch4/POWER2<br />
attr Sonoff_ch2 subscribeReading_state cmnd/sonoffch4/POWER2<br />
attr Sonoff_ch2 webCmd Ein:Aus<br />
<br />
define Sonoff_ch3 MQTT_DEVICE<br />
attr Sonoff_ch3 IODev myBroker<br />
attr Sonoff_ch3 alias Sonoff CH3<br />
attr Sonoff_ch3 devStateIcon on:rc_GREEN:off off:rc_RED:on<br />
attr Sonoff_ch3 eventMap ON:on OFF:off ON:Ein OFF:Aus<br />
attr Sonoff_ch3 group Toröffner<br />
attr Sonoff_ch3 icon light_ceiling<br />
attr Sonoff_ch3 publishSet ON OFF cmnd/sonoffch4/POWER3<br />
attr Sonoff_ch3 stateFormat Power<br />
attr Sonoff_ch3 subscribeReading_Power tele/sonoffch4/POWER3<br />
attr Sonoff_ch3 subscribeReading_state cmnd/sonoffch4/POWER3<br />
attr Sonoff_ch3 webCmd Ein:Aus<br />
<br />
define Sonoff_ch4 MQTT_DEVICE<br />
attr Sonoff_ch4 IODev myBroker<br />
attr Sonoff_ch4 alias Sonoff CH4<br />
attr Sonoff_ch4 devStateIcon on:rc_GREEN:off off:rc_RED:on<br />
attr Sonoff_ch4 eventMap ON:on OFF:off ON:Ein OFF:Aus<br />
attr Sonoff_ch4 group Toröffner<br />
attr Sonoff_ch4 icon light_ceiling<br />
attr Sonoff_ch4 publishSet on off cmnd/sonoffch4/POWER4<br />
attr Sonoff_ch4 stateFormat Power<br />
attr Sonoff_ch4 subscribeReading_Power tele/sonoffch4/POWER4<br />
attr Sonoff_ch4 subscribeReading_state cmnd/sonoffch4/POWER4<br />
attr Sonoff_ch4 webCmd Ein:Aus<br />
<div style="clear:both;"></div><br />
<br />
<br />
==Sonoff B1==<br />
===Besonderheiten ===<br />
[[Datei:SonoffB1.JPG|mini| Sonoff B1 mit angelöteten Kabeln]]<br />
Der Sonoff B1 ist eine LED-Lampe in einer E27-Fassung, deren Farbe (in Grenzen) durch FHEM gesteuert werden kann. Die Lichtausbeute dieser Lampe ist gering, ein normal großes Zimmer kann damit nicht farblich ausgeleuchtet werden (dies gelingt nur mit kaltweißem oder warmweißem Licht), siehe [http://tinkerman.cat/sonoff-b1-lights-and-shades/ diesen Blog] <br />
<br />
Zuerst ist die Abdeckung der Lampe durch "brute force" zu entfernen. Dabei ist nichts zu drehen, zu schrauben oder zu hebeln, die lichtweiße Abdeckung ist einfach gesteckt (siehe beispielsweise [https://www.igorkromin.net/index.php/2017/10/02/how-to-open-the-sonoff-b1-wifi-led-bulb-to-access-its-internal-circuitry/ diese Anleitung]). Danach kann Sonoff wie üblich geflasht werden, da alle Kontakte ausreichend beschriftet sind. Es empfiehlt sich, zum flashen die Kontakte anzulöten.<br />
<br />
Nach dem Flashen kann die LED mit den üblichen MQTT-Kommandos angesteuert werden.<br />
<br />
===Farbechtheit ===<br />
Die Farbe bei Sonoff B1 ist, was die RGB-LEDs (red-green-blue) angeht, nicht hell. Farben wie gelb können praktisch nicht erzeugt werden. Angesteuert werden kann die Sonoff mit einem Webkommando<br />
http://<ip-Adresse>/cm?cmnd=Color%2000000000FF<br />
wobei die ersten 8 Stellen den RGB-Farbcode angeben, die nächsten beiden die Stärke des kaltweißen Lichts und die letzten beiden Stellen die Stärke des warmweißen Lichts wiedergeben. Allerdings scheinen die gelben LEDs praktisch kein Licht zu emittieren. Die kalt- und warmweißen LEDs überstrahlen die Farb-LEDs um ein Mehrfaches: Um also Farben zu erzeugen, müssen die weißen LEDs ausgeschaltet werden (Farbcode 0000 am Ende).<br />
<br />
===Einbindung in FHEM ===<br />
Die Einbindung des Sonoff B1 in FHEM ist leider nicht unmittelbar möglich. Hier existiert bisher eine Behelfslösung, die in diesem {{Link2Forum|Topic=77570|Message=696560|LinkText=siehe Forenbeitrag}} genauer beschrieben ist.<br />
<br />
==Sonoff S20==<br />
Der Sonoff S20 ist eine Neuentwicklung von Itead, bei dem keine weiteren Kabel für den Netzanschluss benötigt werden. Vielmehr befindet sich der gesamte Sonoff in einem Gehäuse. Dieses Gehäuse kann mit drei Schrauben geöffnet werden, dann ist wieder die serielle Schnittstelle zum Flashen erkennbar. <br />
[[Datei:SonoffS20 auseinander.JPG|mini| Sonoff S20 auseinander genommen]]<br />
<br />
Es empfiehlt sich, auf die vier Anschlüsse eine Stiftleiste anzulöten (dies muss aber nicht sein). Danach gelingt der Flashvorgang wie oben beschrieben.<br />
[[Datei:SonoffS20Stiftleiste.jpg|thumb|left| Sonoff S20 mit angelöteter Stiftleiste]]<br />
<br />
<div style="clear:both;"></div><br />
=Erweiterungen mit Sensoren=<br />
<br />
Wozu überhaupt den Switch erweitern wenn es auch die Modelle TH10 und TH16 gibt?<br />
<br />
Manche Personen können dadurch dem Basteltrieb nachkommen, aber das wesentliche ist der Preis, da die Switches doch fast um die Hälfte billiger sind. Die Sensoren kosten ebenfalls kaum nennenswerte Beträge.<br />
<br />
Oder es hat schon jemand Switches im Einsatz und möchte jetzt zusätzlich die Temperatur erfassen!<br />
<br />
<div style="clear:both;"></div><br />
<br />
<br />
==Sonoff Switch mit Temperatur + Luftfeuchte== <br />
=== Hardware erweitern mit DHT22 ===<br />
[[Datei:sonoff_sw_4.PNG|thumb|left|alt=Sonoff Switch Pinleiste mit Temperatur]]<br />
Am Sonoff Switch wurde ja schon eine Stiftleiste zum flashen eingelötet. Diese Stiftleiste bietet schon alle Anschlüsse welche für die Temperatur- und Luftfeuchtemessung benötigt werden. Am 5. Anschluss der Stiftleiste ist das Signal "SCL" (GPIO14) herausgeführt, welches für den DHT22 zur Erfassung der Messdaten benötigt wird. Der Sensor wird mit einem einem 3-poligen Kabel (zB: ein Steckkabel für ein Breadboard oder direkt anlöten) verbunden. Damit der DHT22 korrekt funktioniert, wird ein Widerstand mit 4,7 K Ohm zwischen Vdd und Data am DHT22 zusätzlich benötigt. <br />
<br />
<div style="clear:both;"></div><br />
<br />
[[Datei:sonoff_sw_45.jpg|thumb|left|alt=AM2302 / DHT22]]<br />
<br />
Ansicht des DHT22 (AM2302) mit den aufgesteckten Verbindungskabeln. Von links nach rechts sind das<br />
<br />
1 = VCC 3,3 V<br />
2 = Data<br />
3 = nc (nicht belegt)<br />
4 = GND<br />
<br />
Pin1 (VCC) des DHT22 muss also auf Pin1 der Stiftleiste, Pin2 (Data) auf Pin5 und Pin4 (GND) auf Pin4. <br />
Pin2 und Pin1 soll hier noch der Widerstand aufgelötet werden.<br />
<br />
1 ------- 1 (VDD)<br />
2 ------- 5 (GPIO14)<br />
3<br />
4 ------- 4 (GND)<br />
DHT22 Stiftleiste<br />
<br />
<div style="clear:both;"></div><br />
<br />
[[Datei:sonoff_sw_44.jpg|thumb|left|alt=umgebautes Modul]]<br />
Diese Darstellung zeigt das umgebaute und bereits verschlossene Modul. Auf der Seite des Tasters (bitte nur hier, da auf der anderen Seite die 230 V verlaufen und neben der Lebensgefahr auch den Sensor beeinflussen) ist hier einfach mit einer Eisensäge ein Schlitz eingesägt, der dient in diesem Falle als Kabeldurchführung. Ein Schlitz ist besser als ein Loch, da der Oberteil des Gehäuses sich leichter aufsetzen lässt. Wer ein längeres Kabel benötigt, kann natürlich auch ein 3-poliges Telefonkabel (oder Mikrokabel oder sonstiges) verwenden. Der Sensor sollte etwas Abstand zum Gehäuse haben, da dieses auch eine Eigenerwärmung hat. Wer es ganz originalgetreu lösen will, kann auch eine 3-polige Mini Buchse für Klinkenstecker (3,5mm) einbauen so wie sie am TH10/16 vorhanden ist.<br />
<div style="clear:both;"></div><br />
<br />
=== Software anpassen am Beispiel MQTT ===<br />
[[Datei:sonoff_sw_40.jpg|thumb|left|alt=Sonoff MQTT]]<br />
<br />
Die richtige Auswahl des Sensors und des verwendeten GPIO erfolgt im WEBIF des Modules und wird seit Tasmota nur mehr dort eingestellt. Eventuell sollte das aktuell verwendete [https://github.com/ddtlabs/expandJSON/ JSON Filter] geändert/erweitert werde (siehe beim Modul POW).<br />
<br />
<div style="clear:both;"></div><br />
<br />
=== Software Anpassung DHT22 in FHEM ===<br />
[[Datei:sonoff_sw_41.jpg|thumb|left|alt=umgebautes Modul]]<br />
<br />
Links in der Hardcopy sind die Readings die nach der Anpassung von FHEM (Broker) befüllt werden sollten.<br />
<br />
<div style="clear:both;"></div><br />
<br />
### Temperatur und Luftfeuchte vom Sonoff Switch ###<br />
define Sonoff_Temp MQTT_DEVICE<br />
attr Sonoff_Temp IODev myBroker<br />
attr Sonoff_Temp icon temperature_humidity<br />
attr Sonoff_Temp room MQTT<br />
attr Sonoff_Temp stateFormat {sprintf("Temperatur: %.1f Grad Feuchte: %.1f ", ReadingsVal($name,"temperature",0), ReadingsVal($name,"humidity",0))}<br />
attr Sonoff_Temp subscribeReading_Sensor tele/sonoff/SENSOR<br />
Hier die zusätzliche Erweiterung um die Temperatur und die Luftfeuchte in FHEM. Der in der Topic verwendete Name "sonoff" muss natürlich der Einstellung in der Software am Switch entsprechen. Bei Verwendung mehrerer Switches muss natürlich auch der Name bei jedem geändert werden.<br />
<br />
Als Regexp für JSON kann dieser Filter eingesetzt werden.<br />
define ej3 expandJSON .*\.SEN\..*:.*:.{.*} <br />
<div style="clear:both;"></div><br />
<br />
=== Logfile für die Temperatur ===<br />
define SVG_FileLog_Sonoff_Temp SVG myDbLog:SVG_FileLog_Sonoff_Temp:HISTORY<br />
attr SVG_FileLog_Sonoff_Temp room MQTT<br />
<br />
Und schließlich fehlt noch das Logfile, damit der Temperaturverlauf auch in schönen Plots dargestellt werden kann.<br />
Das hier verwendete Beispiel funktioniert nur mit einer DbLog.<br />
<br />
<div style="clear:both;"></div><br />
<br />
==Sonoff Switch als Thermostat verwenden mit MQTT==<br />
<br />
[[Datei:sonoff_sw_55.jpg|thumb|left|alt=Thermostat]]<br />
Mit diesem einfachen Beispiel wird ein Pelett Ofen mit einem externen Thermostat (sonoff Switch oder TH10/16) gesteuert. Zum besseren Überblick wird die Steuerung in einzelne Module getrennt, es könnte aber auch einiges zu einer einzigen Definition zusammen gefasst werden. Der Thermostat könnte auch als Frostwächter benutzt werden und ein anderes Heizgerät steuern.<br />
<div style="clear:both;"></div> <br />
<br />
###################################<br />
### Sonoff Thermostat Regelung ####<br />
###################################<br />
define Sonoff_dht MQTT_DEVICE<br />
attr Sonoff_dht IODev myBroker<br />
attr Sonoff_dht alias Raumtemperatur<br />
attr Sonoff_dht group Thermostat<br />
attr Sonoff_dht icon temperature_humidity<br />
attr Sonoff_dht publishSet ON OFF cmnd/sonoff_dht/POWER1<br />
attr Sonoff_dht room _Sonoff<br />
attr Sonoff_dht stateFormat {sprintf("Temperatur: %.1f Grad Feuchte: %.1f ", ReadingsVal($name,"temperature",0), ReadingsVal($name,"humidity",0))}<br />
attr Sonoff_dht subscribeReading_Sensor tele/sonoff_dht/SENSOR<br />
attr Sonoff_dht subscribeReading_state cmnd/sonoff_dht/POWER1<br />
FHEM Definition zur Erfassung der Temperatur und der Luftfeuchte. Damit dieses Beispiel funktioniert, ist am Sonoff Modul die Topic "'''sonoff_dht'''" zu setzen. Dieser Temperaturwert dient dem Thermostat als ISTWert.<br />
<br />
<br />
<br />
define Sonoff_Sw MQTT_DEVICE<br />
attr Sonoff_Sw IODev myBroker<br />
attr Sonoff_Sw alias Pellets Ofen<br />
attr Sonoff_Sw devStateIcon on:rc_GREEN:off off:rc_RED:on<br />
attr Sonoff_Sw eventMap ON:on OFF:off<br />
attr Sonoff_Sw group Thermostat<br />
attr Sonoff_Sw icon sani_boiler_temp<br />
attr Sonoff_Sw publishSet ON OFF cmnd/sonoff_dht/POWER1<br />
attr Sonoff_Sw room _Sonoff<br />
attr Sonoff_Sw stateFormat Licht<br />
attr Sonoff_Sw subscribeReading_Licht tele/sonoff_dht/POWER1<br />
attr Sonoff_Sw subscribeReading_state cmnd/sonoff_dht/POWER1<br />
attr Sonoff_Sw webCmd ON:OFF<br />
FHEM Definition zum Absetzen der Befehle für das Relais (Thermostat) Ein- / Aus. Wenn das zu steuernde Geräte einen potentialfreien Thermostatanschluss benötigt (in den meisten Fällen), muss noch ein Relais dazwischen geschaltet werden um die Trennung der Netzspannung zu gewährleisten.<br />
<br />
define ThermostatPellets dummy<br />
attr ThermostatPellets alias Pellets Ofen Sollwert<br />
attr ThermostatPellets group Thermostat<br />
attr ThermostatPellets icon temp_control<br />
attr ThermostatPellets room _Sonoff<br />
attr ThermostatPellets setList state:0,5,10,12,13,14,15,16,17,17.5,18,18.5,19,19.5,20,20.5,21,21.5,22,23,24,25,26,27<br />
attr ThermostatPellets webCmd state<br />
Die Sollwertvorgabe für das Thermostat durch einen Dummy, damit können die gewünschten Temperaturen eingestellt werden.<br />
<br />
### sofort ausführen wenn neuer Sollwert eingestellt wird ###<br />
define Thermostat_on_notify notify ThermostatPellets IF (ReadingsVal("Sonoff_Sw","state",0) eq "OFF" && (ReadingsVal("Sonoff_dht","temperature",0) <= Value("ThermostatPellets"))) (set Sonoff_Sw ON)<br />
define Thermostat_off_notify notify ThermostatPellets IF (ReadingsVal("Sonoff_Sw","state",0) eq "ON" && (ReadingsVal("Sonoff_dht","temperature",0) > Value("ThermostatPellets"))) (set Sonoff_Sw OFF)<br />
Mit einem notify wird die manuelle Änderung des Sollwertes überwacht und sofort reagiert.<br />
<br />
## zyklisch prüfen ob Sollwert erreicht wurde ###<br />
define Thermostat_on at +*00:15:00 IF (ReadingsVal("Sonoff_Sw","Licht",0) eq "OFF" && (ReadingsVal("Sonoff_dht","temperature",0) <= Value("ThermostatPellets"))) (set Sonoff_Sw ON)<br />
define Thermostat_off at +*00:15:00 IF (Value("Sonoff_Sw") eq "ON" && (ReadingsVal("Sonoff_dht","temperature",0) > Value("ThermostatPellets"))) (set Sonoff_Sw OFF)<br />
Hier noch die Soll- Ist Wertvergleiche zur Steuerung. Es wird alle 15 Minuten überprüft ob die Temperatur erreicht ist. Bei einer trägen Heizung sollten 15 Minuten ausreichend sein, wer will kann dies aber auch alle 5 oder 10 Minuten prüfen.<br />
Da des öfteren die Bezeichnungen der Readings im Sketch geändert werden ( zB:temperature ), bitte die richtige Schreibweise ( Groß/Klein ) in den Readings kontrollieren und gegebenenfalls hier anpassen.<br />
<br />
<div style="clear:both;"></div><br />
<br />
==Sonoff Switch mit Bewegungsmelder HC-SR501==<br />
<br />
[[Datei:sonoff_pir_1.jpg|thumb|left|alt=Bewegungsmelder]]<br />
Basierend auf dem Wall Switch MQTT Sketch von Arends wurde hier ein Sonoff BASIC + PIR HC-SR501 in eine größere Verteilerdose (auch Abzweigdose) eingebaut, der Sonoff wurde dabei etwas gekürzt. Die Bewegungsmelder sind ab etwa 70 Cent erhältlich.<br />
<br />
Der Sketch kann auch den Blink Modus. Damit kann man im Alarmfall z.B. Alle Strahler rings ums Haus blinken lassen.<br />
<br />
Mehr dazu kann hier im {{Link2Forum|Topic=63824|LinkText=Forum}}im Diskussionsthread nachgelesen werden.<br />
<div style="clear:both;"></div> <br />
<br />
[[Datei:sonoff_pir_2.jpg|thumb|left|alt=Bewegungsmelder]]<br />
Ein Beispiel wir der Bewegungsmelder in der Feuchtraumdose montiert werden kann. Wird der Bewegungsmelder abgesetzt vom Switch montiert, ist darauf zu achten das die Kabel nicht zu lange werden.<br />
<div style="clear:both;"></div><br />
<br />
===Spannungsversorgung des HC-SR501===<br />
[[Datei:sonoff_pir_4.jpg|thumb|left|alt=5V für Bewegungsmelder]]<br />
Der HC-SR501 wird vom Sonoff versorgt, wobei hier die 3,3 V nicht immer ausreichen. Es ist deshalb am HC-SR501 eine Diode zu überbrücken, dann reichen die 3,3V vom Sonoff. Es können aber auch am Sonoff die 5V angezapft werden. Hier im Bild dargestellt wo die 5V angezapft werden können.<br />
<div style="clear:both;"></div> <br />
<br />
[[Datei:sonoff_pir_5.jpg|thumb|left|alt=3,3V für Bewegungsmelder]]<br />
Hier eine kleine Übersicht der wichtigsten Teile und deren Platzierung am HC-SR501. <br />
Den PIR kann man auch mit 3,3V betreiben wenn man die Diode am Eingang nach Vcc überbrückt, dann reicht die Spannung für einen reibungslosen Betrieb völlig aus. Dies gilt für den HC-SR501, wird ein anderer PIR verwendet muss man nachschauen ob das auch möglich ist, ansonsten die 5V Variante wählen.<br />
<br />
<div style="clear:both;"></div><br />
===Einbindung des HC-SR501 in FHEM===<br />
# ------------- Sonoff_pir mit Bewegungsmelder ---------------<br />
define Sonoff_pir MQTT_DEVICE<br />
attr Sonoff_pir IODev myBroker<br />
attr Sonoff_pir eventMap ON:on OFF:off<br />
attr Sonoff_pir group Sonoff<br />
attr Sonoff_pir icon hue_filled_br30<br />
attr Sonoff_pir publishSet ON OFF cmnd/sonoff_pir/1/POWER<br />
attr Sonoff_pir room MQTT<br />
attr Sonoff_pir stateFormat Licht<br />
attr Sonoff_pir subscribeReading_Licht stat/sonoff_pir/POWER<br />
attr Sonoff_pir subscribeReading_state cmnd/sonoff_pir/1/POWER<br />
attr Sonoff_pir webCmd :<br />
<br />
Ein Beispiel wie der Sonoff Switch in FHEM eingebunden wird. Wenn im Sketch der Prefix von stat auf tele geändert wurde, ist dies auch hier durchzuführen ( subscribeReading_Licht tele/sonoff_pir/POWER ), ansonsten bleibt es so wie im Beispiel. Getestet wurde dieses Beispiel mit Version 5.5.2i. Die Topic sollte auf den Namen "sonoff_pir" eingestellt werden. Bei anderen Namen ist dies entsprechend in FHEM anzupassen. <br />
<br />
Mit dem Kommando '''SwitchTopic Alarm_SO2''' ( direkt im Webinterface des Sonoff ) wird der Wall Switch GPIO14 vom Sonoff entkoppelt und somit sendet der Bewegungsmelder direkt an FHEM --> Motion_pir MQTT_DEVICE.<br />
Bei den älteren Versionen vor Tasmota war das noch das Kommando ButtonTopic.<br />
<br />
Es sollte auch unbedingt kontrolliert werden, wie die Ausgabe des Alarmes in der Console erfolgt. Erscheint hier die Meldung "cmnd/Alarm_SO2/POWER TOGGLE" dann muss mit dem Kommando "'''SwitchMode 1'''" das Ausgabeformat umgeschaltet werden, erst dann kommt das gewünschte Format "ON" und "OFF".<br />
<br />
# ------------------ Motion_pir MQTT_DEVICE -----------------<br />
define Motion_pir MQTT_DEVICE<br />
attr Motion_pir IODev myBroker<br />
attr Motion_pir devStateIcon on:on-for-timer off:off<br />
attr Motion_pir eventMap ON:on OFF:off<br />
attr Motion_pir group Sonoff<br />
attr Motion_pir icon people_sensor<br />
attr Motion_pir room MQTT<br />
attr Motion_pir stateFormat Alarm<br />
attr Motion_pir subscribeReading_Alarm cmnd/Alarm_SO2/POWER1<br />
Die Motion_pir dient nun zur eigentlichen Einschaltung des Lichtes und sendet das Kommando '''cmnd/Alarm_SO2/POWER1''' an den entkoppelten GPIO 14 des Switch.<br />
<br />
<br />
# ------------------ DoIf zur Motion Abfrage -----------------<br />
define di_Sonoff_pir_Alarm DOIF ([Motion_pir:"on"] and [Tag_Nacht:twilight_weather] < 35) (set Sonoff_pir on) DOELSEIF ([Motion_pir:"off"] and [Tag_Nacht:twilight_weather] < 35) (set Sonoff_pir off)<br />
attr di_Sonoff_pir_Alarm comment Abhängig von Helligkeitssensor wird nachts,bei Bewegung das Licht eingeschaltet!<br />
attr di_Sonoff_pir_Alarm group Sonoff<br />
attr di_Sonoff_pir_Alarm room MQTT<br />
Zusätzlich kann nun mit einem '''DOIF''' verknüpft werden um das Ganze mit Tag_Nacht:twilight_weather dann in Abhängigkeit der Helligkeit zu schalten. Selbstverständlich kann jede andere Quelle mit einem Helligkeitswert verwendet werden.<br />
<br />
===Alarmausgabe über Grouptopic===<br />
# ------------------------ Sonoffs Group ----------------------<br />
define Sonoffs MQTT_DEVICE<br />
attr Sonoffs IODev myBroker<br />
attr Sonoffs eventMap ON:on OFF:off<br />
attr Sonoffs group Sonoff<br />
attr Sonoffs icon hue_filled_br30<br />
attr Sonoffs publishSet ON OFF cmnd/sonoffs/POWER1<br />
attr Sonoffs room MQTT<br />
attr Sonoffs stateFormat state<br />
attr Sonoffs subscribeReading_Licht stat/sonoffs/POWER1<br />
attr Sonoffs subscribeReading_state cmnd/sonoffs/POWER1<br />
Wer möchte kann auch mit der Group Topic mehrere Switches mit Bewegungsmelder zusammenfassen und alle Lampen im Alarmfall gemeinsam in den Blinkmodus schalten. cmnd/sonoffs ist das Kommando für die Group Topic, sofern diese vom User nicht verändert wurde.<br />
<div style="clear:both;"></div><br />
<br />
==Sonoff Switch als IR-Sender verwenden == <br />
===Einrichtung ===<br />
<br />
[[Datei:sonoff_ir_1.jpg|thumb|left|alt=IR]]<br />
Mit einem normalen Sonoff Basic Modul kann dies zu einer IR Fernbedienung hochgerüstet werden.<br />
<br />
Der einfache Schaltplan ist [https://raw.githubusercontent.com/altelch/SonoffIR/master/SonoffIR-Schematics.png hier] zu finden und der Nachbau ist sehr einfach. Man kann aber auch aus einer alten FB die IR-Diode ausbauen und zusammen schalten. Ein kleines Howto ist in [https://github.com/altelch/SonoffIR diesem Wiki] auf Github zu finden.<br />
<br />
Verwendet wird dazu der Arends Sketch.<br />
<br />
Als erstes sucht man sich auf [http://lirc.sourceforge.net/remotes/ LIRC]die entsprechenden FB-Codes, im Beispiel hier für einen Samsung TV 55" Curved UHD HU8580. Die FB ist zwar nicht exakt dieselbe, aber die Befehle passen soweit. Im Webif des Sonoff Modules ist beim angeschlossenen GPIO der IR-Diode "8 IRremote" einzustellen.<br />
<br />
Link zum {{Link2Forum|Topic=67316|LinkText=Forums Thread}}<br />
<div style="clear:both;"></div><br />
Wichtig sind dabei folgende Daten:<br />
name Samsung_BN59-00940A<br />
bits 16<br />
pre_data_bits 16<br />
pre_data 0xE0E0<br />
Power On/Off 0x40BF[/code]<br />
<br />
Nun stellt man sich den Sendestring zusammen:<br />
predata+Befehl = E0E0'''40BF''' (hex) = 3772793023 (dec) und 32 Bit Datenlänge.<br />
<br />
Der JSON String für den IRSend ist laut [https://github.com/arendst/Sonoff-Tasmota/wiki/Commands Arends Wiki] folgender.<br />
IRsend | {"protocol": "<proto>", | Send IR remote control as JSON encapsulated command.<br />
| "bits": 1..32 | <proto> is NEC, SONY, RC5, RC6, DISH, JVC or SAMSUNG<br />
| "data": 1..(2^32)-1} | bits are the required number of data bits.<br />
| | data is the data frame as 32 bit unsigned integer.<br />
| | See http://www.lirc.org/ for more info.<br />
<br />
das ergibt dann unseren Befehl für die Kommandozeile am Modul. Die Bitlänge für Pre und Data sind ebenfalls zu addieren (16 + 16 = 32 Bit) und beim Arends Sketch muss im JSON Format gesendet werden:<br />
<br />
'''irsend {"protocol": "SAMSUNG","bits": 32, "data": 3772793023}'''<br />
<br />
hier für die Kommandozeile am Broker alte Version Tasmota bis 4.x:<br />
'''mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772793023}''''<br />
oder hier für die Kommandozeile am Broker Version Tasmota ab 5.x:<br />
'''mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772793023}''''<br />
TestSwitch ist hier der verwendete Name des Sonoff Moduls, wird ein anderer Name verwendet ist dieser hier anzupassen.<br />
<br />
Jedes mal wenn nun der Befehl gesendet wird, wird entweder Ein- oder Aus geschaltet. Die Verzögerung über Wlan ist vernachlässigbar. Ebenso können die Kanäle oder die Lautstärke verstellt werden. Im Prinzip funktionieren alle Befehle die auf der FB vorhanden sind.<br />
<div style="clear:both;"></div><br />
<br />
===FHEM Beispiel===<br />
[[Datei:sonoff_ir_2.jpg|thumb|left|alt=IR]]<br />
Hier ein Beispiel wie der Code für die Fernbedienung in FHEM eingebunden werden kann.<br />
define RC_TV remotecontrol<br />
attr RC_TV rc_iconpath icons/remotecontrol<br />
attr RC_TV rc_iconprefix black_btn_<br />
attr RC_TV room Entwicklung<br />
attr RC_TV row00 KEY_POWER:POWEROFF,:blank,:blank<br />
attr RC_TV row02 :blank,:blank,:blank<br />
attr RC_TV row03 KEY_1:1,KEY_2:2,KEY_3:3<br />
attr RC_TV row04 KEY_4:4,KEY_5:5,KEY_6:6<br />
attr RC_TV row05 KEY_7:7,KEY_8:8,KEY_9:9<br />
attr RC_TV row06 :blank,KEY_0:0,:blank<br />
attr RC_TV row07 :blank,:blank,:blank<br />
attr RC_TV row08 KEY_VOLUMEUP:UP,KEY_MUTE:MUTE,KEY_CHANNELUP:CHUP<br />
attr RC_TV row09 KEY_VOLUMEDOWN:DOWN,:blank,KEY_CHANNELDOWN:CHDOWN<br />
<br />
define Samsung_TV notify RC_TV "/opt/fhem/ircmd.sh $EVENT"<br />
<div style="clear:both;"></div> <br />
In einem externen Shell Script werden die Parameter übergeben und der Sendestring für den IRSend zusammen gestellt. Das Script ins FHEM Home Verzeichnis kopieren ( /opt/fhem ) und die Rechte auf 755 setzen.<br />
[https://wiki.fhem.de/wiki/Remotecontrol Link zum Wiki] einer universellen Fernbedienung.<br />
<br />
#!/bin/sh -e<br />
if [ "$1" = "KEY_POWER" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772793023}'<br />
fi<br />
# E0E0E01F 3772833823<br />
if [ "$1" = "KEY_VOLUMEUP" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772833823}'<br />
fi<br />
# E0E0D02F 3772829743<br />
if [ "$1" = "KEY_VOLUMEDOWN" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772829743}'<br />
fi<br />
# E0E0F00F 3772837903<br />
if [ "$1" = "KEY_MUTE" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772837903}'<br />
fi<br />
# E0E020DF 3772784863<br />
if [ "$1" = "KEY_1" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772784863}'<br />
fi<br />
# E0E0A05F 3772817503<br />
if [ "$1" = "KEY_2" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772817503}'<br />
fi <br />
# E0E0609F 3772801183<br />
if [ "$1" = "KEY_3" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772801183}'<br />
fi <br />
# E0E010EF 3772780783<br />
if [ "$1" = "KEY_4" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772780783}'<br />
fi <br />
# E0E0906F 3772813423<br />
if [ "$1" = "KEY_5" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772813423}'<br />
fi <br />
# E0E050AF 3772797103<br />
if [ "$1" = "KEY_6" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772797103}'<br />
fi <br />
# E0E030CF 3772788943<br />
if [ "$1" = "KEY_7" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772788943}'<br />
fi<br />
# E0E0B04F 3772821583<br />
if [ "$1" = "KEY_8" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772821583}'<br />
fi <br />
# E0E0708F 3772805263<br />
if [ "$1" = "KEY_9" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772805263}'<br />
fi <br />
# E0E08877 3772811383<br />
if [ "$1" = "KEY_0" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772811383}'<br />
fi<br />
# E0E048B7 3772795063<br />
if [ "$1" = "KEY_CHANNELUP" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772795063}'<br />
fi<br />
# E0E008F7 3772778743<br />
if [ "$1" = "KEY_CHANNELDOWN" ]; then<br />
mosquitto_pub -q 2 -t cmnd/TestSwitch/IRSend/set -m '{"protocol": "SAMSUNG","bits": 32, "data": 3772778743}'<br />
fi <br />
Das Script kann sehr leicht für jede andere FB abgeändert werden und auch noch zusätzliche Tasten eingebunden werden. Bitte nicht auf die vorangestellten Pre-Data-Bits vergessen. Auf die Verwendung des Scriptes kann auch verzichtet werden, wenn der JSON String in FHEM direkt zusammen gestellt wird. Für den Nachbau ist es aber leichter verständlicher und kann auch leicht selber an die eigene FB angepasst werden.<br />
<br />
<div style="clear:both;"></div><br />
{{Hinweis|Alternative Methoden ohne externes shell-script sind für [[MQTT_DEVICE]] [[IR-MQTT-Gateway|hier]] zu finden, dies wäre für [[MQTT2_DEVICE]] anzupassen, hier ist ein attrTemplate (''tasmota_ir'') verfügbar, das exemplarisch bestimmte Kommandos auch direkt am Device anbietet. Alternativ könnte auch die ''publish''-Option eines der MQTT-Interfaces genutzt werden.}}<br />
==Sonoff Development Board==<br />
===Einrichtung===<br />
[[Datei:sonoff_dev_1.jpg|thumb|left|alt=Dev. Board]]<br />
Das Board kommt ohne Software und muss zunächst mit einem Sketch bespielt werden. Hier kurz beschrieben der Arends Sketch, es funktioniert aber mit ESPEasy genau so gut. <br />
<br />
Damit die vielen GPIO's auch nach freiem Wunsch zugeordnet werden können, müssen die erforderten Einstellungen da allerdings in der sonoff_template.h bekannt gegeben werden. Hier wurde der GPIO12 und 13 einem Relais zugeordnet. Der Rest kann dann frei im Webif konfiguriert werden (Type = User Test).<br />
<br />
Link zum [https://www.itead.cc/wiki/Sonoff_DEV Wiki des Herstellers]<br />
<br />
Link zum [https://www.itead.cc/wiki/images/3/30/01.73.02.0101_Sonoff_DEV_Schematic.pdf Schaltplan]<br />
<br />
<div style="clear:both;"></div> <br />
<br />
Anschlüsse und GPIO's am Board.<br />
<br />
3V3 VDD 3.3V Power supply output <br />
GND GND Power supply pin <br />
4 GPIO4 GPIO4 <br />
5 GPIO5 GPIO5 <br />
12 GPIO12 GPIO12/HSPIQ <br />
13 GPIO13 GPIO13/HSPID <br />
14 GPIO14 GPIO14/HSPICLK <br />
ADC ADC Detect analog input voltage(0~1V) <br />
RX U0RXD Flash programming UART RX;GPIO3 <br />
TX U0TXD Flash programming UART TX;GPIO1;SPICS1 <br />
E-FW GPIO0 GPIO0/SPICS2/Serial programming enable pin <br />
RESET RESET External reset signal(low active) <br />
<br />
<br />
<br />
[[Datei:sonoff_dev_2.jpg|thumb|left|alt=Dev. Board]]<br />
hier können die wesentlichen Funktionen (Relaisfunktion oder freier GPIO) konfiguriert werden. Man zählt die GPIO's von oben nach unten und wenn einer nicht benötigt wird, wird eine 0 angegeben.<br />
<div style="clear:both;"></div> <br />
{ "User Test", // Sonoff Basic User Test<br />
GPIO_KEY1, // GPIO00 Button<br />
0,<br />
GPIO_USER, // GPIO02 Optional sensor<br />
GPIO_USER, // GPIO03 Serial TXD and Optional sensor<br />
GPIO_USER, // GPIO04 Optional sensor<br />
GPIO_USER, // GPIO05 Optional sensor<br />
0, 0, 0, 0, 0, 0,<br />
'''GPIO_REL2''', // GPIO12 Relay 2 (0 = Off, 1 = On)<br />
'''GPIO_REL1''', // GPIO13 Relay 1 (0 = Off, 1 = On)<br />
GPIO_USER, // GPIO14 Optional sensor<br />
0, 0<br />
}<br />
Hier wurde am Modul "'''User Test'''" in der Datei "sonoff_template.h" abgeändert, um 2 Relais über GIPO12 und GPIO13 ansteuern zu können. <br />
<br />
Gedacht ist es als Entwicklerboard, es ist aber auch genau so gut für den produktiven Einsatz geeignet, hat aber kein eingebautes Netzteil. Es ist zum flashen '''kein externes FTDI Modul notwendig''', das hat es bereits an Board und es muss lediglich der USB Treiber für Windows installiert werden. Geflasht wird dann mit dem USB Kabel der Spannungsversorgung.<br />
<br />
Die 4-pol. Stecker haben das '''Rastermaß 2.0 mm'''. <br />
<br />
<div style="clear:both;"></div> <br />
<div style="clear:both;"></div> <br />
===Anbindung FHEM===<br />
<br />
je nach Anwendungszweck wird entweder ein normaler Schalter oder wie bei DHT16 (?) beschrieben ein oder mehrere Sensoren angebunden.<br />
Beim Arends Sketch ist zu beachten, dass pro Sensorgruppe nur ein Sensor angeschlossen werden kann.<br />
<br />
•DHT11 Temperature and Humidity - DHT11 (1) in group 1<br />
•DHT21 Temperature and Humidity - AM2301 (2) in group 1<br />
•AM2301 Temperature and Humidity - AM2301 (2) in group 1<br />
•DHT22 Temperature and Humidity - DHT22 (3) in group 1<br />
•AM2302 Temperature and Humidity - DHT22 (3) in group 1<br />
•AM2321 Temperature and Humidity - DHT22 (3) in group 1<br />
•DS18B20 Temperature - DS18x20 (4) in group 2<br />
Enable option USE_DS18x20 in user_config.h for multiple sensors using OneWire library<br />
•DS18S20 Temperature - DS18x20 (4) in group 2<br />
Enable option USE_DS18x20 in user_config.h using OneWire library<br />
•External switch - Switch (9) <br />
Use SwitchMode to tune it's behaviour<br />
•HC-SR501 PIR Motion Detection - Switch (9) <br />
Use SwitchMode to tune it's behaviour<br />
Beispiel: 2 DHT22 funktionieren nicht, aber ein DHT22 und ein DS18b20 schon. Wer mehrere Sensoren benötigt, muss auf ESPEasy ausweichen.<br />
<br />
----<br />
<br />
<references /><br />
<br />
[[Kategorie:Other Components]]<br />
[[Kategorie:IP Components]]<br />
[[Kategorie:MQTT]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=ESP8266&diff=35941ESP82662021-08-01T14:19:00Z<p>Andies: /* Tasmota */ webbasiert flashen</p>
<hr />
<div>[[ESP8266]] ist ein 32-Bit-Mikrocontroller mit WLAN-Funkmodul von der chinesischen Firma Espressif, der einfach programmiert werden kann. Er erlaubt einerseits den Anschluss von Sensoren und Aktoren via GPIO, SPI oder serieller Schnittstelle und andererseits via WLAN-Schnittstelle die Verbindung mit dem FHEM-Server. Mehrere Schaltaktoren haben diesen Chip verbaut und können daher umgeflasht werden, so dass eine Einbindung in FHEM möglich ist. <br />
<br />
== ESP8266 Technische Daten ==<br />
Das Datenblatt kann man auf der [https://www.espressif.com/sites/default/files/documentation/0a-esp8266ex_datasheet_en.pdf Webseite von espressif] herunterladen. Weitere technische Details über ESP8266 sind im [https://www.mikrocontroller.net/articles/ESP8266 mikrocontroller.net] zu finden. Auch in der [https://de.wikipedia.org/wiki/ESP8266 Wikipedia] finden sich interessante Informationen. Die umfangreichsten Informationen aber hat Neil Kolban in einem kostenfreien [http://neilkolban.com/tech/esp8266/ eBook] zusammengetragen.<br />
<br />
== ESP8266 mit einer alternativen Firmware flashen ==<br />
Sehr viel Informationen zum flashen des Chips findet man {{Link2Forum|Topic=46205|LinkText=in diesem Forumthread}}. Ein hilfreiches Video findet sich [https://www.youtube.com/watch?v=Gh_pgqjfeQc hier].<br />
<br />
[[Datei:Verdrahtung.jpg|mini|rechts|Verdrahtung im Original]]<br />
<br />
ESP < - > USB-Adapter<br />
TX < - > RX<br />
RX < - > TX<br />
VCC < - > 3.3V<br />
CH_PD < - > 3.3V<br />
GND < - > GND<br />
GPIO0 < - > GND<br />
<br />
Es ist unbedingt darauf zu achten, dass der ESP nur mit 3,3 Volt betrieben werden darf. Allerdings sind die PINs des ESP sehr wohl 5V-tolerant, siehe hierzu [https://forum.fhem.de/index.php/topic,108669.msg1026465.html#msg1026465 diesen Thread]. Entscheidend ist, dass der Stromfluss von dem 5V-Element begrenzt wird, da sonst die innenliegende Diode durchbrennt.<br />
<br />
=== ESPLink ===<br />
ESPLink ist eine open-source Firmware von [https://github.com/jeelabs/esp-link jeelabs], deren Weiterentwicklung anscheinend eingestellt wurde. Sie erlaubt die Anbindung einer seriellen Schnittstelle ans Internet (Port 23) über den ESP. Weitere Sensoren können nicht oder nur mit Abänderung der Firmware verwendet werden.<br />
<br />
Es findet sporadisch eine Weiterentwicklung an ESPLink statt, im Jahr 2020 wurde eine Version 3.0 erwähnt. Eine wichtige Anmerkung zur derzeit stabilen Version 2.2.3: Einige Versionen des ESP-01 enthalten den so genannten Puya-Speicherchip (googled man Puya und ESP-01 so finden sich zahlreiche Hinweise). Hat man einen solchen Puya-Chip, so gibt es beim flashen Probleme: Zwar erfolgt der Schreibvorgang fehlerfrei, es kann aber nicht im internen ESP-Speichersystem (so genannte SPIFFS) geschrieben werden, so dass das eigentliche Programm auf dem ESP nicht läuft und man zum Beispiel keine Wifi-Angaben speichern oder keine Webseiten aufrufen kann. Es ist möglich, dass ESPLink Version 2.2.3 von diesem Fehler betroffen ist. In diesem Fall muss man auf eine andere Software ausweichen, siehe zum Beispiel diesen [https://forum.fhem.de/index.php/topic,108435.msg1024056.html#msg1024056 Forumsbeitrag mit Sketch].<br />
<br />
=== ESPEasy ===<br />
ESPEasy ist eine open-source Firmware von [https://www.letscontrolit.com/wiki/index.php/ESPEasy Letscontrolit], die beständig weiterentwickelt wird. Sie erstellt eine GUI, mit der eine Einbindung in FHEM leicht gelingt und verschiedene Sensoren eingebunden werden können. Dabei muss man davon ausgehen, dass man den Chip selbst verdrahten muss. Mehr Informationen in diesem [[ESPEasy|Eintrag]].<br />
<br />
=== Tasmota ===<br />
Tasmota ist eine open-source Firmware von [https://github.com/arendst/Sonoff-Tasmota Theo Arends], die beständig weiterentwickelt wird. Sie erstellt eine GUI, die eine Einbindung in FHEM erlaubt und zudem eine MQTT-Einbindung erstellt. Oft kann man Tasmota ohne größere Umbauten am Gerät auf den Chip übertragen.<br />
<br />
Inzwischen kann man Tasmota webbasiert flashen, wenn eine USB-Verbindung mit dem ESP besteht: https://arendst.github.io/Tasmota/ <br />
<br />
== Bekannte Geräte ==<br />
Mehrere Geräte, die in FHEM eingebunden werden können, enthalten den ESP8266 und eignen sich daher zum flashen. Zu nennen sind (Angabe mit Forenthreads oder Wikieinträgen)<br />
<br />
{|<br />
| Sonoff-Gerätegruppe<br />
| [https://wiki.fhem.de/wiki/Sonoff Wikieintrag]<br />
|-<br />
| Shelly-Aktoren<br />
| [https://wiki.fhem.de/wiki/Shelly-Aktoren Wikieintrag]<br />
|-<br />
| diverse Eigenbauprojekte<br />
| {{Link2Forum|Topic=91042|LinkText=Forumthread}}<br />
|}<br />
<br />
== Bekannte Probleme ==<br />
Mein USB Seriell Adapter hatte scheinbar Probleme beim Flashen der alternativen Firmware. Nach einem Tipp aus dem Forum, alternativ einen Arduino nano mit FTDI Chip zu nehmen, den ich zum Glück hatte, lief alles problemlos.<br />
<br />
Der ESP ist intern so programmiert, dass er nach 5 Minuten Inaktivität die Kommunikation mit WLAN einstellt. Dadurch kann es zu Verzögerungen bei nachfolgenden Sende- und Empfangsbefehlen kommen. Hierbei kann es sich als hilfreich erweisen, regelmäßig einen ping-Befehl zu senden, damit die WLAN-Kommunikation wieder aufgenommen wird. Allerdings basiert ping auf ICMP (siehe [https://www.tippscout.de/internet-was-sind-tcp-ip-udp-und-icmp_tipp_2268.html diese Erklärung]) und daher kann es sein, dass die TCP-Kommunikation davon gerade nicht beeinflusst und damit aktiviert wird.<br />
<br />
== Links ==<br />
* Hier schon mal die Anleitung als Word Dokument, meinen Dank an alle die dabei im Vorfeld geholfen haben {{Link2Forum|Topic=28905|Message=297646|LinkText=Anleitung}}<br />
* Im Netz gibt es ein entsprechendes Forum [http://www.esp8266.com www.esp8266.com]<br />
* [[Sonoff]]<br />
[[Kategorie:Other Components]]<br />
[[Kategorie:IP Components]]<br />
[[Kategorie:ESP8266]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Modul_YAAHM&diff=35371Modul YAAHM2021-03-28T18:53:58Z<p>Andies: /* Umstellung Sommer- zu Winterzeit */weblink Zeitumstellung</p>
<hr />
<div>{{<br />
Infobox Modul<br />
|ModPurpose=Das Modul stellt eine komfortable Oberfläche bereit, um per Webinterface die zyklische Ausführung von Kommandos - mit Tages- und Wochenprofil - zu konfigurieren<br />
|ModType=h<br />
<!-- |ModCategory= (noch?) nicht verwendet --><br />
|ModCmdRef=YAAHM<br />
|ModForumArea=Unterstuetzende Dienste<br />
|ModTechName=95_YAAHM.pm<br />
|ModOwner=Prof. Dr. Peter A. Henning<br />
}}<br />
Diese Seite beschreibt die Konfiguration und Verwendung des Moduls 95_YAAHM.pm. <br />
<br />
=Einführung=<br />
Viele Kommandos in FHEM orientieren sich an Tageszeiten. Beispielsweise sollen Rollläden zu Sonnenaufgang hochgefahren werden, morgens die Kaffeemaschine und die Heizung eingeschaltet und bei Sonnenuntergang kontrolliert werden, ob das Garagentor geschlossen ist. Jeder dieser Befehle könnte mit einem zeitgesteuerten at-Device definiert werden. Das Modul ''95_YAAHM.pm'' stellt für diese Aufgaben eine einheitliche und komfortable zu steuernde Oberfläche bereit. Man benötigt somit nicht mehrere at, sondern sammelt alle Befehle in YAAHM. Der Titel '''YAAHM''' ist das Akronym für ''Yet Another Auto Home Module'', denn es gibt ja schon verschiedene Module, die den Zeitablauf in einem SmartHome vereinfachen sollen. <br />
<br />
Die Philosophie von YAAHM ist die einfache Bedienbarkeit im Frontend, mit Eingabefeldern und Visualisierungselementen und ohne Unmengen von Attributen. Dafür gilt es zunächst, verschiedene Begriffe zu verstehen.<br />
<br />
== Tages-Typ ==<br />
Ein Tagestyp wird Befehle bestimmen, die im Laufe eines Tages ausgeführt werden sollen. Am Anfang eines Tages (nach Mitternacht) sollen beispielsweise doppelte Einträge in einer Datenbank gelöscht werden, zu Sonnenaufgang werden Rollläden hochgefahren und zur Weckzeit schaltet sich die Kaffeemaschine ein. Dabei soll man aber bei den einzelnen Befehlen unterscheiden können, ob wir einen Arbeitstag, ein Wochenende oder einen Feiertag haben: An einem Werktag soll der Rollladen zu Sonnenaufgang hochfahren, an einem Feiertag dagegen erst später.<br />
<br />
In YAAHM wird dies durch Tagestypen gelöst. Es sind immer die beiden Tagestypen ''Wochenende'' und ''Werktag'' definiert. Weitere Tagestypen, die dann die Steuerung anderer Befehle erlauben, kann man mit den Attributen ''vacationDevices'' (für Ferientage) und ''holidayDevices'' (Feiertage) hinzufügen. Dabei ist jeweils eine Semikolon-separierte Liste aus holiday-Devices oder Calendar-Devices anzugeben (da die Eingaben direkt in fhem("") eingetragen werden, sind die Regeln der [[Klammerebenen]] zu beachten). Der letztendliche Tagestyp wird dann in einer Priorisierung festgelegt: ''Feiertag'' hat die höchste Priorität, gefolgt von ''Wochenende'', ''Ferientag'' und ''Werktag''. Welcher Tagestyp vorliegt, wird durch YAAHM jeden Morgen kurz nach Mitternacht fixiert.<br />
<br />
== Tages-Profil ==<br />
Das Tagesprofil besteht aus einer Kette von Ereignissen, die an jedem Tag aufeinander folgen. Für jedes Ereignis kann eine Liste von FHEM-Kommandos angegeben werden, die dann ausgeführt werden. Welches Ereignis als Letztes eintrat, steht im Reading '''housetime''', das vorhergehende Ereignis im Reading ''prev_housetime'' und das vom gegenwärtigen Zeitpunkt aus nächste Ereignis im Reading ''next_housetime''. <br />
<br />
Wenn man mit jedem eingetretenen Ereignis eine weitere selbst definierte Funktion ausführen möchte, kann man dazu das folgende Attribut verwenden<br />
attr <Modulname> timehelper {hier_die_Perl_Funktion_eintragen(Argumente)}<br />
Die angegebene Perl-Hilfsfunktion wird dann bei jedem Ereignis aufgerufen. Die entsprechenden Argumente, die je nach aktueller Zeit vom Modul automatisch eingefügt werden, lauten dann wie folgt (siehe auch [[#Attribute | Attribute]]):<br />
<br />
*aftermidnight, beforemidnight: ''Nach Mitternacht'' und ''Vor Mitternacht'' sind Ereignisse, die mit einem Offset an jedem Tag nach bzw. vor Mitternacht ausgeführt werden.<br />
*sunrise, beforesunrise, aftersunrise: ''Sonnenaufgang'', ''Vor Sonnenaufgang'' und ''Nach Sonnenaufgang'' sind Ereignisse, die an jedem Tag zu Sonnenaufgang bzw. mit einem Offset davor und danach ausgeführt werden. Der Zeitpunkt des Sonnenaufgangs wird aus dem Modul 95_Astro.pm berechnet. Mit dem Attribut ''sunrise'' kann ausgewählt werden, welcher Horizontwinkel für den Sonnenaufgang genommen wird, siehe dort.<br />
*sunset, beforesunset, aftersunset: ''Sonnenuntergang'', ''Vor Sonnenuntergang'' und ''Nach Sonnenuntergang'' sind Ereignisse, die an jedem Tag zu Sonnenuntergang bzw. mit einem Offset davor und danach ausgeführt werden. Der Zeitpunkt des Sonnenuntergangs wird aus dem Modul 95_Astro.pm berechnet. Mit dem Attribut ''sunset'' kann ausgewählt werden, welcher Horizontwinkel für den Sonnenuntergang genommen wird, siehe dort.<br />
*morning, noon, afternoon, evening, night: ''Morgen'', ''Mittag'', ''Nachmittag'', ''Abend'' und ''Nacht'' sind Ereignisse, die zu einer einstellbaren Zeit an jedem Tag ausgeführt werden. Das Reading '''housephase''' nimmt zwischen ''Morgen'' und ''Nacht'' den Wert ''Tageszeit'' an, sonst den Wert ''Nachtzeit''.<br />
*wakeup, sleep: ''Wecken'' und ''Schlafen'' sind Ereignisse, die durch die beiden Standard-Wochenprofile gleichen Namens ausgelöst werden. Die entsprechenden Zeiten können von Tag zu Tag beliebig variieren.<br />
<br />
== Wochen-Profile ==<br />
Es gibt Ereignisse, die an jedem Wochentag ausgeführt werden sollen. Allerdings variiert möglicherweise die Startzeit je Wochentag. Beispielsweise soll an jedem Tag der Woche das Gartentor öffnen; Montags soll dies aber um 5:40, dienstags um 5:50 und Mittwochs bis Freitags um 6:10 geschehen, am Wochenende soll das Gartentor geschlossen bleiben. Da der Befehl an jedem Wochentag derselbe ist und nur die Startzeit variiert, eignet sich dafür das ''Wochenprofil''. <br />
<br />
Für jedes Wochen-Profil kann man angeben, ob es auch an einem ''Urlaubstag'' (=Url) und an einem ''Feiertag'' (=Fei) gültig sein soll, siehe [[#Einstellung der Wochen-Profile | Wochen-Profile]].<br />
<br />
Ein Wochenprofil definiert dabei diejenigen Ereignisse, die an jedem Wochentag ausgeführt werden sollen. Es ist möglich, mehrere Wochenprofile zu definieren. Zwei Standard-Wochenprofile ''Wecken'' und ''Schlafen'' sind vordefiniert und können nicht gelöscht werden; weitere Wochenprofile können angelegt und wieder gelöscht werden. <br />
<br />
Für jedes Wochenprofil kann eine manuelle Auslösezeit (im Beispiel oben wären dies montags 5:40, dienstags 5:50, mittwochs bis freitags 6:10 sowie samstags und sonntags off) eingegeben werden. Ist die Auslösezeit später als der gegenwärtige Zeitpunkt, wird sie für den aktuellen Tag verwendet. Ist die Auslösezeit früher als der gegenwärtige Zeitpunkt, wird sie erst am nächsten Tag als Ausnahmezeit verwendet. Lautet die manuelle Auslösezeit 'off', wird der heutige Auslösezeitpunkt abgeschaltet, wenn er noch nicht verstrichen ist - sonst der morgige Auslösezeitpunkt. Nach Ausführung wird der manuelle Eintrag anscheinend nicht gelöscht.<br />
<br />
Das Modul ermöglicht mit dem Attribut ''timeHelper'' die Angabe einer Perl-Hilfsfunktion, die für die beiden ersten (Standard-)Wochenprofile bei Eintritt des Events mit den entsprechenden Argumenten aufgerufen wird, siehe [[#Attribute | Attribute]].<br />
<br />
== (Nutzungs-)Modus ==<br />
Der '''housemode''' (bzw. (Nutzungs-)Modus) besagt, dass sich das SmartHome in einem der vier Modi ''Normal'', ''Party'', ''Abwesenheit'' oder ''Nicht Stören'' befindet. Dabei bedeutet:<br />
*''Normal'' (Readingswert normal) = normale Tages- und Wochen-Profile werden angewandt, keine speziellen Anordnungen.<br />
*''Party'' (Readingswert party) = kann in Hilfsfunktionen verwendet werden, um spezielle Anordnungen betreffend die Sicherheit und den Übergang in den Nachtzustand zu realisieren. Das Modul selbst sorgt dafür, dass im Party-Modus das SmartHome nicht in einen gesicherten Zustand versetzt werden kann.<br />
*''Abwesenheit'' (Readingswert absence) = kann in Hilfsfunktionen verwendet werden, um spezielle Anordnungen zu realisieren. <br />
*''Nicht Stören'' (Readingswert donotdisturb) = kann in Hilfsfunktionen verwendet werden, um spezielle Anordnungen zu realisieren. <br />
Die Festsetzung des Modus bleibt bestehen, bis eine erneute manuelle Änderung durchgeführt wird. Ausnahme: Wenn das Attribut ''modeAuto'' gesetzt wird, kann sich der Modus auch bei bestimmten Events ändern.<br />
Für jedes Wochen-Profil kann man angeben, ob es auch im Party-Modus (=Par) und bei Abwesenheit (=Abw) gültig sein soll, siehe [[#Einstellung der Wochen-Profile | Wochen-Profile]].<br />
<br />
Das Modul ermöglicht mit dem Attribut ''modeHelper'' die Angabe einer Perl-Hilfsfunktion, die zu jedem Wechsel des Modus mit den entsprechenden Argumenten aufgerufen wird, siehe [[#Attribute | Attribute]]<br />
<br />
== (Sicherheits-)Zustand ==<br />
Der '''housestate''' (bzw. (Sicherheits-)Zustand) besagt, dass sich das SmartHome in einem der vier Zustände ''Nicht gesichert'', ''Gesichert'', ''Geschützt'' oder ''Überwacht'' befindet. Die Festsetzung des Zustands bleibt bestehen, bis eine erneute manuelle Änderung durchgeführt wird. Ausnahme: Wenn das Attribut ''stateAuto'' gesetzt wird, kann sich der Zustand auch bei bestimmten Events ändern. Dabei bedeutet (beispielsweise !)<br />
**''Ungesichert'' (Readingswert unsecured) = Türen sind unverschlossen, Fenster dürfen geöffnet sein<br />
**''Gesichert'' (Readingswert secured) = Türen sind verschlossen, Fenster dürfen nur in Ausnahmefällen geöffnet sein<br />
**''Geschützt'' (Readingswert protected) = Türen sind verschlossen, Fenster dürfen nur in Ausnahmefällen geöffnet sein, die Alarmanlage ist scharf geschaltet<br />
**''Überwacht'' (Readingswert guarded) = Türen sind verschlossen, Fenster dürfen nur in Ausnahmefällen geöffnet sein, die Alarmanlage ist scharf geschaltet, in regelmäßigen Abständen wird der Zustand des Hauses überprüft und bei Veränderungen irgendwie gemeldet. Vielleicht läuft auch noch eine Anwesenheitssimulation<br />
<br />
Das Modul ermöglicht mit dem Attribut ''stateHelper'' die Angabe einer Perl-Hilfsfunktion, die zu jedem Wechsel des Zustands mit den entsprechenden Argumenten aufgerufen wird, siehe [[#Attribute | Attribute]]. Welche FHEM-Devices dabei geschaltet werden, muss also in dieser externen Hilfsfunktion angegeben werden.<br />
<br />
Allerdings lässt sich in YAAHM der Schaltzustand dieser Devices periodisch überwachen. Sie werden dazu in das Attribut 'stateDevices' eingetragen, siehe unten.<br />
<br />
=YAAHM-Device=<br />
==Installation==<br />
YAAHM ist Bestandteil der FHEM-Distribution. Die Installation erfolgt über den Standard-Updatemechanisnmus. Zu YAAHM gehören das Modul 95_YAAHM.pm und die Datei yaahm.js in /fhem/www/pgm2<br />
==Definition==<br />
Das YAAHM-Device - hier mit dem Namen ''YYY'' versehen - selbst wird über<br />
define YYY YAAHM<br />
definiert. Diese Definition legt einen versteckten Raum "ProfileRoom" an, welcher über einen Weblink im oberen Menü des Webinterfaces erreichbar ist. <br />
*Der Name dieses Raumes kann durch das Attribut ''hiddenRoom'' geändert werden.<br />
*Dieses Modul verwendet das globale Attribut ''language'' zur Bestimmung der Anzeigedaten (Standard: EN=english). Für deutsche Ausgabedaten muss in FHEM das Attribut <br />
attr global language DE<br />
gesetzt werden. Für dieses Wiki werden die deutschen Ausgabedaten verwendet.<br />
<br />
Beim Anklicken des Begriffes ''Profile'' (eben der genannte Weblink) im oberen Menü des Webinterfaces wird dieser versteckte Raum angezeigt. Er enthält an erster Stelle das YAAHM-Device. Für die Konfiguration dieses Devices siehe den nächsten Abschnitt, für die Bedienung siehe den Abschnitt [Bedienung].<br />
<br />
==Set-Befehle ==<br />
Das YAAHM-Device kennt die folgenden Set-Befehle (''YYY'' ist duch den tatsächlichen Device-Namen zu ersetzen):<br />
set YYY time (after|before)midnight | [before|after]sunrise | [before|after]sunset | morning | noon | afternoon | evening | night | wakeup | sleep<br />
Erzeugt manuell den entsprechenden Event.<br />
set YYY manualnext &lt;timernumber&gt; &lt;time&gt;<br />
set YYY manualnext &lt;timername&gt; &lt;time&gt;<br />
Setzt die manuelle Auslösezeit für das Wochen-Profil (Timer genannt), das durch die Angabe einer fortlaufenden Nummerierung (beginnend bei 0) oder seinen Namen identifiziert wird. Das nicht löschbare Standard-Wochen-Profil ''Wecken'' hat die Timer-Nummer 0, das nicht löschbare Standard-Wochen-Profil ''Schlafen'' hat die Timer-Nummer 1.<br />
set YYY mode normal | party | absence | donotdisturb<br />
Setzt den (Nutzungs-)Modus des SmartHome<br />
set YYY state unsecured | secured | protected | guarded<br />
Setzt den (Sicherheits-)Zustand des SmartHome<br />
set YYY checkstate (0|5|10)<br />
Führe die Überprüfung, ob alle stateDevices (siehe Attribute) für diesen (Sicherheits-)Zustand den richtigen Wert haben, manuell sofort oder mit 5 bzw. 10 Sekunden Verzögerung aus.<br />
set YYY correctstate <br />
Führe für jedes stateDevice (siehe Attribute), das nicht den richtigen Wert hat, das FHEM-Kommando ''set <stateDevice> <sollzustand>'' aus.<br />
set YYY createWeekly &lt;string&gt;<br />
set YYY deleteWeekly &lt;string&gt;<br />
Erzeuge oder entferne ein Wochen-Profil mit dem entsprechenden Namen. Die beiden Standard-Wochen-Profile ''Wecken'' und ''Schlafen'' können nicht gelöscht werden.<br />
set YYY locked |unlocked<br />
Sperre oder entsperre das Überschreiben der Timer, siehe [[#Sperrung | Sperrung]].<br />
set YYY save | restore<br />
Speichere die Daten persistent, oder hole sie aus der betreffenden Datei ''YAAHMFile'' (Achtung für Nutzer der configdb: Das File wird in der Datenbank abgelegt, nicht im Dateisystem).<br />
<br />
==Get-Befehle==<br />
Das YAAHM-Device kennt die folgenden Get-Befehle (''YYY'' ist duch den tatsächlichen Device-Namen zu ersetzen):<br />
get YYY next &lt;timernumber&gt; <br />
get YYY next &lt;timername&gt; <br />
get YYY sayNext &lt;timernumber&gt; <br />
get YYY sayNext &lt;timername&gt; <br />
Holt die nächste Auslösezeit für das betreffende Wochen-Profil (Timer genannt). Mit dem Befehl ''next'' erfolgt das in einem Format, das für textuelle Ausgabegeräte geeignet ist, mit dem Befehl ''sayNext'' in einem Format, das für Sprach-Ausgabegeräte geeignet ist. Die Identifikation des Wochen-Profiles (Timer genannt) erfolgt durch die Angabe einer fortlaufenden Nummerierung (beginnend bei 0) oder seinen Namen. Das nicht löschbare Standard-Wochen-Profil ''Wecken'' hat die Timer-Nummer 0, das nicht löschbare Standard-Wochen-Profil ''Schlafen'' hat die Timer-Nummer 1.<br />
get YYY version<br />
Gibt die Versionsnummer des Moduls zurück<br />
get YYY template<br />
Gibt Vorschläge für Helferfunktionen zurück.<br />
<br />
==Attribute==<br />
*Wenn das Attribut '''timeHelper''' auf einen Perl-Funktionsnamen gesetzt wird, erfolgt automatisch der Eintrag des Perl-Funktionsnamens in das Aktionsfeld für das Tages-Profil und die Aktionsfelder der beiden ersten (=Standard-)Wochenprofile, verbunden mit dem Argument des entsprechenden Events. Einen entsprechenden Vorschlag für eine solche Helferfunktion kann man sich durch ''get YYY template'' anzeigen lassen.<br />
<br />
*Wenn das Attribut '''modeHelper''' auf einen Perl-Funktionsnamen gesetzt wird, erfolgt automatisch die Ausführung dieser Funktion (verbunden mit dem Argument des entsprechenden Events) bei einem Wechsel des (Nutzungs-)Modus. Einen entsprechenden Vorschlag für eine solche Helferfunktion kann man sich durch ''get YYY template'' anzeigen lassen.<br />
*Wenn das Attribut '''modeAuto''' auf 1 gesetzt wird, wechselt der (Nutzungs-)Modus automatisch zu bestimmten Events:<br />
**Die Events ''sleep'' und ''morning'' bewirken, dass der Modus ''Party'' aufgehoben wird und wieder ''Normal'' ist.<br />
**Der Event ''wakeup'' bewirkt, dass der Modus ''Abwesenheit'' aufgehoben wird und wieder ''Normal'' ist.<br />
**Jeder Event bewirkt, dass der Modus ''Nicht Stören'' aufgehoben wird und wieder ''Normal'' ist.<br />
<br />
*Wenn das Attribut '''norepeat''' auf 1 gesetzt wird, sind am gleichen Tage keine Wiederholungen eines (Wochen-)Timers aus dem Wochen-Profil möglich - allerdings werden manuelle Zeiten akzeptiert.<br />
<br />
*Wenn das Attribut '''stateHelper''' auf einen Perl-Funktionsnamen gesetzt wird, erfolgt automatisch die Ausführung dieser Funktion (verbunden mit dem Argument des entsprechenden Events) bei einem Wechsel des (Sicherheits-)Zustands. Einen entsprechenden Vorschlag für eine solche Helferfunktion kann man sich durch ''get YYY template'' anzeigen lassen.<br />
*Wenn das Attribut '''stateAuto''' auf 1 gesetzt wird, wechselt der (Sicherheits-)Zustand automatisch zu bestimmten Events:<br />
**Wenn der Modus ''Normal'' ist und der Zustand ''Nicht gesichert'' ist, wird bei Eintritt der Events ''sleep'' oder ''night'' der Zustand auf ''Gesichert'' gesetzt.<br />
**Wenn der Modus ''Party'' durch den Event ''sleep'' verlassen wurde, und der Zustand ''Nicht gesichert'' ist, wird der Zustand auf ''Gesichert'' gesetzt.<br />
<br />
*Das Attribut '''sunrise''' kann die Werte ''SunRise'' (echter Sonnenaufgang, default), ''CivilTwilightMorning'' (Horizontwinkel -6°), ''NauticalTwilightMorning'' (Horizontwinkel -12°), ''AstroTwilightMorning'' (Horizontwinkel -18°) oder ''CustomTwilightMorning'' (beliebiger Horizontwinkel als Attribut im Astro-Device) annehmen. Damit wird bestimmt, welche Zeit tatsächlich als Sonnenaufgangszeit verwendet wird.<br />
*Das Attribut '''sunset''' kann die Werte ''SunSet'' (echter Sonnenuntergang, default), ''CivilTwilightEvening'' (Horizontwinkel -6°), ''NauticalTwilightEvening'' (Horizontwinkel -12°), ''AstroTwilightEvening'' (Horizontwinkel -18°) oder ''CustomTwilightEvening'' (beliebiger Horizontwinkel als Attribut im Astro-Device) annehmen. Damit wird bestimmt, welche Zeit tatsächlich als Sonnenuntergangszeit verwendet wird.<br />
<br />
*Das Attribut '''stateDevices''' enthält eine kommagetrennte Liste von FHEM-Devices, die jeweils gefolgt werden von den erwarteten ''state''-Readings (getrennt durch ein ":"-Zeichen) für die entsprechenden (Sicherheits-) Zustände, also z.B. für eine Haustür, die in den (Sicherheits-) Zuständen ''Gesichert'', ''Geschützt'' und ''Überwacht'' abgeschlossen sein soll:<br />
HausTuer::locked:locked:locked:locked<br />
**Ob die korrekte Stellung der jeweiligen Devices erreicht wurde, wird periodisch in jeweils '''stateInterval''' Minuten geprüft und in der [[#Zusammenfassung | Zusammenfassung]] angezeigt.<br />
**Für jedes Device, dessen Zustand nicht der Vorgabe entspricht, wird die im Attribut '''stateWarning''' genannte Funktion mit den Argumenten ''Device'', ''Sollzustand'', ''Istzustand'' aufgerufen.<br />
<br />
*'''linkname''' ist der Name für den Link im FHEM-Menü. Default: ''Profile''.<br />
*'''hiddenroom''' ist der Name für den versteckten Raum, der das YAAHM-Device enthält. Default: ''ProfileRoom''<br />
*'''lockstate''' ist der Sperrzustand für das Device, siehe [[#Sperrung | Sperrung]]<br />
*Wenn das Attribut '''simulation''' auf 1 gesetzt wird, werden die Kommandos in den Aktionsfeldern nicht ausgeführt, sondern nur eine Log-Meldung geschrieben.<br />
<br />
*'''holidayDevices''', '''vacationDevices''' und '''specialDevices''' sind attribute, die jeweils eine kommagetrennte Liste von FHEM-Devices enthalten. Diese dürfen vom Typ holiday oder vom Typ calendar sein.<br />
**holidayDevices enthält die Liste der Feiertage (=höchste Tagespriorität)<br />
**vacationDevices enthält die Liste der Schulferien (=dritthöchste Tagespriorität)<br />
**specialDevices enthält eine Liste von Einzelterminen (z.B. der Müllabfuhr)<br />
*Diese Kalenderdaten werden jeweils kurz nach Mitternacht eingelesen und in der [[#Zusammenfassung | Zusammenfassung]] angezeigt.<br />
<br />
=Webinterface=<br />
In diesem Abschnitt wird die Bedienung des Webinterfaces und damit die Konfiguration der Hausautomatik beschrieben. Um sie zu erreichen, klickt man auf den Begriff ''Profile'' im oberen Menü des Webinterfaces.<br />
<br />
Das Webinterface teilt sich in zwei Abschnitte: Die Übersicht (oder toptable), bestehend aus den beiden Flächen '''Aktion''' und '''Zusammenfassung''', sowie die Profilbereiche. Die Übersicht lässt sich auch separat als Weblink '''<YAAHM_Device-Name>_shortlink''' in einen beliebigen FHEM-Raum einbinden.<br />
===Aktion===<br />
[[Datei:action_2.png|600px|]]<br />
<br />
Im Aktionsfeld werden links der aktuelle Mode (=housemode) und der aktuelle (Sicherheits-) Zustand (housestate) angezeigt. Das rote Kreuz beim Zustand besagt, dass nicht alle in dem Attribut '''stateDevices''' definierten FHEM-Devices im korrekten Zustand für diesen (Sicherheits-) Zustand sind. Im Feld rechts daneben befinden sich Buttons zum Wechsel von Mode und Zustand.<br />
<br />
Unten befindet sich für jeden Wochentimer ein Eingabefeld für die 'nächste manuelle Auslösezeit'. Trägt man dort einen Wert ein, der für den heutigen Tag in der Vergangenheit liegt, wird dies als die nächste Auslösezeit am morgigen Tag interpretiert. Liegt der Wert für den heutigen Tag in der Zukunft, wird es als die nächste Auslösezeit am heutigen Tag interpretiert. Die Werte werden im Device gespeichert, sobald man das Feld verlässt.<br />
<br />
===Zusammenfassung===<br />
<br />
[[Datei:summary_2.png|600px|]]<br />
<br />
Hier werden in nicht-editierbarer Form die wichtigsten Daten für den gegenwärtigen und den darauffolgenden Tag angezeigt. <br />
*Rechts oben die Liste der '''stateDevices'''. Wie man hier sieht, ist eine der Türen nicht geschlossen und somit der Zustand ''Gesichert'' nicht vollständig erfüllt. Es ist Aufgabe der externen Helferfunktionen, dies ggf. zu korrigieren.<br />
<br />
<br />
==== Das YAAHM-Widget ====<br />
<br />
[[Datei:YAAHM_widget_1.png|400px|]]<br />
<br />
Dabei handelt es sich um eine dynamisch erzeugte SVG-Datei, die man auch in beliebige eigene Webseiten einbinden kann. Der Aufruf dafür lautet<br />
<IP-Adresse:Port>/fhem/YAAHM_timewidget?name='<Device-Name>'&size='<breite>x<höhe>'<br />
Selbstverständlich kann man das auch in einen eigenen Weblink einbauen.<br />
Markiert sind auf diesem Kreis die ''housetime''-Events ''Sonnenaufgang'', ''Morgen'', ''Mittag'', ''Nachmittag'', ''Abend'', ''Sonnenuntergang'' und ''Nacht''. Die ''Tageszeit'' ist ferner durch einen türkisfarbenen Sektor gekennzeichnet, und Mitternacht ist immer "unten". <br />
<br />
Die gegenwärtige Zeit (beim Aufruf !) wird in rot angezeigt.<br />
<br />
Hinweis: Es ist angedacht, dieses Widget noch sehr viel interaktiver zu machen.<br />
<br />
===Einstellung des Tages-Profils===<br />
<br />
[[Datei:daily_2.png|600 px]]<br />
*Der Startbutton erzeugt einen externen Timer (mit dem DOIF-Modul), der auf die Zeiten der definierten ''housetime''-Events zugreift. <br />
*Wenn dieser Timer erzeugt wurde, zeigt das Webinterface den entsprechenden Link an. Ein grüner Haken bedeutet, dass der Timer aktiv (enabled) ist, wenn er deaktiviert wurde (disabled), wird ein rotes Kreuz angezeigt.<br />
*Die Aktionsfelder enthalten jeweils eine semikolon-getrennte List von FHEM-Befehlen, die bei Eintreten des Timer-Events abgearbeitet wird. <br />
*Wenn das Attribut ''timeHelper'' auf einen Perl-Funktionsnamen gesetzt wird, erfolgt automatisch der Eintrag des Perl-Funktionsnamens in das Aktionsfeld, verbunden mit dem Argument des entsprechenden Events.<br />
<br />
==Einstellung der Wochen-Profile==<br />
[[Datei:weekly_2.png|400 px]]<br />
*Der Startbutton erzeugt externe Timer (mit dem DOIF-Modul), die auf das Reading ''ring_<timer-no>'' zugreifen. Dieses Reading wird jeweils kurs nach Mitternacht auf den korrekten Wert für den entsprechenden Tag gesetzt.<br />
*Wenn diese Timer erzeugt wurden, zeigt das Webinterface den entsprechenden Link an. Ein grüner Haken bedeutet, dass der Timer aktiv (enabled) ist, wenn er deaktiviert wurde (disabled), wird ein rotes Kreuz angezeigt.<br />
*Die Checkboxen Par und Abw geben an, ob das betreffende Wochen-Profil (und damit der Timer) auch in den Modi ''Party'' und ''Abwesenheit'' aktiv ist. Die Checkboxen Fer und Fei geben an, ob das betreffende Wochen-Profil (und damit der Timer) auch an den Tagestypen ''Ferientag'' und ''Feiertag'' aktiv ist.<br />
*Die Aktionsfelder enthalten jeweils eine komma-getrennte List von FHEM-Befehlen, die bei Eintreten des Timer-Events abgearbeitet wird. <br />
*Wenn das Attribut ''timeHelper'' auf einen Perl-Funktionsnamen gesetzt wird, erfolgt bei den beiden ersten (=Standard-) Timern automatisch der Eintrag des Perl-Funktionsnamens in das Aktionsfeld, verbunden mit dem Argument ''wakeup'' oder ''sleep''.<br />
<br />
=Sonstiges=<br />
==Sperrung==<br />
Das Reading ''lockstate'' muss den Wert ''unlocked'' haben, damit durch Anklicken der Start-Buttons für die Timer diese auch gestartet werden. Das ist in der Regel beim ersten Laden des Moduls '''nicht''' der Fall, hierzu muss also das Reading von Hand auf den richtigen Wert gesetzt werden. Dazu muss der Befehl '''set ... unlocked''' ausgeführt werden.<br />
<br />
<br />
==Umstellung Sommer- zu Winterzeit==<br />
Das Reading Astro hat derzeit ein Problem, wenn von Sommer- zu Winterzeit umgestellt wird. Dann verrutscht die Aktualisierung des YAAHM-Geräts in den vorigen Tag und die Termine werden nicht korrekt synchronisiert. Um wieder in den Gleichklang zu kommen, genügt eine einmalige Ausführung des Befehls <br />
set <YAAHM-Device> initialize<br />
Siehe dazu https://forum.fhem.de/index.php?topic=74914.0</div>Andieshttp://wiki.fhem.de/w/index.php?title=Vitotronic_200_(Viessmann_Heizungssteuerung)&diff=34578Vitotronic 200 (Viessmann Heizungssteuerung)2021-01-11T08:07:00Z<p>Andies: /* Links */Viessmann Infos von kathrin</p>
<hr />
<div>{{Todo|Ich bin gerade dabei, die Informationen von dieser Seite zu konsolidieren und modulspezifische Information auf die entsprechenden Modulseiten ([[VCONTROL]], [[VCONTROL300]], [[VCLIENT]]) zu verschieben. Das werde ich in den nächsten Tagen machen, bitte also vorerst keine Änderungen an dieser Seite durch andere Benutzer; bei dringendem Kommentarbedürfnis bitte auf die Diskussionsseite dieser Seite ausweichen). <br>Danke, --[[Benutzer:Ph1959de|Peter]] ([[Benutzer Diskussion:Ph1959de|Diskussion]]) 12:03, 3. Dez. 2019 (CET)}}<br />
{{Randnotiz|RNTyp=r|RNText=Die Verwendung des VCONTROL zur ''Ansteuerung'' eines Heizungssystems kann dieses bei unsachgemäßer Anwendung beschädigen. Für unmittelbare oder mittelbare Folgen, die sich aus dem Nachbau des Interfaces oder der Verwendung der hier zur Verfügung gestellten Information ergeben, übernimmt der Autor keine Haftung.}}<br />
Eine [[Vitotronic 200 (Viessmann Heizungssteuerung)]] wird von FHEM über die folgenden Module unterstützt:<br />
* [[VCONTROL]] 89_...pm sowie das Modul <br />
* [[VCONTROL300]] 89_...pm <br />
* [[vitoconnect]]<br />
* [[VCLIENT]]<br />
Die VCONTROL-Module senden direkt an die Viessmann-Anlage, Modul 89_VCLIENT.pm (hier der [https://forum.fhem.de/index.php/topic,78101.0.html Forenthread]), das auf dem Daemon vcontrold (siehe [https://github.com/openv/vcontrold diesen Link]) aufbaut und mit dem sich, wenn vcontrold läuft, ebenfalls die Anlage auslesen und steuern lässt. 89_VCONTROL.pm und 89_VCONTROL300.pm benötigen den Daemon nicht. Modul vitoconnect geht über das Viessmann-API.<br />
<br />
== Einleitung ==<br />
<br clear=all><br />
{{Infobox Modul<br />
|ModPurpose=Anbindung einer Viessmann Heizung<br />
|ModType=d<br />
|ModCmdRef=VCONTROL, VCONTROL300 und VCLIENT<br />
|ModFTopic=20280<br />
|ModForumArea=Heizungssteuerung/Raumklima<br />
|ModTechName=89_VCONTROL.pm<br />
|ModOwner=adamwit ({{Link2FU|448|Forum}}/[[Benutzer Diskussion:Adam|Wiki]])<br />
}}<br />
Mit Hilfe verschiedener Zusatzgeräte ist es möglich, bei einer Viessmann-Heizung die Temperaturen, Timern, Verbrauch usw. auszulesen und verschiedene Heizungszustände (Heizen, Warm Wasser, Spar Modus, Party Modus) zu steuern.<br />
<br />
== Hardware ==<br />
Bevor die Heizung an FHEM angebunden werden kann, muss eine entsprechende Hardware vorliegen. Die Vitotronic weist zwei LEDs sowie ein eingefrästes Viessmann-V auf, das Bestandteil der Steuerung ist. Eine der beiden Diode dient der Steuerung als Empfangsgerät, während die andere Diode Signale sendet. Durch das eingefräste V kann ein entsprechend konstruiertes Gerät passgenau an die Heizung angeschlossen werden. Derzeit sind folgende Geräte bekannt, die mit der Vitotronic kommunzieren können:<br />
* Optolink-Kabel (Originalbauteil Nr. 7856059, relativ teuer: um 100 €<ref>[https://github.com/openv/openv/wiki/Adapter-Eigenbau openv-Selbstbau-Anleitung]</ref> bzw. ca. 60 €<ref>[https://www.wolf-online-shop.de/Viessmann-Aschlussleitung-USB-Optolink-7856059::59899.html?gclid=EAIaIQobChMIzt-etMH31gIVncmyCh1Q1wSQEAQYASABEgLdrvD_BwE Wolf Online Shop]</ref>)<br />
* selbstgebaute Geräte (zum Teil kommerziell angeboten, Eigenbau ist sehr preiswert - erfordert aber Lötmaterialien)<br />
<br />
Der Eigenbau wird auf der eigens dazu errichteten Webseite [https://github.com/openv/openv/wiki/ openv] genauer beschrieben. <br />
Man muss sich beim Eigenbau insbesondere mit der Frage befassen, über welche Schnittstelle die Hardware dann mit FHEM kommuniziert. Derzeit sind folgende Schnittstellen realisiert, deren Einbindung nach Aussage verschiedener Forenteilnehmer auch geglückt ist:<br />
* USB<br />
* seriell (Anschluss an RPi, dort RxTx)<br />
* WLAN<br />
* LAN<br />
Die serielle Schnittstelle kann mit Hilfe des Programms [http://ser2net.sourceforge.net/ ser2net] auch auf eine LAN-Schnittstelle gemappt werden. Derzeit (Herbst 2017) entwickelt der Forumsteilnehmer PeMue ein allgemeines Modul, das sowohl per WLAN, USB als auch seriell an die Heizung angeschlossen werden kann: {{Link2Forum|Topic=51431|LinkText=Optolink Adapterplatine}}.<br />
<br />
Bevor die Software angeschlossen wird, sollte man sich Informationen bezüglich der verwendeten Heizung sowie der entsprechenden Steuerung besorgen. Diese Angaben müssen bei der Definition des Gerätes sowie in der Konfigurationsdatei in FHEM angegeben werden.<br />
<br />
== Software: Einbindung in FHEM ==<br />
Es existieren momentan (2017) drei verschiedene Module, die eine Einbindung der Heizung in FHEM sicherstellen: <br />
# 89_VCONTROL.pm, <br />
# 89_VCONTROL300.pm <br />
# 89_VCLIENT.pm<br />
Das zweite Modul scheint eine schnellere Kommunikation zu ermöglichen und wird derzeit (Herbst 2017) aktiv weiterentwickelt. <br />
<br />
Das dritte Modul setzt einen laufenden vcontrold-Daemon voraus, der die Kommunikation mit Viessmann übernimmt (siehe dazu diesen [https://forum.fhem.de/index.php/topic,78101.0.html Foreneintrag]). <br />
<br />
Die Definition des Gerätes erfolgt bei den beiden ersten Modulen typischerweise wie folgt.<br />
{{Randnotiz|RNText='''Weiterentwicklung'''<br />
In {{Link2Forum|Topic=51167|LinkText=diesem Forenthread}} wird über Korrekturen und Bereinigungen im Modul berichtet. }}<br />
defmod <name> VCONTROL300 <IP-Adresse>:3002 /opt/fhem/FHEM/VScotHO1_300.cfg 300 kw<br />
In dem hier vorliegenden Fall wird das Modul 89_VCONTROL300.pm verwendet. Dieses kommuniziert mit einer LAN-Schnittstelle auf Port 3002 an der angegebenen IP-Adresse mit der Hardware. Im Fall eines USB-Anschluss muss der entsprechende Pfad auf die USB-Schnittstelle angegeben werden. Es wird alle 300 Sekunden abgefragt, das verwendete Protokoll lautet kw (eine andere Option besteht darin, das neuere Protokoll 300 zu verwenden). <br />
<br />
<br />
== Konfiguration VCONTROL und VCONTROL300 ==<br />
<br />
Zur Konfiguration wird die Datei /opt/fhem/FHEM/VScotHO1_300.cfg verwendet. Details zu dieser Datei und ihrer Funktion werden im nächsten Abschnitt erläutert.<br />
<br />
Um die Heizung mit FHEM zu verbinden, müssen die Daten zwischen der Heizungssteuerung und dem Perl-Server ausgetauscht werden. Die Werte in der Heizungssteuerung werden an speziellen Speicheradressen (die durch vierstellige Hexadezimalzahlen beschrieben werden) gesichert, im Viessmann-device befinden sich die entsprechenden Werte dagegen in Readings. Beide Werte müssen nun eindeutig einander zugeordnet werden. Diese Zuordnung gelingt durch die im define genannte Konfigurationsdatei *.cfg, die sowohl die Speicheradressen als auch die Readingsnamen enthält. Die Datei ist zeilenweise aufgebaut (je Zeile eine Zuordnung). Dabei wird noch zwischen Lesezugriff und Schreibzugriff unterschieden, da möglicherweise verschiedene Speicheradressen involviert sind.<br />
<br />
Informationen zu den Speicheradressen findet man ebenfalls im Forum https://github.com/openv/openv/issues, in diesem Forum sind die Adressen teilweise als XML-Datei hinterlegt und müssen entsprechend übertragen werden. In der im Forum geposteten Datei [http://forum.fhem.de/index.php?action=dlattach;topic=20280.0;attach=17498 Viessmann-Software-Config.zip] sind XML Dateien der original Viessmann-Software enthalten. Diese können nützlich sein, um Adressen für den eigenen Heizungstyp zu finden.<br />
<br />
=== Daten lesen ===<br />
Die Konfiguration geschieht mit Hilfe einer cfg-Datei, die von FHEM eingelesen wird. Die Einträge in dieser Datei sind von folgendem Format (wir beschränken uns hier auf das Modul VCONTROL300, für das Modul VCONTROL sind die Einträge analog aufgebaut - dort ist allerdings ein etwas erweitertes Adressformat zu verwenden):<br />
POLL, <adresse>, <parse-methode>, <divisor>, <reading>, <kumulationsmethode><br />
Dies ist wie folgt zu verstehen. POLL zeigt an, dass Daten geholt werden. <adresse> ist die interne Viessmann-Adresse, die die zu holende Variable beherbergt. Dies ist typischerweise eine Hexadezimalzahl mit vier Stellen; beispielsweise findet man unter der Adresse 00F8 die Gerätekennung. Zum Teil können diese Adressen aus Dokumentation bezogen werden, ein Teil der Adressen ist auf der Webseite [https://github.com/openv/openv/wiki/Adressen von openv] dokumentiert. Nicht alle Adressen sind dabei korrekt, hier muss viel probiert werden.<br />
<br />
<divisor> beschreibt, ob die Größe durch eben diesen Divisor dividiert werden soll (Temperaturangaben sind etwa in Zehntelgrad), <reading> nennt den Namen des FHEM-Readings. <kumulationsmethode> kennt die Einträge - (nicht kumulieren) und "day" (über den Tag hinweg addieren). Im letzten Fall werden dann jeweils nach Mitternacht die Werte des letzten Tages ebenfalls als Readings in das Device eingetragen; bei den Readingnamen wird dann jeweils DayStart,Today und LastDay angehangen. Diese Bezeichnungen können mit Readings des Devices angepasst werden.<br />
<br />
<parse-methode> hat die folgenden Auswahlmöglichkeiten<br />
* "1ByteS": Größe 1 Byte mit Vorzeichen, <br />
* "2ByteS": Größe 2 Byte mit Vorzeichen<br />
* "2ByteU": Größe 2 Byte ohne Vorzeichen <br />
* "2ByteU_1stByte": Größe 2 Byte ohne Vorzeichen, 1.tes Byte (allerdings im Thread nicht angegeben)<br />
* "2ByteU_2ndByte": Größe 2 Byte ohne Vorzeichen, 1.tes Byte <br />
* "1ByteH": Größe 1 Byte, vermutlich (im Thread nicht angegeben) hexadezimalkodiert<br />
* "2ByteH": Größe 2 Byte, vermutlich (im Thread nicht angegeben) hexadezimalkodiert<br />
* "2BytePercent": nicht implementiert<br />
* "4Byte": Größe 4 Byte<br />
* "mode": einer der beiden Werte on, off<br />
* "date": 8 Byte Datumswert (Beispiel: Do,28.09.2017 17:01:12)<br />
* "timer": 8 Byte Timer Wert<br />
<br />
Alle Größen, die mit timer kodiert sind, müssen mit einem expliziten Get-Befehl geholt werden und werden nicht automatisch gepollt. Ein User berichtet, dass diese Timerzeiten nur geholt werden konnten, nachdem das automatische Ausfüllen ("Mo-Fr automatic") in der Steuerung ausgeschaltet und jedem Tag ein individueller Wert zugewiesen wurde.<br />
<br />
Ein Beispiel soll einen Eintrag in der cfg-Datei beschreiben:<br />
POLL, 2306, 1ByteU, 1, Temperatur_Haus , -<br />
Die Viessmann-Steuerung enthält an der Speicheradresse 0x2306 den Wert für die Solltemperatur des Hauptheizkreises (oft als M1 bezeichnet). Dieser Wert hat die Größe eines unsignierten Bytes (deshalb 1ByteU). Der Wert soll in FHEM im Reading Temperatur_Haus gespeichert werden. Es soll nur der aktuelle Wert gespeichert werden, die Werte werden über den Tag hinweg nicht addiert/kumuliert (deshalb der Strich am Ende).<br />
<br />
=== Daten schreiben ===<br />
Will man Daten senden, so ist folgendes Kommando zu verwenden<br />
SET, <adresse>, <adresstyp>, <multiplikator>, <setname>, <nextset oder day><br />
Dies ist wie folgt zu verstehen. SET zeigt an, dass Daten gesendet werden. <adresse> ist die interne Viessmann-Adresse (oft, aber nicht immer, sind die Adressen der SET-Kommandos read/write; hier muss man in den Dokumentationen nachschauen). Wieder ist dies eine Hexadezimalzahl mit vier Stellen. Adresstyp entspricht der <parse-methode> oben und gibt an, ob es sich um eine 2Byte-, eine 1Byte- oder was auch immer -Adresse handelt. Als <multiplikator> wird oft 1 verwendet; setzt man hier eine Zahl ein, so wird der zu sendende Wert mit eben diesem Multiplikator multipliziert. Beim Kennwort "mode" und "state" für <multiplikator> können auch Zustände gesendet werden (unklar, wie genau). <setname> ist der Name, mit dem in FHEMWEB auf den Wert zugegriffen wird. <br />
<br />
Dazu ein Beispiel. Im Reading "Temperatur_Haus" wird die Soll-Temperatur des Hauses gespeichert, die dazugehörige Kodierung sei 2306. Der entsprechende POLL-Eintrag in der *.cfg würde dann lauten<br />
POLL, 2306, 1ByteU, 1, Temperatur_Haus , -<br />
(sowohl die Adresse als auch die Übergabeform der Daten, hier 1ByteU, muss natürlich korrekt sein). Nun soll innerhalb von FHEM durch ein Befehl der Form<br />
set <Viessmanndevice> Temperatur_Haus 25 <br />
versucht werden, die Temperatur auf 25 Grad einzustellen. Damit dies möglich ist, muss in der *.cfg folgende Zeile stehen (auch hier gilt: die Adresse muss korrekt sein und es muss möglich sein, in die Steuerung zu schreiben) <br />
SET, 2306, 1ByteU, 1, Temperatur_Haus, <nextset oder day><br />
Nextset bedeutet, dass nach diesem SET-Befehl unmittelbar ein weiterer Setbefehl ausgelöst wird (und zwar genau der, der an dieser Stelle zu finden ist). Day wird nur dann verwendet, wenn der Adresstyp "time" war. In diesem Fall gibt day an, um welchen Wochentag, der einzustellen ist, es sich handelt. Hier sind nur Einträge der Form MO, DI bis SO möglich. Beispielsweise bedeutet<br />
SET, 2028 , timer, 1, TIMER_Haus_SA , SA<br />
dass das Reading TIMER_Haus_SA die Zeiten für die Heizung Samstags enthält, es sich um den Adresstyp timer handelt, die Daten in der Adresse 2028 kodiert sind und die von FHEM gesendeten Daten für Samstag festgeschrieben werden. Der FHEM-Befehl sähe dann so aus<br />
set Heizung TIMER_Haus_SA 08:00,23:00,--,--,--,--,--,--,<br />
Auslesen kann man die Daten dann mit<br />
POLL, 2028, timer, 1 , TIMER_Haus_SA , -<br />
<br />
Etwas umständlicher wird es, wenn eine Auswahlmöglichkeit mit vordefinierten Werten angegeben werden soll. Der Betriebszustand einer Vitotronic 100 HO1A beispielsweise kann nur die Werte 0 (nur_Warmwasser), 3 (Normalbetrieb) und 5 (Frostschutz) annehmen. Die entsprechende Adresse sei 3301. Ziel ist eine Dropdown-Liste in FHEM. Dies muss dann wie folgt in der cfg beschrieben werden<br />
SET, 3301, mode, Betriebsart_Fussb , - <br />
SET, 330100, 1ByteU, 1, nur_Warmwasser , -<br />
SET, 330103, 1ByteU, 1, Normalbetrieb , -<br />
SET, 330105, 1ByteU, 1, Frostschutz , - <br />
<br />
Einige User haben bereits Ihre Heizungen mit der Hilfe diese Moduls angebunden:<br />
* [http://forum.fhem.de/index.php?action=dlattach;topic=20280.0;attach=20811 V200KW1.cfg]<br />
* [http://forum.fhem.de/index.php?action=dlattach;topic=20280.0;attach=21727 VPlusHO1.cfg]<br />
* [http://forum.fhem.de/index.php?action=dlattach;topic=20280.0;attach=21728 VScotHO1.cfg]<br />
* [http://forum.fhem.de/index.php?action=dlattach;topic=20280.0;attach=22863 V200WO1B.cfg]<br />
* [http://forum.fhem.de/index.php?action=dlattach;topic=20280.0;attach=23767 V300KW3_V0002.cfg]<br />
* [https://forum.fhem.de/index.php/topic,67744.msg692581.html#msg692581 Vitotronic 100 HO1A]<br />
* besonders umfangreiche Materialien befinden sich [https://forum.fhem.de/index.php/topic,20280.msg611057.html#msg611057 in diesem Thread]<br />
<br />
<br />
== Konfiguration VCLIENT ==<br />
VCLIENT basiert auf dem (extern) laufenden Daemon vcontrold. <br />
Die Viessmann-Heizung wird ausschließlich durch vcontrold kontrolliert. Dieses Modul verbindet sich nur mit vcontrold und stellt gewissermaßen einen vcontrold-Klienten für FHEM dar. Wenn ein Befehl nicht das tut, was er soll, liegt es an vcontrold, nicht aber an VCLIENT. Zur Installation und Inbetriebnahme von vcontrold sowie dem dazugehörigen Optolink-Kabel siehe die Webseite https://github.com/openv/openv<br />
<br />
=== Konfigurationsdatei ===<br />
VCLIENT setzt eine Konfigurationsdatei voraus. In dieser Datei befinden sich zeilenweise Einträge. Jeder Eintrag ordnet einem vcontrold -Befehl einen Readingnamen zu. Wird der in der Zeile genannte Befehl ausgeführt, so wird das durch vcontrold erhaltene Ergebnis in das entsprechende Reading geschrieben. Eine typische Zeile in der Konfigurationsdatei sieht wie folgt aus:<br />
###### VCLIENT-Konfigurationsdatei #########<br />
#Dies ist eine Kommentarzeile<br />
getTempA Aussentemperatur<br />
getTempBrennerstarts Brennerstarts<br />
getTempBrennerstarts BrennerstartsBisGestern daily<br />
#bisher standen get-Befehle da, nun folgen set-Befehle<br />
getTimerWWMo Warmwasser_1Montag manually<br />
setTimerWWMo WW_1Mo_spaet 08:00-10:00|12:00-12:30|| <br />
setTempWW WarmwasserTemp 70,65,60,55<br />
<br />
'''Get-Befehle:''' Zuerst muss der vcontrold-Befehl in der Zeile stehen, er muss das Wort get enthalten (zB getTempWW). Die Rückgabe des vcontrold-Befehls "getTempA" wird dann in das VCLIENT-Reading Aussentemperatur geschrieben. Bitte für jeden Befehl eine eigene Zeile verwenden. Soll ein Kommando nur einmal am Tag ausgeführt werden, muss als weiteres (drittes) Wort in der cfg-Datei "daily" stehen. Soll ein Kommando nur manuell ausgeführt werden, so muss als weiteres (drittes) Wort in der cfg-Datei "manually" stehen. Das Format von Zeitbefehlen (so genannte timer) wird automatisch erkannt. <br />
<br />
'''Set-Befehle:''' Zuerst muss der vcontrold-Befehl in der Zeile stehen, er muss das Wort set enthalten (zB setTempWW). Dann erfolgt der Name, der im FHEM-Set-Befehl auftauchen soll, hier WarmwasserTemp (der komplette FHEM-Befehl hieße dann set <name> WarmwasserTemp 65). Zuletzt stehen die möglichen Auswahlen einer dropdown-Liste in der Zeile. Es ist unabdingbar, dass die auszuwählenden Werte kommagetrennt und ohne Leerzeichen geschrieben werden. Timer-Befehle machen hier eine Ausnahme. Wieder erfolgt zuerst der vcontrold-Befehl (hier setTimerWWMo), danach folgt der Befehl, mit dem die Angaben in FHEM ausgelöst werden (hier wäre das set <name> WW_1Mo_spaet). In FHEM werden die Zeiten aber nicht eingegeben, dies geschieht vielmehr in der cfg-Datei. Dazu werden die Zeiten, die an die Anlage zu senden sind, in der Datei eingetragen. Es muss sich um eine gerade Anzahl von Zeitangaben, höchstens acht, handeln. Die Zeitangaben sind durch genau drei Trennzeichen | voneinander zu separieren. Die Zeiten wiederum sind durch Angaben HH:MM-HH:MM zu notieren. Dabei sind nur Minuten zulässig, die Vielfache von 10 sind; weiter müssen die Zeitangaben von links nach rechts wachsen und dürfen nicht fallen. Die Zeitangaben wie auch der Set-Befehl dürfen keine Leerzeichen enthalten.<br />
<br />
=== Definition ===<br />
Das Gerät wird wie folgt definiert<br />
define <name> VCLIENT <host> <port> <configfilename> <interval> <br />
<br />
<host> ist der Host, auf dem vcontrold läuft. <br />
<port> ist der Port, unter dem vcontrold ansprechbar ist (sehr oft 3002). <br />
<configfilename> ist die vorbereitete Konfigurationsdatei, siehe hierzu oben. <br />
<interval> ist die Zeitspanne in Sekunden, in denen regelmäßige Abfragen erfolgen sollen. Der Wert 0 (nur manuelle Abfragen) ist möglich. <br />
<br />
=== Set-Kommandos ===<br />
set <name> reload_command_file <configfilename> <br />
Ändert den Namen und/oder Pfad der Konfigurationsdatei. Die Datei muss existieren, sonst erfolgt eine Fehlermeldung (vollständigen Pfad angeben).<br />
<br />
set <name> <vcontrold/FHEM-Kommando> args <br />
Es können mit dem set-Befehl auch vcontrold-Kommandos ausgeführt werden. Diese Kommandos müssen vorab in der cfg-Konfigurationsdatei definiert werden. Schaut man auf das obige Beispiel einer Konfigurationsdatei, so würde ein FHEM-Befehl der Form set <name> WarmwasserTemp 70 intern an die Heizung bzw vcontrold den Befehl setTempWW 70 absetzen, der dann die Warmwassertemperatur auf 70 Grad Celsius setzt. Im Reading last_set_cmd muss ein OK erscheinen, wenn der Befehl erfolgreich ausgeführt wurde. Analog können komplexere Zeitangaben für Timer gesetzt werden. Leider ist es momentan wohl so, dass beim Setzen von timer-Angaben vcontrold eine Fehlermeldung zurück gibt - obwohl die Angaben korrekt übertragen wurden.<br />
<br />
=== Get-Kommandos ===<br />
get <name> update <br />
Führt die in der Konfigurationsdatei genannten vcontrold-Befehle aus und schreibt die Ergebnisse in die dort angegebenen Readings. Sind diese nicht vorhanden, so werden sie angelegt.<br />
update_manually<br />
<br />
get <name> update_manually <br />
Führt die in der Konfigurationsdatei genannten vcontrold-Befehle für sämtliche manuellen Einträge aus und schreibt die Ergebnisse in die dort angegebenen Readings. Sind diese nicht vorhanden, so werden sie angelegt.<br />
<br />
=== Attribute ===<br />
<br />
attr <name> <timeout> 1 <br />
Jeder Zugriff auf einen entfernten Host ist nicht blockierend, muss aber dennoch die Möglichkeit eines Abbruches beinhalten (falls partout keine Antwort erfolgt). Timeout beschreibt, nach wie viel Sekunden die Abfrage erfolglos abgebrochen werden soll. In einem solchen Fall wird auch die gesamte Abfrageliste beendet. Beachten Sie: Ein zu kurzer Timeout ist problematisch, weil dann uU noch keine Rückmeldung von der Heizung erfolgen konnte. Voreinstellung (wenn kein Attribut gesetzt) ist 1 Sekunde.<br />
<br />
attr <name> <internal_update_interval> 0.1<br />
Hier handelt es sich um ein Attribut, das nur verwendet werden sollte, wenn trotz intensiver Suche immer noch Probleme bei der Ansteuerung der Anlage auftreten. Normalerweise ist es nicht nötig, dieses Attribut zu setzen.<br />
<br />
Zwei verschiedene Kommandos können nicht gleichzeitig an die Anlage geschickt werden, weil dann bei einer Antwort nicht klar ist, auf welche Frage sich das Ergebnis bezieht. Dies wird intern so umgesetzt, indem VCLIENT darauf achtet, dass zwischen zwei Kommandos eine kleine Zeitspanne liegt. Diese Zeitspanne ist nun ein genaues Vielfaches von $internal_update_interval. $internal_update_interval ist intern auf 0.1 Sekunden eingestellt; dies sollte normalerweise genügen. $internal_update_interval muss größer als Null sein. Ein größerer Wert führt zu einer längeren Abfragedauer für alle Readings, ein kleinerer Wert verkürzt unter Umständen die gesamte Abfragedauer, könnte aber auch zu Instabilitäten führen.<br />
<br />
== Links ==<br />
* Forenthema zur {{Link2Forum|Topic=51167|LinkText=Weiterentwicklung}} des Moduls<br />
* neueste Version: [https://forum.fhem.de/index.php?action=profile;area=showposts;sa=attach;u=16142 hier]<br />
* Forenthema/-umfrage {{Link2Forum|Topic=51431|LinkText=Optolink Adapterplatine}}<br />
* [http://www.haustechnikdialog.de/SHKwissen/341/Heizkurve Heizkennlinie erläutert]<br />
* [https://www.haustechnikdialog.de/Forum/t/115412/FAQ-Vitotronic-200 wichtige Infos zu Viessmann]<br />
<br />
== Quellen ==<br />
<references /><br />
<br />
[[Kategorie:Heizungssteuerung]]<br />
[[Kategorie:Other Components]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Modul_Astro&diff=34324Modul Astro2020-12-02T15:58:05Z<p>Andies: /* Mondphasen */ https://forum.fhem.de/index.php/topic,73951.msg1106308.html#msg1106308</p>
<hr />
<div>{{<br />
Infobox Modul<br />
|ModPurpose=Das Modul stellt astronomische Daten zur Verfügung (etwa Sonnenauf- und Untergänge)<br />
|ModType=h<br />
<!-- |ModCategory= (noch?) nicht verwendet --><br />
|ModCmdRef=Astro<br />
|ModForumArea=Unterstuetzende Dienste<br />
|ModTechName=95_Astro.pm<br />
|ModOwner=Prof. Dr. Peter A. Henning<br />
}}<br />
Diese Seite beschreibt die Konfiguration und Verwendung des Moduls 95_Astro.pm.<br />
<br />
=Allgemeines=<br />
Das Modul ''95_Astro.pm'' stellt astronomische Daten zur Verfügung (etwa Sonnenauf- und Untergänge). Die Berechungen sind für den Zeitraum 1900 - 2100 gültig.<br />
<br />
Ein SVG-Bild der gegenwärtigen Mondphase gibt es unter dem Link<br />
&lt;ip addresse von fhem&gt;/fhem/Astro_moonwidget?name='&lt;device name&gt;'<br />
Optionale Web-Parameter sind <br />
[&amp;size='&lt;width&gt;x&lt;height&gt;']<br />
[&amp;mooncolor=&lt;color&gt;]<br />
[&amp;moonshadow=&lt;color&gt;]<br />
<br />
<li>Calculations are only valid between the years 1900 and 2100</li><br />
<li>Attention: Timezone is taken from the local Perl settings, NOT automatically defined for a location</li><br />
<li>This module uses the global attribute <code>language</code> to determine its output data<br/><br />
(default: EN=english). For German output set <code>attr global language DE</code>.</li><br />
<li>The time zone is determined automatically from the local settings of the <br/><br />
operating system. If geocordinates from a different time zone are used, the results are<br/><br />
not corrected automatically.<br />
==Definition==<br />
Ein Astro-Device wird definiert durch <br />
define <name> Astro<br />
Dieses Modul verwendet das globale Attribut language zur Bestimmung der Anzeigedaten (Standard: EN=english). Für deutsche Ausgabedaten muss in FHEM das Attribut<br />
attr global language DE<br />
gesetzt werden. <br />
==Position des Beobachters==<br />
Das Modul verwendet verschiedene Attribute zur Bestimmung der Beobachterdefinition, die im ''global''-Device von FHEM abgelegt sein sollten:<br />
attr global longitude &lt;value&gt; <br />
attr global latitude &lt;value&gt; <br />
attr global altitude &lt;value&gt;<br />
Die beiden ersten Angaben erfolgen in Dezimalgrad, die dritte Angabe ist die Höhe in Metern über dem Meeresspiegel. Globale Definitionen dieser Werte werden nur verwendet, wenn keine lokalen Attribute mit diesen Namen vorhanden sind (siehe unten).<br />
<br />
Die Zeitzone wird nicht automatisch eingestellt, sondern aus der lokalen Perl-Installation bezogen.<br />
<br />
==Ausgabedaten==<br />
Readings mit dem Präfix <i>Sun</i> beziehen sich auf die Sonne, solche mit dem Präfix <i>Moon</i> auf den Mond.<br />
*<i>Age</i> = Winkel (in Dezimalgrad) des Körpers auf seiner Bahn<br />
*<i>Az,Alt</i> = Azimuth und Höhe (in Dezimalgrad) des Körpers über dem Horizont<br />
*<i>Dec,Ra</i> = Deklination und Rektaszension (in HH:MM) der Position des Körpers<br />
*<i>Lat,Lon</i> = geografische Breite und Länge der Position des Körpers<br />
*<i>Diameter</i> = Virtueller Durchmesser des Körpers in Bogenminuten<br />
*<i>Distance,DistanceObserver</i> = Entfernung (in km) des Körpers zum Erdmittelpunkt oder zum Beobachter <br />
*<i>PhaseN,PhaseS</i> = Nummerischer Wert und Stringwert für die Phase des Körpers</li><br />
*<i>Sign</i> = Tierkreiszeichen des Körpers auf seiner Bahn<br />
*<i>Rise,Transit,Set</i> = Zeiten (in HH:MM) für Aufgang, höchsten Punkt (Transit) und Untergang des Körpers<br />
<br />
Readings mit dem Präfix <i>Obs</i> beziehen sich auf den Beobachter<br />
<br />
Weitere Readings umfassen<br />
*<i>Date,Dayofyear</i> = Datum<br />
*<i>JD</i> = Julianisches Datum<br />
*<i>Season,SeasonN</i> = Stringwert und nummerischer Wert für die Jahreszeit<br />
*<i>Time,Timezone</i> raten Sie mal...<br />
*<i>IsDST</i> = 1 wenn Sommerzeit gilt, 0 sonst<br />
*<i>GMST,LMST</i> = Greenwich und Local Mean Sidereal Time (in HH:MM)<br />
<br />
=Bedienung=<br />
==Get==<br />
Achtung: Die Ergebnisse von Get-Aufrufen werden nicht in die Readings geschrieben, sondern nur die Ergebnisse zyklischer Updates. Das dient dazu, schnell und ohne Readings spezielle Datenwerte (etwa für andere Zeiten oder Orte) zu generieren. Möglichkeiten für Aufrufe:<br />
get &lt;name&gt; json [&lt;reading&gt;]<br />
get &lt;name&gt; json [&lt;reading&gt;] YYYY-MM-DD<br />
get &lt;name&gt; json [&lt;reading&gt;] YYYY-MM-DD HH:MM:[SS]<br />
liefert JSON-Code für den kompletten Datensatz oder nur einen Datenwert der astronomischen Daten entweder für die gegenwärtige Zeit, oder für ein Datum und eine Zeit im Argument. <br />
get &lt;name&gt; text [&lt;reading&gt;]<br />
get &lt;name&gt; text [&lt;reading&gt;] YYYY-MM-DD<br />
get &lt;name&gt; text [&lt;reading&gt;] YYYY-MM-DD HH:MM:[SS]<br />
liefert Text für den kompletten Datensatz oder nur einen Datenwert der astronomischen Daten entweder für die gegenwärtige Zeit, oder für ein Datum und eine Zeit im Argument. <br />
get &lt;name&gt; version <br />
zeigt die aktuelle Modulversion an.<br />
<br />
==Attribute== <br />
attr &lt;name&gt; interval &lt;interval&gt;<br />
Update-Interval in Sekunden. Default sind 3600 Sekunden, ein Wert 0 verhindert das periodische Update.<br />
Das Astro-Module verwendet verschiedene Attribute zur Bestimmung der Beobachterdefinition, die entweder im ''global''-Device von FHEM abgelegt sein sollten (siehe oben), oder als lokale Attribute gespeichert sind:<br />
attr &lt;name&gt; longitude &lt;value&gt; <br />
attr &lt;name&gt; latitude &lt;value&gt; <br />
attr &lt;name&gt; altitude &lt;value&gt;<br />
Die beiden ersten Angaben erfolgen in Dezimalgrad, die dritte Angabe ist die Höhe in Metern über dem Meeresspiegel. <br />
attr &lt;name&gt; horizon &lt;value&gt;<br />
Nutzerdefinierter Horizontwinkel in Dezimalgrad, Defaulwert 0°<br />
<br />
==Readings Mondphasen== <br />
Die Readings zu den Mondphasen<br />
MoonPhaseI 5 2020-12-01 17:56:32<br />
MoonPhaseN 0.96 2020-12-02 10:00:20<br />
sind wie folgt zu lesen. PhaseN gibt das Mondalter in Radians an, Vollmond entspricht Pi (3,14). PhaseI entspricht einer Ganzzahl von 0 bis 7 für das Mondalter.<br />
<br />
=Verwendung ohne Astro-Device=<br />
Es ist nicht notwendig, für die gelegentliche Verwendung der astronomischen Daten ein Device zu definieren. Es muss lediglich das Modul geladen werden, z.B. durch den Perl-Code<br />
LoadModule("Astro");<br />
Die Verwendung von ''require'' wird nicht empfohlen, da je nach Konstellation dabei Warnmeldungen im Logfile ausgegeben werden können.<br />
Dann kann man z.B. durch den Code<br />
my $somehash<br />
Astro_Get( $somehash,"somehash","text", "SunRise","2019-12-24");<br />
den Sonnenuntergang an Heiligabend 2019 berechnen.<br />
<br />
Die Funktion ''Astro_Get'' bekommt im ersten Argument eine hash-Referenz übergeben, die auch leer sein kann. Wenn sie aber nicht leer ist, versucht das Modul, sich die notwendigen Attribute aus diesem Hash zu holen (etwa geografische Länge und Beite). Es kann z.B. ein beliebiges Dummy-Device angelegt werden, sagen wir mit dem Namen "Blabla". Gibt man diesem als Attribut einen Horizontwinkel, oder andere Geodaten, kann man mit <br />
Astro_Get( $defs{"Blabla"},"Blabla","text", "CustomTwilightEvening","2019-12-24");<br />
den Sonnenuntergang für diesen Horizontwinkel erhalten. Natürlich geht auch<br />
Astro_Get( $defs{"global"},"global","text", <reading>,<datum> );</div>Andieshttp://wiki.fhem.de/w/index.php?title=SUNRISE_EL&diff=34231SUNRISE EL2020-11-15T09:29:17Z<p>Andies: /* Links */berechnungsgrundlage eingefügt</p>
<hr />
<div>{{SEITENTITEL:SUNRISE_EL}}<br />
{{Infobox Modul<br />
|ModPurpose=Funktionen für Sonnenstandsabhängige Aktionen <br />
|ModType=h<br />
<!-- |ModCategory=?? --><br />
|ModCmdRef=SUNRISE_EL<br />
|ModForumArea=Automatisierung<br />
|ModTechName=99_SUNRISE_EL.pm<br />
|ModOwner=rudolfkoenig ({{Link2FU|8|Forum}}] / [[Benutzer Diskussion:Rudolfkoenig|Wiki]])<br />
}}<br />
<br />
Das Hilfsmodul [[SUNRISE_EL]] bietet Funktionen, um Aktionen abhängig von Sonnenauf- und -untergangszeiten durchzuführen. ''SUNRISE_EL'' ist kein [[Device]] im klassischen Sinne, sondern ein Modul, das nicht definiert werden muss, sondern immer zur Verfügung steht (da es automatisch geladen wird, wenn die korrespondierende Datei im <code>FHEM/</code>-Verzeichnis liegt. D.h. ''SUNRISE_EL'' muss nicht definiert werden um die angebotenen Funktionen verwenden zu können.<br />
<br />
== Voraussetzungen ==<br />
In der [[Konfiguration]] (fhem.cfg) muss der gewünschte Standort definiert werden, da der Sonnenauf- und -untergang nicht nur vom Datum, sondern auch vom Längen- und Breitengrad des Standortes abhängig sind. Dazu sind die folgenden Definitionen erforderlich:<br />
:<code>attr global latitude 52.51626 </code><br />
:<code>attr global longitude 13.37778 </code><br />
und zwar in genau dieser Schreibweise. Die Koordinaten können entweder mit Hilfe eines GPS-Systems oder über einen entsprechenden Internet-Dienst ermittelt werden.<br />
<br />
Als Internet-Dienst eignet sich beipielsweise [https://support.google.com/maps/answer/18539?source=gsearch&hl=de Google Maps-Hilfe (Breiten- und Längengrad finden oder eingeben)] oder [http://www.openstreetmap.org/#map=12/52.51626/13.37778 OpenStreetMap]. Die Werte ''latitude'' und ''longitude'' können aus der URL abgelesen werden. In diesem Beispiel ''latitude'' 52.51626 und ''longitude'' 13.37778 (Brandenburger Tor in Berlin).<br />
<br />
== Funktionen ==<br />
Das Modul SUNRISE_EL stellt die folgenden Funktionen zur Verfügung:<br />
* sunrise / sunset geben die absolute Zeit des nächsten Sonnenauf- bzw. -untergangs zurück, wobei 24 Stunden addiert werden, sofern das entsprechende Ereignis am nächsten Tag stattfindet<br />
* sunrise_rel / sunset_rel geben die relative Zeit bis zum nächsten Sonnenauf- bzw. -untergang zurück<br />
* sunrise_abs / sunset_abs geben die absolute Zeit für den aktuellen Tag zurück<br />
Diese Funktionen können jeweils mit einem speziellen und drei weiteren (optionalen) Parametern aufgerufen werden: <br />
: <code>...(offset,min,max)</code><br />
: mit der Bedeutung<br />
:* Horizont; nur einer der Werte REAL, CIVIL, NAUTIC, ASTRONOMIC (in genau dieser Schreibweise) bzw. HORIZON= ist erlaubt<br />
:* offset = Sekunden (Ganzzahl), die auf die Zeit addiert werden<br />
:* min = frühester Zeitpunkt (in Stunden:Minuten - hh:mm), der zurückgegeben werden soll<br />
:* max = spätester Zeitpunkt (in Stunden:Minuten - hh:mm), der zurückgegeben werden soll<br />
* isday() kann benutzt werden um festzustellen, ob der aktuelle Zeitpunkt nach Sonnenauf- aber vor Sonnenuntergang des aktuellen Tages liegt<br />
<br />
== Steuerung ==<br />
Mittels folgender Anweisungen in der Konfiguration:<br />
Außenlampe - Steuerung An-/Ausschaltzeit<br />
define AussenlampeAn1 at *{sunset(0,"17:00","22:00")} set EG.Diele.Aussenlampe on<br />
define AussenlampeAus1 at *{sunrise(0,"05:00","07:30")} set EG.Diele.Aussenlampe off<br />
<br />
wird der Funk-Lichtschalter für die Außenbeleuchtung (hier das FHEM-Gerät mit dem Namen ''EG.Diele.Aussenlampe'')<br />
<br />
* morgens zum Sonnenaufgang, aber nicht vor 05:00 und nicht nach 07:30 Uhr ausgeschaltet<br />
<br />
und<br />
<br />
* abends zum Sonnenuntergang eingeschaltet, aber nicht vor 17:00 Uhr und nicht nach 22:00 Uhr.<br />
<br />
Im FHEM-Standard wird der sogenannte bürgerliche Sonnenuntergang/-aufgang genutzt, der als Sonnenstand 6 Grad unter der Horizontalen definiert ist (entspricht <code>HORIZON=-6.0</code>). Bis bzw. ab dieser Zeit ist das Lesen ohne zusätzliche Beleuchtung möglich.<br />
<br />
Da dies nicht immer gewünscht ist, ist es möglich bei den sunrise/sunset-Funktionen *optional* als ersten Parameter vorne REAL, CIVIL, NAUTIC, ASTRONOMIC oder z.B. HORIZON=-6.0 oder "HORIZON -6.0" anzustellen.<br />
{| class="wikitable"<br />
! Parameter !! Bedeutung !! entspricht<br />
|-<br />
| <code>"REAL"</code> || Sonne in der Horizontalen || <code>"HORIZON=0.0"</code> <br />
|-<br />
| <code>"CIVIL"</code> || Bürgerliche Dämmerung || <code>"HORIZON=-6.0"</code><br />
|-<br />
| <code>"NAUTIC"</code> || Nautische Dämmerung || <code>"HORIZON=-12.0"</code><br />
|-<br />
| <code>"ASTRONOMIC"</code> || Astronomische Dämmerung || <code>"HORIZON=-16.0"</code><br />
|-<br />
|}<br />
<br />
# Normales Verhalten wie im obigen Beispiel: <br />
{sunset(0,"17:00","22:00")}<br />
Ergebnis (als Beispiel): 19:59:22 <br />
<br />
# Gleiches Beispiel mit CIVIL als 1. Parameter: <br />
{sunset("CIVIL",0,"17:00","22:00")} <br />
Ergebnis (als Beispiel): 19:59:22 <br />
<br />
# Gleiches Beispiel mit Eingabe der Höhe über Horizont als 1. Parameter: <br />
{sunset("HORIZON=-6.0",0,"17:00","22:00")} <br />
Ergebnis (als Beispiel): 19:59:22 <br />
<br />
# Gleiches Beispiel mit dem realen Sonnenuntergang auf 0 Grad als 1. Parameter: <br />
{sunset("REAL",0,"17:00","22:00");;} <br />
Ergebnis (als Beispiel): 19:22:07<br />
<br />
== Kontrolle ==<br />
Um die Zeiten zu kontrollieren können Sie in der FHEM-Befehlszeile den Befehl<br />
<br />
<code><br />
list AussenlampeAn1<br />
</code><br />
<br />
eingeben und mit der &lt;Enter&gt;-Taste (nicht "save-Button") bestätigen. Sie sehen dann (hier eine Ausgabe vom 17.01.2013) z.B. folgendes:<br />
<br />
<nowiki>Internals:<br />
DEF *{sunset(0,&quot;17:00&quot;,&quot;22:00&quot;)} set EG.Diele.Aussenlampe on<br />
NAME AussenlampeAn1<br />
NR 225<br />
NTM 17:37:09<br />
REP -1<br />
STATE Next: 17:37:09<br />
TRIGGERTIME 1358527029<br />
TYPE at<br />
Attributes:<br />
room Diele</nowiki><br />
Der Sonnenuntergang liegt am genannten Tag '''innerhalb''' des Start-/Ende-Zeitraums, so dass die Lampe um 17:37 Uhr eingeschaltet wird.<br />
<br />
Die Ausgabe (gleiches Datum) von<br />
<br />
<code><br />
list AussenlampeAus1<br />
</code><br />
<br />
lautet:<br />
<br />
<nowiki>Internals:<br />
DEF *{sunrise(0,&quot;05:00&quot;,&quot;07:30&quot;)} set EG.Diele.Aussenlampe off<br />
NAME AussenlampeAus1<br />
NR 228<br />
NTM 07:30:00<br />
REP -1<br />
STATE Next: 07:30:00<br />
TRIGGERTIME 1358490600<br />
TYPE at<br />
Attributes:<br />
room Diele</nowiki><br />
Hier liegt der Sonnenaufgang noch '''außerhalb''' des Start-/Ende-Zeitraums, so dass die Lampe um 07:30 Uhr ausgeschaltet wird.<br />
<br />
== Links ==<br />
* Workaround um die Zeiten für Sonnenaufgang und -untergang anpassen zu können: [[Trick der Woche#isday]]<br />
* Diskussion über das Modul im {{Link2Forum|Topic=8527|LinkText=Fhem Forum}}<br />
* Berechnungsgrundlage bei StackExchange https://stackoverflow.com/questions/7064531/sunrise-sunset-times-in-c<br />
<br />
== Hinweise ==<br />
* Die ''sunset / sunrise'' Einstellungen arbeiten meist erst '''am nächsten Tag''' richtig. Das hängt zusammen mit einer Falschberechnung beim setzen dieses ''defines''. An einer Korrektur wird gearbeitet (Stand Januar 2013).</div>Andieshttp://wiki.fhem.de/w/index.php?title=Event-aggregator&diff=34002Event-aggregator2020-10-12T06:19:04Z<p>Andies: /* userReadings */siehe https://forum.fhem.de/index.php/topic,114947.msg1091775.html#msg1091775</p>
<hr />
<div>{{SEITENTITEL:event-aggregator}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<!-- Infobox Attribut sinnvoll? --><br />
{{Baustelle}}<br />
Mit dem Attribut [[event-aggregator]] können (nach Wunsch zeitlich gewichtete) Durchschnittswerte, Minima, Maxima oder Median etc. berechnet werden. Der Median kann hilfreich sein, um Messwerte mit Ausreissern (unsinnige Werte, z.B. durch Übertragungsfehler) zu glätten.<br />
<br />
== Syntax ==<br />
Das ''event-aggregator'' Attribut wird in der folgenden Weise spezifiziert:<br />
:<code><nowiki>attr <device> event-aggregator reading:interval:method:function:holdTime</nowiki></code><br />
<br />
Mehrere Readings werden als kommagetrennte Liste angegeben.<br />
<br />
Die einzelnen Teile haben folgende Bedeutung:<br />
=== reading ===<br />
Das zu aggregierende Reading des aktuellen Gerätes. Das Reading selbst muss seine Werte aus einer Aktion oder einem Event in FHEM erhalten (beispielsweise, indem Temperaturwerte ausgegeben oder andere Größen in das Reading geschrieben werden). Indem dann der event-aggregator auf dieses Reading angewandt wird, werden die erhaltenen Größen bearbeitet - je nach Installation wird dann also das Minimum, das Maximum oder der Median der Werte beim Reading ausgegeben.<br />
<br />
Wichtig: Es kann immer nur einen event-aggregator pro Reading geben. Will man daher mehrere Werte (z.B. min, max, avg), muss man weitere Readings erzeugen (z.B. mit userReadings oder notify). Der Aggregator kann als regulärer Ausdruck angegeben werden (bsp. .*_rain.*)<br />
<br />
=== interval === <br />
<br />
Updates des <readings> werden ignoriert, Events werden für mindestens <interval> Sekunden unterdrückt.<br />
<br />
Nach der interval-periode wird das reading mit einem Wert upgedated, der sich aus den Werten und Zeitstempeln der vorher ignorierten Updates zusammensetzt.<br />
<br />
=== method === <br />
<br />
betrifft die Gewichtung nach Zeitintervallen<br />
* <code>none</code>: keine zeitliche Gewichtung<br />
* <code>const</code>: Annahme, dass zwischen den zwei Messpunkten keine Veränderung stattgefunden hat<br />
* <code>linear</code>: Annahme, dass der Wert sich zwischen zwei Messpunkten linear verändert hat.<br />
<br />
=== function === <br />
<br />
* <code>count</code> Anzahl<br />
* <code>min</code> Minimum<br />
* <code>max</code> Maximum<br />
* <code>mean</code> artihmetischer Mittelwert<br />
* <code>sd</code> Standardabweichung<br />
* <code>integral</code> Summe (falls holdTime nicht angegeben) oder Integral für den Zeitraum holdTime<br />
* <code>median</code> [https://de.wikipedia.org/wiki/Median Median] (nur für method <code>none</code> und gesetzte holdTime) - im Gegensatz zum Mittelwert nicht anfällig für Ausreisser, hilfreich bei Sensoren mit sporadisch unsinnigen Messwerten<br />
<br />
=== holdTime === <br />
<br />
Zeitfenster in Sekunden, für die die vergangenen Werte gehalten werden, um die Aggregatfunktion zu berechnen.<br />
<br />
<br />
== Duplizieren von Readings==<br />
Wenn mehrere Funktionen für ein Reading berechnet werden sollen, muss dieses Reading zuvor dupliziert werden.<br />
In der Commandref wird ein notify vorgeschlagen, evtl. können aber auch DOIF_Readings, event_Readings und userReadings verwendet werden:<br />
<br />
<code><br />
original_reading:interval:method:function:holdTime<br />
</code><br />
=== DOIF_Readings ===<br />
TODO!<br />
<code><br />
original_reading:interval:method:function:holdTime<br />
</code><br />
=== event_Readings ===<br />
<code><br />
attr DOIF-Device event_Readings <br />
original_reading:[<Device>:<Reading>], <br /><br />
copy_1:[$SELF:original_reading], <br /><br />
<s>copy_2:int(10*[$SELF:copy_1])/10</s> Funktioniert so nicht!!! <br /><br />
attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime<br />
</code><br />
=== userReadings ===<br />
<code><br />
attr DOIF-Device userReadings <br />
original_reading {ReadingsVal("<Device>","<Reading>",0)}, <br /><br />
copy_1 {ReadingsVal($name,"original_reading",0)}, <br /><br />
copy_2 {int(10*ReadingsVal($name,"copy_1",0))/10}<br /><br />
attr DOIF-Device event-aggregator copy_1:interval:method:function:holdTime<br />
</code><br />
Dabei darf anscheinend kein Leerzeichen zwischen mehreren Readings vorkommen: https://forum.fhem.de/index.php/topic,114947.msg1091775.html#msg1091775<br />
<br />
== Wechselwirkungen == <br />
- keine bekannt - <br />
<br />
== Beispiele ==<br />
; aus der {{Link2CmdRef|Anker=Event-aggregator}}<br />
<code><br />
attr myPowerMeter event-aggregator EP_POWER_METER:300:linear:mean,EP_ENERGY_METER:300:none:v<br />
<br />
attr myBadSensor event-aggregator TEMP::none:median:300<br />
<br />
attr mySunMeter event-aggregator SUN_INTENSITY_24H::const:integral:86400<br />
</code><br />
<br />
== Siehe auch ==<br />
*[[event-on-update-reading]]<br />
*[[event-min-interval]]<br />
*[[event-aggregator]]<br />
<br />
== Links ==<br />
* Benutzungstipps (''Best Practice'') für das Attribut in {{Link2Forum|Topic=36522|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=CUL&diff=34001CUL2020-10-11T10:45:05Z<p>Andies: /* Antenne */ Antennenthread eingefügt, Aussagen zur Anpassung und Antennengewinn</p>
<hr />
<div>'''CUL''' ('''C'''C1101 '''U'''SB '''L'''ite) ist ein RF-Gerät im Formfaktor eines USB-Dongles mit externer [[CUL Ausstattung|Antenne]]. Die über das ISM/SRD Band empfangenen Daten werden durch einen Onboard 8&nbsp;bit Atmel Prozessor vorverarbeitet. Mit verfügbarer quelloffener [[#FW|Firmware]] kann das CUL verschiedene 868MHz [[CUL HomeMatic und FS20|Protokolle]] empfangen und senden, insbesondere die FS20/FHT/S300/EM/HMS sowie durch kurzfristige Umschaltung auf 433&nbsp;MHz Intertechno (z.&nbsp;B. viele Baumarkt Funksteckdosen) Protokolle. <br />
<br />
Im Umfeld von FS20/FHT/EM/S300/HMS ("[[Rfmode|rfmode]] - [[SlowRF]]") wird die Dekodierung der per AM in 1&nbsp;kHz übertragenen Signale per [[#FW|culfw]] auf dem Atmel Prozessor direkt erledigt und dann per USB an den Hostrechner weitergegeben.<br />
<br />
Das CUL kann mittels des CULModuls von FHEM angesprochen und somit wie eine FHZ1X00PC verwendet werden.<br />
<br />
Das CUL kann auch im HM-Mode als HomeMatic Zentrale alternativ zur CCU oder dem [[HMLAN Konfigurator]] betrieben werden. Bei CULs älter als Version&#160;3 ist jedoch der Speicher zu klein, um die Software für FS20/FHT/S300/EM/HMS und HomeMatic zugleich im Speicher zu halten, hier muss man sich beim [[CUL an einer Fritzbox 7390 flashen|Flashen]] der Firmware für eine Protokollfamilie entscheiden. Mit zwei CULs ist aber auch der Mischbetrieb an einem FHEM Hostrechner möglich. Es ist jedoch nicht angeraten, den CUL bei HM-Geräten zu verwenden, siehe {{Link2Forum|Topic=68145|LinkText=Link}}<br />
<br />
Ebenso gibt es ein Modul zur Ansteuerung der [[MAX]]! Heizungsteuerung. Auch hier ist ein Mischbetrieb (MAX! und z.&nbsp;B. FS20 gleichzeitig über ein CUL) obwohl technisch nicht unmöglich {{Link2Forum|Topic=10510|LinkText=nicht angeraten}}.<br />
<br />
Ferner ist der Einsatz eines CUL als [[RFR CUL]] für den ''SlowRF'' Mode (jedoch nicht für den ''HomeMatic'' Mode) möglich, um die Reichweite zu erhöhen. Die Verbindung erfolgt hierbei über Funk, sodass keine USB Verbindung zum FHEM Hostrechner erforderlich ist.<br />
<br />
Alle diese Modi sind in der Original-[[#FW|culfw]] enthalten und werden z.B. durch die Wahl des ''rfmode'' eingestellt.<br />
<br />
Obwohl die eigentliche Betriebsfrequenz der FHT und FS20-Komponenten 868,35 MHz ist, ist bei den aktuellen CUL Firmwareversionen zum Betrieb mit FHEM die Frequenz auf 868,30 MHz eingestellt. Dies hat sich als Kompromiss zum besseren Empfang von EM1000EM (Energiemonitor) Geräten bewährt, '''obwohl''' diese nominal mit 868,360 MHz arbeiten. Praktisch ist die Genauigkeit der Sendefrequenz der meisten ''SlowRF'' Geräte wegen der primitiven Sender sehr schlecht und kann deutlich von der nominalen Frequenz abweichen.<br />
<br />
Frequenz und Bandbreite können daher im ''SlowRF'' Mode frei angepasst und somit für die örtlichen Empfangsgegebenheiten optimiert werden.<br />
<br />
== Hinweise zum Betrieb mit FHEM ==<br />
'''Anmerkung:''' Nachfolgende Beispiele sind so wie dargestellt in die FHEM-Eingabezeile oder per Telnet auf FHEM zu übertragen und per <Taste>Enter</Taste> abzuschicken (nicht "save" klicken); '''''myCUL''''' ist dabei nur ein Platzhalter und durch den Namen '''Ihres''' CUL zu ersetzen. Da diese Funktionen durch die culfw (Firmware) bereitgestellt werden, funktionieren sie auf allen Geräten, die die culfw verwenden ([[CUNO]], [[COC]], CSM):<br />
<br />
* Ist Empfang eingeschaltet ?<br />
*: <code> get myCUL raw C35</code> (13 = ja, z.&nbsp;b.: C35 = 0D / 13)<br />
* Auslesen der culfw Version:<br />
*: <code>get myCUL raw V</code><br />
* LED ausschalten (Achtung: Buchstabe l (L) vorweg für LED, keine Zahl 1)<br />
*: <code>set myCUL raw l00</code><br />
* LED einschalten<br />
*: <code>set myCUL raw l01</code> Blinkt bei Senden oder Empfangen von Paketen<br />
* LED soll blinken (einmal in der Sekunde)<br />
*: <code>set myCUL raw l02</code><br />
* Reboot / Reset des CUL:<br />
*: <code>set myCUL raw B00</code> Andere Werte als 00 starten das CUL im Bootloader-Modus (=&gt; neue Firmware)<br />
* Freie CUL Sendezeit ([[1% Regel]]):<br />
*: <code>get myCUL raw X</code> 2. Wert ist Sendezeit in 10ms Slots, ein FS20 Befehl braucht ca. 210ms (also 21 Slots), eine FHT Kommunikation wesentlich mehr. Alternativ auch <code>get myCUL credit10ms</code> ergibt Sendezeit in 10ms Slots<br />
* Freie Kapazität des FHT Buffers<br />
*: <code> get myCUL raw T03</code> Ergebnis Bytes in HEX. Leer = 4a<br />
* Inhalt des FHT Buffers<br />
*: <code> get myCUL raw T02</code> (CUL V2 Buffer ist 74 Bytes gross, Platz für 14 bis 31 FHT Messages). Rückgabe n/a = Buffer ist leer<br />
* Eingestellte [[Was_ist_der_Hauscode%3F|FHT-ID]]<br />
*: <code> get myCUL raw T01</code> <br />
* Eingestellte Frequenz, Bandbreite etc. Ausgeben<br />
*: <code> get myCUL ccconf</code>. <br>Rückgabe z.&nbsp;B.: <br><code><nowiki>myCUL ccconf =&gt; freq:868.300MHz bWidth:325kHz rAmpl:42dB sens:4dB</nowiki></code><br />
* eingestelle Bandbreite erhöhen (z.B. auf 464 kHz, mehr hat meist keinen Sinn):<br />
*:<code>set myCUL bWidth 464</code><br />
* Einstellen der Sendestärke:<br />
*: <code>set myCUL raw x09</code> Einstellen der Sendeleistung.<br />
<br />
Gültige Werte für die Sendeleistung sind 00-09. Verwendet werden sollten nur die Werte 05-09, diese entsprechen<br />
-10/-5/0/5/10 Sendeleistung in dB. Default ist x08 = +5dB. Bitte im Interesse von Nachbarn und der Abhörsicherheit den kleinsten problemlos funktionierenden Wert einstellen. Dies ist meistens x07 oder x08. Da speziell die Kommunikation mit den FHTs bidirektional ist, kann die Kommunikation durch höhere Werte oft nicht verbessert werden, da die FHTs selber dadurch nicht stärker senden. Besser versuchen, Lage und Antennenausrichtung des CUL zu verändern. <br />
<br />
Werte x00-x04 sind '''mit''' Ramping (''sanften'' Flankenanstieg anstatt Rechteck) und führen zum Verlust der Kommunikationsfähigkeit mit anderen CULs, z.&nbsp;B. [[RFR CUL]], da die CULs Rampingsingnale nicht verstehen (FS20 / FHT und ähnliche Empfänger aber sehr wohl). <br />
<br />
<br />
<br />
<br />
'''Hinweis:''' Beim CUL im HomeMatic-Modus kann man (ohne Firmware-Modifikation) die Empfangs-/Sendeparameter '''nicht''' verstellen. Die üblichen freq/x09 etc. haben hier keine Wirkung ({{Link2Forum|Topic=10203|Message=57191|LinkText=Quelle}}).<br />
<br />
Weiterhin kann man zunehmend mehr Debuggingoutput auf dem CUL einschalten mit&#160;:<br />
* <code> set CUL1 raw X61</code> Communication wird im Detail angezeigt<br />
* <code>set CUL1 raw X25</code> auch checksum Fehler / unerkannte Protokolle werden gemeldet<br />
* <code>set CUL1 raw X2F</code> alle empfangenen Flanken werden gemeldet<br />
* <code>set CUL1 raw X80</code> RSSI / Signalstaerke jeder Flanke wird gemeldet<br />
* <code>set CUL1 raw X21</code> normal Modus<br />
<br />
Achtung: Auf Gross- und Kleinschreibung des "x,X" achten!<br />
<br />
Die kompletten Kommandos mit Erklärung für CUL sind in der [http://culfw.de/commandref.html commandref] zu finden.<br />
<br />
== Versionen ==<br />
Das CUL gibt es in mehreren Versionen, die sich überwiegend in Prozessor und Speicherkonfiguration unterscheiden.<br />
<br />
* CUL V1 - AT90USB162 Prozessor, 0,5Kb RAM, 16Kb Flashmemory, 0,5 kByte EEPROM. Einsatzfähigkeit unbekannt (aber vermutlich wie V2). Wird nicht mehr hergestellt.<br />
* CUL V2 - AT90USB162 Prozessor, 0,5Kb RAM, 16Kb Flashmemory, 0,5 kByte EEPROM. Einsatzfähig. Der Flashspeicher ist jedoch zu klein für eine culfw (CUL Firmware), die Code für ''SlowRF'' Geräte und zugleich ''HomeMatic'' Geräte enthält. Es muss also vor dem Flashen der Firmware zwischen zwei jeweils reduzierten Versionen gewählt werden. Da ein CUL ohnehin nicht beide Sendemodi '''zeitgleich''' betreiben kann, ist dies keine wirkliche Einschränkung. Wird nicht mehr hergestellt.<br />
* CUL V3 - ATMega32U4 Prozessor, 2,5 kB RAM, 32 kB Flashmemory, 1 kByte EEPROM). Voll einsatzfähig.<br />
* CUL V4 - ATMega32U2 Prozessor, 1 kB RAM 32 kB Flashmemory, 1 kByte EEPROM. Voll einsatzfähig. Genau genommen ein "Sparmodell" des V3, um Lieferengpässe des atmega32u4 Prozessors zu umgehen. Der reduzierte RAM-Speicher verursacht (zumindest gegenwärtig) beim Betrieb mit culfw und FHEM keine Einschränkungen oder Nachteile. Achtung: Flashen des CULv4 setzt DFU-Programmer 0.5.4 oder höher voraus.<br />
<br />
Die für die aktuellen Modelle lieferbare Abschirmung ist in der Regel nicht notwendig.<br />
<br />
== Firmware {{Anker|FW}} ==<br />
Die für den CUL und verwandte Hardware wie [[CUN]] und CUR im Zusammenhang mit FHEM überwiegend eingesetzte Firmware culfw findet sich auf der<br />
* [http://culfw.de CUL Firmware Homepage]<br />
Dort kann die jeweils aktuelle Version nachgesehen und heruntergeladen werden.<br />
Alte Stände, Version für Entwickler und ganz aktuelle Änderungen findet man auf der<br />
* [https://sourceforge.net/projects/culfw/ Sourceforge Projektseite der culfw]<br />
Hier kann man sich z.B. mit<br />
<syntaxhighlight lang=bash><br />
svn co svn://svn.code.sf.net/p/culfw/code/trunk/culfw<br />
</syntaxhighlight><br />
die aktuelle Version laden.<br />
<br />
Zusätzlich gibt es ["leider"...!?] folgende Forks der originalen culfw mit dortigen speziellen Anpassungen/Abweichungen:<br />
* [https://github.com/heliflieger/a-culfw Alternative culfw for cul devices] auf GitHub und im {{Link2Forum|Topic=35064|LinkText=Forum}} mit Anpassungen unter anderem für InterTechno. Hier könnte es aber zu Funktionseinschränkungen bei anderen Protokollen kommen. In dieser Version ist auch ein Portierung auf ARM-Prozessoren enthalten (siehe {{Link2Forum|Topic=38404|LinkText=Forum}}) mit der die CUL-Firmware auch auf dem HM-CFG-USB-2 und dem [[MAX]] Cube betrieben werden kann.<br />
* {{Link2Forum|Topic=24436|LinkText=Timestamp Firmware}} mit speziellen Anpassungen für HomeMatic. Bei HomeMatic ist das Timing der Telegramme entscheidend sonst kann es zu "MISSING ACK" bzw. "RESPONSE TIMEOUT:RegisterRead" u.ä. Meldungen kommen.<br />
<br />
Alternativ zu den [a]culfw-Firmwares gibt es [[SIGNALduino]] (zumindest auf manchen Hardware-Konstellationen umgeflashed direkt anwendbar und 1:1 lauffähig; inkl. normierter/kompatibler Weiterleitung/Dispatching auf die gleichen zentralen Geräte-Protokoll-Dekodier-Module, die auch von anderer Transceiver-Hardware/-Firmware - CUL etc. - ähnlich angebunden werden (sollen); somit Kommunikation mit vielen Funk-Komponenten auch dort idealerweise immer 1:1 funktionierend).<br />
<br />
Generell ist das Angebot an Speicherplatz auf dem im CUL verwendeten ATMega32U2 sehr eingeschränkt, wodurch Erweiterungen ohne Abstriche an anderer Stelle kaum mehr möglich sind. Es wird also die optimale CUL-Firmware für alle Zwecke nie geben, so dass man die Auswahl am konkreten Bedarf klären muss. Wer die Firmware selbst compiliert kann gezielt Funktionen die nicht benötigt werden weglassen und dafür ggf. Funktionen die sonst nicht eingefügt sind hinzufügen.<br />
<br />
== Sendefrequenz ==<br />
Das CUL gibt es in Ausführungen für 868 und 433 MHz. <br />
Die Sende- und Empfangsfrequenz des CUL sind in weiten Bereichen einstellbar, im ''SlowRF'' Mode auch durch direkte Befehle aus FHEM (im ''HomeMatic'' Mode derzeit nicht unterstützt). Der wesentliche Unterschied der 868 und 433 MHz CULs ist ein auf die Frequenz richtig abgestimmter HF-Eingangskreis inklusive Antennenlänge.<br />
<br />
Es ist durchaus möglich, ein 868 MHz CUL auf 433 MHz einzustellen. Da dann aber die HF-Eingangskreis-Abstimmung und Antennenlänge nicht korrekt sind, ist Empfangs- und Sendeleistung suboptimal, die Reichweite sinkt. Dennoch wird diese Möglichkeit des freien Einstellens durch das FHEM Intertechnomodul genutzt, da Intertechnokomponenten mit 433 MHz arbeiten. Dazu wird beim Senden eines Intertechno-Befehls die Frequenz eines 868 MHz CULs kurz umgestellt.<br />
Besser ist aber die Nutzung eines dedizierten 433 MHz CUL für Intertechno.<br />
<br />
== Antenne ==<br />
Der CUL ist mit RP-SMA-Stecker für die Antenne aber auch mit angelöteter Drahtantenne lieferbar.<br />
Funktional besteht kein Unterschied: auch die "richtige" Antenne ist (in diesem Fall) nur ein Draht, jedoch gummiummantelt und eventuell mit einem Knickgelenk und einem Schraubanschluss versehen, d.h. die Drahtantenne sieht nur unschön aus.<br />
<br />
Bei einer Antenne sind zwei Dinge auseinanderzuhalten: Einmal die Anpassung sowie die Abstrahlungscharakteristik. <br />
* '''Anpassung''' Eine Antenne ist typischerweise für eine bestimmte Frequenz konstruiert. Wenn die Konstruktionsfrequenz nicht mit der Frequenz übereinstimmt, auf der die Antenne senden und empfangen soll, ist die Anpassung schlecht. Dies führt zu Verlusten bei der Übertragung. Typische Kennwerte für eine Anpassung sind das Stehwellenverhältnis (SWR) sowie die Impedanz. Beide Größen können per Messgerät bestimmt werden, inzwischen gibt es für 150 Euro entsprechende Geräte. Wer eine Antenne selbst konstruiert, sollte ein solches Gerät zumindest ausborgen, um seine Antenne zu bestimmen.<br />
* '''Abstrahlung''' Es gibt mehrere Arten von Antennen, die sich in der Art der Strahlung unterscheiden. Richtantennen versuchen Signale nur in eine bestimmte Richtung zu versenden, Dipole versuchen in die gesamte Umgebung zu senden bzw zu empfangen. Während es bei Anpassung nur die Kategorien "gut" und "schlecht" gibt, ist bei der Abstrahlung eher auf "zweckmäßig" und "unzweckmäßig" zu achten.<br />
<br />
Grundsätzlich hängen Abstrahlung und Antennengewinn zusammen. Die Energie, die eine (perfekt angepasste) Antenne strahlt, wird durch die Antennenkonstruktion weder verdoppelt oder halbiert, sondern nur gebündelt. Während ein Dipol in alle Richtungen abstrahlt, bündelt eine Richtantenne dieselbe Energie in eine bestimmte Richtung. Insofern muss man bei der Antennenkonstruktion überlegen, woher die Signale kommen bzw wohin sie gehen sollen. Jeder Antennengewinn geht einher mit einer Einschränkung bei der Sende/Empfangsrichtung, es sei denn, man verbessert die Anpassung der Antenne. <br />
<br />
Leider kann man auch bei gekauften Antennen nicht davon ausgehen, dass sie korrekt angepasst sind. Es gibt Berichte im Forum, wonach es insbesondere bei 433 MHz-Antennen eher ein Glücksspiel ist, ob man eine vernünftig angepasste Antenne bekommt. Daher kann es durchaus sein, dass eine Eigenbauantenne wesentlich bessere Werte liefert als eine käuflich erworbene. <br />
<br />
Eine zentrale Größe bei der Anpassung ist die Länge der Antenne. Wenn man einen Dipol verwendet, muss diese zweckmäßigerweise so groß sein wie ein Viertel der Wellenlänge ("Lambda/4"). Die sind bei 868 MHz ca. 8,6 Zentimeter. Antennenlängen die länger oder kürzer sind verschlechtern in der Regel die Anpassung. Daher ist eine z.B. 10 Zentimeter lange Antenne (obwohl länger) schlechter als 1/4 Lambda mit 8,6 Zentimeter.<br />
<br />
Weitere Informationen sind im Antennenthread des Forums zu finden: [https://forum.fhem.de/index.php/topic,93021.0.html Link]<br />
<br />
Über besondere Antennenkonstruktionen (bitte nach Colinear, Jpole, Yagi suchen) oder Antennen die "Lambda/2" oder gar ("Lambda") lang sind (also ca. 17,2 bzw. 34,5 Zentimeter) kann ein höherer Gewinn erreicht werden. Einher geht aber gleichzeitig eine stärkere Richtwirkung der Antenne. Je kürzer die Antenne, desto kugelförmiger die Abstrahlung. Bei längeren Antennen wird die Abstrahlung mehr und mehr zylinderähnlich, also mit horizontaler Richtwirkung (und in die Richtung ist das Signal dann stärker, daher der Antennen"gewinn").<br />
Das hat auch Nachteile, speziell wenn man auch "nach oben" funken will. Besonders wenn man Antennen länger als eine λ/4 Antenne (8,6 Zentimeter) in einem mehretagigen Haus verwenden will, muss man diese daher in der Regel waagerecht/horizontal ausrichten, da alles was in Richtung der Spitze (und dem Fuss) der Antenne liegt schlecht empfangen wird.<br />
<br />
Daher: Je mehr Gewinn die Antenne aufweist, desto besser ist die Sende und Empfangsleistung, aber desto mehr Gedanken muss man sich um die Ausrichtung der Antenne machen, um alle Geräte zu empfangen / zu erreichen. "Mehr dB" und speziell "länger" ist also nicht automatisch besser. <br />
<br />
Zu beachten ist auch, dass die Sendeleistung der Module gesetzlich geregelt ist und Spezialantennen mit höherem Gewinn ggf. nur an Empfängern erlaubt sind.<br />
<br />
Falls man den CUL mit RP-SMA Stecker geordert hat, aber keine passend lange RP-SMA-Antenne verfügbar ist, kann (nur für erste Tests) auch eine abschraubbare Antenne für 802.11b/g WLAN-Geräte (2,4&nbsp;GHz) benutzt werden, so diese anschlusstechnisch auf den RP-SMA-Stecker des CUL passt (dies funktioniert zumindest mit FS20- und EM-Geräten). Deren Länge ist wie oben diskutiert aber nicht optimal, besser ist auf jeden Fall eine speziell auf den Einsatzzweck (Frequenz) abgestimmte Antenne.<br />
<br />
== Antennenlänge ==<br />
Die genauen Antennenlängen sind praktisch schwer zu ermitteln, da auch Zuleitung auf dem CUL zugerechnet werden müssten und ggf Dämpfungen (also z.B. Durchführung der Antenne durch eine Gehäuse, oder gebogene Antennen) die Antennenlänge weiter beeinflussen. Gleichzeitig haben schon Abweichungen von wenigen Millimetern messbaren Einfluss. Die Antennenlänge ist daher immer nur ein Kompromiss.<br />
<br />
Exakt berechnet ohne Störeinflüsse wären folgende Antennenlängen nutzbar:<br />
868,35 MHz (z.B. HM, FS20, FHT …)<br />
1/4 Lambda = 8,63 Zentimeter <br />
1/2 Lambda = 17,26 Zentimeter <br />
1 Lambda = 34,52 Zentimeter (Bereits sehr hohe Richtwirkung)<br />
<br />
433,92 MHz (z.B. Intertechno …)<br />
1/4 Lambda = 17,27 Zentimeter <br />
1/2 Lambda = 34,54 Zentimeter <br />
<br />
Folgende Antennenlängen bieten sich praktisch an, diese sind immer etwas kürzer als die optimale Länge, dies wird z.T. durch Leiterlänge im CUL kompensiert.:<br />
<br />
8,6 Zentimeter als 1/4 Lambda für 868,35 MHz<br />
17,2 Zentimeter als 1/2 Lambda für 868,35 MHz und zugleich 1/4 Lambda für 433,92 MHz<br />
34,5 Zentimeter als Lambda für 868,35 MHz und zugleich 1/2 Lambda für 433,92 MHz<br />
<br />
== Bekannte Probleme ==<br />
<br />
=== RF-Tuning ===<br />
Im Gegensatz zu den original FHZ-Zentralen ist das CUL recht schmalbandig, d.h. die Sende- und Empfangsfrequenz wird genauer eingehalten als z.&nbsp;B. bei einer FHZ1x00PC. Dies kann im Zusammenhang mit den eher ungenauen Sendern z.&nbsp;B. der FHT Raumregler zu Empfangsproblemen führen. Es kann daher mitunter sinnvoll sein, die Sende- und Empfangsbandbreite des CUL etwas zu erhöhen. Dies senkt jedoch gleichzeitig die Empfindlichkeit.<br />
<br />
Bei Empfangsproblemen von z.&nbsp;B. HEM-Sensoren oder dem S300TH kann man folgendes testen:<br />
<br />
* Man kann die Frequenz des CUL auf genau 868,35 MHz einstellen. Standardmäßig ist hier aus Kompatibilitätsgründen 868,30 MHz eingestellt. Diese Einstellung wird fest im NVRAM gespeichert und braucht nur einmal vorgenommen zu werden.<br />
*: <code>set CUL freq 868.350</code><br />
* Es ist möglich die "decision boundary" zu vergrößern, frei beschrieben: die "Entscheidungsgrenze" ob die empfangene Signalflanke digital "0" oder "1" darstellte ({{Link2Forum|Topic=8572|Message=44388|LinkText=siehe Diskussion hier}}). Möglich sind die Werte "4", "8" und "16". Default-Einstellung ist hier "4". Zur Steigerung der Empfangsqualität soll es hilfreich sein, hier "8" einzustellen. Mitunter bringt jedoch erst die Einstellung auf "16" signifikante Verbesserungen beim Empfang von S300TH-Sensoren.<br />
*: <code>set CUL sens 8</code><br />
* Oft hilft auch, die Bandbreite auf z.&nbsp;B. 464 kHz aufzuweiten.<br />
*: <code>set CUL bWidth 464</code><br />
<br />
=== Übertragungs-Stall nach zu vielen Einträgen in der Queue ===<br />
<br />
Ich habe mich ewig damit rumgeärgert, dass die Übertragung zu bestimmten häufig angesprochenen Geräten zusammenbrach, sobald die Queue zu lang wurde (FHEM: 'list CUL').<br />
Irgendwann habe ich dann zufällig herausgefunden, dass dieses sehr fragwürdige Anwachsen der Queue an einer krassen [[Sendpool]]-Fehlkonfiguration lag: ich hatte dort ein Transceiver-Device mit angegeben, welches den [[Sendpool]]-Mechanismus (noch) gar nicht unterstützt!<br />
Sobald ich dieses falsche Gerät aus der Sendpool-Element-Liste entfernt hatte, war Ruhe --> BUG im Modul (es kann nicht sein, dass ein Device ohne [[Sendpool]]-Support das Queue-Handling so zerschießt). Dieser Bug existiert allerdings wohl weiterhin (das Perl-Handling war mir etwas zu verwirrend, um direkt zu sehen, wo das Problem ist) --> sollte nachgestellt und gefixt werden.<br />
<br />
=== Harter Lockup des CUL ===<br />
<br />
Trotz behobenem (erkanntem) Queue-Problem gibt es weiterhin Probleme ("Problem #2"): es passiert - recht selten -, dass sich der nanoCUL komplett aufhängt, mit hektisch blinkender LED.<br />
Es ist in diesem Fall noch nicht einmal mit dem Reset-Taster möglich, den Stick zu resetten - es ist also tatsächlich nötig, das USB-Kabel komplett zu ziehen. Wenigstens automatisieren lassen würde sich dieser Workaround wohl per uhubctl ([https://stackoverflow.com/questions/4702216/controlling-a-usb-power-supply-on-off-with-linux]).<br />
Wäre hilfreich, zu wissen, wie man dieses Problem sinnvoll tracen (somit: festnageln) kann.<br />
<br />
Device-Attribute wie version etc. könnten evt. den Zeitpunkt der letzten Aktivität verdeutlichen; dann im FHEM-Log um diesen Zeitpunkt herum suchen, um Auffälligkeiten/Spezialitäten zu erkennen. Und dann muss man, wenn man Pech hat, eine custom culfw bauen, die entsprechendes Reporting mit eingebaut hat...<br />
<br />
(nanoCUL; V 1.26.00 a-culfw Build: 267).<br />
<br />
UPDATE: die Lösung des Problems steht evt. im Forum (Lockup beseitigt durch Optiboot bootloader): [https://forum.fhem.de/index.php/topic,73144.msg977406.html?PHPSESSID=2lj93g4vn277qhm2bfpvfpgntr#msg977406 {Gelöst} Nanocul LED blinkt schnell].<br />
[https://www.ebay.de/itm/1-3-mal-Flash-Service-fur-ZigBee-nanoCUL-JeeLink-Shelly-Sonoff-Blitzwolf-Gosund/264472055531] scheint das zu bestätigen:<br />
"Weiterhin bieten wir beim nanoCUL an, einen alternativen Bootloader (Optiboot Bootloader) zu flashen.<br />
Dieser verhindert das Abstürzen des nanoCUL's im Betrieb z.B. bei FHEM. (Stichwort: opened)"<br />
<br />
Evt. ist auch ein USB-Port-Reset ein funktionierender Workaround (bitte Text als bestätigt umformulieren, falls das hilft): [https://www.computerhilfen.de/info/usb-reset-am-raspberry-pi-usb-ports-zuruecksetzen.html], erwähnt von [https://forum.fhem.de/index.php/topic,77380.msg783352.html#msg783352].<br />
<br />
== Selbstbau-/Bastelprojekte ==<br />
Innerhalb der FHEM-Community werden mittlerweile diverse Bastelprojekte zum Selbstbau eines CUL betrieben. Eine Auswahl dieser Projekte:<br />
* [[Selbstbau CUL]]<br />
* [[FHEMduino]]<br />
* [[SIGNALduino]]<br />
* [[MapleCUN]] mit STM32 Mikrocontroller<br />
<br />
== Links ==<br />
* Hersteller / Bezugsquelle für CUL: [http://www.busware.de/tiki-index.php?page=CUL busware.de]<br />
* Google groups [https://groups.google.com/group/cul-fans/ CUL fans], mittlerweile durch das Board {{Link2Forum|Area=cul-fans}} im [http://forum.fhem.de/index.php FHEM Forum] ergänzt/ersetzt<br />
<br />
[[Kategorie:Interfaces]]<br />
[[Kategorie:CUL|!]]<br />
[[Kategorie:433MHz]]<br />
[[Kategorie:868MHz]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=SIGNALduino&diff=33958SIGNALduino2020-09-24T08:13:21Z<p>Andies: /* Flashen des Arduino mit der SIGNALduino Firmware */ siehe https://forum.fhem.de/index.php/topic,114413.msg1086855.html#msg1086855</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Empfang und Verarbeitung von digitalen Signalen<br />
|ModType=d<br />
|ModFTopic=38402<br />
|ModCmdRef=SIGNALduino<br />
|ModForumArea=Sonstige Systeme<br />
|ModTechName=00_SIGNALduino.pm<br />
|ModOwner=Sidey ({{Link2FU|8018|Forum}}/[[Benutzer Diskussion:Sidey|Wiki]])<br />
}}<br />
<br />
== Einleitung ==<br />
=== Übersicht ===<br />
Unter den Namen SIGNALduino versteht man sowohl den Low-Cost Empfänger für digitale Signale (vergleichbar dem [[CUL]]) als auch das gleichnamige Modul mit dem Dateinamen 00_SIGNALduino.pm. Mit dem SIGNALduino kann man entweder 433 oder 868 MHz-Geräte auslesen und ansprechen. Der SIGNALduino funktioniert auch mit anderen Medien wie Infrarot oder direkter Kabelverbindung.<br />
<br />
Der SIGNALduino(-Stick) erkennt Signale anhand von Mustern und gibt sie (als maximal detaillierte Beschreibung einer Signalabfolge) dann schlicht sofort nur noch an FHEM zur Auswertung (Dekodierung) weiter. Auch nicht erkannte Signale werden an FHEM übergeben.<br />
Aufgabe des SIGNALduino (Firmware/Stick) ist es also nur, Signal-Aktivitäten zu erfassen und maximal präzise (als kurzer Text-String) zu beschreiben.<br />
Alles weitere (echte, finale Auswertung / Zuweisung dieser Signal-Daten) wird dann auf einer großen Box (Raspberry o.ä.) gemacht.<br />
<br />
=== Vorteil gegenüber einem CUL/FHEMduino ===<br />
Der SIGNALduino hat den Vorteil einer sehr schnellen Demodulation des Funksignals. Sollen weitere Protokolle dekodiert werden, so muss dazu nur ein passendes FHEM Modul entwickelt oder ein universelles Modul erweitert werden (also auf flexibel direkt updatebarer Rechner-Seite!!). Änderungen am Arduino-Firmware-Code sind normalerweise nicht notwendig (sofern die grundsätzliche Signal-Klassifizierung des Sticks korrekt funktioniert - leider nicht immer, z.B.: [https://github.com/RFD-FHEM/SIGNALDuino/issues/65 MU-Nachrichten werden z.T. als MC erkannt]).<br />
<br />
Ein großer Vorteil des SIGNALduino besteht darin, dass auch Geräte mit leicht abweichende Frequenzen steuerbar sind; so empfangen die Somfy-Rolladenmotoren beispielsweise auf 433.42 und nicht, wie bei anderen Geräten sehr oft üblich, auf 433.92 MHz. Die Frequenzumstellung stellt für den SIGNALduino kein Problem dar.<br />
<br />
Ebenso kann man den SIGNALduino direkt an den Sendeausgang eines Sensors anbinden und die digitalen Signale empfangen, dabei bitte aber auf die passenden Spannungen achten, denn ein Arduino Nano verträgt nur 5V.<br />
<br />
<br />
=== Entwicklungsversion ===<br />
Der SIGNALduino wird derzeit aktiv weiterentwickelt, siehe dazu https://github.com/RFD-FHEM. Die offizielle Version wird {{Link2Forum|Topic=58396|LinkText=hier}} genauer beschrieben. Es existieren im Forum diverse angepasste Versionen, auf die hier nicht näher eingegangen wird.<br />
<br />
== Hardware ==<br />
=== Controller ===<br />
Der SIGNALduino (Hardware) wird über den USB Port angeschlossen, er kann aber auch mit zusätzlichen ESP Modulen über ein WLAN angebunden werden. Bei Einbindung via ESP muss man beachten, dass der ESP nach 5 Minuten Inaktivität seine TCP-Verbindung unterbricht (siehe [[ESP8266#Bekannte_Probleme|diesen Hinweis]]). Zu diesem Zweck gibt es einen Signalduino-eigenen Ping-Befehl ('get signalduino ping'), der diese Aktivität wieder aufbaut. Ping-Befehle sind auch auf Betriebssystemebene bekannt - allerdings beachte man, dass der ping-Befehl auf Betriebssystemebene ICMP verwendet, zum "aufwachen" des ESP aber auf TCP-Ebene aktiviert werden muss (zum Unterschied siehe [https://www.tippscout.de/internet-was-sind-tcp-ip-udp-und-icmp_tipp_2268.html hier]) und man daher besser den Signalduino-eigenen Befehl und nicht das Betriebssystem verwendet.<br />
<br />
Der SIGNALduino basiert auf einem [http://arduino.cc/de/Main/ArduinoBoardNano Arduino Nano], die Schaltung entspricht dem [[Selbstbau_CUL]] (eine frühere Version ist der nicht mehr weiterentwickelte [[FHEMduino]]):<br />
* Entweder wird ein Arduino mit einfachen Sende- und Empfangsmodulen verwendet, dann ist die Verkabelung identisch zum [[FHEMduino]] <br />
* Oder es wird ein CC1101 Transceiver verwendet, dann ist die Verkabelung identisch zum [[Selbstbau_CUL]]. Dieser Aufbau wird derzeit empfohlen.<br />
* Zuletzt gibt es ein fertig konfektioniertes Modul von In-Circuit mit Radino CC1101 Varianten, link zum [http://shop.in-circuit.de/index.php Hersteller]. <br />
<br />
Achten Sie beim Selbstbau auf die entsprechenden Sender-Empfänger. Der sehr preiswert angebotene XY-MK-5V hat sich als zu unzuverlässig erwiesen, während anscheinend beim CC1101 (insbesondere der "grünen Version") keine Probleme auftreten. <br />
<br />
Es stehen auch für den [https://www.arduino.cc/en/Main/arduinoBoardUno UNO] und [https://www.arduino.cc/en/Main/ArduinoBoardProMini PRO Mini] Firmware-Dateien zur Verfügung. Die ausgelieferte Firmware läuft nur auf Mikrocontrollern mit 16 MHz; wer einen Mikrocontroller mit 8 MHz verwenden möchte, muss die Firmware selbst compilieren. Die SW ist auf [https://github.com/RFD-FHEM/SIGNALDuino github]. Vorgesehen ist nur die Übersetzung unter Windows mit Visual Studio und dem Visual Micro Zusatz. Es gibt aber auch eine Anleitung, wie man mit der [[Arduino]] IDE oder einem Makefile [[SIGNALduino Compilieren]] kann.<br />
<br />
Es gibt auch eine Variante des SIGNALduino, die auf einem [[ESP8266]] nativ läuft, diese funktioniert seit Anfang 2018 annehmbar, allerdings befindet diese sich noch in einer Entwicklungsphase.<br />
<br />
An den "SIGNALESP" kann auch ein CC1101 via SPI angebunden werden:<br />
<br />
{| |<br />
!CC1101 Bezeichnung<br />
!ESP Pin<br />
|-<br />
|CLK||GPIO14<br />
|-<br />
|MOSI||GPIO13<br />
|-<br />
|MISO||GPIO12<br />
|-<br />
|CSN||GPIO15<br />
|-<br />
|GDO0||GPIO4<br />
|-<br />
|GDO2||GPIO5<br />
|}<br />
<br />
Wird ein einfacher Empfänger / Sender Kombination verwendet, dann über die PINs:<br />
<br />
{| |<br />
! Bezeichnung <br />
! ESP Pin<br />
|-<br />
|Transmitter||GPIO4<br />
|-<br />
|Receiver||GPIO5<br />
|}<br />
<br />
=== Sendemodule ===<br />
{{Randnotiz|RNTyp=r|RNText=Viele user berichten über Empfangsprobleme bei Nutzung des XY-MK-5V; es wird ausdrücklich empfohlen, ein anderes Empfangsmodul zu nutzen!}}<br />
[[Datei:Fhemduino_schematic.png|200px|thumb|right|Beispielschaltplan SIGNAL(FHEM)duino]] <br />
<br />
Mit einem Arduino-Nano und folgenden, billigen Sende- und Empfangsmodulen können Sie einen SIGNALduino bauen:<br />
* FS1000A Dies ist das Sendemodul (TX) und wird oft im Set mit dem billigen XY-MK-5V-Empfänger angeboten (etwa 5€). <br />
* RXB6 Das ist das empfohlene Empfangsmodul (RX), statt XY-MK-5V, etwa 5€ aus Deutschland.<br />
<br />
Die Verkabelung erfolgt analog zum [[FHEMduino]] und das bedeutet (Arduino -> Modul):<br />
* PIN D2 an DATA des RX-Moduls<br />
* PIN D11 an DATA des TX-Moduls (PIN links mit Beschriftung ATAD)<br />
<br />
Zusätzlich muss noch jeweils GND und 5V des Arduino mit dem GND bzw. VCC des Moduls verbunden werden.<br />
<br />
Jetzt fehlen noch die Antennen. Dafür braucht man ein 17,2 cm langes Stück Kupferdraht, das wird beim Anschluss "ANT" jeweils am Modul angelötet (anfängergeeignet).<br />
<br />
== Software ==<br />
<br />
=== USB-ID ermitteln ===<br />
Bevor der SIGNALduino mit dem FHEM Server (im Beispiel hier ein Raspberry PI) verbunden werden kann, muss die USB-Schnittstelle ermittelt werden. Hierzu bitte auf dem Terminal den Befehl<br />
<pre> ls -l /dev/serial/by-id </pre><br />
ausführen. Beispielhaft sieht das Ergebnis etwa so aus: <br />
''lrwxrwxrwx 1 root root 13 Jan 31 00:02 '''usb-FTDI_FT232R_USB_UART_A903N5T5-if00-port''' -> ../../ttyUSB0'' <br />
Damit ist der Anschluss des SIGNALduino bestimmt und das Gerät kann wie im nächsten Abschnitt beschrieben definiert werden. Zuvor muss noch das Modul geladen werden.<br />
<br />
=== FHEM-Modul laden ===<br />
Die SIGNALduino Module werden über das FHEM [[update]] verteilt, sobald die Änderungen einen "stabilen" und alltags tauglichen Zustand haben. Aktuell wird dort die Version 3.4.2 seit 08.04.2020 verteilt.<br />
<br />
Die in der Entwicklung befindliche Version (3.4.x) kann mit folgenden Befehlen geladen werden:<br />
<br />
* FHEM aktualisieren: <code>update</code> <br />
* SIGNALduino Modul aktualisieren: <code>update all <nowiki>https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/dev-r34/controls_signalduino.txt</nowiki></code> Durch das Update von FHEM wird sichergestellt, dass das Modul mit FHEM arbeitet.<br />
*Danach kann das Gerät wie folgt definiert werden (die Spezifikation des USB-Anschlusses muss dabei an die aktuellen Gegebenheiten angepasst werden):<br />
:<code>define <eigener-SIGNALduino-Name> SIGNALduino /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A903N5T5-if00-port0@57600</code><br />
* Solltet Ihr einen SIGNALESP via IP einbinden wollen ist die Syntax<br />
:<code>define <eigener-SIGNALESP-Name> SIGNALduino <ip-adresse>:23</code><br />
Nach dem Einbinden wird der SIGNALduino, falls er erkannt wird, im Status "Opened" angezeigt. Die Baudrate beim SIGNALduino beträgt 57600 - via telnet muss dann dieselbe Baudrate eingestellt werden. <br />
<br />
Für neuere Entwicklungen kann in FHEM auch dauerhaft die developer Version aktualisiert werden:<br />
<code>update add <nowiki>https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/dev-r34/controls_signalduino.txt</nowiki></code> <br />
Danach wird FHEM bei dem normalen Update-Befehl immer automatisch die aktuelle dev Version laden.<br />
<br />
Die nachfolgenden Beispiel-Befehle verwenden "sduino" als <eigener-SIGNALduino-Name>.<br />
<br />
==== Flashen des Arduino mit der SIGNALduino Firmware ====<br />
Falls avrdude noch nicht vorhanden ist, kann es mit folgendem Befehl installiert werden:<br />
:<code>sudo apt-get install avrdude</code><br />
<br />
In FHEM ist der SIGNALduino mit dem Status "Open" vorhanden. Jetzt müssen wir FHEM noch mitteilen, welche Hardware wir angeschlossen haben. Über das Attribut ''hardware'' lässt sich zwischen den mitgelieferten Firmware-Dateien wechseln. Solltet ihr einen Nano mit cc1101 Transceiver verwenden, so wählt bitte folgende Hardware<br />
:<code>attr sduino hardware nanoCC1101</code><br />
sonst üblicherweise<br />
:<code>attr sduino hardware nano328</code><br />
<br />
Dann muss mitgeteilt werden, welche Version man geladen haben will: stable oder testing. <br />
:<code>attr sduino updateChannelFW testing</code><br />
Nun wird die entsprechende Firmware heruntergeladen. Dies geschieht durch den Befehl<br />
:<code>get sduino availableFirmware</code><br />
Anschließend kann der ''flash'' Befehl abgesetzt werden: <br />
:<code>set sduino flash <und-dann-auswaehlen></code><br />
Dadurch wird der Arduino mit der gewählten Firmware geflasht. Das Ergebnis wird im Webinterface direkt angezeigt.<br />
<br />
Alternativ kann auch der Flash-Befehl mit einem Dateinamen aufgerufen werden. Diese Möglichkeit sollte jedoch nur verwendet werden, wenn die SIGNALduino Firmware selbst compiliert wurde und eine andere Hardware verwendet wird. Der Flash-Befehl wird wie folgt aufgerufen:<br />
:<code>set sduino flash FHEM/firmware/SIGNALduino_mega2560.hex</code><br />
(je nachdem wo und unter welchem Namen die .hex Datei abgelegt wurde)<br />
<br />
Wenn ein miniCUL geflasht werden soll, sind einige Besonderheiten zu beachten. Details in diesem Thread: https://forum.fhem.de/index.php/topic,114413.msg1086855.html#msg1086855<br />
<br />
==== Flashen einer Firmware über HTTP ====<br />
Die Firmware wird in nicht mehr über den FHEM Update Mechanismus verteilt. <br />
Damit die passende Firmware auf den SIGNALduino geladen werden kann, wird diese dann über HTTP aus den Github Releases geladen.<br />
<br />
==== Vorabversion einer Firmware ====<br />
Die Firmware des SIGNALduino wird ebenso wie das FHEM Modul auch weiter entwickelt.<br />
Die Entwickler sind auf Tests und Rückmeldungen der Nutzer angewiesen, da leider nicht alle Sensoren vorher getestet werden können.<br />
<br />
Aktuell (April 2020) ist noch die Version 3.3.1 fertig. Die Version 3.4 ist seit Februar 2020 in einer Vorabversion verfügbar.<br />
<br />
Für die folgenden Microcontroller kann man die Firmware seit 21.02.2019 auch direkt downloaden und teilweise flashen. <br />
Dazu muss das Attribut hardware auf einen gültigen Wert angepasst werden!<br />
Über den GET Befehl availableFirmware werden dann für die hinterlegte Hardware die passenden Versionen gesucht. Über das Attribut updateChannelFW kann zwischen "stable" und "testing" definiert werden, welche Art von Firmware angeboten werden soll.<br />
<br />
Nachdem die Firmwareversion erfragt wurde, bietet der set flash Befehl eine Auswahlliste an. Wird ein Flash Befehl mit einer der Versionen ausgewählt, wird diese Version zunächst heruntergeladen und bei den AVR Versionen auch versucht diese mittels avrdude zu flashen.<br />
Die Firmware für den ESP8266 kann aktuell leider noch nicht über diesen Befehl aktualisiert werden.<br />
<br />
Alternativ funktioniert aber auch die Option, dem Flash Befehl eine URL zu übergeben. Dann wird die Datei aus der URL heruntergeladen und auch versucht diese zu Flashen. z.B.<br />
SIGNALDuino_nanocc1101.hex für einen Nano mit CC1101<br />
<br />
<code>set sduino flash </code>https://github.com/RFD-FHEM/SIGNALDuino/releases/download/3.3.1/SIGNALDuino_radinocc11013.3.1.hex<br />
<br />
oder<br />
SIGNALESP_.hex (mit cc1101) für einen ESP8266 <br />
<code>set ipduino flash </code>https://github.com/RFD-FHEM/SIGNALDuino/releases/download/3.3.1/SIGNALDuino_ESP8266cc11013.3.1.hex<br />
<br />
!Achtung, aktuell wird die Firmware für den ESP dadurch nur herunter geladen. Flashen müsst ihr leider immer noch über ein passendes Tool <br />
z.B. [https://github.com/nodemcu/nodemcu-flasher ESP8266Flasher.exe] oder Esptool und einer seriellen Konsole.<br />
Auch ist zu beachten, es handelt sich hierbei tatsächlich um ein Binary und nicht um ein Hex File. <br />
<br />
Nach dem Booten des ESPs, spannt dieser ein eigenes WLAN auf. Habt ihr euch damit verbunden, könnt ihr den ESP mit eurem vorhandenen WLAN nach Eingabe der Daten verbinden.<br />
<br />
Die Hauptseite für Firmware-Releases findet sich unter https://github.com/RFD-FHEM/SIGNALDuino/releases/ .<br />
Dort kann auch eine Änderungshistorie eingesehen werden.<br />
==== Flashen eines radino Boards mit ATmega32U4 ====<br />
<br />
Diese Funktion steht seit 21.02.2019 nun auch in der via FHEM aktualisierten version zur Verfügung:<br />
<br />
Auch sind Berichte bekannt, dass der Radino beim Neustart von FHEM nicht korrekt initialisiert wird.<br />
Weiterhin ist zu beachten, dass der Bootloader eine andere USB ID bekommt und diese im Attribut flashCommand hinterlegt werden muss.<br />
<br />
==== Fehler beim Flashen ====<br />
Sollte bei einem Flash Vorgang ein Fehler auftreten, solltet ihr zunächst im Logfile mit Verbose 5 nachsehen.<br />
<br />
Findet ihr dort keine Fehlermeldung, gibt es noch ein separates Flashlog, welches ihr über einen Browser aufrufen könnt. Dazu müsst ihr nur den Folgenden Pfad an euren Servernamen anhängen:<br />
<code><br />
/fhem/FileLog_logWrapper?dev=Logfile&type=text&file=SIGNALduino-Flash.log<br />
</code><br />
<br />
=== Geräteerkennung ===<br />
==== Unterstützte Geräte ====<br />
Für die folgenden Geräte gibt es derzeit (2017) eine Unterstützung für den Betrieb mit FHEM. Die Geräte werden [[autocreate|automatisch erkannt]] und in der Konfiguration eingetragen, wenn der SIGNALduino läuft.<br />
Bitte Geräte mit sehr präzisen Referenzen hier listen (Produktnummer, Protokoll-Variantenname etc.), damit eine globale Suche/Verifikation maximal erfolgreich ist. In der detaillierten Liste [[Geprüfte_Geräte]] lassen sich die Geräte näher identifizieren.<br />
{| class="wikitable"<br />
! style="text-align:left;" | Produkt <br />
! (E)mpfangen<br />(S)enden <br />
! Hinweise <br />
! Verwendetes Modul <br />
! Protokoll ID<br />
|-<br />
|Conrad Wetterstation KW9110||E S||Sensor: KW9010, neben Temperatur u. Luftfeuchte werden auch Trend, Batterie u. Kanal erfasst|| CUL_TCM97001 || 0.3<br />
|-<br />
|TCM Wetterstation (97001 und 21xxx Serie)||E|| || CUL_TCM97001 || 0<br />
|-<br />
|ABS Wetterstation (ABS 700)||E|| || CUL_TCM97001 || 0<br />
|-<br />
|Prologue Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|Rubicson Wetterstation ||E|| ||CUL_TCM97001 ||0 <br />
|-<br />
|NC_WS Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|[http://www.gt-support.de/ GT-WT-02 Wetterstation]||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|AURIOL Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|Mebus Wetterstation ||E|| ||CUL_TCM97001 || 0<br />
|-<br />
|Intertechno Funkschalter||E S|| ||IT || 3,4,5,17<br />
|-<br />
|<strike>Conrad RSL Funkschalter</strike>||E S|| Funktioniert aktuell nicht || SIGNALduino_RSL || <br />
|-<br />
|[http://global.oregonscientific.com/product_view.php?id=5 Oregon Scientific Wettersensoren]||E || Protokoll V2 & V3 implementiert || OREGON || 10<br />
|-<br />
|Bresser Temp/Hydro Sensor||E || || Hideki || 12<br />
|-<br />
|[https://de.hama.com/00104985/hama-aussensensor-ts33c-fuer-wetterstation Hama TS33C]||E || || Hideki || 12<br />
|-<br />
|TFA Temp/Hydro Sensor||E || || Hideki || 12<br />
|-<br />
|Lacrosse TX2/TX3 Sensoren||E || || CUL_TX || 8<br />
|-<br />
|TFA 30320902||E || || SD_WS07 || 7<br />
|-<br />
|Eurochron eas800z||E || || SD_WS07 || 7<br />
|-<br />
|Technoline WS6750/TX70DTH||E || || SD_WS07 || 7<br />
|-<br />
|FreeTec Außenmodul NC-7344||E || || SD_WS07 || 7<br />
|-<br />
|CTW600||E || || SD_WS09 || 9<br />
|-<br />
|CTW602||E ||neuere Version des CTW600 mit 868.35 MHz || SD_WS09 || 9<br />
|-<br />
|WH1080||E || || SD_WS09 || 9<br />
|-<br />
|Visivon remote pt4450||E || || none || 24<br />
|-<br />
|Einhell HS 434/6||E || || none || 21<br />
|-<br />
|Flamingo FA20RF / FA21RF / FA22RF Rauchmelder||E || || FLAMINGO || 13,13.1,13.2<br />
|-<br />
|mumbi m-FS300||E || || none || 26,27<br />
|-<br />
|TFA 30.3200||E || || none || 33<br />
|-<br />
|Livolo||E|| || none || 20<br />
|-<br />
|Smartwares RM174RF/2 (RM174RF-001CPR) 4500177571 ||E [S?]|| IT EV1527; TODO herausfinden: Alarmierung (wie Alarmton getriggered werden kann); Batterieinfo? || IT || 3<br />
|-<br />
|Smartwares SH5-TSO-A||E S|| || IT || ?<br />
|-<br />
|X10 Security Devices||E|| || || 39<br />
|-<br />
|[[Somfy_via_SIGNALduino|Somfy RTS]]||E S|| || SOMFY || 43<br />
|}<br />
Bei einigen Intertechno-Funksteckdosen (Brennenstuhl) kann es zu Empfangsproblemen kommen. Hier muss die Taktrate, mit der gesendet wird, angepasst werden. Dazu muss für ''Funksteckdose'' (also sauber per-Client-Instanz-spezifisch, NICHT SIGNALduino-Transceiver-global) das Attribut <br />
:<code>attr <Funksteckdose> ITclock 300</code> <br />
gesetzt werden, der Standardwert ist 250.<br />
<br />
==== Mein Gerät wird in FHEM nicht erkannt ====<br />
1. Prüfen, ob vom Sensor die Signaldaten (verbose >=4) erkannt werden. Sobald ihr die empfangenen Signaldaten im Logfile zuordnen könnt, geht es weiter mit:<br />
<br />
2. Eröffnet ein Thema unter [https://github.com/RFD-FHEM/RFFHEM/issues/new?template=sensor---device-feature.md github]:<syntaxhighlight lang="md"><br />
## Specifications for new sensor / switch / or other device ... <br />
<br />
- manufacturer:<br />
- model name:<br />
- pictures of the device / the board (very helpful)<br />
<br />
<br />
## Specifications <br />
<br />
- Microcontroller:<br />
- Version (Firmware):<br />
<br />
<!-- ( can be found here devicename -> Internals -> version ) --><br />
- Versionmodul (FHEM Module):<br />
<br />
</syntaxhighlight>3. Auszug aus dem Logfile, welches zum Gerät gehört.<br />
:''Alles was ihr sonst noch über das Gerät und die übertragenen Daten wisst.''<br />
<br />
Im Forum solltet ihr solche Fragen besser nicht posten, wenn das Gerät noch nicht unterstützt wird, dazu ist Github besser geeignet. Inzwischen wurde im Wiki eine eigene Seite eröffnet, die sich mit der Erkennung unbekannter Protokolle beschäftigt: [[Unbekannte_Funkprotokolle#Ansatz_1_-_Versuchen|Unbekannte_Funkprotokolle]].<br />
<br />
==== Es wird ein Protokoll erkannt, Autocreate legt aber kein device an ====<br />
Im SIGNALduino sind >70 Protokolle implementiert. Jedoch gibt es nicht immer ein logisches Module, welche diese Protokolle verarbeiten.<br />
Teilweise ist das auch nicht zwingend notwendig, um seine Anforderungen zu erfüllen. Insbesondere für Schalter bzw. Sensoren, die nur zwei Zustände kennen, geht es meist ohne Modul und automatisch angelegtem Gerät.<br />
<br />
Nehmen wir an, wir haben einen Schalter. Dieser kann einen oder zwei Zustände senden.<br />
Im FHEM Log (und, insbesondere, im FHEMWEB Event Monitor) tauchen Meldungen ähnlich dieser auf<br />
<br />
<code><br />
2015.11.15 15:52:23 4: SIGNALduino_unknown incomming msg: u85#FF8081<br />
</code><br />
<br />
Wir können mit Hilfe des Modules DOIF auf diese Nachricht eine Aktion ausführen:<br />
<br />
Entweder, wenn wir den Inhalt der Nachricht nur zu Teilen wissen, da er sich ändert:<br />
<br />
<code><br />
define mydoif DOIF ([sduino:&DMSG] =~ "u85#FF8081") (set Lamp on)<br />
attr mydoif do always<br />
</code><br />
<br />
Oder, wenn wir den Inhalt exakt kennen, dann auch als Vergleichsstring<br />
<br />
<code><br />
define mydoif DOIF ([sduino:&DMSG] eq "u85#FF8081") (set relais on)<br />
attr mydoif do always<br />
</code><br />
<br />
Der Teil u85#FF8081 muss individuell angepasst werden, der Name eures SIGNALduino möglicherweise auch.<br />
<br />
Als Alternative zu DOIF hier ein regex-verwendendes notify-Beispiel für einen Sender, der meint, zwei Codes alternierend senden zu müssen:<br />
<br />
<code><br />
define n_sender_trigger notify sduino:UNKNOWNCODE.*u41#(13B72253|163873B3) { my_sender_trigger_indicate();; }<br />
</code><br />
<br />
Selbstverfreilich muss in diesem Moment auch eine sub my_sender_trigger_indicate() definiert werden (z.B. in FHEM/99_myUtils.pm), die dort z.B. als Test eine Log-Ausgabe (Log3()) machen kann.<br />
<br />
=== Das Logfile ===<br />
Im Logfile ab [[Verbose]] 4 tauchen diverse Meldungen auf, deren Bedeutung kurz erläutert wird (verbose 3 unterdrückt diese Meldungen).<br />
<br />
UPDATE: der folgende Bereich ist von einem weniger erfahrenen Zeitgenossen früher nach Kräften erweitert/geschrieben worden. Mittlerweile existiert aber ein neuer Inhalt [[Unbekannte_Funkprotokolle]] (siehe auch Erwähnung weiter oben), der als sehr gut beschrieben und unvergleichlich detailreicher bezeichnet werden muss ("endlich gibt es sowas!"). Der Bereich hier dürfte somit zwar für grundlegende Verdeutlichungen noch recht sinnvoll sein, der Inhalt sollte allerdings evt. in eine konsistente Dokumentation überarbeitet (verlagert/dedupliziert/reduziert) werden.<br />
<br />
Die Protokolle (von der SIGNALDuino-Firmware gesendete Signal-Beschreibungs-Strings) können wie folgt unterschieden werden:<br />
<br />
*MS - Nachricht mit Sync Puls: Hierzu ein Beispiel<br />
:<code>MS;P0=-108;P1=395;P2=-1033;P3=-547;P4=-19932;P5=-8916;P6=1368;D=151313131312131313131313131313131312121212121313131313131312131212132;CP=1;SP=5;</code> P0-P6 sind die Signalpegel (Dauer und positiv/negativ). Hinter D= befindet sich die Abfolge der Signale. Die ersten beiden Ziffern 15 in D sind wie folgt zu lesen. Zuerst wurde ein Signal "1" also P1 mit 395 Mikrosekunden high (die Zeitdauer ergibt sich aufgrund der Mitteilung "P1=395") und anschließend ein Signal "5" also P5 mit 8916 Mikrosekunden low (die Zeitdauer ergibt sich aufgrund der Mitteilung "P5=-8916") gemessen. CP=1 ist die Referenz auf den Takt des Signales - der Basistakt ist in diesem Fall ~395 Mikrosekunden. SP=5 gibt die Referenz zum Syncpuls an, der das gesamte Signal einleitet. Welche Signalfolge nun eine binäre 1 bzw. 0 bedeutet, wird im SIGNALduino über die integrierte Protokoll Liste realisiert.<br />
<br />
*MC - Nachricht vom Typ Manchester: Manchesterkodierte Signale können bereits sehr einfach im Arduino in eine Binärform umgewandelt werden. Es wird hier nach IEEE 802.3 umgewandelt. In Manchester Signalen gibt es lange und kurze Pulse. Deren Durchschnittswert wird mit LL (long low), LH (long high), SL (short low) und SH (short high) übermittelt. Zusätzlich, um das Protokoll schneller erkennen zu können, wird die Taktfrequenz mit übermittelt (C=429 Mikrosekunden). Die Daten befinden sich hinter D= und werden in HEX Form übergeben.<br />
:<code>MC;LL=-1066;LH=904;SL=-562;SH=385;D=332B4B4D54D5554B552CD2D554B2B5354A;C=429;</code><br />
<br />
*MU - Message unsynced: Diese Art von Nachrichten sind nicht nach Manchester codiert und haben auch keinen erkennbaren Sync / Clock Signalpegel am Start der Nachricht. Bei diesen Nachrichtentypen ist es, im Vergleich zu den anderen, am wahrscheinlichsten, dass das übermittelte Signal unvollständig oder überhaupt kein Signal ist. Wie bei MS sind P0-P6 die Signalpegel und in D= wird die Abfolge der Signalpegel referenziert. CP=2 gibt auch hier die Referenz zum Takt an, allerdings muss dieser nicht korrekt erkannt worden sein.<br />
:<code>MU;P0=1372;P1=-580;P2=362;P3=-1047;D=01212321212321212121212121212123212123212321232121212121212321;CP=2;</code><br />
<br />
Es erscheinen viele Meldungen dieser Art:<br />
<br />
<pre><br />
Fingerprint for MU Protocol id xxxx -> yyy matches, trying to demodulate<br />
sduino: Starting demodulation at Position 1<br />
Fingerprint for MU Protocol id 28 -> IC Ledspot matches, trying to demodulate<br />
sduino: Starting demodulation at Position 1<br />
Fingerprint for MU Protocol id 29 -> HT12e remote matches, trying to demodulate<br />
</pre><br />
<br />
Dies sind nun Bemühungen, anhand der von der SIGNALDuino-Firmware gelieferten rohen aber detaillierten Signal-Strings eine Vor-Analyse / Fingerprinting vorzunehmen.<br />
Man könnte nun z.B. bei solchen Fingerprinting-Analysen erkennen:<br />
* dass der Basis-Takt-Wert innerhalb eines charakteristischen Zeit-Bereichs liegt<br />
* dass die Anzahl der Sync-Pulse eine präzise Zahl ist<br />
* dass Längen erkannter Puls-Typen innerhalb eines Bereichs liegen<br />
<br />
Mittels solcher Untersuchungen kann man also final hoffentlich hinreichend plausibel feststellen, "dass diese Aktivitäten offensichtlich(?) zu einer Funk-Komponente Rauchmelder von Hersteller XYZ gehören müssen, und man somit weiterleiten muss an ein (möglicherweise bereits existierendes) Userdaten-Dekodier-Modul für diese Herstellerkomponente".<br />
<br />
<br />
Bei einer dann erfolgenden Demodulation des noch rohen SIGNALDuino-Strings könnte man z.B. (hoffentlich richtigerweise) annehmen, dass eine Signalpegel-Typ-Folge "13" eine binäre 1 bedeuten soll, während eine Folge "12" eine binäre 0 bedeuten soll. Man erhält aus dem Gesamt-Puls-String also nach vollständiger Demodulation eine Abfolge von vielen 0/1 Bits, die insgesamt ein Datenwort darstellen, mit einer gewissen Länge von NN bits (diese Längen-Angabe könnte übrigens - neben Namenssuche nach Hersteller oder Produkt etc. - ein wichtiges Such-Merkmal sein, ob andere Frameworks tatsächlich bereits wissen, wie Daten dieser Funk-Komponente zu dekodieren sind!). Dieses demodulierte Datenwort ist nun das finale Datenwort, welches einen Container für die Funk-Komponenten-Informationen darstellt (in diesem Container also beispielsweise enthalten: Temperatur, Feuchte, Akku-Status, ID, Alarm, ... - zumindest wenn nicht dummerweise der ganze Container erst einmal CRC- oder Crypto-verschlüsselt ist...).<br />
<br />
Man muss an dieser Stelle unbedingt sagen, dass dieses Userdaten-Datenwort (einer bestimmten Hersteller-Funk-Komponente!) natürlich bei ''jeglichen'' Transceiver-Systemen ''immer'' gleich erkannt werden ''muss'' - an dieser Stelle ist also ganz klar, dass diese Daten an ''allgemeine'' FHEM-Module weitergeleitet (Dispatched) werden müssen, die nach Übernahme von Daten von ''jeglichen'' Transceiver-Systemen diese Daten immer auf die gleiche Weise ('''''generisch/zentral''''') für die jeweilige Hersteller-Funk-Komponente erledigen.<br />
<br />
'''Die Abfolge ist also ganz klar:'''<br />
Funk-Aktivität --> Transceiver-Gerät/Firmware (SIGNALDuino) --> maximal detailreich beschreibender Rx-Analyse-Output-String --> Fingerprinting-Grobzuordnung des (SIGNALDuino-Firmware-)Outputs (durch 00_SIGNALduino.pm) auf gerätespezifisches Verhalten --> ''generische/zentrale'' Dekodierung des gerätespezifischen Protokoll-Datenworts, in zentralen Grundsatz-Modulen wie z.B. <code>14_SD_WS.pm</code>).<br />
<br />
Und wenn dann bei einer solchen Schritte-Abfolge irgendetwas noch fehlen/unpassend sein sollte, dann muss eben entsprechendes Development an gewissen Stellen erfolgen ;-)<br />
<br />
====Minimieren (whitelist/blacklist) von unerwünschter Kommunikations-Aktivität/Einträgen====<br />
<br />
"Unknown Code" bedeutet, dass der SIGNALduino Signaldaten empfangen und diese binär interpretiert hat. Diese Meldung soll uns nun aber mitteilen, dass es dann nicht weiter verarbeitet werden kann, da kein Modul existiert (oder kein Weiterleitungs-Dispatch zu einem bereits existierenden), welches diese Daten jetzt in ihre Bedeutung umwandeln kann. <br />
:<code>sduino: Unknown code u1FFFFF0, help me!</code><br />
<br />
Außerdem kommt es gehäuft zu Logmeldungen und auch Events in ähnlicher Form:<br />
:<code>SIGNALduino_unknown incomming msg: u85#FF8081</code><br />
<br />
Mittlerweile sind über 50 Protokolle für den SIGNALduino definiert. Dadurch kommt es vor, dass sich ein Signal mit mehr als einem Protokoll demodulieren lässt. Meist führt dies dann zu zusätzlichen "Unknown code"-Einträgen.<br />
<br />
Derartige Einträge können mit dem Attribut WhitelistID minimiert werden. Dabei werden die Geräte, die nach Daten-Empfang tatsächlich verarbeitet werden sollen (also welche Protokolle vom FHEM Modul berücksichtigt werden), mit ihrer Protokollnummer in die WhitelistID aufgenommen.<br />
Für Protokolle, die nicht berücksichtigt werden, gibt es weder Logeinträge noch Events. Diese werden im Programmablauf nicht berücksichtigt. Das spart zum einen Ressourcen und trägt auch zur Übersichtlichkeit bei. <br />
Die Protokollnummer kann Tabelle [[#Unterst.C3.BCtzte_Ger.C3.A4te]] entnommen werden (hilfreich ist es auch, wenn in den verwendeten Geräten im Internal <gerätename>_DMSG nachgesehen wird). So bedeutet beispielsweise ein Eintrag der Form <code>W50#FF553335FFBC</code> dass dann das Protokoll #50 in die Whitelist aufzunehmen wäre (<code>attr sduino whitelist_IDs 50</code>).<br />
{{Randnotiz|RNTyp=r|RNText=Achtung Schreibweise: Dokumentation oft als WhitelistID o.ä., aber Name ist whitelist_IDs!!<br />
}}<br />
Die Angabe erfolgt durch Komma getrennt: z.B.:<br />
:<code>1,2,5,10</code><br />
<br />
=== Senden mit dem SIGNALduino ===<br />
Der SIGNALduino kann etwas "raw senden", indem ihm das SIGNAL so übermittelt wird, wie er es moduliert. Hierzu muss der Befehl wie folgt eingegeben werden:<br />
<br />
<code><br />
set sduino sendMsg P3#00111010#R4<br />
</code><br />
<br />
Dieser Befehl moduliert die Bitfolge 00111010 mittels Protokoll #3 und wiederholt die Nachricht 4x.<br />
Die Protokoll Nummer kann aus einer empfangenen Nachricht extrahiert werden. Ebenso die Bits.<br />
<code><br />
sduino: extracted data 00111010 (bin)<br />
sduino: Found Protocol id 3 <br />
</code><br />
<br />
Alternativ kann das Signal auch in einer "rohform" angegeben werden. Dies ist manchmal in speziellen Fällen notwendig:<br />
<code><br />
set sduino raw SR;;R=3;;P0=4742;;P1=-1554;;P2=286;;P3=-786;;P4=649;;P5=-420;;D=0123234545234545452323232323454523234523454523232345454523232323452345234523452345;;<br />
</code><br />
<br />
R=3 bedeutet, das Signal wird 3x gesendet.<br />
Die Übertragung besteht aus den in D angegeben Pulsen, welche in P0-P5 definiert werden.<br />
Die Daten kann man aus einer empfangenen MS oder MU Nachricht extrahieren.<br />
<br />
Alternativ kann ab Version 3.2 auch eine vereinfachte Form eingegeben werden.<br />
<br />
====Fehlersuche====<br />
(Zielgerät reagiert nicht, etc.)<br />
<br />
* Nachrichtenwiederholungsanzahl muss evt. für manche Geräte entsprechend groß eingestellt sein<br />
{{Randnotiz|RNTyp=r|RNText=VORSICHT blöder Schreibweisen-Mismatch ITClock vs. ITclock!!}}<br />
* Sende-Takt-Wert (Clock) passt evt. nicht ganz, siehe z.B. Thread-Antwort {{Link2Forum|Topic=58397|Message=775434|LinkText=Signalduino Version 3.3.1}}, wo für IT-Geräte ein Attribut anhand der CP= des Empfangsdaten-Logs modifiziert wird. ACHTUNG: dies kann entweder global das Internal-Attribut ITClock eines SIGNALduino-Transceiver-Devices sein, oder (viel besser da korrekt geräte-instanz-spezifische Konfiguration) das ITclock eines IT-Client-Devices.<br />
<br />
== Fehlerbehandlung ==<br />
Der SIGNALduino kann mit folgendem Befehl auf Werkseinstellungen zurückgesetzt werden:<br />
:<code>set raw e</code><br />
Ob ein solcher Reset nötig ist, erkennt man an dem Inhalt vom Reading <code>cc1101_config</code>, dort unsinnige Werte angezeigt werden oder dem Reading <code>config</code> welches durch den Befehl "get config" aktualisiert wird, was im Standard auf "MS=1;MU=1;MC=1" entspricht.<br />
<br />
In der Firmware sind die diverse Befehle eingebaut, welche über einen <code>set raw</code> Befehl im Modul direkt ausgeführt werden können. Sofern möglich, sollten die Abfrage von Werten aus dem Modul allerdings mit den dafür vorgesehenen Kommandos erfolgen, da die Rückmeldungen des <code>set raw</code> Befehls nur im Logfile ab Verbose 4 erscheinen. Die Befehle sind nützlich, wenn direkt auf den Microcontroller zugegriffen wird: <br />
<br />
:<code>C<reg></code> <reg> is a (two digit) hex number: return the value of the cc1101 register. <reg>=99 dumps the first 48 registers. Example: <code>set raw C35</code> führt ab Verbose 4 zu einer Logausgabe folgender Art <code>Read, msg: C35 = 0D</code><br />
:<code>e</code> EEPROM / factory reset. resets all eeprom values without reboot<br />
:<code>W<AA><XX></code> Write eeprom (schreibt einen Wert ins EEPROM und ins CC1101 Register. Die eeprom Adresse hat einen Offset von 2. z.B W041D schreibt 1D ins Register 2 des CC1101)<br />
<br />
Die Sendeleistung lässt sich mit <br />
:<code>get sduino ccpatable</code> <br />
<br />
prüfen, wobei die Rückmeldung wie folgt zu lesen ist: <br />
"-10_dBm" => '34',<br />
"-5_dBm" => '68',<br />
"0_dBm" => '60',<br />
"5_dBm" => '84',<br />
"7_dBm" => 'C8',<br />
"10_dBm" => 'C0' <br />
Dabei wird die Sendeleistung dauerhaft mit dem Befehl<br />
:<code>set sduino cc1101_patable <value></code><br />
hochgeschaltet (<value> durch den Wert ersetzen).<br />
<br />
Weitere Firmware-Befehle sind im Thread-Beitrag {{Link2Forum|Topic=58396|Message=497921}} zu finden.<br />
<br />
== Foren Links ==<br />
* {{Link2Forum|Topic=38402|LinkText=Forenthread - Ankündigung}}<br />
* {{Link2Forum|Topic=58396|LinkText=SIGNALDuino Empfänger Firm- und Hardware}}<br />
* {{Link2Forum|Topic=82379|Message=1033374|LinkText=SIGNALDuino Schaltplan}}<br />
* {{Link2Forum|Topic=58397|LinkText=Signalduino Entwicklung Version 3.3.1 }}<br />
* [http://www.rflink.nl/blog2/wiring Beschreibung zu diversen Empfängern und Verbesserung der Empfangsleistung]<br />
* [[SIGNALduino in die Arduino Entwicklungsumgebung einbinden]]<br />
* [[Somfy via SIGNALduino]]<br />
<br />
[[Kategorie:Interfaces]]<br />
[[Kategorie:Arduino]]<br />
[[Kategorie:433MHz]]<br />
[[Kategorie:868MHz]]</div>Andieshttp://wiki.fhem.de/w/index.php?title=Nextion&diff=33891Nextion2020-09-07T14:03:03Z<p>Andies: /* ESPEasy */ Bug ESPEasy erwähnt</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Anbindung von Nextion Touch Displays<br />
|ModType=d<br />
|ModForumArea=Bastelecke<br />
|ModTechName=42_Nextion.pm<br />
|ModOwner={{Link2FU|12772|viegener}}<br />
}}<br />
<br />
Das FHEM Modul [[Nextion]] dient zur Einbindung der kostengünstigen, mit serieller Schnittstelle ausgestatteten Displays, die von der Firma [https://nextion.itead.cc/ Fa. Itead] in verschiedenen Größen angeboten werden.<br />
<br />
== Modelle ==<br />
Es gibt zwei Grundmodelle (basic und enhanced), wobei die enhanced-Modelle Zugriff auf GPIOs erlauben. Beide Modelle sind in Größen von 2,4 Zoll bis zu 7 Zoll erhältlich.<br />
<br />
== Inbetriebnahme ==<br />
=== Stromversorgung ===<br />
Die Nextion-Displays benötigen eine stabile 5V Spannungsversorgung. Zudem befindet sich auf dem Display ein 3.3V-Ausgang, der aber maximal 100 mA liefert und daher nicht für die Anbindung leistungsintensiver Geräte (dazu gehört schon der ESP8266) genutzt werden kann. Ausgeliefert werden die Displays mit einem vierkabligen Anschluss, der die Spannungsversorgung (5V und GND) sowie die serielle Schnittstelle (Rx und Tx) liefert.<br />
<br />
Wird das Display über USB oder sogar mit Hilfe des 5V-Pins eines Wemos betrieben, so kann es massive Probleme bis hin zum Totalausfall kommen. Dies liegt daran, dass im Wemos intern eine Diode verbaut ist, die aus den 5V des USB-Anschlusses dann nur noch 4,5V macht; zudem benötigt der Nextion eine Versorgungsspannung oberhalb von 4,75. Nicht selten halten selbst hochamperige USB-Netzteile eine solche Spannung nicht konstant. Es empfiehlt sich also, eine eigene Stromversorgung für den Nextion anzubringen und nicht einfach auf USB zu vertrauen.<br />
<br />
Mehr Informationen sind in diesem {{Link2Forum|Topic=100470|Thread}} enthalten.<br />
<br />
=== Serielle Schnittstelle und Flashing ===<br />
Um die Displays anzuschließen, muss daher die serielle Schnittstelle physisch mit der vorhandenen Infrastruktur gekoppelt werden. Dabei bietet es sich an, die Displays ins eigene WLAN-Netz einzubinden (auch eine direkte USB-Verbindung ist denkbar). Die Einbindung ins WLAN kann beispielsweise mit den [[ESP8266|ESP8266-Modulen]] vorgenommen werden, da diese auch über eine serielle Schnittstelle verfügen und zudem leicht für das eigene WLAN vorbereitet werden können. Eine möglichst einfache Anbindung scheint dann gegeben, wenn man einen Wemos D1 Mini verwendet. <br />
<br />
In {{Link2Forum|Topic=51267|LinkText=diesem Forenthema}} wird intensiv diskutiert, ob die serielle Schnittstelle mit einem Spannungsteiler oder direkt an den ESP angeschlossen werden kann. Da die Produkte aus Fernost oft massive Abweichungen von den Standards besitzen können, sollte hier nachgemessen werden. Ist ein Spannungsteiler nötig, kann man sich etwa an {{Link2Forum|Topic=51267|Message=465888|LinkText=diesem Schaltplan}} orientieren. Der oben genannte Wemos Mini besitzt einen Micro-USB Anschluss, der die 5V Stromversorgung für das Display liefert; mehrere User berichteten, dass sie das Display direkt (also ohne Spannungsteiler) an den Wemos anschließen konnten. <br />
<br />
Das Nextion-Modul verlangt (anscheinend) eine Baudrate von 115200. Dieses muss in einem HMI-File, der das Display bespielt, vorab eingestellt werden. Dazu verwendet man auf der ersten Seite (page 0) die post-initialization den Befehl <code>baud=115200</code>.<br />
<br />
Die Firmware für die serielle Verbindung auf dem ESP8266 kann zum Beispiel [[ESPEasy]] oder {{Link2Forum|Topic=51267|Message=743457|LinkText=ESPlink}} sein.<br />
<br />
==== ESPLink ==== <br />
Flasht man den Chip mit ESPLink, so lautet der Befehl bei Verwendung von esptool.py<br />
:<code>esptool.py --port /dev/tty.<USB Port eintragen> write_flash -fm qio -ff 80m 0x00000 boot_v1.7.bin 0x01000 user1.bin 0x3fc000 esp_init_data_default.bin 0x3fe000 blank.bin</code><br />
In ESPLink muss man dann den WLAN-Zugang eintragen, danach funktioniert die Verbindung zur seriellen Schnittstelle sofort (normal UART einstellen, nicht swapped).<br />
<br />
==== ESPEasy ==== <br />
Flasht man den Chip mit ESPEasy, so lautet der flash-Befehl<br />
:<code>./esptool.py --port /dev/tty.<USB Port eintragen> --baud 115200 write_flash -u -fm dio -fs 1MB 0x00000 ESP_Easy_mega-20181220_normal_ESP8266_1024.bin</code><br />
(evtl lautet der Dateiname der Firmwaredatei inzwischen anders). In ESPEasy muss man auf der advanced-Seite die serielle Schnittstelle aktivieren, die Baudzahl einstellen (115200) und dann bei den Geräten ("devices") unter Communication-Seriell Server die entsprechenden Daten für den Port (23) sowie 8 Datenbits, non-parity und 1 stopbit einstellen, mehr hierzu in diesem Beitrag {{Link2Forum|Topic=87231|Message=846634|LinkText=diesem Beitrag im Forum}}. Wichtig: Es gibt derzeit (September 2020) immer noch eine Art Bug in der Software von ESPEasy: die serielle Schnittstelle funktioniert nur, wenn das Logging vollständig ausgeschaltet wird. <br />
<br />
=== Programmierung ===<br />
Es gibt zwei Möglichkeiten, die Displays zu programmieren. Einmal bietet Itead mit dem [https://nextion.itead.cc/resources/download/nextion-editor/ Nextion Software Editor] eine Windows-basierte Software an, mit der man auf dem Display verschiedene Stilelemente (Buttons, Labels, Pages etc.) platzieren kann. Dabei ist zu beachten, dass eventuelle Schriftarten zuerst erstellt und ebenfalls geladen werden müssen. Ein Video für eine solche Installation findet man etwa [https://www.youtube.com/watch?v=Q77Bfb3PhwQ hier] oder [https://youtu.be/D-zgtylBKUc hier]. Ebenso findet sich eine sehr gute Einführung in die Programmierung auf folgender [https://www.boecker-systemelektronik.de/epages/63381271.sf/de_DE/?ObjectPath=/Shops/63381271/Categories/Tutorials/Nextion_Tutorials Webseite von Böcker]. Nachdem die Software kompiliert wurde, muss sie hochgeladen werden. Das kann entweder durch eine micro-SD-Karte geschehen, die man in das Display steckt. Oder man verwendet die serielle Schnittstelle, mit der man die Firmware hochlädt (upload-Button im Editor).<br />
<br />
Die zweite Möglichkeit betrifft die Einbindung in FHEM, siehe dazu unten.<br />
<br />
== Zubehör ==<br />
Es wird für die so genannten Enhanced Modelle Zubehör angeboten. Die Enhanced Modelle haben zum einen eine Batterie sowie eine Echtzeituhr an Bord, zum anderen können mehrere GPIOs nach außen geführt werden. An genau diese GPIOs können zwei mögliche Erweiterungen angeschlossen werden: <br />
* Das Expansion Board mit sechs Buttons, einer LED und einem Buzzer<br />
* Den Nextion IO Adapter<br />
Das Expansion Board wird mit einem mitgelieferten Kabel an das Display angeschlossen. Dabei muss man die Polung des Kabels sehr genau beachten, da sonst 5V auf Gnd liegen. In einigen Videos wird behauptet, dass statt 5V in Wirklichkeit nur 3.3V anliegen, dies konnte durch Spannungsmessungen nicht bestätigt werden. Den Buzzer wie auch die Buttons kann man mit den Nextion-Befehlen cfgpio einstellen (google: Schlagwort cfgpio und Nextion, wobei die Dokumentation von Nextion mehr als dürftig ist). Der Buzzer liegt auf dem GPIO 7 und die LED auf GPIO 6, die anderen Taster auf den GPIO 0 bis 5. Der Buzzer ist sehr ungeschickt angebracht, da er wesentlich höher als die Tastenhubs sind. Die Maße des Expansion Boards sind in {{Link2Forum|Topic=51267|Message=989451|LinkText=diesem Forenbeitrag}} angegeben.<br />
<br />
== Einbindung in FHEM ==<br />
=== Programmierung mit Modul ===<br />
Eine andere Möglichkeit besteht darin, mit Hilfe der seriellen Schnittstelle das Modul 42_Nextion.pm zu verwenden. Dieses Modul ist bereits in der Standardinstallation von FHEM enthalten. Man legt dazu ein device an<br />
:<code>defmod <myNextion> Nextion <hostname/ip>:23@115200 </code><br />
und folgt der Darstellung aus der {{Link2CmdRef|Anker=Nextion|Label=Commandref}}. Die Baudrate sollte der Portnummer mit @ anhängt werden. Sie sollte ebenfalls im Display mit dem Befehl baud=115200 (unter Postinitialize event auf page 0) eingegeben werden (siehe oben).<br />
<br />
=== Darstellung zur Laufzeit ===<br />
<br />
Im Gerät angelegte Elemente (wie hier zum Beispiel Texte) spricht man dann zum Beispiel so an<br />
:<code> set <myNextion> cmd t0.txt=\"test\";</code><br />
oder auch <br />
:<code> set <myNextion> cmd t0.txt="test";</code><br />
Handelt es sich um Zahlen, dann<br />
:<code> set <myNextion> cmd t1.txt=12345;</code><br />
Ebenso kann man dargestellte Bilder während der Laufzeit austauschen, unsichtbar oder sichtbar machen. Weitere Befehle finden sich sowohl auf der Itead-Webseite oder dem oben angegebenen Link: so kann man beispielsweise das Display dimmen oder bestimmte Seiten auswählen.<br />
<br />
Hat man mehrere Seiten erstellt und wechselt zwischen diesen Seiten, setzt Nextion die Werte auf die ursprünglichen Größen zurück (irritierenderweise wird dieses Zurücksetzen als "Refresh" bezeichnet - obwohl gerade kein refresh stattfindet). Will man, dass auf der Seite 0 auch nach einem Seitenwechsel wieder bestimmte Werte angezeigt werden, muss man im Modul das folgende Attribut setzen (hier wird [[Set_magic|Setmagic]] verwendet, wir lesen das Attribut ''temperature'' des devices ''Messgeraet'' aus und weisen es dem Text-Inhalt der Komponente ''temp'' auf Seite 0 zu):<br />
:<code>attr <myNextion> initPage0 temp.txt="[Messgeraet:temperature]";</code><br />
Damit diese Zuweisung funktioniert, müssen zu Beginn aber im Event einer jeder einzelnen Seite bei "Preinitialize Event" der Eintrag "bkcmd=3" und bei "Postinitialize Event" der Befehl "sendme" eingetragen sein (damit die aufgerufene Seitenzahl dem Modul mitgeteilt wird).<br />
<br />
Eine etwas aufwendiger zu gestaltende Idee besteht darin, Icons aus einem Wetterdevice (zum Beispiel Proplanta) auf das Nextion-Display zu übertragen. Dazu fügt man in initPage0 neben den bisher bestehenden Zuweisungen folgendes hinzu<br />
:<code>wetter.pic={(WeatherToNextion(ReadingsVal(<WetterDeviceName>,"fc1_code",100)))};</code><br />
wobei das Device <WetterDeviceName> ein Reading mit fc1_code enthält. Dieses Reading enthält dann Informationen, welches Icon zu einem bestimmten Vorhersagezeitpunkt aufgerufen werden soll. Die Perl-Funktion WeatherToNextion wandelt dann diesen Reading-Wert in die entsprechende ID des anzuzeigenden Bildes um; dabei müssen vorab alle später anzuzeigenden Bilder in den Editor geladen werden. Beispielhaft könnte die Funktion so aussehen<br />
sub WeatherToNextion($)<br />
{<br />
my ( $val ) = @_;<br />
return 20 if ( $val == 2 );<br />
return 21 if ( $val == 3 );<br />
return 21 if ( $val == 4 );<br />
return 22 if ( $val == 5 );<br />
return 23 if ( $val == 6 );<br />
return 24 if ( $val == 7 );<br />
return 25 if ( $val == 8 );<br />
return 25 if ( $val == 9 );<br />
usw....<br />
return 48;<br />
}<br />
Bei der Verwendung von Perl-Code muss SetMagic verwendet werden, d.h. der Code ist einzuklammern in {( Code )}.<br />
<br />
=== Wakeup ===<br />
Es besteht die Möglichkeit, das Display automatisch nach einer gewissen Anzahl von Sekunden auszuschalten (thsp=10). Beachten Sie, dass das Display nur dann nach einer Berührung wieder aufwacht, wenn '''vorher''' die Variable thup=1 gesetzt wurde. Es bietet sich an, beide Variablen bereits im Nextion-Editor zu definieren.<br />
<br />
Dieser sleep-Modus setzt das Gerät auf die ursprünglichen Werte zurück, auch scheint zwischendurch ein Senden an das Display nicht möglich (obwohl in den Dokumentationen etwas anderes behauptet wird). Der Sleep-Modus scheint dem arduino zu ähneln, bei dem der Stromverbrauch nur noch auf das notwendigste gedrosselt wird. <br />
<br />
Will man zwischendurch nur das Display ausschalten, bietet es sich dagegen an, mit dem internen dim-Befehl zu arbeiten. Beispielsweise schaltet <code>dim=0</code> den Bildschirm aus; hier muss man einen internen Timer hinzufügen. Hier sind also zwei Angaben notwendig: Einmal bei einem Timer und ein weiteres Mal bei dem Objekt, das den Bildschirm aufwecken soll:<br />
* Dazu definiert man einen timer (beispielsweise tm0). Ein solcher Timer zählt von der angegeben Anzahl (tm0.timer) die Anzahl der Millisekunden nach unten und fängt dann wieder erneut an herunterzuzählen. Immer dann, wenn er den Wert 0 erreicht, führt er das timer-Event aus (dieses Objekt würde man besser als "repeater" bezeichnen). Fügt man in die Definition dieses Events den Befehl tm0.en=0 sowie dim=0 ein, so wird der Timer nach einem einmaligen Herunterzählen ausgeschaltet; ebenso schaltet sich der Bildschirm aus. <br />
* Wenn nun an dem Objekt, das den Bildschirm aufwachen lassen soll, die Befehle dim=85 und tm0.en=1 eingefügt werden, wird durch Drücken des Objektes der Bildschirm erhellt und der Timer aktiviert. Dieser Timer zählt dann einmal nach unten und schaltet sich selbst aus.<br />
<br />
Da sich die Objekte auf dem Display unter Umständen gegenseitig überlagern, muss vermutlich bei jedem am Bildschirm sichtbaren Objekt dieser Code eingegeben werden,<br />
<br />
=== Buttons auslesen ===<br />
Die Buttons auf dem Display können ausgelesen werden (anscheinend darf dazu eine Seite/page nicht ihre Component ID senden, siehe oben). Man macht dazu bei den Buttons oder Tastern einen Haken bei ''Send Component ID'' und kann dann mittels notify entsprechende Events abfangen. Typischerweise sieht ein notify so aus<br />
:<code> defmod <myname> notify myNextion:received:.H65\(e\).H01.H04.H01 {} </code>:<br />
Anscheinend sind die Elemente am Ende wie folgt zu lesen. H65 steht für ''Touch Event'' (siehe dazu auch [https://www.boecker-systemelektronik.de/epages/63381271.sf/de_DE/?ObjectPath=/Shops/63381271/Categories/Tutorials/Nextion_Tutorials/%22R%C3%BCckgabeformate%20und%20Fehlercodes%22 Böckers Übersicht]). Die erste 01 steht anscheinend für page1, der der Button entnommen wurde. 04 bezeichnet die id des Buttons (nicht den ''objname'', sondern ''id'' - rechts unter Attribute im Nextion-Editor zu erkennen). Die zweite 01 steht für das Event ''Niederdrücken'', 00 steht für ''Loslassen''.<br />
<br />
Auch einen Fehler kann man abfangen, dies geschieht mit<br />
:<code>defmode <myname> notify myNextion:received:.H00.H00.H00.H00.H00.H00.H00.H00.H00.H00.H00.* {}</code>:<br />
<br />
Einfacher geht es direkt mit dem Nextion-Editor. Trägt man den folgenden Code eines Buttons in das "Touch Release Event" ein<br />
print "button="<br />
get button.val<br />
so erscheint im Reading "rectext" des Moduls beim Drücken des Tasters "button=1" (bzw 0 bei einem dual-state Button). Man beachte, dass der print-Befehl alleine nicht notwendig in rectext einen Text liefert! Das liegt darin begründet, dass bei print keine Steuerungsbefehle gesendet werden (bei get dagegen schon), die vom Modul aber benötigt werden, um Rückmeldungen des Displays korrekt zu verarbeiten. Im Zweifel muss man den print-Befehl mit <code>get 1</code> abschließen.<br />
<br />
=== Taster entprellen? ===<br />
Die Taster auf dem Display können mit Software-Mitteln etwas entprellt werden. Dazu wird bei ''Touch Release Event(2)'' folgender Code in zwei Zeilen untereinander eingegeben<br />
<code> delay=500<br />
code_c<br />
</code><br />
Der erste Befehl sorgt dafür, dass nach der Ausführung des Tastendrucks das Diplay für 500ms steht. Eigentlich soll der zweite Befehl die Codeelemente, die in diesen 500ms in den Puffer geschrieben werden, löschen. Das scheint aber nicht zu funktionieren. Auch die Verwendung von <code>comp_stop</code> oder <code>com_start</code> brachte keine anderen Ergebnisse. In jedem Fall wird ein weiterer möglicher Tastendruck, der innerhalb dieser 500ms erfolgt, dann erst nach 500ms weitergegeben. <br />
<br />
Eventuell muss man also mit einem DOIF das Entprellen durchführen. Bei einem notify kann man das Attribut<br />
:<code>attr <myNextion_notify> disabledAfterTrigger <Sekundenbruchteile></code><br />
verwenden. Dabei kann man Werte kleiner als 1 Sekunde verwenden, siehe auch {{Link2Forum|Topic=87231|Message=98175|LinkText=dieses Forenthema}}.<br />
<br />
== Links ==<br />
* [https://nextion.itead.cc/nextion-shop/ Nextion Shop von Itead]<br />
* [https://www.boecker-systemelektronik.de/epages/63381271.sf/de_DE/?ObjectPath=/Shops/63381271/Categories/Tutorials/Nextion_Tutorials Webseiten von Böcker]<br />
* [https://nextion.itead.cc/resources/datasheets/ Datenblätter]</div>Andieshttp://wiki.fhem.de/w/index.php?title=HM-CC-RT-DN_Funk-Heizk%C3%B6rperthermostat&diff=33700HM-CC-RT-DN Funk-Heizkörperthermostat2020-08-25T19:10:28Z<p>Andies: /* Pairen bei Firmware 1.5 */</p>
<hr />
<div>{{Infobox Hardware<br />
|Bild=HM-CC-RT-DN.jpg<br />
|Bildbeschreibung=HM-CC-RT-DN an Heizkörper montiert<br />
|HWProtocol=[[HomeMatic]]<br />
|HWType=[[HomeMatic Type Thermostat|thermostat]]<br />
|HWCategory=[[:Kategorie:Heizungsventile|Heizungsventile]]<br />
|HWComm=868 MHz<br />
|HWChannels=6<br />
|HWVoltage=3&nbsp;V<br />
|HWPowerConsumption=180&nbsp;mA<br />
|HWPoweredBy=2x LR6/Mignon/AA<br />
|HWSize=54x65x93 mm (BxHxT)<br />
|HWDeviceFHEM=[[CUL_HM]]<br />
<!-- |ModOwner= --><br />
|HWManufacturer=ELV / eQ-3<br />
}}<br />
<br />
'''HM-CC-RT-DN''' (häufig einfach '''RT''' genannt) ist ein Funk-''Heizkörperthermostate'' mit integriertem ''Stellantrieb''. Das Thermostat ist seit September&nbsp;2013 verfügbar und ist der Nachfolger des [[HM-CC-VD Funk-Stellantrieb]]s.<br />
<br />
== Vorbemerkungen ==<br />
: ''→ Einstellungen und Informationen, die alle [[HomeMatic]] Thermostate betreffen, sind unter [[HomeMatic Type Thermostat#Temperaturlisten|HomeMatic Type Thermostat]] zu finden.''<br />
<br />
Der HM-CC-RT-DN kann die Temperatur selbst messen (im Gegensatz zum [[HM-CC-VD Funk-Stellantrieb|Vorgänger]]) und verfügt über eine Fenster-Offen-Erkennung sowie eine Boost-Funktion. Der HM-CC-RT-DN ''kann'' von einem [[HM-TC-IT-WM-W-EU Funk-Wandthermostat AP]] gesteuert werden, das ist aber ''optional''.<br />
<br />
Das Gerät wird seit Anfang Oktober 2013 von FHEM unterstützt (siehe Diskussion im {{Link2Forum|Topic=14738|LinkText=Forum}}).<br />
<br />
Der HM-CC-RT-DN scheint das erste HomeMatic-Device zu sein, bei dem ein Update der Firmware auch vom Anwender durchgeführt werden kann. Ein Firmware-Update erfordert einen [[HM-CFG-USB_USB_Konfigurations-Adapter|USB Konfigurations-Adapter]] und eine auf der eQ-3 Webseite herunterladbare Firmwareupdate-Software. Weitere Details sind unter [[#Firmware Update|Firmware Update]] beschrieben.<br />
{{Hinweis|Die Solltemperaturen eines HM-CC-RT-DN lassen sich ''nicht'' durch einen [[HM-CC-TC Funk-Wandthermostat]] ''steuern''. Dieser kann nur die Ist-Temperatur an den HM-CC-RT-DN weitergeben, damit nicht die am HM-CC-RT-DN direkt gemessene Raumtemperatur zur Regelung verwendet wird.}}<br />
Mit einem HM-CC-RT-DN können maximal (neben der Zentrale/FHEM):<br />
* 7 HomeMatic Heizkörperthermostate<br />
* 8 HomeMatic Tür-Fensterkontakte / Fenster-Drehgriffkontakte<br />
* 8 Tastenpaare von HomeMatic Fernbedienungen bzw. Display-Wandtaster<br />
* 1 HomeMatic Innen-Temperatur-Sensor<br />
[[Peering (HomeMatic)|gepeert]] werden.<br />
<br />
{{Hinweis|Wird für Wartungs-/Umbaumaßnahmen das Wasser der Heizung abgelassen bzw. diese neubefüllt, sind alle Stellantriebe manuell dauerhaft auf '''on''' zu setzen: set <HM_Stellantrieb>_Clima controlManu on. Beim Einsatz eines Wandthermostaten ist der Wandthermostat entsprechend einzustellen.}}<br />
<br />
== Technische Daten ==<br />
* Betriebsspannung: 2 Stck. 1,5V LR6/Mignon/AA<br />
* Stromaufnahme: 180 mA max.<br />
* Abmessungen (B x H x T): 54 x 65 x 93 mm<br />
* Gewicht: 180 g (ohne Batterien)<br />
* Ventilanschluss: M30 x 1,5 mm<br />
<br />
Aktuelle Firmware: 1.5 (2020)<br />
<br />
== Betrieb mit FHEM ==<br />
Der Funk-Heizkörperthermostat muss zuerst mit FHEM [[Pairing (HomeMatic)|gepairt]] werden. Stellen Sie sicher, dass FHEM aktuell ist ([[update]] durchführen)<br />
<br />
Das Pairing sollte wie in [[HomeMatic Devices pairen]] beschrieben durchgeführt werden (mittlere Taste mindestens drei Sekunden drücken, um den Vorgang auszulösen). Vereinzelt muss mehrfach gepairt werden, es wurde auch berichtet, dass dabei die Batterie zwichendurch entfernt und neu eingelegt werden muss.<br />
<br />
=== Channels (Kanäle) ===<br />
==== Channel (Kanal) 01 _Weather ====<br />
<br />
Dieser Kanal dient zur Einspeisung der (gemessenen) ''Ist-Temperatur''. Als Sensor können zum Beispiel das [[HM-TC-IT-WM-W-EU Funk-Wandthermostat AP|HM-TC-IT-WM-W-EU Funk-Wandthermostat]] oder ein [[HM-WDS40-TH-I Funk-Temperatur-/Feuchtesensor innen (IT)|HM-WDS40-TH-I Funk-Temperatur-/Feuchtesensor]] dienen.<br />
<br />
Ein Temperatur-Sensor ''tempSensor'' kann mit dem ''_Weather''-Kanal wie folgt [[Peering (HomeMatic)|gepeert]] werden: <br />
<br />
set <HM-TC-IT-WM-W-EU>_Weather peerChan 0 <HM-CC-RT-DN>_Weather single set<br />
<br />
Beispiel:<br />
set EG_Buero_WANDTHERMOSTAT_Weather peerChan 0 EG_Buero_THERMOSTAT_Weather single set<br />
<br />
ACHTUNG: Das Wandthermostat sowie das Thermostat Ventil (Beispiel "EG_Buero_WANDTHERMOSTAT" und EG_Buero_THERMOSTAT) werden vorher in FHEM den Status "CMDs_done" anzeigen.<br />
Beim peerChan wird dann bei beiden "CMDs_pending" stehen. Wobei das Wandthermostat sehr schnell wieder auf CMDs_done zurück springt.<br />
Allerdings ist dringend darauf zu achten, dass das Thermostat Ventil auch wieder auf "CMDs_done" wechselt, bevor man den nächsten Befehl absendet.<br />
Das Heizkörper Ventil kann unter Umständen 3 bis 5 min benötigen bis wieder "CMDs_done" steht. Evtl. kann man dies durch die BOOST Taste beschleunigen. Da das Ventil etwa alle 3 min aufwacht, prüft und Daten sendet / empfängt. Sollte man mit dem Befehlen weiter gemacht haben, so kann es zu dem Problem führen, dass einer nicht mehr mit dem Pending aufhört. In dem Fall empfiehlt es sich beide Devices von FHEM abzumelden und auf Werkseinstellung zu resetten. <br />
<br />
Zum Test haucht man das Wandthermostat an oder hält es einige Zeit in der Hand bis die Temperatur steigt, nach etwa 3 Minuten sollte man auch am Thermostat Ventil einen Temperaturanstieg sehen.<br />
<br />
==== Channel (Kanal) 02 _Climate ====<br />
Dieser Kanal erlaubt es dem [[HM-TC-IT-WM-W-EU Funk-Wandthermostat AP|HM-TC-IT-WM-W-EU Funk-Wandthermostat]] den HM-CC-RT-DN zu steuern. Dazu müssen die beiden Geräte gepeert werden:<br />
<br />
set <HM-TC-IT-WM-W-EU>_Climate peerChan 0 <HM-CC-RT-DN>_Climate single set<br />
<br />
==== Channel (Kanal) 03 _WindowRec ====<br />
Mit diesem Kanal können Fensterkontakte ([[HM-SEC-SC Tür-Fensterkontakt|HM-SEC-SC]] und [[HM-Sec-RHS Funk-Fenster-Drehgriffkontakt|HM-SEC-RHS]]) ihren Fensterstatus (geöffnet / gekippt) an ein oder mehrere Thermostate senden. Die Thermostate stellen anschließend die entsprechende (konfigurierbare) Temperatur ein. Der Temperaturwert kann je Fenster-Sensor unterschiedlich definiert werden. Sind mehrere Fenster gleichzeitig geöffnet, so wird der Thermostat auf die Temperatur des Sensors mit dem geringsten Temperaturwert eingestellt. <br />
Ferner wird empfohlen, bei Einsatz von externen Sensoren, die interne „Fenster auf Erkennung“ zu deaktivieren (weitere Details sind im [[HM-CC-RT-DN Funk-Heizkörperthermostat#Channel .28Kanal.29 04 _Clima|Channel (Kanal) 04 _Clima]] beschrieben).<br />
<br />
Der Befehl zum Peeren lautet, wobei <fensterSensor> die FHEM-Kanalbezeichnung für den Fensterkontakt ist und <rt_WindowRec> die Kanalbezeichnung für den entsprechenden Kanal des Heizkörperthermostates (siehe [https://forum.fhem.de/index.php/topic,41541.msg348044.html#msg348044 diesen Thread]):<br />
set <fensterSensor> peerChan 0 <rt_WindowRec>_WindowRec single <br />
<br />
Zum Löschen (=unpeeren) dieser Kopplung:<br />
set <fensterSensor> peerChan 0 <rt_WindowRec>_WindowRec single unset<br />
<br />
'''Achtung''': Der Peer-(Lösch-)Vorgang muss erst am Fensterkontakt durch Drücken der Anlerntaste ausgelöst werden, und zwar auch dann, wenn der Fensterkontakt schon vorher mit FHEM gepairt wurde. Dann kann der oben genannte Befehl in FHEM abgesetzt werden. Wichtig scheint auch, dass der Fensterkontakt geschlossen ist wenn man die Anlerntaste drückt.<br />
<br />
Der Befehl zur Temperatureinstellung des Heizkörperthermostaten für den Zustand "Fenster offen" lautet, wobei <fensterSensor> die FHEM-Kanalbezeichnung für den Fensterkontakt ist und <rt_WindowRec> die Kanalbezeichnung für den entsprechenden Kanal des Heizkörperthermostates, sowie <Temp> die einzustellende Temperatur (ganzzahliger Wert):<br />
set <rt_WindowRec>_WindowRec regSet winOpnTemp <Temp> <fensterSensor><br />
<br />
Weitere Hinweise im Forum, siehe {{Link2Forum|Topic=41541|Message=348044|LinkText=FHEM Forum-Beitrag}}<br />
<br />
==== Channel (Kanal) 04 _Clima ====<br />
Dieser Kanal dient zum Einstellen der Betriebsparameter, auch [[#Temperaturlisten|Temperaturlisten]] sind hierauf zu übertragen.<br />
Mit dem Modul [[Weekprofile|Wochenplan / Weekprofile]] können die Wochenpläne komfortabel in FHEM erstellt und an die Thermostate übertragen werden.<br />
<br />
{{Hinweis|In älteren Versionen von FHEM wurde dieser Kanal durch ''autocreate'' als <code>_ClimRT_tr</code> angelegt. Der Hersteller hat hier offenbar die internen Bezeichnungen geändert, denn beim Vorläufermodell HM-CC-TC mussten Temperaturlisten auf den Kanal ''Climate'' übertragen werden.}}<br />
<br />
Die maximale Öffnung des Ventils kann mittels folgendem Befehl eingestellt werden (hier auf 80 %):<br />
set <HM-CC-RT-DN>_Clima regSet valveMaxPos 80<br />
<br />
Die interne "Fenster-auf"-Erkennung kann man wie folgt abschalten:<br />
set <HM-CC-RT-DN>_Clima regSet winOpnMode off<br />
<br />
==== Channel (Kanal) 05 _ClimaTeam ====<br />
Dieser Kanal erlaubt es mehrere HM-CC-RT-DN zu einem "Team" zu gruppieren. Ein Mitglied des Teams meldet<br />
* Änderungen der Temperatur am Handrad<br />
* Einschalten des Boost-Modus am Taster<br />
an seine "Teamkollegen" weiter. Folgende Änderungen werden '''nicht''' weitergegeben:<br />
* Status der Fensterkontakte<br />
* Temperaturlisten/Wochenplan und daraus folgende Änderungen<br />
* Änderungen durch Fernbedienungen<br />
* Änderungen durch eine HomeMatic-Zentrale<br />
<br />
Befehl zum Peeren, wobei ''<HM-CC-RT-DN#1>_ClimaTeam'', ''<HM-CC-RT-DN#2>_ClimaTeam'', ..., ''<HM-CC-RT-DN#8>_ClimaTeam'' die Kanalbezeichnungen der jeweiligen ClimaTeam-Kanäle sind:<br />
set <HM-CC-RT-DN#1>_ClimaTeam peerChan 0 <HM-CC-RT-DN#2>_ClimaTeam single<br />
set <HM-CC-RT-DN#1>_ClimaTeam peerChan 0 <HM-CC-RT-DN#3>_ClimaTeam single<br />
set <HM-CC-RT-DN#2>_ClimaTeam peerChan 0 <HM-CC-RT-DN#3>_ClimaTeam single<br />
...<br />
<br />
==== Channel (Kanal) 06 _remote ====<br />
Dieser Kanal kann an eine Fernbedienung gekoppelt werden. Per Tastendruck kann man einen bestimmten Mode und/oder eine bestimmte Temperatur wählen. Dabei kann die Reaktion auf einen langen oder kurzen Tastendruck gesondert eingestellt werden.<br />
<br />
Der Befehl zum Peeren lautet, wobei <button> die Kanalbezeichnung der Fernbedienung und <rt-remote> die Kanalbezeichnung des Heizkörperthermostates ist:<br />
set <button> peerChan 0 <HM-CC-RT-DN>_remote single<br />
<br />
=== Betriebsmodus Auto, Manu, Party (Urlaub) ===<br />
<br />
Der HM-CC-RT-DN verfügt über drei Betriebsmodus: Auto, Manu (Manuell) und Party (Urlaub). <br />
<br />
==== Modus Auto ====<br />
Das Gerät arbeitet gemäß des gespeicherten Wochenprogramms. Manuelle Änderungen sind möglich, werden aber beim nächsten Schaltpunkt überschrieben.<br />
<br />
==== Modus Manu ====<br />
Die Temperatur wird manuell eingestellt, das Wochenprogramm wird nicht abgearbeitet. "Manuell Einstellen" bedeutet entweder am Handrad oder durch Übermittlung eines "set desired temp"-Befehls von FHEM (oder equivalent von einer CCU).<br />
<br />
==== Modus Party (Urlaub) ====<br />
Die eingestellte Temperatur gilt bis zu einem gegebenen Endzeitpunkt, anschließend wechselt das Thermostat in den ''Auto''-Modus. <br />
<br />
==== Welchen Modus nutzen? ====<br />
Im Umfeld von FHEM sind alle drei Modi einsetzbar. Betrieb in "Auto" hat den Vorteil, dass bei Ausfall der FHEM-Instanz der Thermostat trotzdem noch die eingespeicherten Wochenprogramme abarbeitet. Nachteilig ist aber, dass die Steuerung komplexer wird, weil sowohl die Einstellungen am Thermostat als auch Schaltbefehle von FHEM das Verhalten beeinflussen. Vielfach wird daher im Umfeld von FHEM der Modus "Manu" benutzt, hier wird die Temperatur nur per einzelnem FHEM Schaltbefehl gesteuert, ausgelöst z.b. durch "at" Kommandos, Anwesenheitserkennung oder Bewegungsmelder. Sollte FHEM (oder die Funkverbindung) ausfallen, bleibt der Thermostat allerdings auf der letzten eingestellten Temperatur stehen.<br />
<br />
Denkbar ist auch, den Modus "Auto" zu verwenden und dann die Steuerung per FHEM dadurch durchzuführen, dass durch FHEM die Wochenprogramme verändert werden. Dies verbindet zwar die Vorteil der vorgenannten Methoden, ist aber am Aufwendigsten in der Programmierung und erzeugt die höchste Funklast.<br />
<br />
Auch der Urlaubsmodus ist einsetzbar, so kann beispielsweise bei Abwesenheit ein niedrigeres Temperaturprofil eingestellt werden, ohne dass eventuell vorhandene Temperaturlisten verändert werden müssen.<br />
<br />
set <HM-CC-RT-DN>_Clima controlParty 16 06.12.13 16:30 09.12.13 05:00<br />
<br />
Dadurch wird <br />
* von 06.12.2013, 16:30 Uhr<br />
* bis 09.12.2013, 05:00 Uhr <br />
* die gewünschte Raumtemperatur auf 16 °C eingestellt.<br />
<br />
{{Hinweis|<br />
* Der Befehl muss auf dem Kanal 4 ''(_Clima)'' erfolgen.<br />
* Es werden nur Uhrzeiten zu jeder vollen oder halben Stunde angenommen (Minuten also 00 oder 30).}}<br />
<br />
Mit der folgenden Funktion <code>Urlaub()</code> kann man eine ganze Wohnung (also mehrere RTs) mit nur einem Befehl in den Party-Modus versetzen. Im Beispiel werden zwei Heizkörper ("Treppenhaus" und "Kammer") angesteuert.<br />
<br />
Zu beachten sind folgende Dinge:<br />
# Aktuelle Dateien (z.B. <code>10_CUL_HM</code>) verwenden!<br />
# Bei dem ''controlParty''-Befehl ''kein'' Komma zwischen den Parametern.<br />
# Bei der Funktion die Parameterübergabe definieren <code>($$$$$)</code><br />
<br />
'''Aufruf:'''<br />
:<code>{Urlaub ("16", "06.12.13", "16:30", "09.12.13" ,"05:00")}</code><br />
<br />
'''Funktion:'''<br />
<syntaxhighlight lang=perl><br />
my $Urlaub;<br />
sub<br />
Urlaub($$$$$)<br />
{<br />
my ($temp, $startDate, $startTime, $endDate, $endTime) = @_;<br />
<br />
# HM-CC-RT-DN akzeptiert nur Zeiten, die auf Minute 00 oder 30 enden.<br />
# Daher $startTime und $endTime abrunden<br />
$startTime =~ s/\:[0-2].$/:00/;<br />
$startTime =~ s/\:[3-5].$/:30/;<br />
$endTime =~ s/\:[0-2].$/:00/;<br />
$endTime =~ s/\:[3-5].$/:30/;<br />
<br />
# controlParty bei jedem HM-CC-RT-DN setzen.<br />
for my $rt (qw(Kammer Treppenhaus)) {<br />
fhem ("set $rt controlParty $temp $startDate $startTime $endDate $endTime");<br />
}<br />
}<br />
</syntaxhighlight><br />
<br />
=== Tastensperre ===<br />
<br />
Um zu verhindern, dass der Modus oder die Temperatur per Tasten bzw. Drehrad am HM-CC-RT-DN verändert wird, kann eine Tastensperre gesetzt werden. Dies erfolgt mittels des Befehls:<br />
<br />
set <HM-CC-RT-DN> regSet btnLock on<br />
<br />
Rückgängig machen geht per:<br />
<br />
set <HM-CC-RT-DN> regSet btnLock off<br />
<br />
Diese Tastensperre kann man aber am HM-CC-RT-DN durch eine Tastenkombination wieder zurücksetzen. Um sie nur per FHEM rücksetzen zu können, muss<br />
<br />
set <HM-CC-RT-DN> regSet globalBtnLock on<br />
<br />
eingegeben werden. Rückgängig geht wieder per:<br />
<br />
set <HM-CC-RT-DN> regSet globalBtnLock off<br />
<br />
Es gibt auch eine Tastensperre die nur das Umschalten des Modus (Auto, Manuell, Urlaub) am Gerät verhindert. Diese wird mit<br />
<br />
set <HM-CC-RT-DN> regSet modusBtnLock on<br />
<br />
eingeschaltet. Abschalten geht mit:<br />
<br />
set <HM-CC-RT-DN> regSet modusBtnLock off<br />
<br />
=== Burst-Modus ===<br />
Das ist ein '''Übertragungs'''modus für Nachrichten zwischen HM-Geräten und der Zentrale. Der RT erwacht alle 2,5 Minuten und dann überträgt die Zentrale die Kommandos. Wenn man einen Fensterkontakt oder eine Fernsteuerung nutzt, muss der RT sofort reagieren - dann muss man den Burst ''enablen''. Der RT kann in diesem Fall sofort aufgeweckt werden und bearbeitet die Anforderung (Request). Das kann man auch von der Zentrale aus nutzen (so man möchte). Das ist der '''Vorteil''' des eingeschalteten Burst-Modus.<br />
<br />
'''Nachteil:''' Der Burst-Modus benötigt mehr Leistung, das heißt die Batterien müssen häufiger gewechselt werden: Der RT muss den Receiver ständig empfangsbereit halten. Außerdem wachen bei jedem Burst ''alle'' Burst-Empfänger auf – egal an wen die Kommunikation gerichtet war.<br />
<br />
'''Burst – wie es funktioniert'''<br />
<br />
Schickt ein Sender eine burst Sequenz, wachen alle burst-Empfänger auf und prüfen die Message. <br />
Wenn sie betroffen sind bleiben sie eine Zeit lang wach, ansonsten schlafen sie wieder ein. <br />
Man beachte also, dass Senden eines Burst Energie in ALLEN burst-Empfängern verbraucht, egal ob sie angesprochen sind.<br />
<br />
'''HMLAN und burst'''<br />
<br />
[[HMLAN]] hat ein Sendebudget das über eine Stunde berechnet wird. Burst belastet dieses Konto deutlich - so können nicht mehr als 100 bursts /h gesendet werden - dann geht HMLAN in overload. Wenn zusätzliche Nachrichten gesendet werden sind es entsprechend weniger. <br />
Es ist nicht vorteilhaft, unnötig bursts zu senden.<br />
<br />
'''Burst devices'''<br />
<br />
Es gibt Devices, die immer auf burst reagieren und solche bei denen es abgeschaltet werden kann. So reagiert ein Rauchmelder immer auf Burst damit er seine Team-Kollegen hören kann. <br />
Ein TC oder RT hingegen hat diese Funktion abschaltbar. 'Per default ist dies ausgeschaltet um Batterie zu sparen'. Wenn ein VD gesteuert wird ist der TC ja selbst wach. Wird er aber mit einem Fensterkontakt gekoppelt muss es eingeschaltet werden – sonst verpasst er die Nachricht. <br />
<br />
'''ConditionalBurst devices'''<br />
<br />
Devices mit abschaltbarem Burst wie z.B. der ''HM-CC-RT-DN'' haben ein Register, ''burstRx'', mit dem das burst-Erwachen eingestellt werden kann. <br />
Sendern, die einen burst-Aktor erwecken sollen, muss man sagen, welcher Peer Burst benötigt. Hier kann ggf. das Register ''peerNeedsBurst'' nach dem Peeren gesetzt werden. FHEM versucht dies automatisch beim Peeren zu erledigen. Siehe [[HomeMatic HMInfo|HMinfo]] Befehl ''models'' um herauszufinden, welche Devices welchen Modus unterstützen.<br />
<br />
'''Attribut burstAccess''' <br />
<br />
Devices, die abschaltbaren burst haben kann man ein attribut burstAccess 1_auto setzen. Es wird beim Abschicken eines Kommandos versucht, das Device mit burst zu wecken. Sollte es nicht funktionieren wird gewartet, bis das Device aufwacht (meist reagieren solche Devices auch auf wakeup). Das Setzen des Attributs ist angenehm – es werden aber ggf. viele bursts gesendet.<br />
<br />
'''Kommando burstXmit'''<br />
<br />
Mit diesem Kommando, das bei Devices mit conditional-Burst zu Verfügung steht, wird der burst gezielt vom User angestoßen.<br />
<br />
Der User schickt erst seine Kommandos an das device. Die Kommandos werden im Command-stack gesammelt. <br />
<br />
Dann sendet der User ein set burstXmit.<br />
<br />
Es passiert das gleiche wie bei burstAccess.<br />
<br />
FHEM versucht mittels burst zu wecken und sendet bei Erfolg die Messages aus dem Kommandostack. <br />
<br />
Im Gegensatz zu burstAccess ist burstXmit gezielt einsetzbar und kann sparsamer verwendet werden.<br />
<br />
''' FHEM und burst devices'''<br />
<br />
FHEM sendet eine burst automatisch mit Kommandos zu Devices, die nur burst unterstützen.<br />
<br />
'''So aktiviert man den burst-Betrieb am HM-CC-RT-DN'''<br />
<br />
''Burst Mode einschalten'' (der Kanal 4 des Device WZ1 heisst hier WZ1_4)<br />
:<code>set WZ1_4 regSet burstRx on </code><br />
prüfen mit:<br />
:<code>get WZ1_4 reg burstRx </code><br />
''Nun in FHEM den Burst mode einschalten (sofern nicht burstXmit verwendet wird)''<br />
:<code>attr WZ1 burstAccess 1_auto</code><br />
<br />
Hinweis: Das Attribut im Device und nicht im Kanal setzen, ansonsten gibt es eine Fehlermeldung.<br />
<br />
=== Temperaturlisten ===<br />
Die Temperaturlisten des HM-CC-RT-DN werden identisch mit denen anderer HomeMatic Thermostate verwaltet (siehe [[HomeMatic Type Thermostat#Temperaturlisten|HomeMatic Type Thermostat]]). Beim HM-CC-RT-DN ist der Kanal 4 (_Clima) für die Temperaturlisten zuständig.<br />
<br />
==FHEM-Log==<br />
In den folgenden Logs heißt Kanal 4 noch "_ClimRT_tr". Inzwischen würde man dort "_Clima" sehen.<br />
<br />
=== Device-Log ===<br />
2013.10.10 20:03:24 3: CUL_HM Unknown device CUL_HM_HM_CC_RT_DN_2212BC, please define it<br />
2013.10.10 20:03:24 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC CUL_HM 2212BC A1A0184002212BC0000001000954B4551303531303031375900FFFF<br />
2013.10.10 20:03:24 3: Device CUL_HM_HM_CC_RT_DN_2212BC added to ActionDetector with 000:10 time<br />
2013.10.10 20:03:24 3: CUL_HM pair: CUL_HM_HM_CC_RT_DN_2212BC thermostat, model HM-CC-RT-DN serialNr KEQ0510017<br />
2013.10.10 20:03:24 3: LANCUL pairing (hmPairForSec) not enabled<br />
2013.10.10 20:03:24 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC-%Y.log CUL_HM_HM_CC_RT_DN_2212BC<br />
2013.10.10 20:03:24 3: Device Heizung_Wohnzimmer added to ActionDetector with 000:10 time<br />
2013.10.10 20:03:24 3: CUL_HM pair: Heizung_Wohnzimmer thermostat, model HM-CC-TC serialNr JEQ0044286<br />
2013.10.10 20:03:24 3: Device CUL_HM_HM_CC_RT_DN_2212BC added to ActionDetector with 000:10 time<br />
2013.10.10 20:03:24 3: CUL_HM pair: CUL_HM_HM_CC_RT_DN_2212BC thermostat, model HM-CC-RT-DN serialNr KEQ0510017<br />
2013.10.10 20:03:25 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_Weather CUL_HM 2212BC01<br />
2013.10.10 20:03:25 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_Weather FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_Weather-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_Weather<br />
2013.10.10 20:03:25 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_Weather FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_Weather-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_Weather<br />
2013.10.10 20:03:26 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_Climate CUL_HM 2212BC02<br />
2013.10.10 20:03:26 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_Climate FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_Climate-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_Climate<br />
2013.10.10 20:03:26 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_Climate FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_Climate-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_Climate<br />
2013.10.10 20:03:27 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_WindowRec CUL_HM 2212BC03<br />
2013.10.10 20:03:27 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_WindowRec FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_WindowRec-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_WindowRec<br />
2013.10.10 20:03:27 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_WindowRec FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_WindowRec-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_WindowRec<br />
2013.10.10 20:03:28 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr CUL_HM 2212BC04<br />
2013.10.10 20:03:28 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr<br />
2013.10.10 20:03:28 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr<br />
2013.10.10 20:03:29 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam CUL_HM 2212BC05<br />
2013.10.10 20:03:29 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam<br />
2013.10.10 20:03:29 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_ClimaTeam<br />
2013.10.10 20:03:30 2: autocreate: define CUL_HM_HM_CC_RT_DN_2212BC_remote CUL_HM 2212BC06<br />
2013.10.10 20:03:30 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_remote FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_remote-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_remote<br />
2013.10.10 20:03:30 2: autocreate: define FileLog_CUL_HM_HM_CC_RT_DN_2212BC_remote FileLog /usr/local/FHEM/var/log/CUL_HM_HM_CC_RT_DN_2212BC_remote-%Y.log CUL_HM_HM_CC_RT_DN_2212BC_remote<br />
2013.10.10 20:03:35 3: Device CUL_HM_HM_CC_RT_DN_2212BC added to ActionDetector with 000:10 time<br />
2013.10.10 20:03:40 2: CUL_HM set CUL_HM_HM_CC_RT_DN_2212BC getSerial<br />
2013.10.10 20:03:40 2: CUL_HM set CUL_HM_HM_CC_RT_DN_2212BC getConfig<br />
2013.10.10 20:03:54 3: Device CUL_HM_HM_CC_RT_DN_2212BC added to ActionDetector with 000:10 time<br />
<br />
=== Event monitor ===<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr motorErr: ok<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr measured-temp: 18.4<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr desired-temp: 18<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr ValvePosition: 3 %<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr mode: manu<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr unknown0: 24<br />
2013-10-12 12:05:35.610 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC_ClimRT_tr T: 18.4 desired: 18 valve: 3 %<br />
2013-10-12 12:05:35.646 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC battery: ok<br />
2013-10-12 12:05:35.646 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC batteryLevel: 3.1 V<br />
2013-10-12 12:05:35.646 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC measured-temp: 18.4<br />
2013-10-12 12:05:35.646 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC desired-temp: 18<br />
2013-10-12 12:05:35.646 CUL_HM CUL_HM_HM_CC_RT_DN_2212BC actuator: 3 %<br />
<br />
== Firmware Update ==<br />
Seit 24.10.2014 gibt es für den HM-CC-RT-DN die neue Firmware Version 1.4. Diese kann von der eQ-3 Webseite heruntergeladen werden. Genauere Informationen gibt es unter [[HomeMatic Firmware Update]].<br />
<br />
=== HM-CC-RT-DN spezifische Update Informationen ===<br />
Durch gleichzeitiges Drücken der "Auto-/Manu"-Taste und der "Comfort-/Eco"-Taste am HM-CC-RT-DN während man die Batterien wieder einlegt wird der updatemodus gestartet. Während des Updates steht "FUP" im Display. Nach erfolgreichem Update erscheint "Ins" im Display und es muss eine erneute Adaptierfahrt durch Drücken der Boost-Taste ausgelöst werden. Anschließend sollte der HM-CC-RT-DN wieder normal funktionieren. Die eingestellten Parameter und das Pairing mit FHEM gehen beim Update nicht verloren. Sollte das Update fehlschlagen, erscheint "Err" bzw. "CrC" im Display.<br />
<br />
Normalerweise sollte dann durch erneutes Starten der Prozedur am PC und HM-CC-RT-DN das ganze erneut durchführbar sein.<br />
<br />
Es gibt einige Readings, die nicht durch ein einfaches ''getConfig'' aktualisiert werden, z.B. "battery"(nicht batteryLevel). Um diese Readings zu bekommen, ist ein <br />
:<code>set Device_Channel04 controlMode auto </code><br />
notwendig. Daraufhin werden die Readings übertragen/aktualisiert.<br />
<br />
== Simulation von Fensterkontakten und externen Temperatursensoren ==<br />
{{Randnotiz|RNTyp=r|RNText=Für jeden separat zu steuernden HM-CC-RT-DN kann nur je ein Kanal eines virtuellen Devices als Temperatur- bzw. Fensterkontakt genutzt werden. Insbesondere die virtuellen Kanäle der VCCU eignen sich nicht dazu, mehrere HM-CC-RT-DN unabhängig voneinander anzusteuern! Hat man mehrere unabhängig arbeitende RT's, muß für jeden auch ein '''eigenes virtuelles Gerät''' angelegt werden! <br />
<br />
Die folgenden Beispiele sind nicht für Anfänger und Unwissende geeignet! Es gibt zahlreiche Stolpersteine:<br />
# Die HMId für virtuelle Geräte muss einmalig im System sein. Sie muss selbst gewählt werden und es darf '''keine''' vorhandene ID verwendet werden!<br />
# Es kann vorkommen, das beim Anlegen eines virtual Gerätes kein attr IODev gesetzt wird. Das Attribute ist aber notwendig, sonst arbeitet das Gerät nicht! Bitte kontrollieren und gegebenenfalls per Hand setzen.<br />
}}<br />
Grober Ablauf:<br />
* erstelle ein virtuelles Device<br />
* erstelle dazu einen virtuellen Kanal (bzw. mehrere, wenn sowohl ein virtueller Fensterkontakt wie ein virtueller Temperaturkanal benötigt werden).<br />
* peere den Kanal mit dem RT (als Fenster-Kontakt oder als remote, wenn du willst)<br />
* sende ein postEvent / stelle die neue Temperatur im Kanal ein<br />
<br />
=== Fensterkontakte ===<br />
''Angelehnt an diese {{Link2Forum|Topic=31078|Message=236245|LinkText=Forenbeitrag}}''<br />
define virtKitchenSensors CUL_HM 221133<br />
Um das Device als virtuelles zu kennzeichnen benötigt man den folgenden Befehl (legt weitere Attribute an): <br />
attr virtKitchenSensors modelForce VIRTUAL<br />
<br />
Kanal bzw. Kanäle erstellen:<br />
set virtKitchenSensors virtual 1 <br />
oder (für das Anlegen je eines Kanals für einen Fenster- und Temperatur-Kanal):<br />
set virtKitchenSensors virtual 2 <br />
Als Zwischenergebnis sehen wir in der Detailansicht des ''virtKitchenSensors'' ein bzw. zwei weitere Devices mit Namen ''virtKitchenSensors_Btn1'' bzw. ''virtKitchenSensors_Btn2''. <br />
<br />
Umbenennen des 1. Kanals: <br />
rename virtKitchenSensors_Btn1 virtualKitchenDoor<br />
<br />
Danach sollte man das webCmd-Attribut wie folgt vergeben:<br />
attr virtualKitchenDoor webCmd postEvent open:postEvent closed <br />
<br />
Anschließend peeren und (wer weniger wie den default-Wert von 12°C einstellen möchte) Temperatur festlegen mit:<br />
set virtualKitchenDoor peerChan 0 <Thermostat_Window_Rec> single set<br />
set <Thermostat_Window_Rec> regSet winOpnTemp 5 virtualKitchenDoor<br />
<br />
Ggf noch interne "Fenster-auf" Erkennung abschalten<br />
set <HM-CC-RT-DN>_Clima regSet winOpnMode off<br />
<br />
Die virtuelle Tür wird dann entsprechend über ein Notify getriggert.<br />
Einfache Form (nur ein Fensterkontakt im Raum):<br />
define notify_virtualKitchenDoor notify Fensterkontakt_1:(open|closed) set virtualKitchenDoor postEvent $EVENT<br />
Komplexere Form (zwei Fensterkontakte):<br />
define notify_virtualKitchenDoor notify (Fensterkontakt_1|Fensterkontakt_2) {if($EVENT eq "open" and Value("virtualKitchenDoor") eq "set_postEvent closed"){fhem("set virtualKitchenDoor postEvent open")} elsif (Value("virtualKitchenDoor") eq "closed" && Value("Fensterkontakt_2") eq "closed") {fhem("set virtualKitchenDoor postEvent closed")}}<br />
{{Hinweis|Die ''postEvent''-Anweisung wird unmittelbar an die Funkschnittstelle weitergegeben und löst einen ''burst'' aus.}}<br />
<br />
=== Temperatursensoren ===<br />
''Angelehnt an diesen {{Link2Forum|Topic=19686|Message=233788|LinkText=Forenbeitrag}}''<br />
<br />
1. Virtuelles HomeMatic Device mit eigener HM Id definieren, (s.o.), es kann auch ein weiterer Kanal des oben erstellten Devices genutzt werden<br />
<br />
2. Dem Device einen virtuellen Kanal (Default ist ein virtueller Button) hinzufügen, wieder mit <code>set virtKitchenSensors virtual 1</code> bzw. <code>set virtKitchenSensors virtual 2</code> (2 geht auch, wenn bereits ein erster Kanal vorhanden war).<br />
<br />
3. Es ist kein virtueller Button sondern ein virtueller Temperatursensor - darum rename:<br />
rename virtKitchenSensors_Btn1 Kitchen_vT_Sensor1<br />
bzw. <code>rename virtKitchenSensors_Btn2 Kitchen_vT_Sensor1</code><br />
<br />
4. Virtuellen Peer Sensor mit dem Weather Channel des RT-DN peeren:<br />
set Kitchen_vT_Sensor1 peerChan 0 <RT_DN>_Weather single<br />
<br />
5. Peering kontrollieren (Voraussetzung: Device ''hm'' vom Typ [[HomeMatic HMInfo|HMinfo]] existiert):<br />
:<code>set hm peerXref</code><br />
Beispiel-Ausgabe:<br />
peerXref done: <br />
x-ref list <br />
wz_Thermostat_Weather => Kitchen_vT_Sensor1 <br />
Kitchen_vT_Sensor1 => wz_Thermostat_Weather<br />
<br />
6. Gemessene Temperatur vom z.B. 1-Wire DS1820 dem virtuellen HM Sensor übergeben. Z.B. alle zwei Minuten per notify:<br />
define at_Kitchen_vT notify myRealKitchenTempSensor:temperature:.* set Kitchen_vT_Sensor1 virtTemp $EVTPART1<br />
<br />
{{Hinweis|Die ''virtTemp''-Anweisung ändert zunächst nur den Wert im virtuellen Kanal. Diese wird zu bestimmten Zeiten als ''broadcast'' gesendet. Diese Zeiten kennt der RT und hält sich kurzfristig empfangsbereit.}}<br />
Sollte es Probleme geben, dass der RT des Öfteren wieder auf seine eigenen Messwerte wechselt, weil die von FHEM errechnete Sendezeit und die vom RT errechnete Empfangszeit zu weit auseinanderliegen, sollte das Attr cyclicMsgOffset im Virtuellen Kanal beachtet werden. Näheres dazu ist ca. ab {{Link2Forum|Topic=45735|Message=572806|LinkText=hier}} im Forum zu finden.<br />
<br />
7. Sicherstellen, dass nicht längerfristig veraltete Temperaturdaten berücksichtigt werden:<br />
Aufgrund des oben beschriebenen Verfahrens wird solange der im virtuellen Kanal vorhandene Wert wieder gesendet, wie dieser dort steht. Fällt z.B. der echte Sensor oder das Interface nicht nur vorübergehend aus, muß der Wert gelöscht werden. Hier ein Vorschlag für ein ''at'', das alle 15 Minuten alle virtuellen Temperaturwerte löscht, die älter als eine Stunde sind, und damit den Rückfall des jeweiligen RT auf seinen internen Sensor bewirkt:<br />
defmod a_delete_outdated_virtTemps at +*00:15 {\<br />
my @vTemps = devspec2array("TYPE=CUL_HM:FILTER=model=VIRTUAL:FILTER=temperature~.+");;\<br />
foreach my $vTemp (@vTemps) {\<br />
CommandDeleteReading(undef,"$vTemp temperature" ) if ReadingsAge($vTemp,"temperature",0) > HOURSECONDS ;;\<br />
}\<br />
}<br />
=== Exkurs: HMCCUDEV ===<br />
{{Hinweis|Das Nachfolgende entspricht dem Stand Janaur 2020. Die HMCCU-Module sind jedoch derzeit in der Weiterentwicklung, so dass es sich ggf. empfiehlt, im Forum nachzufragen.}}<br />
Das Nutzen externer Sensoren scheint mit HMCCU nicht möglich zu sein, siehe {{Link2Forum|Topic=107134|LinkText=Forenbeitrag: RaspberryMatic (HMCCU) und LaCrosse Temperature als "Wandthermostat"}}, die Weitergabe eines externen Türkontakts ist eventuell möglich, siehe {{Link2Forum|Topic=106807|LinkText=Forenbeitrag: HMCCU mit Thermostat HM-CC-RT-DN und ZWave Türsensor}}, an anderer Stelle hat der Modulentwickler ausgeführt, es könnten nur {{Link2Forum|Topic=107501|Message=1015944|LinkText=Homematic Geräte}} als Sensoren verwendet werden.<br />
<br />
== Auflistung und Beschreibung der Readings ==<br />
<br />
Einige der Readings können via "regSet" parametriert werden.<br />
Wobei der Registername etwas anders geschrieben wird als der Reading Name (ohne R-).<br />
<br />
set <name> regSet <register> <value><br />
Beispiel für Reading R-winOpnPeriod erhöhen auf 60 Minuten: <br />
set EG_Buero_THERMOSTAT_Clima regSet winOpnPeriod 60<br />
<br />
Eine vollständige Liste erhält man auch, wenn man einen Falschen Register Namen angibt.<br />
supported register are backOnTime boostPeriod boostPos btnLock btnNoBckLight burstRx cyclicInfoMsg cyclicInfoMsgDis dayTemp daylightSaveTime decalcTime decalcWeekday globalBtnLock localResDis lowBatLimitRT modePrioManu modePrioParty modusBtnLock nightTemp noMinMax4Manu pairCentral regAdaptive reguExtI reguExtP reguExtPstart reguIntI reguIntP reguIntPstart showInfo showWeekday sign tempMax tempMin tempOffset valveErrPos valveMaxPos valveOffsetRt winOpnBoost winOpnDetFall winOpnMode winOpnPeriod winOpnTempI<br />
<br />
<table cellspacing="0" border="0"><br />
<tr><br />
<td style="border-top: 2px solid #ffffff; border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#A6A6A6"><font face="Arial" size=2 color="#0D0D0D">Reading</font></td><br />
<td style="border-top: 2px solid #ffffff" align="left" valign=middle bgcolor="#A6A6A6"><font face="Arial" size=2 color="#0D0D0D">Beispielwert</font></td><br />
<td style="border-top: 2px solid #ffffff" align="left" valign=middle bgcolor="#A6A6A6"><font face="Arial" size=2 color="#0D0D0D">M&ouml;gliche Werte</font></td><br />
<td style="border-top: 2px solid #ffffff; border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#A6A6A6"><font face="Arial" size=2 color="#0D0D0D">Beschreibung</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">CommandAccepted</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">yes</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">yes; no</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Letztes Kommando akzeptiert (yes/ No)</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-boostPeriod</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">5 min</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">1 min bis x min</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Zeit wie lange das Ventil im Boost Modus sein soll.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-boostPos</font></td><br />
<td align="left" valign=middle bgcolor="#111111" sdval="0.8" sdnum="1033;0;0%"><font face="Arial" size=2 color="#CCCCCC">80%</font></td><br />
<td align="left" valign=middle bgcolor="#111111" sdnum="1033;0;0%"><font face="Arial" size=2 color="#CCCCCC">0 bis 100</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Ventilposition die im Boost Modus gesetzt wird.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-btnNoBckLight</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">off</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="35" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-dayTemp</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">21 C</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Siehe R-tempMin bis R-tempMax</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Solltemperatur die gesetzt werden soll, wenn das Sonnensymbol am Thermostat gedr&uuml;ckt wird. Ebenso wird bei dieser Solltemperatur das Sonnensymbol im Display angezeigt.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-daylightSaveTime</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">on</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-decalcTime</font></td><br />
<td align="left" valign=middle bgcolor="#111111" sdval="0.458333333333333" sdnum="1033;1033;H:MM"><font face="Arial" size=2 color="#CCCCCC">11:00</font></td><br />
<td align="left" valign=middle bgcolor="#111111" sdnum="1033;1033;H:MM"><font face="Arial" size=2 color="#CCCCCC">00:00 bis 23:59</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Uhrzeit wann die Entkalkungsfahrt durchgef&uuml;hrt werden soll. </font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-decalcWeekday</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Sat</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Mon; Tue; Wed; Thu; Fri; Sat; Sun</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Tag an dem die Entkalkungsfahrt durchgef&uuml;hrt werden soll.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-modePrioManu</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">all</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">all; ???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-modePrioParty</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">all</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">all; ???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="35" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-nightTemp</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">17 C</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Siehe R-tempMin bis R-tempMax</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Solltemperatur die gesetzt werden soll, wenn das Mondsymbol am Thermostat gedr&uuml;ckt wird. Ebenso wird bei dieser Solltemperatur das Mondsymbol im Display angezeigt.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-noMinMax4Manu</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">off</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-regAdaptive</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">on</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-reguExtI</font></td><br />
<td align="left" valign=middle bgcolor="#333333" sdval="15" sdnum="1033;"><font face="Arial" size=2 color="#CCCCCC">15</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-reguExtP</font></td><br />
<td align="left" valign=middle bgcolor="#111111" sdval="30" sdnum="1033;"><font face="Arial" size=2 color="#CCCCCC">30</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-reguExtPstart</font></td><br />
<td align="left" valign=middle bgcolor="#333333" sdval="30" sdnum="1033;"><font face="Arial" size=2 color="#CCCCCC">30</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-reguIntI</font></td><br />
<td align="left" valign=middle bgcolor="#111111" sdval="18" sdnum="1033;"><font face="Arial" size=2 color="#CCCCCC">18</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-reguIntP</font></td><br />
<td align="left" valign=middle bgcolor="#333333" sdval="33" sdnum="1033;"><font face="Arial" size=2 color="#CCCCCC">33</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-reguIntPstart</font></td><br />
<td align="left" valign=middle bgcolor="#111111" sdval="44" sdnum="1033;"><font face="Arial" size=2 color="#CCCCCC">44</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-showInfo</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">time</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">date; time</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Zeige Datum oder Uhrzeit im Display an</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-showWeekday</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">off</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Zeige den Wochentag im Display an</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-sign</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">off</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-tempMax</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">30.5 C</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Gr&ouml;&szlig;te einstellbare Temperatur</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-tempMin</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">4.5 C</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Kleinste einstellbare Temperatur</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-tempOffset</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">0.0K</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">0.0 bis ???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Temperaturabweichung gemessene Temperatur vs. realer Temperatur in Grad Kelvin. Angabe in 0.5-Schritten ohne Einheitenzeichen, z.B. 0.5 oder -1.0</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-valveErrPos</font></td><br />
<td align="left" valign=middle bgcolor="#333333" sdval="0.15" sdnum="1033;0;0%"><font face="Arial" size=2 color="#CCCCCC">15%</font></td><br />
<td align="left" valign=middle bgcolor="#333333" sdnum="1033;0;0%"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-valveMaxPos</font></td><br />
<td align="left" valign=middle bgcolor="#111111" sdval="1" sdnum="1033;0;0%"><font face="Arial" size=2 color="#CCCCCC">100%</font></td><br />
<td align="left" valign=middle bgcolor="#111111" sdnum="1033;0;0%"><font face="Arial" size=2 color="#CCCCCC">0 bis 100</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Maximale Ventilstellung die das Thermostat fahren darf.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-valveOffsetRt</font></td><br />
<td align="left" valign=middle bgcolor="#333333" sdval="0" sdnum="1033;0;0%"><font face="Arial" size=2 color="#CCCCCC">0%</font></td><br />
<td align="left" valign=middle bgcolor="#333333" sdnum="1033;0;0%"><font face="Arial" size=2 color="#CCCCCC">0 Bis 100</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="52" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-winOpnBoost</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">off</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Startet nach dem Fensterschlie&szlig;en die Boostfunktion um unabh&auml;ngig von der Raumtemperatur den Heizk&ouml;rper eine Zeit x aufzuheizen. (Siehe R-boostPeriod &amp; R-boostPos)</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-winOpnDetFall</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">1.4 K</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">0.5 bis 2.5</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Temperatur Sturz zwischen zwei Messungen, die als Fenster offen erkannt werden.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="35" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-winOpnMode</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">off</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">on; off</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Thermostat soll anhand eines schnellen Temperaturabfalls erkennen, dass das Fenster ge&ouml;ffnet ist.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R-winOpnPeriod</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">15 min</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">1 bis 60 Minuten</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Dauer bis das Signal Fenster offen wieder entfernt wird.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R-winOpnTemp</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">12 C</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Siehe R-tempMin bis R-tempMax</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Temperatur die eingestellt werden soll, wenn das Fenster als offen erkannt wird.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="104" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R_0_tempListSat</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">07:00 20.0 22:30 22.0 24:00 20.0</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">incomplete = Daten werden mit Thermostat abgeglichen<br><br>Zeit/Temperaturangaben siehe Beispiel</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Tages Solltemperaturen abh&auml;ngig von der Uhrzeit. <br>- Der Beginn um 00:00 ist nicht einzutragen. <br>- Es sind immer Paare einzutragen (Uhrzeit Temperatur). <br>- Der letzte Eintrag muss an jedem Tag 24:00 sein.<br>- Uhrzeiten sind auf halbe Stunden beschr&auml;nkt. Eintr&auml;ge 08:00 und 08:30 sind g&uuml;ltig. 08:20 ist ung&uuml;ltig.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R_1_tempListSun</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">07:00 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R_2_tempListMon</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">04:30 20.0 07:00 22.0 12:45 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R_3_tempListTue</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">04:30 20.0 07:00 22.0 12:45 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R_4_tempListWed</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">04:30 20.0 07:00 22.0 12:45 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R_5_tempListThu</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">04:30 20.0 07:00 22.0 12:45 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">R_6_tempListFri</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">04:30 20.0 07:00 22.0 12:45 20.0 22:00 22.0 24:00 20.0</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Siehe R_0_tempListSat</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="35" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">R_tempList_State</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">verified</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">incomplete = Daten werden mit Thermostat abgeglichen<br>verified = Daten sind mit Thermostat abgeglichen</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Aktualisierungsstatus der Wochen Temperatur Einstellungen</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">ValvePosition</font></td><br />
<td align="left" valign=middle bgcolor="#333333" sdval="36" sdnum="1033;"><font face="Arial" size=2 color="#CCCCCC">36</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">0 bis 100</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">aktuelle Ventilstellung</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="35" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">boostTime</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">-</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">-<br>1 min bis n min</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Zeit wie lange der Boostmodus noch aktiv ist.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="121" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">controlMode</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">auto</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">auto = Thermostat wird nach der TempListe gesteuert<br>manual = Die eingestellte Temperatur am Thermostat wird nicht ver&auml;ndert, au&szlig;er bei Verwendung von WinOpn; <br>boost = Thermostat wird in den Boost Modus gesetzt. Siehe R-boostPeriod/Pos<br>day = Thermostat wird auf die eingestellte Tag Temperatur gesetzt (R-dayTemp).<br>night = Thermostat wird auf die eingestellte Nacht Temperatur gesetzt (R-nightTemp).</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Setzt das Thermostat in einen bestimmten Modus</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">desired-temp</font></td><br />
<td align="left" valign=middle bgcolor="#111111" sdval="22" sdnum="1033;"><font face="Arial" size=2 color="#CCCCCC">22</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">N/A</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Solltemperatur</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">measured-temp</font></td><br />
<td align="left" valign=middle bgcolor="#333333" sdval="23.2" sdnum="1033;"><font face="Arial" size=2 color="#CCCCCC">23.2</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">N/A</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Isttemperatur</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">partyEnd</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">-</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Ende Datum/Zeit in dem die Party Temperatur (partyTemp) gesetzt sein soll.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">partyStart</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">-</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">Start Datum/Zeit in dem die Party Temperatur (partyTemp) gesetzt sein soll.</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">partyTemp</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">-</font></td><br />
<td align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">-; 20.0</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Party Temperatur</font></td><br />
</tr><br />
<tr><br />
<td style="border-left: 2px solid #ffffff" height="21" align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">recentStateType</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">ack</font></td><br />
<td align="left" valign=middle bgcolor="#333333"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
<td style="border-right: 2px solid #ffffff" align="left" valign=middle bgcolor="#333333" sdnum="1033;1033;M/D/YYYY H:MM"><font face="Arial" size=2 color="#CCCCCC">???</font></td><br />
</tr><br />
<tr><br />
<td style="border-bottom: 2px solid #ffffff; border-left: 2px solid #ffffff" height="23" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">state</font></td><br />
<td style="border-bottom: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">T: 23.2 desired: 22.0 valve: 36</font></td><br />
<td style="border-bottom: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC"><br></font></td><br />
<td style="border-bottom: 2px solid #ffffff" align="left" valign=middle bgcolor="#111111"><font face="Arial" size=2 color="#CCCCCC">Aktuelle Statusinformation</font></td><br />
</tr><br />
</table><br />
<br />
== Bekannte Probleme ==<br />
=== TempList: Bad format ... ===<br />
Wenn Sie beim Setzen einer Temperaturliste nach dem o.a. Schema ("SetTempList...") die Meldung<br />
<br />
Bad format, use HH:MM TEMP ......<br />
<br />
erhalten, sollten Sie zunächst ein [[update]] von FHEM durchführen.<br />
<br />
=== Der Thermostat heizt über die Solltemperatur hinaus ===<br />
In der Regel ist das ein ganz normales Verhalten, wenn der Thermostat nicht mit einem externen Temperaturfühler oder einem Wandthermostat gepeert ist. In dem Fall muss sich der Thermostat auf den eingebauten Temperatursensor verlassen, der sehr nahe an der Heizung selbst sitzt. Dadurch ist die gemessene Temperatur höher, als sie z.B. in der Raummitte wäre. Der Hersteller hat hier einen mehr oder weniger intelligenten Algorithmus eingebaut, um diesen Effekt zu kompensieren. Das sieht dann so aus, als ob der Thermostat nicht richtig regelt.<br />
Dieses Verhalten kann man im Prinzip nur verhindern, indem man einen externen Temperatursensor oder einen Wandthermostat peert. Wie das geht ist hier beschrieben: [[#Channel (Kanal) 01 _Weather]]. Normalerweise regelt der Thermostat dann genau auf die Solltemperatur. <br />
Ansonsten sollte man sich auch fragen, ob das gezeigte Verhalten vielleicht doch gut genug ist. Dazu platziert man irgendein Thermometer möglichst in der Mitte des Raums und beobachtet den Temperaturverlauf eine Weile. Wenn man dann noch eine Abweichung feststellt, kann es sinnvoll sein, diese mittels des Registers R-tempOffset zu beheben.<br />
<br />
=== Pairen bei Firmware 1.5 ===<br />
<br />
Das nachfolgende Vorgehen bietet sich ab Firmware 1.5 ab, da sonst das pairen nicht erfolgreich sein wird:<br />
<br />
1. Pairing wie angegeben<br />
<br />
2. Get Config erst nachdem die Zeit von hmPairVorSecnds abgelaufen ist.<br />
<br />
3. burstXmit<br />
<br />
4. set <gerät> reset<br />
<br />
5. set <gerät> unpair <br />
Jetzt bloß nichts löschen!<br />
<br />
6. harten HW Reset nach Handbuch am Gerät<br />
<br />
7. erneut pairen<br />
<br />
== Links ==<br />
* [http://www.eq-3.de/produkt-detail-aktoren/items/homematic-funk-heizkoerperthermostat.html Produktinfo bei EQ-3]<br />
* [http://www.eq-3.de/Downloads/eq3/downloads_produktkatalog/homematic/bda/HM-CC-RT-DN_UM_GE_eQ-3_web.pdf Bedienungsanleitung bei EQ-3 (PDF)]<br />
* [http://www.eq-3.de/Downloads/eq3/downloads_produktkatalog/homematic/pdb/Funk-Heizkoerperthermostat_105155_Produktdatenblatt_V2.3.pdf Datenblatt bei EQ-3 (PDF)]<br />
* [http://www.eq-3.de/Downloads/eq3/downloads/Ventilkompatibilitaeten.pdf Ventil-Kompatibilitätsliste bei EQ-3 (zur Zeit nicht verfügbar)]<br />
* {{Link2Forum|Topic=14738|LinkText=Forenthema zum Thermostat}}<br />
* {{Link2Forum|Topic=64446|LinkText=Reparatur einer durch mechanischen Stoß von außen abgerissenen Lichtschranke}}<br />
<br />
[[Kategorie:HomeMatic Components]]<br />
[[Kategorie:Heizungsventile]]<br />
[[Kategorie:868MHz]]</div>Andies