KNX Device Definition - Beispiele: Unterschied zwischen den Versionen
KKeine Bearbeitungszusammenfassung |
|||
(30 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
=== Vorwort === | === Vorwort === | ||
Hier soll | {{Randnotiz|RNTyp=Warn|RNText=Hinweis: Das EIB-Modul ist seit 2018 deprecated und wird auch nicht mehr gewartet. Es ist daher dringend empfohlen, auf das [[KNX]]-Modul umzusteigen! Mit diesen Beispielen sollte auch der Umstieg auf das KNX-Modul etwas leichter fallen! Tips zur Migration sind auch in {{Link2Forum|Topic=126994|LinkText=diesem Forenthema}} zu finden.}} | ||
Hier soll ein Austausch von funktionierenden Beispielen aus dem KNX Bereich stattfinden. Es geht um die Definition, die Darstellung im FHEM-Web und um die Weiterverarbeitung mittels [[notify]], [[DOIF]], usw. | |||
Viele Anfragen im Forum beziehen sich auf Probleme bei der Definition, Darstellung und "Weiterverarbeitung" von KNX-Geräten. Alle User sind eingeladen, mit weiteren Beispielen mitzuwirken. Im ersten Schritt werden einige Beispiele aus der [https://fhem.de/commandref.html#KNX Command-Referenz] hierher übertragen, auch um die Command-Ref (in einem zweiten Schritt) etwas kompakter zu gestalten. | Viele Anfragen im Forum beziehen sich auf Probleme bei der Definition, Darstellung und "Weiterverarbeitung" von KNX-Geräten. Alle User sind eingeladen, mit weiteren Beispielen mitzuwirken. Im ersten Schritt werden einige Beispiele aus der [https://fhem.de/commandref.html#KNX Command-Referenz] hierher übertragen, auch um die Command-Ref (in einem zweiten Schritt) etwas kompakter zu gestalten. | ||
Die [https://fhem.de/commandref.html#KNX Command-Referenz] | Die [https://fhem.de/commandref.html#KNX Command-Referenz] ist nach wie vor die aktuellste (und verbindliche) Dokumentation des Moduls. Hier sollen zusätzliche Infos, Tips & Tricks gegeben werden. | ||
Generelle Hinweise zum KNX Modul sind hier auf der Modulbeschreibungsseite [[KNX]] zu finden. | |||
=== Beispiele === | === Beispiele === | ||
==== on/off Device - einfach ==== | ==== on/off Device - einfach ==== | ||
<syntaxhighlight lang="text"> | <syntaxhighlight lang="text"> | ||
define | define Lampe1 KNX 14/0/1:dpt1 | ||
</syntaxhighlight>Einfachstes KNX-Device ohne Alias und Rückmeldung. | </syntaxhighlight> | ||
Einfachstes KNX-Device ohne Alias und Rückmeldung. | |||
==== on/off Device - mit Rückmeldung ==== | ==== on/off Device - mit Rückmeldung ==== | ||
<syntaxhighlight lang="text"> | <syntaxhighlight lang="text"> | ||
define | define Lampe2 KNX 14/1/1:dpt1:EinAus 14/2/1:dpt1:Status:listenonly | ||
attr | attr Lampe2 webCmd EinAus | ||
# attr | # attr Lampe2 webCmd : | ||
attr | attr Lampe2 stateFormat Status-get | ||
attr | attr Lampe2 devStateIcon off:li_wht_off:on on:li_wht_on:off | ||
</syntaxhighlight>Hier gibt es | </syntaxhighlight> | ||
Hier gibt es zwei GA-Adressen, eine zum Schalten und die zweite für die Rückmeldung vom Aktor (muss natürlich via ETS so programmiert sein!). | |||
Zusätzlich hat jede GA-Adresse nun einen Alias (=gadName), z.B. EinAus, Status. Das Attr "webcmd EinAus" erzeugt ein Pulldown Menü das die jeweilige Funktion ausführt. Falls man kein Pulldown Menü will, nimmt man die 2te Variante von webCmd und klickt auf das DeviceIcon um Ein/Aus zu schalten. DevStateIcon hat den Sinn, damit Icons den Zustand darstellen und beim anklicken die jeweilige Funktion ausführen. Die listenonly Option verhindert, dass ein Set- oder Get-cmd im FHEMWeb dargestellt wird. - Set oder Get sind auf diesen Alias dann nicht möglich! | Zusätzlich hat jede GA-Adresse nun einen Alias (=gadName), z.B. EinAus, Status. Das Attr "webcmd EinAus" erzeugt ein Pulldown Menü das die jeweilige Funktion ausführt. Falls man kein Pulldown Menü will, nimmt man die 2te Variante von webCmd und klickt auf das DeviceIcon um Ein/Aus zu schalten. DevStateIcon hat den Sinn, damit Icons den Zustand darstellen und beim anklicken die jeweilige Funktion ausführen. Die listenonly Option verhindert, dass ein Set- oder Get-cmd im FHEMWeb dargestellt wird. - Set oder Get sind auf diesen Alias dann nicht möglich! | ||
==== on/off Device - blinken ==== | |||
<syntaxhighlight lang="Perl"> | |||
define dpt1blink KNX 14/1/1:dpt1:Blinker:set:nosuffix | |||
attr dpt1blink comment blink example | |||
attr dpt1blink devStateIcon on:sprinkler_icon@red:off off:sprinkler_icon@green:on | |||
attr dpt1blink eventMap {usr=>{'^(?:.*)?blink.([\d])[\s,]([\d])'=>'Blinker blink $1 $2'}, fw=>{'^(?:.*)?blink.([\d])[\s,]([\d])'=>'blink'} } | |||
attr dpt1blink widgetOverride blink@set:widgetList,2,textField,Anzahl_blinks,2,textField,Dauer(sec) Blinker@set:widgetList,4,select,on,off,blink,2,textField,Anzahl_blinks,2,textField,Dauer(sec) | |||
</syntaxhighlight> | |||
Ein Beispiel, wie man ein KNX-Geräte blinken lassen kann. Extensive Nutzung der Möglichkeiten vom attr eventmap und widgetoverride! | |||
==== on/off Device - mit verzögerter Rückmeldung ==== | ==== on/off Device - mit verzögerter Rückmeldung ==== | ||
Es gibt KNX-Aktoren, die erst nach erfolgreicher Ausführung (mit Verzögerung) eine Rückmeldung schicken. Bsp: Großer Drehstrom Motor mit Anlaufstrom-Begrenzung. Nach einem set-cmd (von FHEM) wird vorerst ein hourglass-icon dargestellt, solange bis die Rückmeldung vom KNX-Aktor kommt.<syntaxhighlight lang="text"> | Es gibt KNX-Aktoren, die erst nach erfolgreicher Ausführung (mit Verzögerung) eine Rückmeldung schicken. Bsp: Großer Drehstrom Motor mit Anlaufstrom-Begrenzung. Nach einem set-cmd (von FHEM) wird vorerst ein hourglass-icon dargestellt, solange bis die Rückmeldung vom KNX-Aktor kommt.<syntaxhighlight lang="text"> | ||
define dpt1_1tst KNX 14/1/1:dpt1: | define dpt1_1tst KNX 14/1/1:dpt1:switch:set 14/2/1:dpt1:status:listenonly:nosuffix | ||
attr dpt1_1tst devStateIcon on:general_an: | attr dpt1_1tst devStateIcon on:general_an:off off:general_aus:on steuern.*:hourglass:off | ||
attr dpt1_1tst stateRegex / | attr dpt1_1tst stateRegex /switch-set/steuern-/ /switch-get// | ||
</syntaxhighlight>Gleichzeitig ein Beispiel zu stateRegex Verwendung: der 1. Teil muss dem reading[:value] entsprechen, Im konkreten Fall übersetzt das stateRegex "EinAus-set[:value]" nach "steuern-<value> im state-reading, Ein EinAus-get wird ignoriert! Damit kann das state-reading nicht on oder off werden, außer es kommt ein Status von der GA: 14/2/1. Das wird im devStateIcon genutzt, um | </syntaxhighlight> | ||
Gleichzeitig ein Beispiel zu stateRegex Verwendung: der 1. Teil muss dem reading[:value] entsprechen, Im konkreten Fall übersetzt das stateRegex "EinAus-set[:value]" nach "steuern-<value> im state-reading, Ein EinAus-get wird ignoriert! Damit kann das state-reading nicht on oder off werden, außer es kommt ein Status von der GA: 14/2/1. Das wird im devStateIcon genutzt, um drei Zusände darzustellen (on,off,steuern). | |||
Dieses Beispiel | ==== on/off Device - Treppenlicht ==== | ||
Üblicherweise haben KNX-Aktoren eine Staircase (Treppenlicht) Funktion, die mittes ETS programmiert werden kann. Falls das nicht der Fall ist, oder man die Zeitdauer dynamisch vorgeben will, könnte das so aussehen:<syntaxhighlight lang="text"> | |||
defmod dpt1Treppenlicht KNX 14/1/1:dpt1:switch:set:nosuffix 14/2/1:dpt1:status:listenonly:nosuffix | |||
attr dpt1Treppenlicht devStateIcon on-for-timer.*:on-for-timer@red:off on:on@red:off off:off:on | |||
attr dpt1Treppenlicht stateCmd { if ($gadName eq 'status' && $state eq 'on') { | |||
fhem ("sleep 15.0 $name quiet; set $name switch off"); | |||
return 'on-for-timer'; | |||
} | |||
return $state; | |||
} | |||
</syntaxhighlight>stateCmd reagiert auf die "status = on" -msg vom Aktor, startet einen 15 Sekunden Timer und schaltet nach Ablauf auf off. Gleichzeitig wird das DevstateIcon auf "on-for-timer" gesetzt. | |||
==== Sensor - mit Umrechnung ==== | |||
Ein Windspeed Sensor sendet einen dpt9 Wert in Meter/Sekunde (nach ISO). Nachdem die gebräuchliche Einheit für Windgeschwindigkeiten km/h sind, muss also umgerechent werden. Das kann mittels Userreading passieren, geht aber auch einfacher: | |||
<syntaxhighlight lang="Perl"> | |||
defmod Windspeed KNX 14/0/9:dpt9.005:get:nosuffix | |||
attr Windspeed stateCmd {return sprintf("%.1f",ReadingsNum($name,'g1',0)*3.6);;} | |||
attr Windspeed stateFormat state km/h | |||
</syntaxhighlight> | |||
Im reading '''g1''' steht die WIndspeed in m/s, im reading '''state''' (siehe stateCmd) die Windspeed in km/h - ohne Einheit, im Internal '''STATE''' die Windspeed mit Einheit. | |||
Will man jedoch auch im reading '''state''' die Einheit haben, adaptiert man das stateCmd Attribute z.b. so: | |||
<syntaxhighlight lang="Perl"> | |||
attr Windspeed stateCmd {return sprintf("%.1f km/h",ReadingsNum($name,'g1',0)*3.6);;} | |||
</syntaxhighlight> | |||
und lässt das Attr. stateFormat weg. | |||
==== Dimmer ==== | |||
[[Datei:Dimmer.png|mini|600x600px]] | |||
Eine Steuerung für KNX-Dimmer. Die Bedienung kann sowohl über on/off, als auch über prozent-Helligkeit und über dimup/dimdown (jeweils 10%) erfolgen. Dazu sind insgesamt vier GA-Adressen definert, die im KNX-Aktor (mittels ETS) konfiguriert sind . | |||
"EinAus" ist die GA für das senden von on/off, "Status" - die Rückmeldung vom Aktor, "Dimmen" ist die GA für das Senden von Helligkeitswerten (Range 0-100%), "Dimmstatus" die Rückmeldung vom Aktor. | |||
Das devStateIcon wird grau bei state=off, gelb bei state=on oder bei state= >0. | |||
Die [[eventMap]]-Syntax ist reichlich verwirrend, im Wesentlichen: ein klick auf "dimup" erhöht den Wert von "Dimmen" um 10%, "dimdown" reduziert um 10%. | |||
stateCmd wird bei jedem Event aufgerufen, in diesem Fall: Wenn sich "EinAus" ändert, wird dieser Wert nicht nur in das reading EinAus geschrieben, sondern auch in das reading Dimmen, allerdings übersetzt: on =>100, off=>0. Damit zeigt der Slider jederzeit den richtigen Zustand an. Zusätzlich wird der Wert auch in das Reading state geschrieben. Weiters: ändert sich "Dimmstatus", wird dieser Wert auch in das reading Dimmen geschreiben, damit der Slider auch den richtigen Wert anzeigt (der Dimmer könnte ja auch ausserhalb von FHEM bedient werden...). | |||
webCmd und widgetOverride bestimmen das Aussehen und die Funktion der Overview Zeile. <syntaxhighlight lang="perl"> | |||
defmod Dimmer KNX 14/6/1:dpt1:EinAus:set:nosuffix\ | |||
14/7/1:dpt1:Status:listenonly:nosuffix\ | |||
14/6/5:dpt5.001:Dimmen:set:nosuffix\ | |||
14/7/5:dpt5.001:DimmStatus:listenonly:nosuffix | |||
attr Dimmer devStateIcon devStateIcon off:li_wht_off:on on:li_wht_on:off 0.*:li_wht_off:on \d+.*:li_wht_on:off | |||
attr Dimmer eventMap {usr=>{'^dimup'=> '" . sprintf("Dimmen %d",minNum(100,ReadingsNum($NAME,"Dimmen",0) + 10)) . "', \ | |||
'^dimdown' => '" . sprintf("Dimmen %d",maxNum(0,ReadingsNum($NAME,"Dimmen",0) - 10)) . "'}, \ | |||
fw=>{'^dimup'=> 'dimup', '^dimdown'=> 'dimdown'} } | |||
attr Dimmer stateCmd { if ($gadName eq 'DimmStatus') {\ | |||
fhem ("sleep 0.05 quiet;;setreading $name Dimmen $state;;");; \ | |||
}\ | |||
elsif ($gadName eq 'EinAus') {\ | |||
my $val = ($state eq 'on')?'100':'0';;\ | |||
fhem ("sleep 0.05 quiet;;setreading $name Dimmen $val;;");;\ | |||
}\ | |||
return $state;;\ | |||
} | |||
attr Dimmer webCmd :dimup:dimdown:Dimmen | |||
attr Dimmer widgetOverride Dimmen@set:slider,0,5,100 | |||
</syntaxhighlight> | |||
==== Garagentor Steuerung ==== | |||
Dieses Beispiel kann für die (noch immer) üblichen 1-Taster Garagentor-Steuerungen genutzt werden. | |||
Die GA 14/1/100-move ist einem Aktor zugeordnet, der den Garagentor-Taster simuliert. | |||
Die GA 14/1/101-move_status ist die übliche Rückmeldung vom Status des Aktors. Wird hier nicht verwendet, kann weggelassen werden. | |||
Die GA 14/1/102-Doorstatus ist mit dem Garagensensor (KNX-Input) Tor= zu/offen verknüpft. <syntaxhighlight lang="text"> | |||
defmod Garagentor KNX 14/1/100:dpt1.001:move:set:nosuffix\ | |||
14/1/101:dpt1.001:move_status:listenonly:nosuffix\ | |||
14/1/102:dpt1.019:Doorstatus:listenonly:nosuffix\ | |||
attr Garagentor IODev myKNXIO | |||
attr Garagentor comment set door trigger for 2 seconds, Status des Tors wird durch GA "Doorstatus" bestimmt. | |||
attr Garagentor devStateIcon closed:fts_garage_door_100@green:on open:fts_garage@red:on | |||
attr Garagentor eventMap {usr=>{'on'=>'move on-for-timer 2','move off'=>'off'} } | |||
attr Garagentor stateRegex /move// /move_status// | |||
attr Garagentor webCmd : | |||
attr Garagentor widgetOverride move:on | |||
</syntaxhighlight> | |||
Ein Klick auf das DeviceState-Icon bewirkt ein "Set on", das wird mittels eventMap auf "Set move on-for-timer 2" geändert. Der KNX-Aktor schließt den entsprechenden Kontakt für zwei Sekunden, simuliert damt einen Taster. Das Attribut stateRegex verhindert, dass von move und von move_status GAs der Wert ins reading "state" geschrieben wird. Ist das Garagentor geöffnet, wird der Wert von GA Doorstatus "open" - was auch ins state-reading kopiert wird und damit das DevstateIcon als offen/geschlossen anzeigt. | |||
Alternativ: falls der KNX-Aktor eine "TreppenLicht Funktion" implementiert hat (bei einem on wird eingeschaltet und nach x Sekunden augeschaltet), kann das Attribut eventMap komplett weggelassen werden. | |||
"Doorstatus" muss nicht unbedingt ein KNX-Gerät sein, das könnte auch von einem anderen Device z.B.via notify gesetzt werden:<syntaxhighlight lang="text"> | |||
setreading Garagentor Doorstatus open/closed | |||
</syntaxhighlight> | |||
==== Slider - einfach ==== | ==== Slider - einfach ==== | ||
Zeile 36: | Zeile 140: | ||
define Slider_Test KNX 15/2/2:dpt5:Position | define Slider_Test KNX 15/2/2:dpt5:Position | ||
attr Slider_Test webCmd Position | attr Slider_Test webCmd Position | ||
attr Slider_Test widgetOverride Position | attr Slider_Test widgetOverride Position@set:slider,0,5,100 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Zeile 43: | Zeile 147: | ||
define Slider2_Test KNX 15/2/2:dpt5.001:Position:set:nosuffix 15/2/3:dpt5.001:PosStatus:get:nosuffix | define Slider2_Test KNX 15/2/2:dpt5.001:Position:set:nosuffix 15/2/3:dpt5.001:PosStatus:get:nosuffix | ||
attr Slider2_Test stateCmd { fhem "sleep 0.05 quiet;; setreading $name Position $state" if ($gadName eq 'PosStatus');; return $state;; } | attr Slider2_Test stateCmd { fhem "sleep 0.05 quiet;; setreading $name Position $state" if ($gadName eq 'PosStatus');; return $state;; } | ||
#attr Slider2_Test userReadings Position:PosStatus.* {return readingsNum($name, 'PosStatus',0);; } | |||
attr Slider2_Test webCmd Position | attr Slider2_Test webCmd Position | ||
attr Slider2_Test widgetOverride Position:slider,0,5,100 | attr Slider2_Test widgetOverride Position@set:slider,0,5,100 | ||
</syntaxhighlight>Das Attr stateCmd setzt den Wert der vom Aktor kommt - zusätzlich in das reading 'Position', damit der Slider immer auch die aktuelle Position anzeigt. Die doppelten semicolons sind aus parsing Gründen nötig. Falls man das Attribut über Device-Detail-view setzt, sind nur einfache ; nötig! | </syntaxhighlight> | ||
Das Attr stateCmd setzt den Wert der vom Aktor kommt - zusätzlich in das reading 'Position', damit der Slider immer auch die aktuelle Position anzeigt. | |||
Alternativ zu Attr stateCmd kann auch Attr userReadings verwendet werden. | |||
Die doppelten semicolons sind aus parsing Gründen nötig. Falls man das Attribut über Device-Detail-view setzt, sind nur einfache ; nötig! | |||
==== Zwei Slider mit Rückmeldung ==== | ==== Zwei Slider mit Rückmeldung ==== | ||
[[Datei:KNX dpt5tst.png|rechts|rahmenlos|450x450px]] | [[Datei:KNX dpt5tst.png|rechts|rahmenlos|450x450px]] | ||
Z.B. für eine Jalousie mit Lamellensteuerung. Das ist eine Erweiterung des vorigen Beispiels.<syntaxhighlight lang=" | Z.B. für eine Jalousie mit Lamellensteuerung. Das ist eine Erweiterung des vorigen Beispiels. | ||
<syntaxhighlight lang="perl"> | |||
define dpt5test KNX 9/1/1:dpt5.001:blind:set:nosuffix 9/1/2:dpt5.001:blindStatus:listenonly:nosuffix | define dpt5test KNX 9/1/1:dpt5.001:blind:set:nosuffix 9/1/2:dpt5.001:blindStatus:listenonly:nosuffix | ||
9/1/3:dpt5.001:slat:set:nosuffix 9/1/4:dpt5.001:slatStatus:listenonly:nosuffix | 9/1/3:dpt5.001:slat:set:nosuffix 9/1/4:dpt5.001:slatStatus:listenonly:nosuffix | ||
Zeile 65: | Zeile 177: | ||
attr dpt5test webCmdLabel Blind | attr dpt5test webCmdLabel Blind | ||
:Slat | :Slat | ||
attr dpt5test widgetOverride blind:slider,0,1,100 slat:slider,0,10,100 | attr dpt5test widgetOverride blind@set:slider,0,1,100 slat@set:slider,0,10,100 | ||
</syntaxhighlight>Dazu braucht es noch eine sub in 99_myUtils.pm (siehe auch Beispiel Jalousie / Rolladen). Der Trick liegt in der indizierten Variante von stateFormat (1:blind,...), damit wird auch in devStateIcon dieser Index ausgewertet! Leider gibts für die Lamellen-Stellung nur 3 Icons, für die Stellungen: 0%,50%,100%.<syntaxhighlight lang=" | </syntaxhighlight> | ||
Dazu braucht es noch eine sub in 99_myUtils.pm (siehe auch Beispiel Jalousie / Rolladen). Der Trick liegt in der indizierten Variante von stateFormat (1:blind,...), damit wird auch in devStateIcon dieser Index ausgewertet! Leider gibts für die Lamellen-Stellung nur 3 Icons, für die Stellungen: 0%,50%,100%. | |||
<syntaxhighlight lang="Perl"> | |||
## return string for devStateIcon | ## return string for devStateIcon | ||
## input: none | ## input: none | ||
Zeile 73: | Zeile 187: | ||
my $iconstring = 'block.on:fts_door_open@red ' . | my $iconstring = 'block.on:fts_door_open@red ' . | ||
"block.off: " . | "block.off: " . | ||
'aufab.off:black_down:Ab ' . | |||
'aufab.on:black_up:Auf ' . | |||
'moving:fts_shutter_updown@red:Stop ' . | 'moving:fts_shutter_updown@red:Stop ' . | ||
'1.100.*:fts_shutter_100 1.1\d.*:fts_shutter_10 ' . | '1.100.*:fts_shutter_100 1.1\d.*:fts_shutter_10 ' . | ||
Zeile 88: | Zeile 202: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
==== RaumThermostat / HeizungsAktor ==== | |||
[[Datei:Fhemwiki KNX - RaumThermostat.png|rechts|rahmenlos|674x674px]] | |||
<br clear=all> | |||
<syntaxhighlight lang="text"> | |||
define XXXZimmer_Heizung KNX 5/0/52:dpt9:solltemp:set:nosuffix 5/0/53:dpt9:solltemp_ist:get:nosuffix 5/0/50:dpt9:temperature:get:nosuffix 5/0/51:dpt5.001:valvepos:get:nosuffix | |||
attr XXXZimmer_Heizung comment GAs: SollTemp-schreiben, SollTemp-lesen, IstTemp, ValvePosition | |||
attr XXXZimmer_Heizung stateFormat temperature °C, Soll: solltemp_ist °C, Ventil: valvepos | |||
attr XXXZimmer_Heizung webCmd solltemp | |||
attr XXXZimmer_Heizung webCmdLabel SollTemperatur | |||
attr XXXZimmer_Heizung widgetOverride solltemp@set:18.0,18.5,19.0,19.5,20.0,20.5,21.0,21.5,22.0,22.5,23.0,23.5,24.0,24.5,25.0 solltemp_ist:noArg temperature:noArg | |||
attr XXXZimmer_Heizung widgetOverride solltemp@set:slider,18,0.5,25,1 solltemp_ist:noArg temperature:noArg | |||
</syntaxhighlight> | |||
Beispiel für einen RaumThermostat / Heizungsregler. Die Soll-Temperatur kann entweder mittels pull-down oder mittels slider eingestellt werden. Siehe die beiden Attribute widgetoverride... (nur eines davon verwenden!) | |||
Falls '''solltemp_ist''' nicht zur Verfügung steht, kann es weggelassen werden. Funktion: Es könnte ja die SollTemperatur am Raumthermostat eingestellt worden sein! | |||
'''valvepos''' ist der Prozentwert, den das Raumthermostat für das Ventil der FB-Heizung sendet. | |||
==== Zeit und Datum ==== | ==== Zeit und Datum ==== | ||
<syntaxhighlight lang="text"> | <syntaxhighlight lang="text"> | ||
define timedev KNX 0/0/7:dpt10:time 0/0/8:dpt11:date 0/0/9:dpt19:datetime | define timedev KNX 0/0/7:dpt10:time 0/0/8:dpt11:date 0/0/9:dpt19:datetime | ||
</syntaxhighlight>Hier sind alle Varianten von Zeit / Datum dargestellt. Die Empfänger müssen den jeweiligen DPT natürlich unterstützen! | </syntaxhighlight> | ||
Hier sind alle Varianten von Zeit / Datum dargestellt. Die Empfänger müssen den jeweiligen DPT natürlich unterstützen! | |||
die entsprechenden set- | die entsprechenden set-cmds lauten:<syntaxhighlight lang="text"> | ||
# setze das Datum auf den Bus: | # setze das Datum auf den Bus: | ||
set timedev date now | set timedev date now | ||
Zeile 111: | Zeile 244: | ||
<syntaxhighlight lang="text"> | <syntaxhighlight lang="text"> | ||
define textdev KNX 0/0/9:dpt16:txt | define textdev KNX 0/0/9:dpt16:txt | ||
</syntaxhighlight>Die entsprechenden set- | </syntaxhighlight> | ||
set textdev txt AbCdEfGhIjkLmN # | Die entsprechenden set-cmds lauten: | ||
set textdev txt >CLR< # | <syntaxhighlight lang="text"> | ||
set textdev txt AbCdEfGhIjkLmN # sende text zum KNX display (max 14 Char.) | |||
set textdev txt >CLR< # löscht gesamten text am KNX display | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Zeile 121: | Zeile 256: | ||
attr putDemo putCmd {ReadingsNum($name,'refVal-get',0) if ($gadName eq 'temp');} | attr putDemo putCmd {ReadingsNum($name,'refVal-get',0) if ($gadName eq 'temp');} | ||
</syntaxhighlight>Es sind 3 GA_Adressen definiert, FHEM antwortet allerdings nur auf einen read-request vom Bus wenn die 1/0/30 Adresse angesprochen wird, mit dem Wert der im refVal reading steht! | </syntaxhighlight> | ||
Es sind 3 GA_Adressen definiert, FHEM antwortet allerdings nur auf einen read-request vom Bus wenn die 1/0/30 Adresse angesprochen wird, mit dem Wert der im refVal reading steht! | |||
==== Jalousie / Rolladen ==== | ==== Jalousie / Rolladen ==== | ||
[[Datei:KNX JalKueche.png|rechts|rahmenlos|450x450px]] | [[Datei:KNX JalKueche.png|rechts|rahmenlos|450x450px]] | ||
Ein komplexes Beispiel, getestet mit einem Jal-Aktor von MDT. Ganz wichtig ist die GA: moving, der Aktor sendet on solange sich die Jalousie bewegt. Das ist ein Parameter, der mittels ETS konfiguriert werden kann. Ergebnis ist ein Device, dass jederzeit die Position anzeigt, Schlaltfllächen für Auf/Ab und einen Slider für's setzen der absoluten Position bietet. Dazu braucht es allerdings | Ein komplexes Beispiel, getestet mit einem Jal-Aktor von MDT. Ganz wichtig ist die GA: moving, der Aktor sendet on solange sich die Jalousie bewegt. Das ist ein Parameter, der mittels ETS konfiguriert werden kann. Ergebnis ist ein Device, dass jederzeit die Position anzeigt, Schlaltfllächen für Auf/Ab und einen Slider für's setzen der absoluten Position bietet. Dazu braucht es allerdings zwei Subroutinen in der 99_myUtils! | ||
<syntaxhighlight lang="text"> | |||
define Jal_Kueche KNX 5/1/53:dpt1.008:aufab:set:nosuffix | define Jal_Kueche KNX 5/1/53:dpt1.008:aufab:set:nosuffix | ||
5/1/55:dpt1.010:stop:set:nosuffix | 5/1/55:dpt1.010:stop:set:nosuffix | ||
Zeile 138: | Zeile 275: | ||
attr Jal_Kueche comment GA's: aufab,stop,movestatus,posstatus,Setposition,block,uppos,dnpos | attr Jal_Kueche comment GA's: aufab,stop,movestatus,posstatus,Setposition,block,uppos,dnpos | ||
attr Jal_Kueche devStateIcon {Jal_devStateIcon()} | attr Jal_Kueche devStateIcon {Jal_devStateIcon()} | ||
attr Jal_Kueche eventMap { usr=>{ | attr Jal_Kueche eventMap { usr=>{'Stop'=>'stop stop','Auf'=>'aufab up','Ab'=>'aufab down'} } | ||
attr Jal_Kueche stateCmd {Jal_stateCmd($name,$gadName,$state)} | attr Jal_Kueche stateCmd {Jal_stateCmd($name,$gadName,$state)} | ||
attr Jal_Kueche webCmd Auf:Ab:position | attr Jal_Kueche webCmd Auf:Ab:position | ||
attr Jal_Kueche widgetOverride position:slider,0,5,100 | attr Jal_Kueche widgetOverride position@set:slider,0,5,100 | ||
</syntaxhighlight>.. und die beiden | </syntaxhighlight>.. und die beiden subs in 99_myUtils.pm (Diese werden von allen Jalousien / Rolladen verwendet. | ||
<syntaxhighlight lang="Perl"> | |||
### Jalousie Utilities | ### Jalousie Utilities | ||
## return string for stateCmd | ## return string for stateCmd | ||
Zeile 149: | Zeile 287: | ||
my ($dname,$gadname,$dstate) = @_; | my ($dname,$gadname,$dstate) = @_; | ||
my $newstate = ''; | my $newstate = ''; | ||
if (ReadingsVal($dname, | if (ReadingsVal($dname,'block','off') eq 'on' ) { | ||
$newstate = | $newstate = 'block:on'; | ||
} elsif (ReadingsVal($dname, | } elsif (ReadingsVal($dname,'moving','off') eq 'on' ) { | ||
$newstate = | $newstate = 'moving'; | ||
Log3 $dname, 5, "in stateCmd-movingon: $dname, $gadname,$dstate,newstate: $newstate"; | Log3 $dname, 5, "in stateCmd-movingon: $dname, $gadname,$dstate,newstate: $newstate"; | ||
} else { | } else { | ||
$newstate = int((ReadingsNum($dname, | $newstate = int((ReadingsNum($dname,'posstatus',0)+5)/10) * 10; | ||
} | } | ||
return $newstate; | return $newstate; | ||
Zeile 165: | Zeile 303: | ||
sub Jal_devStateIcon { | sub Jal_devStateIcon { | ||
my $iconstring = 'block.on:fts_door_open@red ' . | my $iconstring = 'block.on:fts_door_open@red ' . | ||
'block.off: ' . | |||
'wind.on:weather_wind@red ' . | 'wind.on:weather_wind@red ' . | ||
'wind.off: ' . | 'wind.off: ' . | ||
'aufab.off:black_down:Ab ' . | |||
'aufab.on:black_up:Auf ' . | |||
'moving:fts_shutter_updown@red:Stop ' . | 'moving:fts_shutter_updown@red:Stop ' . | ||
'100.*:fts_shutter_100 1\d.*:fts_shutter_10 ' . | '100.*:fts_shutter_100 1\d.*:fts_shutter_10 ' . | ||
Zeile 179: | Zeile 317: | ||
return $iconstring; | return $iconstring; | ||
} | } | ||
</syntaxhighlight> | |||
Die sub stateCmd berücksichtigt auch noch die GA: block - z.B. wenn Fenster/Tür offen ist oder einen einen WindAlarm! | |||
==== Jalousie / Rolladen - Erweiterung mit ASC (AutoShuttersControl) ==== | |||
Das ist eine Erweiterung des vorigen Beispiels. Die grundsätzliche Funktionalität von ASC wird '''[[AutoShuttersControl|hier]]''' behandelt. Im Folgenden werden nur jene Definitionen gezeigt, die KNX-spezifisch sind. | |||
==== Slider - mit Rückmeldung '''und Wert | Einige Funktionen des ASC.Moduls sind in einem KNX.System möglicherweise bereits vorhanden, z.B.: automatisch Rauf-/Runterfahren bei diversen Alarmen (Wind,Regen,Frost, Fenster/Tür offen) oder in Kombination mit einer Wetterstation auch Beschattung. Das ASC Modul sendet Werte von 0-100, um die Jalousieposition zu setzen und erwartet im ASC_Pos_Reading Attribut die aktuelle Position.<syntaxhighlight lang="text"> | ||
Ein komplexer Fall, wo ein Hersteller zwar den dpt5 verwendet, aber sein "eigenes Zahlen-Format" implementiert hat. Konkret geht's um eine Lüftungsanlage, die Stufen 0 (=Aus) bis 8 (=Maximum) verwendet. Am Bus kommen / werden erwartet die folgenden Werte:<syntaxhighlight lang="text"> | attr Jal_Kueche ASC 1 | ||
attr Jal_Kueche ASC_Closed_Pos 100 | |||
attr Jal_Kueche ASC_Open_Pos 0 | |||
attr Jal_Kueche ASC_CommandTemplate set $name position $pos | |||
attr Jal_Kueche ASC_Pos_Reading posstatus | |||
</syntaxhighlight> | |||
ASC_Open_Pos, ASC_Closed_Pos: 0 bedeutet Jalousie ist oben, 100 unten. | |||
ASC_Pos_Reading: das ist der Ist-Wert der Jalousie. Muss mit dem Readingnamen im KNX-Device übereinstimmen. | |||
ASC_CommandTemplate: so muss der set command für das KNX-Device zusammengestellt werden, also z.B: '''set Jal_Kueche position 50''' | |||
Beim Testen wurde festgestellt, dass nach Definition/Änderung von Attributen u.U. ein FHEM Restart erforderlich ist, um die korrekte Funktion des ASC Moduls zu erhalten. | |||
Um die Funktion zu testen, kann man den Befehl '''set <ASC_device> wiggle''' verwenden. Die Jalousie sollte sich um 5% (default) bewegen und nach 60 Sekunden um 5% in die Gegenrichtung. | |||
==== Slider - mit Rückmeldung '''und Wert umrechnung''' ==== | |||
Ein komplexer Fall, wo ein Hersteller zwar den dpt5 verwendet, aber sein "eigenes Zahlen-Format" implementiert hat. Konkret geht's um eine Lüftungsanlage, die Stufen 0 (=Aus) bis 8 (=Maximum) verwendet. Am Bus kommen / werden erwartet die folgenden Werte: | |||
<syntaxhighlight lang="text"> | |||
0 (Aus)->0, 1->31, 2->63, 3->95, ... , 8->255 | 0 (Aus)->0, 1->31, 2->63, 3->95, ... , 8->255 | ||
</syntaxhighlight>Im FHEM-Web sollen aber die Stufen 0-8 verwendet werden. | </syntaxhighlight> | ||
<syntaxhighlight lang=" | Im FHEM-Web sollen aber die Stufen 0-8 verwendet werden. | ||
<syntaxhighlight lang="perl"> | |||
define KNXStufentest KNX 11/1/18:dpt5:StufeSoll:set:nosuffix 11/1/20:dpt5:StufeIst:get:nosuffix | define KNXStufentest KNX 11/1/18:dpt5:StufeSoll:set:nosuffix 11/1/20:dpt5:StufeIst:get:nosuffix | ||
Zeile 203: | Zeile 363: | ||
} | } | ||
attr KNXStufentest webCmd Aus:Ein:Stufe | attr KNXStufentest webCmd Aus:Ein:Stufe | ||
attr KNXStufentest widgetOverride Aus:noArg Ein:noArg Stufe:slider,0,1,8 | attr KNXStufentest widgetOverride Aus:noArg Ein:noArg Stufe@set:slider,0,1,8 | ||
</syntaxhighlight>Ankommende Messages (von Alias StufeIst) werden wie üblich im reading "StufeIst" (Werte: 0-255) gespeichert und '''zusätzlich''' umgerechnet und im reading "Stufe" (Wert: 0-8) gespeichert. Ein cmd vom User (Werte: 0-8) wird durch die eventMap umgerechnet und auf den Bus gesendet. Zusätzlich gibt's noch die Schaltflächen "Ein" und "Aus" . Auch diese Werde mittels eventMap auf Stufe 3(=Ein) bzw. Stufe 0(=Aus) umgerechnet. Die Syntax der eventMap ist gewöhnungsbedüftig, aber so funktioniert's! Was noch fehlt ist die Darstellung der Lüfterstufe mittels Icon. | </syntaxhighlight> | ||
Ankommende Messages (von Alias StufeIst) werden wie üblich im reading "StufeIst" (Werte: 0-255) gespeichert und '''zusätzlich''' umgerechnet und im reading "Stufe" (Wert: 0-8) gespeichert. Ein cmd vom User (Werte: 0-8) wird durch die eventMap umgerechnet und auf den Bus gesendet. Zusätzlich gibt's noch die Schaltflächen "Ein" und "Aus" . Auch diese Werde mittels eventMap auf Stufe 3(=Ein) bzw. Stufe 0(=Aus) umgerechnet. Die Syntax der eventMap ist gewöhnungsbedüftig, aber so funktioniert's! Was noch fehlt ist die Darstellung der Lüfterstufe mittels Icon. Das Beispiel soll auch zeigen, dass man aus einem cmd bzw. event einen (zusätzlichen) beliebigen reading-namen mit Wert erstellen kann. | |||
[[Datei:KNX_dpt251GUI.png|rechts|503x503px]] | |||
==== RGBW Steuerung (dpt251.600) ==== | |||
Die GUI für diesen dpt ist komplex, weil sie aus zwei Widgets besteht: '''colopicker,RGB''' und '''slider'''. | |||
Die eventmap setzt die beiden Werte (RGB u. White), die jeweils von den widgets kommen, zusammen und sendet das Resultat an den Bus. | |||
Der stateCmd setzt zwei "Hilfs-readings" (rgb,white), die aktuellen Basis-Werte für die widgets darstellen. | |||
<syntaxhighlight lang="perl"> | |||
define dpt251tst KNX 14/1/251:dpt251.600:set:nosuffix | |||
attr dpt251tst eventMap {usr => {'^rgb.(.+)' => '" . sprintf("g1 %s%s",$1,substr(ReadingsVal($NAME,"state","00000000"),6,2)) . "' , | |||
'^white.(.+)' => '" . sprintf("g1 %s%.2x",substr(ReadingsVal($NAME,"state","00000000"),0,6),round($1*2.55,0)) . "' }, | |||
fw => {'^rgb.(.+)' => 'rgb', '^white.(.+)' => 'white'}, | |||
} | |||
attr dpt251tst stateCmd { my $rgb = substr($state,0,6); | |||
my $white = round(hex(substr($state,6,2))/2.55,0); | |||
fhem("sleep 0.1; setreading $name rgb $rgb; setreading $name white $white"); | |||
return $state; | |||
} | |||
attr dpt251tst webCmd rgb:white | |||
attr dpt251tst widgetOverride rgb:colorpicker,RGB white@set:slider,0,1,100 | |||
</syntaxhighlight> | |||
=== DPT nicht unterstützt im KNX Modul? === | |||
Im KNX-Modul sind (fast) alle | Im KNX-Modul sind (fast) alle DPTs unterstützt, die in den frei verfügbaren Standarddokumenten definiert sind. Hersteller definieren manchmal eigene sub-DPTs, die dann möglicherweise nicht unmittelbar unterstützt sind. | ||
Im | Im Wesentlichen unterscheiden sich die sub-DPTs z.B. dpt9.020 von den "Haupt-DPTs" z.B. dpt9 durch die angefügte Einheit, den min/max Werte-Bereich, die Skalierung oder einen Offset. Falls also ein Gerät eine 2Byte-float Wert senden will, dann könnte das so aussehen: | ||
<syntaxhighlight lang="text"> | |||
define dpt9test KNX 0/4/6:dpt9 | define dpt9test KNX 0/4/6:dpt9 | ||
attr dpt9test format g/m³ # gramm / m³ | attr dpt9test format g/m³ # gramm / m³ | ||
</syntaxhighlight>und schon steht die richtige Einheit dahinter... Oder Skalierung - Watt -> kW:<syntaxhighlight lang=" | </syntaxhighlight> | ||
attr dpt9test stateCmd { return sprintf( | und schon steht die richtige Einheit dahinter... Oder Skalierung - Watt -> kW: | ||
</syntaxhighlight>Falsch definierte | <syntaxhighlight lang="Perl"> | ||
attr dpt9test stateCmd { return sprintf('%.3f kW',$state / 1000); } | |||
</syntaxhighlight> | |||
Falsch definierte DPTs (z.B: dpt5 statt dpt7) produzieren falsche Ergebnisse, sowohl in FHEM als auch im KNX Device! | |||
=== Übernehmen dieser Beispiele in die eigene Konfiguration === | |||
Die meisten dieser Beispiele sind mittels "exportdevice <name>" erstellt. Bei der Übernahme mit c&p in die FHEM- commandozeile (oder auch Telnet) gibt's Fallstricke...(Es müssen Semicolons u. Zeilenumbrüche maskiert werden). Um das zu umgehen, schlage ich folgenden Vorgangsweise vor: | Die meisten dieser Beispiele sind mittels "exportdevice <name>" erstellt. Bei der Übernahme mit c&p in die FHEM- commandozeile (oder auch Telnet) gibt's Fallstricke...(Es müssen Semicolons u. Zeilenumbrüche maskiert werden). Um das zu umgehen, schlage ich folgenden Vorgangsweise vor: | ||
Definiere z. | Definiere z.B. ein (kompliziertes) Attr stateCmd auf der FHEM-cmd Zeile: | ||
<syntaxhighlight lang="text"> | |||
attr meinDevice stateCmd {} | attr meinDevice stateCmd {} | ||
</syntaxhighlight>... also mit nichts drin! - Damit kann's auch keine | </syntaxhighlight>... also mit nichts drin! - Damit kann's auch keine Syntaxfehler geben! Danach geht man in den device-detail-View, klickt auf statecmd und mit c&p wird der code zwischen den (äussersten {} ) eingefügt. Selbes Vorgehen gilt auch für komplexe DevstateIcon, notifies, at,... Noch grössere code Teile sind sinnvoller in einer sub-routine in 99_myUtils.pm aufgehoben und werden z.B. im stateCmd aufgerufen: | ||
<syntaxhighlight lang="text"> | |||
attr <meinDevice> stateCmd { $state = meineAllerwichtigsteSubroutine(p1,p2,p3); } | attr <meinDevice> stateCmd { $state = meineAllerwichtigsteSubroutine(p1,p2,p3); } | ||
</syntaxhighlight>Das hat dann auch den Vorteil, dass die sub-Routine von mehreren | </syntaxhighlight> | ||
Das hat dann auch den Vorteil, dass die sub-Routine von mehreren Devices verwendet werden kann! | |||
[[Kategorie:Examples]] | [[Kategorie:Examples]] | ||
[[Kategorie:EIB/KNX]] | [[Kategorie:EIB/KNX]] |
Aktuelle Version vom 10. November 2024, 18:49 Uhr
Vorwort
Hier soll ein Austausch von funktionierenden Beispielen aus dem KNX Bereich stattfinden. Es geht um die Definition, die Darstellung im FHEM-Web und um die Weiterverarbeitung mittels notify, DOIF, usw.
Viele Anfragen im Forum beziehen sich auf Probleme bei der Definition, Darstellung und "Weiterverarbeitung" von KNX-Geräten. Alle User sind eingeladen, mit weiteren Beispielen mitzuwirken. Im ersten Schritt werden einige Beispiele aus der Command-Referenz hierher übertragen, auch um die Command-Ref (in einem zweiten Schritt) etwas kompakter zu gestalten.
Die Command-Referenz ist nach wie vor die aktuellste (und verbindliche) Dokumentation des Moduls. Hier sollen zusätzliche Infos, Tips & Tricks gegeben werden.
Generelle Hinweise zum KNX Modul sind hier auf der Modulbeschreibungsseite KNX zu finden.
Beispiele
on/off Device - einfach
define Lampe1 KNX 14/0/1:dpt1
Einfachstes KNX-Device ohne Alias und Rückmeldung.
on/off Device - mit Rückmeldung
define Lampe2 KNX 14/1/1:dpt1:EinAus 14/2/1:dpt1:Status:listenonly
attr Lampe2 webCmd EinAus
# attr Lampe2 webCmd :
attr Lampe2 stateFormat Status-get
attr Lampe2 devStateIcon off:li_wht_off:on on:li_wht_on:off
Hier gibt es zwei GA-Adressen, eine zum Schalten und die zweite für die Rückmeldung vom Aktor (muss natürlich via ETS so programmiert sein!).
Zusätzlich hat jede GA-Adresse nun einen Alias (=gadName), z.B. EinAus, Status. Das Attr "webcmd EinAus" erzeugt ein Pulldown Menü das die jeweilige Funktion ausführt. Falls man kein Pulldown Menü will, nimmt man die 2te Variante von webCmd und klickt auf das DeviceIcon um Ein/Aus zu schalten. DevStateIcon hat den Sinn, damit Icons den Zustand darstellen und beim anklicken die jeweilige Funktion ausführen. Die listenonly Option verhindert, dass ein Set- oder Get-cmd im FHEMWeb dargestellt wird. - Set oder Get sind auf diesen Alias dann nicht möglich!
on/off Device - blinken
define dpt1blink KNX 14/1/1:dpt1:Blinker:set:nosuffix
attr dpt1blink comment blink example
attr dpt1blink devStateIcon on:sprinkler_icon@red:off off:sprinkler_icon@green:on
attr dpt1blink eventMap {usr=>{'^(?:.*)?blink.([\d])[\s,]([\d])'=>'Blinker blink $1 $2'}, fw=>{'^(?:.*)?blink.([\d])[\s,]([\d])'=>'blink'} }
attr dpt1blink widgetOverride blink@set:widgetList,2,textField,Anzahl_blinks,2,textField,Dauer(sec) Blinker@set:widgetList,4,select,on,off,blink,2,textField,Anzahl_blinks,2,textField,Dauer(sec)
Ein Beispiel, wie man ein KNX-Geräte blinken lassen kann. Extensive Nutzung der Möglichkeiten vom attr eventmap und widgetoverride!
on/off Device - mit verzögerter Rückmeldung
Es gibt KNX-Aktoren, die erst nach erfolgreicher Ausführung (mit Verzögerung) eine Rückmeldung schicken. Bsp: Großer Drehstrom Motor mit Anlaufstrom-Begrenzung. Nach einem set-cmd (von FHEM) wird vorerst ein hourglass-icon dargestellt, solange bis die Rückmeldung vom KNX-Aktor kommt.
define dpt1_1tst KNX 14/1/1:dpt1:switch:set 14/2/1:dpt1:status:listenonly:nosuffix
attr dpt1_1tst devStateIcon on:general_an:off off:general_aus:on steuern.*:hourglass:off
attr dpt1_1tst stateRegex /switch-set/steuern-/ /switch-get//
Gleichzeitig ein Beispiel zu stateRegex Verwendung: der 1. Teil muss dem reading[:value] entsprechen, Im konkreten Fall übersetzt das stateRegex "EinAus-set[:value]" nach "steuern-<value> im state-reading, Ein EinAus-get wird ignoriert! Damit kann das state-reading nicht on oder off werden, außer es kommt ein Status von der GA: 14/2/1. Das wird im devStateIcon genutzt, um drei Zusände darzustellen (on,off,steuern).
on/off Device - Treppenlicht
Üblicherweise haben KNX-Aktoren eine Staircase (Treppenlicht) Funktion, die mittes ETS programmiert werden kann. Falls das nicht der Fall ist, oder man die Zeitdauer dynamisch vorgeben will, könnte das so aussehen:
defmod dpt1Treppenlicht KNX 14/1/1:dpt1:switch:set:nosuffix 14/2/1:dpt1:status:listenonly:nosuffix
attr dpt1Treppenlicht devStateIcon on-for-timer.*:on-for-timer@red:off on:on@red:off off:off:on
attr dpt1Treppenlicht stateCmd { if ($gadName eq 'status' && $state eq 'on') {
fhem ("sleep 15.0 $name quiet; set $name switch off");
return 'on-for-timer';
}
return $state;
}
stateCmd reagiert auf die "status = on" -msg vom Aktor, startet einen 15 Sekunden Timer und schaltet nach Ablauf auf off. Gleichzeitig wird das DevstateIcon auf "on-for-timer" gesetzt.
Sensor - mit Umrechnung
Ein Windspeed Sensor sendet einen dpt9 Wert in Meter/Sekunde (nach ISO). Nachdem die gebräuchliche Einheit für Windgeschwindigkeiten km/h sind, muss also umgerechent werden. Das kann mittels Userreading passieren, geht aber auch einfacher:
defmod Windspeed KNX 14/0/9:dpt9.005:get:nosuffix
attr Windspeed stateCmd {return sprintf("%.1f",ReadingsNum($name,'g1',0)*3.6);;}
attr Windspeed stateFormat state km/h
Im reading g1 steht die WIndspeed in m/s, im reading state (siehe stateCmd) die Windspeed in km/h - ohne Einheit, im Internal STATE die Windspeed mit Einheit.
Will man jedoch auch im reading state die Einheit haben, adaptiert man das stateCmd Attribute z.b. so:
attr Windspeed stateCmd {return sprintf("%.1f km/h",ReadingsNum($name,'g1',0)*3.6);;}
und lässt das Attr. stateFormat weg.
Dimmer
Eine Steuerung für KNX-Dimmer. Die Bedienung kann sowohl über on/off, als auch über prozent-Helligkeit und über dimup/dimdown (jeweils 10%) erfolgen. Dazu sind insgesamt vier GA-Adressen definert, die im KNX-Aktor (mittels ETS) konfiguriert sind .
"EinAus" ist die GA für das senden von on/off, "Status" - die Rückmeldung vom Aktor, "Dimmen" ist die GA für das Senden von Helligkeitswerten (Range 0-100%), "Dimmstatus" die Rückmeldung vom Aktor.
Das devStateIcon wird grau bei state=off, gelb bei state=on oder bei state= >0.
Die eventMap-Syntax ist reichlich verwirrend, im Wesentlichen: ein klick auf "dimup" erhöht den Wert von "Dimmen" um 10%, "dimdown" reduziert um 10%.
stateCmd wird bei jedem Event aufgerufen, in diesem Fall: Wenn sich "EinAus" ändert, wird dieser Wert nicht nur in das reading EinAus geschrieben, sondern auch in das reading Dimmen, allerdings übersetzt: on =>100, off=>0. Damit zeigt der Slider jederzeit den richtigen Zustand an. Zusätzlich wird der Wert auch in das Reading state geschrieben. Weiters: ändert sich "Dimmstatus", wird dieser Wert auch in das reading Dimmen geschreiben, damit der Slider auch den richtigen Wert anzeigt (der Dimmer könnte ja auch ausserhalb von FHEM bedient werden...).
webCmd und widgetOverride bestimmen das Aussehen und die Funktion der Overview Zeile.
defmod Dimmer KNX 14/6/1:dpt1:EinAus:set:nosuffix\
14/7/1:dpt1:Status:listenonly:nosuffix\
14/6/5:dpt5.001:Dimmen:set:nosuffix\
14/7/5:dpt5.001:DimmStatus:listenonly:nosuffix
attr Dimmer devStateIcon devStateIcon off:li_wht_off:on on:li_wht_on:off 0.*:li_wht_off:on \d+.*:li_wht_on:off
attr Dimmer eventMap {usr=>{'^dimup'=> '" . sprintf("Dimmen %d",minNum(100,ReadingsNum($NAME,"Dimmen",0) + 10)) . "', \
'^dimdown' => '" . sprintf("Dimmen %d",maxNum(0,ReadingsNum($NAME,"Dimmen",0) - 10)) . "'}, \
fw=>{'^dimup'=> 'dimup', '^dimdown'=> 'dimdown'} }
attr Dimmer stateCmd { if ($gadName eq 'DimmStatus') {\
fhem ("sleep 0.05 quiet;;setreading $name Dimmen $state;;");; \
}\
elsif ($gadName eq 'EinAus') {\
my $val = ($state eq 'on')?'100':'0';;\
fhem ("sleep 0.05 quiet;;setreading $name Dimmen $val;;");;\
}\
return $state;;\
}
attr Dimmer webCmd :dimup:dimdown:Dimmen
attr Dimmer widgetOverride Dimmen@set:slider,0,5,100
Garagentor Steuerung
Dieses Beispiel kann für die (noch immer) üblichen 1-Taster Garagentor-Steuerungen genutzt werden.
Die GA 14/1/100-move ist einem Aktor zugeordnet, der den Garagentor-Taster simuliert.
Die GA 14/1/101-move_status ist die übliche Rückmeldung vom Status des Aktors. Wird hier nicht verwendet, kann weggelassen werden.
Die GA 14/1/102-Doorstatus ist mit dem Garagensensor (KNX-Input) Tor= zu/offen verknüpft.
defmod Garagentor KNX 14/1/100:dpt1.001:move:set:nosuffix\
14/1/101:dpt1.001:move_status:listenonly:nosuffix\
14/1/102:dpt1.019:Doorstatus:listenonly:nosuffix\
attr Garagentor IODev myKNXIO
attr Garagentor comment set door trigger for 2 seconds, Status des Tors wird durch GA "Doorstatus" bestimmt.
attr Garagentor devStateIcon closed:fts_garage_door_100@green:on open:fts_garage@red:on
attr Garagentor eventMap {usr=>{'on'=>'move on-for-timer 2','move off'=>'off'} }
attr Garagentor stateRegex /move// /move_status//
attr Garagentor webCmd :
attr Garagentor widgetOverride move:on
Ein Klick auf das DeviceState-Icon bewirkt ein "Set on", das wird mittels eventMap auf "Set move on-for-timer 2" geändert. Der KNX-Aktor schließt den entsprechenden Kontakt für zwei Sekunden, simuliert damt einen Taster. Das Attribut stateRegex verhindert, dass von move und von move_status GAs der Wert ins reading "state" geschrieben wird. Ist das Garagentor geöffnet, wird der Wert von GA Doorstatus "open" - was auch ins state-reading kopiert wird und damit das DevstateIcon als offen/geschlossen anzeigt.
Alternativ: falls der KNX-Aktor eine "TreppenLicht Funktion" implementiert hat (bei einem on wird eingeschaltet und nach x Sekunden augeschaltet), kann das Attribut eventMap komplett weggelassen werden.
"Doorstatus" muss nicht unbedingt ein KNX-Gerät sein, das könnte auch von einem anderen Device z.B.via notify gesetzt werden:
setreading Garagentor Doorstatus open/closed
Slider - einfach
define Slider_Test KNX 15/2/2:dpt5:Position
attr Slider_Test webCmd Position
attr Slider_Test widgetOverride Position@set:slider,0,5,100
Slider - mit Rückmeldung
define Slider2_Test KNX 15/2/2:dpt5.001:Position:set:nosuffix 15/2/3:dpt5.001:PosStatus:get:nosuffix
attr Slider2_Test stateCmd { fhem "sleep 0.05 quiet;; setreading $name Position $state" if ($gadName eq 'PosStatus');; return $state;; }
#attr Slider2_Test userReadings Position:PosStatus.* {return readingsNum($name, 'PosStatus',0);; }
attr Slider2_Test webCmd Position
attr Slider2_Test widgetOverride Position@set:slider,0,5,100
Das Attr stateCmd setzt den Wert der vom Aktor kommt - zusätzlich in das reading 'Position', damit der Slider immer auch die aktuelle Position anzeigt.
Alternativ zu Attr stateCmd kann auch Attr userReadings verwendet werden.
Die doppelten semicolons sind aus parsing Gründen nötig. Falls man das Attribut über Device-Detail-view setzt, sind nur einfache ; nötig!
Zwei Slider mit Rückmeldung
Z.B. für eine Jalousie mit Lamellensteuerung. Das ist eine Erweiterung des vorigen Beispiels.
define dpt5test KNX 9/1/1:dpt5.001:blind:set:nosuffix 9/1/2:dpt5.001:blindStatus:listenonly:nosuffix
9/1/3:dpt5.001:slat:set:nosuffix 9/1/4:dpt5.001:slatStatus:listenonly:nosuffix
attr dpt5test devStateIcon {Jal_devStateIcon()}
attr dpt5test room KNXtest
attr dpt5test stateCmd { if ($gadName =~ /(.*)Status/x) {
fhem ("sleep 0.05 quiet; setreading $name $1 $state");
}
return $state;
}
attr dpt5test stateFormat 1:blind
<br/>
2:slat
attr dpt5test webCmd blind:slat
attr dpt5test webCmdLabel Blind
:Slat
attr dpt5test widgetOverride blind@set:slider,0,1,100 slat@set:slider,0,10,100
Dazu braucht es noch eine sub in 99_myUtils.pm (siehe auch Beispiel Jalousie / Rolladen). Der Trick liegt in der indizierten Variante von stateFormat (1:blind,...), damit wird auch in devStateIcon dieser Index ausgewertet! Leider gibts für die Lamellen-Stellung nur 3 Icons, für die Stellungen: 0%,50%,100%.
## return string for devStateIcon
## input: none
## return string
sub Jal_devStateIcon {
my $iconstring = 'block.on:fts_door_open@red ' .
"block.off: " .
'aufab.off:black_down:Ab ' .
'aufab.on:black_up:Auf ' .
'moving:fts_shutter_updown@red:Stop ' .
'1.100.*:fts_shutter_100 1.1\d.*:fts_shutter_10 ' .
'1.2\d.*:fts_shutter_20 1.3\d.*:fts_shutter_30 ' .
'1.4\d.*:fts_shutter_40 1.5\d.*:fts_shutter_50 ' .
'1.6\d.*:fts_shutter_60 1.7\d.*:fts_shutter_70 ' .
'1.8\d.*:fts_shutter_80 1.9\d.*:fts_shutter_90 ' .
'1.\d.*:fts_window_2w ' .
'2.100.*:fts_blade_arc_close_100 ' .
'2.\d\d.*:fts_blade_arc_close_50 ' .
'2.\d.*:fts_blade_arc_close_00 ';
return $iconstring;
}
RaumThermostat / HeizungsAktor
define XXXZimmer_Heizung KNX 5/0/52:dpt9:solltemp:set:nosuffix 5/0/53:dpt9:solltemp_ist:get:nosuffix 5/0/50:dpt9:temperature:get:nosuffix 5/0/51:dpt5.001:valvepos:get:nosuffix
attr XXXZimmer_Heizung comment GAs: SollTemp-schreiben, SollTemp-lesen, IstTemp, ValvePosition
attr XXXZimmer_Heizung stateFormat temperature °C, Soll: solltemp_ist °C, Ventil: valvepos
attr XXXZimmer_Heizung webCmd solltemp
attr XXXZimmer_Heizung webCmdLabel SollTemperatur
attr XXXZimmer_Heizung widgetOverride solltemp@set:18.0,18.5,19.0,19.5,20.0,20.5,21.0,21.5,22.0,22.5,23.0,23.5,24.0,24.5,25.0 solltemp_ist:noArg temperature:noArg
attr XXXZimmer_Heizung widgetOverride solltemp@set:slider,18,0.5,25,1 solltemp_ist:noArg temperature:noArg
Beispiel für einen RaumThermostat / Heizungsregler. Die Soll-Temperatur kann entweder mittels pull-down oder mittels slider eingestellt werden. Siehe die beiden Attribute widgetoverride... (nur eines davon verwenden!)
Falls solltemp_ist nicht zur Verfügung steht, kann es weggelassen werden. Funktion: Es könnte ja die SollTemperatur am Raumthermostat eingestellt worden sein!
valvepos ist der Prozentwert, den das Raumthermostat für das Ventil der FB-Heizung sendet.
Zeit und Datum
define timedev KNX 0/0/7:dpt10:time 0/0/8:dpt11:date 0/0/9:dpt19:datetime
Hier sind alle Varianten von Zeit / Datum dargestellt. Die Empfänger müssen den jeweiligen DPT natürlich unterstützen!
die entsprechenden set-cmds lauten:
# setze das Datum auf den Bus:
set timedev date now
set timedev date 01.11.2021
# setze die Zeit auf den Bus:
set timedev time now
set timedev time 18:33:44
# setze Datum und Zeit (gleichzeitig) auf den Bus:
set timedev datetime now
set timedev datetime 01.11.2020_18:33:44
Text senden / empfangen
define textdev KNX 0/0/9:dpt16:txt
Die entsprechenden set-cmds lauten:
set textdev txt AbCdEfGhIjkLmN # sende text zum KNX display (max 14 Char.)
set textdev txt >CLR< # löscht gesamten text am KNX display
Fhem antwortet auf Read Request vom Bus
define putDemo KNX 1/0/30:dpt9.001:temp 1/0/31:dpt9.001:humidity 1/0/32:dpt9:refVal
attr putDemo putCmd {ReadingsNum($name,'refVal-get',0) if ($gadName eq 'temp');}
Es sind 3 GA_Adressen definiert, FHEM antwortet allerdings nur auf einen read-request vom Bus wenn die 1/0/30 Adresse angesprochen wird, mit dem Wert der im refVal reading steht!
Jalousie / Rolladen
Ein komplexes Beispiel, getestet mit einem Jal-Aktor von MDT. Ganz wichtig ist die GA: moving, der Aktor sendet on solange sich die Jalousie bewegt. Das ist ein Parameter, der mittels ETS konfiguriert werden kann. Ergebnis ist ein Device, dass jederzeit die Position anzeigt, Schlaltfllächen für Auf/Ab und einen Slider für's setzen der absoluten Position bietet. Dazu braucht es allerdings zwei Subroutinen in der 99_myUtils!
define Jal_Kueche KNX 5/1/53:dpt1.008:aufab:set:nosuffix
5/1/55:dpt1.010:stop:set:nosuffix
5/1/57:dpt1:moving:listenonly:nosuffix
5/1/58:dpt5.001:position:set:nosuffix
5/1/60:dpt5.001:posstatus:get:nosuffix
5/1/72:dpt1:block:set:nosuffix
5/1/65:dpt1:uppos:listenonly:nosuffix
5/1/66:dpt1:dnpos:listenonly:nosuffix
attr Jal_Kueche cmdIcon Auf:black_up Ab:black_down Stop:remotecontrol/black_btn_RED
attr Jal_Kueche comment GA's: aufab,stop,movestatus,posstatus,Setposition,block,uppos,dnpos
attr Jal_Kueche devStateIcon {Jal_devStateIcon()}
attr Jal_Kueche eventMap { usr=>{'Stop'=>'stop stop','Auf'=>'aufab up','Ab'=>'aufab down'} }
attr Jal_Kueche stateCmd {Jal_stateCmd($name,$gadName,$state)}
attr Jal_Kueche webCmd Auf:Ab:position
attr Jal_Kueche widgetOverride position@set:slider,0,5,100
.. und die beiden subs in 99_myUtils.pm (Diese werden von allen Jalousien / Rolladen verwendet.
### Jalousie Utilities
## return string for stateCmd
## input: devicename, Gadname, state
sub Jal_stateCmd {
my ($dname,$gadname,$dstate) = @_;
my $newstate = '';
if (ReadingsVal($dname,'block','off') eq 'on' ) {
$newstate = 'block:on';
} elsif (ReadingsVal($dname,'moving','off') eq 'on' ) {
$newstate = 'moving';
Log3 $dname, 5, "in stateCmd-movingon: $dname, $gadname,$dstate,newstate: $newstate";
} else {
$newstate = int((ReadingsNum($dname,'posstatus',0)+5)/10) * 10;
}
return $newstate;
}
## return string for devStateIcon
## input: none
## return string
sub Jal_devStateIcon {
my $iconstring = 'block.on:fts_door_open@red ' .
'block.off: ' .
'wind.on:weather_wind@red ' .
'wind.off: ' .
'aufab.off:black_down:Ab ' .
'aufab.on:black_up:Auf ' .
'moving:fts_shutter_updown@red:Stop ' .
'100.*:fts_shutter_100 1\d.*:fts_shutter_10 ' .
'2\d.*:fts_shutter_20 3\d.*:fts_shutter_30 ' .
'4\d.*:fts_shutter_40 5\d.*:fts_shutter_50 ' .
'6\d.*:fts_shutter_60 7\d.*:fts_shutter_70 ' .
'8\d.*:fts_shutter_80 9\d.*:fts_shutter_90 ' .
'\d.*:fts_window_2w';
return $iconstring;
}
Die sub stateCmd berücksichtigt auch noch die GA: block - z.B. wenn Fenster/Tür offen ist oder einen einen WindAlarm!
Jalousie / Rolladen - Erweiterung mit ASC (AutoShuttersControl)
Das ist eine Erweiterung des vorigen Beispiels. Die grundsätzliche Funktionalität von ASC wird hier behandelt. Im Folgenden werden nur jene Definitionen gezeigt, die KNX-spezifisch sind.
Einige Funktionen des ASC.Moduls sind in einem KNX.System möglicherweise bereits vorhanden, z.B.: automatisch Rauf-/Runterfahren bei diversen Alarmen (Wind,Regen,Frost, Fenster/Tür offen) oder in Kombination mit einer Wetterstation auch Beschattung. Das ASC Modul sendet Werte von 0-100, um die Jalousieposition zu setzen und erwartet im ASC_Pos_Reading Attribut die aktuelle Position.
attr Jal_Kueche ASC 1
attr Jal_Kueche ASC_Closed_Pos 100
attr Jal_Kueche ASC_Open_Pos 0
attr Jal_Kueche ASC_CommandTemplate set $name position $pos
attr Jal_Kueche ASC_Pos_Reading posstatus
ASC_Open_Pos, ASC_Closed_Pos: 0 bedeutet Jalousie ist oben, 100 unten.
ASC_Pos_Reading: das ist der Ist-Wert der Jalousie. Muss mit dem Readingnamen im KNX-Device übereinstimmen.
ASC_CommandTemplate: so muss der set command für das KNX-Device zusammengestellt werden, also z.B: set Jal_Kueche position 50
Beim Testen wurde festgestellt, dass nach Definition/Änderung von Attributen u.U. ein FHEM Restart erforderlich ist, um die korrekte Funktion des ASC Moduls zu erhalten.
Um die Funktion zu testen, kann man den Befehl set <ASC_device> wiggle verwenden. Die Jalousie sollte sich um 5% (default) bewegen und nach 60 Sekunden um 5% in die Gegenrichtung.
Slider - mit Rückmeldung und Wert umrechnung
Ein komplexer Fall, wo ein Hersteller zwar den dpt5 verwendet, aber sein "eigenes Zahlen-Format" implementiert hat. Konkret geht's um eine Lüftungsanlage, die Stufen 0 (=Aus) bis 8 (=Maximum) verwendet. Am Bus kommen / werden erwartet die folgenden Werte:
0 (Aus)->0, 1->31, 2->63, 3->95, ... , 8->255
Im FHEM-Web sollen aber die Stufen 0-8 verwendet werden.
define KNXStufentest KNX 11/1/18:dpt5:StufeSoll:set:nosuffix 11/1/20:dpt5:StufeIst:get:nosuffix
attr KNXStufentest eventMap { usr => {'Aus' => 'StufeSoll 0', '^Ein' => 'StufeSoll ' . (3 * 32 - 1), '^Stufe (\d)' => '" . sprintf("StufeSoll %d",(($1 == 0)?0:($1 * 32 - 1)) ) . "' },
fw => {'^Ein' => 'Ein', '^Stufe (\d)' => 'Stufe' } }
attr KNXStufentest stateCmd { ($state,undef) = split(/\s/ix,$state);
my $stateC = int(($state + 1) / 32);
if ($gadName eq 'StufeIst') {
fhem ("sleep 0.1;setreading $name Stufe $stateC");
}
if ($gadName eq 'StufeSoll') {
fhem ("sleep 0.1;setreading $name Stufe $stateC");
}
return $state;
}
attr KNXStufentest webCmd Aus:Ein:Stufe
attr KNXStufentest widgetOverride Aus:noArg Ein:noArg Stufe@set:slider,0,1,8
Ankommende Messages (von Alias StufeIst) werden wie üblich im reading "StufeIst" (Werte: 0-255) gespeichert und zusätzlich umgerechnet und im reading "Stufe" (Wert: 0-8) gespeichert. Ein cmd vom User (Werte: 0-8) wird durch die eventMap umgerechnet und auf den Bus gesendet. Zusätzlich gibt's noch die Schaltflächen "Ein" und "Aus" . Auch diese Werde mittels eventMap auf Stufe 3(=Ein) bzw. Stufe 0(=Aus) umgerechnet. Die Syntax der eventMap ist gewöhnungsbedüftig, aber so funktioniert's! Was noch fehlt ist die Darstellung der Lüfterstufe mittels Icon. Das Beispiel soll auch zeigen, dass man aus einem cmd bzw. event einen (zusätzlichen) beliebigen reading-namen mit Wert erstellen kann.
RGBW Steuerung (dpt251.600)
Die GUI für diesen dpt ist komplex, weil sie aus zwei Widgets besteht: colopicker,RGB und slider.
Die eventmap setzt die beiden Werte (RGB u. White), die jeweils von den widgets kommen, zusammen und sendet das Resultat an den Bus.
Der stateCmd setzt zwei "Hilfs-readings" (rgb,white), die aktuellen Basis-Werte für die widgets darstellen.
define dpt251tst KNX 14/1/251:dpt251.600:set:nosuffix
attr dpt251tst eventMap {usr => {'^rgb.(.+)' => '" . sprintf("g1 %s%s",$1,substr(ReadingsVal($NAME,"state","00000000"),6,2)) . "' ,
'^white.(.+)' => '" . sprintf("g1 %s%.2x",substr(ReadingsVal($NAME,"state","00000000"),0,6),round($1*2.55,0)) . "' },
fw => {'^rgb.(.+)' => 'rgb', '^white.(.+)' => 'white'},
}
attr dpt251tst stateCmd { my $rgb = substr($state,0,6);
my $white = round(hex(substr($state,6,2))/2.55,0);
fhem("sleep 0.1; setreading $name rgb $rgb; setreading $name white $white");
return $state;
}
attr dpt251tst webCmd rgb:white
attr dpt251tst widgetOverride rgb:colorpicker,RGB white@set:slider,0,1,100
DPT nicht unterstützt im KNX Modul?
Im KNX-Modul sind (fast) alle DPTs unterstützt, die in den frei verfügbaren Standarddokumenten definiert sind. Hersteller definieren manchmal eigene sub-DPTs, die dann möglicherweise nicht unmittelbar unterstützt sind.
Im Wesentlichen unterscheiden sich die sub-DPTs z.B. dpt9.020 von den "Haupt-DPTs" z.B. dpt9 durch die angefügte Einheit, den min/max Werte-Bereich, die Skalierung oder einen Offset. Falls also ein Gerät eine 2Byte-float Wert senden will, dann könnte das so aussehen:
define dpt9test KNX 0/4/6:dpt9
attr dpt9test format g/m³ # gramm / m³
und schon steht die richtige Einheit dahinter... Oder Skalierung - Watt -> kW:
attr dpt9test stateCmd { return sprintf('%.3f kW',$state / 1000); }
Falsch definierte DPTs (z.B: dpt5 statt dpt7) produzieren falsche Ergebnisse, sowohl in FHEM als auch im KNX Device!
Übernehmen dieser Beispiele in die eigene Konfiguration
Die meisten dieser Beispiele sind mittels "exportdevice <name>" erstellt. Bei der Übernahme mit c&p in die FHEM- commandozeile (oder auch Telnet) gibt's Fallstricke...(Es müssen Semicolons u. Zeilenumbrüche maskiert werden). Um das zu umgehen, schlage ich folgenden Vorgangsweise vor:
Definiere z.B. ein (kompliziertes) Attr stateCmd auf der FHEM-cmd Zeile:
attr meinDevice stateCmd {}
... also mit nichts drin! - Damit kann's auch keine Syntaxfehler geben! Danach geht man in den device-detail-View, klickt auf statecmd und mit c&p wird der code zwischen den (äussersten {} ) eingefügt. Selbes Vorgehen gilt auch für komplexe DevstateIcon, notifies, at,... Noch grössere code Teile sind sinnvoller in einer sub-routine in 99_myUtils.pm aufgehoben und werden z.B. im stateCmd aufgerufen:
attr <meinDevice> stateCmd { $state = meineAllerwichtigsteSubroutine(p1,p2,p3); }
Das hat dann auch den Vorteil, dass die sub-Routine von mehreren Devices verwendet werden kann!