http://wiki.fhem.de/w/api.php?action=feedcontributions&user=Hauswart&feedformat=atomFHEMWiki - Benutzerbeiträge [de]2024-03-29T10:09:29ZBenutzerbeiträgeMediaWiki 1.39.3http://wiki.fhem.de/w/index.php?title=KNXIO&diff=37457KNXIO2022-05-30T12:58:58Z<p>Hauswart: /* Umstellung von TUL oder KNXTUL Modul */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Unterstützung des KNX Feldbus in FHEM<br />
|ModType=d<br />
|ModForumArea=KNX/EIB<br />
|ModFTopic=<br />
|ModTechName=00_KNXIO.pm<br />
|ModOwner=Erwin ({{Link2FU|115|Forum}}/[[Benutzer Diskussion:Erwin111|Wiki]])<br />
}}<br />
Das Modul [[KNXIO]] implementiert die Unterstützung für den Gebäudeautomations-Feldbus [https://de.wikipedia.org/wiki/KNX-Standard KNX] (eine Weiterentwicklung von EIB) innerhalb von FHEM.<br />
<br />
== Vorwort ==<br />
KNX ist in FHEM nach dem 2-stufigen Modell implementiert. Das KNXIO-Modul unterstützt die Kommunikation mit einem KNX-Gateway, der "Aussenwelt", während das [[KNX|KNX-Modul]] die logische Schnitstelle zum Anwender ist.<br />
<br />
Die Idee zu diesem Modul ist: ein Modul für (fast) alle möglichen Kommunikations-Varianten zu haben, das auch vernünftig wartbar ist. Dieses Modul soll langfristig die bisherigen Module TUL und KNXTUL ablösen. <br />
<br />
KNX-secure ist nicht unterstüzt, weil bisher m.W. keine frei zugängliche Dokumentation des Prokotolls verfügbar ist und ich dzt. kein GW besitze, dass KNX-secure unterstützt. <br />
== Anwendung ==<br />
=== Define ===<br />
<syntaxhighlight lang="text"><br />
define <name> KNXIO <[MHT]> <IP-Adresse/Hostname>:<Port> <Phy-Adresse> bzw.<br />
define <name> KNXIO S <socket-path> <Phy-Adresse><br />
<br />
</syntaxhighlight>Wie in FHEM üblich, alles was hier zwischen <...> dargestellt ist, sind verpflichtende Angaben! Optionales wird zwischen [...] dargestellt. <br />
<br />
==== Definitions-Felder im Detail ====<br />
<br />
====== Mode: ======<br />
* '''H -Host Mode:''' Verbindung zu einem KNX-Gateway mit UDP Point-Point Protokoll. Dieser Protokoll wird auch von der ETS verwendet (KNXNET/IP). Das Protokoll ist sehr kritisch in Bezug auf Timing, Verzögerungen in FHEM (durch andere Tasks...) größer 1 Sekunde führen zu Verbindungsabbrüchen! Die Verbindung wird zwar unmittelbar wieder hergestellt, allerdings können einige Messages verloren gehen. <br />
* '''M -Multicast mode:''' Verbindung zu knxd-Daemon oder KNX-Router mit Multicast Protokoll. Dieses Protokoll wird auch von der ETS verwendet (KNXNET/Routing). Falls ein KNX-Gateway Multicast unterstützt, braucht man keine knxd Installation! Dieser Modus ist der Nachfolger des KNXTUL-Moduls. <br />
* '''T -TCP Mode:''' Verbindet mittels TCP-Protokoll mit knxd. Dieser Modus ist der Nachfolger des TUL-Moduls.. Eine direkte Unterstützung von Seriellen/USB Gateways ist nicht implementiert! Falls ein Serielles / USB -Gateway verwendet wird ist die Empfehlung, das via knxd-daemon einzubinden und die Modes: M,S oder T zur Verbindung knxd->FHEM zu verwenden. <br />
* '''S -Socket Mode:''' Verbindet mittels UNIX_Socket zum knxd - Funktionert nur wenn sowohl FHEM als auch knxd am selben System laufen! Getestet wurde mit knxd-Verion 0.14.30. (Funktioniert definitiv NICHT mit knxd Version 0.10.0) <br />
* '''X - Dummy Mode:''' Mode zum Testen ohne KNX-GW (und für ganz spezielle Fälle...) <br />
<br />
=====IP-Adresse/Hostname:Port=====<br />
Hostnamen sind unterstützt im Mode H und T. <br />
<br />
Default Multicast Adresse (Mode M) ist: 244.0.23.12<br />
<br />
Default Port für Mode H und M ist 3671, für Mode T 6720.<br />
<br />
Default Socket path (Mode S) : /var/run/knxd (knxd-Version: 0.10.0) oder /run/knx (knxd-Version: 0.14.46) oder /var/run/knx (knxd-Version: 0.14.46), am besten in /etc/knxd.conf nachschauen!<br />
=====Phy-Adresse=====<br />
Das ist die Physikalische Adresse, die das KNX-Gateway bzw. knxd für Clients am LAN (also auch FHEM) bereitstellt. Der Wert sollte (bei Verwendung knxd) dem -E Parameter (Pool) in der knxd-Konfiguration entsprechen.<br />
<br />
Alle Parameter sind verpflichtend! Bitte sicherstellen, dass es nur einen Kommunikationspfad zwischen dem KNX-Gateway und FHEM gibt! Das ist am sichersten erreichbar, wenn es in FHEM '''nur ein IO-Device''' (TUL/KNXTUL/KNXIO) für den KNX-Bus gibt.<br />
====Definitions-Beispiele====<br />
<syntaxhighlight lang="text"><br />
define myKNXGW KNXIO H 192.168.1.201:3671 0.0.51<br />
define myKNXGW KNXIO M 224.0.23.12:3671 0.0.51<br />
define myKNXGW KNXIO S /var/run/knx 0.0.51<br />
define myKNXGW KNXIO T 192.168.1.200:6720 0.0.51<br />
</syntaxhighlight><br />
Siehe auch {{Link2CmdRef|Anker=KNXIO}}. <br />
<br />
Empfohlene Parameter für knxd Konfiguration: (üblicherweise zu finden: /etc/knxd.conf)<br />
<syntaxhighlight lang="text"><br />
KNXD_OPTS="-e 0.0.50 -E 0.0.51:8 -D -T -R -S -b ipt:192.168.xx.yy" # connect to a knx-GW with ip-addr<br />
KNXD_OPTS="-e 0.0.50 -E 0.0.51:8 -D -T -R -S -single -b tpuarts:/dev/ttyxxx" # connect to a serial/USB KNX GW<br />
KNXD_OPTS="-e 0.0.50 -E 0.0.51:8 -D -T -S -b ip:" # knxd acts as multicast client (connect to other knxd or KNX-Router with MC support)<br />
</syntaxhighlight>Der Parameter '''-e 0.0.50''' definiert die phy-Addresse des Gateways, '''-E 0.0.51:8''' definiert einen Pool von 8 Phy-Addr. für Clients am LAN! (FHEM ist ein Client am LAN aus KNX Sicht! )<br />
<br />
Die Parameter '''-R -S''' aktivieren den Multicast Support, '''-T -S''' den Tunnel Support im knxd. '''-D''' aktiviert Autodiscovery, wird allerdings von FHEM/KNXIO nicht verwendet, aber von der ETS-Software! <br />
<br />
Der '''-S''' Parameter muss immer als letztes der Server Parameter (-D -T -R) stehen! <br />
<br />
Siehe auch [[Knxd|knxd-Wiki]]<br />
<br />
=== Attribute ===<br />
* '''disable''' - ident zum FHEM Standard - kein Senden / Empfangen möglich.<br />
* '''verbose''' - ident zum FHEM Standard - bestimmt welche/wieviele Meldungen ins Log geschrieben werden.<br />
<br />
== Matrix - Modes<->Produkte ==<br />
Die Tabelle soll die möglichen KNXIO-modes für KNX-GW's bzw. KNX-Router zeigen. Entstanden (und hoffentlich erweitert...) durch eigene Erfahrung und Tests bzw. auch aus Feedback aus dem Forum. Verwendete Produkt-Bezeichnungen können geschützte Namen sein, Diese werden hier ausschließlich verwendet um die Kompatibilität zum KNXIO-Modul darzustellen. Info über Produkte und ErfolgsMeldungen, aber auch Korrekturen sind willkommen, entweder direkt hier hinzufügen oder via Forum!<br />
{| class="wikitable"<br />
|+<br />
!Produkt<br />
!KNXIO-mode<br />
!Kommentar<br />
|-<br />
|knxd<br />
|M S T<br />
|knxd -daemon (getestet ab V.0.10.0, Mode S ab V.0.14.30)<br />
|-<br />
|Weinzierl IP731<br />
|H T<br />
|4 Tunnel<br />
|-<br />
|Hager TYF120<br />
|H<br />
|mode T ?<br />
|-<br />
|MDT SCN-IP000.02<br />
|T<br />
|4 Tunnel möglich, mode H(untested)?<br />
|-<br />
|MDT SCN-IP100.02<br />
|M T<br />
|4 Tunnel möglich, mode H (untested)?<br />
|-<br />
|Enertex® KNX IP Secure Router<br />
|H M T<br />
|kein support im secure Mode - H,T untested<br />
|-<br />
|<br />
|<br />
|<br />
|-<br />
|Produkte mit seriellen Schnittstellen<br />
| -<br />
|Nur über knxd unterstützt<br />
|}<br />
<br />
== Umstellung von TUL oder KNXTUL Modul ==<br />
Vorgangsweise: Config sichern! Bestehende TUL/KNXTUL - Definition löschen und neue KNXIO - Definition anlegen. FHEM restart!<br />
<br />
Auf Grund der Änderung des Namens kann es passieren, dass im '''Reading IODev''' der KNX-Geräte nach wie vor das bisherige IO-Device (z.b: myTUL) steht.<br />
<br />
Damit würde das Senden von FHEM -> KNX nicht funktionieren. Abhilfe schaftt das definieren vom '''Attribut IODev''' für alle KNX-Geräte, z.B so:<syntaxhighlight lang="text"><br />
attr TYPE=KNX IODev myKNXIO<br />
</syntaxhighlight>Das '''Attribut IODev''' kann nach einem weiteren restart vom FHEM wieder gelöscht werden! <syntaxhighlight lang="text"><br />
deleteattr TYPE=KNX IODev<br />
</syntaxhighlight>Es sollte jetzt das '''Reading IODev''' in den KNX-Geräten auf das neueKNXIO-Gerät gesetzt sein! Das wird ab jetzt auch für künftige FHEM Starts verwendet.<br />
<br />
=== TUL-Modul ===<br />
<syntaxhighlight lang="text"><br />
Aus:<br />
define myTUL TUL 192.168.5.246:6720 5.1.251<br />
..wird:<br />
define myKNXGW KNXIO T 192.168.5.246:6720 5.1.251<br />
</syntaxhighlight><br />
<br />
=== KNXTUL-Modul ===<br />
<syntaxhighlight lang="text"><br />
Aus:<br />
define myKNXTUL KNXTUL 0.0.252 <br />
..wird:<br />
define myKNXGW KNXIO M 224.0.23.12:3671 0.0.252<br />
</syntaxhighlight><br />
<br />
== Bekannte Probleme ==<br />
<br />
==== Timing Problem Mode H ====<br />
Wie bereits erwähnt, dieser Mode stellt hohe Ansprüche an das Antwortzeitverhalten von FHEM. Jede empfangene und gesendete Message muss in weniger als 1 Sekunde bestätigt werden. Falls FHEM länger mit anderen Modulen beschäftigt ist, gibt das Probleme. Typische Module, die Probleme machen können, sind (u.A.): SVG,, Onewire, HTTPMOD,, usw...<br />
<br />
Typische Meldungen im Log:<syntaxhighlight lang="text"><br />
2021.12.13 00:00:06.506 4: KNXIO_TunnelRequestTO hit - attempt resend<br />
2021.12.13 00:00:08.023 3: KNXIO_TunnelRequestTO hit - sending disconnect request<br />
2021.12.15 13:12:09.045 3: KNXIO_Read: TunnelRequest received: duplicate message received (seqcntr=67) - ack it<br />
</syntaxhighlight>Eine mögliche Lösung: Mittels apptime cmd: "apptime average" bzw. "apptime max" jene Funktionen/Module herausfinden, die viel Zeit in FHEM beanspruchen... Werte größer 500ms können die Kommunikation zwischen FHEM und dem KNX-GW massiv stören. Evtl hilft auch, die Anzahl Events zu reduzieren (Stichwort: event-on-change-reading).<br />
<br />
Falls das nicht funktioniert, gibts noch die Möglichkeit, für das KNXIO-Modul eine eigene FHEM Instanz zu installieren und mittels FHEM2FHEM mit der Hauptinstanz zu verbinden.. In diesem Beispiel auf zwei Raspberrys im selben LAN. Sinnvollerweise beginnt man mit der Konfiguration von FHEM-B.<br />
<br />
===== Konfiguration FHEM-A (Hauptinstanz): =====<br />
Das ist jenes FHEM, wo bisher das KNXIO Modul und alle KNX-Devices definiert sind.<syntaxhighlight lang="text"><br />
define <remoteDevice> KNXIO X # das ist ein dummy device,wird aber für die FHEM2FHEM definition benötigt<br />
<br />
define <name_F2F> FHEM2FHEM <ip-addr:port> RAW:<remoteDevice> # verbindet zum telnet-dev auf FHEM-B<br />
attr <name_F2F> keepaliveInterval 60<br />
attr <name_F2F> reportConnected 1<br />
<br />
</syntaxhighlight>'''Wichtig:''' <remoteDevice> muss in allen Definitionen (FHEM-A, FHEM-B) '''der gleiche Name''' sein! <ip-addr:port> ist die Adresse von FHEM-B, port ist der port aus der telnet-Definition. <br />
<br />
Ändern des Attr IODev in allen KNX-definitionen: Attr IODev muss auf das FHEM2FHEM <name_F2F> Device zeigen. Entweder jedes KNX-device einzeln ändern, oder alle IODev Attribute in allen KNX-devices auf einmal löschen, mittels:<syntaxhighlight lang="text"><br />
deleteattr TYPE=KNX IODev<br />
</syntaxhighlight>Das ist kein Problem, (solange man nur EIN IO-device für KNX definiert hat), FHEM sucht beim start / defmod sich ein passendes IO-Device automatisch aus.<br />
<br />
Die bisherige KNXIO-Definition löschen! (Backup?)<br />
<br />
===== Konfiguration FHEM-B: =====<br />
Starten mit minimal (default) Konfiguration, am besten nach Neu-Installation und fhem-update.<br />
<br />
Hier wird das KNXIO-Modul konfiguriert, das mit dem KNX Gateway kommuniziert.<br />
<br />
Vorher braucht es aber noch einige Definitionen zur Kommunikation mit FHEM-A:<syntaxhighlight lang="text"><br />
define telnetPortKNX telnet <port> global # das kommuniziert mit FHEM-A<br />
attr telnetPortKNX allowfrom (127.0.0.1|192.168.x) # little bit of security, replace x with yr. local network...<br />
<br />
define allowed_telnetPortKNX allowed # little bit of security<br />
attr allowed_telnetPortKNX allowedCommands iowrite,inform,trigger,quit<br />
attr allowed_telnetPortKNX allowedIfAuthenticatedByMe 0<br />
attr allowed_telnetPortKNX validFor telnetPortKNX<br />
<br />
attr initialUsbCheck disable 1 # stört alle seriellen IO's (ausser CUL....)<br />
<br />
attr autocreate ignoreTypes KNX_.* # we dont need/want KNX-devices on this FHEM<br />
<br />
define <remoteDevice> KNXIO <mode> <GW-IP:GW-port> <phy-addr> # exakt gleiche Definition wie bisher in FHEM-A<br />
</syntaxhighlight>'''Empfohlen:''' Für die telnet definition nicht den Standard-port 7072 verwenden, sondern z.B: 7073. <br />
<br />
'''Wichtig:''' Nach der Definition: save und shutdown/restart auf beiden FHEMs! Danach sollte das FHEM2FHEM-device connected zeigen, das KNXIO-device auf FHEM-A disconnected! <br />
<br />
'''Keine weiteren Verbindungen''' zwischen den beiden FHEM machen, e.g: FHEM2FHEM im Log Modus, RFHEM, notifies., Telnet connections,...., -Das ergibt Chaos!<br />
<br />
Es werden alle KNX-Messages zwischen FHEM-A und FHEM-B ausgetauscht!<br />
<br />
Zur Verbesserung der Sicherheit könnte man das telnet-device UND das FHEM2FHEM-device jeweils mit Passwort (globalpassword) und/oder SSL versehen. <br />
<br />
== Links ==<br />
Info zum Thema KNXD Konfiguration (beim Author): [https://github.com/knxd/knxd/wiki KNXD Wiki]<br />
<br />
[[Knxd|Knxd-Wiki]]<br />
<br />
[[FHEM2FHEM|FHEM2FHEM-Wiki]]<br />
[[Kategorie:EIB/KNX]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=KNX_Device_Definition_-_Beispiele&diff=37230KNX Device Definition - Beispiele2022-02-16T06:57:59Z<p>Hauswart: /* RaumThermostat / HeizungsAktor */</p>
<hr />
<div>=== Vorwort ===<br />
{{Randnotiz|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!<br />
Mit diesen Beispielen sollte auch der Umstieg auf das KNX-Modul etwas leichter fallen!|RNTyp=Warn}}<br />
<br />
Hier soll mit eine 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.<br />
<br />
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.<br />
<br />
Die [https://fhem.de/commandref.html#KNX Command-Referenz] ist nach wie vor die aktuellste (und verbindliche) Dokumentation des Moduls. Hier sollen zusätzliche Info's, Tip's & Tricks gegeben werden.<br />
<br />
Generelle Hinweise zum KNX Modul sind hier [[KNX]] zu finden.<br />
<br />
=== Beispiele ===<br />
==== on/off Device - einfach ====<br />
<syntaxhighlight lang="text"><br />
define Lampe KNX 0/10/11:dpt1<br />
</syntaxhighlight>Einfachstes KNX-Device ohne Alias und Rückmeldung.<br />
<br />
==== on/off Device - mit Rückmeldung ====<br />
<syntaxhighlight lang="text"><br />
define Lampe KNX 0/10/11:dpt1:EinAus 0/10/12:dpt1:Status:listenonly<br />
attr Lampe webCmd EinAus<br />
# attr Lampe webCmd :<br />
attr Lampe stateFormat Status<br />
attr Lampe devStateIcon off:li_wht_off:on on:li_wht_on:off<br />
</syntaxhighlight>Hier gibt es 2 GA-Adressen, eine zum Schalten und die 2te für die Rückmeldung vom Aktor (muß natürlich via ETS so programmiert sein!).<br />
<br />
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! <br />
<br />
==== on/off Device - mit verzögerter Rückmeldung ====<br />
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"><br />
define dpt1_1tst KNX 14/1/1:dpt1:EinAus:set 14/2/1:dpt1:Status:listenonly:nosuffix<br />
attr dpt1_1tst devStateIcon on:general_an:Aus off:general_aus:Ein steuern.*:hourglass:Aus<br />
attr dpt1_1tst stateRegex /EinAus-set/steuern-/ /EinAus-get//<br />
</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 3 Zusände darzustellen (on,off,steuern). <br />
<br />
Dieses Beispiel könnte auch für die (noch immer) üblichen 1-Taster Garagentor-Steuerungen genutzt werden, In diesem Fall wäre die GA 14/2/1 ein Kontakt, der "Tor zu" ,meldet! <br />
<br />
==== Slider - einfach ====<br />
<syntaxhighlight lang="text"><br />
define Slider_Test KNX 15/2/2:dpt5:Position<br />
attr Slider_Test webCmd Position<br />
attr Slider_Test widgetOverride Position-set:slider,0,5,100<br />
</syntaxhighlight><br />
<br />
==== Slider - mit Rückmeldung ====<br />
<syntaxhighlight lang="text"><br />
define Slider2_Test KNX 15/2/2:dpt5.001:Position:set:nosuffix 15/2/3:dpt5.001:PosStatus:get:nosuffix<br />
attr Slider2_Test stateCmd { fhem "sleep 0.05 quiet;; setreading $name Position $state" if ($gadName eq 'PosStatus');; return $state;; }<br />
attr Slider2_Test webCmd Position<br />
attr Slider2_Test widgetOverride Position:slider,0,5,100<br />
</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!<br />
<br />
==== Zwei Slider mit Rückmeldung ====<br />
[[Datei:KNX dpt5tst.png|rechts|rahmenlos|450x450px]]<br />
Z.B. für eine Jalousie mit Lamellensteuerung. Das ist eine Erweiterung des vorigen Beispiels.<syntaxhighlight lang="text"><br />
define dpt5test KNX 9/1/1:dpt5.001:blind:set:nosuffix 9/1/2:dpt5.001:blindStatus:listenonly:nosuffix<br />
9/1/3:dpt5.001:slat:set:nosuffix 9/1/4:dpt5.001:slatStatus:listenonly:nosuffix<br />
attr dpt5test devStateIcon {Jal_devStateIcon()}<br />
attr dpt5test room KNXtest<br />
attr dpt5test stateCmd { if ($gadName =~ /(.*)Status/x) {<br />
fhem ("sleep 0.05 quiet; setreading $name $1 $state");<br />
}<br />
return $state;<br />
}<br />
attr dpt5test stateFormat 1:blind<br />
<br/> <br />
2:slat<br />
attr dpt5test webCmd blind:slat<br />
attr dpt5test webCmdLabel Blind<br />
:Slat<br />
attr dpt5test widgetOverride blind:slider,0,1,100 slat:slider,0,10,100<br />
</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="text"><br />
## return string for devStateIcon<br />
## input: none<br />
## return string<br />
sub Jal_devStateIcon {<br />
my $iconstring = 'block.on:fts_door_open@red ' .<br />
"block.off: " .<br />
"aufab.off:black_down:Ab " .<br />
"aufab.on:black_up:Auf " .<br />
'moving:fts_shutter_updown@red:Stop ' .<br />
'1.100.*:fts_shutter_100 1.1\d.*:fts_shutter_10 ' .<br />
'1.2\d.*:fts_shutter_20 1.3\d.*:fts_shutter_30 ' .<br />
'1.4\d.*:fts_shutter_40 1.5\d.*:fts_shutter_50 ' .<br />
'1.6\d.*:fts_shutter_60 1.7\d.*:fts_shutter_70 ' .<br />
'1.8\d.*:fts_shutter_80 1.9\d.*:fts_shutter_90 ' .<br />
'1.\d.*:fts_window_2w ' .<br />
'2.100.*:fts_blade_arc_close_100 ' .<br />
'2.\d\d.*:fts_blade_arc_close_50 ' .<br />
'2.\d.*:fts_blade_arc_close_00 ';<br />
return $iconstring;<br />
}<br />
</syntaxhighlight><br />
<br />
==== RaumThermostat / HeizungsAktor ====<br />
[[Datei:Fhemwiki KNX - RaumThermostat.png|rechts|rahmenlos|674x674px]]<br />
<syntaxhighlight lang="text"><br />
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<br />
attr XXXZimmer_Heizung comment GAs: SollTemp-schreiben, SollTemp-lesen, IstTemp, ValvePosition<br />
attr XXXZimmer_Heizung stateFormat temperature °C, Soll: solltemp_ist °C, Ventil: valvepos<br />
attr XXXZimmer_Heizung webCmd solltemp<br />
attr XXXZimmer_Heizung webCmdLabel SollTemperatur<br />
attr XXXZimmer_Heizung widgetOverride solltemp: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<br />
attr XXXZimmer_Heizung widgetOverride solltemp:slider,18,0.5,25,1 solltemp_ist:noArg temperature:noArg<br />
</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!)<br />
<br />
Falls '''solltemp_ist''' nicht zur Verfügung steht, kann es weggelassen werden. Funktion: Es könnte ja die SollTemperatur am Raumthermostat eingestellt worden sein! <br />
<br />
'''valvepos''' ist der Prozentwert, den das Raumthermostat für das Ventil der FB-Heizung sendet.<br />
<br />
==== Zeit und Datum ====<br />
<syntaxhighlight lang="text"><br />
define timedev KNX 0/0/7:dpt10:time 0/0/8:dpt11:date 0/0/9:dpt19:datetime<br />
</syntaxhighlight>Hier sind alle Varianten von Zeit / Datum dargestellt. Die Empfänger müssen den jeweiligen DPT natürlich unterstützen!<br />
<br />
die entsprechenden set-cmd's lauten:<syntaxhighlight lang="text"><br />
# setze das Datum auf den Bus:<br />
set timedev date now<br />
set timedev date 01.11.2021<br />
<br />
# setze die Zeit auf den Bus:<br />
set timedev time now<br />
set timedev time 18:33:44<br />
<br />
# setze Datum und Zeit (gleichzeitig) auf den Bus:<br />
set timedev datetime now<br />
set timedev datetime 01.11.2020_18:33:44<br />
</syntaxhighlight><br />
<br />
==== Text senden / empfangen ====<br />
<syntaxhighlight lang="text"><br />
define textdev KNX 0/0/9:dpt16:txt<br />
</syntaxhighlight>Die entsprechenden set-cmd's lauten:<syntaxhighlight lang="text"><br />
set textdev txt AbCdEfGhIjkLmN # send text to Bus (max 14 Char.)<br />
set textdev txt >CLR< # delete text on the KNX display<br />
</syntaxhighlight><br />
<br />
==== Fhem antwortet auf Read Request vom Bus ====<br />
<syntaxhighlight lang="text"><br />
define putDemo KNX 1/0/30:dpt9.001:temp 1/0/31:dpt9.001:humidity 1/0/32:dpt9:refVal<br />
<br />
attr putDemo putCmd {ReadingsNum($name,'refVal-get',0) if ($gadName eq 'temp');}<br />
</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!<br />
<br />
==== Jalousie / Rolladen ====<br />
[[Datei:KNX JalKueche.png|rechts|rahmenlos|450x450px]]<br />
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 2 sub-routinen in der 99_myUtils!<syntaxhighlight lang="text"><br />
define Jal_Kueche KNX 5/1/53:dpt1.008:aufab:set:nosuffix<br />
5/1/55:dpt1.010:stop:set:nosuffix<br />
5/1/57:dpt1:moving:listenonly:nosuffix<br />
5/1/58:dpt5.001:position:set:nosuffix<br />
5/1/60:dpt5.001:posstatus:get:nosuffix<br />
5/1/72:dpt1:block:set:nosuffix<br />
5/1/65:dpt1:uppos:listenonly:nosuffix<br />
5/1/66:dpt1:dnpos:listenonly:nosuffix<br />
<br />
attr Jal_Kueche cmdIcon Auf:black_up Ab:black_down Stop:remotecontrol/black_btn_RED<br />
attr Jal_Kueche comment GA's: aufab,stop,movestatus,posstatus,Setposition,block,uppos,dnpos<br />
attr Jal_Kueche devStateIcon {Jal_devStateIcon()}<br />
attr Jal_Kueche eventMap { usr=>{"Stop"=>"stop stop","Auf"=>"aufab up","Ab"=>"aufab down"} }<br />
attr Jal_Kueche stateCmd {Jal_stateCmd($name,$gadName,$state)}<br />
attr Jal_Kueche webCmd Auf:Ab:position<br />
attr Jal_Kueche widgetOverride position:slider,0,5,100<br />
</syntaxhighlight>.. und die beiden sub's in 99_myUtils.pm (Diese werden von allen Jalousien / Rolladen verwendet.<syntaxhighlight lang="text"><br />
### Jalousie Utilities<br />
## return string for stateCmd<br />
## input: devicename, Gadname, state<br />
sub Jal_stateCmd {<br />
my ($dname,$gadname,$dstate) = @_;<br />
my $newstate = '';<br />
if (ReadingsVal($dname,"block","off") eq "on" ) {<br />
$newstate = "block:on";<br />
} elsif (ReadingsVal($dname,"moving","off") eq "on" ) {<br />
$newstate = "moving";<br />
Log3 $dname, 5, "in stateCmd-movingon: $dname, $gadname,$dstate,newstate: $newstate";<br />
} else {<br />
$newstate = int((ReadingsNum($dname,"posstatus","0")+5)/10) * 10;<br />
}<br />
return $newstate;<br />
}<br />
<br />
## return string for devStateIcon<br />
## input: none<br />
## return string<br />
sub Jal_devStateIcon {<br />
my $iconstring = 'block.on:fts_door_open@red ' .<br />
"block.off: " .<br />
'wind.on:weather_wind@red ' .<br />
'wind.off: ' .<br />
"aufab.off:black_down:Ab " .<br />
"aufab.on:black_up:Auf " .<br />
'moving:fts_shutter_updown@red:Stop ' .<br />
'100.*:fts_shutter_100 1\d.*:fts_shutter_10 ' .<br />
'2\d.*:fts_shutter_20 3\d.*:fts_shutter_30 ' .<br />
'4\d.*:fts_shutter_40 5\d.*:fts_shutter_50 ' .<br />
'6\d.*:fts_shutter_60 7\d.*:fts_shutter_70 ' .<br />
'8\d.*:fts_shutter_80 9\d.*:fts_shutter_90 ' .<br />
'\d.*:fts_window_2w';<br />
return $iconstring;<br />
}<br />
<br />
</syntaxhighlight>Die sub stateCmd berücksichtigt auch noch die GA: block - z.B. wenn Fenster/Tür offen ist oder einen einen WindAlarm! <br />
<br />
==== Slider - mit Rückmeldung '''und Wert Umrechnung''' ====<br />
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"><br />
0 (Aus)->0, 1->31, 2->63, 3->95, ... , 8->255<br />
</syntaxhighlight>Im FHEM-Web sollen aber die Stufen 0-8 verwendet werden.<br />
<syntaxhighlight lang="text"><br />
define KNXStufentest KNX 11/1/18:dpt5:StufeSoll:set:nosuffix 11/1/20:dpt5:StufeIst:get:nosuffix<br />
<br />
attr KNXStufentest eventMap { usr => {'Aus' => 'StufeSoll 0', '^Ein' => 'StufeSoll ' . (3 * 32 - 1), '^Stufe (\d)' => '" . sprintf("StufeSoll %d",(($1 == 0)?0:($1 * 32 - 1)) ) . "' },<br />
fw => {'^Ein' => 'Ein', '^Stufe (\d)' => 'Stufe' } }<br />
<br />
attr KNXStufentest stateCmd { ($state,undef) = split(/\s/ix,$state);<br />
my $stateC = int(($state + 1) / 32);<br />
if ($gadName eq 'StufeIst') {<br />
fhem ("sleep 0.1;setreading $name Stufe $stateC"); <br />
}<br />
if ($gadName eq 'StufeSoll') {<br />
fhem ("sleep 0.1;setreading $name Stufe $stateC"); <br />
}<br />
return $state;<br />
}<br />
attr KNXStufentest webCmd Aus:Ein:Stufe<br />
attr KNXStufentest widgetOverride Aus:noArg Ein:noArg Stufe:slider,0,1,8<br />
</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. <br />
<br />
=== DPT nicht unterstützt im KNX Modul ? ===<br />
Im KNX-Modul sind (fast) alle DPT's unterstützt, die in den frei verfügbaren Standard-Dokumenten definiert sind. Hersteller definieren manchmal eigene sub-DPT's, die dann möglicherweise nicht unmittelbar unterstützt sind. <br />
<br />
Im wesentlichen unterscheiden sich die sub-DPT's z.B. dpt9.020 von den "Haupt-DPT's" 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"><br />
define dpt9test KNX 0/4/6:dpt9<br />
attr dpt9test format g/m&sup3; # gramm / m³<br />
</syntaxhighlight>und schon steht die richtige Einheit dahinter... Oder Skalierung - Watt -> kW:<syntaxhighlight lang="text"><br />
attr dpt9test stateCmd { return sprintf("%.3f kW",$state / 1000); }<br />
</syntaxhighlight>Falsch definierte DPT's (z.B: dpt5 statt dpt7) produzieren falsche Ergebnisse, sowohl in FHEM als auch im KNX Device!<br />
<br />
=== Übernehmen dieser Beispiele in die eigene config ===<br />
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:<br />
<br />
Definiere z.b. ein (kompliziertes) Attr stateCmd auf der FHEM-cmd Zeile:<syntaxhighlight lang="text"><br />
attr meinDevice stateCmd {}<br />
</syntaxhighlight>... also mit nichts drin! - Damit kann's auch keine syntax-Fehler 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"><br />
attr <meinDevice> stateCmd { $state = meineAllerwichtigsteSubroutine(p1,p2,p3); }<br />
</syntaxhighlight>Das hat dann auch den Vorteil, dass die sub-Routine von mehreren devices verwendet werden kann!<br />
[[Kategorie:Examples]]<br />
[[Kategorie:EIB/KNX]]<br />
[[Kategorie:Gerätemodul]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Datei:Fhemwiki_KNX_-_RaumThermostat.png&diff=37229Datei:Fhemwiki KNX - RaumThermostat.png2022-02-16T06:56:05Z<p>Hauswart: </p>
<hr />
<div>RaumThermostat / HeizungsAktor</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Unbekannte_Funkprotokolle&diff=28249Unbekannte Funkprotokolle2018-11-06T13:32:43Z<p>Hauswart: /* Log-Meldungen */</p>
<hr />
<div>Es gibt jede Menge offiziell in FHEM unterstützte Devices und Funkprotokolle. Solange das Device Ross und Reiter benennt (Homematic, Z-Wave, Intertechno etc.) ist es einfach dieses in FHEM einzubinden. Was aber, wenn selbst mit hinreichend gut aktualisierter Installation nichts erkannt wird und es ein No-Name Produkt ist bei dem man nur die Hoffnung hat, dass es im Innern etwas Bekanntes beherbergt?<br />
<br />
Dieser Wiki-Artikel soll jenen helfen, die Geräte mit einem unbekannten Funkprotokoll an FHEM anbinden bzw. mit FHEM steuern wollen.<br />
<br />
== Basics ==<br />
<br />
==== Hardware ====<br />
<br />
Neben den bekannten Hardware-Dongles gibt es Selbstbaulösungen in Form eines SIGNALduino, CUL oder JeeLink. <br />
<br />
Diese unterscheiden sich in verschiedener Hinsicht:<br />
* Sendemodul (SIGNALduino/CUL -> CC1101; JeeLink -> RF12B) [https://de.wikipedia.org/wiki/Amplitudenumtastung]<br />
* Modulationsverfahren (OOK, ASK/FSK)<br />
* Frequenzband (433 MHz, 868 MHz)<br />
<br />
==== Frequenzbereich ====<br />
Für die funkbasierte Heimautomation kommen im Wesentlichen zwei Frequenzbänder in Frage: 433 und 868 MHz. Die meisten Geräte haben auf der Rückseite ein Typenschild, auf dem das Frequenzband ausgewiesen ist.<br />
<br />
Dann gibt es noch 2,4 GHz und 5 GHz (WLAN, Bluetooth...), dieses Frequenzband wird in diesem Artikel aber nicht betrachtet.<br />
<br />
==== Modulationsverfahren ====<br />
<br />
So, wie vom Rundfunk (AM/FM) her bekannt, kennt man auch bei 433/868 MHz verschiedene Modulationsverfahren. <br />
<br />
* [https://de.wikipedia.org/wiki/Amplitudenumtastung OOK/ASK/Amplitudenabtastung]<br />
: Das Signal des Senders wir auf der angegebenen Frequenz ein-/ausgeschaltet um die Dateninformationen zu übermitteln. <br />
* [https://de.wikipedia.org/wiki/Frequenzumtastung FSK/Frequenzumtastung]<br />
: Der Sender überträgt den Datenstrom indem, ausgehend von der Trägerfrequenz, zwischen Frequenzen (z.B. Frequenz-Frequenzhub, Frequenz+Frequenzhub) hin- und hergeschaltet wird. Dieses Verfahren kennt verschiedene Ausprägungen: 2-FSK, 4-FSK, GFSK (Details siehe [http://www.rfwireless-world.com/Terminology/2FSK-modulation-vs-4FSK-modulation.html hier]).<br />
<br />
==== Encoding oder auch Leitungscode ====<br />
<br />
Die Art und Weise wie dieses Signal interpretiert wird hängt wiederum vom Encoding ab. Dazu sei auf die nachfolgenden Quellen verwiesen.<br />
<br />
* [https://de.wikipedia.org/wiki/Leitungscode Leitungscode (Einstieg)]<br />
* [https://de.wikipedia.org/wiki/Non_Return_to_Zero NRZ]<br />
* [https://de.wikipedia.org/wiki/Manchester-Code Manchester]<br />
<br />
Je nach verwendetem Encoding wird ggf. mehr als 1 Übertragungs-Bit für ein Datenbit benötigt. Der Empfänger erwartet z.B. einen Bitwechsel zu einem bestimmten Zeitpunkt. Eine Abfolge <br />
* 100 (short high, long low) wird als 0<br />
* 110 (long high, short low) wird als 1<br />
interpretiert.<br />
<br />
Im FHEM-Forum gibt es viele freundliche Helfer die Euch bei Bedarf den richtigen Weg weisen.<br />
<br />
==== Signalstruktur ====<br />
<br />
Ein typischer Aufbau einer Signalstruktur sieht z.B. so aus<br />
<br />
| Pause | Sync | Pause | Daten |<br />
<br />
* eine größere Pause zur Trennung der Sequenzen <br />
* ein Sync-Block mit dem sich der Empfänger auf den Sender einstellt<br />
* eine Pause um Sync und Daten zu trennen<br />
* die eigentlichen, zu übertragenden Daten.<br />
<br />
Es müssen nicht immer alle Bestandteile in der übertragenen Signalstruktur vorkommen (Details siehe auch [https://de.wikipedia.org/wiki/Datenpr%C3%A4ambel Datenpräambel] oder auch [https://en.wikipedia.org/wiki/Syncword Syncword]).<br />
<br />
Die Sequenz wird ggf. mehrfach wiederholt <br />
<br />
| Pause | Sync | Pause | Daten | Pause | Sync | Pause | Daten | Pause | Sync | Pause | Daten | ...<br />
<br />
==== Protokoll ====<br />
<br />
Das ist der herstellerspezifische Teil des Signalstroms - die Daten. Hersteller haben i.d.R. ihre eigene Definition der übertragenen Datenströme. Teils werden feste Code-Sequenzen übertragen, es gibt aber auch rollierende Codes (Engl.: Rolling Codes) bei denen sich die Daten bei jeder Übertragung ändern. <br />
<br />
Mit etwas Glück erkennt z.B. SIGNALduino das Protokoll, damit den Hersteller und legt automatisch ein passendes Device in FHEM an. Manchmal gibt es auch Fehlinterpretationen und das vermeintlich bekannte Device entpuppt sich als etwas anderes (Statement aus dem Forum "Lösung war, wo Dooya drauf steht muss nicht immer Dooya drin stecken.").<br />
<br />
== Wie fange ich an? ==<br />
<br />
==== Recherche ====<br />
<br />
Sucht im Internet nach Informationen zu dem fraglichen Device. Zu bekannten Devices sollten sich Informationen finden lassen, die einem weiter helfen. Solltet Ihr fündig werden, verfolgt die Hinweise, wie diese Devices in FHEM eingebunden werden können.<br />
<br />
Wenn sich nichts Verwertbares finden lässt, geht's mit dem nächsten Abschnitt weiter.<br />
<br />
==== Ansatz 1 - Versuchen ====<br />
<br />
Einfach probieren: Bau Dir einen [[SIGNALduino]] für das passende Frequenzband (die 433 oder 868 MHz-Variante des CC1101). Stelle im SIGNALduino-Setting die Frequenz auf die genannte ein (durch den Befehl cc1101_freq = 433.000 oder 868.000) und die Bandbreite auf das Maximum (cc1101_bWidth = 325 kHz bzw. 650 kHz). Jetzt noch das Attribut verbose auf 5 setzen und dann das FHEM-log (tail -f fhem-yyyy-mm.log) beobachten.<br />
<br />
Ist ein Gerät in Reichweite, das regelmäßig etwas sendet (z.B. ein Funkthermometer), sollte hin und wieder etwas empfangen werden. Wenn autocreate aktiv ist, werden auf Basis der erkannten, bekannten Funkprotokolle automatisch neue Devices angelegt (dabei können auch diverse Funkthermometer der Nachbarschaft auftauchen).<br />
<br />
Ist es ein Gerät, das sich über eine Fernbedienung steuern lässt: Eine Taste betätigen und hoffen, dass sich im FHEM-Log etwas tut. Auch hier gilt: Handelt es sich um ein bekanntes Funkprotokoll, wird automatisch ein Device angelegt, allerdings nur eines für die Gerätefamilie. Bei Baumarkt-Funksteckdosen z.B. nur das erste gefundene. Die anderen müsst Ihr manuell anlegen und die entsprechenden Codes zur Identifikation der einzelnen Steckdosen anpassen (schaut z.B. hier [[Intertechno_Code_Berechnung]]) nach. <br />
<br />
Solltet Ihr mit diesem Ansatz Erfolg haben, ist das schon mal gut - Euer Gerät sendet ein bekanntes Protokoll und wird unterstützt.<br />
<br />
Solltet Ihr etwas empfangen (MC, MS, MU), aber keine neuen Devices sehen, wird Euer Gerät möglicherweise noch nicht unterstützt. Jetzt gibt es zwei Varianten<br />
* es handelt sich um ein neues, noch nicht bekanntes Protokoll -> postet einen Log-Ausschnitt auf [https://github.com/RFD-FHEM/RFFHEM/issues github] wie im [[SIGNALduino]]-Wiki vorgeschlagen)<br />
* es handelt sich um etwas proprietäres, altes oder ähnlich kompliziertes (nicht aufgeben, weiterlesen)<br />
<br />
==== Ansatz 2 - Aufschrauben ====<br />
<br />
Fernbedienung aufschrauben, schauen welcher Chip dort verbaut ist.<br />
Endgerät/Device aufschrauben, schauen welcher Chip dort verbaut ist.<br />
<br />
Das Teil ist zu klein? Abfotografieren und das Foto vergößern bis Ihr den Aufdruck lesen könnt.<br />
<br />
Danach folgt dann Google und das Studium der zugehörigen Data Sheets der Chips.<br />
<br />
Das gibt Euch weitere Anhaltspunkte zum Modulationsverfahren, den Frequenzen und Optionen die die Chips unterstützen.<br />
<br />
Wenn die Grundsatzfrage geklärt ist, ergeben sich die ersten Handlungsoptionen<br />
* OOK-Modulation -> [[SIGNALduino]]<br />
* ASK/FSK -> [[Selbstbau_CUL]] oder [[JeeLink]]<br />
<br />
Die Devices senden/empfangen nicht notwendigerweise auf 433 oder 868 MHz, sondern auf Frequenzen "knapp daneben", das kann z.B. bis zu 870 MHz hochgehen. Darüber, welche Frequenz es genau ist, gibt möglicherweise der verbaute Quarz Auskunft. Meist klein, silber mit einer Gravur wie z.B. 6,70 MHz versehen. Mit Hilfe der Spezifikationen im Datenblatt des daneben verbauten Chips lässt sich dann die Sende- bzw. Empfangsfrequenz errechnen.<br />
<br />
==== Ansatz 3 - Messen ====<br />
<br />
Ihr nutzt einen Spektrumanalysator. Es gibt verschiedene preisgünstige Ansätze. <br />
<br />
* Zum einen könnte Ihr den nrfmon-Ansatz verfolgen (siehe [https://jeelabs.net/projects/cafe/wiki/NRfMon_-_nano_Spectrum_Analyzer_with_the_RFM12B hier)]. Tipp: bestellt Euch direkt genug Material um zwei zu bauen, denn die RF12demo kann als Sender und Empfänger genutzt werden. Damit lässt sich direkt verifizieren, dass Euer RFM12B-Device wirklich sendet/empfängt.<br />
* Der andere Ansatz nutzt einen DVB-T-Stick (siehe z.B. [https://homematic-forum.de/forum/viewtopic.php?t=11087 hier]. Es gibt aber viele Google-Treffer unter dem Stichwort [https://www.mikrocontroller.net/topic/243367 SDR].<br />
* Mein persönlicher Favorit ist der [https://github.com/jopohl/urh Universal Radio Hacker]. Mit dem war ich in der Lage mittels RTL-SDR-Stick nicht nur Sequenzen mitzuschneiden sondern auch direkt zu analysieren.<br />
<br />
Wieso überhaupt so kompliziert? OOK nutzt nur eine Frequenz, FSK zwei, vier, je nach Variante. Es kann auch vorkommen (so wie bei mir), dass ein FSK-Device auf einen OOK-Sender anspricht. Der Grund dafür sind Oberwellen die mit dem Ein-/Auschalten der Frequenz einher gehen.<br />
<br />
Die Spektrumanalyse gibt Aufschluss über<br />
* das Modulationsverfahren (OOK vs. FSK) sowie<br />
* die relevante(n) Frequenz(en)<br />
<br />
== SIGNALduino - OOK ==<br />
<br />
Dieses Kapitel geht davon aus, dass ihr einen SIGNALduino für alle weiteren Schritte nutzt.<br />
<br />
==== Log-Meldungen ====<br />
<br />
Der SIGNALduino empfängt die Rohdaten, ermittelt identische Zeitscheiben und ordnet diese den Zahlen 0-7 zu (P0...P7). Ein negativer Zahlenwert bedeutet "kein Empfang" und ein positiver "Signal empfangen". Damit lässt sich der Datenstrom analysieren und für das Senden auch wieder generieren.<br />
<br />
Die folgenden Pulslängen-Zahlen stehen für Mikrosekunden.<br />
<br />
<code>P0=-13020;P1=15916;P2=-398;P3=415;P4=4008;P5=-794;P6=812;D=01232323232323232323232324532653265353532653262653265326 26262626265353532653265326532653535326265353535353265353532653262653265353265353535353535353265326;</code><br />
<br />
Was bedeutet D=012323...?<br />
: 0 -> P0=-13020 => 13.020 Mikrosekunden Pause<br />
: 1 -> P1=15916 => 15.916 Mikrosekunden Signal<br />
: 2 -> P2=-398 => 398 Mikrosekunden Pause<br />
: 3 -> P3=415 => 415 Mikrosekunden Signal<br />
: 2 -> P2=-398 => 398 Mikrosekunden Pause<br />
: 3 -> P3=415 => 415 Mikrosekunden Signal<br />
: ...<br />
<br />
<br />
Tip: um hier schnell zu einem guten Analyse-Ergebnis zu kommen, sind einige verfügbare Beispiel-Zeilen sinnvoll - hier könnte folgendes hilfreich sein:<br />
Bei Geräten, die nicht on-demand (Knopfdruck) Funk-Aktivität generieren können:<br />
Nicht langwierig auf das jeweils nächste verzögerte Intervall der Funk-Aktivität des Geräts warten, sondern stattdessen mehrfach die Geräte-Batterien erneut wieder einsetzen, so dass (hoffentlich) das Gerät immer eine erste Funk-Aktivität sendet, die:<br />
- Log-Zeitstempelmäßig genau erkennbar ist<br />
- hoffentlich immer gleich/ähnlich ist --> gute Analyse-Grundlage<br />
Damit dürfte die Funk-Aktivität hinsichtlich Empfangsstärke, Trägerfrequenz etc. leichter festnagelbar sein.<br />
<br />
==== Frequenz ermitteln ====<br />
<br />
Das folgende Beispiel geht davon aus, dass Ihr im 868 MHz-Band unterwegs seid. Bei 433 MHz könnt Ihr in gleicher Weise vorgehen.<br />
<br />
Fangt damit an, dass Ihr den CC101 mittels set-Command cc1101_freq auf 868.000, cc1101_bWidth auf 650 und cc11=1_sens auf 8 einstellt. Kontrollieren könnt Ihr das durch get ccconf. Die Bandbreite bWidth gibt an wie groß der Empfangsbereich ist. Bei 650 kHz sind das z.B. +/- 325 kHz, also der Bereich von 867.675 bis 868.325 MHz. <br />
<br />
Wenn ihr etwas empfangt ist das ein Ansatzpunkt. Anderfalls könnt Ihr die cc1101_freq in 200 kHz-Schritten (868.200, 868.400 ...) erhöhen und das Frequenzband auf diese Art und Weise absuchen. Ein Hinweis an der Stelle: Im FHEM-Log folgt bei den SIGNALduino-Einträgen nach dem Datenteil D= die Empfangsstärke R=. Damit könnt Ihr feststellen, ob Ihr Euch der Sendefrequenz nähert oder entfernt.<br />
<br />
Wenn Ihr nun Frequenzen gefunden habt bei denen Ihr etwas empfangt, dann könnt Ihr die bWidth jeweils halbieren und den Bereich, in dem etwas empfangen wurde, mit halbierter Frequenz-Schrittweite weiter durchforsten. Das macht Ihr so lange, bis bWidth bei 58 kHz angekommen ist. Damit sollte sich die gesuchte Trägerfrequenz herauskristallisieren.<br />
<br />
==== Selektiver Empfang ====<br />
<br />
Am sichersten geht man selektiv vor - einen Message-Typ nach dem anderen testen. Im SIGNALduino kann man über das set-Command disableMessagetype die Interpretation als MC, MS und MU selektiv ausschalten. Man kann mit MC beginnen und danach beobachten, ob es bei aktivem MS + MU Dekoder jeweils nur eine Art von Nachrichten gibt.<br />
<br />
Sobald man sieht, dass die Meldungen im FHEM-Log wechseln, die Message-Typen MS, MU bzw. MC mit nur einem aktiven Dekoder aufzeichnen.<br />
<br />
Das sollte Anhaltspunkte geben worauf der S'duino am Besten reagiert.<br />
<br />
==== Variationen ====<br />
<br />
Solltet Ihr verschiedene Fernbedienungen für die Produktfamilie besitzen oder so wie ich eine die 8 Rolllädenmotoren bedienen kann, könnt Ihr bei nicht dokumentierten Protokollen trotzdem die Funktion der einzelnen Bytes herausarbeiten.<br />
<br />
Spielt jede Tastenkombination durch, extrahiert die Meldungen aus dem FHEM-Log und legt sie in separaten Dateien ab die ihr z.B. mit Motor, Richtung, Fernbedienung kennzeichnet.<br />
<br />
==== Signal analysieren ====<br />
<br />
Habt Ihr nun den Punkt erreicht an dem Ihr ''reproduzierbar'' (stabil erfasste) Code-Sequenzen im FHEM-Log seht, geht es ans Entschlüsseln. Auch hier wieder der einfache Fall: SIGNALduino kennt den Hersteller bzw. Device-Typ schon und legt automatisch ein FHEM-Device an (da das aber öfter nicht der Fall sein wird, muss man hier weiterarbeiten).<br />
<br />
Wenn ein Signal demoduliert wurde ist man den Bits und Bytes schon einen Schritt näher gekommen.<br />
<br />
Gehen wir wieder von unserem Beispiel aus:<br />
<br />
<code>P0=-13020;P1=15916;P2=-398;P3=415;P4=4008;P5=-794;P6=812;D=01232323232323232323232324532653265353532653262653265326 26262626265353532653265326532653535326265353535353265353532653262653265353265353535353535353265326;</code><br />
<br />
Wie ist diese Sequenz zu interpretieren?<br />
<br />
* Es startet mit einer Pause D='''0'''123232323232<br />
* gefolgt von einem Signal D=0'''1'''23232323232 in der Länge von ca. 16 ms.<br />
* danach folgt ein Sync-Block D=01'''23232323232'''... bei dem jeweils Pärchen von 400 µs Pause/400 µs Signal wiederholt werden.<br />
* Sync- und Datenteil sind durch einen Puls von 4 ms [P4=4008] getrennt D=0123232323232323232323232'''4'''53265<br />
* gefolgt vom Datenteil D=01232323232323232323232324'''53265'''....<br />
<br />
Beim Datenteil wird es etwas komplizierter. Hier sind immer ein kurzer (2 oder 3) und ein langer (5 oder 6) Wert kombiniert. Folglich muss man bei der Interpretation zwischen Vorzeichen und Dauer differenzieren. Ein Pärchen ist immer 1.200 µs lang. In der Mitte dieser Zeitscheibe kann der übertragene Wert folglich eine Pause oder ein Signal sein.<br />
<br />
Beispiel: Den Vorspann<br />
<code>P0=-32001;P1=15874;P2=-364;P3=447;P4=4060;P5=-762;P6=853;D=01232323232323232323232324</code> lassen wir mal außen vor und konzentrieren uns auf die Daten<br />
<br />
<code>53265326535326535326265353262653265353535326265353265326262653265326265353535353532653535353262653265353265353535353535353532626<br />
<br />
lSsLlSsLlSlSsLlSlSsLsLlSlSsLsLlSsLlSlSlSlSsLsLlSlSsLlSsLsLsLlSsLlSsLsLlSlSlSlSlSlSsLlSlSlSlSsLsLlSsLlSlSsLlSlSlSlSlSlSlSlSlSsLsL<br />
<br />
1 0 1 0 1 1 0 1 1 0 0 1 1 0 0 1 0 1 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 0 0 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0<br />
<br />
10101101 10011001 01111001 10100010 10011111 10111100 10110111 11111100<br />
<br />
AD99 79A2 9FBC B7FC</code><br />
<br />
Die Analyse basiert auf folgenden Annahmen (mit Beispiels-Werten)<br />
* Mapping von Puls-Werten auf logische Zustände: wenn 800-ter Pulse: Wert kleiner 0 (z.B. -800) ist ein l (long low), größer 0 ist L (long high), wenn 400-ter Pulse: analog, gemapped auf sS (short low/high) - "sSlL-Notation"...<br />
* Weiter angenommen es werden immer 2 Frequenzen/Zustände verglichen (lS => 1 und sL => 0) (ein Gerät hat ja salopp gesagt nicht mehr zu tun als nur 2 Zustände - 0er und 1er Daten-Bits - robust codiert über Funk zu vermitteln - aus diesen Bits ergibt sich dann zusammengefügt ein gesamtes Geräte-Datenwort, welches anschließend in Bit-Bereiche wie Temperatur, Feuchte, Wind zerlegungs-analysiert werden muss, anhand charakteristischer Werte-Veränderungen, die man idealerweise auch direkt in z.B. einem Sensor-LCD-Display erkennen kann)<br />
<br />
Sollte man mit dem SIGNALduino ein FSK-Signal empfangen/interpretieren, hängt die Bewertung davon ab, ob man die Sendefrequenz+Frequenzhub oder Sendefrequenz-Frequenzhub empfängt. Die Bedeutung von 0/1 wird dann negiert.<br />
<br />
Weitere wichtige Tips:<br />
* es ist wohl sinnvoll, zu versuchen, sich evt. an einem längsten Puls (das ist nämlich evt. eine Sync-Pause) zu orientieren, um nachfolgende Bereiche evt. als startendes Datenpaket identifizieren zu können<br />
* man sollte die Pulsfolge per Textsuche analysieren, in einem Editor/Reader, der Such-Texte in einer Zeile '''mehrfach''' farbig markieren kann (less, ...) - bei markiertem Suchtreffer kann man dann Teil-Folgen identifizieren, welche sich deterministisch ''wiederholen'' - diese sind dann wohl offensichtlich codierte Bit-Daten, welche es passend zu entschlüsseln gilt<br />
* die identifizierten Merkmale sind dann als ein neues Protokoll (falls kein bereits existierendes Protokoll zu unpräzise formuliert sein sollte!) in FHEM/lib/signalduino_protocols.hash hinzuzufügen (Angabe präziser Durchschnittswerte von Basis-Takt, Gesamt-Patternlänge, Puls-Pause-Verhältnisse: in [x,-y]-Format, ...), und dann muss ein "reload 00_SIGNALduino" gemacht werden, um dies zu testen (hier: beim sduino-Device temporär(!) Attribute verbose 5 und debug 1 setzen!)<br />
<br />
==== Steuern ====<br />
<br />
Die empfangenen, im Log ausgewiesenen Sequenzen könnt Ihr als Basis für das Senden verwenden. Relevant sind dabei Puls-Beschreibungen P0...P7 sowie D (Data). Die RSSI-Empfangsstärke wird beim Empfang als R= ausgewiesen. Beim Senden steht R jedoch für die Anzahl der Wiederholungen. Entnehmt die Details und Möglichkeiten bitte der Dokumentation [https://github.com/RFD-FHEM/SIGNALDuino/wiki/Commands Commands].<br />
<br />
== CUL - FSK und Co. ==<br />
<br />
Dieses Kapitel geht davon aus, dass ihr einen CUL für alle weiteren Schritte nutzt. <br />
<br />
Es befindet sich aber noch im Aufbau....<br />
<br />
== FAQ ==<br />
<br />
=== Woran genau wird erkannt ob ein Signal ShortHigh, bzw ShortLow ist? ===<br />
<br />
Diese Begriffe kommen nur bei der Manchester Codierung zum Einsatz.<br />
<br />
Die Bestimmung short High / Low erfolgt einfach dadurch ob gesendet wird oder ob gerade eine Pause eingelegt wird.<br />
<br />
Short und Long wird einfach durch die Kalkulation der Dauer ermittelt.<br />
<br />
Die Dauer eines short Intervalles ist in der Regel halb so lang wie die von einem long und entspricht der Taktrate.<br />
Bei der ganzen Berechnung müssen natürlich Toleranzen berücksichtigt werden.<br />
<br />
Beispiel einer empfangenen Sequenz<br />
<br />
<code>P0=-32001;P1=15874;P2=-364;P3=447;P4=4060;P5=-762;P6=853;D=01232323232323232323232324</code><br />
<br />
P0, P2 + P5 haben ein negatives Vorzeichen. Damit ist gemeint, dass für eine Zeit von 762µs (P5) kein Signal empfangen wurde (Low). Die positiven sind dann High.<br />
<br />
Generell sind die absoluten, gemessenen low-Werte bei Signalduino kürzer als die high-Werte.<br />
<br />
Wie bereits ausgeführt, werden für die Daten die Pulse P2, P3, P5 und P6 genutzt. Der Mittelwert [ (P2 + P3 + P5 + P6) / 6 ] der absoluten Werte ergibt 404µs für ein Short und 808µs ein Long (2xShort). Idealisiert werden 400µs angenommen.<br />
<br />
Das Umwandeln der Pulse in den Daten in eine "sSlL-Notation" vereinfacht die Erkennung von Mustern (in mehreren Nachrichten variieren auch die Pulse).<br />
Dass ein lS=1 und sL=0 entspricht, ist nur eine willkürlich angenommene Arbeitshypothese, die bis dato ganz gute Ergebnisse produziert hat.<br />
<br />
== Links ==<br />
<br />
* [https://www.hamspirit.de/2286/signalanalyse-fuer-dummies/ Signalanalyse für Dummies]<br />
* [https://github.com/jopohl/urh Universal Radio Hacker]<br />
* [https://www.elttam.com.au/blog/intro-sdr-and-rf-analysis/ Intro SDR and RF Analysis]<br />
* [https://www.sigidwiki.com/wiki/Signal_Identification_Guide Signal Identification Guide]<br />
* [https://www.rtl-sdr.com/tag/fsk/ Unknown Signal Reverse Engineering and Decoding AFSK Signals Tutorial]<br />
* [[Intertechno Code Berechnung]]<br />
* [[Funksignalanalyse mit DVB-T Stick]]<br />
<br />
[[Kategorie:Intertechno]]<br />
[[Kategorie:HOWTOS]]<br />
[[Kategorie:433MHz]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Unbekannte_Funkprotokolle&diff=28248Unbekannte Funkprotokolle2018-11-06T13:31:45Z<p>Hauswart: /* Log-Meldungen */</p>
<hr />
<div>Es gibt jede Menge offiziell in FHEM unterstützte Devices und Funkprotokolle. Solange das Device Ross und Reiter benennt (Homematic, Z-Wave, Intertechno etc.) ist es einfach dieses in FHEM einzubinden. Was aber, wenn selbst mit hinreichend gut aktualisierter Installation nichts erkannt wird und es ein No-Name Produkt ist bei dem man nur die Hoffnung hat, dass es im Innern etwas Bekanntes beherbergt?<br />
<br />
Dieser Wiki-Artikel soll jenen helfen, die Geräte mit einem unbekannten Funkprotokoll an FHEM anbinden bzw. mit FHEM steuern wollen.<br />
<br />
== Basics ==<br />
<br />
==== Hardware ====<br />
<br />
Neben den bekannten Hardware-Dongles gibt es Selbstbaulösungen in Form eines SIGNALduino, CUL oder JeeLink. <br />
<br />
Diese unterscheiden sich in verschiedener Hinsicht:<br />
* Sendemodul (SIGNALduino/CUL -> CC1101; JeeLink -> RF12B) [https://de.wikipedia.org/wiki/Amplitudenumtastung]<br />
* Modulationsverfahren (OOK, ASK/FSK)<br />
* Frequenzband (433 MHz, 868 MHz)<br />
<br />
==== Frequenzbereich ====<br />
Für die funkbasierte Heimautomation kommen im Wesentlichen zwei Frequenzbänder in Frage: 433 und 868 MHz. Die meisten Geräte haben auf der Rückseite ein Typenschild, auf dem das Frequenzband ausgewiesen ist.<br />
<br />
Dann gibt es noch 2,4 GHz und 5 GHz (WLAN, Bluetooth...), dieses Frequenzband wird in diesem Artikel aber nicht betrachtet.<br />
<br />
==== Modulationsverfahren ====<br />
<br />
So, wie vom Rundfunk (AM/FM) her bekannt, kennt man auch bei 433/868 MHz verschiedene Modulationsverfahren. <br />
<br />
* [https://de.wikipedia.org/wiki/Amplitudenumtastung OOK/ASK/Amplitudenabtastung]<br />
: Das Signal des Senders wir auf der angegebenen Frequenz ein-/ausgeschaltet um die Dateninformationen zu übermitteln. <br />
* [https://de.wikipedia.org/wiki/Frequenzumtastung FSK/Frequenzumtastung]<br />
: Der Sender überträgt den Datenstrom indem, ausgehend von der Trägerfrequenz, zwischen Frequenzen (z.B. Frequenz-Frequenzhub, Frequenz+Frequenzhub) hin- und hergeschaltet wird. Dieses Verfahren kennt verschiedene Ausprägungen: 2-FSK, 4-FSK, GFSK (Details siehe [http://www.rfwireless-world.com/Terminology/2FSK-modulation-vs-4FSK-modulation.html hier]).<br />
<br />
==== Encoding oder auch Leitungscode ====<br />
<br />
Die Art und Weise wie dieses Signal interpretiert wird hängt wiederum vom Encoding ab. Dazu sei auf die nachfolgenden Quellen verwiesen.<br />
<br />
* [https://de.wikipedia.org/wiki/Leitungscode Leitungscode (Einstieg)]<br />
* [https://de.wikipedia.org/wiki/Non_Return_to_Zero NRZ]<br />
* [https://de.wikipedia.org/wiki/Manchester-Code Manchester]<br />
<br />
Je nach verwendetem Encoding wird ggf. mehr als 1 Übertragungs-Bit für ein Datenbit benötigt. Der Empfänger erwartet z.B. einen Bitwechsel zu einem bestimmten Zeitpunkt. Eine Abfolge <br />
* 100 (short high, long low) wird als 0<br />
* 110 (long high, short low) wird als 1<br />
interpretiert.<br />
<br />
Im FHEM-Forum gibt es viele freundliche Helfer die Euch bei Bedarf den richtigen Weg weisen.<br />
<br />
==== Signalstruktur ====<br />
<br />
Ein typischer Aufbau einer Signalstruktur sieht z.B. so aus<br />
<br />
| Pause | Sync | Pause | Daten |<br />
<br />
* eine größere Pause zur Trennung der Sequenzen <br />
* ein Sync-Block mit dem sich der Empfänger auf den Sender einstellt<br />
* eine Pause um Sync und Daten zu trennen<br />
* die eigentlichen, zu übertragenden Daten.<br />
<br />
Es müssen nicht immer alle Bestandteile in der übertragenen Signalstruktur vorkommen (Details siehe auch [https://de.wikipedia.org/wiki/Datenpr%C3%A4ambel Datenpräambel] oder auch [https://en.wikipedia.org/wiki/Syncword Syncword]).<br />
<br />
Die Sequenz wird ggf. mehrfach wiederholt <br />
<br />
| Pause | Sync | Pause | Daten | Pause | Sync | Pause | Daten | Pause | Sync | Pause | Daten | ...<br />
<br />
==== Protokoll ====<br />
<br />
Das ist der herstellerspezifische Teil des Signalstroms - die Daten. Hersteller haben i.d.R. ihre eigene Definition der übertragenen Datenströme. Teils werden feste Code-Sequenzen übertragen, es gibt aber auch rollierende Codes (Engl.: Rolling Codes) bei denen sich die Daten bei jeder Übertragung ändern. <br />
<br />
Mit etwas Glück erkennt z.B. SIGNALduino das Protokoll, damit den Hersteller und legt automatisch ein passendes Device in FHEM an. Manchmal gibt es auch Fehlinterpretationen und das vermeintlich bekannte Device entpuppt sich als etwas anderes (Statement aus dem Forum "Lösung war, wo Dooya drauf steht muss nicht immer Dooya drin stecken.").<br />
<br />
== Wie fange ich an? ==<br />
<br />
==== Recherche ====<br />
<br />
Sucht im Internet nach Informationen zu dem fraglichen Device. Zu bekannten Devices sollten sich Informationen finden lassen, die einem weiter helfen. Solltet Ihr fündig werden, verfolgt die Hinweise, wie diese Devices in FHEM eingebunden werden können.<br />
<br />
Wenn sich nichts Verwertbares finden lässt, geht's mit dem nächsten Abschnitt weiter.<br />
<br />
==== Ansatz 1 - Versuchen ====<br />
<br />
Einfach probieren: Bau Dir einen [[SIGNALduino]] für das passende Frequenzband (die 433 oder 868 MHz-Variante des CC1101). Stelle im SIGNALduino-Setting die Frequenz auf die genannte ein (durch den Befehl cc1101_freq = 433.000 oder 868.000) und die Bandbreite auf das Maximum (cc1101_bWidth = 325 kHz bzw. 650 kHz). Jetzt noch das Attribut verbose auf 5 setzen und dann das FHEM-log (tail -f fhem-yyyy-mm.log) beobachten.<br />
<br />
Ist ein Gerät in Reichweite, das regelmäßig etwas sendet (z.B. ein Funkthermometer), sollte hin und wieder etwas empfangen werden. Wenn autocreate aktiv ist, werden auf Basis der erkannten, bekannten Funkprotokolle automatisch neue Devices angelegt (dabei können auch diverse Funkthermometer der Nachbarschaft auftauchen).<br />
<br />
Ist es ein Gerät, das sich über eine Fernbedienung steuern lässt: Eine Taste betätigen und hoffen, dass sich im FHEM-Log etwas tut. Auch hier gilt: Handelt es sich um ein bekanntes Funkprotokoll, wird automatisch ein Device angelegt, allerdings nur eines für die Gerätefamilie. Bei Baumarkt-Funksteckdosen z.B. nur das erste gefundene. Die anderen müsst Ihr manuell anlegen und die entsprechenden Codes zur Identifikation der einzelnen Steckdosen anpassen (schaut z.B. hier [[Intertechno_Code_Berechnung]]) nach. <br />
<br />
Solltet Ihr mit diesem Ansatz Erfolg haben, ist das schon mal gut - Euer Gerät sendet ein bekanntes Protokoll und wird unterstützt.<br />
<br />
Solltet Ihr etwas empfangen (MC, MS, MU), aber keine neuen Devices sehen, wird Euer Gerät möglicherweise noch nicht unterstützt. Jetzt gibt es zwei Varianten<br />
* es handelt sich um ein neues, noch nicht bekanntes Protokoll -> postet einen Log-Ausschnitt auf [https://github.com/RFD-FHEM/RFFHEM/issues github] wie im [[SIGNALduino]]-Wiki vorgeschlagen)<br />
* es handelt sich um etwas proprietäres, altes oder ähnlich kompliziertes (nicht aufgeben, weiterlesen)<br />
<br />
==== Ansatz 2 - Aufschrauben ====<br />
<br />
Fernbedienung aufschrauben, schauen welcher Chip dort verbaut ist.<br />
Endgerät/Device aufschrauben, schauen welcher Chip dort verbaut ist.<br />
<br />
Das Teil ist zu klein? Abfotografieren und das Foto vergößern bis Ihr den Aufdruck lesen könnt.<br />
<br />
Danach folgt dann Google und das Studium der zugehörigen Data Sheets der Chips.<br />
<br />
Das gibt Euch weitere Anhaltspunkte zum Modulationsverfahren, den Frequenzen und Optionen die die Chips unterstützen.<br />
<br />
Wenn die Grundsatzfrage geklärt ist, ergeben sich die ersten Handlungsoptionen<br />
* OOK-Modulation -> [[SIGNALduino]]<br />
* ASK/FSK -> [[Selbstbau_CUL]] oder [[JeeLink]]<br />
<br />
Die Devices senden/empfangen nicht notwendigerweise auf 433 oder 868 MHz, sondern auf Frequenzen "knapp daneben", das kann z.B. bis zu 870 MHz hochgehen. Darüber, welche Frequenz es genau ist, gibt möglicherweise der verbaute Quarz Auskunft. Meist klein, silber mit einer Gravur wie z.B. 6,70 MHz versehen. Mit Hilfe der Spezifikationen im Datenblatt des daneben verbauten Chips lässt sich dann die Sende- bzw. Empfangsfrequenz errechnen.<br />
<br />
==== Ansatz 3 - Messen ====<br />
<br />
Ihr nutzt einen Spektrumanalysator. Es gibt verschiedene preisgünstige Ansätze. <br />
<br />
* Zum einen könnte Ihr den nrfmon-Ansatz verfolgen (siehe [https://jeelabs.net/projects/cafe/wiki/NRfMon_-_nano_Spectrum_Analyzer_with_the_RFM12B hier)]. Tipp: bestellt Euch direkt genug Material um zwei zu bauen, denn die RF12demo kann als Sender und Empfänger genutzt werden. Damit lässt sich direkt verifizieren, dass Euer RFM12B-Device wirklich sendet/empfängt.<br />
* Der andere Ansatz nutzt einen DVB-T-Stick (siehe z.B. [https://homematic-forum.de/forum/viewtopic.php?t=11087 hier]. Es gibt aber viele Google-Treffer unter dem Stichwort [https://www.mikrocontroller.net/topic/243367 SDR].<br />
* Mein persönlicher Favorit ist der [https://github.com/jopohl/urh Universal Radio Hacker]. Mit dem war ich in der Lage mittels RTL-SDR-Stick nicht nur Sequenzen mitzuschneiden sondern auch direkt zu analysieren.<br />
<br />
Wieso überhaupt so kompliziert? OOK nutzt nur eine Frequenz, FSK zwei, vier, je nach Variante. Es kann auch vorkommen (so wie bei mir), dass ein FSK-Device auf einen OOK-Sender anspricht. Der Grund dafür sind Oberwellen die mit dem Ein-/Auschalten der Frequenz einher gehen.<br />
<br />
Die Spektrumanalyse gibt Aufschluss über<br />
* das Modulationsverfahren (OOK vs. FSK) sowie<br />
* die relevante(n) Frequenz(en)<br />
<br />
== SIGNALduino - OOK ==<br />
<br />
Dieses Kapitel geht davon aus, dass ihr einen SIGNALduino für alle weiteren Schritte nutzt.<br />
<br />
==== Log-Meldungen ====<br />
<br />
Der SIGNALduino empfängt die Rohdaten, ermittelt identische Zeitscheiben und ordnet diese den Zahlen 0-7 zu (P0...P7). Ein negativer Zahlenwert bedeutet "kein Empfang" und ein positiver "Signal empfangen". Damit lässt sich der Datenstrom analysieren und für das Senden auch wieder generieren.<br />
<br />
Die folgenden Pulslängen-Zahlen stehen für Mikrosekunden.<br />
<br />
<code>P0=-13020;P1=15916;P2=-398;P3=415;P4=4008;P5=-794;P6=812;D=01232323232323232323232324532653265353532653262653265326 26262626265353532653265326532653535326265353535353265353532653262653265353265353535353535353265326;</code><br />
<br />
Was bedeutet D=012323...?<br />
: 0 -> P0=-13020 => 13.020 Mikrosekunden Pause<br />
: 1 -> P1=15916 => 15.916 Mikrosekunden Signal<br />
: 2 -> P2=-398 => 398 Mikrosekunden Pause<br />
: 3 -> P3=415 => 415 Mikrosekunden Signal<br />
: 2 -> P4=-398 => 398 Mikrosekunden Pause<br />
: 3 -> P5=415 => 415 Mikrosekunden Signal<br />
: ...<br />
<br />
<br />
Tip: um hier schnell zu einem guten Analyse-Ergebnis zu kommen, sind einige verfügbare Beispiel-Zeilen sinnvoll - hier könnte folgendes hilfreich sein:<br />
Bei Geräten, die nicht on-demand (Knopfdruck) Funk-Aktivität generieren können:<br />
Nicht langwierig auf das jeweils nächste verzögerte Intervall der Funk-Aktivität des Geräts warten, sondern stattdessen mehrfach die Geräte-Batterien erneut wieder einsetzen, so dass (hoffentlich) das Gerät immer eine erste Funk-Aktivität sendet, die:<br />
- Log-Zeitstempelmäßig genau erkennbar ist<br />
- hoffentlich immer gleich/ähnlich ist --> gute Analyse-Grundlage<br />
Damit dürfte die Funk-Aktivität hinsichtlich Empfangsstärke, Trägerfrequenz etc. leichter festnagelbar sein.<br />
<br />
==== Frequenz ermitteln ====<br />
<br />
Das folgende Beispiel geht davon aus, dass Ihr im 868 MHz-Band unterwegs seid. Bei 433 MHz könnt Ihr in gleicher Weise vorgehen.<br />
<br />
Fangt damit an, dass Ihr den CC101 mittels set-Command cc1101_freq auf 868.000, cc1101_bWidth auf 650 und cc11=1_sens auf 8 einstellt. Kontrollieren könnt Ihr das durch get ccconf. Die Bandbreite bWidth gibt an wie groß der Empfangsbereich ist. Bei 650 kHz sind das z.B. +/- 325 kHz, also der Bereich von 867.675 bis 868.325 MHz. <br />
<br />
Wenn ihr etwas empfangt ist das ein Ansatzpunkt. Anderfalls könnt Ihr die cc1101_freq in 200 kHz-Schritten (868.200, 868.400 ...) erhöhen und das Frequenzband auf diese Art und Weise absuchen. Ein Hinweis an der Stelle: Im FHEM-Log folgt bei den SIGNALduino-Einträgen nach dem Datenteil D= die Empfangsstärke R=. Damit könnt Ihr feststellen, ob Ihr Euch der Sendefrequenz nähert oder entfernt.<br />
<br />
Wenn Ihr nun Frequenzen gefunden habt bei denen Ihr etwas empfangt, dann könnt Ihr die bWidth jeweils halbieren und den Bereich, in dem etwas empfangen wurde, mit halbierter Frequenz-Schrittweite weiter durchforsten. Das macht Ihr so lange, bis bWidth bei 58 kHz angekommen ist. Damit sollte sich die gesuchte Trägerfrequenz herauskristallisieren.<br />
<br />
==== Selektiver Empfang ====<br />
<br />
Am sichersten geht man selektiv vor - einen Message-Typ nach dem anderen testen. Im SIGNALduino kann man über das set-Command disableMessagetype die Interpretation als MC, MS und MU selektiv ausschalten. Man kann mit MC beginnen und danach beobachten, ob es bei aktivem MS + MU Dekoder jeweils nur eine Art von Nachrichten gibt.<br />
<br />
Sobald man sieht, dass die Meldungen im FHEM-Log wechseln, die Message-Typen MS, MU bzw. MC mit nur einem aktiven Dekoder aufzeichnen.<br />
<br />
Das sollte Anhaltspunkte geben worauf der S'duino am Besten reagiert.<br />
<br />
==== Variationen ====<br />
<br />
Solltet Ihr verschiedene Fernbedienungen für die Produktfamilie besitzen oder so wie ich eine die 8 Rolllädenmotoren bedienen kann, könnt Ihr bei nicht dokumentierten Protokollen trotzdem die Funktion der einzelnen Bytes herausarbeiten.<br />
<br />
Spielt jede Tastenkombination durch, extrahiert die Meldungen aus dem FHEM-Log und legt sie in separaten Dateien ab die ihr z.B. mit Motor, Richtung, Fernbedienung kennzeichnet.<br />
<br />
==== Signal analysieren ====<br />
<br />
Habt Ihr nun den Punkt erreicht an dem Ihr ''reproduzierbar'' (stabil erfasste) Code-Sequenzen im FHEM-Log seht, geht es ans Entschlüsseln. Auch hier wieder der einfache Fall: SIGNALduino kennt den Hersteller bzw. Device-Typ schon und legt automatisch ein FHEM-Device an (da das aber öfter nicht der Fall sein wird, muss man hier weiterarbeiten).<br />
<br />
Wenn ein Signal demoduliert wurde ist man den Bits und Bytes schon einen Schritt näher gekommen.<br />
<br />
Gehen wir wieder von unserem Beispiel aus:<br />
<br />
<code>P0=-13020;P1=15916;P2=-398;P3=415;P4=4008;P5=-794;P6=812;D=01232323232323232323232324532653265353532653262653265326 26262626265353532653265326532653535326265353535353265353532653262653265353265353535353535353265326;</code><br />
<br />
Wie ist diese Sequenz zu interpretieren?<br />
<br />
* Es startet mit einer Pause D='''0'''123232323232<br />
* gefolgt von einem Signal D=0'''1'''23232323232 in der Länge von ca. 16 ms.<br />
* danach folgt ein Sync-Block D=01'''23232323232'''... bei dem jeweils Pärchen von 400 µs Pause/400 µs Signal wiederholt werden.<br />
* Sync- und Datenteil sind durch einen Puls von 4 ms [P4=4008] getrennt D=0123232323232323232323232'''4'''53265<br />
* gefolgt vom Datenteil D=01232323232323232323232324'''53265'''....<br />
<br />
Beim Datenteil wird es etwas komplizierter. Hier sind immer ein kurzer (2 oder 3) und ein langer (5 oder 6) Wert kombiniert. Folglich muss man bei der Interpretation zwischen Vorzeichen und Dauer differenzieren. Ein Pärchen ist immer 1.200 µs lang. In der Mitte dieser Zeitscheibe kann der übertragene Wert folglich eine Pause oder ein Signal sein.<br />
<br />
Beispiel: Den Vorspann<br />
<code>P0=-32001;P1=15874;P2=-364;P3=447;P4=4060;P5=-762;P6=853;D=01232323232323232323232324</code> lassen wir mal außen vor und konzentrieren uns auf die Daten<br />
<br />
<code>53265326535326535326265353262653265353535326265353265326262653265326265353535353532653535353262653265353265353535353535353532626<br />
<br />
lSsLlSsLlSlSsLlSlSsLsLlSlSsLsLlSsLlSlSlSlSsLsLlSlSsLlSsLsLsLlSsLlSsLsLlSlSlSlSlSlSsLlSlSlSlSsLsLlSsLlSlSsLlSlSlSlSlSlSlSlSlSsLsL<br />
<br />
1 0 1 0 1 1 0 1 1 0 0 1 1 0 0 1 0 1 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 0 0 1 1 1 1 1 1 0 1 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 0<br />
<br />
10101101 10011001 01111001 10100010 10011111 10111100 10110111 11111100<br />
<br />
AD99 79A2 9FBC B7FC</code><br />
<br />
Die Analyse basiert auf folgenden Annahmen (mit Beispiels-Werten)<br />
* Mapping von Puls-Werten auf logische Zustände: wenn 800-ter Pulse: Wert kleiner 0 (z.B. -800) ist ein l (long low), größer 0 ist L (long high), wenn 400-ter Pulse: analog, gemapped auf sS (short low/high) - "sSlL-Notation"...<br />
* Weiter angenommen es werden immer 2 Frequenzen/Zustände verglichen (lS => 1 und sL => 0) (ein Gerät hat ja salopp gesagt nicht mehr zu tun als nur 2 Zustände - 0er und 1er Daten-Bits - robust codiert über Funk zu vermitteln - aus diesen Bits ergibt sich dann zusammengefügt ein gesamtes Geräte-Datenwort, welches anschließend in Bit-Bereiche wie Temperatur, Feuchte, Wind zerlegungs-analysiert werden muss, anhand charakteristischer Werte-Veränderungen, die man idealerweise auch direkt in z.B. einem Sensor-LCD-Display erkennen kann)<br />
<br />
Sollte man mit dem SIGNALduino ein FSK-Signal empfangen/interpretieren, hängt die Bewertung davon ab, ob man die Sendefrequenz+Frequenzhub oder Sendefrequenz-Frequenzhub empfängt. Die Bedeutung von 0/1 wird dann negiert.<br />
<br />
Weitere wichtige Tips:<br />
* es ist wohl sinnvoll, zu versuchen, sich evt. an einem längsten Puls (das ist nämlich evt. eine Sync-Pause) zu orientieren, um nachfolgende Bereiche evt. als startendes Datenpaket identifizieren zu können<br />
* man sollte die Pulsfolge per Textsuche analysieren, in einem Editor/Reader, der Such-Texte in einer Zeile '''mehrfach''' farbig markieren kann (less, ...) - bei markiertem Suchtreffer kann man dann Teil-Folgen identifizieren, welche sich deterministisch ''wiederholen'' - diese sind dann wohl offensichtlich codierte Bit-Daten, welche es passend zu entschlüsseln gilt<br />
* die identifizierten Merkmale sind dann als ein neues Protokoll (falls kein bereits existierendes Protokoll zu unpräzise formuliert sein sollte!) in FHEM/lib/signalduino_protocols.hash hinzuzufügen (Angabe präziser Durchschnittswerte von Basis-Takt, Gesamt-Patternlänge, Puls-Pause-Verhältnisse: in [x,-y]-Format, ...), und dann muss ein "reload 00_SIGNALduino" gemacht werden, um dies zu testen (hier: beim sduino-Device temporär(!) Attribute verbose 5 und debug 1 setzen!)<br />
<br />
==== Steuern ====<br />
<br />
Die empfangenen, im Log ausgewiesenen Sequenzen könnt Ihr als Basis für das Senden verwenden. Relevant sind dabei Puls-Beschreibungen P0...P7 sowie D (Data). Die RSSI-Empfangsstärke wird beim Empfang als R= ausgewiesen. Beim Senden steht R jedoch für die Anzahl der Wiederholungen. Entnehmt die Details und Möglichkeiten bitte der Dokumentation [https://github.com/RFD-FHEM/SIGNALDuino/wiki/Commands Commands].<br />
<br />
== CUL - FSK und Co. ==<br />
<br />
Dieses Kapitel geht davon aus, dass ihr einen CUL für alle weiteren Schritte nutzt. <br />
<br />
Es befindet sich aber noch im Aufbau....<br />
<br />
== FAQ ==<br />
<br />
=== Woran genau wird erkannt ob ein Signal ShortHigh, bzw ShortLow ist? ===<br />
<br />
Diese Begriffe kommen nur bei der Manchester Codierung zum Einsatz.<br />
<br />
Die Bestimmung short High / Low erfolgt einfach dadurch ob gesendet wird oder ob gerade eine Pause eingelegt wird.<br />
<br />
Short und Long wird einfach durch die Kalkulation der Dauer ermittelt.<br />
<br />
Die Dauer eines short Intervalles ist in der Regel halb so lang wie die von einem long und entspricht der Taktrate.<br />
Bei der ganzen Berechnung müssen natürlich Toleranzen berücksichtigt werden.<br />
<br />
Beispiel einer empfangenen Sequenz<br />
<br />
<code>P0=-32001;P1=15874;P2=-364;P3=447;P4=4060;P5=-762;P6=853;D=01232323232323232323232324</code><br />
<br />
P0, P2 + P5 haben ein negatives Vorzeichen. Damit ist gemeint, dass für eine Zeit von 762µs (P5) kein Signal empfangen wurde (Low). Die positiven sind dann High.<br />
<br />
Generell sind die absoluten, gemessenen low-Werte bei Signalduino kürzer als die high-Werte.<br />
<br />
Wie bereits ausgeführt, werden für die Daten die Pulse P2, P3, P5 und P6 genutzt. Der Mittelwert [ (P2 + P3 + P5 + P6) / 6 ] der absoluten Werte ergibt 404µs für ein Short und 808µs ein Long (2xShort). Idealisiert werden 400µs angenommen.<br />
<br />
Das Umwandeln der Pulse in den Daten in eine "sSlL-Notation" vereinfacht die Erkennung von Mustern (in mehreren Nachrichten variieren auch die Pulse).<br />
Dass ein lS=1 und sL=0 entspricht, ist nur eine willkürlich angenommene Arbeitshypothese, die bis dato ganz gute Ergebnisse produziert hat.<br />
<br />
== Links ==<br />
<br />
* [https://www.hamspirit.de/2286/signalanalyse-fuer-dummies/ Signalanalyse für Dummies]<br />
* [https://github.com/jopohl/urh Universal Radio Hacker]<br />
* [https://www.elttam.com.au/blog/intro-sdr-and-rf-analysis/ Intro SDR and RF Analysis]<br />
* [https://www.sigidwiki.com/wiki/Signal_Identification_Guide Signal Identification Guide]<br />
* [https://www.rtl-sdr.com/tag/fsk/ Unknown Signal Reverse Engineering and Decoding AFSK Signals Tutorial]<br />
* [[Intertechno Code Berechnung]]<br />
* [[Funksignalanalyse mit DVB-T Stick]]<br />
<br />
[[Kategorie:Intertechno]]<br />
[[Kategorie:HOWTOS]]<br />
[[Kategorie:433MHz]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=DBPlan&diff=28108DBPlan2018-10-16T07:41:20Z<p>Hauswart: </p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Abfahrtszeiten Deutsche Bahn<br />
|ModType=x<br />
|ModFTopic=36057<br />
|ModForumArea=Unterstützende Dienste<br />
|ModTechName=98_DBPlan.pm<br />
|ModOwner=JoWiemann ({{Link2FU|94|Forum}})<br />
}}<br />
<br />
Das Modul holt von der Infoseite der DB aktuelle Informationen zu einer angegeben Verbindung. Weitere Information zur API können im Dokument [[media:Parametrisierte_%C3%9Cbergabe_Bahnauskunft(V_5.12-R4.30c,_f%C3%BCr.pdf|Internet-Reiseauskunft der<br />
Deutschen Bahn AG]] nachgelesen werden. Das Dokument stammt von folgender Quelle: http://www.geiervally.lechtal.at/sixcms/media.php/1405/Parametrisierte%20%DCbergabe%20Bahnauskunft(V%205.12-R4.30c,%20f%FCr.pdf.<br />
<br />
== Einbinden in FHEM ==<br />
<br />
Zunächst muss, sofern noch nicht geschehen das Perl Modul HTML:Table Extract installiert werden. Hierzu bitte folgende Befehle in die Terminalsession eingeben:<br />
<br />
<pre>sudo apt-get update</pre><br />
<pre>sudo apt-get install libhtml-tableextract-perl</pre><br />
<br />
Nun muss noch das FHEM-Modul installiert werden. (Das DBPlan-Modul wird noch nicht über das FHEM [[update]] verteilt.)<br />
<br />
Dies kann über GitHub und den update Befehl in FHEM geschehen. Dazu folgenden Befehl in der FHEM Kommandozeile ausführen:<br><br />
<pre>update all https://raw.githubusercontent.com/jowiemann/DBPlan-for-Fhem/master/controls_dbplan.txt</pre><br />
<br />
oder mit<br />
<pre>update add https://raw.githubusercontent.com/jowiemann/DBPlan-for-Fhem/master/controls_dbplan.txt</pre><br />
der FHEM Updatesteuerung hinzufügen. Ab diesem Zeitpunkt wird DBPlan im Update berücksichtigt.<br />
<br />
Anschließend FHEM neu starten.<br />
<br />
Nun sollte sich mit folgendem Befehl das Modul nutzen lassen.<br />
<br />
:<code>define <Name> DBPlan <Interval for refresh in seconds> [time offset in minutes]</code><br />
<br />
Weitere Information können über Eingabe von:<br />
<pre>? DBPlan</pre><br />
in der FHEM Kommandozeile abgerufen werden und befinden sich im entsprechenden Thread ({{Link2Forum|Topic=36057|LinkText=DBPlan}}) im Forum.<br />
<br />
== Attribute ==<br />
*dbplan_station-> Abfahrtsbahnhof / Haltestelle<br />
*dbplan_destination -> Ankunftsbahnhof / Haltestelle<br />
*dbplan_via_1 -> 1. Zwischenhalt in Bahnhof / Haltestelle<br />
*dbplan_via_2 -> 2. Zwischenhalt in Bahnhof / Haltestelle<br />
*dbplan_journey_prod -> Verkehrsmittel, wie z.B.: ICE, Bus, Straßenbahn<br />
*dbplan_journey_opt -> Reiseoptionen wie z.B.: direct connection<br />
*dbplan_tariff_class -> 1. oder 2. Klasse<br />
*dbplan_board_type -> Fahrplansuche bzw. Bahnhofsanzeige für Abfahrts- oder Ankunftszeit<br />
*dbplan_delayed_Journey -> Bei off werden nur pünktliche Verbindungen angezeigt<br />
*dbplan_max_Journeys -> Anzahl der angezeigten Zugverbindungen in der Bahnhofsansicht.<br />
*dbplan_reg_train -> die Zugbezeichnung, z.B. S für alles was S- und Straßenbahnen angeht, ICE alle ICE oder ICE mit Zugnummer. Usw.<br />
*dbplan_travel_date -> Reisedatum in der Angabe: dd.mm.yy<br />
*dbplan_travel_time -> Abfahtrtszeit in der Angabe: hh.mm<br />
*dbplan_addon_options -> weitere Optionen, wie sie im API-Dokument der DB beschrieben sind<br />
<br />
Steuernde Attribute:<br />
*dbplan-disable -> Device aktivieren / deaktivieren (s. auch FHEM-Doku)<br />
*dbplan-default-char -> Hinweis, der angezeigt wird, wenn keine Information für ein reading zur Verfügung steht.<br />
**"none" ist der Standardhinweis. <br />
**"delete" nicht genutzte readings werden auch nicht angezeigt.<br />
**"nochar" das Reading wird mit leerem Inhalt angezeigt.<br />
*dbplan-tabel-headers -> internes Attribut um die Spaltenbezeichnungen für HTML::TableExtract<br />
*dbplan-station-file -> Pfad zur Bahnhofstabelle (/opt/fhem/FHEM/deutschland_bhf.csv). Die Tabelle ist im csv Format abgelegt<br />
*dbplan-base-type -> Anzeige als Bahnhofstabelle (table) oder Verbindungsinformation (plan)<br />
<br />
HTTPMOD Attribute, siehe entsprechende Doku<br />
*dbplan-remote-timeout<br />
*dbplan-remote-noshutdown<br />
*dbplan-remote-loglevel<br />
<br />
Bitte die Attribute nur über die FHEM Oberfläche setzen. Es können für dbplan_journey_prod und dbplan_journey_opt mehrere Einträge aus den jeweiligen Listen kombiniert werden. Für Abfahrs- und Ankunftsort bitte vorher prüfen, ob diese Orte von www.bahn.de erkannt werden und ggf. anpassen. Ist die Bahnhofstabelle vorhanden, kann man auch über das entsprechende get sich Bahnhöfe anzeigen oder suchen lassen. Die Bahnhofstabelle wird über das Fhem-Update mitgeladen. Es muss also nur das Attribut mit dem Pfad (/opt/fhem/FHEM/deutschland_bhf.csv)gesetzt werden. '''Leider funktioniert das Laden der Tabelle nicht, wenn configDB genutzt wird.'''<br />
<br />
== Readings ==<br />
<br />
*departure_(1..3) -> Abfahrtszeit<br />
*arrival_(1..3) -> Ankunftszeit<br />
*connection_(1..3) -> Verbindungstyp<br />
*departure_delay_(1..3) -> Verspätung in der Abfahrtszeit<br />
*arrival_delay_(1..3) -> Verspätung in der Ankunftszeit<br />
<br />
*travel_note_(1..3) -> Hinweise für die Verbindung<br />
*travel_note_link_(1..3) -> Link zu den weiteren Verbindungsinformationen<br />
*travel_note_text_(1..3) -> Verbindungshinweis<br />
*travel_note_error_(1..3) -> Fehlertext der Detailinformation<br />
<br />
*travel_duration_(1..3) -> Reisezeit<br />
*travel_departure_(1..3) -> Informationen über den Abfahtsbahnhof und das Ankunftsgleis<br />
*travel_destination_(1..3) -> Informationen über den Zielbahnhof und das Ankunftsgleis<br />
*travel_change_(1..3) -> Anzahl der Umstiege<br />
*travel_price_(1..3) -> Fahrpreis<br />
*travel_vehicle_nr_(1..3) -> Anzeige der Zug, Bus,... Bezeichnung / Nummer</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=SetList&diff=28086SetList2018-10-15T10:57:30Z<p>Hauswart: /* Beispiele */</p>
<hr />
<div>{{SEITENTITEL:setList}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<!-- Infobox Attribut sinnvoll? --><br />
<br />
Das Attribut [[setList]] dient dazu, bei generischen Devices die Liste der möglichen set Kommandos zu spezifizieren. <br />
<br />
{{Todo|Bitte analog zu [[eventMap]] mit Inhalt füllen.}}<br />
<br />
== Syntax ==<br />
Das ''setList'' Attribut wird in der folgenden Weise spezifiziert:<br />
<br />
== Einschränkungen == <br />
Dieses Attribut existiert nur bei [[DOIF]]-, [[dummy]]- und [[readingsProxy]]-Devices.<br />
<br />
== Beispiele ==<br />
<br />
define Raumtemperatur dummy<br />
attr Raumtemperatur setList state:slider,10,0.5,30<br />
attr Raumtemperatur readingList state<br />
attr Raumtemperatur webCmd state<br />
<br />
define Wecker_Uhrzeit dummy<br />
attr Wecker_Uhrzeit setList state:AUS,05:00,05:15,05:30,05:45,06:00,06:15,06:30,06:35,06:40,06:45,06:50,06:55,07:00,07:05,07:10,07:15,07:20,07:25,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00,10:15,10:30,10:45,11:00,11:15,11:30,11:45,12:00,12:15,12:30,12:45,13:00,13:15,13:30,13:45,14:00,14:15,14:30,14:45,15:00,15:15,15:30,15:45,16:00,16:15,16:30,16:45,17:00,17:15,17:30,17:45,18:00,18:15,18:30,18:45,19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00,22:15,22:30,22:45,23:00,23:15,23:30,23:45,00:00,00:15,00:30,00:45,01:00,01:15,01:30,01:45,02:00,02:15,02:30,02:45,03:00,03:15,03:30,03:45,04:00,04:15,04:30,04:45<br />
attr Wecker_Uhrzeit readingList state<br />
attr Wecker_Uhrzeit webCmd state<br />
<br />
define Beschattung_auto dummy<br />
attr Beschattung_auto setList state:aktiv,passiv<br />
attr Beschattung_auto readingList state<br />
attr Beschattung_auto webCmd state<br />
<br />
define Heizungsmodus dummy<br />
attr Heizungsmodus setList state:auto,FHEM,Frostschutz,AUS<br />
attr Heizungsmodus readingList state<br />
attr Heizungsmodus webCmd state<br />
<br />
define TV_ProgrammKanal dummy<br />
attr TV_ProgrammKanal setList ARD_Ch ZDF_Ch HR_Ch RTL_Ch Sat1_Ch VOX_Ch Pro7_Ch Kabel1_Ch COMEDYCENTRAL_Ch DREISAT_Ch ARTE_Ch EINSPLUS_Ch EINSFESTIVAL_Ch ZDFNEO_Ch NDR_Ch MDR_Ch BR_Ch RBB_Ch SWR_Ch WDR_Ch RTL2_Ch SUPERRTL_Ch SPORT1_Ch EUROSPORT_Ch DMAX_Ch N24_Ch NTV_Ch RTLNITRO_Ch SAT1GOLD_Ch SIXX_Ch TELE5_Ch<br />
attr TV_ProgrammKanal readingList state<br />
<br />
define benzinpreis dummy<br />
attr benzinpreis readingList SuperE5_2 SuperPlus_2<br />
attr benzinpreis setList SuperE5_2:slider,140,1,200 SuperPlus_2:slider,140,1,200<br />
attr benzinpreis stateFormat SuperE5, SuperPlus<br />
attr benzinpreis userReadings SuperE5 {(ReadingsVal("oil","SuperE5_2",0) / 100 )}, SuperPlus {(ReadingsVal("oil","SuperPlus_2",0) / 100 )}<br />
attr benzinpreis webCmd SuperE5_2:SuperPlus_2<br />
<br />
== Links ==<br />
* Ausführliche Beschreibung (mit Beispielen) zu [[eventMap]], [[devStateIcon]], setList und [[webCmd]] in {{Link2Forum|Topic=12080|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=SSCAM_-_Steuerung_von_Kameras_in_Synology_Surveillance_Station&diff=26166SSCAM - Steuerung von Kameras in Synology Surveillance Station2018-03-21T12:01:56Z<p>Hauswart: /* Eine Übersicht mit Hilfe von readingsGroup */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Steuerung von Kameras in Synology Surveillance Station<br />
|ModType=d<br />
|ModCmdRef=SSCam<br />
|ModForumArea=Sonstiges<br />
|ModTechName=49_SSCam.pm<br />
|ModOwner=DS_Starter}}<br />
<br />
== Zweckbeschreibung ==<br />
<br />
Mit diesem Modul können Operationen von in der Synology Surveillance Station (SVS) definierten Kameras und Funktionen der SVS ausgeführt werden.<br />
Es basiert auf der SVS API und unterstützt die SVS ab Version 7. <br />
Zur Zeit werden folgende Funktionen unterstützt: <br />
<br />
* Start einer Aufnahme<br />
* Stop einer Aufnahme (per Befehl bzw. automatisch nach Ablauf der Aufnahmedauer)<br />
* Aufnehmen eines Schnappschusses und Ablage in der Synology Surveillance Station<br />
* Deaktivieren einer Kamera in Synology Surveillance Station<br />
* Aktivieren einer Kamera in Synology Surveillance Station<br />
* Steuerung der Belichtungsmodi Tag, Nacht bzw. Automatisch<br />
* Umschaltung der Ereigniserkennung durch Kamera, durch SVS oder deaktiviert<br />
* steuern der Erkennungsparameterwerte Empfindlichkeit, Schwellwert, Objektgröße und Prozentsatz für Auslösung<br />
* Abfrage von Kameraeigenschaften (auch mit Polling) sowie den Eigenschaften des installierten SVS-Paketes<br />
* Bewegen an eine vordefinierte Preset-Position (bei PTZ-Kameras)<br />
* Start einer vordefinierten Überwachungstour (bei PTZ-Kameras)<br />
* Positionieren von PTZ-Kameras zu absoluten X/Y-Koordinaten<br />
* kontinuierliche Bewegung von PTZ-Kameras<br />
* auslösen externer Ereignisse 1-10 (Aktionsregel SVS) <br />
* starten und beenden von Kamera-Livestreams<br />
* Abruf und Ausgabe der Kamera Streamkeys sowie Stream-Urls (zur Nutzung von Kamera-Livestreams ohne Session Id) <br />
* abspielen der letzten Aufnahme bzw. Anzeige des letzten Schnappschusses<br />
* Ein- bzw. Ausschalten des Surveillance Station HomeMode und abfragen des HomeMode-Status <br />
* erzeugen einer Gallerie der letzten 1-10 Schnappschüsse (als Popup oder permanentes Device) <br />
<br />
Die Aufnahmen stehen in der Synology Surveillance Station (SVS) zur Verfügung und unterliegen, wie jede andere Aufnahme, den in der Synology Surveillance Station eingestellten Regeln.<br />
So werden zum Beispiel die Aufnahmen entsprechend ihrer Archivierungsfrist gespeichert und dann gelöscht. <br />
<br />
Wenn sie über dieses Modul diskutieren oder zur Verbesserung des Moduls beitragen möchten, ist im FHEM-Forum ein Sammelplatz unter:<br><br />
{{Link2Forum|Topic=45671.0 |LinkText=49_SSCam: Fragen, Hinweise, Neuigkeiten und mehr rund um dieses Modul}}<br />
<br />
== Vorbereitung ==<br />
<br />
Dieses Modul nutzt das Perl-Modul JSON.<br />
Auf Debian-Linux basierenden Systemen kann es installiert werden mit:<br />
<br />
<pre><br />
sudo apt-get install libjson-perl<br />
</pre><br />
<br />
Das Modul verwendet für HTTP-Calls die nichtblockierenden Funktionen von HttpUtils bzw. HttpUtils_NonblockingGet.<br />
Im DSM bzw. der Synology Surveillance Station muß ein Nutzer angelegt sein. Die Zugangsdaten werden später über ein Set-Kommando dem angelegten Gerät zugewiesen. <br><br />
Nähere Informationen dazu unter [[#Credentials | Credentials]].<br />
<br />
Überblick über die Perl-Module welche von SSCam genutzt werden: <br><br><br />
<br />
JSON <br />
Data::Dumper <br />
MIME::Base64 <br />
Time::HiRes <br />
HttpUtils (FHEM-Modul)<br />
<br />
== Define ==<br />
<br />
Bei der Definition wird zwischen einer Kamera-Definition und der Definition einer Surveillance Station (SVS) unterschieden. Abhängig von der Art des definierten Devices wird das Internal MODEL auf CAM oder SVS gesetzt und eine passende Teilmenge der beschriebenen set/get-Befehle dem Device zugewiesen. <br><br />
Der Gültigkeitsbereich von set/get-Befehlen ist nach dem jeweiligen Befehl angegeben (gilt für CAM, SVS, CAM/SVS).<br />
<br />
Eine Kamera wird definiert durch:<br />
<br />
<pre><br />
define <name> SSCAM <Kameraname in SVS> <ServerAddr> [Port]<br />
</pre><br />
<br />
Zunächst muß diese Kamera in der Synology Surveillance Station 7.0 oder höher eingebunden sein und entsprechend funktionieren.<br />
<br />
Ein SVS-Device zur Steuerung von Funktionen der Surveillance Station wird definiert mit:<br />
<br />
<pre><br />
define <name> SSCAM SVS <ServerAddr> [Port]<br />
</pre><br />
<br />
In diesem Fall wird statt <Kameraname in SVS> nur '''SVS''' angegeben.<br />
<br />
Das Modul SSCam basiert auf Funktionen der Synology Surveillance Station API.<br />
Momentan wird nur das HTTP-Protokoll unterstützt um die Web-Services der Synology DS aufzurufen.<br />
<br />
Die Parameter beschreiben im Einzelnen: <br />
<br />
<pre><br />
name : der Name des neuen Gerätes in FHEM<br />
Kameraname : Kameraname wie er in der Synology Surveillance Station angegeben ist für Kamera-Device, "SVS" für SVS-Device. <br />
Leerzeichen im Namen sind nicht erlaubt.<br />
ServerAddr : die IP-Addresse des Synology Surveillance Station Host. <br />
Achtung: Es sollte kein Servername verwendet werden weil DNS-Aufrufe in FHEM blockierend sind<br />
Port : optional - der Port des Synology Surveillance Station Host. <br />
Wenn nicht angegeben, wird der Standardport 5000 gesetzt(nur HTTP)<br />
</pre><br />
<br />
'''Beispiel:'''<br />
<br />
define CamCP SSCAM Carport 192.168.2.20 [5000]<br />
erstellt ein neues Kamera-Device CamCP<br />
<br />
define DS1 SSCAM SVS 192.168.2.20 [5000] <br />
erstellt ein neues SVS-Device DS1<br />
<br />
Wird eine neue Kamera definiert, wird diesem Device zunächst eine Standardaufnahmdauer von 15 zugewiesen. <br />
Über das Attribut "rectime" kann die Aufnahmedauer für jede Kamera individuell angepasst werden. Der Wert "0" für "rectime" führt zu einer Endlosaufnahme die durch '''"set <name> off"''' gestoppt werden muß. Ein Logeintrag mit einem entsprechenden Hinweis auf diesen Umstand wird geschrieben. <br />
<br />
Wird das Attribut "rectime" gelöscht, greift wieder der Default-Wert (15s) für die Aufnahmedauer.<br />
<br />
Mit dem Befehl '''"set <name> on [rectime]"''' wird die Aufnahmedauer temporär festgelegt und überschreibt einmalig sowohl den Defaultwert als auch den Wert des gesetzten Attributs "rectime". Auch in diesem Fall führt "set <name> on 0" zu einer Daueraufnahme.<br />
<br />
Eine eventuell in der SVS eingestellte Dauer der Voraufzeichnung wird weiterhin berücksichtigt.<br />
<br />
<br />
=== Credentials ===<br />
<br />
Nach dem Definieren des Gerätes müssen zuerst die Zugangsparameter gespeichert werden. Das geschieht mit dem Befehl:<br />
<br />
set <name> credentials <username> <password><br />
<br />
Der Anwender kann in Abhängigkeit der beabsichtigten einzusetzenden Funktionen einen Nutzer im DSM bzw. in der Surveillance Station einrichten.<br />
Ist der DSM-Nutzer der Gruppe Administratoren zugeordnet, hat er auf alle Funktionen Zugriff. Ohne diese Gruppenzugehörigkeit können nur Funktionen mit niedrigeren Rechtebedarf ausgeführt werden. Die benötigten Mindestrechte der Funktionen sind in der Tabelle weiter unten aufgeführt.<br />
Alternativ zum DSM-Nutzer kann ein in der SVS angelegter Nutzer verwendet werden. Auch in diesem Fall hat ein Nutzer vom Typ Manager das Recht alle Funktionen auszuführen, wobei der Zugriff auf bestimmte Kameras/ im Privilegienprofil beschränkt werden kann (siehe Hilfefunktion in SVS).<br />
Als Best Practice wird vorgeschlagen jeweils einen User im DSM und einen in der SVS anzulegen.<br />
<br />
* DSM-User als Mitglied der Admin-Gruppe: uneingeschränkter Test aller Modulfunktionen -> session:DSM<br />
* SVS-User als Manager oder Betrachter: angepasstes Privilegienprofil -> session: SurveillanceStation <br />
<br />
Über das Attribut "session" kann ausgewählt werden, ob die Session mit dem DSM oder der SVS augebaut werden soll.<br />
Erfolgt der Session-Aufbau mit dem DSM, stehen neben der SVS Web-API auch darüber hinaus gehende API Zugriffe zur Verfügung die unter Umständen zur Verarbeitung benötigt werden.<br />
<br />
Nach der Gerätedefinition ist die Grundeinstellung "Login in das DSM", d.h. es können Credentials mit Admin-Berechtigungen genutzt werden um zunächst alle Funktionen der Kameras testen zu können. Danach können die Credentials z.B. in Abhängigkeit der benötigten Funktionen auf eine SVS-Session mit entsprechend beschränkten Privilegienprofil umgestellt werden.<br />
<br />
Die nachfolgende Aufstellung zeigt die Mindestanforderungen der jeweiligen Modulfunktionen an die Nutzerrechte. <br />
<pre><br />
* set ... credentials -<br />
* set ... disable session: ServeillanceStation - Manager<br />
* set ... enable session: ServeillanceStation - Manager<br />
* set ... expmode session: ServeillanceStation - Manager <br />
* set ... extevent session: DSM - Nutzer Mitglied von Admin-Gruppe<br />
* set ... goPreset session: ServeillanceStation - Betrachter mit Privileg Objektivsteuerung der Kamera<br />
* set ... goAbsPTZ session: ServeillanceStation - Betrachter mit Privileg Objektivsteuerung der Kamera<br />
* set ... homeMode session: ServeillanceStation - Betrachter mit Privileg Home-Modus schalten <br />
* set ... motdetsc session: ServeillanceStation - Manager <br />
* set ... move session: ServeillanceStation - Betrachter mit Privileg Objektivsteuerung der Kamera<br />
* set ... on session: ServeillanceStation - Betrachter mit erweiterten Privileg "manuelle Aufnahme"<br />
* set ... off session: ServeillanceStation - Betrachter mit erweiterten Privileg "manuelle Aufnahme"<br />
* set ... runPatrol session: ServeillanceStation - Betrachter mit Privileg Objektivsteuerung der Kamera<br />
* set ... runView session: ServeillanceStation - Betrachter mit Privileg Liveansicht für Kamera<br />
* set ... stopView -<br />
* set ... snap session: ServeillanceStation - Betrachter <br />
* get ... caminfoall session: ServeillanceStation - Betrachter <br />
* get ... eventlist session: ServeillanceStation - Betrachter<br />
* get ... scanVirgin session: ServeillanceStation - Betrachter<br />
* get ... svsinfo session: ServeillanceStation - Betrachter<br />
* get ... snapfileinfo session: ServeillanceStation - Betrachter<br />
* get ... snapGallery session: ServeillanceStation - Betrachter<br />
* get ... snapinfo session: ServeillanceStation - Betrachter<br />
* get ... stmUrlPath session: ServeillanceStation - Betrachter<br />
</pre><br />
<br />
=== HTTP-Timeout setzen ===<br />
<br />
Alle Funktionen dieses Moduls verwenden HTTP-Aufrufe gegenüber der SVS Web API. <br><br />
Der Standardwert für den HTTP-Timeout beträgt 4 Sekunden. <br />
Durch Setzen des Attributes "httptimeout" > 0 kann dieser Wert bei Bedarf entsprechend den technischen Gegebenheiten angepasst werden. <br />
<br />
<br />
<br><br />
<br />
== Set ==<br />
<br />
Siehe {{Link2CmdRef|Lang=de|Anker=SSCamset}}<br />
<br />
== Get ==<br />
<br />
Siehe {{Link2CmdRef|Lang=de|Anker=SSCamget}}<br />
<br />
== Das Modul bzw. eine Gerätedefinition deaktivieren ==<br />
<br />
Mit dem Attribut "disable" kann das Modul bzw. eine Gerätedefinition deaktiviert werden. Im Gegensatz zum Befehl "set ... disable" wird nicht die Kamera an sich deaktiviert, sondern lediglich das Gerätemodul. In diesem Fall werden keine Funktionen mehr ausgeführt.<br />
Wird das Modul deaktiviert, werden die folgenden Readings gesetzt:<br />
<br />
<pre><br />
state: inactive <br />
Availability: ???<br />
PollState: Inactive <br />
</pre><br />
<br />
Ist für eine Kamera Polling aktiviert, wird diese Aktivität abgeschaltet. Nach Reaktivierung des Gerätemoduls wird das Polling automatisch wieder fortgesetzt.<br />
<br />
<br />
<br><br />
<br />
== Lösungsbeispiele und Ansätze für verschiedene Aufgabenstellungen ==<br />
<br />
=== Eine Übersicht mit Hilfe von readingsGroup ===<br />
<br />
Mit den umfangreichen Möglichkeiten des Moduls [[readingsGroup]] kann ein FHEM-Widget nach eigenen Vorstellungen erstellt werden. Hierbei ist es möglich sowohl einen Überblick über die Status der Kameras zu erhalten als auch Steuerungsaktivitäten vorzusehen. Das nachfolgende Beipiel soll als Anregung dafür dienen. Weitere Informationen in der {{Link2CmdRef|Anker=readingsGroup}} zu readingsGroup.<br />
<br />
'''Hinweis:''' <br />
Die folgenden Beispiele enthalten keine Maskierungen oder Verdopplungen für ; und Zeilenende, sondern sind so angegeben, wie sie im Web Interface im Befehls-Eingabefeld, nach Klick auf DEF und im Attribut-Eingabefeld eingegeben werden. Mehrere Leerzeichen innerhalb von < > sind als <code><&amp;nbsp;&amp;nbsp;&amp;nbsp;></code> zu kodieren.<br />
<br />
{| class="wikitable"<br />
! Definition !! Erläuterungen <br />
|-<br />
| colspan=2 | [[Bild:RgSSCam.jpg|thumb|500px|links|Kamerastatus und Steuerung]]<br />
|-<br />
| style="width:50%" |<code>define Cams_All_States readingsGroup <%it_camera>,<Verfügbar>,< >,<Status>,< >,<Erkennung>,< >,<letzte Aufnahme>,< >,<bel. Platz (MB)>,< >,<letzte Aktualisierung>,< >,<Modul Deaktivierung>,< >,<Image> TYPE=SSCam:Availability,<&nbsp;;&nbsp;;&nbsp;;>,state,<&nbsp;;&nbsp;;&nbsp;;>,CamMotDetSc,<&nbsp;;&nbsp;;&nbsp;;>,CamLastRecTime,<&nbsp;;&nbsp;;&nbsp;;>,UsedSpaceMB,<&nbsp;;&nbsp;;&nbsp;;>,LastUpdateTime,<&nbsp;;&nbsp;;&nbsp;;>,?!disable,<&nbsp;;&nbsp;;&nbsp;;>,<%Start>,<%Stop></code><br />
| ReadingsGoup anlegen. <br />
|-<br />
| <code>attr Cams_All_States valueIcon {'Availability.enabled' => 'remotecontrol/black_btn_GREEN',<br />
'Availability.disabled' => 'remotecontrol/black_btn_RED',<br />
'state.inactive' => 'StandBy',<br />
'state' => '%devStateIcon'}</code><br />
| In Abhängigkeit vom Wert der Kameraverfügbarkeit und des state-Readings entsprechende Icons anzeigen. Wird das Modul deaktiviert, wird ein Standby-Icon angezeigt unabhängig davon ob in der Kameradefinition ein devStateIcon hinterlegt wurde.<br />
|-<br />
| <code>attr Cams_All_States valueStyle {if($READING eq "Availability" && $VALUE eq "enabled"){ ' style="color:green" ' }<br />
elsif( $READING eq "Availability" && $VALUE eq "disabled"){ ' style="color:red" ' }<br />
elsif( $READING eq "CamMotDetSc" && $VALUE =~ /SVS.*/ ){ ' style="color:orange" ' }<br />
elsif( $READING eq "CamMotDetSc" && $VALUE eq "disabled"){ ' style="color:LimeGreen" ' }<br />
elsif( $READING eq "CamMotDetSc" && $VALUE =~ /Cam.*/ ){ ' style="color:SandyBrown" ' }}</code><br />
| Farbgestaltung der Texte in Anhängigkeit der Werte setzen.<br />
|-<br />
| <code>attr Cams_All_States valueFormat {($READING eq "CamMotDetSc" && $VALUE eq "disabled") ? "external" : $VALUE}</code><br />
| Wenn die Quelle der Bewegungserkennung auf "disabled" gestellt wurde, soll "external" in der Übersicht angezeigt werden weil die Bewegungserkennung in dem Fall durch IR-Melder durchgeführt wird.<br />
|-<br />
| <code>attr Cams_All_States valueColumns { 'Image' => 'colspan="2"'}</code><br />
| Die Überschrift "Image" soll sich über die letzten zwei Spalten strecken. Es gilt sowohl für "Start" und "Stop" .<br />
|-<br />
| <code>attr Cams_All_States nameStyle style="color:black;font-weight:bold"</code><br />
| Die Überschriften sollen schwarz und fett sein.<br />
|-<br />
| <code>attr Cams_All_States commands { 'Availability.enabled' => 'set $DEVICE disable',<br />
'Availability.disabled' => 'set $DEVICE enable',<br />
'Cams_All_States.Start' => 'set %DEVICE runView image',<br />
'Cams_All_States.Stop' => 'set %DEVICE stopView',<br />
disable => "disable:"}</code><br />
| Es sollen Kommandos bestimmten Readings / Werten unterlegt werden. Zum Beispiel kann die Kamera mit Klick auf das Availability-Icon disabled werden wenn der Readingswert "enabled" ist. Der Livestream kann mit "Start" in der letzten Spalte gestartet, oder das Modul über eine Auswahl in der Drop-Down-Liste unterhalb von "Modul Deaktivierung" deaktiviert/aktiviert werden.<br />
|-<br />
| <code>attr Cams_All_States cellStyle { "c:0" => 'style="text-align:left;color:green;font-weight:normal"',<br />
"c:5" => 'style="text-align:center;color:green;font-weight:normal"',<br />
"c:9" => 'style="text-align:center;font-weight:normal"'}</code><br />
| Formatierung bestimmter Spalten (0,5,9).<br />
|-<br />
| <code>attr Cams_All_States alias Status aller Kameras</code><br />
| Alias setzen.<br />
|-<br />
| <code>attr Cams_All_States group Kamerastatus</code><br />
| Gruppenzugehörigkeit setzen. Wird auch für die Anzeige im Dashboard benutzt.<br />
|}<br />
<br />
<br />
<br><br />
<br />
=== Einen Snapshot der Surveillance Station mit TelegramBot versenden ===<br />
<br />
In dieser Beispielbeschreibung wird der Versand eines Snapshots mit Hilfe eines TelegramBot-Devices beschrieben.<br />
Es wird vorausgesetzt dass sowohl ein TelegramBot-Device als auch ein SSCam-Device definiert sind und als solches für sich bereits fehlerfrei funktionieren.<br />
<br />
Informationen zur Definition dieser Devices finden sich sowohl in der {{Link2CmdRef|Lang=de}} als auch im Wiki:<br />
<br />
* SSCam -> https://wiki.fhem.de/wiki/SSCAM_-_Steuerung_von_Kameras_in_Synology_Surveillance_Station<br />
* TelegramBot -> https://wiki.fhem.de/wiki/TelegramBot<br />
<br />
Weiterhin wird angenommen, dass FHEM auf einem separaten Rechner (Rasperry Pi oder virtuellem Server) läuft und die Synology Diskstation den Surveillance Dienst bereitstellt.<br />
<br />
Mit Stand DSM 6.1 werden die Snapshots aller Kameras in einem zentralen Ordner "/volume1/surveillance/@Snapshot" abgelegt, wobei "volume1" von der konkreten Installation abhängt. Die Dateinamen beginnen mit dem Kameranamen und enthalten weiterhin den Timestamp des Schnapschusses.<br />
[[Datei:NFS_Regel.PNG|right|thumb|500px|NFS-Regel erstellen]]<br />
<br />
Zunächst wird im Synology DSM -> Systemsteuerung -> Gemeinsamer Ordner der Ordner "surveillance" zum Bearbeiten geöffnet. Im Reiter "NFS-Berechtigungen" wird eine neue NFS-Regel erstellt um den oder die FHEM-Rechner den Zugriff zu erlauben. <br />
<br />
<br />
<br />
Um nur bestimmte Hosts zu erlauben, können die zugelassenen IP-Adressen in der Spalte "Client" spezifiziert werden. <br />
Im unteren Bereich des Fensters ist der später benötigte Mount-Pfad ersichtlich. In diesem Beispiel ist es "/volume1/surveillance".<br />
Da der zugreifende User lediglich Leseberechtigung benötigt, brauchen keine weiteren Einstellungen vorgenommen werden da dem Client beim Zugriff auf den gemeinsamen Ordner die Berechtigungen von others/Sonstige“ zugewiesen werden sofern die UID/GID von Client nicht mit Synology NAS User numerisch übereinstimmt.<br />
<br />
Auf dem FHEM-Rechner nun ein Directory anlegen, in welches der Mount-Pfad "/volume1/surveillance" eingehängt werden soll, z.B.:<br />
<br />
<pre><br />
sudo mkdir /sds1/surveillance<br />
</pre><br />
<br />
und in der Datei "/etc/fstab" den Mount hinzufügen/abspeichern, z.B.:<br />
<br />
<pre><br />
<Name oder IP Synology DS:>/volume1/surveillance /sds1/surveillance nfs auto,defaults,tcp,intr 0 0<br />
</pre><br />
<br />
Nun kann mit:<br />
<br />
<pre><br />
sudo mount -a<br />
</pre><br />
<br />
das freigegebene Verzeichnis mit den Snapshots gemounted werden und steht damit auf dem FHEM-Server zur Verfügung.<br />
<br />
Damit sind die Voraussetzungen für einen Snapshotversand erfüllt und es kann direkt mit der Definition eines Notify fortgefahren werden, z.B.:<br />
<br />
<pre><br />
define N.CamHE1.Snap.TeleBot notify CamHE1:LastSnapFilename.* { my $var = '/sds1/surveillance/@Snapshot/'.(ReadingsVal("CamHE1","LastSnapFilename",""));; fhem ("set teleBot sendImage $var Eine Bewegung an der Haustür wurde aufgezeichnet");; }<br />
attr N.CamHE1.Snap.TeleBot room Cams<br />
</pre><br />
<br />
(Der Code kann als RAW-Definition im FHEMWEB übernommen werden)<br />
<br />
Zur Funktionsweise: <br><br />
Wenn durch die Kamera "CamHE1" ein Snapshot aufgenommen wurde, erstellt das Cam-Device im Reading "LastSnapFilename" den Namen der Bilddatei im Ordner @Snapshot der Synology bzw. des gemounteten Verzeichnis "/sds1/surveillance/@Snapshot". Ergänzt wird noch der Dateiname des Schnapschusses mit "ReadingsVal("CamHE1","LastSnapFilename","") und wird mit dem TelegramBot-Device "teleBot" sowie einem erläuternden Text an den default Peer des Telebot-Devices versendet.<br />
<br />
<br />
<br />
<br><br />
<br />
=== Mail mit Snapshot im Anhang und Aufnahmelink versenden (sendemail) ===<br />
<br />
Nachfolgendes Beispiel zeigt eine Möglichkeit in Linux mit dem Tool [http://caspian.dotconf.net/menu/Software/SendEmail/ sendemail] eine Mail mit einem Link zu einer Kameraaufnahme und bis zu drei Anhängen zu versenden. Das Tool ist in vielen Repositories erhalten und kann unter Debian (z.B. Ubuntu) installiert werden mittels <code>apt-get install sendemail libio-socket-ssl-perl</code>.<br />
Die Mail wird mit einem DOIF Kommando in Abhängigkeit von einer angefertigten Aufnahme angestoßen.<br />
<br />
Zunächst die Mailfunktion in der 99_myUtils als Unterroutinen einfügen. Die Funktion ist nicht blockierend (mit Modul Blocking.pm) ausgeführt. Die "\" dienen nachfolgend nur<br />
zur Kennzeichnung eines Zeilenumbruchs - den Code bitte auf eine Zeile schreiben.<br />
<br />
<syntaxhighlight lang=perl><br />
# Am Anfang von 99_myUtils hinzufügen<br />
use Blocking;<br />
<br />
##############################################################################<br />
######## DebianMail Mail versenden nonblocking ############<br />
##############################################################################<br />
<br />
sub DebianMailnbl {<br />
<br />
my $rcpt = shift;<br />
my $subject = shift; <br />
my $text = shift;<br />
my $attach = shift; <br />
my $attach1 = shift; <br />
my $attach2 = shift; <br />
my $hash->{NAME_MAIL} = "Debianmail";<br />
my $name = $hash->{NAME_MAIL};<br />
<br />
if ($attach2) {<br />
$hash->{helper}{RUNNING_PID} = BlockingCall("DebianMailnbl_send", $name."|".$rcpt."|".$subject."|".$text."|".$attach." \<br />
|".$attach1."|".$attach2, "", "", "", "");<br />
} elsif ($attach1) {<br />
$hash->{helper}{RUNNING_PID} = BlockingCall("DebianMailnbl_send", $name."|".$rcpt."|".$subject."|".$text."|".$attach."|" \<br />
.$attach1, "", "", "", "");<br />
} else {<br />
$hash->{helper}{RUNNING_PID} = BlockingCall("DebianMailnbl_send", $name."|".$rcpt."|".$subject."|".$text."|".$attach,<br />
"", "", "", "");<br />
}<br />
<br />
}<br />
<br />
######################################################<br />
######## Mailfunktion nonblocking <br />
######################################################<br />
<br />
sub DebianMailnbl_send {<br />
my ($string) = @_;<br />
my ($name, $rcpt, $subject, $text, $attach, $attach1, $attach2) = split("\\|", $string);<br />
my $ret = "";<br />
my $sender = "<Sendername>\@<Domäne>"; <br />
my $konto = "<Mailkonto";<br />
my $passwrd = "<Mailkontopasswort>";<br />
my $provider = "<Mailserver>";<br />
<br />
<br />
if ($attach2) {<br />
$ret .= qx(sendEmail -f '$sender' -t '$rcpt' -u '$subject' -m '$text' -a '$attach' -a '$attach1' -a '$attach2' -s '$provider' \<br />
-xu '$konto' -xp '$passwrd' -o tls=no -o message -charset=utf-8 -o message-content-type=text/plain );<br />
} elsif ($attach1) {<br />
$ret .= qx(sendEmail -f '$sender' -t '$rcpt' -u '$subject' -m '$text' -a '$attach' -a '$attach1' -s '$provider' -xu '$konto' \<br />
-xp '$passwrd' -o tls=no -o message-charset=utf-8 -o message-content-type=text/plain );<br />
} else {<br />
$ret .= qx(sendEmail -f '$sender' -t '$rcpt' -u '$subject' -m '$text' -a '$attach' -s '$provider' -xu '$konto' -xp '$passwrd' \<br />
-o tls=no -o message-charset=utf-8 -o message-content-type=text/plain );<br />
}<br />
<br />
# remove CR from return-string <br />
$ret =~ s,[\r\n]*,,g; <br />
<br />
Log3 $name, 3, "$name - sendEmail returned: $ret";<br />
}<br />
</syntaxhighlight><br />
<br />
Um die TLS Verschlüsselung (ehem. SSL) zu nutzen, dann tls=auto verwenden.<br />
<br />
Falls der Body-Text in einem (Android-)Mailer auf dem Handy nicht gezeigt wird, kann evtl. der Parameter '''-o message-content-type=html''' helfen.<br />
<br />
<br />
<br />
<br><br />
==== Versand triggern - Beispiel mit DOIF ====<br />
Der Mailversand wird in dem Beispiel mit einem DOIF angetriggert:<br />
<br />
<pre><br />
define CamHE1.email DOIF ([CamHE1:"CamLastRec"]) ({DebianMailnbl ('<Empfänger>@<Domäne>','Bewegungsalarm CamHE1','Eine Bewegung wurde an der Haustür registriert. <br />
Aufnahmelink: [CamHE1:VideoFolder]/[CamHE1:CamLastRec]','/media/sf_surveillance/@Snapshot/[CamHE1:LastSnapFilename]')})<br />
</pre><br />
<br />
Wird eine Aufnahme der Kamera CamHE1 beendet, wird integriert der Befehl "get .. eventlist" ausgeführt. Dadurch aktualisiert sich das Reading "CamLastRec".<br />
Dieser Event wird genutzt um eine Mail mit einem Link zur Aufnahme und einem während der Aufnahme angelegten Schnappschuß zu versenden.<br />
Will man einen weiteren Anhang versenden, sähe das DOIF folgendermaßen aus:<br />
<br />
<pre><br />
define CamHE1.email DOIF ([CamHE1:"CamLastRec"]) ({DebianMailnbl ('<Empfänger>@<Domäne>','Bewegungsalarm CamHE1','Eine Bewegung wurde an der Haustür registriert. <br />
Aufnahmelink: [CamHE1:VideoFolder]/[CamHE1:CamLastRec]','/media/sf_surveillance/@Snapshot/[CamHE1:LastSnapFilename]','<weiteres File>')})<br />
</pre><br />
<br />
<br />
Dss Reading "VideoFolder" muß, wie in dem Beispiel zu sehen, dem "CamLastRec" vorangestellt werden um den kompletten Pfad zur Aufnahme zu erhalten. Der versendete Link würde somit etwa den folgenden Aufbau haben:<br />
<br />
<pre><br />
/volume1/surveillance/Carport/20160407PM/Carport20160407-221541-1460060141.mp4<br />
</pre><br />
<br />
Wenn in einer Mail nach extern versendet wird, ist ein solcher Link wahrscheinlich über eine Anwendung nicht zugreifbar.<br />
Um den Link dynamisch anzupassen und so den Zugriff von extern über z.B. einen Webserver zu ermöglichen, kann das Attribut "videofolderMap" verwendet werden.<br />
<br />
Wird dieses Attribut auf zum Beispiel ...<pre>"http://<Server>:8083/fhem/svs/Carport/"</pre> ...gesetzt, ergibt sich folgender Link der in der Mail versendet wird:<br />
<br />
<pre><br />
http://<Server>:8083/fhem/svs/Carport/20160407PM/Carport20160407-221541-1460060141.mp4<br />
</pre><br />
<br />
In dem obigen Beispiel wird ein FHEM-Webserver verwendet, der zuvor über HTTPSRV (siehe {{Link2CmdRef|Anker=HTTPSRV}}) angelegt wurde,<br />
WIe der Webserver angelegt werden kann ist [[SSCAM_-_Steuerung_von_Kameras_in_Synology_Surveillance_Station#Einsatz_FHEM_Webserver_zum_Zugriff_auf_Aufnahmen | hier]] beschrieben. <br />
<br />
'''Hinweis:'''<br />
<br />
Nach dem Snapshot wird implizit die Funktion "get ... snapfileinfo" aufgerufen. Diese Funktion trägt den neuen/letzten Snapfilename in das Reading "LastSnapFilename" ein.<br />
Es ist somit sicherzustellen dass dieses Funktion abgeschlossen ist bevor die Aufnahme per Mail versendet werden soll. Das kann zum Beispiel mit einem Notify auf den Event "<Device>:LastSnapFilename.*" geschehen.<br />
Sollten das Problem auftreten dass alte Snapshots versendet werden, ist aller Wahrscheinlichkeit nach in dem beschriebenen Sachverhalt die Ursache zu finden.<br />
<br />
<br />
<br><br />
<br />
==== Versand triggern - Beispiel mit Notify ====<br />
<br />
Mit diesem Notify wird das Snapshotfile angehängt und auch ein Link zu dem Snapshot mit eingefügt.<br />
<br />
<pre><br />
define CamHE1.email NOTIFY CamHE1:LastSnapFilename.* {DebianMailnbl ('<Empfänger>@<Domäne>','Bewegungsalarm CamHE1', <br />
'Eine Bewegung wurde an der Haustür registriert. Aufnahmelink: http://<Server>:8083/fhem/snap/'.(ReadingsVal("CamHE1","LastSnapFilename","")), <br />
'/media/sf_surveillance/@Snapshot/'.(ReadingsVal("CamHE1","LastSnapFilename","")))}<br />
</pre><br />
<br />
Um den Link in dieser Form aufrufen zu können ist erst ein HTTPSRV anzulegen mit:<br />
<br />
<pre><br />
define snapweb HTTPSRV snap /media/sf_surveillance/@Snapshot SVS-Snapshots<br />
</pre><br />
<br />
Natürlich muß dabei der Pfad "/media/sf_surveillance/" so angepasst werden dass er dem (gemounteten) SVS-Aufnahmeverzeichnis entspricht.<br />
<br />
<br />
<br><br />
<br />
=== Einsatz eines Webservers zum Zugriff auf Aufnahmen ===<br />
<br />
==== Nutzung des FHEM-internen HTTPSRV Plug-In ====<br />
<br />
Ziel der nachfolgenden Beschreibung ist es, eine Möglichkeit darzustellen, um den FHEM Webserver für den Zugriff auf die Aufnahmen der Synology Surveillance Station zu nutzen. <br />
<br />
Folgende Ausgangslage wird für das Beispiel als gegeben angenommen:<br />
<br />
<br />
* der gemeinsame Ordner der Surveillance Station (normalerweise "surveillance") in der Diskstation ist am FHEM-Server gemountet. <br>Für das Beipiel ist das gemountete Verzeichnis: /media/sf_surveillance<br />
* FHEMWEB ist im Einsatz<br />
* für das Beispiel ist eine Kamera CamHE1 (SVS-Name: Hauseingang) definiert<br />
<br />
<br />
HTTPSRV ist ein Plug-in für FHEMWEB und stellt den Webserver für den Zugriff zur Verfügung. Diese Möglichkeit ist sicherlich für jene Fälle interessant bei denen der Zugriff über einen Verzeichnisdienst nicht möglich oder nicht gewünscht ist (zum Bespiel von extern).<br />
Es steht auch eine Modul-interne Zugriffsmöglichkeit auf die letzte Aufnahme mit dem Befehl "set CamHE1 runView lastrec (oder lastrec_open)" zur Verfügung.<br />
<br />
<br />
<br />
Der Webserver wird definiert mit:<br />
<br />
define svsweb HTTPSRV svs /media/sf_surveillance WebServer SVS-Aufnahmen<br />
<br />
Der definierte Webserver sollte nun links im Seitenmenü unter dem Namen "WebServer SVS-Aufnahmen" erscheinen. Ein Klick auf diesen Link sollte nun die Meldung zeigen:<br />
<br />
File not found: /media/sf_surveillance/index.html<br />
<br />
Die Datei index.html existiert natürlich normalerweise nicht im surveillance-Verzeichnis. Der Inhalt des Verzeichnisses "/media/sf_surveillance", also des surveillance-Stammordners, wird nun mit der Basisadresse ... <pre>http://<FHEM-Server>:8083/fhem/svs/</pre> ...erreicht.<br />
<br />
Alle Aufnahmen der Kameras werden in Unterordnern des surveillance-Stammerzeichnisses gespeichert, die den gleichen Namen wie die Kamera in der Surveillance Station haben. Um den Pfad zu dem Aufnahmefile zu spezifizieren, ist die Basisadresse des erstellten Webservers mit dem Unterordner der entsprechenden Kamera zu ergänzen. Mit diesem zusammengesetzten Gesamtpfad ist ebenfalls das Reading "VideoFolder", welches den physikalischen Pfad von Aufnahmen der entsprechenden Kamera beschreibt, zu überschreiben. <br />
<br />
Die wird mit dem Attribut "videofolderMap" erreicht. In dem Beispiel wird es gesetzt auf:<br />
<br />
<pre><br />
attr CamHE1 videofolderMap http://<FHEM-Server>:8083/fhem/svs/Hauseingang/<br />
</pre><br />
<br />
Jede Aufnahme der Kamera "Hauseingang" bzw. "CamHE1" wird somit durch die Webadresse ...<br />
<br />
<pre><br />
http://<FHEM-Server>:8083/fhem/svs/Hauseingang/<Inhalt Reading CamLastRec><br />
</pre><br />
<br />
... erreicht.<br />
<br />
Wie eine Mail mit diesem Link versendet werden kann ist [[SSCAM_-_Steuerung_von_Kameras_in_Synology_Surveillance_Station#Mail_mit_Snapshot_im_Anhang_und_Aufnahmelink_versenden_.28sendmail.29 | hier]] beschrieben.<br />
<br />
Der komplette in der Mail versendete Aufnahmelink sieht folgendermaßen aus: <br />
<pre><br />
http://<FHEM-Server>:8083/fhem/svs/Hauseingang//20160408PM/Hauseingang20160408-215150-1460145110.mp4<br />
</pre><br />
<br />
<br />
<br><br />
<br />
==== Nutzung der Webstation auf Synology DS zum Zugriff auf Recordings ====<br />
<br />
Da die Benutzung des HTTPSRV für diesen Zweck FHEM belastet bzw. blockiert, hat Martin Fischer im Forum unter:<br />
https://forum.fhem.de/index.php/topic,45671.msg482616.html#msg482616<br />
<br />
zwei Möglichkeiten bschrieben wie man den internen Webserver des Synology DS statt dessen verwenden kann (DSM 6).<br />
<br />
Darauf aufbauend ist hier folgend die Umsetzung im DSM 5.2 beschrieben.<br />
<br />
<br />
<br />
'''1. schnelle Variante A'''<br />
<br />
Die nachfolgende Beschreibung bezieht sich auf DSM 5.2. Es wird ein virtueller Host (test.myds.me) definiert, der auf Port HTTP 8081 hört. Das Dokument-Root soll in dem Beispiel der Ordner "/volume1/web/fhemsvs" sein. <br />
<br />
* Nach dem Login als root wechselt man in das web-Verzeichnis mit "cd /volume1/web"<br />
* anlegen des Root-Verzeichnisses für den virtuellen Host und setzen der Berechtigungen:<br />
mkdir fhemsvs<br />
chown http:http fhemsvs<br />
chmod 775 fhemsvs<br />
<br />
* Link im Root-Verzeichnis zum SVS-Stammverzeichnis setzen:<br />
ln -s /volume1/surveillance/ /volume1/web/fhemsvs<br />
<br />
(Hinweis: Wenn es zu Problemen beim Mailversand kommt - "leere" Bilder angehängt -, schaut mal, ob das Verzeichnis richtig ist. Einige (Beta-)Versionen von SVS benutzen @surveillance statt surveillance als Verzeichnis, so dass ein leicht anderer Link gesetzt werden muss: ln -s /volume1/\@surveillance/ /volume1/web/fhemsvs)<br />
<br />
* einen virtuellen Host in Systemsteuerung -> Webdienste -> virtueller Host anlegen. Soll der Host von extern erreichbar sein, muß ebenfalls eine Registrierung des Hostnamens z.B. bei dem kostenfreien DNS-Dienst von Synology erfolgen sowie der verwendete Port im Router freigeschaltet werden.<br />
<br />
[[Bild:vHost.PNG|left|thumb|300px|]] Der virtuelle Host ist durch die Angabe des Unterodners (fhemsvs), des Hostnamens (test.myds.me), des Protokolls und des Ports (8081) zu definieren. Die Angaben sind natürlichen den realen Werten anzupassen.<br />
<br />
* die Recordings sind nun prinzipiell unter der Adresse erreichbar:<br />
<pre><br />
http://test.myds.me:8081/surveillance/<Camname>/<Zeitordner>/<Dateiname><br />
</pre><br />
<br />
* in FHEM ist der Zugangspfad zu dem Aufnahmen zusammengesetzt aus den Readings "VideoFolder" (Original z.B. /volume1/surveillance/Carport) und "CamLastRec". Über das Attribut "videofolderMap" wird "/volume1/surveillance/Carport" nun ersetzt durch <pre>"http://test.myds.me:8081/surveillance/Carport/"</pre><br />
<br />
Der substituierte Aufnahmelink wird nun zu: (ReadingsVal("<camname>","VideoFolder","")).(ReadingsVal("<name>","CamLastRec",""))<br />
<br />
* Der Versand des Aufnahmelinks per Mail kann durch ein Notify erfolgen:<br />
<br />
define N.CamCP1.Rec.Email notify CamCP1:CamLastRec:.* {DebianMailnbl ('<Mailempfänger>','Bewegungsaufnahme Carport', 'Aufnahmelink: '.(ReadingsVal("CamCP1","VideoFolder","")).(ReadingsVal("CamCP1","CamLastRec",""))) }<br />
<br />
Die Funktion DebianMailnbl für den Mailversand ist zuvor in 99_myUtils zu definieren. (siehe [[#Mail_mit_Snapshot_im_Anhang_und_Aufnahmelink_versenden_.28sendmail.29 | Mailversandroutine]] )<br />
<br />
<br />
* Der Versand des Aufnahmelinks per TelegramBot kann durch folgendes Notify erfolgen:<br />
<br />
define N.CamCP1.Rec.TeleBot notify CamCP1:CamLastRec:.* { my $var = (ReadingsVal("CamCP1","VideoFolder","")).(ReadingsVal("CamCP1","CamLastRec","")); fhem ("set teleBot message $var Bewegungsaufnahme beim Carport"); }<br />
<br />
Natürlich ist TelegramBot vorab einzurichten. Der Versand erfolgt in dem Beispiel an den defaultPeer.<br />
<br />
<br />
<br><br />
<br />
'''2. Variante B'''<br />
<br />
(noch für DSM 5.2 zu beschreiben).<br />
<br />
<br />
<br />
<br><br />
=== Kamerastreams in Weblinks zusammenstellen ===<br />
<br />
Eine Routine, die dynamisch alle "enabled" Devices vom TYPE=SSCam in einem Weblink zusammenstellt.<br />
<br />
<pre><br />
Internals: <br />
CFGFN <br />
DEF htmlCode {SurveillanceMjpegHtml("WBL.sscamview",320,240)} <br />
LINK {SurveillanceMjpegHtml("WBL.sscamview",320,240)} <br />
NAME WBL.sscamview <br />
NR 34874 <br />
STATE initialized <br />
TYPE weblink <br />
WLTYPE htmlCode <br />
Helper: <br />
Bm: <br />
Weblink_define: <br />
cnt 6 <br />
dmx 0 <br />
mAr <br />
max 0 <br />
tot 0 <br />
Attributes: <br />
alias Livestream <br />
group Kameras - Livestream <br />
htmlattr width="800" height="600" <br />
room Cams <br />
</pre><br />
<br />
Subroutine in 99_myUtils:<br />
<br />
<pre><br />
sub SurveillanceMjpegHtml(@) {<br />
my $name = "SurveillanceMjpegHtml";<br />
my ( $devWeblink, $width, $height ) = @_;<br />
my $debug = ( AttrVal( $devWeblink, "verbose", 3 ) == 5 ) ? 1 : 0;<br />
Log3 $name, 1, "DEBUG $name: devWeblink:$devWeblink width:$width height:$height"<br />
if ($debug);<br />
<br />
my $htmlCode;<br />
<br />
$htmlCode .=<br />
sprintf( '<div class="makeTable wide"> <a href="/fhem?detail=%s">Livestream</a>',<br />
$devWeblink );<br />
$htmlCode .= '<table class="block wide internals">';<br />
$htmlCode .= '<tbody>';<br />
<br />
$htmlCode .= '<tr class="odd">';<br />
my @camDevs = devspec2array("TYPE=SSCam");<br />
my $cell = 1;<br />
foreach my $camDev (@camDevs) {<br />
my $StmKey = ReadingsVal( $camDev, "StmKey", undef );<br />
<br />
if ( defined($StmKey) && ReadingsVal( $camDev, "Availability", "" ) eq "enabled" ) {<br />
<br />
my $webapi = sprintf(<br />
'http://%s:%d/webapi/entry.cgi?api=SYNO.SurveillanceStation.VideoStreaming&version=1&method=Stream&format=mjpeg&cameraId=%d&StmKey="%s"',<br />
$defs{$camDev}{SERVERADDR},<br />
$defs{$camDev}{SERVERPORT},<br />
$defs{$camDev}{CAMID}, $StmKey<br />
);<br />
<br />
my $html = sprintf(<br />
'<td>%s<br /> <img src=\'%s\' width=%d height=%d /> </td>',<br />
$defs{$camDev}{CAMNAME},<br />
$webapi, $width, $height<br />
);<br />
<br />
Log3 $name, 1, "DEBUG $name: cell:$cell camDev:$camDev StmKey:$StmKey"<br />
if ($debug);<br />
<br />
$cell++;<br />
<br />
if ( $cell == 3 ) {<br />
$htmlCode .= $html;<br />
$htmlCode .= '</tr>';<br />
$htmlCode .= '<tr class="odd">';<br />
$cell = 1;<br />
}<br />
else {<br />
$htmlCode .= $html;<br />
}<br />
<br />
Log3 $name, 1, "DEBUG $name: cell: $cell"<br />
if ($debug);<br />
<br />
}<br />
}<br />
<br />
if ( $cell == 2 ) {<br />
$htmlCode .= '<td>&nbsp;</td>';<br />
}<br />
<br />
$htmlCode .= '</tr>';<br />
<br />
$htmlCode .= '</tbody>';<br />
$htmlCode .= '</table>';<br />
$htmlCode .= '</div>';<br />
return $htmlCode;<br />
}<br />
</pre><br />
<br />
<br><br />
=== Aktionen mit dem Aktionsregeleditor der Surveillance Station auslösen ===<br />
<br />
Das Modul SSCam ist vordergründig dafür gedacht die Kameras in der Surveillance Station (SS) durch auslösende Aktionen innerhalb von FHEM zu steuern, d.h. dass FHEM üblicherweise das führende Element in der Steuerkette ist.<br />
<br />
Allerdings gibt es auch die Fälle, in denen eine Kamera durch die eigene Bewegungserkennung oder der Bewegungserkennung der SS Aufnahmen erstellt. Wenn neue Aufnahmen erstellt wurden, bekommt SSCam dies zwar über eine Pollingabfrage über "get ... caminfoall", "get ... snapinfo" bzw. "get ... eventlist" angezeigt, aber dies erfolgt mit entsprechender Zeitverzögerung des Pollingintervalls.<br />
<br />
Mit Hilfe des Aktionsregeleditors der Surveillance Station können solche Aufgaben bei zeitkritischen Vorgängen recht elegant gelöst werden.<br />
<br />
Um die Funktionsweise darzustellen, soll ein einfaches Beispiel dienen. Es soll ein Licht angeschaltet werden wenn die Kamera "Hauseingang" eine Bewegung entdeckt hat.<br />
<br />
# den Aktionsregeleditor in der SS aufrufen [[Datei:ssar1.PNG|right|thumb|300px|Aktionsregeleditor neue Regel anlegen]] [[Datei:ssar2.PNG|right|thumb|300px|Ereignis definieren]]<br />
# eine neue Aktionsregel "Licht einschalten" vom Typ "ausgelöst" anlegen -> "Weiter" <br><br><br><br><br><br><br><br><br><br><br><br><br />
# Unter "Ereignis 1" das Ereignis hinzufügen. Als Ereignisquelle "Kamera", Gerät "Hauseingang" und Ereignis "Bewegung entdeckt" aswählen. Es können noch weitere Ereignisse hnzugefügt werden (z.B. Bewegung einer zweiten Kamera erkannt) und über die Einstellungssektion die logische Verknüpfung beider Ereignisse (AND/OR) ausgewählt werden. -> "Weiter" <br><br><br> [[Datei:ssar3.PNG|right|thumb|300px|Aktion definieren]] [[Datei:ssar4.PNG|right|thumb|300px|Zeitplan einstellen]] <br />
# Im nächsten Screen ist die Aktion hinzuzufügen.<br> Das Aktionsgerät ist in diesem Fall "Externes Gerät". Es soll eine URL angesprochen werden. <br> <pre>http://<IP-FHEM>:<Port-FHEM>/fhem?cmd=set%20eg.wz.stehlampe%20on</pre> Weiterhin ist noch der FHEM-User und Passwort für das Login einzugeben. <br> Es könnte noch die Anzahl der auszulösenden Aktionen und deren Intervall eingegeben werden. Es kann auf "1" belassen werden. -> "Weiter" <br><br><br><br><br><br><br><br><br><br><br />
# ein Zeitplan für diese Regel festlegen. Im Beispiel soll sie immer aktiv sein. Also keine Änderung und "Fertigstellen". <br><br><br><br><br> <br />
<br />
Sobald nun eine Bewegung durch die Kamera entdeckt wird, schaltet FHEM das Licht "eg.wz.stehlampe" an. Dazu muß natürlich die Bewegungserkennung der Kamera in der SS (unter IP-Kamera) aktiviert sein.<br />
<br />
Nach dem gleichen Prinzip kann zum Beispiel auch ein "get ... caminfoall", "get ... snapinfo" bzw. "get ... eventlist" getriggert werden.<br />
Lässt man ein Notify oder DOIF auf das Reading "CamLastRec" oder "LastSnapFilename" lauschen, kann man sich daraus abgeleitet eine Mail bzw. eine TelegramBot/Jabber-Nachricht mit dem Link zur letzten Aufnahme oder das Schnappschußbild senden lassen. <br />
<br />
Diese Möglichkeit ist zum Beispiel in diesem [[#Nutzung_der_Webstation_auf_Synology_DS_zum_Zugriff_auf_Recordings|Abschnitt]] beschrieben.<br />
<br />
<br />
<br><br />
<br />
=== Workaround bei DSM 2-Stufen Verifizierung ===<br />
1. Benutzer in der SVS einrichten, zum Manager machen<br><br />
2. Benutzer wird automatisch auch in FHEM eingerichtet, dort zum Admin machen<br><br />
3. 2-Stufen Verifizierung ausschalten<br><br />
4. Modul / Kamera zum Laufen bringen<br><br />
5. Session im Modul auf SVS stellen<br><br />
6. Benutzer in der DSM aus der Admin-Gruppe rausnehmen<br><br />
7. 2-Stufen Verifizierung einschalten (Option nur für Admins)<br><br />
<br />
<br />
== Hinweise zu Fehlern ==<br />
=== "Execution failed" in Snap-Funktion nach SVS update auf 8.0.1 ===<br />
<br />
Die Rechte auf das Verzeichnis /volume1/surveillance/@Snapshot wurden nicht auf den neuen Benutzer/Gruppe SurveillanceStation/SurveillanceStation umgesetzt.<br />
<br />
Mit<br />
<br />
chown -R SurveillanceStation:SurveillanceStation /volume1/surveillance/@Snapshot<br />
<br />
konnte das Problem behoben werden.<br />
Die Rechte des Verzeichnisses sind jetzt:<br />
<br />
<pre><br />
drwxrwxrwx 8 root root 4096 Mar 4 16:03 .<br />
drwxr-xr-x 49 root root 4096 Mar 4 15:06 ..<br />
drwxrwxrwx 47 SurveillanceStation SurveillanceStation 4096 Mar 3 21:26 Carport<br />
drwxrwxrwx+ 3 root root 4096 Mar 2 01:01 @eaDir<br />
drwxr-xr-x 24 SurveillanceStation SurveillanceStation 4096 Mar 4 15:07 Hauseingang<br />
drwxr-xr-x 4 SurveillanceStation SurveillanceStation 4096 Feb 26 19:59 Keller<br />
drwxr-xr-x 3 SurveillanceStation SurveillanceStation 45056 Mar 4 15:39 @Snapshot<br />
drwxr-xr-x 20 SurveillanceStation SurveillanceStation 4096 Mar 3 07:17 Terrasse<br />
</pre><br />
<br />
<br></div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Modul_Babble&diff=25576Modul Babble2018-02-28T10:59:19Z<p>Hauswart: /* Installation */</p>
<hr />
<div>{{<br />
Infobox Modul<br />
|ModPurpose=Das Modul stellt eine komfortable Oberfläche bereit, um per Webinterface ein 'Natural Language User Interface' (NLUI) zu konfigurieren. Es stellt auch einen ChatBot zur Verfügung.<br />
|ModType=h<br />
<!-- |ModCategory= (noch?) nicht verwendet --><br />
|ModCmdRef=Babble<br />
|ModForumArea=Unterstuetzende Dienste<br />
|ModTechName=95_Babble.pm<br />
|ModOwner=Prof. Dr. Peter A. Henning<br />
}}<br />
Diese Seite beschreibt die Konfiguration und Verwendung des Moduls 95_Babble.pm.<br />
=Allgemeines=<br />
Das Modul ''95_Babble.pm'' stellt eine komfortable Oberfläche bereit, um per Webinterface ein ''Natural Language User Interface'' (NLUI) zu konfigurieren. <br />
<br />
Darüber hinaus stellt Babble eine Verbindung zu einem RiveScript-Modul her, falls dies in der lokalen Perl-Installation vorhanden ist. RiveScript ist eine einfach Programmiersprache für ChatBots, Babble realisiert also für die Ansprache von FHEM auch einen ChatBot.<br />
<br />
==Funktionsweise==<br />
Babble überprüft einen empfangenen natürlichsprachlichen Satz auf einen darin enthaltenen Orts-Identifikator, sowie auf eine Liste von vordefinierten Verben und Verbteilen. Ein weiteres darin enthaltenes Nomen wird je nach Artikeln und Verben als ''Gerät'' identifiziert. Beispielsweise resultieren die beiden Eingabesätze<br />
* '''Schalte die Beleuchtung in der Sitzgruppe an'''<br />
* '''Beleuchtung in der Sitzgruppe anschalten'''<br />
jeweils im gleichen Ergebnis:<br />
<br />
'''Gerät=licht Ort=sitzgruppe Verb=schalten Ziel=ein'''<br />
<br />
Der Gerätename (auch als Babble-Device bezeichnet) ist ein von der FHEM-Bezeichung unabhängiger Begriff, der aber eindeutig mit einem FHEM-Device verbunden sein muss. also z.B. ''Licht'' für eine Lightscene. <br />
<br />
In einem mehrfach geschachtelten Daten-Hash wird anschließend unter der Adresse<br />
<br />
'''$hash->{DATA}{"command"}{"licht"}{"sitzgruppe"}{"schalten"}{"ein"}'''<br />
<br />
nachgesehen, ob dort ein FHEM-Kommando hinterlegt wurde. Dieses lautet im Beispiel ''set WZ.Scene scene Sitzgruppe'' und schaltet eine entsprechende Lightscene an.<br />
<br />
Sollte kein hinterlegtes FHEM-Kommando gefunden werden, aber das entsprechende Babble-Device bekannt sein, wird vom Modul ein einstellbarer Hilfetext entweder zurückgegeben oder per TTS (Text-to-Speech) ausgegeben.<br />
<br />
In allen anderen Fällen wird der Eingabesatz an den ChatBot weitergereicht (wenn dieser nicht explizit blockiert wurde).<br />
<br />
===Beispiel-Dialog 1 (lang)===<br />
User: "Hallo" => Babble: "Hallo, ich bin Jeannie. Wer bist Du ?" (Hier antwortet der ChatBot, weil der unvollständige Eingangssatz nicht mit einem Kommando belegt ist)<br />
<br />
User: "Ich bin Peter." => Babble: "Schoen, Dich kennenzulernen, Peter!" (Hier antwortet wieder der ChatBot)<br />
<br />
User: "Was kannst Du für mich tun ?" => Babble: "Ich kann für Dich das Haus steuern." (Hier antwortet wieder der ChatBot)<br />
<br />
User: "Was kannst Du steuern ?" => Babble: "Ich kenne die Geräte Licht, ....." (Hier antwortet wieder der ChatBot, holt sich aber die Liste der Geräte aus den Babble-Daten)<br />
<br />
User: Wie kannst Du Licht steuern => Babble: "Sprich: Licht, gefolgt von einer Ortsangabe und dem Wort an oder aus" (Hier antwortet wieder der ChatBot, indem er den Hilfetext für das Gerät ''Licht'' von Babble holt)<br />
<br />
User: "Welche Orte kennst Du ?" => Babble: "Ich kenne die Orte Wohnzimmer, ....." (Hier antwortet wieder der ChatBot, holt sich aber die Liste der Orte aus den Babble-Daten)<br />
<br />
User: Schalte das Licht in der Sitzgruppe an. => Babble sagt nun gar nichts mehr, sondern schaltet das Licht in der Sitzgruppe an.<br />
<br />
==Geräte==<br />
Die Verbindung von (Babble-)Gerätenamen mit real existierenden FHEM-Devices erfolgt im unteren Bereich des Web-Frontends. Solche Geräte können entweder ''lokal'' sein, (also derselben FHEM-Instanz angehören, wie das Babble-Device). Oder sie sind ''entfernte Geräte (''remote''). <br />
* Lokale Geräte sind dadurch gekennzeichnet, dass in ihrem FHEM-Device das Attribut '''babbleDevice''' auf den Wert des gewünschten Gerätenamens gesetzt wird (siehe Abschnitt Vorarbeiten). <br />
** Solche lokalen Geräte werden automatisch (d.h. ohne weitere nötige Vorarbeiten) in der Babble-Übersicht angezeigt.<br />
* Entfernte Geräte liegen in einer anderen FHEM-Instanz. Sie müssen im Attribut '''babbleDevices''' des Babble-Devices angegeben werden.<br />
**In der gegenwärtigen ersten Fassung des Moduls können drei solche anderen FHEM-Instanzen angegeben werden, dazu müssen die Attribute '''remoteFHEM(1|2|3)''' '''remoteFunc(1|2|3)''' gesetzt werden. Bei der tatsächlichen Ausführung eines Befehls (siehe Abschnitt Nutzung) werden diese Attribute berücksichtigt<br />
==Nutzung==<br />
Zur Nutzung durch beliebige andere FHEM-Module muss nur das Perl-Unterprogramm<br />
Babble_DoIt("Babble","<zu analysierender Satz>"[,parm0,parm1,...])<br />
aufgerufen werden (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen). Die Anzahl der Parameter beim Aufruf ist nicht festgelegt, es kann eine beliebige Anzahl von Parametern im Aufruf angegeben werden.<br />
<br />
Bei der semantischen Analyse werden identifiziert<br />
* ein (Babble-)Gerätename ''device''<br />
* eine Ortsangabe ''place'', diese darf auch leer bleiben (abgespeichert als Wert ''none'')<br />
* ein Verb ''verb'' in der Infinitiv-Form<br />
* eine Zielvariable, ggf. ein Reading ''target''<br />
* ein Zielwert ''value''<br />
Wird ein natürlichsprachlicher Satz korrekt interpretiert und ein dazu hinterlegtes Kommando (gespeichert im Babble-Hash $hash->{DATA}{"command"}) gefunden, werden in diesem Substitutionen durchgeführt.<br />
* der String $VALUE wird durch den Zielwert ''value'' ersetzt.<br />
* ein String $PARM[0|1|2..] wird durch den beim Aufruf übergebenen Wert parm0, parm1,... ersetzt.<br />
Durch diesen Mechanismus kann man den auszuführenden Kommandos verschiedene Parameter mitgeben.<br />
<br />
Anschließend wird dieses Kommando ausgeführt. Vor der Ausführung <br />
* Bei lokalen (Babble-)Geräten wird im Modul einfach <br />
fhem(<Kommando>)<br />
ausgeführt.<br />
* Bei entfernten (Babble-)Geräten gibt es zwei Möglichkeiten:<br />
** Wurde nur die IP-Adresse der entfernten FHEM-Instanz (im Attribut remoteFHEM(1|2|3)) angegeben, erfolgt die Ausführung durch den HTTP-Request<br />
http://<IP-Adresse:Port>/fhem?XHR=1&cmd.<FHEM-Device>=<Kommando><br />
** Achtung: Wenn hierbei die entfernte FHEM-Instanz durch ein csrfToken geschützt ist, oder dieses sich bei jedem Neustart der externen FHEM-Instanz verändert, muss Babble dieses Token natürlich kennen. Mit dem Befehl<br />
get Babble tokens<br />
werden diese csrfToken für alle bei Babble gemeldeten externen FHEM-Instanzen geholt. Wer dieses manuelle Neuholen vermeiden möchte, sollte bitte ein festes csrfToken für die entfernte FHEM-Instanz definieren. Das csrfToken wird natürlich nur benötigt, wenn keine entsprechende remoteFunc (siehe entsprechendes Attribut) verwendet wird.<br />
** Wurde zusätzlich zur IP-Adresse der entfernten FHEM-Instanz ein Funktionsname (im Attribute remoteFunc(1|2|3)) angegeben, erfolgt die Ausführung durch den Aufruf der Funktion<br />
<remoteFunc(1|2|3)>("<Kommando>")<br />
<br />
===Hilfetexte===<br />
Wird zu einem Device bei der entsprechenden Kombination aus Ortsangabe, Verb und Ziel kein hinterlegtes Kommando gefunden, kommt es zu einem anderen Ablauf.<br />
* Falls der ChatBot aktiv ist (d.h. das RiveScript-Modul muss installiert sein und darf nicht mit dem Attribut '''noChatBot=1''' blockiert werden), wird der gesamte Eingabesatz an diesen ChatBot weitergeleitet. Dieser liefert in jedem Fall eine Antwort, diese Antwort wird an Stelle des Parameters $HELP in das unter dem Attribut '''helpFunc''' hinterlegte FHEM-Kommando substituiert und dieses ausgeführt.<br />
* Falls der ChatBot nicht aktiv ist (d.h., entweder ist das RiveScript-Modul nicht installiert oder wurde durch das Attribut '''noChatBot=1''' blockiert), überprüft Babble, ob wenigstens ein Babble-Device erkannt wurde. Wenn ja, wird der diesem Babble-Device zugeordnete Hilfetext an Stelle des Parameters $HELP in das unter dem Attribut '''helpFunc''' hinterlegte FHEM-Kommando substituiert und dieses ausgeführt.<br />
In beiden Fällen werden in der '''helpFunc'''-Funktion auch die Parameter $PARM(0|1|2|...) durch die Werte ersetzt, die beim Aufruf der '''DoIt'''-Funktion übergeben wurden.<br />
<br />
Beispielsweise kann man mit der Hinterlegung von<br />
attr Babble helpFunc {speak('$PARM0','$HELP')}<br />
dafür sorgen, dass die Perl-Funktion speak mit dem entsprechenden Hilfetext ausgeführt wird. Also resultiert in diesem Fall<br />
Babble_DoIt("Babble","<zu analysierender Satz>",parm0[,parm1,...]) -> speak("parm0","<Antwort des ChatBot>")<br />
bzw.<br />
Babble_DoIt("Babble","<zu analysierender Satz>",parm0[,parm1,...]) -> speak("parm0","<Hilfetext für das betreffende Device>")<br />
<br />
===Test===<br />
Zum Test der durch beliebige andere FHEM-Module muss nur das Perl-Unterprogramm<br />
Babble_TestIt("Babble","<zu analysierender Satz>",<exec-Flag>,[,parm0,parm1,...])<br />
aufgerufen werden (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen). Die Anzahl der Parameter beim Aufruf ist nicht festgelegt, es kann eine beliebige Anzahl von Parametern im Aufruf angegeben werden. <br />
* Wenn <exec-Flag>==1 ist, wird zusätzlich zur Ausgabe des Analysestrings auch noch das zugehörige Kommando ausgeführt.<br />
* Ansonsten erfolgt nur die Ausgabe des Analysestrings.<br />
Neben der Möglichkeit eines Online-Tests mit beliebigen Sätzen besteht auch ncoh die Möglichkeit zum Selbsttest des Moduls. Dazu ruft man den Befehl<br />
set Babble test<br />
auf. In der Ausgabe sieht man eine Vielzahl von Beispielsätzen und kann überprüfen, ob diese korrekt analysiert werden.<br />
<br />
=Babble-Device=<br />
==Vorarbeiten==<br />
Will man ''lokale'' (d.h. in derselben FHEM-Instanz befindliche) Devices per Babble ansteuern, muss man vorher im Device ''global'' dem Attribut ''userAttr'' ein neues global verfügbares Attribut ''babbleDevice'' hinzufügen. Dieses wird damit für jedes FHEM-Device setzbar.<br />
==Installation==<br />
Durch den normalen Update-Mechanismus wird das Modul 95_Babble.pm in den Modulordner installiert, sowie die Datei babble.js in /fhem/www/pgm2. Installationsvoraussetzung ist das Modul JSON.<br />
<br />
'''Achtung, nur wer den ChatBot nutzen möchte''', sollte das Perl-Modul RiveScript installieren, entweder durch Download von [https://github.com/aichaos/rivescript-perl github], oder via CPAN (<code>cpan RiveScript</code>)<br />
Zusätzlich zu diesem Perl-Modul benötigt man dann noch RiveScript-Dateien (Endung .rive). Babble erzeugt einen RiveScript-Interpreter, dieser sucht seine Konfigurationsdateien (unter Linux) im Verzeichnis ''/opt/fhem/rivescript''. Die benötigten RiveScript-Dateien befinden sich im Contrib-Ordner [https://svn.fhem.de/trac/browser/trunk/fhem/contrib/Babble] und können folgendermassen direkt aus dem SVN kopiert werden:<br />
<br \><code>cd /opt/fhem && mkdir rivescript && cd rivescript && wget https://svn.fhem.de/trac/export/HEAD/trunk/fhem/contrib/Babble/begin.rive && wget https://svn.fhem.de/trac/export/HEAD/trunk/fhem/contrib/Babble/general.rive</code><br />
<br />
Ein Tutorial für RiveScript findet man [https://www.rivescript.com/docs/tutorial hier].<br />
<br />
==Definition==<br />
Das Babble-Device - hier mit dem Namen ''Babble'' versehen - selbst wird über<br />
define Babble Babble<br />
definiert. Diese Definition legt einen versteckten Raum "babbleRoom" 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 ''Babble'' (eben der genannte Weblink) im oberen Menü des Webinterfaces wird dieser versteckte Raum angezeigt. Er enthält an erster Stelle das Babble-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 Babble-Device kennt die folgenden Set-Befehle (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen):<br />
set Babble locked | unlocked<br />
Sperre oder entsperre das Überschreiben der persistenten Daten, siehe [[#Sperrung | Sperrung]]. <br />
'''TIPP:''' Diese Sperre sollte bei Experimenten immer gesetzt sein.<br />
set Babble save | restore<br />
Speichere die Daten persistent, oder hole sie aus der betreffenden Datei ''babbleFile'' (Achtung für Nutzer der configdb: Das File wird in der Datenbank abgelegt, nicht im Dateisystem).<br />
set Babble rivereload<br />
Erzeuge eine neue Instanz des RiveScript Interpreters und lese die Konfigurationsdaten neu ein.<br />
set Babble test<br />
Lasse eine interne Testsuite von Erkennungssätzen durchlaufen<br />
<br />
==Get-Befehle==<br />
Das Babble-Device kennt die folgenden Get-Befehle (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen):<br />
get Babble version<br />
Gibt die Versionsnummer des Moduls zurück<br />
<br />
==Attribute==<br />
Das Babble-Device benötigt zum Funktionieren unbedingt ein paar wichtige Attribute mit Wortlisten. Bei der ersten Definition sollten diese automatisch belegt werden, können aber jederzeit geändert werden.<br />
*'''babblePlaces''' ist eine durch Leerzeichen separierte Liste von Orts-Identifikatoren, die in der Sprachsteuerung erkannt werden sollen. Die in FHEM bekannten ''Rooms''=Räume werden ebenfalls als Ortsbezeichnungen zur Verfügung gestellt und brauchen nicht in dieser Liste aufzutauchen.<br />
*'''babbleNotPlaces''' ist eine durch Leerzeichen separierte Liste von FHEM-Räumen, die ''nicht'' als Orts-Indentifikatoren erkannt werden sollen.<br />
*'''babbleStatus''' ist eine durch Leerzeichen separierte Liste von Status-Identifikatoren, also Nomen, die den Status eines Untersystems wiedergeben. Beispiel: ''Status Wert Wetter Zeit''<br />
*'''babblePrepos''' ist eine durch Leerzeichen separierte Liste von Präpositionen. Beispiel: ''von vom des der in im auf bei am''<br />
*'''babbleTimes''' ist eine durch Leerzeichen separierte Liste von Zeit-Adverbien, die eine Zeitangabe eines Untersystems signalisieren. Beispiel: ''heute morgen übermorgen nacht''<br />
*'''babbleQuests''' ist eine durch Leerzeichen separierte Liste von Frage-Adverbien. Beispiel: ''wie wo wann''<br />
*'''babbleArticles''' ist eine durch Leerzeichen separierte Liste von Artikeln. Beispiel: ''der die das den des dem zur''<br />
*'''babbleVerbs''' ist eine durch Leerzeichen separierte Liste von Verbengruppen, die jeweils aus kommagetrennten Variationen und Konjugationen sowie einem davon per ':' getrennten Infinitiv bestehen. Beispiel: ''schalt,schalte:schalten mach,machs,mache:machen öffne:öffnen schließe,schließ:schließen''<br />
*'''babbleVerbParts''' ist eine durch Leerzeichen separierte Liste von Verbteilen, die den durch das grundlegende Tun (beschrieben durch ein Verb, z.B. ''schließen'') erreichten Zustand festlegen (z.B. ''zu'' in zuschließen und ''auf'' in aufschließen). Beispiel für diese Liste: ''zu auf ent wider ein an aus ab um''<br />
*'''babbleWrites''' ist eine durch Leerzeichen separierte Liste, die spezielle Verben enthält, die mit Schreiboperationen befasst sind. Beispiel: ''sagen senden hinzufügen entfernen ändern löschen''<br />
<br />
*'''helpFunc''' ist ein FHEM-Kommando, das aufgerufen wird, wenn zu einem Eingabesatz zwar ein Device, aber kein passendes Kommando gefunden wird. Siehe betreffenden Abschnitt unter Benutzung.<br />
*'''testParm(0|1|2|3)''' sind Attribute, die bei reinen Tests von Babble-Erkennungen an Stelle der Parameter $PARM(0|1|2|3) eingesetzt werden.<br />
<br />
*'''noChatBot''' muss auf 1 gesetzt werden, wenn zwar RiveScript als Modul im System vorhanden ist, der ChatBot aber nicht genutzt werden soll.<br />
<br />
*'''babbleIds''' ist eine durch Leerzeichen separierte Liste von Namen, unter denen Babble selbst angesprochen werden kann<br />
*'''babblePreSubs''' ist eine durch Leerzeichen separierte Liste von regulären Ausdrücken und Ersetzungsstrings, diese sind jeweils durch ''':''' getrennt. Diese Substitutionen werden vor der Normalisierung des Eingabesatzes angewandt. Leerzeichen in den regulären Ausdrücken oder den Ersetzungsstrings müssen im Attribut als ''\s'' angegeben werden.<br />
<regexp1>:<ersetzung1> <regexp2>:<ersetzung2> ...<br />
*'''remoteFHEM(0|1|2|3)''' ist die IP-Adresse (+ Port) einer entfernten FHEM-Instanz. Username und Passwort müssen ggf. ebenfalls angegeben werden, im Format <user>:<password>@<host>:<port><br />
*'''remoteToken(0|1|2|3)''' ist der csrf-Token einer entfernten FHEM-Instanz, siehe [[Modul_Babble#Nutzung|Nutzung]]<br />
*'''remoteFunc(0|1|2|3)''' ist der Name einer Perl-Funktion, die aufgerufen wird, um die entfernte FHEM-Instanz anzusprechen. Hierbei kann beispielsweise das Modul RFHEM oder das Modul FHEM2FHEM eingesetzt werden. Die Angabe dieser Funktion ist optional - verzichtet man darauf, wird Babble versuchen, die entfernten FHEM-Devices durch einfache Web-Aufrufe zu steuern (und dafür wird natürlich der csrf-Token benötigt). <br />
<br />
*'''babbleDevices''' ist eine durch Leerzeichen separierte Liste von (''remote''-)Device-Identifikatoren in der Form <br />
<Babble Devicename>:<FHEM-Devicename>:<Ziffer> <Babble Devicename>:<FHEM-Devicename>:<Ziffer> ... <Babble Devicename>:<FHEM-Devicename>:<Ziffer><br />
**Als Ziffer sind die Werte 0,1,2,3 erlaubt, sie teilen Babble mit, um welche der gegenwärtig möglichen vier verschiedenen entfernten FHEM-Instanzen (siehe Attribut remoteFHEM) es sich handelt.<br />
**Der Babble Devicename darf ein '''*'''-Zeichen enthalten. Ist dies der Fall, wird der Babble Devicename als regulärer Ausdruck interpretiert, in dem '''*''' durch '''(.*)''' ersetzt wird. Wenn Babble nun mit einem Satz aufgerufen wird, dessen Device-Teil auf diesen Ausdruck passt, wird die entsprechende Zeichengruppe in den Parameter ''$STAR'' übernommen. Taucht ''$STAR'' nun in der Kommandosequenz auf, wird dies durch den aktuellen Wert der Zeichengruppe ersetzt. Beispiel: der Babble-Devicename im Attribut sei ''*liste''. Wird nun im zu interpretierenden Satz der Devicename ''Einkaufsliste'' erkannt, enthält ''$STAR'' den Wert ''Einkaufs''. Im FHEM-Kommando, das Babble ausführt, wird ''$STAR'' dann durch ''Einkaufs'' ersetzt.<br />
<br />
*'''linkname''' ist der Name für den Link im FHEM-Menü. Default: ''Babble''.<br />
*'''hiddenroom''' ist der Name für den versteckten Raum, der das Babble-Device enthält. Default: ''babbleRoom''<br />
*'''lockstate''' ist der Sperrzustand für das Device, siehe [[#Sperrung | Sperrung]]<br />
<br />
=Webinterface=<br />
In diesem Abschnitt wird die Bedienung des Webinterfaces und damit die Konfiguration des NLUI beschrieben. Um sie zu erreichen, klickt man auf den Begriff ''Babble'' im oberen Menü des Webinterfaces.<br />
==Babble Test==<br />
In diesem Teil des Webinterfaces kann ein Testsatz eingegeben werden. Durch anklicken des Buttons ''Test'' wird dieser analysiert und das Resultat der Analyse unmittelbar darunter angezeigt. Ist bereits ein FHEM-Kommando dafür definiert (siehe übernächsten Abschnitt), wird dieses ebenfalls angezeigt. Wenn man vorher die Checkbox ''Ausführung'' setzt, wird dieses FHEM-Kommando auch ausgeführt.<br />
<br />
[[Datei:Babble_Test.png|600px|]]<br />
<br />
==Babble Orte und Babble Verben==<br />
Hier können im oberen Bereich zusätzliche Orts-Identifikatoren angegeben und mit Hilfe des Buttons ''Hinzufügen'' dem Attribut '''babblePlaces''' hinzugefügt werden. Wählt man stattdessen einen bereits definierten Orts-Identifikator aus, verändert sich der Button in einen ''Entfernen''-Button, zusätzlich erscheint ein Button zum ''Abbruch''. <br />
<br />
Hier können im unteren Bereich zusätzliche Verbengruppen angegeben und mit Hilfe des Buttons ''Hinzufügen'' dem Attribut '''babbleVerbs''' hinzugefügt werden. Wählt man stattdessen ein bereits definiertes Verb aus, verändert sich der Button in einen ''Entfernen''-Button, zusätzlich erscheinen ein Button zum ''Ändern'' und zum ''Abbruch''. <br />
<br />
[[Datei:Babble_Places.png|600px|]]<br />
<br />
==Babble Devices==<br />
In diesem Bereich können mit Dropdown-Listen die bekannten Orte, Verben, und Zielzustände ausgewählt werden, die in der semantischen Analyse erkannt werden. Zusätzliche Zeilen können mit dem Button ''Hinzufügen'' gewonnen werden, alle bis auf die erste Zeile für jedes Device können entfernt werden. <br />
<br />
In der ersten Zeile sollte ein Hilfetext eingetragen werden - dieser wird ausgegeben, wenn für dieses Device keine Kombination aus Raum, Verb und Ziel erkannt worden ist. Für neue Devices wird ein Vorschlag geliefert.<br />
<br />
Im rechten Feld wird dann das auszuführende FHEM-Kommando eingetragen. <br />
* Perl-Aufrufe werden dabei wie üblich in '''{..}''' Klammern eingeschlossen.<br />
* '''Achtung:''' Derzeit noch doppelte Anführungszeichen vermeiden, nur einfache Anführungszeichen sind erlaubt.<br />
<br />
[[Datei:Babble_Devices.png|600px|]]<br />
<br />
===Gruppierung===<br />
Mit der Spracheingabe können ''verschiedene FHEM-Devices mit dem gleichen Babble-Device'' adressiert werden. Dafür müssen lediglich Babble-Devicenamen vergeben werden, die sich durch ein angehängtes <br />
_<Ziffern><br />
voneinander unterscheiden. Beispiel<br />
* Ein entferntes FHEM-Device WZ.Scene (auf der entfernten FHEM-Instanz Nr. 1) wird im Attribut babbleDevices mit dem Babble-Devicenamen ''Licht'' definiert:<br />
attr Babble babbleDevices WZ.Scene:Licht:1<br />
* Ein lokales FHEM-Device Schlafzimmerlampe erhält selbst ein Attribut <br />
attr Schlafzimmerlampe babbleDevice Licht_1<br />
Die beiden werden dann im Webfrontend von Babble direkt untereinander dargestellt, jeweils mit eigenem Hilfetext. Für den Zweck der Konfiguration sind sie dann unterschiedliche Geräte (so, wie es ja auch semantisch richtig ist). Bei der Verarbeitung eines Eingabesatzes werden aber '''beide''' Geräte durch den Devicenamen ''Licht'' adressiert, d.h. Babble geht alle intern gespeicherten Geräte mit den Babble-Devicenamen ''Licht'', ''Licht_<Ziffern>'' durch und führt das erste passende Kommando aus.<br />
<br />
=Anwendungsbeispiele=<br />
==Temperatur abfragen==<br />
Im Beispiel gehen wir davon aus, dass es ein dummy-Device ''tempProfileC'' mit verschiedenen userReadings gibt, z.B. steht ''WZ.T'' für die Temperatur im Wohnzimmer.<br />
<br />
[[Datei:Babble_Temperatur.png|400px|]]<br />
<br />
Dieses dummy-Device erhält nun den Attributwert <br />
attr tempProfileC babbleDevice Temperatur<br />
Damit erscheint dieses Device mit FHEM-Devicename ''tempProfileC'' und Babble-Devicename ''Temperatur'' in der Liste der Babble-Devices. Im nächsten Schritt müssen dafür Kommandos angelegt werden. Für das Beispiel wollen wir die Temperatur im Schlafzimmer und im Wohnzimmer abfragen. Dazu müssen diese beiden Orte der Liste ''babblePlaces'' hinzugefügt werden, das geht im Webfrontend von Babble.<br />
<br />
Als erstes wollen wir die Frage stellen: '''Wie ist die Temperatur im Schlafzimmer'''. Babble ist derzeit intern so konfiguriert, dass eine Frage "wie ist" mit dem Verb ''sagen'' assoziiert wird. Weil ein konkretes Ziel nicht genannt wurde, setzt Babble als Ziel der Abfrage den ''Status'' des Gerätes ein. Nötig sind also die beiden Einträge<br />
$hash->{DATA}{"command"}{"temperatur"}{"schlafzimmer"}{"sagen"}{"status"} = <1. Kommando zur Ausgabe><br />
$hash->{DATA}{"command"}{"temperatur"}{"wohnzimmer"}{"sagen"}{"status"} = <2. Kommando zur Ausgabe><br />
Alternativ kann man auch den Befehl erteilen '''Sage den Wert der Temperatur im Schlafzimmer'''. Hier wird spezifisch der ''Wert'' abgefragt, sinnvoll sind also zwei weitere Einträge mit denselben Ausgaben<br />
$hash->{DATA}{"command"}{"temperatur"}{"schlafzimmer"}{"sagen"}{"wert"} = <1. Kommando zur Ausgabe><br />
$hash->{DATA}{"command"}{"temperatur"}{"wohnzimmer"}{"sagen"}{"wert"} = <2. Kommando zur Ausgabe><br />
Auch diese beiden Einträge lassen sich komfortabel über das Webfrontend von Babble machen. Für das Beispiel verwenden wir eine Perl-Funktion namens ''speak(<speechdevice>,<text>)'', die nichts weiter macht, als auf einem der dazu fähigen Devices (hier ''speechdevice'') die zuständige TTS (Text-to-Speech) Funktion aufzurufen. <br />
<1. Kommando zur Ausgabe> = {speak($PARM0,'Die Temperatur im Schlafzimmer beträgt '.ReadingsVal('tempProfileC','SZ.T','').' Grad')}<br />
<2. Kommando zur Ausgabe> = {speak($PARM0,'Die Temperatur im Wohnzimmer beträgt '.ReadingsVal('tempProfileC','WZ.T','').' Grad')}<br />
Der Parameter ''$PARM0'' wird dabei durch denjenigen ersten Parameter ersetzt, den die Erkennungsfunktion mitgeliefert bekommen hat (siehe oben).<br />
<br />
[[Datei:Babble_Temperatur2.png|800px|]]<br />
<br />
Nach dem ''Sichern'' steht das zur Verfügung. Übergibt man an Babble den Textstring '''Wie ist die Temperatur im Schlafzimmer''', wird auf den Sprachausgabedevices z.B. der Text ausgegeben '''Die Temperatur im Schlafzimmer beträgt 21 Punkt 4 Grad'''. Schönheitsfehler ist noch, dass der englische Dezimalpunkt mit ausgegeben wird. Das lässt sich aber problemlos beheben, indem die Perl-Funktion ''speakEG'' etwas aufgebohrt wird. Durch einen einfachen regulären Ausdruck kann man jeden Punkt zwischen Ziffern durch ein Komma ersetzen lassen.<br />
<br />
==Weckzeit setzen==<br />
Im Beispiel gehen wir davon aus, dass es ein FHEM-dummy-Device ''Alexa.Weckzeit'' gibt, dieses dummy-Device erhält nun den Attributwert <br />
attr Alexa.Weckzeit babbleDevice Wecker<br />
Damit erscheint dieses Device mit FHEM-Devicename ''Alexa.Weckzeit'' und Babble-Devicename ''Wecker'' in der Liste der Babble-Devices. Im nächsten Schritt müssen dafür Kommandos angelegt werden. <br />
<br />
Als Sprachbefehl soll verwendet werden '''Wecken um 18 Uhr 27'''. Babble ist derzeit intern so konfiguriert, dass eine dem Teilstring ''weck'' versehene Sprachnachricht automatisch mit dem Device ''Wecker'' und dem Verb ''stellen'' assoziiert wird. Nötig ist also erstens der Eintrag des Verbs ''stellen'' in die Liste der Verben (geht mit dem Webfrontend) sowie ein Eintrag<br />
$hash->{DATA}{"command"}{"wecker"}{"none"}{"stellen"}{"auf"} = <Kommando zum Stellen><br />
Auch dieser Eintrag lässt sich komfortabel über das Webfrontend von Babble machen. Als Kommando zum Stellen trägt man nun ein<br />
set Weckzeit $VALUE<br />
Der String $VALUE wird bei der Ausführung durch den Value-Parameter ersetzt, den Babble bei der semantischen Analyse herausfiltert, also im Beispiel '''18:27 Uhr'''. Aus dem Weckzeit-Dummy kann man nun diese Weckzeit mit einem einfachen notify auf den "echten" Wecker übertragen (natürlich ein FHEM-Device...)<br />
<br />
[[Datei:Babble_Weckzeit.png|800px|]]<br />
<br />
==Wetter abfragen==<br />
In diesem Beispiel gehen wir davon aus, das in dem FHEM-Device ''wunderground'' drei Readings vorliegen:<br />
*fc0_message ist die Wettervorhersage für heute<br />
*fc1_message ist die Wettervorhersage für morgen<br />
*fc2_message ist die Wettervorhersage für übermorgen<br />
Das Device erhält nun den Attributewert<br />
attr wunderground babbleDevice Wetter<br />
Damit erscheint dieses Device mit FHEM-Devicename ''wunderground'' und Babble-Devicename ''Wetter'' in der Liste der Babble-Devices. Im nächsten Schritt müssen dafür Kommandos angelegt werden. Da bei der Analyse der Zeitwert (''heute'',''morgen'' oder ''übermorgen'') in der Variablen '''$VALUE''' abgelegt wird, reichen zwei Kommands aus, indem die Fallunterscheidung untergebracht wird:<br />
$hash->{DATA}{"command"}{"wetter"}{"none"}{"sagen"}{"wetter"} = <Kommando zur Abfrage><br />
$hash->{DATA}{"command"}{"wetter"}{"none"}{"sagen"}{"status"} = <Kommando zur Abfrage><br />
Auch dieser Eintrag lässt sich komfortabel über das Webfrontend von Babble machen. Als Kommando zur Abfrage trägt man nun in beide Felder ein:<br />
{speakEG(ReadingsVal('wunderground','fc'.(('$VALUE' eq 'übermorgen')?'2':(('$VALUE' eq 'morgen')?'1':'0')).'_message',' '))}<br />
Für das Beispiel verwenden wir eine Perl-Funktion namens ''speak(<speechdevice>,<text>)'', die nichts weiter macht, als auf einem der dazu fähigen Devices (hier ''speechdevice'') die zuständige TTS (Text-to-Speech) Funktion aufzurufen. Der Parameter ''$PARM0'' wird dabei durch denjenigen ersten Parameter ersetzt, den die Erkennungsfunktion mitgeliefert bekommen hat (siehe oben).<br />
<br />
[[Datei:Babble_Wetter.png|800px|]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Modul_Babble&diff=25575Modul Babble2018-02-28T10:58:00Z<p>Hauswart: /* Installation */</p>
<hr />
<div>{{<br />
Infobox Modul<br />
|ModPurpose=Das Modul stellt eine komfortable Oberfläche bereit, um per Webinterface ein 'Natural Language User Interface' (NLUI) zu konfigurieren. Es stellt auch einen ChatBot zur Verfügung.<br />
|ModType=h<br />
<!-- |ModCategory= (noch?) nicht verwendet --><br />
|ModCmdRef=Babble<br />
|ModForumArea=Unterstuetzende Dienste<br />
|ModTechName=95_Babble.pm<br />
|ModOwner=Prof. Dr. Peter A. Henning<br />
}}<br />
Diese Seite beschreibt die Konfiguration und Verwendung des Moduls 95_Babble.pm.<br />
=Allgemeines=<br />
Das Modul ''95_Babble.pm'' stellt eine komfortable Oberfläche bereit, um per Webinterface ein ''Natural Language User Interface'' (NLUI) zu konfigurieren. <br />
<br />
Darüber hinaus stellt Babble eine Verbindung zu einem RiveScript-Modul her, falls dies in der lokalen Perl-Installation vorhanden ist. RiveScript ist eine einfach Programmiersprache für ChatBots, Babble realisiert also für die Ansprache von FHEM auch einen ChatBot.<br />
<br />
==Funktionsweise==<br />
Babble überprüft einen empfangenen natürlichsprachlichen Satz auf einen darin enthaltenen Orts-Identifikator, sowie auf eine Liste von vordefinierten Verben und Verbteilen. Ein weiteres darin enthaltenes Nomen wird je nach Artikeln und Verben als ''Gerät'' identifiziert. Beispielsweise resultieren die beiden Eingabesätze<br />
* '''Schalte die Beleuchtung in der Sitzgruppe an'''<br />
* '''Beleuchtung in der Sitzgruppe anschalten'''<br />
jeweils im gleichen Ergebnis:<br />
<br />
'''Gerät=licht Ort=sitzgruppe Verb=schalten Ziel=ein'''<br />
<br />
Der Gerätename (auch als Babble-Device bezeichnet) ist ein von der FHEM-Bezeichung unabhängiger Begriff, der aber eindeutig mit einem FHEM-Device verbunden sein muss. also z.B. ''Licht'' für eine Lightscene. <br />
<br />
In einem mehrfach geschachtelten Daten-Hash wird anschließend unter der Adresse<br />
<br />
'''$hash->{DATA}{"command"}{"licht"}{"sitzgruppe"}{"schalten"}{"ein"}'''<br />
<br />
nachgesehen, ob dort ein FHEM-Kommando hinterlegt wurde. Dieses lautet im Beispiel ''set WZ.Scene scene Sitzgruppe'' und schaltet eine entsprechende Lightscene an.<br />
<br />
Sollte kein hinterlegtes FHEM-Kommando gefunden werden, aber das entsprechende Babble-Device bekannt sein, wird vom Modul ein einstellbarer Hilfetext entweder zurückgegeben oder per TTS (Text-to-Speech) ausgegeben.<br />
<br />
In allen anderen Fällen wird der Eingabesatz an den ChatBot weitergereicht (wenn dieser nicht explizit blockiert wurde).<br />
<br />
===Beispiel-Dialog 1 (lang)===<br />
User: "Hallo" => Babble: "Hallo, ich bin Jeannie. Wer bist Du ?" (Hier antwortet der ChatBot, weil der unvollständige Eingangssatz nicht mit einem Kommando belegt ist)<br />
<br />
User: "Ich bin Peter." => Babble: "Schoen, Dich kennenzulernen, Peter!" (Hier antwortet wieder der ChatBot)<br />
<br />
User: "Was kannst Du für mich tun ?" => Babble: "Ich kann für Dich das Haus steuern." (Hier antwortet wieder der ChatBot)<br />
<br />
User: "Was kannst Du steuern ?" => Babble: "Ich kenne die Geräte Licht, ....." (Hier antwortet wieder der ChatBot, holt sich aber die Liste der Geräte aus den Babble-Daten)<br />
<br />
User: Wie kannst Du Licht steuern => Babble: "Sprich: Licht, gefolgt von einer Ortsangabe und dem Wort an oder aus" (Hier antwortet wieder der ChatBot, indem er den Hilfetext für das Gerät ''Licht'' von Babble holt)<br />
<br />
User: "Welche Orte kennst Du ?" => Babble: "Ich kenne die Orte Wohnzimmer, ....." (Hier antwortet wieder der ChatBot, holt sich aber die Liste der Orte aus den Babble-Daten)<br />
<br />
User: Schalte das Licht in der Sitzgruppe an. => Babble sagt nun gar nichts mehr, sondern schaltet das Licht in der Sitzgruppe an.<br />
<br />
==Geräte==<br />
Die Verbindung von (Babble-)Gerätenamen mit real existierenden FHEM-Devices erfolgt im unteren Bereich des Web-Frontends. Solche Geräte können entweder ''lokal'' sein, (also derselben FHEM-Instanz angehören, wie das Babble-Device). Oder sie sind ''entfernte Geräte (''remote''). <br />
* Lokale Geräte sind dadurch gekennzeichnet, dass in ihrem FHEM-Device das Attribut '''babbleDevice''' auf den Wert des gewünschten Gerätenamens gesetzt wird (siehe Abschnitt Vorarbeiten). <br />
** Solche lokalen Geräte werden automatisch (d.h. ohne weitere nötige Vorarbeiten) in der Babble-Übersicht angezeigt.<br />
* Entfernte Geräte liegen in einer anderen FHEM-Instanz. Sie müssen im Attribut '''babbleDevices''' des Babble-Devices angegeben werden.<br />
**In der gegenwärtigen ersten Fassung des Moduls können drei solche anderen FHEM-Instanzen angegeben werden, dazu müssen die Attribute '''remoteFHEM(1|2|3)''' '''remoteFunc(1|2|3)''' gesetzt werden. Bei der tatsächlichen Ausführung eines Befehls (siehe Abschnitt Nutzung) werden diese Attribute berücksichtigt<br />
==Nutzung==<br />
Zur Nutzung durch beliebige andere FHEM-Module muss nur das Perl-Unterprogramm<br />
Babble_DoIt("Babble","<zu analysierender Satz>"[,parm0,parm1,...])<br />
aufgerufen werden (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen). Die Anzahl der Parameter beim Aufruf ist nicht festgelegt, es kann eine beliebige Anzahl von Parametern im Aufruf angegeben werden.<br />
<br />
Bei der semantischen Analyse werden identifiziert<br />
* ein (Babble-)Gerätename ''device''<br />
* eine Ortsangabe ''place'', diese darf auch leer bleiben (abgespeichert als Wert ''none'')<br />
* ein Verb ''verb'' in der Infinitiv-Form<br />
* eine Zielvariable, ggf. ein Reading ''target''<br />
* ein Zielwert ''value''<br />
Wird ein natürlichsprachlicher Satz korrekt interpretiert und ein dazu hinterlegtes Kommando (gespeichert im Babble-Hash $hash->{DATA}{"command"}) gefunden, werden in diesem Substitutionen durchgeführt.<br />
* der String $VALUE wird durch den Zielwert ''value'' ersetzt.<br />
* ein String $PARM[0|1|2..] wird durch den beim Aufruf übergebenen Wert parm0, parm1,... ersetzt.<br />
Durch diesen Mechanismus kann man den auszuführenden Kommandos verschiedene Parameter mitgeben.<br />
<br />
Anschließend wird dieses Kommando ausgeführt. Vor der Ausführung <br />
* Bei lokalen (Babble-)Geräten wird im Modul einfach <br />
fhem(<Kommando>)<br />
ausgeführt.<br />
* Bei entfernten (Babble-)Geräten gibt es zwei Möglichkeiten:<br />
** Wurde nur die IP-Adresse der entfernten FHEM-Instanz (im Attribut remoteFHEM(1|2|3)) angegeben, erfolgt die Ausführung durch den HTTP-Request<br />
http://<IP-Adresse:Port>/fhem?XHR=1&cmd.<FHEM-Device>=<Kommando><br />
** Achtung: Wenn hierbei die entfernte FHEM-Instanz durch ein csrfToken geschützt ist, oder dieses sich bei jedem Neustart der externen FHEM-Instanz verändert, muss Babble dieses Token natürlich kennen. Mit dem Befehl<br />
get Babble tokens<br />
werden diese csrfToken für alle bei Babble gemeldeten externen FHEM-Instanzen geholt. Wer dieses manuelle Neuholen vermeiden möchte, sollte bitte ein festes csrfToken für die entfernte FHEM-Instanz definieren. Das csrfToken wird natürlich nur benötigt, wenn keine entsprechende remoteFunc (siehe entsprechendes Attribut) verwendet wird.<br />
** Wurde zusätzlich zur IP-Adresse der entfernten FHEM-Instanz ein Funktionsname (im Attribute remoteFunc(1|2|3)) angegeben, erfolgt die Ausführung durch den Aufruf der Funktion<br />
<remoteFunc(1|2|3)>("<Kommando>")<br />
<br />
===Hilfetexte===<br />
Wird zu einem Device bei der entsprechenden Kombination aus Ortsangabe, Verb und Ziel kein hinterlegtes Kommando gefunden, kommt es zu einem anderen Ablauf.<br />
* Falls der ChatBot aktiv ist (d.h. das RiveScript-Modul muss installiert sein und darf nicht mit dem Attribut '''noChatBot=1''' blockiert werden), wird der gesamte Eingabesatz an diesen ChatBot weitergeleitet. Dieser liefert in jedem Fall eine Antwort, diese Antwort wird an Stelle des Parameters $HELP in das unter dem Attribut '''helpFunc''' hinterlegte FHEM-Kommando substituiert und dieses ausgeführt.<br />
* Falls der ChatBot nicht aktiv ist (d.h., entweder ist das RiveScript-Modul nicht installiert oder wurde durch das Attribut '''noChatBot=1''' blockiert), überprüft Babble, ob wenigstens ein Babble-Device erkannt wurde. Wenn ja, wird der diesem Babble-Device zugeordnete Hilfetext an Stelle des Parameters $HELP in das unter dem Attribut '''helpFunc''' hinterlegte FHEM-Kommando substituiert und dieses ausgeführt.<br />
In beiden Fällen werden in der '''helpFunc'''-Funktion auch die Parameter $PARM(0|1|2|...) durch die Werte ersetzt, die beim Aufruf der '''DoIt'''-Funktion übergeben wurden.<br />
<br />
Beispielsweise kann man mit der Hinterlegung von<br />
attr Babble helpFunc {speak('$PARM0','$HELP')}<br />
dafür sorgen, dass die Perl-Funktion speak mit dem entsprechenden Hilfetext ausgeführt wird. Also resultiert in diesem Fall<br />
Babble_DoIt("Babble","<zu analysierender Satz>",parm0[,parm1,...]) -> speak("parm0","<Antwort des ChatBot>")<br />
bzw.<br />
Babble_DoIt("Babble","<zu analysierender Satz>",parm0[,parm1,...]) -> speak("parm0","<Hilfetext für das betreffende Device>")<br />
<br />
===Test===<br />
Zum Test der durch beliebige andere FHEM-Module muss nur das Perl-Unterprogramm<br />
Babble_TestIt("Babble","<zu analysierender Satz>",<exec-Flag>,[,parm0,parm1,...])<br />
aufgerufen werden (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen). Die Anzahl der Parameter beim Aufruf ist nicht festgelegt, es kann eine beliebige Anzahl von Parametern im Aufruf angegeben werden. <br />
* Wenn <exec-Flag>==1 ist, wird zusätzlich zur Ausgabe des Analysestrings auch noch das zugehörige Kommando ausgeführt.<br />
* Ansonsten erfolgt nur die Ausgabe des Analysestrings.<br />
Neben der Möglichkeit eines Online-Tests mit beliebigen Sätzen besteht auch ncoh die Möglichkeit zum Selbsttest des Moduls. Dazu ruft man den Befehl<br />
set Babble test<br />
auf. In der Ausgabe sieht man eine Vielzahl von Beispielsätzen und kann überprüfen, ob diese korrekt analysiert werden.<br />
<br />
=Babble-Device=<br />
==Vorarbeiten==<br />
Will man ''lokale'' (d.h. in derselben FHEM-Instanz befindliche) Devices per Babble ansteuern, muss man vorher im Device ''global'' dem Attribut ''userAttr'' ein neues global verfügbares Attribut ''babbleDevice'' hinzufügen. Dieses wird damit für jedes FHEM-Device setzbar.<br />
==Installation==<br />
Durch den normalen Update-Mechanismus wird das Modul 95_Babble.pm in den Modulordner installiert, sowie die Datei babble.js in /fhem/www/pgm2. Installationsvoraussetzung ist das Modul JSON.<br />
<br />
'''Achtung, nur wer den ChatBot nutzen möchte''', sollte das Perl-Modul RiveScript installieren, entweder durch Download von [https://github.com/aichaos/rivescript-perl github], oder via CPAN (''cpan RiveScript'')<br />
Zusätzlich zu diesem Perl-Modul benötigt man dann noch RiveScript-Dateien (Endung .rive). Babble erzeugt einen RiveScript-Interpreter, dieser sucht seine Konfigurationsdateien (unter Linux) im Verzeichnis ''/opt/fhem/rivescript''. Die benötigten RiveScript-Dateien befinden sich im Contrib-Ordner [https://svn.fhem.de/trac/browser/trunk/fhem/contrib/Babble] und können folgendermassen direkt aus dem SVN kopiert werden:<br />
''cd /opt/fhem && mkdir rivescript && cd rivescript && wget https://svn.fhem.de/trac/export/HEAD/trunk/fhem/contrib/Babble/begin.rive && wget https://svn.fhem.de/trac/export/HEAD/trunk/fhem/contrib/Babble/general.rive''<br />
<br />
Ein Tutorial für RiveScript findet man [https://www.rivescript.com/docs/tutorial hier].<br />
<br />
==Definition==<br />
Das Babble-Device - hier mit dem Namen ''Babble'' versehen - selbst wird über<br />
define Babble Babble<br />
definiert. Diese Definition legt einen versteckten Raum "babbleRoom" 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 ''Babble'' (eben der genannte Weblink) im oberen Menü des Webinterfaces wird dieser versteckte Raum angezeigt. Er enthält an erster Stelle das Babble-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 Babble-Device kennt die folgenden Set-Befehle (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen):<br />
set Babble locked | unlocked<br />
Sperre oder entsperre das Überschreiben der persistenten Daten, siehe [[#Sperrung | Sperrung]]. <br />
'''TIPP:''' Diese Sperre sollte bei Experimenten immer gesetzt sein.<br />
set Babble save | restore<br />
Speichere die Daten persistent, oder hole sie aus der betreffenden Datei ''babbleFile'' (Achtung für Nutzer der configdb: Das File wird in der Datenbank abgelegt, nicht im Dateisystem).<br />
set Babble rivereload<br />
Erzeuge eine neue Instanz des RiveScript Interpreters und lese die Konfigurationsdaten neu ein.<br />
set Babble test<br />
Lasse eine interne Testsuite von Erkennungssätzen durchlaufen<br />
<br />
==Get-Befehle==<br />
Das Babble-Device kennt die folgenden Get-Befehle (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen):<br />
get Babble version<br />
Gibt die Versionsnummer des Moduls zurück<br />
<br />
==Attribute==<br />
Das Babble-Device benötigt zum Funktionieren unbedingt ein paar wichtige Attribute mit Wortlisten. Bei der ersten Definition sollten diese automatisch belegt werden, können aber jederzeit geändert werden.<br />
*'''babblePlaces''' ist eine durch Leerzeichen separierte Liste von Orts-Identifikatoren, die in der Sprachsteuerung erkannt werden sollen. Die in FHEM bekannten ''Rooms''=Räume werden ebenfalls als Ortsbezeichnungen zur Verfügung gestellt und brauchen nicht in dieser Liste aufzutauchen.<br />
*'''babbleNotPlaces''' ist eine durch Leerzeichen separierte Liste von FHEM-Räumen, die ''nicht'' als Orts-Indentifikatoren erkannt werden sollen.<br />
*'''babbleStatus''' ist eine durch Leerzeichen separierte Liste von Status-Identifikatoren, also Nomen, die den Status eines Untersystems wiedergeben. Beispiel: ''Status Wert Wetter Zeit''<br />
*'''babblePrepos''' ist eine durch Leerzeichen separierte Liste von Präpositionen. Beispiel: ''von vom des der in im auf bei am''<br />
*'''babbleTimes''' ist eine durch Leerzeichen separierte Liste von Zeit-Adverbien, die eine Zeitangabe eines Untersystems signalisieren. Beispiel: ''heute morgen übermorgen nacht''<br />
*'''babbleQuests''' ist eine durch Leerzeichen separierte Liste von Frage-Adverbien. Beispiel: ''wie wo wann''<br />
*'''babbleArticles''' ist eine durch Leerzeichen separierte Liste von Artikeln. Beispiel: ''der die das den des dem zur''<br />
*'''babbleVerbs''' ist eine durch Leerzeichen separierte Liste von Verbengruppen, die jeweils aus kommagetrennten Variationen und Konjugationen sowie einem davon per ':' getrennten Infinitiv bestehen. Beispiel: ''schalt,schalte:schalten mach,machs,mache:machen öffne:öffnen schließe,schließ:schließen''<br />
*'''babbleVerbParts''' ist eine durch Leerzeichen separierte Liste von Verbteilen, die den durch das grundlegende Tun (beschrieben durch ein Verb, z.B. ''schließen'') erreichten Zustand festlegen (z.B. ''zu'' in zuschließen und ''auf'' in aufschließen). Beispiel für diese Liste: ''zu auf ent wider ein an aus ab um''<br />
*'''babbleWrites''' ist eine durch Leerzeichen separierte Liste, die spezielle Verben enthält, die mit Schreiboperationen befasst sind. Beispiel: ''sagen senden hinzufügen entfernen ändern löschen''<br />
<br />
*'''helpFunc''' ist ein FHEM-Kommando, das aufgerufen wird, wenn zu einem Eingabesatz zwar ein Device, aber kein passendes Kommando gefunden wird. Siehe betreffenden Abschnitt unter Benutzung.<br />
*'''testParm(0|1|2|3)''' sind Attribute, die bei reinen Tests von Babble-Erkennungen an Stelle der Parameter $PARM(0|1|2|3) eingesetzt werden.<br />
<br />
*'''noChatBot''' muss auf 1 gesetzt werden, wenn zwar RiveScript als Modul im System vorhanden ist, der ChatBot aber nicht genutzt werden soll.<br />
<br />
*'''babbleIds''' ist eine durch Leerzeichen separierte Liste von Namen, unter denen Babble selbst angesprochen werden kann<br />
*'''babblePreSubs''' ist eine durch Leerzeichen separierte Liste von regulären Ausdrücken und Ersetzungsstrings, diese sind jeweils durch ''':''' getrennt. Diese Substitutionen werden vor der Normalisierung des Eingabesatzes angewandt. Leerzeichen in den regulären Ausdrücken oder den Ersetzungsstrings müssen im Attribut als ''\s'' angegeben werden.<br />
<regexp1>:<ersetzung1> <regexp2>:<ersetzung2> ...<br />
*'''remoteFHEM(0|1|2|3)''' ist die IP-Adresse (+ Port) einer entfernten FHEM-Instanz. Username und Passwort müssen ggf. ebenfalls angegeben werden, im Format <user>:<password>@<host>:<port><br />
*'''remoteToken(0|1|2|3)''' ist der csrf-Token einer entfernten FHEM-Instanz, siehe [[Modul_Babble#Nutzung|Nutzung]]<br />
*'''remoteFunc(0|1|2|3)''' ist der Name einer Perl-Funktion, die aufgerufen wird, um die entfernte FHEM-Instanz anzusprechen. Hierbei kann beispielsweise das Modul RFHEM oder das Modul FHEM2FHEM eingesetzt werden. Die Angabe dieser Funktion ist optional - verzichtet man darauf, wird Babble versuchen, die entfernten FHEM-Devices durch einfache Web-Aufrufe zu steuern (und dafür wird natürlich der csrf-Token benötigt). <br />
<br />
*'''babbleDevices''' ist eine durch Leerzeichen separierte Liste von (''remote''-)Device-Identifikatoren in der Form <br />
<Babble Devicename>:<FHEM-Devicename>:<Ziffer> <Babble Devicename>:<FHEM-Devicename>:<Ziffer> ... <Babble Devicename>:<FHEM-Devicename>:<Ziffer><br />
**Als Ziffer sind die Werte 0,1,2,3 erlaubt, sie teilen Babble mit, um welche der gegenwärtig möglichen vier verschiedenen entfernten FHEM-Instanzen (siehe Attribut remoteFHEM) es sich handelt.<br />
**Der Babble Devicename darf ein '''*'''-Zeichen enthalten. Ist dies der Fall, wird der Babble Devicename als regulärer Ausdruck interpretiert, in dem '''*''' durch '''(.*)''' ersetzt wird. Wenn Babble nun mit einem Satz aufgerufen wird, dessen Device-Teil auf diesen Ausdruck passt, wird die entsprechende Zeichengruppe in den Parameter ''$STAR'' übernommen. Taucht ''$STAR'' nun in der Kommandosequenz auf, wird dies durch den aktuellen Wert der Zeichengruppe ersetzt. Beispiel: der Babble-Devicename im Attribut sei ''*liste''. Wird nun im zu interpretierenden Satz der Devicename ''Einkaufsliste'' erkannt, enthält ''$STAR'' den Wert ''Einkaufs''. Im FHEM-Kommando, das Babble ausführt, wird ''$STAR'' dann durch ''Einkaufs'' ersetzt.<br />
<br />
*'''linkname''' ist der Name für den Link im FHEM-Menü. Default: ''Babble''.<br />
*'''hiddenroom''' ist der Name für den versteckten Raum, der das Babble-Device enthält. Default: ''babbleRoom''<br />
*'''lockstate''' ist der Sperrzustand für das Device, siehe [[#Sperrung | Sperrung]]<br />
<br />
=Webinterface=<br />
In diesem Abschnitt wird die Bedienung des Webinterfaces und damit die Konfiguration des NLUI beschrieben. Um sie zu erreichen, klickt man auf den Begriff ''Babble'' im oberen Menü des Webinterfaces.<br />
==Babble Test==<br />
In diesem Teil des Webinterfaces kann ein Testsatz eingegeben werden. Durch anklicken des Buttons ''Test'' wird dieser analysiert und das Resultat der Analyse unmittelbar darunter angezeigt. Ist bereits ein FHEM-Kommando dafür definiert (siehe übernächsten Abschnitt), wird dieses ebenfalls angezeigt. Wenn man vorher die Checkbox ''Ausführung'' setzt, wird dieses FHEM-Kommando auch ausgeführt.<br />
<br />
[[Datei:Babble_Test.png|600px|]]<br />
<br />
==Babble Orte und Babble Verben==<br />
Hier können im oberen Bereich zusätzliche Orts-Identifikatoren angegeben und mit Hilfe des Buttons ''Hinzufügen'' dem Attribut '''babblePlaces''' hinzugefügt werden. Wählt man stattdessen einen bereits definierten Orts-Identifikator aus, verändert sich der Button in einen ''Entfernen''-Button, zusätzlich erscheint ein Button zum ''Abbruch''. <br />
<br />
Hier können im unteren Bereich zusätzliche Verbengruppen angegeben und mit Hilfe des Buttons ''Hinzufügen'' dem Attribut '''babbleVerbs''' hinzugefügt werden. Wählt man stattdessen ein bereits definiertes Verb aus, verändert sich der Button in einen ''Entfernen''-Button, zusätzlich erscheinen ein Button zum ''Ändern'' und zum ''Abbruch''. <br />
<br />
[[Datei:Babble_Places.png|600px|]]<br />
<br />
==Babble Devices==<br />
In diesem Bereich können mit Dropdown-Listen die bekannten Orte, Verben, und Zielzustände ausgewählt werden, die in der semantischen Analyse erkannt werden. Zusätzliche Zeilen können mit dem Button ''Hinzufügen'' gewonnen werden, alle bis auf die erste Zeile für jedes Device können entfernt werden. <br />
<br />
In der ersten Zeile sollte ein Hilfetext eingetragen werden - dieser wird ausgegeben, wenn für dieses Device keine Kombination aus Raum, Verb und Ziel erkannt worden ist. Für neue Devices wird ein Vorschlag geliefert.<br />
<br />
Im rechten Feld wird dann das auszuführende FHEM-Kommando eingetragen. <br />
* Perl-Aufrufe werden dabei wie üblich in '''{..}''' Klammern eingeschlossen.<br />
* '''Achtung:''' Derzeit noch doppelte Anführungszeichen vermeiden, nur einfache Anführungszeichen sind erlaubt.<br />
<br />
[[Datei:Babble_Devices.png|600px|]]<br />
<br />
===Gruppierung===<br />
Mit der Spracheingabe können ''verschiedene FHEM-Devices mit dem gleichen Babble-Device'' adressiert werden. Dafür müssen lediglich Babble-Devicenamen vergeben werden, die sich durch ein angehängtes <br />
_<Ziffern><br />
voneinander unterscheiden. Beispiel<br />
* Ein entferntes FHEM-Device WZ.Scene (auf der entfernten FHEM-Instanz Nr. 1) wird im Attribut babbleDevices mit dem Babble-Devicenamen ''Licht'' definiert:<br />
attr Babble babbleDevices WZ.Scene:Licht:1<br />
* Ein lokales FHEM-Device Schlafzimmerlampe erhält selbst ein Attribut <br />
attr Schlafzimmerlampe babbleDevice Licht_1<br />
Die beiden werden dann im Webfrontend von Babble direkt untereinander dargestellt, jeweils mit eigenem Hilfetext. Für den Zweck der Konfiguration sind sie dann unterschiedliche Geräte (so, wie es ja auch semantisch richtig ist). Bei der Verarbeitung eines Eingabesatzes werden aber '''beide''' Geräte durch den Devicenamen ''Licht'' adressiert, d.h. Babble geht alle intern gespeicherten Geräte mit den Babble-Devicenamen ''Licht'', ''Licht_<Ziffern>'' durch und führt das erste passende Kommando aus.<br />
<br />
=Anwendungsbeispiele=<br />
==Temperatur abfragen==<br />
Im Beispiel gehen wir davon aus, dass es ein dummy-Device ''tempProfileC'' mit verschiedenen userReadings gibt, z.B. steht ''WZ.T'' für die Temperatur im Wohnzimmer.<br />
<br />
[[Datei:Babble_Temperatur.png|400px|]]<br />
<br />
Dieses dummy-Device erhält nun den Attributwert <br />
attr tempProfileC babbleDevice Temperatur<br />
Damit erscheint dieses Device mit FHEM-Devicename ''tempProfileC'' und Babble-Devicename ''Temperatur'' in der Liste der Babble-Devices. Im nächsten Schritt müssen dafür Kommandos angelegt werden. Für das Beispiel wollen wir die Temperatur im Schlafzimmer und im Wohnzimmer abfragen. Dazu müssen diese beiden Orte der Liste ''babblePlaces'' hinzugefügt werden, das geht im Webfrontend von Babble.<br />
<br />
Als erstes wollen wir die Frage stellen: '''Wie ist die Temperatur im Schlafzimmer'''. Babble ist derzeit intern so konfiguriert, dass eine Frage "wie ist" mit dem Verb ''sagen'' assoziiert wird. Weil ein konkretes Ziel nicht genannt wurde, setzt Babble als Ziel der Abfrage den ''Status'' des Gerätes ein. Nötig sind also die beiden Einträge<br />
$hash->{DATA}{"command"}{"temperatur"}{"schlafzimmer"}{"sagen"}{"status"} = <1. Kommando zur Ausgabe><br />
$hash->{DATA}{"command"}{"temperatur"}{"wohnzimmer"}{"sagen"}{"status"} = <2. Kommando zur Ausgabe><br />
Alternativ kann man auch den Befehl erteilen '''Sage den Wert der Temperatur im Schlafzimmer'''. Hier wird spezifisch der ''Wert'' abgefragt, sinnvoll sind also zwei weitere Einträge mit denselben Ausgaben<br />
$hash->{DATA}{"command"}{"temperatur"}{"schlafzimmer"}{"sagen"}{"wert"} = <1. Kommando zur Ausgabe><br />
$hash->{DATA}{"command"}{"temperatur"}{"wohnzimmer"}{"sagen"}{"wert"} = <2. Kommando zur Ausgabe><br />
Auch diese beiden Einträge lassen sich komfortabel über das Webfrontend von Babble machen. Für das Beispiel verwenden wir eine Perl-Funktion namens ''speak(<speechdevice>,<text>)'', die nichts weiter macht, als auf einem der dazu fähigen Devices (hier ''speechdevice'') die zuständige TTS (Text-to-Speech) Funktion aufzurufen. <br />
<1. Kommando zur Ausgabe> = {speak($PARM0,'Die Temperatur im Schlafzimmer beträgt '.ReadingsVal('tempProfileC','SZ.T','').' Grad')}<br />
<2. Kommando zur Ausgabe> = {speak($PARM0,'Die Temperatur im Wohnzimmer beträgt '.ReadingsVal('tempProfileC','WZ.T','').' Grad')}<br />
Der Parameter ''$PARM0'' wird dabei durch denjenigen ersten Parameter ersetzt, den die Erkennungsfunktion mitgeliefert bekommen hat (siehe oben).<br />
<br />
[[Datei:Babble_Temperatur2.png|800px|]]<br />
<br />
Nach dem ''Sichern'' steht das zur Verfügung. Übergibt man an Babble den Textstring '''Wie ist die Temperatur im Schlafzimmer''', wird auf den Sprachausgabedevices z.B. der Text ausgegeben '''Die Temperatur im Schlafzimmer beträgt 21 Punkt 4 Grad'''. Schönheitsfehler ist noch, dass der englische Dezimalpunkt mit ausgegeben wird. Das lässt sich aber problemlos beheben, indem die Perl-Funktion ''speakEG'' etwas aufgebohrt wird. Durch einen einfachen regulären Ausdruck kann man jeden Punkt zwischen Ziffern durch ein Komma ersetzen lassen.<br />
<br />
==Weckzeit setzen==<br />
Im Beispiel gehen wir davon aus, dass es ein FHEM-dummy-Device ''Alexa.Weckzeit'' gibt, dieses dummy-Device erhält nun den Attributwert <br />
attr Alexa.Weckzeit babbleDevice Wecker<br />
Damit erscheint dieses Device mit FHEM-Devicename ''Alexa.Weckzeit'' und Babble-Devicename ''Wecker'' in der Liste der Babble-Devices. Im nächsten Schritt müssen dafür Kommandos angelegt werden. <br />
<br />
Als Sprachbefehl soll verwendet werden '''Wecken um 18 Uhr 27'''. Babble ist derzeit intern so konfiguriert, dass eine dem Teilstring ''weck'' versehene Sprachnachricht automatisch mit dem Device ''Wecker'' und dem Verb ''stellen'' assoziiert wird. Nötig ist also erstens der Eintrag des Verbs ''stellen'' in die Liste der Verben (geht mit dem Webfrontend) sowie ein Eintrag<br />
$hash->{DATA}{"command"}{"wecker"}{"none"}{"stellen"}{"auf"} = <Kommando zum Stellen><br />
Auch dieser Eintrag lässt sich komfortabel über das Webfrontend von Babble machen. Als Kommando zum Stellen trägt man nun ein<br />
set Weckzeit $VALUE<br />
Der String $VALUE wird bei der Ausführung durch den Value-Parameter ersetzt, den Babble bei der semantischen Analyse herausfiltert, also im Beispiel '''18:27 Uhr'''. Aus dem Weckzeit-Dummy kann man nun diese Weckzeit mit einem einfachen notify auf den "echten" Wecker übertragen (natürlich ein FHEM-Device...)<br />
<br />
[[Datei:Babble_Weckzeit.png|800px|]]<br />
<br />
==Wetter abfragen==<br />
In diesem Beispiel gehen wir davon aus, das in dem FHEM-Device ''wunderground'' drei Readings vorliegen:<br />
*fc0_message ist die Wettervorhersage für heute<br />
*fc1_message ist die Wettervorhersage für morgen<br />
*fc2_message ist die Wettervorhersage für übermorgen<br />
Das Device erhält nun den Attributewert<br />
attr wunderground babbleDevice Wetter<br />
Damit erscheint dieses Device mit FHEM-Devicename ''wunderground'' und Babble-Devicename ''Wetter'' in der Liste der Babble-Devices. Im nächsten Schritt müssen dafür Kommandos angelegt werden. Da bei der Analyse der Zeitwert (''heute'',''morgen'' oder ''übermorgen'') in der Variablen '''$VALUE''' abgelegt wird, reichen zwei Kommands aus, indem die Fallunterscheidung untergebracht wird:<br />
$hash->{DATA}{"command"}{"wetter"}{"none"}{"sagen"}{"wetter"} = <Kommando zur Abfrage><br />
$hash->{DATA}{"command"}{"wetter"}{"none"}{"sagen"}{"status"} = <Kommando zur Abfrage><br />
Auch dieser Eintrag lässt sich komfortabel über das Webfrontend von Babble machen. Als Kommando zur Abfrage trägt man nun in beide Felder ein:<br />
{speakEG(ReadingsVal('wunderground','fc'.(('$VALUE' eq 'übermorgen')?'2':(('$VALUE' eq 'morgen')?'1':'0')).'_message',' '))}<br />
Für das Beispiel verwenden wir eine Perl-Funktion namens ''speak(<speechdevice>,<text>)'', die nichts weiter macht, als auf einem der dazu fähigen Devices (hier ''speechdevice'') die zuständige TTS (Text-to-Speech) Funktion aufzurufen. Der Parameter ''$PARM0'' wird dabei durch denjenigen ersten Parameter ersetzt, den die Erkennungsfunktion mitgeliefert bekommen hat (siehe oben).<br />
<br />
[[Datei:Babble_Wetter.png|800px|]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Modul_Babble&diff=25574Modul Babble2018-02-28T10:08:55Z<p>Hauswart: /* Installation */</p>
<hr />
<div>{{<br />
Infobox Modul<br />
|ModPurpose=Das Modul stellt eine komfortable Oberfläche bereit, um per Webinterface ein 'Natural Language User Interface' (NLUI) zu konfigurieren. Es stellt auch einen ChatBot zur Verfügung.<br />
|ModType=h<br />
<!-- |ModCategory= (noch?) nicht verwendet --><br />
|ModCmdRef=Babble<br />
|ModForumArea=Unterstuetzende Dienste<br />
|ModTechName=95_Babble.pm<br />
|ModOwner=Prof. Dr. Peter A. Henning<br />
}}<br />
Diese Seite beschreibt die Konfiguration und Verwendung des Moduls 95_Babble.pm.<br />
=Allgemeines=<br />
Das Modul ''95_Babble.pm'' stellt eine komfortable Oberfläche bereit, um per Webinterface ein ''Natural Language User Interface'' (NLUI) zu konfigurieren. <br />
<br />
Darüber hinaus stellt Babble eine Verbindung zu einem RiveScript-Modul her, falls dies in der lokalen Perl-Installation vorhanden ist. RiveScript ist eine einfach Programmiersprache für ChatBots, Babble realisiert also für die Ansprache von FHEM auch einen ChatBot.<br />
<br />
==Funktionsweise==<br />
Babble überprüft einen empfangenen natürlichsprachlichen Satz auf einen darin enthaltenen Orts-Identifikator, sowie auf eine Liste von vordefinierten Verben und Verbteilen. Ein weiteres darin enthaltenes Nomen wird je nach Artikeln und Verben als ''Gerät'' identifiziert. Beispielsweise resultieren die beiden Eingabesätze<br />
* '''Schalte die Beleuchtung in der Sitzgruppe an'''<br />
* '''Beleuchtung in der Sitzgruppe anschalten'''<br />
jeweils im gleichen Ergebnis:<br />
<br />
'''Gerät=licht Ort=sitzgruppe Verb=schalten Ziel=ein'''<br />
<br />
Der Gerätename (auch als Babble-Device bezeichnet) ist ein von der FHEM-Bezeichung unabhängiger Begriff, der aber eindeutig mit einem FHEM-Device verbunden sein muss. also z.B. ''Licht'' für eine Lightscene. <br />
<br />
In einem mehrfach geschachtelten Daten-Hash wird anschließend unter der Adresse<br />
<br />
'''$hash->{DATA}{"command"}{"licht"}{"sitzgruppe"}{"schalten"}{"ein"}'''<br />
<br />
nachgesehen, ob dort ein FHEM-Kommando hinterlegt wurde. Dieses lautet im Beispiel ''set WZ.Scene scene Sitzgruppe'' und schaltet eine entsprechende Lightscene an.<br />
<br />
Sollte kein hinterlegtes FHEM-Kommando gefunden werden, aber das entsprechende Babble-Device bekannt sein, wird vom Modul ein einstellbarer Hilfetext entweder zurückgegeben oder per TTS (Text-to-Speech) ausgegeben.<br />
<br />
In allen anderen Fällen wird der Eingabesatz an den ChatBot weitergereicht (wenn dieser nicht explizit blockiert wurde).<br />
<br />
===Beispiel-Dialog 1 (lang)===<br />
User: "Hallo" => Babble: "Hallo, ich bin Jeannie. Wer bist Du ?" (Hier antwortet der ChatBot, weil der unvollständige Eingangssatz nicht mit einem Kommando belegt ist)<br />
<br />
User: "Ich bin Peter." => Babble: "Schoen, Dich kennenzulernen, Peter!" (Hier antwortet wieder der ChatBot)<br />
<br />
User: "Was kannst Du für mich tun ?" => Babble: "Ich kann für Dich das Haus steuern." (Hier antwortet wieder der ChatBot)<br />
<br />
User: "Was kannst Du steuern ?" => Babble: "Ich kenne die Geräte Licht, ....." (Hier antwortet wieder der ChatBot, holt sich aber die Liste der Geräte aus den Babble-Daten)<br />
<br />
User: Wie kannst Du Licht steuern => Babble: "Sprich: Licht, gefolgt von einer Ortsangabe und dem Wort an oder aus" (Hier antwortet wieder der ChatBot, indem er den Hilfetext für das Gerät ''Licht'' von Babble holt)<br />
<br />
User: "Welche Orte kennst Du ?" => Babble: "Ich kenne die Orte Wohnzimmer, ....." (Hier antwortet wieder der ChatBot, holt sich aber die Liste der Orte aus den Babble-Daten)<br />
<br />
User: Schalte das Licht in der Sitzgruppe an. => Babble sagt nun gar nichts mehr, sondern schaltet das Licht in der Sitzgruppe an.<br />
<br />
==Geräte==<br />
Die Verbindung von (Babble-)Gerätenamen mit real existierenden FHEM-Devices erfolgt im unteren Bereich des Web-Frontends. Solche Geräte können entweder ''lokal'' sein, (also derselben FHEM-Instanz angehören, wie das Babble-Device). Oder sie sind ''entfernte Geräte (''remote''). <br />
* Lokale Geräte sind dadurch gekennzeichnet, dass in ihrem FHEM-Device das Attribut '''babbleDevice''' auf den Wert des gewünschten Gerätenamens gesetzt wird (siehe Abschnitt Vorarbeiten). <br />
** Solche lokalen Geräte werden automatisch (d.h. ohne weitere nötige Vorarbeiten) in der Babble-Übersicht angezeigt.<br />
* Entfernte Geräte liegen in einer anderen FHEM-Instanz. Sie müssen im Attribut '''babbleDevices''' des Babble-Devices angegeben werden.<br />
**In der gegenwärtigen ersten Fassung des Moduls können drei solche anderen FHEM-Instanzen angegeben werden, dazu müssen die Attribute '''remoteFHEM(1|2|3)''' '''remoteFunc(1|2|3)''' gesetzt werden. Bei der tatsächlichen Ausführung eines Befehls (siehe Abschnitt Nutzung) werden diese Attribute berücksichtigt<br />
==Nutzung==<br />
Zur Nutzung durch beliebige andere FHEM-Module muss nur das Perl-Unterprogramm<br />
Babble_DoIt("Babble","<zu analysierender Satz>"[,parm0,parm1,...])<br />
aufgerufen werden (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen). Die Anzahl der Parameter beim Aufruf ist nicht festgelegt, es kann eine beliebige Anzahl von Parametern im Aufruf angegeben werden.<br />
<br />
Bei der semantischen Analyse werden identifiziert<br />
* ein (Babble-)Gerätename ''device''<br />
* eine Ortsangabe ''place'', diese darf auch leer bleiben (abgespeichert als Wert ''none'')<br />
* ein Verb ''verb'' in der Infinitiv-Form<br />
* eine Zielvariable, ggf. ein Reading ''target''<br />
* ein Zielwert ''value''<br />
Wird ein natürlichsprachlicher Satz korrekt interpretiert und ein dazu hinterlegtes Kommando (gespeichert im Babble-Hash $hash->{DATA}{"command"}) gefunden, werden in diesem Substitutionen durchgeführt.<br />
* der String $VALUE wird durch den Zielwert ''value'' ersetzt.<br />
* ein String $PARM[0|1|2..] wird durch den beim Aufruf übergebenen Wert parm0, parm1,... ersetzt.<br />
Durch diesen Mechanismus kann man den auszuführenden Kommandos verschiedene Parameter mitgeben.<br />
<br />
Anschließend wird dieses Kommando ausgeführt. Vor der Ausführung <br />
* Bei lokalen (Babble-)Geräten wird im Modul einfach <br />
fhem(<Kommando>)<br />
ausgeführt.<br />
* Bei entfernten (Babble-)Geräten gibt es zwei Möglichkeiten:<br />
** Wurde nur die IP-Adresse der entfernten FHEM-Instanz (im Attribut remoteFHEM(1|2|3)) angegeben, erfolgt die Ausführung durch den HTTP-Request<br />
http://<IP-Adresse:Port>/fhem?XHR=1&cmd.<FHEM-Device>=<Kommando><br />
** Achtung: Wenn hierbei die entfernte FHEM-Instanz durch ein csrfToken geschützt ist, oder dieses sich bei jedem Neustart der externen FHEM-Instanz verändert, muss Babble dieses Token natürlich kennen. Mit dem Befehl<br />
get Babble tokens<br />
werden diese csrfToken für alle bei Babble gemeldeten externen FHEM-Instanzen geholt. Wer dieses manuelle Neuholen vermeiden möchte, sollte bitte ein festes csrfToken für die entfernte FHEM-Instanz definieren. Das csrfToken wird natürlich nur benötigt, wenn keine entsprechende remoteFunc (siehe entsprechendes Attribut) verwendet wird.<br />
** Wurde zusätzlich zur IP-Adresse der entfernten FHEM-Instanz ein Funktionsname (im Attribute remoteFunc(1|2|3)) angegeben, erfolgt die Ausführung durch den Aufruf der Funktion<br />
<remoteFunc(1|2|3)>("<Kommando>")<br />
<br />
===Hilfetexte===<br />
Wird zu einem Device bei der entsprechenden Kombination aus Ortsangabe, Verb und Ziel kein hinterlegtes Kommando gefunden, kommt es zu einem anderen Ablauf.<br />
* Falls der ChatBot aktiv ist (d.h. das RiveScript-Modul muss installiert sein und darf nicht mit dem Attribut '''noChatBot=1''' blockiert werden), wird der gesamte Eingabesatz an diesen ChatBot weitergeleitet. Dieser liefert in jedem Fall eine Antwort, diese Antwort wird an Stelle des Parameters $HELP in das unter dem Attribut '''helpFunc''' hinterlegte FHEM-Kommando substituiert und dieses ausgeführt.<br />
* Falls der ChatBot nicht aktiv ist (d.h., entweder ist das RiveScript-Modul nicht installiert oder wurde durch das Attribut '''noChatBot=1''' blockiert), überprüft Babble, ob wenigstens ein Babble-Device erkannt wurde. Wenn ja, wird der diesem Babble-Device zugeordnete Hilfetext an Stelle des Parameters $HELP in das unter dem Attribut '''helpFunc''' hinterlegte FHEM-Kommando substituiert und dieses ausgeführt.<br />
In beiden Fällen werden in der '''helpFunc'''-Funktion auch die Parameter $PARM(0|1|2|...) durch die Werte ersetzt, die beim Aufruf der '''DoIt'''-Funktion übergeben wurden.<br />
<br />
Beispielsweise kann man mit der Hinterlegung von<br />
attr Babble helpFunc {speak('$PARM0','$HELP')}<br />
dafür sorgen, dass die Perl-Funktion speak mit dem entsprechenden Hilfetext ausgeführt wird. Also resultiert in diesem Fall<br />
Babble_DoIt("Babble","<zu analysierender Satz>",parm0[,parm1,...]) -> speak("parm0","<Antwort des ChatBot>")<br />
bzw.<br />
Babble_DoIt("Babble","<zu analysierender Satz>",parm0[,parm1,...]) -> speak("parm0","<Hilfetext für das betreffende Device>")<br />
<br />
===Test===<br />
Zum Test der durch beliebige andere FHEM-Module muss nur das Perl-Unterprogramm<br />
Babble_TestIt("Babble","<zu analysierender Satz>",<exec-Flag>,[,parm0,parm1,...])<br />
aufgerufen werden (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen). Die Anzahl der Parameter beim Aufruf ist nicht festgelegt, es kann eine beliebige Anzahl von Parametern im Aufruf angegeben werden. <br />
* Wenn <exec-Flag>==1 ist, wird zusätzlich zur Ausgabe des Analysestrings auch noch das zugehörige Kommando ausgeführt.<br />
* Ansonsten erfolgt nur die Ausgabe des Analysestrings.<br />
Neben der Möglichkeit eines Online-Tests mit beliebigen Sätzen besteht auch ncoh die Möglichkeit zum Selbsttest des Moduls. Dazu ruft man den Befehl<br />
set Babble test<br />
auf. In der Ausgabe sieht man eine Vielzahl von Beispielsätzen und kann überprüfen, ob diese korrekt analysiert werden.<br />
<br />
=Babble-Device=<br />
==Vorarbeiten==<br />
Will man ''lokale'' (d.h. in derselben FHEM-Instanz befindliche) Devices per Babble ansteuern, muss man vorher im Device ''global'' dem Attribut ''userAttr'' ein neues global verfügbares Attribut ''babbleDevice'' hinzufügen. Dieses wird damit für jedes FHEM-Device setzbar.<br />
==Installation==<br />
Durch den normalen Update-Mechanismus wird das Modul 95_Babble.pm in den Modulordner installiert, sowie die Datei babble.js in /fhem/www/pgm2. Installationsvoraussetzung ist das Modul JSON.<br />
<br />
'''Achtung, nur wer den ChatBot nutzen möchte''', sollte das Perl-Modul RiveScript installieren, entweder durch Download von [https://github.com/aichaos/rivescript-perl github], oder via CPAN (''cpan RiveScript'')<br />
Zusätzlich zu diesem Perl-Modul benötigt man dann noch RiveScript-Dateien (Endung .rive). Babble erzeugt einen RiveScript-Interpreter, dieser sucht seine Konfigurationsdateien (unter Linux) im Verzeichnis ''/opt/fhem/rivescript''. Die benötigten RiveScript-Dateien befinden sich im Contrib-Ordner [https://svn.fhem.de/trac/browser/trunk/fhem/contrib/Babble]. Ein Tutorial für RiveScript findet man [https://www.rivescript.com/docs/tutorial hier].<br />
<br />
==Definition==<br />
Das Babble-Device - hier mit dem Namen ''Babble'' versehen - selbst wird über<br />
define Babble Babble<br />
definiert. Diese Definition legt einen versteckten Raum "babbleRoom" 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 ''Babble'' (eben der genannte Weblink) im oberen Menü des Webinterfaces wird dieser versteckte Raum angezeigt. Er enthält an erster Stelle das Babble-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 Babble-Device kennt die folgenden Set-Befehle (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen):<br />
set Babble locked | unlocked<br />
Sperre oder entsperre das Überschreiben der persistenten Daten, siehe [[#Sperrung | Sperrung]]. <br />
'''TIPP:''' Diese Sperre sollte bei Experimenten immer gesetzt sein.<br />
set Babble save | restore<br />
Speichere die Daten persistent, oder hole sie aus der betreffenden Datei ''babbleFile'' (Achtung für Nutzer der configdb: Das File wird in der Datenbank abgelegt, nicht im Dateisystem).<br />
set Babble rivereload<br />
Erzeuge eine neue Instanz des RiveScript Interpreters und lese die Konfigurationsdaten neu ein.<br />
set Babble test<br />
Lasse eine interne Testsuite von Erkennungssätzen durchlaufen<br />
<br />
==Get-Befehle==<br />
Das Babble-Device kennt die folgenden Get-Befehle (''Babble'' ist duch den tatsächlichen Device-Namen zu ersetzen):<br />
get Babble version<br />
Gibt die Versionsnummer des Moduls zurück<br />
<br />
==Attribute==<br />
Das Babble-Device benötigt zum Funktionieren unbedingt ein paar wichtige Attribute mit Wortlisten. Bei der ersten Definition sollten diese automatisch belegt werden, können aber jederzeit geändert werden.<br />
*'''babblePlaces''' ist eine durch Leerzeichen separierte Liste von Orts-Identifikatoren, die in der Sprachsteuerung erkannt werden sollen. Die in FHEM bekannten ''Rooms''=Räume werden ebenfalls als Ortsbezeichnungen zur Verfügung gestellt und brauchen nicht in dieser Liste aufzutauchen.<br />
*'''babbleNotPlaces''' ist eine durch Leerzeichen separierte Liste von FHEM-Räumen, die ''nicht'' als Orts-Indentifikatoren erkannt werden sollen.<br />
*'''babbleStatus''' ist eine durch Leerzeichen separierte Liste von Status-Identifikatoren, also Nomen, die den Status eines Untersystems wiedergeben. Beispiel: ''Status Wert Wetter Zeit''<br />
*'''babblePrepos''' ist eine durch Leerzeichen separierte Liste von Präpositionen. Beispiel: ''von vom des der in im auf bei am''<br />
*'''babbleTimes''' ist eine durch Leerzeichen separierte Liste von Zeit-Adverbien, die eine Zeitangabe eines Untersystems signalisieren. Beispiel: ''heute morgen übermorgen nacht''<br />
*'''babbleQuests''' ist eine durch Leerzeichen separierte Liste von Frage-Adverbien. Beispiel: ''wie wo wann''<br />
*'''babbleArticles''' ist eine durch Leerzeichen separierte Liste von Artikeln. Beispiel: ''der die das den des dem zur''<br />
*'''babbleVerbs''' ist eine durch Leerzeichen separierte Liste von Verbengruppen, die jeweils aus kommagetrennten Variationen und Konjugationen sowie einem davon per ':' getrennten Infinitiv bestehen. Beispiel: ''schalt,schalte:schalten mach,machs,mache:machen öffne:öffnen schließe,schließ:schließen''<br />
*'''babbleVerbParts''' ist eine durch Leerzeichen separierte Liste von Verbteilen, die den durch das grundlegende Tun (beschrieben durch ein Verb, z.B. ''schließen'') erreichten Zustand festlegen (z.B. ''zu'' in zuschließen und ''auf'' in aufschließen). Beispiel für diese Liste: ''zu auf ent wider ein an aus ab um''<br />
*'''babbleWrites''' ist eine durch Leerzeichen separierte Liste, die spezielle Verben enthält, die mit Schreiboperationen befasst sind. Beispiel: ''sagen senden hinzufügen entfernen ändern löschen''<br />
<br />
*'''helpFunc''' ist ein FHEM-Kommando, das aufgerufen wird, wenn zu einem Eingabesatz zwar ein Device, aber kein passendes Kommando gefunden wird. Siehe betreffenden Abschnitt unter Benutzung.<br />
*'''testParm(0|1|2|3)''' sind Attribute, die bei reinen Tests von Babble-Erkennungen an Stelle der Parameter $PARM(0|1|2|3) eingesetzt werden.<br />
<br />
*'''noChatBot''' muss auf 1 gesetzt werden, wenn zwar RiveScript als Modul im System vorhanden ist, der ChatBot aber nicht genutzt werden soll.<br />
<br />
*'''babbleIds''' ist eine durch Leerzeichen separierte Liste von Namen, unter denen Babble selbst angesprochen werden kann<br />
*'''babblePreSubs''' ist eine durch Leerzeichen separierte Liste von regulären Ausdrücken und Ersetzungsstrings, diese sind jeweils durch ''':''' getrennt. Diese Substitutionen werden vor der Normalisierung des Eingabesatzes angewandt. Leerzeichen in den regulären Ausdrücken oder den Ersetzungsstrings müssen im Attribut als ''\s'' angegeben werden.<br />
<regexp1>:<ersetzung1> <regexp2>:<ersetzung2> ...<br />
*'''remoteFHEM(0|1|2|3)''' ist die IP-Adresse (+ Port) einer entfernten FHEM-Instanz. Username und Passwort müssen ggf. ebenfalls angegeben werden, im Format <user>:<password>@<host>:<port><br />
*'''remoteToken(0|1|2|3)''' ist der csrf-Token einer entfernten FHEM-Instanz, siehe [[Modul_Babble#Nutzung|Nutzung]]<br />
*'''remoteFunc(0|1|2|3)''' ist der Name einer Perl-Funktion, die aufgerufen wird, um die entfernte FHEM-Instanz anzusprechen. Hierbei kann beispielsweise das Modul RFHEM oder das Modul FHEM2FHEM eingesetzt werden. Die Angabe dieser Funktion ist optional - verzichtet man darauf, wird Babble versuchen, die entfernten FHEM-Devices durch einfache Web-Aufrufe zu steuern (und dafür wird natürlich der csrf-Token benötigt). <br />
<br />
*'''babbleDevices''' ist eine durch Leerzeichen separierte Liste von (''remote''-)Device-Identifikatoren in der Form <br />
<Babble Devicename>:<FHEM-Devicename>:<Ziffer> <Babble Devicename>:<FHEM-Devicename>:<Ziffer> ... <Babble Devicename>:<FHEM-Devicename>:<Ziffer><br />
**Als Ziffer sind die Werte 0,1,2,3 erlaubt, sie teilen Babble mit, um welche der gegenwärtig möglichen vier verschiedenen entfernten FHEM-Instanzen (siehe Attribut remoteFHEM) es sich handelt.<br />
**Der Babble Devicename darf ein '''*'''-Zeichen enthalten. Ist dies der Fall, wird der Babble Devicename als regulärer Ausdruck interpretiert, in dem '''*''' durch '''(.*)''' ersetzt wird. Wenn Babble nun mit einem Satz aufgerufen wird, dessen Device-Teil auf diesen Ausdruck passt, wird die entsprechende Zeichengruppe in den Parameter ''$STAR'' übernommen. Taucht ''$STAR'' nun in der Kommandosequenz auf, wird dies durch den aktuellen Wert der Zeichengruppe ersetzt. Beispiel: der Babble-Devicename im Attribut sei ''*liste''. Wird nun im zu interpretierenden Satz der Devicename ''Einkaufsliste'' erkannt, enthält ''$STAR'' den Wert ''Einkaufs''. Im FHEM-Kommando, das Babble ausführt, wird ''$STAR'' dann durch ''Einkaufs'' ersetzt.<br />
<br />
*'''linkname''' ist der Name für den Link im FHEM-Menü. Default: ''Babble''.<br />
*'''hiddenroom''' ist der Name für den versteckten Raum, der das Babble-Device enthält. Default: ''babbleRoom''<br />
*'''lockstate''' ist der Sperrzustand für das Device, siehe [[#Sperrung | Sperrung]]<br />
<br />
=Webinterface=<br />
In diesem Abschnitt wird die Bedienung des Webinterfaces und damit die Konfiguration des NLUI beschrieben. Um sie zu erreichen, klickt man auf den Begriff ''Babble'' im oberen Menü des Webinterfaces.<br />
==Babble Test==<br />
In diesem Teil des Webinterfaces kann ein Testsatz eingegeben werden. Durch anklicken des Buttons ''Test'' wird dieser analysiert und das Resultat der Analyse unmittelbar darunter angezeigt. Ist bereits ein FHEM-Kommando dafür definiert (siehe übernächsten Abschnitt), wird dieses ebenfalls angezeigt. Wenn man vorher die Checkbox ''Ausführung'' setzt, wird dieses FHEM-Kommando auch ausgeführt.<br />
<br />
[[Datei:Babble_Test.png|600px|]]<br />
<br />
==Babble Orte und Babble Verben==<br />
Hier können im oberen Bereich zusätzliche Orts-Identifikatoren angegeben und mit Hilfe des Buttons ''Hinzufügen'' dem Attribut '''babblePlaces''' hinzugefügt werden. Wählt man stattdessen einen bereits definierten Orts-Identifikator aus, verändert sich der Button in einen ''Entfernen''-Button, zusätzlich erscheint ein Button zum ''Abbruch''. <br />
<br />
Hier können im unteren Bereich zusätzliche Verbengruppen angegeben und mit Hilfe des Buttons ''Hinzufügen'' dem Attribut '''babbleVerbs''' hinzugefügt werden. Wählt man stattdessen ein bereits definiertes Verb aus, verändert sich der Button in einen ''Entfernen''-Button, zusätzlich erscheinen ein Button zum ''Ändern'' und zum ''Abbruch''. <br />
<br />
[[Datei:Babble_Places.png|600px|]]<br />
<br />
==Babble Devices==<br />
In diesem Bereich können mit Dropdown-Listen die bekannten Orte, Verben, und Zielzustände ausgewählt werden, die in der semantischen Analyse erkannt werden. Zusätzliche Zeilen können mit dem Button ''Hinzufügen'' gewonnen werden, alle bis auf die erste Zeile für jedes Device können entfernt werden. <br />
<br />
In der ersten Zeile sollte ein Hilfetext eingetragen werden - dieser wird ausgegeben, wenn für dieses Device keine Kombination aus Raum, Verb und Ziel erkannt worden ist. Für neue Devices wird ein Vorschlag geliefert.<br />
<br />
Im rechten Feld wird dann das auszuführende FHEM-Kommando eingetragen. <br />
* Perl-Aufrufe werden dabei wie üblich in '''{..}''' Klammern eingeschlossen.<br />
* '''Achtung:''' Derzeit noch doppelte Anführungszeichen vermeiden, nur einfache Anführungszeichen sind erlaubt.<br />
<br />
[[Datei:Babble_Devices.png|600px|]]<br />
<br />
===Gruppierung===<br />
Mit der Spracheingabe können ''verschiedene FHEM-Devices mit dem gleichen Babble-Device'' adressiert werden. Dafür müssen lediglich Babble-Devicenamen vergeben werden, die sich durch ein angehängtes <br />
_<Ziffern><br />
voneinander unterscheiden. Beispiel<br />
* Ein entferntes FHEM-Device WZ.Scene (auf der entfernten FHEM-Instanz Nr. 1) wird im Attribut babbleDevices mit dem Babble-Devicenamen ''Licht'' definiert:<br />
attr Babble babbleDevices WZ.Scene:Licht:1<br />
* Ein lokales FHEM-Device Schlafzimmerlampe erhält selbst ein Attribut <br />
attr Schlafzimmerlampe babbleDevice Licht_1<br />
Die beiden werden dann im Webfrontend von Babble direkt untereinander dargestellt, jeweils mit eigenem Hilfetext. Für den Zweck der Konfiguration sind sie dann unterschiedliche Geräte (so, wie es ja auch semantisch richtig ist). Bei der Verarbeitung eines Eingabesatzes werden aber '''beide''' Geräte durch den Devicenamen ''Licht'' adressiert, d.h. Babble geht alle intern gespeicherten Geräte mit den Babble-Devicenamen ''Licht'', ''Licht_<Ziffern>'' durch und führt das erste passende Kommando aus.<br />
<br />
=Anwendungsbeispiele=<br />
==Temperatur abfragen==<br />
Im Beispiel gehen wir davon aus, dass es ein dummy-Device ''tempProfileC'' mit verschiedenen userReadings gibt, z.B. steht ''WZ.T'' für die Temperatur im Wohnzimmer.<br />
<br />
[[Datei:Babble_Temperatur.png|400px|]]<br />
<br />
Dieses dummy-Device erhält nun den Attributwert <br />
attr tempProfileC babbleDevice Temperatur<br />
Damit erscheint dieses Device mit FHEM-Devicename ''tempProfileC'' und Babble-Devicename ''Temperatur'' in der Liste der Babble-Devices. Im nächsten Schritt müssen dafür Kommandos angelegt werden. Für das Beispiel wollen wir die Temperatur im Schlafzimmer und im Wohnzimmer abfragen. Dazu müssen diese beiden Orte der Liste ''babblePlaces'' hinzugefügt werden, das geht im Webfrontend von Babble.<br />
<br />
Als erstes wollen wir die Frage stellen: '''Wie ist die Temperatur im Schlafzimmer'''. Babble ist derzeit intern so konfiguriert, dass eine Frage "wie ist" mit dem Verb ''sagen'' assoziiert wird. Weil ein konkretes Ziel nicht genannt wurde, setzt Babble als Ziel der Abfrage den ''Status'' des Gerätes ein. Nötig sind also die beiden Einträge<br />
$hash->{DATA}{"command"}{"temperatur"}{"schlafzimmer"}{"sagen"}{"status"} = <1. Kommando zur Ausgabe><br />
$hash->{DATA}{"command"}{"temperatur"}{"wohnzimmer"}{"sagen"}{"status"} = <2. Kommando zur Ausgabe><br />
Alternativ kann man auch den Befehl erteilen '''Sage den Wert der Temperatur im Schlafzimmer'''. Hier wird spezifisch der ''Wert'' abgefragt, sinnvoll sind also zwei weitere Einträge mit denselben Ausgaben<br />
$hash->{DATA}{"command"}{"temperatur"}{"schlafzimmer"}{"sagen"}{"wert"} = <1. Kommando zur Ausgabe><br />
$hash->{DATA}{"command"}{"temperatur"}{"wohnzimmer"}{"sagen"}{"wert"} = <2. Kommando zur Ausgabe><br />
Auch diese beiden Einträge lassen sich komfortabel über das Webfrontend von Babble machen. Für das Beispiel verwenden wir eine Perl-Funktion namens ''speak(<speechdevice>,<text>)'', die nichts weiter macht, als auf einem der dazu fähigen Devices (hier ''speechdevice'') die zuständige TTS (Text-to-Speech) Funktion aufzurufen. <br />
<1. Kommando zur Ausgabe> = {speak($PARM0,'Die Temperatur im Schlafzimmer beträgt '.ReadingsVal('tempProfileC','SZ.T','').' Grad')}<br />
<2. Kommando zur Ausgabe> = {speak($PARM0,'Die Temperatur im Wohnzimmer beträgt '.ReadingsVal('tempProfileC','WZ.T','').' Grad')}<br />
Der Parameter ''$PARM0'' wird dabei durch denjenigen ersten Parameter ersetzt, den die Erkennungsfunktion mitgeliefert bekommen hat (siehe oben).<br />
<br />
[[Datei:Babble_Temperatur2.png|800px|]]<br />
<br />
Nach dem ''Sichern'' steht das zur Verfügung. Übergibt man an Babble den Textstring '''Wie ist die Temperatur im Schlafzimmer''', wird auf den Sprachausgabedevices z.B. der Text ausgegeben '''Die Temperatur im Schlafzimmer beträgt 21 Punkt 4 Grad'''. Schönheitsfehler ist noch, dass der englische Dezimalpunkt mit ausgegeben wird. Das lässt sich aber problemlos beheben, indem die Perl-Funktion ''speakEG'' etwas aufgebohrt wird. Durch einen einfachen regulären Ausdruck kann man jeden Punkt zwischen Ziffern durch ein Komma ersetzen lassen.<br />
<br />
==Weckzeit setzen==<br />
Im Beispiel gehen wir davon aus, dass es ein FHEM-dummy-Device ''Alexa.Weckzeit'' gibt, dieses dummy-Device erhält nun den Attributwert <br />
attr Alexa.Weckzeit babbleDevice Wecker<br />
Damit erscheint dieses Device mit FHEM-Devicename ''Alexa.Weckzeit'' und Babble-Devicename ''Wecker'' in der Liste der Babble-Devices. Im nächsten Schritt müssen dafür Kommandos angelegt werden. <br />
<br />
Als Sprachbefehl soll verwendet werden '''Wecken um 18 Uhr 27'''. Babble ist derzeit intern so konfiguriert, dass eine dem Teilstring ''weck'' versehene Sprachnachricht automatisch mit dem Device ''Wecker'' und dem Verb ''stellen'' assoziiert wird. Nötig ist also erstens der Eintrag des Verbs ''stellen'' in die Liste der Verben (geht mit dem Webfrontend) sowie ein Eintrag<br />
$hash->{DATA}{"command"}{"wecker"}{"none"}{"stellen"}{"auf"} = <Kommando zum Stellen><br />
Auch dieser Eintrag lässt sich komfortabel über das Webfrontend von Babble machen. Als Kommando zum Stellen trägt man nun ein<br />
set Weckzeit $VALUE<br />
Der String $VALUE wird bei der Ausführung durch den Value-Parameter ersetzt, den Babble bei der semantischen Analyse herausfiltert, also im Beispiel '''18:27 Uhr'''. Aus dem Weckzeit-Dummy kann man nun diese Weckzeit mit einem einfachen notify auf den "echten" Wecker übertragen (natürlich ein FHEM-Device...)<br />
<br />
[[Datei:Babble_Weckzeit.png|800px|]]<br />
<br />
==Wetter abfragen==<br />
In diesem Beispiel gehen wir davon aus, das in dem FHEM-Device ''wunderground'' drei Readings vorliegen:<br />
*fc0_message ist die Wettervorhersage für heute<br />
*fc1_message ist die Wettervorhersage für morgen<br />
*fc2_message ist die Wettervorhersage für übermorgen<br />
Das Device erhält nun den Attributewert<br />
attr wunderground babbleDevice Wetter<br />
Damit erscheint dieses Device mit FHEM-Devicename ''wunderground'' und Babble-Devicename ''Wetter'' in der Liste der Babble-Devices. Im nächsten Schritt müssen dafür Kommandos angelegt werden. Da bei der Analyse der Zeitwert (''heute'',''morgen'' oder ''übermorgen'') in der Variablen '''$VALUE''' abgelegt wird, reichen zwei Kommands aus, indem die Fallunterscheidung untergebracht wird:<br />
$hash->{DATA}{"command"}{"wetter"}{"none"}{"sagen"}{"wetter"} = <Kommando zur Abfrage><br />
$hash->{DATA}{"command"}{"wetter"}{"none"}{"sagen"}{"status"} = <Kommando zur Abfrage><br />
Auch dieser Eintrag lässt sich komfortabel über das Webfrontend von Babble machen. Als Kommando zur Abfrage trägt man nun in beide Felder ein:<br />
{speakEG(ReadingsVal('wunderground','fc'.(('$VALUE' eq 'übermorgen')?'2':(('$VALUE' eq 'morgen')?'1':'0')).'_message',' '))}<br />
Für das Beispiel verwenden wir eine Perl-Funktion namens ''speak(<speechdevice>,<text>)'', die nichts weiter macht, als auf einem der dazu fähigen Devices (hier ''speechdevice'') die zuständige TTS (Text-to-Speech) Funktion aufzurufen. Der Parameter ''$PARM0'' wird dabei durch denjenigen ersten Parameter ersetzt, den die Erkennungsfunktion mitgeliefert bekommen hat (siehe oben).<br />
<br />
[[Datei:Babble_Wetter.png|800px|]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=ABFALL&diff=23343ABFALL2017-11-23T17:58:47Z<p>Hauswart: /* Pushbullet Beispiel */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Filtern von (Abfall-)Terminen aus einem Calendar.<br />
|ModType=x<br />
|ModFTopic=48237<br />
|ModForumArea=Codeschnipsel<br />
|ModTechName=57_ABFALL.pm<br />
|ModOwner=Constantin / {{Link2FU|14026|uniqueck}}<br />
}}<br />
<br />
[[ABFALL]] ist ein (inoffizielles, nicht Bestandteil der Distribution) Hilfsmodul, das bestimmte Termine aus einem bestehenden Kalender des Moduls [[Calendar]] in Readings übernimmt. <br />
<br />
== Voraussetzungen ==<br />
Es muss ein [[Calendar]]-Objekt definiert sein. Der dabei benutzte Name muss in der Definition des ABFALL-Objekts spezifiziert werden.<br />
Es können auch mehrere Calendar Objekte übergeben werden.<br />
<br />
Sonderzeichen aus dem Namen der Termine, werden entfernt um die Namen der generierten Readings FHEM tauglich zu machen, für die Werte der Readings bleiben diese allerdings erhalten.<br />
<br />
== Anwendung ==<br />
=== Installation ===<br />
Mit folgendem Befehl kann das Modul direkt in den Standard FHEM Update Prozess eingeklinkt werden.<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
Um es nur zu installieren, kann auch einfach nur das Command<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
eingegeben werden.<br />
<br />
=== Entwicklungsstrang ===<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
bzw.<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
<br />
=== Define ===<br />
:<code>define <Name> ABFALL <calendarname>,<calendarname2>,...</code><br />
<br />
Erläuterung der Parameter im '''define''':<br />
;<calendarname><br />
:Name des '''Calendar''' Kalenders <br />
<br />
Beispiel:<br />
:<code>define AbfallGoogleCalender Calendar ical url https://......</code><br />
:<code>define myABFALL ABFALL AbfallGoogleCalender</code><br />
<br />
=== Werte aktualisieren ===<br />
Die Werte aktualisieren sich abhängig vom [[notify]] der entsprechenden Calendar Instanz, welche im define angegeben wurde(n).<br />
<br />
=== Weitere Attribute ===<br />
<br />
{| class="wikitable"<br />
!Attribut<br />
!Werteliste<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |calendarname_praefix<br />
|0 und 1<br />
|soll der Kalendername als praefix dem Reading vorangestellt werden, sollte bei nur einem Kalender auf 0 gesetzt werden<br />
|1 - praefix wird vorangestellt<br />
|-<br />
!align="right" |abfall_clear_reading_regex<br />
|<br />
|regex zum Entfernen von Anteilen aus dem Termin, dieser wird vor dem Entfernen von Sonderzeichen aus den Namen der Termine angewandt.<br />
|<br />
|-<br />
!align="right" |disable<br />
|0 und 1<br />
|deaktiviert das Modul<br />
|0<br />
|-<br />
!align="right" |weekday_mapping<br />
|<br />
|Mapping, wie die Readings der Tage angezeigt werden sollen, zum Beispiel So Mo Di Mi Do Fr Sa<br />
|Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag<br />
|-<br />
!align="right" |delimiter_text_reading<br />
|<br />
|Wenn zwei Abholungen an ein und demselben Tag existieren, wird dieses Trennzeichen genutzt, um die beiden (oder mehrere) Werte zu einem Text zu verbinden. Nur relevant für die Readings next_text und now_text<br />
|und<br />
|-<br />
!align="right" |delimiter_reading<br />
|<br />
|wie attribute delimiter_text_reading, allerdings nur für die readings next und now<br />
|<br />
|-<br />
!align="right" |filter<br />
|<br />
|regex zum Filtern der Namen der Termine aus den Kalendern, so dass nur solche genutzt werden, welche diesem Filter entsprechen<br />
|<br />
|-<br />
|}<br />
<br />
== Anwendungsbeispiel(e) ==<br />
=== Einbindung ins Tablet UI ===<br />
<pre><div data-device="myABFALL" data-type="symbol" class="bigger warn wider" <br />
data-get="next" data-get-warn=".*(\d+).*" <br />
data-get-on='["Restmuell_.*","Wertstoff_.*"]'<br />
data-on-colors='["#000","#6EB54C"]' <br />
data-icons='["fa-trash-o","fa-trash-o"]'></div></pre><br />
<br />
=== Einbindung ins Tablet UI, erweitert ===<br />
Fallen die Leerungen zweier verschiedener Tonnen nicht auf den selben Tag, reicht es normalerweise, nur ein Symbol auf der Oberfläche zu platzieren und dieses dann dynamisch zu befüllen. In folgendem Beispiel werden folgende Anforderungen umgesetzt:<br />
* Anzeige unterschiedlicher Symbole bzw. Farben für Papiertonne, Restmülltonne, Biotonne und gelbe Säcke<br />
* Anzeige der verbleibenden Tage bis zur Leerung als "Warn"-Marker in Rot, aber nur, wenn die Leerung innerhalb der nächsten 2 Tage ist<br />
* Blinken des Symbols, wenn die nächste Leerung morgen ansteht<br />
* Rotation des Symbols, wenn die nächste Leerung noch am selben Tag ansteht. Nach einer bestimmten Uhrzeit (z.B. 9 Uhr morgens) soll dann auf die nächste Tonne geschaltet werden<br />
* Anzeige des Datums bzw. von "heute" oder "morgen" unter dem Symbol als Label<br />
<br />
Zur Datumsanzeige wird eine kleine Hilfsfunktion in die 99_myUtils eingebaut. <br />
<syntaxhighlight lang="perl"><br />
sub datumHeuteMorgen($){<br />
my $compareDate = shift;<br />
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);<br />
$year += 1900; $mon += 1; <br />
my $heute = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time+86400);<br />
$year += 1900; $mon += 1;<br />
my $morgen = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
return "heute" if $compareDate eq $heute;<br />
return "morgen" if $compareDate eq $morgen;<br />
return $compareDate;<br />
}<br />
</syntaxhighlight><br />
Diese Funktion wird in den userReadings des Abfall-Moduls verwendet. Das Abfallmodul erzeugt eine Gruppe von Readings mit dem Namen now_*, wenn die Leerung am selben Tag ansteht, bzw. genau dann, wenn der Termin im zu Grunde liegenden Kalender gerade aktiv ist. In diesem Beispiel liegt dem Kalender-Modul ein Google-Kalender zu Grunde, bei dem die Termine immer von 0 Uhr bis 9 Uhr morgens eingetragen sind. Dadurch wird erreicht, dass die Anzeige nach 9 Uhr weiterspringt, weil dann die now-Readings verschwinden.<br />
<br />
Folgende userReadings werden zum Abfallmodul hinzugefügt, welches in diesem Beispiel "abf.abfall" genannt ist:<br />
<syntaxhighlight lang="perl"><br />
attr myABFALL userReadings ftui_datum {ReadingsVal("myABFALL","now_text","") eq "" ? datumHeuteMorgen(ReadingsVal("myABFALL","next_datum","")) : "heute";},ftui_next {ReadingsVal("myABFALL","now_text","") eq "" ? ReadingsVal("myABFALL","next","") : ReadingsVal("myABFALL","now","")."_0";;}<br />
</syntaxhighlight><br />
Das Reading "ftui_next" bildet die Grundlage für das Symbol in TabletUI, das Reading "ftui_datum" wird für das Label genutzt. <br />
<br />
Somit lässt sich ganze in FTUI wie folgt darstellen:<br />
<syntaxhighlight lang="html"><br />
<div data-device="myABFALL" <br />
data-type="symbol"<br />
data-get="ftui_next"<br />
data-get-on='["Biotonne_0$","Biotonne_1$","Biotonne_.*","GelberSack_0$","GelberSack_1$","GelberSack_.*","Papiertonne_0$","Papiertonne_1$","Papiertonne_.*","Restmuelltonne_0$","Restmuelltonne_1$","Restmuelltonne_.*"]'<br />
data-get-warn=".*([0|1|2]).*"<br />
data-on-colors='["#8B4513","#8B4513","#8B4513","#f4e946","#f4e946","#f4e946","#2d9e1c","#2d9e1c","#2d9e1c","#696969","#696969","#696969"]'<br />
class="large warn"<br />
data-icons='["fa-trash-o fa-spin","fa-trash-o blink","fa-trash-o","fs-bag fa-spin","fs-bag blink","fs-bag","fs-dustbin fa-spin","fs-dustbin blink","fs-dustbin","fa-trash fa-spin","fa-trash blink","fa-trash"]'<br />
/><br />
<div data-device="myABFALL" data-get="ftui_datum" data-type="label"/><br />
</syntaxhighlight><br />
Für Jede Tonne werden hier drei Zustände unterschieden und einzeln in "data-get-on", "data-on-colors" und "data-icons" zugeordnet. Daher haben diese Listen jeweils 12 Einträge.<br />
<br />
=== Benachrichtigung ===<br />
==== DOIF ====<br />
====== TelegramBot Beispiel ======<br />
<pre>[myABFALL:next_days] == 1) ( set fhemBot message 'Morgen wird [myABFALL:next_text] abgeholt')<br />
[myABFALL:now_text] ne "") ( set fhemBot message 'Heute wird [myABFALL:now_text] abgeholt')</pre><br />
<br />
====== Pushbullet Beispiel ======<br />
<br />
Die morgigen Leerungen per Push um 19:30 mittels Pushbullet:<br />
<br />
<code>define dAbfallmorgen doif ([19:30] and [myABFALL:next_days] == 1) ( msg |Morgen wird [myABFALL:next_text] abgeholt)<br />
<br />
attr dAbfallmorgen do always</code><br />
<br />
Die heutigen Leerungen per Push um 07:00 mittels Pushbullet:<br />
<br />
<code>define dAbfallheute doif ([07:00] and [myABFALL:now_text] ne "") ( msg |Heute wird [myABFALL:now_text] abgeholt)<br />
<br />
attr dAbfallheute do always</code><br />
<br />
=== Links ===<br />
* Forenthema {{Link2Forum|Topic=50177|LinkText=Abfall Visualisierung mit Bilderrahmen}}</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Spritpreismonitor&diff=23311Spritpreismonitor2017-11-16T08:22:34Z<p>Hauswart: /* Konfiguration */</p>
<hr />
<div>Die hier vorgestellten Fragmente ermöglichen es, mit Hilfe von [[HTTPMOD]] bei [http://www.clever-tanken.de clever-tanken.de] von Wunschtankstellen die Spritpreise zu protokollieren. Die Credits dafür gehen an Forum-Benutzer {{Link2FU|1774|Phil__}}. Die Original Diskussion im Forum ist {{Link2Forum|Topic=22554|Message=210795|LinkText=hier}}.<br />
<br />
Alternativ können die Kraftstoffpreise auch über die Webseite tankerkönig.de bezogen werden. Die Vorgehensweise dafür ist im Detail in [http://www.cyberwulf.de/2016/fhem-spritpreise-von-tankerkoenig-de/ diesem Blog] beschrieben.<br />
<br />
== Einleitung ==<br />
{{Randnotiz|RNTyp=y|RNText=Die gezeigten Anweisungen basieren noch auf einer alten Version (vor Februar 2016) des Moduls HTTPMOD. Das betrifft insbesondere die gewählten ''readings...''-Namen. Dieses Namensschema wird u.U. in Zukunft nicht mehr unterstützt.<br />
Zur Umstellung auf das aktuelle Namensschema (am Beispiel ''Shell'') bitte folgende Aktionen (Eingabe in das Befehlsfenster!) ausführen:<br />
:<code>attr Shell enableControlSet 1</code><br />
:<code>set Shell upgradeAttributes</code><br />
Im FHEM-Log sollten dann Meldungen auftauchen nach dem Schema <br />
:''Shell: upgraded attribute ... to new syntax ...''<br />
:''Shell: dropping readings... from userattr list''<br />
}}<br />
<br />
Im folgenden wird mit Hilfe des Moduls HTTPMOD der Spritpreis von ausgewählten Tankstellen abgerufen. Die Daten werden [[Regulärer Ausdruck|gefiltert]], gespeichert und als Diagramm aufbereitet.<br />
<br />
Zum Nachbau ist es erforderlich, "seine" Wunschtankstellen bei Clever-Tanken zu suchen. Jede Tankstelle hat eine eigene Nummer:<br />
:<code>/tankstelle_details/0815</code><br />
<br />
Die ''600'' in den Beispielen gibt das Abrufintervall in Sekunden an.<br />
<br />
== Konfiguration ==<br />
Die erforderlichen Definitionen in der FHEM [[Konfiguration]] bestehen aus mehreren Teilen. Zunächst die erforderlichen Einstellungen, um die Daten der gewünschten Tankstellen abzuholen:<br />
<br />
<pre><br />
define Shell HTTPMOD http://www.clever-tanken.de/tankstelle_details/4871 600<br />
attr Shell group Spritpreise<br />
attr Shell icon tanken<br />
attr Shell reading01Name Diesel<br />
attr Shell reading02Name SuperE5<br />
attr Shell reading01Regex <span>Diesel</span>[^0-9]+([0-9\.]+)<br />
attr Shell reading02Regex <span>Super E5</span>[^0-9]+([0-9\.]+)<br />
attr Shell room Spritpreise<br />
attr Shell stateFormat Liter_Diesel: Diesel<br />
attr Shell timeout 5<br />
<br />
define Total HTTPMOD http://www.clever-tanken.de/tankstelle_details/4870 600<br />
attr Total group Spritpreise<br />
attr Total icon tanken<br />
attr Total reading01Name Diesel<br />
attr Total reading02Name SuperE5<br />
attr Total reading01Regex <span>Diesel</span>[^0-9]+([0-9\.]+)<br />
attr Total reading02Regex <span>Super E5</span>[^0-9]+([0-9\.]+)<br />
attr Total room Spritpreise<br />
attr Total stateFormat Liter_Diesel: Diesel<br />
attr Total timeout 5<br />
<br />
define Aral HTTPMOD http://www.clever-tanken.de/tankstelle_details/4869 600<br />
attr Aral group Spritpreise<br />
attr Aral icon tanken<br />
attr Aral reading01Name Diesel<br />
attr Aral reading02Name SuperE5<br />
attr Aral reading01Regex <span>Diesel</span>[^0-9]+([0-9\.]+)<br />
attr Aral reading02Regex <span>Super E5</span>[^0-9]+([0-9\.]+)<br />
attr Aral room Spritpreise<br />
attr Aral stateFormat Liter_Diesel: Diesel<br />
attr Aral timeout 5<br />
</pre><br />
<br />
Wer die Anzeige der Benzinpreise inklusive der obligatorisch abschließenden "9" möchte, muss zu jedem readingsName einen entsprechenden Zusatzzeile hinzufügen:<br />
<br />
<pre><br />
# Addiert zum Wert ($val) des Readings (readingsName_Diesel) den Wert 0.009<br />
attr Shell reading01OExpr $val + 0.009<br />
</pre><br />
<br />
Diese Zeile fügt dem Dieselpreis der Shell-Tankstelle bei einem Literpreis von 1.29 die Ziffer "9" hinzu und ergibt 1.299.<br />
<br />
<br />
Dazu kommen noch die Definitionen für das [[FileLog]]:<br />
<pre><br />
define FileLog_Spritpreise FileLog /media/usblog/fhem/log/spritpreise-langen-%Y-%m.log (Shell|Total|Aral):(SuperE5|Diesel).*<br />
attr FileLog_Spritpreise alias Log Spritpreise<br />
attr FileLog_Spritpreise group Logfile<br />
attr FileLog_Spritpreise logtype text<br />
attr FileLog_Spritpreise room Spritpreise<br />
</pre><br />
<br />
<br />
Sowie eine passende [[readingsGroup]]:<br />
<pre><br />
define Spritpreise readingsGroup (Shell|Total|Aral):(SuperE5|Diesel).*<br />
attr Spritpreise group Spritpreisuebersicht<br />
attr Spritpreise notime 1<br />
attr Spritpreise room Spritpreise<br />
#attr Spritpreise style style="font-size:16px" # führt ggf. zu einem PERL WARNING<br />
attr Spritpreise valueFormat {'%.2f €'}<br />
#attr Spritpreise valueStyle {Werte($READING,$VALUE)} # führt ggf. zu einem PERL WARNING<br />
</pre><br />
<br />
<br />
Und eine [[SVG|Plotdefinition]]<br />
<pre><br />
define SVG_FileLog_Spritpreise_1 SVG FileLog_Spritpreise:SVG_FileLog_Spritpreise_1:CURRENT<br />
attr SVG_FileLog_Spritpreise_1 group Spritpreisverlauf<br />
attr SVG_FileLog_Spritpreise_1 room Spritpreise<br />
</pre><br />
<br />
== Farbliche Hervorhebung ==<br />
Folgender Code gehört in [[99 myUtils anlegen|99_myUtils.pm]]; die Werte können natürlich entsprechend eigener Wünsche und Vorlieben angepasst werden.<br />
<pre><br />
###################################################<br />
### Spritpreisübersicht - Farbsortierung ###<br />
###################################################<br />
<br />
sub Werte($$) {<br />
my ($name, $wert) = @_;<br />
# Log(3,"$name $wert");<br />
if ($name eq "Diesel") {<br />
return 'style="color:red"' if($wert >= 1.39); <br />
return 'style="color:blue"' if(($wert >= 1.33) && ($wert < 1.39));<br />
return 'style="color:green;;font-weight:bold"' if($wert <= 1.32);<br />
}elsif ($name eq "SuperE10") {<br />
return 'style="color:crimson"' if($wert >= 1.70); <br />
return 'style="color:yellow"' if(($wert >= 1.55) && ($wert < 1.70));<br />
return 'style="color:lightgreen;;font-weight:bold"' if($wert < 1.55);<br />
}elsif ($name eq "SuperE5") {<br />
return 'style="color:red"' if($wert >= 1.59); <br />
return 'style="color:blue"' if(($wert >= 1.49) && ($wert < 1.59));<br />
return 'style="color:green;;font-weight:bold"' if($wert <= 1.48);<br />
} <br />
}<br />
</pre><br />
<br />
=== Die zugehörige .gplot Datei ===<br />
SVG_FileLog_Spritpreise_1.gplot<br />
<pre><br />
# Created by FHEM/98_SVG.pm, 2014-10-22 12:57:34<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 'Spritpreise'<br />
set ytics <br />
set y2tics <br />
set grid<br />
set ylabel "Preise (€/Liter)"<br />
set y2label "Preise (€/Liter)"<br />
<br />
#FileLog 4:Aral.Diesel\x3a:1:<br />
#FileLog 4:Shell.Diesel\x3a:1:<br />
#FileLog 4:Total.Diesel\x3a:1:<br />
#FileLog 4:Aral.SuperE5\x3a:1:<br />
#FileLog 4:Shell.SuperE5\x3a:1:<br />
#FileLog 4:Total.SuperE5\x3a:1:<br />
<br />
plot "<IN>" using 1:2 axes x1y2 title 'Aral Diesel' ls l2 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Shell Diesel' ls l1 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Total Diesel' ls l0 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Aral Super' ls l3 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Shell Super' ls l4 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Total Super' ls l5 lw 1 with lines<br />
</pre><br />
<br />
== Tricks für HTTPMOD ==<br />
Je nach Internetverbindung und Geschwindigkeit des FHEM Rechners kann das Modul manchmal Probleme haben, die Daten schnell genug zu verarbeiten.<br />
<br />
Eine Lösung dazu wäre, die Daten vorher mit wget auf einem eigenen Webserver zu speichern (z.B. ein lokaler Apache) und HTTPMOD auf diesen zugreifen zu lassen. <br />
<br />
== Links ==<br />
* Vorstellung und Diskussion im {{Link2Forum|Topic=22554|LinkText=FHEM Forum}}<br />
* Der "Datenlieferant": [http://www.clever-tanken.de/ Clever Tanken]<br />
* Eine Anleitung, wie man das mit wget macht, gibt es {{Link2Forum|Topic=28123|Message=216228|LinkText=hier}} (ist aber noch nicht ganz fertig)<br />
* Umsetzung für [http://www.cyberwulf.de/2016/fhem-spritpreise-von-tankerkoenig-de/ Tankerkönig API]<br />
<br />
[[Kategorie:Code Snippets]]<br />
[[Kategorie:Examples]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Spritpreismonitor&diff=23306Spritpreismonitor2017-11-15T10:56:03Z<p>Hauswart: /* Konfiguration */</p>
<hr />
<div>Die hier vorgestellten Fragmente ermöglichen es, mit Hilfe von [[HTTPMOD]] bei [http://www.clever-tanken.de clever-tanken.de] von Wunschtankstellen die Spritpreise zu protokollieren. Die Credits dafür gehen an Forum-Benutzer {{Link2FU|1774|Phil__}}. Die Original Diskussion im Forum ist {{Link2Forum|Topic=22554|Message=210795|LinkText=hier}}.<br />
<br />
Alternativ können die Kraftstoffpreise auch über die Webseite tankerkönig.de bezogen werden. Die Vorgehensweise dafür ist im Detail in [http://www.cyberwulf.de/2016/fhem-spritpreise-von-tankerkoenig-de/ diesem Blog] beschrieben.<br />
<br />
== Einleitung ==<br />
{{Randnotiz|RNTyp=y|RNText=Die gezeigten Anweisungen basieren noch auf einer alten Version (vor Februar 2016) des Moduls HTTPMOD. Das betrifft insbesondere die gewählten ''readings...''-Namen. Dieses Namensschema wird u.U. in Zukunft nicht mehr unterstützt.<br />
Zur Umstellung auf das aktuelle Namensschema (am Beispiel ''Shell'') bitte folgende Aktionen (Eingabe in das Befehlsfenster!) ausführen:<br />
:<code>attr Shell enableControlSet 1</code><br />
:<code>set Shell upgradeAttributes</code><br />
Im FHEM-Log sollten dann Meldungen auftauchen nach dem Schema <br />
:''Shell: upgraded attribute ... to new syntax ...''<br />
:''Shell: dropping readings... from userattr list''<br />
}}<br />
<br />
Im folgenden wird mit Hilfe des Moduls HTTPMOD der Spritpreis von ausgewählten Tankstellen abgerufen. Die Daten werden [[Regulärer Ausdruck|gefiltert]], gespeichert und als Diagramm aufbereitet.<br />
<br />
Zum Nachbau ist es erforderlich, "seine" Wunschtankstellen bei Clever-Tanken zu suchen. Jede Tankstelle hat eine eigene Nummer:<br />
:<code>/tankstelle_details/0815</code><br />
<br />
Die ''600'' in den Beispielen gibt das Abrufintervall in Sekunden an.<br />
<br />
== Konfiguration ==<br />
Die erforderlichen Definitionen in der FHEM [[Konfiguration]] bestehen aus mehreren Teilen. Zunächst die erforderlichen Einstellungen, um die Daten der gewünschten Tankstellen abzuholen:<br />
<br />
<pre><br />
define Shell HTTPMOD http://www.clever-tanken.de/tankstelle_details/4871 600<br />
attr Shell group Spritpreise<br />
attr Shell icon tanken<br />
attr Shell reading01Name Diesel<br />
attr Shell reading02Name SuperE5<br />
attr Shell reading01Regex <span>Diesel</span>[^0-9]+([0-9\.]+)<br />
attr Shell reading02Regex <span>Super E5</span>[^0-9]+([0-9\.]+)<br />
attr Shell room Spritpreise<br />
attr Shell stateFormat Liter_Diesel: Diesel<br />
attr Shell timeout 5<br />
<br />
define Total HTTPMOD http://www.clever-tanken.de/tankstelle_details/4870 600<br />
attr Total group Spritpreise<br />
attr Total icon tanken<br />
attr Total reading01Name Diesel<br />
attr Total reading02Name SuperE5<br />
attr Total reading01Regex <span>Diesel</span>[^0-9]+([0-9\.]+)<br />
attr Total reading02Regex <span>Super E5</span>[^0-9]+([0-9\.]+)<br />
attr Total room Spritpreise<br />
attr Total stateFormat Liter_Diesel: Diesel<br />
attr Total timeout 5<br />
<br />
define Aral HTTPMOD http://www.clever-tanken.de/tankstelle_details/4869 600<br />
attr Aral group Spritpreise<br />
attr Aral icon tanken<br />
attr Aral reading01Name Diesel<br />
attr Aral reading02Name SuperE5<br />
attr Aral reading01Regex <span>Diesel</span>[^0-9]+([0-9\.]+)<br />
attr Aral reading02Regex <span>Super E5</span>[^0-9]+([0-9\.]+)<br />
attr Aral room Spritpreise<br />
attr Aral stateFormat Liter_Diesel: Diesel<br />
attr Aral timeout 5<br />
</pre><br />
<br />
Wer die Anzeige der Benzinpreise inklusive der obligatorisch abschließenden "9" möchte, muss zu jedem readingsName einen entsprechenden Zusatzzeile hinzufügen:<br />
<br />
<pre><br />
# Addiert zum Wert ($val) des Readings (readingsName_Diesel) den Wert 0.009<br />
attr Shell reading01Expr $val + 0.009<br />
</pre><br />
<br />
Diese Zeile fügt dem Dieselpreis der Shell-Tankstelle bei einem Literpreis von 1.29 die Ziffer "9" hinzu und ergibt 1.299.<br />
<br />
<br />
Dazu kommen noch die Definitionen für das [[FileLog]]:<br />
<pre><br />
define FileLog_Spritpreise FileLog /media/usblog/fhem/log/spritpreise-langen-%Y-%m.log (Shell|Total|Aral):(SuperE5|Diesel).*<br />
attr FileLog_Spritpreise alias Log Spritpreise<br />
attr FileLog_Spritpreise group Logfile<br />
attr FileLog_Spritpreise logtype text<br />
attr FileLog_Spritpreise room Spritpreise<br />
</pre><br />
<br />
<br />
Sowie eine passende [[readingsGroup]]:<br />
<pre><br />
define Spritpreise readingsGroup (Shell|Total|Aral):(SuperE5|Diesel).*<br />
attr Spritpreise group Spritpreisuebersicht<br />
attr Spritpreise notime 1<br />
attr Spritpreise room Spritpreise<br />
#attr Spritpreise style style="font-size:16px" # führt ggf. zu einem PERL WARNING<br />
attr Spritpreise valueFormat {'%.2f €'}<br />
#attr Spritpreise valueStyle {Werte($READING,$VALUE)} # führt ggf. zu einem PERL WARNING<br />
</pre><br />
<br />
<br />
Und eine [[SVG|Plotdefinition]]<br />
<pre><br />
define SVG_FileLog_Spritpreise_1 SVG FileLog_Spritpreise:SVG_FileLog_Spritpreise_1:CURRENT<br />
attr SVG_FileLog_Spritpreise_1 group Spritpreisverlauf<br />
attr SVG_FileLog_Spritpreise_1 room Spritpreise<br />
</pre><br />
<br />
== Farbliche Hervorhebung ==<br />
Folgender Code gehört in [[99 myUtils anlegen|99_myUtils.pm]]; die Werte können natürlich entsprechend eigener Wünsche und Vorlieben angepasst werden.<br />
<pre><br />
###################################################<br />
### Spritpreisübersicht - Farbsortierung ###<br />
###################################################<br />
<br />
sub Werte($$) {<br />
my ($name, $wert) = @_;<br />
# Log(3,"$name $wert");<br />
if ($name eq "Diesel") {<br />
return 'style="color:red"' if($wert >= 1.39); <br />
return 'style="color:blue"' if(($wert >= 1.33) && ($wert < 1.39));<br />
return 'style="color:green;;font-weight:bold"' if($wert <= 1.32);<br />
}elsif ($name eq "SuperE10") {<br />
return 'style="color:crimson"' if($wert >= 1.70); <br />
return 'style="color:yellow"' if(($wert >= 1.55) && ($wert < 1.70));<br />
return 'style="color:lightgreen;;font-weight:bold"' if($wert < 1.55);<br />
}elsif ($name eq "SuperE5") {<br />
return 'style="color:red"' if($wert >= 1.59); <br />
return 'style="color:blue"' if(($wert >= 1.49) && ($wert < 1.59));<br />
return 'style="color:green;;font-weight:bold"' if($wert <= 1.48);<br />
} <br />
}<br />
</pre><br />
<br />
=== Die zugehörige .gplot Datei ===<br />
SVG_FileLog_Spritpreise_1.gplot<br />
<pre><br />
# Created by FHEM/98_SVG.pm, 2014-10-22 12:57:34<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 'Spritpreise'<br />
set ytics <br />
set y2tics <br />
set grid<br />
set ylabel "Preise (€/Liter)"<br />
set y2label "Preise (€/Liter)"<br />
<br />
#FileLog 4:Aral.Diesel\x3a:1:<br />
#FileLog 4:Shell.Diesel\x3a:1:<br />
#FileLog 4:Total.Diesel\x3a:1:<br />
#FileLog 4:Aral.SuperE5\x3a:1:<br />
#FileLog 4:Shell.SuperE5\x3a:1:<br />
#FileLog 4:Total.SuperE5\x3a:1:<br />
<br />
plot "<IN>" using 1:2 axes x1y2 title 'Aral Diesel' ls l2 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Shell Diesel' ls l1 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Total Diesel' ls l0 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Aral Super' ls l3 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Shell Super' ls l4 lw 1 with lines,\<br />
"<IN>" using 1:2 axes x1y2 title 'Total Super' ls l5 lw 1 with lines<br />
</pre><br />
<br />
== Tricks für HTTPMOD ==<br />
Je nach Internetverbindung und Geschwindigkeit des FHEM Rechners kann das Modul manchmal Probleme haben, die Daten schnell genug zu verarbeiten.<br />
<br />
Eine Lösung dazu wäre, die Daten vorher mit wget auf einem eigenen Webserver zu speichern (z.B. ein lokaler Apache) und HTTPMOD auf diesen zugreifen zu lassen. <br />
<br />
== Links ==<br />
* Vorstellung und Diskussion im {{Link2Forum|Topic=22554|LinkText=FHEM Forum}}<br />
* Der "Datenlieferant": [http://www.clever-tanken.de/ Clever Tanken]<br />
* Eine Anleitung, wie man das mit wget macht, gibt es {{Link2Forum|Topic=28123|Message=216228|LinkText=hier}} (ist aber noch nicht ganz fertig)<br />
* Umsetzung für [http://www.cyberwulf.de/2016/fhem-spritpreise-von-tankerkoenig-de/ Tankerkönig API]<br />
<br />
[[Kategorie:Code Snippets]]<br />
[[Kategorie:Examples]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=SetList&diff=23305SetList2017-11-15T10:20:35Z<p>Hauswart: /* Beispiele */</p>
<hr />
<div>{{SEITENTITEL:setList}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<!-- Infobox Attribut sinnvoll? --><br />
<br />
Das Attribut [[setList]] dient dazu, bei generischen Devices die Liste der möglichen set Kommandos zu spezifizieren. <br />
<br />
{{Todo|Bitte analog zu [[eventMap]] mit Inhalt füllen.}}<br />
<br />
== Syntax ==<br />
Das ''setList'' Attribut wird in der folgenden Weise spezifiziert:<br />
<br />
== Einschränkungen == <br />
Dieses Attribut existiert nur bei [[dummy]]- und [[readingsProxy]]-Devices. <br />
<br />
== Beispiele ==<br />
<br />
define Raumtemperatur dummy<br />
attr Raumtemperatur setList state:slider,10,0.5,30<br />
attr Raumtemperatur readingList state<br />
attr Raumtemperatur webCmd state<br />
<br />
define Wecker_Uhrzeit dummy<br />
attr Wecker_Uhrzeit setList state:AUS,05:00,05:15,05:30,05:45,06:00,06:15,06:30,06:35,06:40,06:45,06:50,06:55,07:00,07:05,07:10,07:15,07:20,07:25,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00,10:15,10:30,10:45,11:00,11:15,11:30,11:45,12:00,12:15,12:30,12:45,13:00,13:15,13:30,13:45,14:00,14:15,14:30,14:45,15:00,15:15,15:30,15:45,16:00,16:15,16:30,16:45,17:00,17:15,17:30,17:45,18:00,18:15,18:30,18:45,19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00,22:15,22:30,22:45,23:00,23:15,23:30,23:45,00:00,00:15,00:30,00:45,01:00,01:15,01:30,01:45,02:00,02:15,02:30,02:45,03:00,03:15,03:30,03:45,04:00,04:15,04:30,04:45<br />
attr Wecker_Uhrzeit readingList state<br />
attr Wecker_Uhrzeit webCmd state<br />
<br />
define Beschattung_auto dummy<br />
attr Beschattung_auto setList state:aktiv,passiv<br />
attr Beschattung_auto readingList state<br />
attr Beschattung_auto webCmd state<br />
<br />
define Heizungsmodus dummy<br />
attr Heizungsmodus setList state:auto,FHEM,Frostschutz,AUS<br />
attr Heizungsmodus readingList state<br />
attr Heizungsmodus webCmd state<br />
<br />
define TV_ProgrammKanal dummy<br />
attr TV_ProgrammKanal setList ARD_Ch ZDF_Ch HR_Ch RTL_Ch Sat1_Ch VOX_Ch Pro7_Ch Kabel1_Ch COMEDYCENTRAL_Ch DREISAT_Ch ARTE_Ch EINSPLUS_Ch EINSFESTIVAL_Ch ZDFNEO_Ch NDR_Ch MDR_Ch BR_Ch RBB_Ch SWR_Ch WDR_Ch RTL2_Ch SUPERRTL_Ch SPORT1_Ch EUROSPORT_Ch DMAX_Ch N24_Ch NTV_Ch RTLNITRO_Ch SAT1GOLD_Ch SIXX_Ch TELE5_Ch<br />
attr TV_ProgrammKanal readingList state<br />
<br />
define benzinpreis dummy<br />
attr benzinpreis readingList SuperE5_2 SuperPlus_2<br />
attr benzinpreis setList SuperE5_2:slider,140,1,200 SuperPlus_2:slider,140,1,200<br />
attr oil stateFormat SuperE5, SuperPlus<br />
attr oil userReadings SuperE5 {(ReadingsVal("oil","SuperE5_2",0) / 100 )}, SuperPlus {(ReadingsVal("oil","SuperPlus_2",0) / 100 )}<br />
attr oil webCmd SuperE5_2:SuperPlus_2<br />
<br />
== Links ==<br />
* Ausführliche Beschreibung (mit Beispielen) zu [[eventMap]], [[devStateIcon]], setList und [[webCmd]] in {{Link2Forum|Topic=12080|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=SetList&diff=23304SetList2017-11-15T10:19:31Z<p>Hauswart: /* Beispiele */</p>
<hr />
<div>{{SEITENTITEL:setList}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<!-- Infobox Attribut sinnvoll? --><br />
<br />
Das Attribut [[setList]] dient dazu, bei generischen Devices die Liste der möglichen set Kommandos zu spezifizieren. <br />
<br />
{{Todo|Bitte analog zu [[eventMap]] mit Inhalt füllen.}}<br />
<br />
== Syntax ==<br />
Das ''setList'' Attribut wird in der folgenden Weise spezifiziert:<br />
<br />
== Einschränkungen == <br />
Dieses Attribut existiert nur bei [[dummy]]- und [[readingsProxy]]-Devices. <br />
<br />
== Beispiele ==<br />
<br />
define Raumtemperatur dummy<br />
attr Raumtemperatur setList state:slider,10,0.5,30<br />
attr Raumtemperatur readingList state<br />
attr Raumtemperatur webCmd state<br />
<br />
define Wecker_Uhrzeit dummy<br />
attr Wecker_Uhrzeit setList state:AUS,05:00,05:15,05:30,05:45,06:00,06:15,06:30,06:35,06:40,06:45,06:50,06:55,07:00,07:05,07:10,07:15,07:20,07:25,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00,10:15,10:30,10:45,11:00,11:15,11:30,11:45,12:00,12:15,12:30,12:45,13:00,13:15,13:30,13:45,14:00,14:15,14:30,14:45,15:00,15:15,15:30,15:45,16:00,16:15,16:30,16:45,17:00,17:15,17:30,17:45,18:00,18:15,18:30,18:45,19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00,22:15,22:30,22:45,23:00,23:15,23:30,23:45,00:00,00:15,00:30,00:45,01:00,01:15,01:30,01:45,02:00,02:15,02:30,02:45,03:00,03:15,03:30,03:45,04:00,04:15,04:30,04:45<br />
attr Wecker_Uhrzeit readingList state<br />
attr Wecker_Uhrzeit webCmd state<br />
<br />
define Beschattung_auto dummy<br />
attr Beschattung_auto setList state:aktiv,passiv<br />
attr Beschattung_auto readingList state<br />
attr Beschattung_auto webCmd state<br />
<br />
define Heizungsmodus dummy<br />
attr Heizungsmodus setList state:auto,FHEM,Frostschutz,AUS<br />
attr Heizungsmodus readingList state<br />
attr Heizungsmodus webCmd state<br />
<br />
define TV_ProgrammKanal dummy<br />
attr TV_ProgrammKanal setList ARD_Ch ZDF_Ch HR_Ch RTL_Ch Sat1_Ch VOX_Ch Pro7_Ch Kabel1_Ch COMEDYCENTRAL_Ch DREISAT_Ch ARTE_Ch EINSPLUS_Ch EINSFESTIVAL_Ch ZDFNEO_Ch NDR_Ch MDR_Ch BR_Ch RBB_Ch SWR_Ch WDR_Ch RTL2_Ch SUPERRTL_Ch SPORT1_Ch EUROSPORT_Ch DMAX_Ch N24_Ch NTV_Ch RTLNITRO_Ch SAT1GOLD_Ch SIXX_Ch TELE5_Ch<br />
attr TV_ProgrammKanal readingList state<br />
<br />
define benzinpreis dummy<br />
attr benzinpreis readingList SuperE5_2 SuperPlus_2<br />
attr benzinpreis setList SuperE5_2:slider,140,1,200 SuperPlus_2:slider,140,1,200<br />
attr oil stateFormat SuperE5, SuperPlus<br />
attr oil userReadings SuperE5 {(ReadingsVal("oil","SuperE5_2",0) / 100 )},\<br />
SuperPlus {(ReadingsVal("oil","SuperPlus_2",0) / 100 )}<br />
attr oil webCmd SuperE5_2:SuperPlus_2<br />
<br />
== Links ==<br />
* Ausführliche Beschreibung (mit Beispielen) zu [[eventMap]], [[devStateIcon]], setList und [[webCmd]] in {{Link2Forum|Topic=12080|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=SetList&diff=23302SetList2017-11-15T10:06:55Z<p>Hauswart: /* Beispiele */</p>
<hr />
<div>{{SEITENTITEL:setList}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<!-- Infobox Attribut sinnvoll? --><br />
<br />
Das Attribut [[setList]] dient dazu, bei generischen Devices die Liste der möglichen set Kommandos zu spezifizieren. <br />
<br />
{{Todo|Bitte analog zu [[eventMap]] mit Inhalt füllen.}}<br />
<br />
== Syntax ==<br />
Das ''setList'' Attribut wird in der folgenden Weise spezifiziert:<br />
<br />
== Einschränkungen == <br />
Dieses Attribut existiert nur bei [[dummy]]- und [[readingsProxy]]-Devices. <br />
<br />
== Beispiele ==<br />
<br />
define Raumtemperatur dummy<br />
attr Raumtemperatur setList state:slider,10,0.5,30<br />
attr Raumtemperatur readingList state<br />
attr Raumtemperatur webCmd state<br />
<br />
define Wecker_Uhrzeit dummy<br />
attr Wecker_Uhrzeit setList state:AUS,05:00,05:15,05:30,05:45,06:00,06:15,06:30,06:35,06:40,06:45,06:50,06:55,07:00,07:05,07:10,07:15,07:20,07:25,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00,10:15,10:30,10:45,11:00,11:15,11:30,11:45,12:00,12:15,12:30,12:45,13:00,13:15,13:30,13:45,14:00,14:15,14:30,14:45,15:00,15:15,15:30,15:45,16:00,16:15,16:30,16:45,17:00,17:15,17:30,17:45,18:00,18:15,18:30,18:45,19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00,22:15,22:30,22:45,23:00,23:15,23:30,23:45,00:00,00:15,00:30,00:45,01:00,01:15,01:30,01:45,02:00,02:15,02:30,02:45,03:00,03:15,03:30,03:45,04:00,04:15,04:30,04:45<br />
attr Wecker_Uhrzeit readingList state<br />
attr Wecker_Uhrzeit webCmd state<br />
<br />
define Beschattung_auto dummy<br />
attr Beschattung_auto setList state:aktiv,passiv<br />
attr Beschattung_auto readingList state<br />
attr Beschattung_auto webCmd state<br />
<br />
define Heizungsmodus dummy<br />
attr Heizungsmodus setList state:auto,FHEM,Frostschutz,AUS<br />
attr Heizungsmodus readingList state<br />
attr Heizungsmodus webCmd state<br />
<br />
define TV_ProgrammKanal dummy<br />
attr TV_ProgrammKanal setList ARD_Ch ZDF_Ch HR_Ch RTL_Ch Sat1_Ch VOX_Ch Pro7_Ch Kabel1_Ch COMEDYCENTRAL_Ch DREISAT_Ch ARTE_Ch EINSPLUS_Ch EINSFESTIVAL_Ch ZDFNEO_Ch NDR_Ch MDR_Ch BR_Ch RBB_Ch SWR_Ch WDR_Ch RTL2_Ch SUPERRTL_Ch SPORT1_Ch EUROSPORT_Ch DMAX_Ch N24_Ch NTV_Ch RTLNITRO_Ch SAT1GOLD_Ch SIXX_Ch TELE5_Ch<br />
attr TV_ProgrammKanal readingList state<br />
<br />
== Links ==<br />
* Ausführliche Beschreibung (mit Beispielen) zu [[eventMap]], [[devStateIcon]], setList und [[webCmd]] in {{Link2Forum|Topic=12080|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=SetList&diff=23301SetList2017-11-15T10:05:24Z<p>Hauswart: /* Beispiele */</p>
<hr />
<div>{{SEITENTITEL:setList}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<!-- Infobox Attribut sinnvoll? --><br />
<br />
Das Attribut [[setList]] dient dazu, bei generischen Devices die Liste der möglichen set Kommandos zu spezifizieren. <br />
<br />
{{Todo|Bitte analog zu [[eventMap]] mit Inhalt füllen.}}<br />
<br />
== Syntax ==<br />
Das ''setList'' Attribut wird in der folgenden Weise spezifiziert:<br />
<br />
== Einschränkungen == <br />
Dieses Attribut existiert nur bei [[dummy]]- und [[readingsProxy]]-Devices. <br />
<br />
== Beispiele ==<br />
<br />
define Raumtemperatur dummy<br />
attr Raumtemperatur setList state:slider,10,0.5,30,1<br />
attr Raumtemperatur readingList state<br />
attr Raumtemperatur webCmd state<br />
<br />
define Wecker_Uhrzeit dummy<br />
attr Wecker_Uhrzeit setList state:AUS,05:00,05:15,05:30,05:45,06:00,06:15,06:30,06:35,06:40,06:45,06:50,06:55,07:00,07:05,07:10,07:15,07:20,07:25,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00,10:15,10:30,10:45,11:00,11:15,11:30,11:45,12:00,12:15,12:30,12:45,13:00,13:15,13:30,13:45,14:00,14:15,14:30,14:45,15:00,15:15,15:30,15:45,16:00,16:15,16:30,16:45,17:00,17:15,17:30,17:45,18:00,18:15,18:30,18:45,19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00,22:15,22:30,22:45,23:00,23:15,23:30,23:45,00:00,00:15,00:30,00:45,01:00,01:15,01:30,01:45,02:00,02:15,02:30,02:45,03:00,03:15,03:30,03:45,04:00,04:15,04:30,04:45<br />
attr Wecker_Uhrzeit readingList state<br />
attr Wecker_Uhrzeit webCmd state<br />
<br />
define Beschattung_auto dummy<br />
attr Beschattung_auto setList state:aktiv,passiv<br />
attr Beschattung_auto readingList state<br />
attr Beschattung_auto webCmd state<br />
<br />
define Heizungsmodus dummy<br />
attr Heizungsmodus setList state:auto,FHEM,Frostschutz,AUS<br />
attr Heizungsmodus readingList state<br />
attr Heizungsmodus webCmd state<br />
<br />
define TV_ProgrammKanal dummy<br />
attr TV_ProgrammKanal setList ARD_Ch ZDF_Ch HR_Ch RTL_Ch Sat1_Ch VOX_Ch Pro7_Ch Kabel1_Ch COMEDYCENTRAL_Ch DREISAT_Ch ARTE_Ch EINSPLUS_Ch EINSFESTIVAL_Ch ZDFNEO_Ch NDR_Ch MDR_Ch BR_Ch RBB_Ch SWR_Ch WDR_Ch RTL2_Ch SUPERRTL_Ch SPORT1_Ch EUROSPORT_Ch DMAX_Ch N24_Ch NTV_Ch RTLNITRO_Ch SAT1GOLD_Ch SIXX_Ch TELE5_Ch<br />
attr TV_ProgrammKanal readingList state<br />
<br />
== Links ==<br />
* Ausführliche Beschreibung (mit Beispielen) zu [[eventMap]], [[devStateIcon]], setList und [[webCmd]] in {{Link2Forum|Topic=12080|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=SetList&diff=23300SetList2017-11-15T10:00:05Z<p>Hauswart: /* Beispiele */</p>
<hr />
<div>{{SEITENTITEL:setList}} <!-- da richtige Schreibweise kleinen Anfangsbuchstaben hat --><br />
<!-- Infobox Attribut sinnvoll? --><br />
<br />
Das Attribut [[setList]] dient dazu, bei generischen Devices die Liste der möglichen set Kommandos zu spezifizieren. <br />
<br />
{{Todo|Bitte analog zu [[eventMap]] mit Inhalt füllen.}}<br />
<br />
== Syntax ==<br />
Das ''setList'' Attribut wird in der folgenden Weise spezifiziert:<br />
<br />
== Einschränkungen == <br />
Dieses Attribut existiert nur bei [[dummy]]- und [[readingsProxy]]-Devices. <br />
<br />
== Beispiele ==<br />
<br />
define Raumtemperatur dummy<br />
attr Raumtemperatur setList state:slider,10,0.5,30,1<br />
attr Raumtemperatur readingList state<br />
<br />
attr Wecker_Uhrzeit setList state:AUS,05:00,05:15,05:30,05:45,06:00,06:15,06:30,06:35,06:40,06:45,06:50,06:55,07:00,07:05,07:10,07:15,07:20,07:25,07:30,07:45,08:00,08:15,08:30,08:45,09:00,09:15,09:30,09:45,10:00,10:15,10:30,10:45,11:00,11:15,11:30,11:45,12:00,12:15,12:30,12:45,13:00,13:15,13:30,13:45,14:00,14:15,14:30,14:45,15:00,15:15,15:30,15:45,16:00,16:15,16:30,16:45,17:00,17:15,17:30,17:45,18:00,18:15,18:30,18:45,19:00,19:15,19:30,19:45,20:00,20:15,20:30,20:45,21:00,21:15,21:30,21:45,22:00,22:15,22:30,22:45,23:00,23:15,23:30,23:45,00:00,00:15,00:30,00:45,01:00,01:15,01:30,01:45,02:00,02:15,02:30,02:45,03:00,03:15,03:30,03:45,04:00,04:15,04:30,04:45<br />
attr Wecker_Uhrzeit readingList state<br />
<br />
attr Beschattung_auto setList state:aktiv,passiv<br />
attr Heizungsmodus setList state:auto,FHEM,Frostschutz,AUS<br />
attr TV_ProgrammKanal setList ARD_Ch ZDF_Ch HR_Ch RTL_Ch Sat1_Ch VOX_Ch Pro7_Ch Kabel1_Ch COMEDYCENTRAL_Ch DREISAT_Ch ARTE_Ch EINSPLUS_Ch EINSFESTIVAL_Ch ZDFNEO_Ch NDR_Ch MDR_Ch BR_Ch RBB_Ch SWR_Ch WDR_Ch RTL2_Ch SUPERRTL_Ch SPORT1_Ch EUROSPORT_Ch DMAX_Ch N24_Ch NTV_Ch RTLNITRO_Ch SAT1GOLD_Ch SIXX_Ch TELE5_Ch<br />
<br />
== Links ==<br />
* Ausführliche Beschreibung (mit Beispielen) zu [[eventMap]], [[devStateIcon]], setList und [[webCmd]] in {{Link2Forum|Topic=12080|LinkText=diesem Forenthread}}<br />
<br />
[[Kategorie:Attribut (allgemeingültig)]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=HomeMatic_Devices_pairen&diff=22846HomeMatic Devices pairen2017-10-06T09:37:01Z<p>Hauswart: /* Pairing verifizieren */</p>
<hr />
<div>HomeMatic Geräte müssen mit dem für das HomeMatic-Protokoll eingesetzten IO-Device (zB [[CUL]], CUN, [[HomeMatic|Homematic IO's]]) ''[[Pairing (HomeMatic)|gepairt]]'' (deutsch: "gepaart") werden, damit sie von FHEM gesteuert oder ausgelesen werden können.<br />
<br />
<br />
Die Adresse eines HomeMatic Gerätes ist nicht frei einstellbar, sondern für jedes Gerät fest vorgegeben. Da die HM-Geräte über eine sehr komplexe Kanalstruktur verfügen, empfiehlt sich daher, die Geräte in FHEM per ''autocreate'' Funktion anlegen zu lassen, Eine nachträgliche Umbenennung oder manuelle Bearbeitung der erzeugten Konfigurationsdaten ist problemlos möglich.<br />
<br />
Zunächst mal muss man einen [[HomeMatic_Installieren|CUL/CUN/Homematic IO installieren]]. <br />
<br />
Einige Geräte werden mit aktivierter [[AES Encryption]] ausgeliefert (Meistens, aber nicht immer mit SEC im Namen). Das Anlernen an HM IO's funktioniert ohne Probleme, für alle CUL Derivate muss unbedingt der Hinweis im Artikel AES Encryption im Abschnitt I/O-Device <-> Gerät beachtet werden. '''Die dort beschriebene Installation sollte generell vorgenommen werden!'''<br />
<br />
Danach geht es hier weiter:<br />
<br />
= Grundlagen=<br />
Durch das Pairing wird ein HM-Gerät genau einem IO-Device (zB CUL) zugeordnet. Wenn ein Gerät mit dem IO-Device gepairt ist, kann es darüber gesteuert werden. <br />
<br />
Beim Pairing wird die HMID des IO-Device in das Gerät geschrieben. Das Pairing findet also im Wesentlichen im Gerät statt, nicht in FHEM selbst.<br />
<br />
Zu bemerken ist, dass ein IO-Device (zB CUL) standardmäßig die ID F11034 von FHEM erhält. Da viele HM-Geräte das IO-Device nur anhand der HMIDs erkennen, können alle in Reichweite der HM-Geräte befindlichen IO-Devices mit der in das HM-Gerät geschriebenen HMID das HM-Gerät steuern. Hinzu kommt, dass die ''autocreate'' Funktion die in Reichweite befindlichen HM-Geräte findet und automatisch einbindet. Nachbarn, die IO-Devices mit der gleichen HMID betreiben, können also HM-Geräte untereinander sehen und steuern!<br />
<br />
Es ist daher dringen zu empfehlen, die HMID vor dem Pairing der HM-Geräte mit: <br />
<br />
attr <CUL> hmId <6-stellige Hexadresse><br />
<br />
zu individualisieren. <br />
<br />
Gepairt wird nur das Device. Die Channels sind dem Device untergeordnet und somit implizit auch gepairt. <br />
<br />
'''Achtung:''' Ist ein Device gepairt werden Konfigurationsänderungen über die Zentrale (FHEM) vorgenommen. Man kann u.a. keine Kanäle mehr ''direkt'' peeren (verknüpfen). Stattdessen verwendet man Kommandos in FHEM. Siehe <u>[[Homematic_Peering_Beispiele|peeren]]</u><br />
<br />
= IO-Device in den Pairing-Modus versetzen =<br />
* CUL/CUN/HMLAN Konfigurator in den "Akzeptiere-Pairing-Requests-Modus" bringen:<br />
<br />
set <CUL> hmPairForSec 600<br />
<br />
600 bedeutet hier, dass das IO-Device 600 Sekunden, also 10 Minuten lang im Pairing-Modus ist.<br />
<br />
Bei aktivem Pairing-Modus gibt das IO-Device folgende ''Internals'' Variable zurück: <br />
<br />
hmPair 1<br />
<br />
Alternativ kann <br />
<br />
set <CUL> hmPairSerial <serial><br />
<br />
genutzt werden.<br />
<br />
= Devices pairen =<br />
<br />
Das Gerät wird in den Anlern- oder auch Konfigurationsmode versetzt. Es sendet hierzu eine entsprechende Nachricht an alle. <br />
Das Vorgehen ist stark vom Gerät(Typ) abhängig, bitte unbedingt das Handbuch lesen: Stichwort "anlernen". <br />
<br />
Falls das Gerät einen separaten Anlernknopf hat, ist der normalerweise nur ganz kurz zu drücken. <br />
Danach beginnt die LED regelmäßig zu blinken.<br />
<br />
Hat das Gerät keinen separaten Anlernknopf, muss in der Regel eine Taste solange gedrückt werden, bis die LED anfängt regelmäßig zu blinken.<br />
<br />
Kommt der Anlernvorgang in Gang, wird dies durch ein wechselndes, schnelles Blinken signalisiert. Kommt kein Anlernvorgang zustande, blinkt die LED regelmäßig für einen bestimmten Zeitraum (ca. 20 sec). <br />
Ist das Gerät schon gepairt, werden bei batteriebetriebenen Geräten eventuell auch noch nicht übertragende Daten gesendet. Dabei blinkt die LED auch unregelmäßig.<br />
{{Randnotiz|RNText=Hinweis: Das genaue Vorgehen ist bei jedem Gerätetyp anders -> unbedingt Handbuch genau lesen!}}<br />
In FHEM werden nun:<br />
* alle fehlenden Devices und Channels angelegt<br />
* das Register pairCentral im Device gesetzt. <br />
<br />
Ein save danach sichert die neu gepairten Geräte in der Konfiguration.<br />
<br />
Hinweis: Auch mit hmPairForSec kann jeweils nur '''ein''' Device gepaired werden. Für mehrere Devices den Vorgang bitte wiederholen.<br />
<br />
= Pairing verifizieren =<br />
Nur weil ein Gerät angelegt wurde, heißt das '''nicht''', dass es auch gepaired ist. In den Readings eines Devices muss stehen (list <name> oder im Webinterface):<br />
<br />
R_pairCentral 0xABCDEF<br />
<br />
ABCDEF steht dabei für die HMID des IO-Device (zB CUL). Wurde für das IO-Device kein attribute mit einer individuellen HMID gesetzt, sollte hier die Standard-ID F11034 stehen. Die führende 0x steht für den Hinweis auf eine HEX-Adresse. <br />
<br />
Ist das Pairing noch nicht abgeschlossen, kann man nach kurzer Pause den Befehl: <br />
<br />
set <HM-Gerät> getConfig <br />
<br />
absetzen, um zu prüfen, ob sich der Status zwischenzeitlich geändert hat. Wenn das Reading R_pairCentral nicht auftaucht oder der Wert mit set_ beginnt hat das Pairing '''nicht''' geklappt. Man kann entweder:<br />
* noch einmal probieren, ein getConfig auszulösen - vielleicht hat das Lesen nicht funktioniert<br />
* noch einmal pairen - das schadet nichts<br />
* die Anlerntaste / Configtaste / irgendeine Taste am Gerät (hängt vom konkreten Device ab) wiederholt drücken um die Datenübertragung anzustoßen.<br />
<br />
Alternativ kann man auch mit HMinfo einen Config check durchführen:<br />
<br />
define hm HMInfo<br />
get hm configCheck<br />
<br />
= Vorgehen bei Problemen =<br />
<br />
Wenn das Pairing nicht erfolgreich ist, das Gerät sich also nicht steuern lässt, ist es möglich, dass es schon bzw. noch mit einem anderen IO-Device gepairt ist. Dann das Gerät in den Auslieferungszustand bringen (siehe Handbuch, oft Knopf mindestens 5 Sekunden drücken, bis es blinkt, dann loslassen und nochmals 5 Sekunden drücken, bis es schneller blinkt) und danach erneut pairen. <br />
<br />
Alternativ kann das Pairing per Befehl gelöst werden. Siehe dazu unten. <br />
<br />
Wenn das zu pairende Geräte ein Empfänger ist, kann mit FHEM per Telnet oder in der Kommandozeile des Webinterfaces folgendes Kommando abgesetzt werden:<br />
<br />
set <CUL> hmPairSerial <10-stellige Seriennummer><br />
<br />
Die 10-stellige Seriennummer ist beim Empfängern idR. auf der Rückseite des Geräte aufgedruckt. Die Seriennummer fängt normalerweise mit Buchstaben an und endet mit Zahlen.<br />
<br />
Es gilt auch sicherzustellen, dass das zu pairende Gerät nicht bereits zuvor mit der Homematic Config Software gepairt wurde. Ist dies der Fall, so sollte das Pairing in der Homematic Config Software gelöscht und das Pairing in FHEM erneut durchgeführt werden.<br />
<br />
Beim Pairen ist, wie im normalen Betrieb auch, ein Mindestabstand (etwa 1-2 Meter) zwischen dem Sender der Zentrale (CUL, HMLAN etc.) einzuhalten, da die Funkempfänger sonst mit Übersteuerung reagieren und keine Kommunikation zustande kommt.<br />
Außerdem kann die Funklast beim Auslesen einer unfangreichen Konfiguration eines Gerätes bereits nach wenigen Versuchen das Limit der 1%-Regel erreichen. Sollte also scheinbar keine Kommunikation stattfinden können, ist auch zu prüfen, ob der Zentralensender sich deswegen temporär deaktiviert hat.<br />
<br />
= Gezieltes Pairing =<br />
Bei bereits bekanntem HM-Gerät kann man mit:<br />
<br />
set <Name HM-Gerät> pair<br />
<br />
das pairing überschreiben. Es funktioniert aber nur, wenn schon ein IO-Device eingetragen ist.<br />
<br />
= Pairing lösen =<br />
Das Pairing kann mit:<br />
<br />
set <Name HM-Gerät> unpair<br />
<br />
gelöst werden. Wichtig ist dabei, dass das IO-Device, das entpairt werden soll, mit der ursprünglich in das HM-Gerät geschriebenen HMID konfiguriert ist. <br />
<br />
[[Kategorie:HomeMatic Components]]<br />
[[Kategorie:HOWTOS]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=ABFALL&diff=22810ABFALL2017-10-02T16:08:10Z<p>Hauswart: /* Pushbullet Beispiel */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Filtern von (Abfall-)Terminen aus einem Calendar.<br />
|ModType=x<br />
|ModFTopic=48237<br />
|ModForumArea=Codeschnipsel<br />
|ModTechName=57_ABFALL.pm<br />
|ModOwner=Constantin / {{Link2FU|14026|uniqueck}}<br />
}}<br />
<br />
[[ABFALL]] ist ein (inoffizielles, nicht Bestandteil der Distribution) Hilfsmodul, das bestimmte Termine aus einem bestehenden Kalender des Moduls [[Calendar]] in Readings übernimmt. <br />
<br />
== Voraussetzungen ==<br />
Es muss ein [[Calendar]]-Objekt definiert sein. Der dabei benutzte Name muss in der Definition des ABFALL-Objekts spezifiziert werden.<br />
Es können auch mehrere Calendar Objekte übergeben werden.<br />
<br />
Sonderzeichen aus dem Namen der Termine, werden entfernt um die Namen der generierten Readings FHEM tauglich zu machen, für die Werte der Readings bleiben diese allerdings erhalten.<br />
<br />
== Anwendung ==<br />
=== Installation ===<br />
Mit folgendem Befehl kann das Modul direkt in den Standard FHEM Update Prozess eingeklinkt werden.<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
Um es nur zu installieren, kann auch einfach nur das Command<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
eingegeben werden.<br />
<br />
=== Entwicklungsstrang ===<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
bzw.<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
<br />
=== Define ===<br />
:<code>define <Name> ABFALL <calendarname>,<calendarname2>,...</code><br />
<br />
Erläuterung der Parameter im '''define''':<br />
;<calendarname><br />
:Name des '''Calendar''' Kalenders <br />
<br />
Beispiel:<br />
:<code>define AbfallGoogleCalender Calendar ical url https://......</code><br />
:<code>define myABFALL ABFALL AbfallGoogleCalender</code><br />
<br />
=== Werte aktualisieren ===<br />
Die Werte aktualisieren sich abhängig vom [[notify]] der entsprechenden Calendar Instanz, welche im define angegeben wurde(n).<br />
<br />
=== Weitere Attribute ===<br />
<br />
{| class="wikitable"<br />
!Attribut<br />
!Werteliste<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |calendarname_praefix<br />
|0 und 1<br />
|soll der Kalendername als praefix dem Reading vorangestellt werden, sollte bei nur einem Kalender auf 0 gesetzt werden<br />
|1 - praefix wird vorangestellt<br />
|-<br />
!align="right" |abfall_clear_reading_regex<br />
|<br />
|regex zum Entfernen von Anteilen aus dem Termin, dieser wird vor dem Entfernen von Sonderzeichen aus den Namen der Termine angewandt.<br />
|<br />
|-<br />
!align="right" |disable<br />
|0 und 1<br />
|deaktiviert das Modul<br />
|0<br />
|-<br />
!align="right" |weekday_mapping<br />
|<br />
|Mapping, wie die Readings der Tage angezeigt werden sollen, zum Beispiel So Mo Di Mi Do Fr Sa<br />
|Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag<br />
|-<br />
!align="right" |delimiter_text_reading<br />
|<br />
|Wenn zwei Abholungen an ein und demselben Tag existieren, wird dieses Trennzeichen genutzt, um die beiden (oder mehrere) Werte zu einem Text zu verbinden. Nur relevant für die Readings next_text und now_text<br />
|und<br />
|-<br />
!align="right" |delimiter_reading<br />
|<br />
|wie attribute delimiter_text_reading, allerdings nur für die readings next und now<br />
|<br />
|-<br />
!align="right" |filter<br />
|<br />
|regex zum Filtern der Namen der Termine aus den Kalendern, so dass nur solche genutzt werden, welche diesem Filter entsprechen<br />
|<br />
|-<br />
|}<br />
<br />
== Anwendungsbeispiel(e) ==<br />
=== Einbindung ins Tablet UI ===<br />
<pre><div data-device="myABFALL" data-type="symbol" class="bigger warn wider" <br />
data-get="next" data-get-warn=".*(\d+).*" <br />
data-get-on='["Restmuell_.*","Wertstoff_.*"]'<br />
data-on-colors='["#000","#6EB54C"]' <br />
data-icons='["fa-trash-o","fa-trash-o"]'></div></pre><br />
<br />
=== Einbindung ins Tablet UI, erweitert ===<br />
Fallen die Leerungen zweier verschiedener Tonnen nicht auf den selben Tag, reicht es normalerweise, nur ein Symbol auf der Oberfläche zu platzieren und dieses dann dynamisch zu befüllen. In folgendem Beispiel werden folgende Anforderungen umgesetzt:<br />
* Anzeige unterschiedlicher Symbole bzw. Farben für Papiertonne, Restmülltonne, Biotonne und gelbe Säcke<br />
* Anzeige der verbleibenden Tage bis zur Leerung als "Warn"-Marker in Rot, aber nur, wenn die Leerung innerhalb der nächsten 2 Tage ist<br />
* Blinken des Symbols, wenn die nächste Leerung morgen ansteht<br />
* Rotation des Symbols, wenn die nächste Leerung noch am selben Tag ansteht. Nach einer bestimmten Uhrzeit (z.B. 9 Uhr morgens) soll dann auf die nächste Tonne geschaltet werden<br />
* Anzeige des Datums bzw. von "heute" oder "morgen" unter dem Symbol als Label<br />
<br />
Zur Datumsanzeige wird eine kleine Hilfsfunktion in die 99_myUtils eingebaut. <br />
<syntaxhighlight lang="perl"><br />
sub datumHeuteMorgen($){<br />
my $compareDate = shift;<br />
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);<br />
$year += 1900; $mon += 1; <br />
my $heute = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time+86400);<br />
$year += 1900; $mon += 1;<br />
my $morgen = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
return "heute" if $compareDate eq $heute;<br />
return "morgen" if $compareDate eq $morgen;<br />
return $compareDate;<br />
}<br />
</syntaxhighlight><br />
Diese Funktion wird in den userReadings des Abfall-Moduls verwendet. Das Abfallmodul erzeugt eine Gruppe von Readings mit dem Namen now_*, wenn die Leerung am selben Tag ansteht, bzw. genau dann, wenn der Termin im zu Grunde liegenden Kalender gerade aktiv ist. In diesem Beispiel liegt dem Kalender-Modul ein Google-Kalender zu Grunde, bei dem die Termine immer von 0 Uhr bis 9 Uhr morgens eingetragen sind. Dadurch wird erreicht, dass die Anzeige nach 9 Uhr weiterspringt, weil dann die now-Readings verschwinden.<br />
<br />
Folgende userReadings werden zum Abfallmodul hinzugefügt, welches in diesem Beispiel "abf.abfall" genannt ist:<br />
<syntaxhighlight lang="perl"><br />
attr myABFALL userReadings ftui_datum {ReadingsVal("myABFALL","now_text","") eq "" ? datumHeuteMorgen(ReadingsVal("myABFALL","next_datum","")) : "heute";},ftui_next {ReadingsVal("myABFALL","now_text","") eq "" ? ReadingsVal("myABFALL","next","") : ReadingsVal("myABFALL","now","")."_0";;}<br />
</syntaxhighlight><br />
Das Reading "ftui_next" bildet die Grundlage für das Symbol in TabletUI, das Reading "ftui_datum" wird für das Label genutzt. <br />
<br />
Somit lässt sich ganze in FTUI wie folgt darstellen:<br />
<syntaxhighlight lang="html"><br />
<div data-device="myABFALL" <br />
data-type="symbol"<br />
data-get="ftui_next"<br />
data-get-on='["Biotonne_0$","Biotonne_1$","Biotonne_.*","GelberSack_0$","GelberSack_1$","GelberSack_.*","Papiertonne_0$","Papiertonne_1$","Papiertonne_.*","Restmuelltonne_0$","Restmuelltonne_1$","Restmuelltonne_.*"]'<br />
data-get-warn=".*([0|1|2]).*"<br />
data-on-colors='["#8B4513","#8B4513","#8B4513","#f4e946","#f4e946","#f4e946","#2d9e1c","#2d9e1c","#2d9e1c","#696969","#696969","#696969"]'<br />
class="large warn"<br />
data-icons='["fa-trash-o fa-spin","fa-trash-o blink","fa-trash-o","fs-bag fa-spin","fs-bag blink","fs-bag","fs-dustbin fa-spin","fs-dustbin blink","fs-dustbin","fa-trash fa-spin","fa-trash blink","fa-trash"]'<br />
/><br />
<div data-device="myABFALL" data-get="ftui_datum" data-type="label"/><br />
</syntaxhighlight><br />
Für Jede Tonne werden hier drei Zustände unterschieden und einzeln in "data-get-on", "data-on-colors" und "data-icons" zugeordnet. Daher haben diese Listen jeweils 12 Einträge.<br />
<br />
=== Benachrichtigung ===<br />
==== DOIF ====<br />
====== TelegramBot Beispiel ======<br />
<pre>[myABFALL:next_days] == 1) ( set fhemBot message 'Morgen wird [myABFALL:next_text] abgeholt')<br />
[myABFALL:now_text] ne "") ( set fhemBot message 'Heute wird [myABFALL:now_text] abgeholt')</pre><br />
<br />
====== Pushbullet Beispiel ======<br />
<br />
Die morgigen Leerungen per Push um 19:30 mittels Pushbullet:<br />
<br />
<code>define dAbfallmorgen doif ([19:30] and [myABFALL:next_days] == 1) (msg |Morgen wird [myABFALL:next_text] abgeholt)<br />
<br />
attr dAbfallmorgen do always</code><br />
<br />
Die heutigen Leerungen per Push um 07:00 mittels Pushbullet:<br />
<br />
<code>define dAbfallheute doif ([07:00] and [myABFALL:now_text] ne "") (msg |Heute wird [myABFALL:now_text] abgeholt)<br />
<br />
attr dAbfallheute do always</code><br />
<br />
=== Links ===<br />
* Forenthema {{Link2Forum|Topic=50177|LinkText=Abfall Visualisierung mit Bilderrahmen}}</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=ABFALL&diff=22809ABFALL2017-10-02T16:06:56Z<p>Hauswart: /* Pushbullet Beispiel */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Filtern von (Abfall-)Terminen aus einem Calendar.<br />
|ModType=x<br />
|ModFTopic=48237<br />
|ModForumArea=Codeschnipsel<br />
|ModTechName=57_ABFALL.pm<br />
|ModOwner=Constantin / {{Link2FU|14026|uniqueck}}<br />
}}<br />
<br />
[[ABFALL]] ist ein (inoffizielles, nicht Bestandteil der Distribution) Hilfsmodul, das bestimmte Termine aus einem bestehenden Kalender des Moduls [[Calendar]] in Readings übernimmt. <br />
<br />
== Voraussetzungen ==<br />
Es muss ein [[Calendar]]-Objekt definiert sein. Der dabei benutzte Name muss in der Definition des ABFALL-Objekts spezifiziert werden.<br />
Es können auch mehrere Calendar Objekte übergeben werden.<br />
<br />
Sonderzeichen aus dem Namen der Termine, werden entfernt um die Namen der generierten Readings FHEM tauglich zu machen, für die Werte der Readings bleiben diese allerdings erhalten.<br />
<br />
== Anwendung ==<br />
=== Installation ===<br />
Mit folgendem Befehl kann das Modul direkt in den Standard FHEM Update Prozess eingeklinkt werden.<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
Um es nur zu installieren, kann auch einfach nur das Command<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
eingegeben werden.<br />
<br />
=== Entwicklungsstrang ===<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
bzw.<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
<br />
=== Define ===<br />
:<code>define <Name> ABFALL <calendarname>,<calendarname2>,...</code><br />
<br />
Erläuterung der Parameter im '''define''':<br />
;<calendarname><br />
:Name des '''Calendar''' Kalenders <br />
<br />
Beispiel:<br />
:<code>define AbfallGoogleCalender Calendar ical url https://......</code><br />
:<code>define myABFALL ABFALL AbfallGoogleCalender</code><br />
<br />
=== Werte aktualisieren ===<br />
Die Werte aktualisieren sich abhängig vom [[notify]] der entsprechenden Calendar Instanz, welche im define angegeben wurde(n).<br />
<br />
=== Weitere Attribute ===<br />
<br />
{| class="wikitable"<br />
!Attribut<br />
!Werteliste<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |calendarname_praefix<br />
|0 und 1<br />
|soll der Kalendername als praefix dem Reading vorangestellt werden, sollte bei nur einem Kalender auf 0 gesetzt werden<br />
|1 - praefix wird vorangestellt<br />
|-<br />
!align="right" |abfall_clear_reading_regex<br />
|<br />
|regex zum Entfernen von Anteilen aus dem Termin, dieser wird vor dem Entfernen von Sonderzeichen aus den Namen der Termine angewandt.<br />
|<br />
|-<br />
!align="right" |disable<br />
|0 und 1<br />
|deaktiviert das Modul<br />
|0<br />
|-<br />
!align="right" |weekday_mapping<br />
|<br />
|Mapping, wie die Readings der Tage angezeigt werden sollen, zum Beispiel So Mo Di Mi Do Fr Sa<br />
|Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag<br />
|-<br />
!align="right" |delimiter_text_reading<br />
|<br />
|Wenn zwei Abholungen an ein und demselben Tag existieren, wird dieses Trennzeichen genutzt, um die beiden (oder mehrere) Werte zu einem Text zu verbinden. Nur relevant für die Readings next_text und now_text<br />
|und<br />
|-<br />
!align="right" |delimiter_reading<br />
|<br />
|wie attribute delimiter_text_reading, allerdings nur für die readings next und now<br />
|<br />
|-<br />
!align="right" |filter<br />
|<br />
|regex zum Filtern der Namen der Termine aus den Kalendern, so dass nur solche genutzt werden, welche diesem Filter entsprechen<br />
|<br />
|-<br />
|}<br />
<br />
== Anwendungsbeispiel(e) ==<br />
=== Einbindung ins Tablet UI ===<br />
<pre><div data-device="myABFALL" data-type="symbol" class="bigger warn wider" <br />
data-get="next" data-get-warn=".*(\d+).*" <br />
data-get-on='["Restmuell_.*","Wertstoff_.*"]'<br />
data-on-colors='["#000","#6EB54C"]' <br />
data-icons='["fa-trash-o","fa-trash-o"]'></div></pre><br />
<br />
=== Einbindung ins Tablet UI, erweitert ===<br />
Fallen die Leerungen zweier verschiedener Tonnen nicht auf den selben Tag, reicht es normalerweise, nur ein Symbol auf der Oberfläche zu platzieren und dieses dann dynamisch zu befüllen. In folgendem Beispiel werden folgende Anforderungen umgesetzt:<br />
* Anzeige unterschiedlicher Symbole bzw. Farben für Papiertonne, Restmülltonne, Biotonne und gelbe Säcke<br />
* Anzeige der verbleibenden Tage bis zur Leerung als "Warn"-Marker in Rot, aber nur, wenn die Leerung innerhalb der nächsten 2 Tage ist<br />
* Blinken des Symbols, wenn die nächste Leerung morgen ansteht<br />
* Rotation des Symbols, wenn die nächste Leerung noch am selben Tag ansteht. Nach einer bestimmten Uhrzeit (z.B. 9 Uhr morgens) soll dann auf die nächste Tonne geschaltet werden<br />
* Anzeige des Datums bzw. von "heute" oder "morgen" unter dem Symbol als Label<br />
<br />
Zur Datumsanzeige wird eine kleine Hilfsfunktion in die 99_myUtils eingebaut. <br />
<syntaxhighlight lang="perl"><br />
sub datumHeuteMorgen($){<br />
my $compareDate = shift;<br />
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);<br />
$year += 1900; $mon += 1; <br />
my $heute = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time+86400);<br />
$year += 1900; $mon += 1;<br />
my $morgen = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
return "heute" if $compareDate eq $heute;<br />
return "morgen" if $compareDate eq $morgen;<br />
return $compareDate;<br />
}<br />
</syntaxhighlight><br />
Diese Funktion wird in den userReadings des Abfall-Moduls verwendet. Das Abfallmodul erzeugt eine Gruppe von Readings mit dem Namen now_*, wenn die Leerung am selben Tag ansteht, bzw. genau dann, wenn der Termin im zu Grunde liegenden Kalender gerade aktiv ist. In diesem Beispiel liegt dem Kalender-Modul ein Google-Kalender zu Grunde, bei dem die Termine immer von 0 Uhr bis 9 Uhr morgens eingetragen sind. Dadurch wird erreicht, dass die Anzeige nach 9 Uhr weiterspringt, weil dann die now-Readings verschwinden.<br />
<br />
Folgende userReadings werden zum Abfallmodul hinzugefügt, welches in diesem Beispiel "abf.abfall" genannt ist:<br />
<syntaxhighlight lang="perl"><br />
attr myABFALL userReadings ftui_datum {ReadingsVal("myABFALL","now_text","") eq "" ? datumHeuteMorgen(ReadingsVal("myABFALL","next_datum","")) : "heute";},ftui_next {ReadingsVal("myABFALL","now_text","") eq "" ? ReadingsVal("myABFALL","next","") : ReadingsVal("myABFALL","now","")."_0";;}<br />
</syntaxhighlight><br />
Das Reading "ftui_next" bildet die Grundlage für das Symbol in TabletUI, das Reading "ftui_datum" wird für das Label genutzt. <br />
<br />
Somit lässt sich ganze in FTUI wie folgt darstellen:<br />
<syntaxhighlight lang="html"><br />
<div data-device="myABFALL" <br />
data-type="symbol"<br />
data-get="ftui_next"<br />
data-get-on='["Biotonne_0$","Biotonne_1$","Biotonne_.*","GelberSack_0$","GelberSack_1$","GelberSack_.*","Papiertonne_0$","Papiertonne_1$","Papiertonne_.*","Restmuelltonne_0$","Restmuelltonne_1$","Restmuelltonne_.*"]'<br />
data-get-warn=".*([0|1|2]).*"<br />
data-on-colors='["#8B4513","#8B4513","#8B4513","#f4e946","#f4e946","#f4e946","#2d9e1c","#2d9e1c","#2d9e1c","#696969","#696969","#696969"]'<br />
class="large warn"<br />
data-icons='["fa-trash-o fa-spin","fa-trash-o blink","fa-trash-o","fs-bag fa-spin","fs-bag blink","fs-bag","fs-dustbin fa-spin","fs-dustbin blink","fs-dustbin","fa-trash fa-spin","fa-trash blink","fa-trash"]'<br />
/><br />
<div data-device="myABFALL" data-get="ftui_datum" data-type="label"/><br />
</syntaxhighlight><br />
Für Jede Tonne werden hier drei Zustände unterschieden und einzeln in "data-get-on", "data-on-colors" und "data-icons" zugeordnet. Daher haben diese Listen jeweils 12 Einträge.<br />
<br />
=== Benachrichtigung ===<br />
==== DOIF ====<br />
====== TelegramBot Beispiel ======<br />
<pre>[myABFALL:next_days] == 1) ( set fhemBot message 'Morgen wird [myABFALL:next_text] abgeholt')<br />
[myABFALL:now_text] ne "") ( set fhemBot message 'Heute wird [myABFALL:now_text] abgeholt')</pre><br />
<br />
====== Pushbullet Beispiel ======<br />
<br />
Die morgigen Leerungen per Push um 19:30 mittels Pushbullet:<br />
<br />
<code>define dAbfallmorgen doif ([19:30] and [myABFALL:next_days] == 1) ( msg |Morgen wird [myABFALL:next_text] abgeholt)<br />
<br />
attr dAbfallmorgen do always</code><br />
<br />
Die heutigen Leerungen per Push um 07:00 mittels Pushbullet:<br />
<br />
<code>define dAbfallheute doif ([07:00] and [myABFALL:now_text] ne "") ( msg |Heute wird [myABFALL:now_text] abgeholt)<br />
<br />
attr dAbfallheute do always</code><br />
<br />
=== Links ===<br />
* Forenthema {{Link2Forum|Topic=50177|LinkText=Abfall Visualisierung mit Bilderrahmen}}</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=ABFALL&diff=22808ABFALL2017-10-02T16:06:46Z<p>Hauswart: /* TelegramBot Beispiel */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Filtern von (Abfall-)Terminen aus einem Calendar.<br />
|ModType=x<br />
|ModFTopic=48237<br />
|ModForumArea=Codeschnipsel<br />
|ModTechName=57_ABFALL.pm<br />
|ModOwner=Constantin / {{Link2FU|14026|uniqueck}}<br />
}}<br />
<br />
[[ABFALL]] ist ein (inoffizielles, nicht Bestandteil der Distribution) Hilfsmodul, das bestimmte Termine aus einem bestehenden Kalender des Moduls [[Calendar]] in Readings übernimmt. <br />
<br />
== Voraussetzungen ==<br />
Es muss ein [[Calendar]]-Objekt definiert sein. Der dabei benutzte Name muss in der Definition des ABFALL-Objekts spezifiziert werden.<br />
Es können auch mehrere Calendar Objekte übergeben werden.<br />
<br />
Sonderzeichen aus dem Namen der Termine, werden entfernt um die Namen der generierten Readings FHEM tauglich zu machen, für die Werte der Readings bleiben diese allerdings erhalten.<br />
<br />
== Anwendung ==<br />
=== Installation ===<br />
Mit folgendem Befehl kann das Modul direkt in den Standard FHEM Update Prozess eingeklinkt werden.<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
Um es nur zu installieren, kann auch einfach nur das Command<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
eingegeben werden.<br />
<br />
=== Entwicklungsstrang ===<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
bzw.<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
<br />
=== Define ===<br />
:<code>define <Name> ABFALL <calendarname>,<calendarname2>,...</code><br />
<br />
Erläuterung der Parameter im '''define''':<br />
;<calendarname><br />
:Name des '''Calendar''' Kalenders <br />
<br />
Beispiel:<br />
:<code>define AbfallGoogleCalender Calendar ical url https://......</code><br />
:<code>define myABFALL ABFALL AbfallGoogleCalender</code><br />
<br />
=== Werte aktualisieren ===<br />
Die Werte aktualisieren sich abhängig vom [[notify]] der entsprechenden Calendar Instanz, welche im define angegeben wurde(n).<br />
<br />
=== Weitere Attribute ===<br />
<br />
{| class="wikitable"<br />
!Attribut<br />
!Werteliste<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |calendarname_praefix<br />
|0 und 1<br />
|soll der Kalendername als praefix dem Reading vorangestellt werden, sollte bei nur einem Kalender auf 0 gesetzt werden<br />
|1 - praefix wird vorangestellt<br />
|-<br />
!align="right" |abfall_clear_reading_regex<br />
|<br />
|regex zum Entfernen von Anteilen aus dem Termin, dieser wird vor dem Entfernen von Sonderzeichen aus den Namen der Termine angewandt.<br />
|<br />
|-<br />
!align="right" |disable<br />
|0 und 1<br />
|deaktiviert das Modul<br />
|0<br />
|-<br />
!align="right" |weekday_mapping<br />
|<br />
|Mapping, wie die Readings der Tage angezeigt werden sollen, zum Beispiel So Mo Di Mi Do Fr Sa<br />
|Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag<br />
|-<br />
!align="right" |delimiter_text_reading<br />
|<br />
|Wenn zwei Abholungen an ein und demselben Tag existieren, wird dieses Trennzeichen genutzt, um die beiden (oder mehrere) Werte zu einem Text zu verbinden. Nur relevant für die Readings next_text und now_text<br />
|und<br />
|-<br />
!align="right" |delimiter_reading<br />
|<br />
|wie attribute delimiter_text_reading, allerdings nur für die readings next und now<br />
|<br />
|-<br />
!align="right" |filter<br />
|<br />
|regex zum Filtern der Namen der Termine aus den Kalendern, so dass nur solche genutzt werden, welche diesem Filter entsprechen<br />
|<br />
|-<br />
|}<br />
<br />
== Anwendungsbeispiel(e) ==<br />
=== Einbindung ins Tablet UI ===<br />
<pre><div data-device="myABFALL" data-type="symbol" class="bigger warn wider" <br />
data-get="next" data-get-warn=".*(\d+).*" <br />
data-get-on='["Restmuell_.*","Wertstoff_.*"]'<br />
data-on-colors='["#000","#6EB54C"]' <br />
data-icons='["fa-trash-o","fa-trash-o"]'></div></pre><br />
<br />
=== Einbindung ins Tablet UI, erweitert ===<br />
Fallen die Leerungen zweier verschiedener Tonnen nicht auf den selben Tag, reicht es normalerweise, nur ein Symbol auf der Oberfläche zu platzieren und dieses dann dynamisch zu befüllen. In folgendem Beispiel werden folgende Anforderungen umgesetzt:<br />
* Anzeige unterschiedlicher Symbole bzw. Farben für Papiertonne, Restmülltonne, Biotonne und gelbe Säcke<br />
* Anzeige der verbleibenden Tage bis zur Leerung als "Warn"-Marker in Rot, aber nur, wenn die Leerung innerhalb der nächsten 2 Tage ist<br />
* Blinken des Symbols, wenn die nächste Leerung morgen ansteht<br />
* Rotation des Symbols, wenn die nächste Leerung noch am selben Tag ansteht. Nach einer bestimmten Uhrzeit (z.B. 9 Uhr morgens) soll dann auf die nächste Tonne geschaltet werden<br />
* Anzeige des Datums bzw. von "heute" oder "morgen" unter dem Symbol als Label<br />
<br />
Zur Datumsanzeige wird eine kleine Hilfsfunktion in die 99_myUtils eingebaut. <br />
<syntaxhighlight lang="perl"><br />
sub datumHeuteMorgen($){<br />
my $compareDate = shift;<br />
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);<br />
$year += 1900; $mon += 1; <br />
my $heute = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time+86400);<br />
$year += 1900; $mon += 1;<br />
my $morgen = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
return "heute" if $compareDate eq $heute;<br />
return "morgen" if $compareDate eq $morgen;<br />
return $compareDate;<br />
}<br />
</syntaxhighlight><br />
Diese Funktion wird in den userReadings des Abfall-Moduls verwendet. Das Abfallmodul erzeugt eine Gruppe von Readings mit dem Namen now_*, wenn die Leerung am selben Tag ansteht, bzw. genau dann, wenn der Termin im zu Grunde liegenden Kalender gerade aktiv ist. In diesem Beispiel liegt dem Kalender-Modul ein Google-Kalender zu Grunde, bei dem die Termine immer von 0 Uhr bis 9 Uhr morgens eingetragen sind. Dadurch wird erreicht, dass die Anzeige nach 9 Uhr weiterspringt, weil dann die now-Readings verschwinden.<br />
<br />
Folgende userReadings werden zum Abfallmodul hinzugefügt, welches in diesem Beispiel "abf.abfall" genannt ist:<br />
<syntaxhighlight lang="perl"><br />
attr myABFALL userReadings ftui_datum {ReadingsVal("myABFALL","now_text","") eq "" ? datumHeuteMorgen(ReadingsVal("myABFALL","next_datum","")) : "heute";},ftui_next {ReadingsVal("myABFALL","now_text","") eq "" ? ReadingsVal("myABFALL","next","") : ReadingsVal("myABFALL","now","")."_0";;}<br />
</syntaxhighlight><br />
Das Reading "ftui_next" bildet die Grundlage für das Symbol in TabletUI, das Reading "ftui_datum" wird für das Label genutzt. <br />
<br />
Somit lässt sich ganze in FTUI wie folgt darstellen:<br />
<syntaxhighlight lang="html"><br />
<div data-device="myABFALL" <br />
data-type="symbol"<br />
data-get="ftui_next"<br />
data-get-on='["Biotonne_0$","Biotonne_1$","Biotonne_.*","GelberSack_0$","GelberSack_1$","GelberSack_.*","Papiertonne_0$","Papiertonne_1$","Papiertonne_.*","Restmuelltonne_0$","Restmuelltonne_1$","Restmuelltonne_.*"]'<br />
data-get-warn=".*([0|1|2]).*"<br />
data-on-colors='["#8B4513","#8B4513","#8B4513","#f4e946","#f4e946","#f4e946","#2d9e1c","#2d9e1c","#2d9e1c","#696969","#696969","#696969"]'<br />
class="large warn"<br />
data-icons='["fa-trash-o fa-spin","fa-trash-o blink","fa-trash-o","fs-bag fa-spin","fs-bag blink","fs-bag","fs-dustbin fa-spin","fs-dustbin blink","fs-dustbin","fa-trash fa-spin","fa-trash blink","fa-trash"]'<br />
/><br />
<div data-device="myABFALL" data-get="ftui_datum" data-type="label"/><br />
</syntaxhighlight><br />
Für Jede Tonne werden hier drei Zustände unterschieden und einzeln in "data-get-on", "data-on-colors" und "data-icons" zugeordnet. Daher haben diese Listen jeweils 12 Einträge.<br />
<br />
=== Benachrichtigung ===<br />
==== DOIF ====<br />
====== TelegramBot Beispiel ======<br />
<pre>[myABFALL:next_days] == 1) ( set fhemBot message 'Morgen wird [myABFALL:next_text] abgeholt')<br />
[myABFALL:now_text] ne "") ( set fhemBot message 'Heute wird [myABFALL:now_text] abgeholt')</pre><br />
<br />
====== Pushbullet Beispiel ======<br />
<br />
Die morgigen Leerungen per Push um 19:30 mittels Pushbullet:<br />
<br />
<code>define dAbfallmorgen doif ([19:30] and [myABFALL:next_tage] == 1) ( msg |Morgen wird [myABFALL:next_text] abgeholt)<br />
<br />
attr dAbfallmorgen do always</code><br />
<br />
Die heutigen Leerungen per Push um 07:00 mittels Pushbullet:<br />
<br />
<code>define dAbfallheute doif ([07:00] and [myABFALL:now_text] ne "") ( msg |Heute wird [myABFALL:now_text] abgeholt)<br />
<br />
attr dAbfallheute do always</code><br />
<br />
=== Links ===<br />
* Forenthema {{Link2Forum|Topic=50177|LinkText=Abfall Visualisierung mit Bilderrahmen}}</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Batterie%C3%BCberwachung&diff=22661Batterieüberwachung2017-09-22T08:33:06Z<p>Hauswart: /* Erweiterung des Geräts um battery-Reading */</p>
<hr />
<div>Verschiedene batteriebetriebene Geräte ([[:Kategorie:HomeMatic Components|Homematic]], RFXtrx, ZWave,..) übermitteln unter anderem den Zustand der eingelegten Batterie. Bei diesen kann der Batteriestatus übersichtlich dargestellt und / oder aktiv überwacht werden. Bei Geräten ohne eigenen Batteriestatus muss man diesen "nachrüsten".<br />
<br />
== Geräte mit Batteriestatus ==<br />
=== Übersichtsdarstellung per readingsGroup ===<br />
Mit Hilfe einer ReadingsGroup kann einfach eine Übersicht aller Geräte mit "battery"-Reading erstellt werden, s. [[ReadingsGroup#Auswahl_.C3.BCber_Reading-Namen.2C_Status_als_Symbol_dargestellt|hier]].<br />
<br />
=== Benachrichtigung per notify ===<br />
Um Ausfälle frühzeitig zu erkennen, kann man sich per E-Mail benachrichtigen lassen, sobald eine Batteriemeldung mit etwas anderem als "ok" gesendet wird (z.B. "low"). Zusätzlich erzeugt der unten stehende Code einen Eintrag im Logfile.<br />
<br />
<nowiki>define n_batt_chk notify .*:[Bb]attery.* { if ($EVENT !~ m/ok/) { \<br />
{ FB_mail('recipient@internet.de', 'FHEM Batteriewarnung', $NAME.': '.$EVENT)};; \<br />
Log 3, "$NAME : Batteriewarnung $EVENT";; \<br />
} \<br />
}</nowiki><br />
<br />
'''Achtung:''' Für Nutzer eines [[HM-CC-RT-DN_Funk-Heizk%C3%B6rperthermostat|HM-CC-RT-DN]] muss der Code anders aussehen, da mit diesem Thermostat erstmalig der aktuelle Spannungswert der Batterie gesendet wird, also z.B.:<br />
<br />
UG.Treppe.Heizung batteryLevel: 3.1 V<br />
<br />
Man würde bei der Verwendung des o.g. Codes bei jeder Batteriemeldung eines HM-CC-RT-DN eine E-Mail erhalten. Daher muss der o.g. Code wie folgt geändert werden (Doppelpunkt hinter "[Bb]attery"):<br />
<br />
<nowiki>define n_batt_chk notify .*:[Bb]attery:.* { if($EVENT !~ m/ok/) { \<br />
{ FB_mail('recipient@internet.de', 'FHEM Batteriewarnung', $NAME.': '.$EVENT)};; \<br />
Log 3, "$NAME: Batteriewarnung $EVENT";; \<br />
} \<br />
}</nowiki><br />
<br />
Achtung: FB_mail setzt die Installation auf einer FritzBox voraus. Für andere Hardware-/OS-Plattformen ist die Vorgehensweise unter dem Titel [[E-Mail_senden]] beschrieben.<br />
<br />
Testen kann man dies z.B. mit <code>trigger HeizungWZ Battery:low</code><br />
<br />
Man sollte auch darauf achten, dass sich das Ereignis, auf das man triggert, nicht zu häufig wiederholt (z.B. durch das Attribut <code>event-on-change-reading</code>).<br />
<br />
== Geräte ohne Batteriestatus ==<br />
Bei Geräten ohne Reading für den Batteriestatus kann man diesen auf verschiedene Weisen schätzen und als Reading eintragen. Dies funktioniert aber natürlich nur, wenn das Gerät sendet - bei einem rein empfangenden Aktor wie dem [[FHT 8v direkt ansprechen|FHT Stellantrieb]] klappt es also nicht... <br />
<br />
=== Erweiterung des Geräts um battery-Reading ===<br />
Mit Hilfe von [http://fhem.de/commandref_DE.html#userReadings userReadings] kann man recht einfach einen Batteriestatus schätzen und als Reading bereitstellen. Dann greift auch direkt die oben beschriebene Auswertung.<br />
<br />
Die Idee ist, den zeitlichen Abstand des aktuellen Timestamps mit dem letzten geloggten Timestamp zu vergleichen und daraus auf den Batteriestatus zu schliessen - bspw. Abstand > 10min = Batterie low.<br />
<br />
Dazu muss lediglich folgendes userReading für jedes batteriebetriebene Device (ohne Batteriestatus) angelegt werden (um bei >10min "low" zu setzen): <br />
<br />
; Konfiguration:<br />
Lediglich der Schwellwert (600) braucht nach Wunsch angepasst zu werden, alles andere passt automatisch (vgl. [[Notify#Hinweise]]).<br />
<br />
; Im Webinterface:<br />
<pre><br />
battery { return "ok" if ( (time_str2num(ReadingsTimestamp($NAME,"state","0")) - time_str2num(OldTimestamp($NAME))) < 600 ); return "low" }<br />
</pre><br />
<br />
; Alternativ im Config-File:<br />
<pre><br />
attr MeinSensor userReadings battery { return "ok" if ( (time_str2num(ReadingsTimestamp($NAME,"state","0")) - time_str2num(OldTimestamp($NAME))) < 600 ); return "low" }<br />
</pre><br />
<br />
; Erläuterung:<br />
: <code>$NAME</code> - ist die Variable für das Device (und braucht nicht angepasst zu werden)<br />
: <code>battery {...}</code> - Name des userreadings mit Spezifikation, vgl. [http://fhem.de/commandref_DE.html#userReadings]<br />
: <code>return "ok" if ( ... ); return "low"</code> - Spezifikation: Reading = "ok", wenn if erfüllt, sonst "low"<br />
: <code>time_str2num(ReadingsTimestamp($NAME,"state","0")</code> - Aktueller Timestamp in Sekunden, vgl. [http://fhem.de/commandref_DE.html#perl], [[Notify#Hinweise]]<br />
: <code>time_str2num(OldTimestamp($NAME))</code> - Letzter Timestamp im Log in Sekunden (egal ob FileLog oder DbLog), vgl. [http://fhem.de/commandref_DE.html#perl], [[Notify#Hinweise]]<br />
: <code>600</code> - Schwellwert für "low" (600 sec = 10 min), nach Bedarf anpassen<br />
<br />
=== Alternativ per Skript ===<br />
Andere Komponenten, wie z. B. [[:Kategorie:FS20 Components|FS20 Komponenten]], übermitteln keinen Batteriestatus. <br />
<br />
Um dort dennoch einen Test darauf zu machen, ob die Batterie evtl. leer ist, kann man z. B. prüfen, wann der letzte Status des jeweiligen Gerätes empfangen wurde, etwa mit folgender Funktion in [[99_myUtils_anlegen|99_myUtils.pm]]:<br />
<br />
<pre>sub check_if_alive($$) {<br />
# Expects:<br />
# 1. Devicename to be checked<br />
# 2. Age in hours, after the expiry of which with no new state the device will be considered as dead.<br />
# Returns:<br />
# 0 -> Device dead<br />
# 1 -> Device alive<br />
# 2 -> Error<br />
my ($Device,$hours_threshold) = @_;<br />
my ($Device) = @_;<br />
my $now = time;<br />
my $Timestamp = ReadingsTimestamp($Device,"state","0");<br />
if ($Timestamp eq "0") {<br />
return 2;<br />
}<br />
<br />
my @splitdatetime = split(/ /,$Timestamp);<br />
my @splitdate = split(/-/, $splitdatetime[0]);<br />
my @splittime = split(/:/, $splitdatetime[1]);<br />
my $last_state_time = timelocal($splittime[2], $splittime[1], $splittime[0], $splitdate[2], $splitdate[1]-1, $splitdate[0]);<br />
my $age_in_hours = ($now - $last_state_time) / 3600;<br />
<br />
if ($age_in_hours > $hours_threshold) {<br />
Log 1, ("check_if_alive: $Device dead, last state was $age_in_hours hours ago");<br />
return 0;<br />
} else {<br />
return 1;<br />
}<br />
<br />
}</pre><br />
<br />
Diese Funktion kann man z.B. in einem at je zu prüfendem Gerät regelmäßig (z. B. einmal am Tag um 05:55 Uhr) aufrufen, und testen, ob die letzten 12 Stunden etwas empfangen wurde:<br />
<br />
<pre>*05:55:55 { <br />
check_if_alive("KS300", 12);<br />
}</pre><br />
<br />
KS300 ist dabei der Name des Devices in fhem. <br />
<br />
Wenn das Gerät nicht geantwortet hat, erzeugt die oben vorgeschlagene Funktion einen Logeintrag.<br />
<br />
Hinweis: Dieser Batterietest schlägt natürlich auch an, wenn die FS20 Geräte noch funktionieren, aber der CUL zum Empfangen der Signale nicht mehr funktioniert. In dem Fall sind dann auf einen Schlag angeblich alle Batterien leer. Um dies zumindest teilweise abzufangen, könnte man vor dem Erzeugen des Logeintrags noch auf den state des CUL testen, dass dieser nicht "disconnected" ist.<br />
<br />
==== Visualisierung ====<br />
Der Abschnitt Links unten enthält einen Verweis, wie man den Batteriestatus visuell anzeigen kann. Das funktioniert mit der oben vorgeschlagenen Funktion mit einigen Ergänzungen auch, wenn das Gerät selbst keinen Batteriestatus anzeigt.<br />
<br />
Dafür braucht man einen zusätzlichen Dummy je zu überwachendem Gerät, mit dem Namen dum_<zu_überwachendes_Gerät>_dead. Für das Gerät KS300 heißt dieser dummy also z. B. dum_KS300_dead:<br />
<br />
<pre>Internals: <br />
NAME dum_KS300_dead <br />
NR 795 <br />
STATE nein <br />
TYPE dummy <br />
Readings: <br />
2015-04-28 07:47:48 state nein <br />
Attributes: <br />
devStateIcon ja:measure_battery_50@red nein:measure_battery_100@green</pre><br />
<br />
Dieser dummy soll hier die Zustände "ja" und "nein" annehmen können. Bei ja ist ihm über devStateIcon ein rotes Icon einer eher leeren Batterie zugewiesen, bei nein ein grünes Icon einer vollen Batterie. <br />
<br />
Nun muss noch die oben vorgeschlagene Funktion angepasst werden, um den Zustand des dummy entsprechend dem ermittelten Batteriestatus neu zu setzen. Dafür wird die Abfrage des Alters am Ende der Funktion um eine Zeile erweitert, die den Status des dummy setzt:<br />
<br />
<pre> if ($age_in_hours > $hours_threshold) {<br />
Log 1, ("check_if_alive: $Device dead, last state was $age_in_hours hours ago");<br />
fhem("set dum_".$Device."_dead ja");<br />
return 0;<br />
} else {<br />
fhem("set dum_".$Device."_dead nein");<br />
return 1;<br />
}</pre><br />
<br />
Den Dummy mit diesem devStateIcon kann man so der unter "Links" unten vorgeschlagenen readingsGroup hinzufügen, und damit auch Geräte ohne eigenen Batteriestatus überwachen.<br />
<br />
== Links ==<br />
* [[ReadingsGroup#Auswahl_.C3.BCber_Reading-Namen.2C_Status_als_Symbol_dargestellt|visuelle Batterieüberwachung mit readingsGroup]]<br />
* [http://fhem.de/commandref_DE.html#userReadings commandref - userReadings]<br />
* [http://fhem.de/commandref_DE.html#perl commandref - Perl specials]<br />
* [[Notify#Hinweise|Hinweise zu Variablen]] (ansonsten auch an div. Stellen in der [http://fhem.de/commandref_DE.html commandref])<br />
<br />
[[Kategorie:HOWTOS]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=SIGNALduino&diff=21828SIGNALduino2017-07-19T07:21:00Z<p>Hauswart: /* Unterstützte Geräte */</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 erkennt Signale anhand von Mustern und gibt sie an FHEM zur Auswertung (Dekodierung) weiter. Auch nicht erkannte Signale werden an FHEM übergeben. <br />
<br />
=== Vorteil gegenüber einem CUL/FHEMduino ===<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 />
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. Änderungen am Arduino-Code sind normalerweise nicht notwendig.<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 />
== Hardware: Verkabelung ==<br />
[[Datei:Fhemduino_schematic.png|200px|thumb|right|Beispielschaltplan SIGNAL(FHEM)duino]] <br />
<br />
Der SIGNALduino (Hardware) wird über den USB Port angeschlossen, er kann aber auch mit zusätzlichen ESP Modulen über ein WLAN angebunden werden. <br />
<br />
Der SIGNALduino basiert auf einem [http://arduino.cc/de/Main/ArduinoBoardNano Arduino Nano], die Schaltung entspricht der des [[FHEMduino]] oder dem [[Selbstbau_CUL]]:<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]].<br />
* Zuletzt gibt ein fertig konfektionierte 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.<br />
<br />
Es gibt auch eine Variante des SIGNALduino, die auf einem [[ESP8266]] nativ läuft, diese funktioniert derzeit aber noch nicht zufiedenstellend. Das Modul wird derzeit (2017) stetig weiterentwickelt.<br />
<br />
== Software: Modul ==<br />
<br />
=== USB-ID ermitteln ===<br />
Bevor der SIGNALduino mit dem FHEM Server (im Beispiel hier ein Raspberry PI) angeschlossen 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. <br />
<br />
Die in der Entwicklung befindliche Version kann mit folgenden Befehlen geladen werden:<br />
<br />
* FHEM aktualisieren: <code>update</code> <br />
* SIGNALduino Modul und Firmware aktualisieren: <code>update all <nowiki>https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/dev-r33/controls_signalduino.txt</nowiki></code> Durch das Update von FHEM wird sichergestellt, dass das Modul mit FHEM arbeitet. Außerdem wird auch die Firmware geladen, im Log-File sieht man, wo diese hinkopiert wurden: z.B. nach FHEM/firmware/SIGNALduino_nano328.hex<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 />
Nach dem Einbinden wird der SIGNALduino, falls er erkannt wird, im Status "Opened" angezeigt. <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-r33/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 Ardunio 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 Transreceiver 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 />
Anschließend kann der ''flash'' Befehl abgesetzt werden: <br />
<code>set sduino flash </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 />
==== Flashen eines radino Boards mit ATmega32U4 ====<br />
<br />
Diese Funktion steht nur in der Entwicklungsversion dev-r33 zur Verfügung:<br />
Das Radino Board muss derzeit noch mit Angabe des Dateinamens geflasht werden:<br />
<code>set sduino flash FHEM/firmware/SIGNALDuino_radinoCC1101.hex</code><br />
<br />
Auch sind berichte bekannt, dass der Radino beim Neustart von FHEM nicht korrekt initalisiert wird.<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 />
{|class="wikitable"<br />
! style="text-align:left;"| Produkt <br />
! (E)mpfangen<br />(S)enden <br />
! Hinweise <br />
! Verwendetes Modul <br />
! Protokoll ID<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 />
|Eurochon 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 />
|WH1080||E || || SD_WS09 || 9<br />
|-<br />
|Visivon remote pt4450||E || || none || 24<br />
|-<br />
|Einhel HS 434/6||E || || none || 21<br />
|-<br />
|Flamingo FA20RF / FA21RF Rauchmelder||E || || none || 13<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 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 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 github] nach folgendem Muster:<br />
:''Thema : Protokoll für <Das verwendete Gerät><br />
:Inhalt: Eure Hardware z.B. Arduino Nano mit XYZ Empfänger, oder Arduino Nano direkt an Gerät x<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 />
Alternativ könnt ihr auch im Forum posten. Um einzelne Erweiterungen besser im Überblick zu behalten, eignet sich das github jedoch besser.<br />
<br />
==== Es wird ein Protokoll erkannt, Autocreate legt aber kein device an ====<br />
Im SIGNALduino sind >30 Protokolle implementiert. Jedoch gibt es nur wenige 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 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 />
<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 />
<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 />
=== Der 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 />
"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, welches diese Daten jetzt in ihre Bedeutung umwandeln kann. <br />
:<code>sduino: Unknown code u1FFFFF0, help me!</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, empfangen werden sollen, mit ihrer Protokollnummer in die WhitelistID aufgenommen. Die Protokollnummer kann der obigen Tabelle 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 />
<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 />
Die Protokolle 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 mit 395 Mikrosekunden high (die Zeitdauer ergibt sich aufgrund der Mitteilung "P1=395") und anschließend ein Signal 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 />
Dennoch kommt es gehäuft zu Logmeldungen und auch Events in ähnlicher Form:<br />
:<code>SIGNALduino_unknown incomming msg: u85#FF8081</code><br />
<br />
Das Attribut ''whitelistIDs'' erlaubt es, anzugeben, welche Protokolle vom FHEM Modul berücksichtigt werden. 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. 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 />
== Fehlerbehandlung ==<br />
Der SIGNALduino kann mit folgendem Befehl auf Werkseinstellungen zurückgesetzt werden:<br />
:<code>get raw e</code><br />
als Antwort kommt dann "ccFactoryReset done". Ob ein solcher Reset nötig ist, erkennt man an der Antwort auf den Befehl "get config", auf den dann die Meldung "config: MS=1;MU=1;MC=1" folgen sollte.<br />
<br />
In der Firmware sind die folgenden Befehle eingebaut<br />
<br />
*:<code>get raw C<reg></code><br />
<reg> is a (two digit) hex number: return the value of the cc1101 register. <reg>=99 dumps the first 48 registers.<br />
Example: C35 -> C35 = 0D<br />
*:<code>get raw e</code><br />
EEPROM / factory reset. resets all eeprom values without reboot<br />
*:<code>get raw r<AA></code><br />
Read eeprom (da das "R" beim SIGNALDuino bereits mit freeram belegt ist, habe ich das "r" verwendet)<br />
*:<code>get raw r<AA>n</code><br />
Read 16 byte from eeprom (z.B. r00n)<br />
*:<code>get raw W<AA><DD></code><br />
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)<br />
<br />
Die Sendeleistung lässt sich mit <br />
:<code>get sduino ccreg 3E</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=58397|LinkText=Signalduino Entwicklung Version 3.3.1 }}<br />
* [http://www.nemcon.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 />
<br />
[[Kategorie:Interfaces]]<br />
[[Kategorie:Arduino]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Notify&diff=19981Notify2017-02-15T13:52:28Z<p>Hauswart: /* Einfache UND Funktion */</p>
<hr />
<div>{{SEITENTITEL:notify}}<br />
{{Infobox Modul<br />
|ModPurpose=Ausführung von Anweisung(en) als Reaktion auf Ereignisse<br />
|ModType=h<br />
|ModCmdRef=notify<br />
|ModForumArea=Automatisierung<br />
|ModTechName=91_notify.pm<br />
|ModOwner=rudolfkoenig ({{Link2FU|8|Forum}} / [[Benutzer Diskussion:Rudolfkoenig|Wiki]])<br />
}}<br />
__TOC__<br />
{{Todo|generelle Überarbeitung, Fehlerkontrolle, Formatierung}}<br />
{{Randnotiz|RNTyp=[g|Info|RNText= Tipps<br />
* Weitere grundlegende Informationen/Beispiele zu notify enthält [http://fhem.de/Heimautomatisierung-mit-fhem.pdf Heimautomatisierung mit FHEM] <br> "Um Ihren Perlcode zu testen, verwenden Sie das [http://fhem.de/commandref#trigger trigger-Kommando]. [...] Wenn Sie also z.B. ein <code>define Testcode notify Schalter1:on {Perlcode}</code> testen möchten, können Sie Ihren Code mit <code>trigger Schalter1 on</code> testen. trigger simuliert das Eintreten eines Ereignisses [...]" (Tipp von S. 38 der Version 4.0)<br />
<!-- AUSKOMMENTIERT wegen derzeitiger Funktionsproblemen iZm codemirror * FHEM enthält für notify eine eingebaute Perl-Syntax-Prüfung. Diese ist nach [http://fhem.de/commandref.html#perlSyntaxCheck Aktivierung] aber nur aktiv, wenn die [[Konfiguration]] -wie empfohlen- nicht direkt bearbeitet wird. ({{Link2Forum|Topic=51744}}) --> }}<br />
== Notify, das mächtige Tool ==<br />
Die nachfolgenden Beispiele beziehen sich hauptsächlich auf [[EIB / KNX|KNX (EIB)]]. Sie sind aber auf alle anderen Systeme übertragbar.<br />
<br />
Was ist notify? <br />
Das Hilfsmodul notify dient dazu, Aktionen abhängig von einem anderen [[Event|Ereignis/Event]] auszulösen. Es ist damit möglich, Logikfunktionen im FHEM abzubilden.<br />
<br />
Z.B.: das Licht in der Küche wird eingeschaltet ====&gt; draus folgt, dass auch das Radio eingeschaltet wird.<br />
<br />
=== Syntax von notify ===<br />
<br />
define <name> notify <Suchmuster> <command> <br />
<br />
Das [[Regulärer Ausdruck|Suchmuster (auch Regexp = regulärer Ausdruck)]] ist sehr wichtig. Es ist entweder der Name des auslösenden ("triggernden") Gerätes oder die Kombination aus Gerät und auslösendem Ereignis (Event) Gerätename:Event. Die Events kann man dem [[Event_monitor|Event-Monitor]] entnehmen. Wenn da z.B. Rollo1 steht, dann reagiert notify auf Rollo1 on und off und was es sonst noch alles gibt.<br />
<br />
Wenn man mehrere Suchmuster möchte, kann man diese in Klammer schreiben (Rollo1|Rollo2|Steckdose5)<br />
als Trenner wird dann Pipe (|) genutzt.<br />
<br />
Man kann auch mit Platzhaltern arbeiten.<br />
<br />
* Rollo. ==> das notify reagiert auf alles was mit Rollo und '''einem''' weiteren beliebigen Zeichen anfängt. Also auf Rollo1 wie auch auf RolloG, aber nicht auf Rollo_wischundweg<br />
* Rollo.* ==> das notify reagiert auf alles das mit Rollo beginnt.<br />
* .*isch ==>; Reagiere auf alles das mit isch aufhört (Tisch, Fisch)<br />
<br />
Suchmuster/Regex kann man im Internet beispielsweise auf [http://regexpal.com/| http://regexpal.com/] testen.<br />
<br />
=== Regexp wizard - FHEMWEB-unterstützte Anlage eines notify ===<br />
Die Erstellung eines notify und insbesondere die korrekte Angabe des Suchmusters (Regex) führt gerade bei Einsteigern immer wieder zu Schwierigkeiten. Zur Fehlerminimierung empfiehlt es sich einmal die [[Konfiguration]] nicht direkt zu bearbeiten, sondern die "Befehl-Eingabezeile" und die "Objektdetails" zur Bearbeitung zu nutzen. Zudem enthält FHEM einen Regexp wizard mit dem Regex anhand der in FHEM vorhandenen Devices und deren Events aus einer Auswahlbox selektiert werden können. Voraussetzungen sind:<br />
* Aktivierung des Hilfsmoduls [[eventTypes]] (bei allen Neuinstallationen Standard) <br />
* das gesuchte Ereignis (Event) ist nach Aktivierung des Hilfsmoduls bereits mindestens einmal eingetreten<br />
<br />
Schrittweise Darstellung der Nutzung des Regexp wizard zur Anlage eines "notify":<br />
<br />
In das [[Konfiguration#Befehl-Eingabefeld|Befehls-Eingabefeld]] eingeben und mit {{Taste|Enter}} bestätigen:<br />
define ntest notify a b<br />
Als Beispiel wird ein notify mit <name> "ntest" angelegt. "a" und "b" sind beliebige Platzhalter für <Suchmuster> und <Command>, die bei der weiteren Bearbeitung mit dem endgültigen Werten ersetzt werden.<br />
Der Regexp wizard öffnet sich:<br />
[[Datei:Regexp wizard1.JPG|400px|thumb|center]]<br />
Nun in der Auswahlbox das auslösende Event (Ereignis) auswählen; zunächst das Device und dann das gewünschte Regex. Hier soll das notify bei jeder Veränderung der Temperatur (temperature.*) des Device BTHR918N reagieren. Abschließend mit einem Mausklick auf {{Taste|set}} bestätigen. Wählt man mehrere Regex in dieser Weise aus, so wird das "notify" bei Eintritt jedes dieser Events ausgeführt:<br />
[[Datei:Regexp wizard2.JPG|400px|thumb|center]]<br />
Anschließend den Platzhalter "a" mit Klick auf den Link "removeRegexpPart" löschen:<br />
[[Datei:Regexp wizard3.JPG|400px|thumb|center]]<br />
Den Link "DEF" anklicken, damit sich der DEF-Editor öffnet:<br />
[[Datei:Regexp wizard4.JPG|400px|thumb|center]]<br />
Jetzt den auszuführenden Befehl im "DEF"-Bereich durch Überschreiben des Platzhalters "b" eintragen und mit Klick auf {{Taste|modify ntest}} abschließen:<br />
[[Datei:Regexp wizard5.JPG|400px|thumb|center]]<br />
Das fertige und sofort aktive "notify" sieht abschließend folgendermaßen aus:<br />
[[Datei:Regexp wizard6.JPG|400px|thumb|center]]<br />
Am Schluss das Speichern über {{Taste|Save config}} nicht vergessen.<br />
<br />
=== Etwas schalten, wenn ein anderes Gerät geschaltet wird ===<br />
Wenn man das obige mit KNX abbilden möchte, benötigt man auf der KNX Seite:<br />
<br />
==== Vorbereitung ====<br />
* Gruppenadresse (GA) für die Steckdose vom Radio (0/0/10)<br />
* GA vom Licht (0/0/20)<br />
<br />
Auf der FHEM Seite wird benötigt:<br />
<br />
define RadioKueche EIB 0/0/10<br />
define LichtKueche EIB 0/0/20<br />
<br />
==== notify Befehl ====<br />
define LichtamRadioan notify LichtKueche { fhem "set RadioKueche $EVENT" } <br />
oder '''besser'''<br />
define LichtamRadioan notify LichtKueche set RadioKueche $EVENT <br />
<br />
==== Erklärung ====<br />
* Der Begriff "LichtamRadioan" ist nur ein Platzhalter, damit das notify in FHEM verwaltet werden kann.<br />
* "$EVENT" ist ein Platzhalter für den Zustand vom Pattern. $EVENT enthält ein "off" wenn das LichtKueche aus ist und ein "on" wenn das Licht eingeschaltet ist.<br />
* "{ &lt;perlcode&gt; }" alles was zwischen {} steht ist Perl code. Perl kennt das Schlüsselwort fhem. Das Schlüsselwort FHEM dient dazu, FHEM Befehle auszuführen. Es wird also der FHEM Befehl "set RadioKueche on/off" ausgeführt. on oder off ist abhängig vom Pattern. Der eigentliche FHEM Befehl muss in " " stehen.<br />
* Warum ist die 2. Variante besser? In der 1. Variante wechselt man von FHEM-Ebene des notify mittels {} auf Perl-Ebene, wo man mit dem Schlüsselwort fhem "" wieder einen Befehl auf FHEM-Ebene ausführt. In der 2. Variante werden diese unnötigen, resourcenverschwendenden Ebenen-Wechsel vermieden. Alles wird auf der FHEM-Ebene ausgeführt.<br />
<br />
=== Einschalten von mehreren Geräten/Lampen, wenn das Licht eingeschaltet wird ===<br />
==== Vorbereitung ====<br />
KNX:<br />
* 3 GAs für drei Geräten bzw Lampen (0/0/30 0/0/31 0/0/32)<br />
<br />
FHEM:<br />
define LichtWZ EIB 0/0/30<br />
define Steckdose1 EIB 0/0/31<br />
define Steckdose2 EIB 0/0/32<br />
<br />
==== notify Befehl ====<br />
define SteckdoseWZein notify LichtWZ { fhem "set Steckdose1 $EVENT;;set Steckdose2 $EVENT " } <br />
oder '''besser'''<br />
define SteckdoseWZein notify LichtWZ set Steckdose1,Steckdose2 $EVENT<br />
<br />
==== Erklärung ====<br />
Wenn das LichtWZ eingeschaltet wird, dann werden auch die Steckdosen (1 und 2) eingeschaltet.<br />
<br />
=== Einfache ODER Funktion ===<br />
Eine einfache ODER Funktion kann sehr einfach realisiert werden<br />
<br />
==== Vorbereitung ====<br />
KNX:<br />
* 3x GAs der abzufragende Werte (0/0/40 0/0/41 0/0/42)<br />
<br />
FHEM:<br />
define Licht1 EIB 0/0/40<br />
define Licht2 EIB 0/0/41<br />
define Steckdose EIB 0/0/42<br />
<br />
==== notify Befehl ====<br />
define SteckdoseWZein notify (Licht1|Licht2) set Steckdose $EVENT <br />
oder<br />
define SteckdoseWZein notify (Licht.) set Steckdose $EVENT<br />
<br />
==== Erklärung ====<br />
Die Werte in der Klammer (wichtig ist das »|«) sind die Rückgabewerte. Alternativ kann in diesem Beispiel auch »Licht.« (zu beachten ist der Punkt) geschrieben werden. Der Punkt ist ein Platzhalter für (genau) ein beliebiges Zeichen.<br />
<br />
Danach folgt der set Befehl.<br />
Wenn also das Licht1 oder Licht2 den Wert "on" hat, dann hat auch die Steckdose den Wert "on"<br />
<br />
Alternative: [[structure]]<br />
<br />
=== Einfache UND Funktion ===<br />
Ob man dieses Konstrukt noch als einfach bezeichnen kann, wage ich mal zu bezeifeln. In FHEM fehlen Loggingfunktionen, die man alle selber mit Perl Code erstellen kann (Danke an MAZ).<br />
Dadurch ist FHEM zwar mächtig, wird aber für viele sehr kompliziert.<br />
<br />
In diesem Beispiel soll - wenn drei Rollos geschlossen sind - am Taster eine LED eingeschaltet werden.<br />
<br />
==== Vorbereitung ====<br />
KNX:<br />
* 3x GDs für die Rückgabewert Rollo geschlossen == 1 (0/0/50 0/0/51 0/0/52)<br />
* GD LED am Lichtschalter (0/0/106)<br />
<br />
FHEM:<br />
define R1ZU EIB 0/0/50<br />
attr R1ZU dummy 1<br />
define R2ZU EIB 0/0/51<br />
attr R2ZU dummy 1<br />
define R3ZU EIB 0/0/52<br />
attr R3ZU dummy 1<br />
define LEDalleRolloZu EIB 0/0/106<br />
Durch das Atribut dummy werden keine Schaltfunktion angeboten. Es kann nur Werte anzeigen.<br />
<br />
==== notify Befehl ====<br />
define nt.allerolloszu notify (R1ZU|R2ZU|R3ZU) {<br />
my $r1 = Value("R1ZU");;<br />
my $r2 = Value("R2ZU");;<br />
my $r3 = Value("R3ZU");;<br />
if ($r1 eq "on" &amp;&amp; $r2 eq "on" &amp;&amp; $r3 eq "on") {<br />
fhem "set LEDalleRolloZu on"<br />
} else {<br />
fhem "set LEDalleRolloZu off"<br />
}<br />
}<br />
<br />
==== Erklärung ====<br />
Es werden die drei Rückgabewerte R1ZU, R2ZU und R3ZU ausgewertet. Danach folgt Perl Code, deswegen beginnt das ganze mit einer { und endet mit }<br />
<br />
my $r1 =&gt; Variable $r1 definieren<br />
= Value("R1ZU");; ==&gt; weist den Rückgabewert (on oder off) von R1ZU der Variable $r1 zu <br />
<br />
Der doppelte ;; ist ein FHEM Thema. Eigentlich würde für Perl ein ; reichen. Aber FHEM nutzt selbst das ; und daher wird ein ;; benötigt. Mit den ersten drei my Zeilen werden die Rückgabewerte den Variabeln zugewiesen.<br />
<br />
Danach erfolgt ein normales "if then else" Konstrukt. Die Zeile »($r1 eq "on" &amp;&amp; $r2 eq "on" &amp;&amp; $r3 eq "on")«&#160;kann man so lesen: Wenn $r1 den Wert "on" und (&amp;&amp;) $r2 den Wert "on" und $r3 den Wert "on" dann schalte die LEDalleRolloZu ein {fhem("set LEDalleRolloZu on")}<br />
ansonsten else schalte die LED aus. {fhem("set LEDalleRolloZu off")<br />
<br />
Alternative: [[structure]]<br />
<br />
=== Zeitverzögert schalten ===<br />
{| class="wikitable"<br />
| '''Aufgabe:''' || Zeitverzögert schalten<br />
|- <br />
| '''Beschreibung:''' || Mit einem Notify zeitverzögert eine Aktion auslösen.<br />
|- <br />
| '''Vorbereitung:''' || Gerät "Lampe" ist definiert und es gibt eine Situation, die ein Ereignis "Fernbedienung:.*" generiert.<br />
|-<br />
| '''Befehl:''' || <code>define ntfy1 notify Fernbedienung:.* sleep 7.5;; set Lampe $EVENT</code><br />
|-<br />
| '''Erläuterungen:''' || Bei Eintreten eines Ereignisses "Fernbedienung*" wird nach einer Pause von siebeneinhalb Sekunden der Befehl <set Lampe ??> ausgeführt, wobei der eigentliche Befehl aus dem auslösenden Ereignis übernommen wird.<br />
:''Quelle: [http://forum.fhem.de/index.php/topic,17161.0.html FHEM Forum]''<br />
|}<br />
<br />
<br />
=== Eine PV-Anlage (Solarstrom) zur Steuerung der Rollos nutzen (optional Zeit und Datums abhängig) ===<br />
Hier ein kleines Beispiel, wie man mit Hilfe einer PV-Anlage die Sonneneinstrahlung auf der Südseite ermittelt und dies zur Rolladensteuerung nutzt.<br />
Optional: Die Funktion soll allerdings nur zwischen 9:30 und 17:00 stattfinden. (zweites Beispiel)<br />
Optional: Die Funktion soll nur zwischen dem 6. und 9. Monat funktioneren. (drittes Beispiel)<br />
<br />
==== Vorbereitung ====<br />
PV Anlage mit SolarView abfragen.<br />
Per Hand ermitteln, ab wieviel erzeugtem Strom es sinnvoll ist die Rollos zu schließen.<br />
<br />
==== notify Syntax ====<br />
FHEM:<br />
<br />
define sv SolarView solarview 15000 wr1 wr2 wr3 wr4 <----vier Wechselrichter<br />
attr sv event-on-change-reading currentPower <br />
<br />
define nt.sonnenlichtpersolar notify (sv:currentPower.*) { <br />
if ($EVTPART1 &lt; 3000 ) {<br />
fhem('set Flur1 Auf');<br />
}else {<br />
if ($EVTPART1 &gt; 5000 ) {<br />
fhem('set Flur1 Ab');<br />
} <br />
}<br />
}<br />
<br />
Optional 1: Zeitabhängig<br />
<br />
(sv:currentPower.*) { <br />
my $hm = sprintf("%02d:%02d", $hour, $min);<br />
if ( $hm gt "09:30" &amp;&amp; $hm lt "17:00") { <br />
if ($EVTPART1 &lt; 5000 ) {<br />
fhem('set Flur1 Auf');<br />
}else {<br />
if ($EVTPART1 &gt; 8000 ) {<br />
fhem('set Flur1 Ab');<br />
} <br />
}<br />
}<br />
}<br />
<br />
Optional 2: Zeit und Datum<br />
<br />
(sv:currentPower.*) { <br />
my $hm = sprintf("%02d:%02d", $hour, $min);<br />
if ($month >= 6 &amp;&amp; $month <= 9) {<br />
if ( $hm gt "09:30" &amp;&amp; $hm lt "17:00") { <br />
if ($EVTPART1 &lt; 5000 ) {<br />
fhem('set Flur1,RBUERO1,RBUERO2 Auf');<br />
}else {<br />
if ($EVTPART1 &gt; 8000 ) {<br />
fhem('set Flur1,Flur2,RBUERO1,RBUERO2 Ab');<br />
} <br />
}<br />
}<br />
}<br />
}<br />
<br />
==== Erklärung ====<br />
* Das define wird in der Kommandozeile im Webbrowser eingegeben.<br />
* Anschliessend wird im Webbrowser die DEF bearbeitet, das erspart uns Probleme mit Perl<br />
* define sv SolarView ... <==== ist die Schnittstelle vom SolarView<br />
* define nt.sonnenlichtpersolar notify (sv:currentPower.*) { <==== hier wird ein notify angelegt, der auf das "define sv" Wert "currentPower.*" (.* ist irgendwas) reagiert<br />
if ($EVTPART1 &lt; 3000 ) {<br />
fhem('set Flur1 Auf');<br />
}else {<br />
if ($EVTPART1 &gt; 5000 ) {<br />
fhem('set Flur1 Ab');<br />
} <br />
}<br />
}<br />
Diese if-Funktion wertet den Rückgabewert von currentPower aus. Hierbei muss man wissen, dass $EVTPART1 das Splitergebnis vom Rückgabewert ist<br />
<br />
Beispiel: Der Rückgabewert (wie im Beispiel) ist "currentPower: 6000".<br />
Jetzt steht im "$EVTPART0 == currentPower:" und im "$EVTPART1 == 6000"<br />
Das bedeutet, dass man sich nicht selbst den richtigen split (Perl Befehl) Aufruf ausdenken muss, dies übernimmt vielmehr FHEM.<br />
<br />
Ergebnis: <br />
Das Rollo wird abhängig von der erzeugten IST_Strommenge auf und zu gefahren.<br />
Damit dies nicht dauernd hin und her pendelt, wurde der Auf Wert sehr klein und den Ab Wert sehr groß gewählt.<br />
<br />
'''Optional 1:''' Der Block "my $hm = sprintf("%02d:%02d", $hour, $min);" erzeugt die String-Variable $hm mit dem Inhalt $hour:$min. %02d begrenzt die Ausgabe auf zwei Stellen.<br />
Danach wird mit "if ( $hm gt "09:30" && $hm lt "17:00")" mit stringvergleichende Operatoren geprüft, ob die Uhrzeit zwischen 9:30 und 17:00 liegt (lt = kleiner als; gt = größer als). Es wäre auch ein le und ge möglich: le = kleiner/gleich als, ge = größer/gleich als.<br />
<br />
'''Optional 2:'''if( $month >= 6 && $month <= 9) {<br />
<br />
Hier wird die numerische FHEM-Standard-Variable $month (Monat) auf größer/gleich bzw kleiner/gleich mit den binären Operatoren überprüft.<br />
Die Funktion arbeitet also nur zwischen dem 6. und dem 9. Monat und dann auch nur zwischen 9:31 und 16:59.<br />
<br />
=== Hinweise ===<br />
* Entsprechend zu $EVENT gibt es auch noch $NAME und $TYPE. $NAME und $TYPE enthalten den Namen bzw. Typ des Ereignis auslösenden Gerätes.<br />
* Wird der Perl-Code in einem <code>notify</code> immer länger, lagere den Code wegen der Übersichtlichkeit in eine eigene Programmdatei aus, wie in [[99_myUtils anlegen]] beschrieben.<br />
* Achtung! Wenn man das Skript für den notify-Befehl über mehrere Zeilen schreibt, muss man anscheinend darauf achten, dass keine abschliessende Leerzeile mitgespeichert wird. Sonst wird der notify-Befehl ignoriert.<br />
* Dieser {{Link2Forum|Topic=38520|Message=307325}} enthält Vorschläge zur Vorgehensweise bei der Erstellung von komplexen ''notify'' Definitionen bzw. bei deren Fehlerbehebung.<br />
<br />
== Weiterführende Links ==<br />
* [[Escapen in Perlbefehlen]]<br />
* [[Klammerebenen]]<br />
* [[DOIF]] als Alternative vereinigt die Funktionalität des notify-, at-, watchdog-Befehls in Kombination mit logischen Abfragen unter einem Dach<br />
<br />
[[Kategorie:HOWTOS]]<br />
[[Kategorie:Hilfsmodul]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Homebridge_Start_und_Status_in_FHEM&diff=19617Homebridge Start und Status in FHEM2017-02-09T11:49:32Z<p>Hauswart: /* FHEM Benutzer Zugriff auf Script gewähren */</p>
<hr />
<div>Um nicht bei jeder Änderung, welche die Homebridge betrifft, diese über die Console manuell neustarten zu müssen zeigt diese Lösung wie dies bequem aus FHEMWEB erfolgen kann. In den nachfolgenden Abschnitten sind die einzelnen Schritte dazu erläutert.<br />
<br />
== Vorwort ==<br />
Die im weitern genutzten Bezeichnungen von Dummys, Scriptdateinamen o.ä. können geändert werden. Die Änderungen müssen jedoch auch an allen entsprechenden Stellen vorgenommen werden.<br />
Genannte IP Adressen, Benutzernamen und Passwörter sind auf die eigenen Gegebenheiten anzupassen. Die Berechtigungen des Benutzers müssen zur Ausführung der Scripte geprüft und ggf. angepasst werden. Entprechende Linux Kentnisse sollten vorhanden sein. Dieser Artikel berücksichtigt das FHEM und Homebridge nicht zwingend auf dem selben System laufen. Die hier gezeigte Lösung kann für beide Varianten genutzt werden, FHEM und Homebridge auf dem gleichen System oder auf getrennten Systemen.<br />
<br />
== Umsetzung ==<br />
<br />
=== Status- und Kontroll-Dummy ===<br />
[[Datei:HomebridgeDummy.PNG|mini|550px|Status- bzw. Kontroll-Dummy]]<br />
<br />
Es wird ein Dummy benötigt, welcher den Status des Homebridge-Dienstes anzeigt und über den dieser Dienst gesteuert werden kann. Das nötige Script um die Homebridge als Dienst zu starten wird weiter unten in diesem Artikel erstellt.<br />
<br />
<source lang="bash" style="width:100%;"><br />
define SYS_Homebridge dummy<br />
attr SYS_Homebridge devStateIcon .*on:general_an .*off:general_aus .*:audio_rec<br />
attr SYS_Homebridge eventMap status:status start:start stop:stop restart:restart<br />
attr SYS_Homebridge icon it_router<br />
attr SYS_Homebridge room System<br />
attr SYS_Homebridge userReadings OnStateChange:(start|stop|restart|status) { system ("sudo service homebridge ".ReadingsVal($NAME,"state","restart")." &" );; }<br />
attr SYS_Homebridge webCmd status:start:stop:restart<br />
</source><br />
<br />
Der Dummy wird durch setzen von "start", "stop", "restart" oder "status" jeweils das userReading ausführen und somit letztendlich den homebridge Dienst steuert.<br />
<br />
=== Start Script anlegen ===<br />
Nun ist das Startscript für die Homebridge anzulegen. Mittels dem folgenden Befehl wird (wenn noch nicht vorhanden) das homebridge Script angelegt und im Editor geöffnet.<br />
<br />
<source lang="bash" style="width:100%;"><br />
sudo nano /etc/init.d/homebridge<br />
</source><br />
Wenn die Homebridge nicht auf dem selben System läuft wie FHEM muss dieser Schritt auf dem Homebridge System ausgeführt werden.<br />
<br />
Das nun folgende Script kann in die homebridge Datei, die im Nano Editor geöffnet, ist rein kopiert werden. <br />
<br />
'''Achtung''': die Variabeln ''homeBridgeUser'', ''fhemHost'' und ''fhemHostTelnetPort'' sind ggf. auf die eigenen Gegebenheiten anzupassen.<br />
<br />
<source lang="bash" style="width:100%;"><br />
#!/bin/sh<br />
### BEGIN INIT INFO<br />
# Provides: homebridge<br />
# Required-Start: $network $remote_fs $syslog<br />
# Required-Stop: $remote_fs $syslog<br />
# Default-Start: 2 3 4 5<br />
# Default-Stop: 0 1 6<br />
# Short-Description: Start daemon at boot time for homebridge<br />
# Description: Enable service provided by daemon.<br />
### END INIT INFO<br />
export PATH=$PATH:/usr/local/bin<br />
export NODE_PATH=$NODE_PATH:/usr/local/lib/node_modules<br />
<br />
PID=`pidof homebridge`<br />
homeBridgeUser="fhem"<br />
fhemHost=127.0.0.1 #FHEM Server (Masterinstanz)<br />
fhemHostTelnetPort=7072 #TelnetPort der FHEM Instanz<br />
fhemDefine="SYS_Homebridge"<br />
<br />
case "$1" in<br />
start)<br />
if ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is already running"<br />
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge is already running" <br />
else<br />
su - $homeBridgeUser -c "homebridge > /dev/null 2>&1 &"<br />
echo "Homebridge starting"<br />
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge starting" <br />
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine on"<br />
sleep 2<br />
$0 status<br />
fi<br />
;;<br />
stop)<br />
if ! ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is not running"<br />
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge is not running"<br />
else<br />
kill $PID<br />
echo "Homebridge stopping"<br />
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge stopping"<br />
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "set $fhemDefine off"<br />
sleep 2<br />
$0 status <br />
fi<br />
;;<br />
restart)<br />
if ! ps -p $PID > /dev/null 2>&1; then<br />
$0 start<br />
else<br />
$0 stop<br />
$0 start<br />
fi<br />
;;<br />
status)<br />
if ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is running PID $PID"<br />
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge running as PID $PID"<br />
else<br />
echo "Homebridge is not running"<br />
perl /opt/fhem/fhem.pl $fhemHost:$fhemHostTelnetPort "setreading $fhemDefine info Homebridge is not running"<br />
fi<br />
;;<br />
*)<br />
echo "Usage: $0 {start|stop|status|restart}"<br />
exit 1<br />
;;<br />
esac<br />
exit 0<br />
<br />
</source><br />
<br />
Das Script setzt in dem bereits angelegten Dummy ein Reading ''info'' in dem der Ausführungsstatus des Scripts wieder gegeben wird. Das Reading ''state'' wir auf on oder off gesetzt. ''On'' bedeutet das Homebridge gestartet ist, ''off'' das die Homebridge nicht ausgeführt wird.<br />
<br />
<br />
Damit die Homebridge auch mit Start des Systems gestartet wird sind die folgenden zwei Schritte notwendig<br />
<br />
<source lang="bash" style="width:100%;"><br />
sudo chmod 755 /etc/init.d/homebridge<br />
sudo update-rc.d homebridge defaults<br />
</source><br />
<br />
Zum testen kann der Dienst nun mit dem Befehl<br />
<br />
<source lang="bash" style="width:100%;"><br />
sudo service homebridge start<br />
</source><br />
bzw.<br />
<source lang="bash" style="width:100%;"><br />
sudo /etc/init.d/homebridge start<br />
</source><br />
<br />
gestartet werden. In dem angelegten Dummy werden zwei Readings erzeugt mit den entsprechenden Rückmeldungen aus dem Script. Die Readings werden erst angezeigt wenn die bereits geöffnete Detailseite des Dummys neu geladen wird.<br />
<br />
=== Testlauf / Fertig ===<br />
Nun können die einzelnen Aktionen über den Dummy ausführt werden. Dabei wird jeweils der eingerichtete Dienst angesteuert und eine (mit kurzer Verzögerung) Rückmeldung gegeben.<br />
<br />
== Sonstiges ==<br />
<br />
=== FHEM Benutzer Zugriff auf Script gewähren ===<br />
<br />
Damit aus FHEM das Script ausgeführt werden kann benötigt dieser Benutzer entsprechende Berechtigungen. Dazu ist in der sudoers ein Eintrag zu ergänzen.<br />
Dazu wird die sudoers Datei im Nano Editor geöffnet<br />
<br />
<source lang="bash" style="width:100%;"><br />
sudo nano /etc/sudoers<br />
</source><br />
<br />
Dort sollte im Abschnitt ''# User privilege specification'' die folgende Zeile ergänzt werden <br />
<br />
<source lang="bash" style="width:100%;"><br />
fhem ALL=(ALL) NOPASSWD:/etc/init.d/homebridge<br />
</source><br />
<br />
'''Achtung!''' Sollte FHEM nicht unter dem Benuter ''fhem'' laufen ist dies an den entsprechenden Stellen anzupassen. <br />
<br />
Beispielinhalt der sudoers:<br />
<source lang="bash" style="width:100%;"><br />
#<br />
# This file MUST be edited with the 'visudo' command as root.<br />
#<br />
# Please consider adding local content in /etc/sudoers.d/ instead of<br />
# directly modifying this file.<br />
#<br />
# See the man page for details on how to write a sudoers file.<br />
#<br />
Defaults env_reset<br />
Defaults mail_badpass<br />
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"<br />
<br />
# Host alias specification<br />
<br />
# User alias specification<br />
<br />
# Cmnd alias specification<br />
<br />
# User privilege specification<br />
root ALL=(ALL:ALL) ALL<br />
fhem ALL=(ALL) NOPASSWD:/etc/init.d/homebridge<br />
<br />
# Members of the admin group may gain root privileges<br />
%admin ALL = (ALL) NOPASSWD: ALL<br />
<br />
# Allow members of group sudo to execute any command<br />
%sudo ALL=(ALL:ALL) ALL<br />
<br />
# See sudoers(5) for more information on "#include" directives:<br />
<br />
#includedir /etc/sudoers.d<br />
</source><br />
<br />
[[Kategorie:HOWTOS]]<br />
<br />
=== Anpassung wenn FHEM und Homebridge auf getrennten Systemen laufen ===<br />
Unter dem Kapitel [[Umsetzung]] wurde bereits alles vorbereitet um mit wenigen Änderungen eine Homebridge zu starten die nicht auf dem selben System läuft wie FHEM. Es sind nur 2 Änderungen notwendig.<br />
Die erste Änderung betrifft den eingerichteten Dummy. Hier ist das vorhandenen ''userReadings'' wie folgt abzuändern<br />
<br />
<source lang="bash" style="width:100%;"><br />
attr SYS_Homebridge userReadings OnStateChange:(start|stop|restart|status) { system ("sudo /opt/fhem/FHEM/homebridgeserviceremote.sh ".ReadingsVal($NAME,"state","restart")." &" );; } <br />
</source><br />
<br />
Dadurch wird, durch die Aktionen des Dummys, ein weiteres Script angesprochen.<br />
<br />
Nun wird dieses Script mit hilfe des Nano Editor angelegt<br />
<br />
<source lang="bash" style="width:100%;"><br />
sudo nano /opt/fhem/FHEM/homebridgeserviceremote.sh<br />
</source><br />
<br />
und mit dem folgenden Inhalt befüllt.<br />
<br />
'''Achtung''': die Variabeln ''remoteUser'', ''remotePasswort'' und ''remoteHost'' sind ggf. auf die eigenen Gegebenheiten der entfernt laufenden Homebridge anzupassen. Der hier genannte Benutzer muss natürlich berechtigt sein die Homebridge starten zu können. Es sollte auch nicht der root User verwendet werden, sondern ein eigens dafür angelegter und in den Berechtigungen eingeschränkter Benutzer verwendet werden.<br />
Wer zur Fehleranalyse etwas mehr sehen möchte ändert den Wert von ''debug'' auf 1.<br />
<br />
<source lang="bash" style="width:100%;"><br />
#!/bin/bash<br />
debug=0<br />
remoteUser="root"<br />
remotePasswort="root"<br />
remoteHost="192.168.1.111"<br />
remoteService="homebridge"<br />
fhemHostTelnetPort=7072 #TelnetPort der FHEM Instanz<br />
<br />
# Vorraussetzungen prüfen<br />
if [ $(dpkg-query -W -f='${Status}' sshpass 2>/dev/null | grep -c "ok installed") -eq 0 ];<br />
then<br />
if [ "$debug" = "1" ]; then <br />
echo "sshpass wird benötigt. Installation beginnt"; <br />
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] sshpass wird benötigt. Installation beginnt\"}";<br />
fi<br />
apt-get install sshpass<br />
if [ "$debug" = "1" ]; then <br />
echo "sshpass wurde installiert";<br />
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] sshpass wurde installiert\"}"; <br />
fi<br />
fi<br />
###################################<br />
<br />
# Befehl ausführen<br />
case "$1" in<br />
start)<br />
if [ "$debug" = "1" ]; then <br />
echo "Ausführen von 'sudo service $remoteService start' auf '$remoteHost' als '$remoteUser'"; <br />
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService start' auf '$remoteHost' als '$remoteUser'\"}";<br />
fi<br />
sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService start"<br />
if [ "$debug" = "1" ]; then <br />
echo "Ausführung beendet"; <br />
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";<br />
fi<br />
;;<br />
stop)<br />
if [ "$debug" = "1" ]; then <br />
echo "Ausführen von 'sudo service $remoteService stop' auf '$remoteHost' als '$remoteUser'"; <br />
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService stop' auf '$remoteHost' als '$remoteUser'\"}";<br />
fi<br />
sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService stop"<br />
if [ "$debug" = "1" ]; then <br />
echo "Ausführung beendet"; <br />
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";<br />
fi<br />
;;<br />
restart)<br />
if [ "$debug" = "1" ]; then <br />
echo "Ausführen von 'sudo service $remoteService restart' auf '$remoteHost' als '$remoteUser'"; <br />
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService restart' auf '$remoteHost' als '$remoteUser'\"}";<br />
fi<br />
sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService restart"<br />
if [ "$debug" = "1" ]; then <br />
echo "Ausführung beendet"; <br />
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";<br />
fi<br />
<br />
;;<br />
status)<br />
if [ "$debug" = "1" ]; then <br />
echo "Ausführen von 'sudo service $remoteService status' auf '$remoteHost' als '$remoteUser'";<br />
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführen von 'sudo service $remoteService status' auf '$remoteHost' als '$remoteUser'\"}"; <br />
fi<br />
sshpass -p "$remotePasswort" ssh -o StrictHostKeyChecking=no $remoteUser@$remoteHost "sudo service $remoteService status"<br />
if [ "$debug" = "1" ]; then <br />
echo "Ausführung beendet"; <br />
perl /opt/fhem/fhem.pl $fhemHostTelnetPort "{Log 1, \"[homebridgeserviceremote.sh] Ausführung beendet\"}";<br />
fi<br />
;;<br />
*)<br />
echo "Usage: $0 {start|stop|status|restart}"<br />
exit 1<br />
;;<br />
esac<br />
exit 0<br />
###################################<br />
</source><br />
<br />
Das Script macht nicht sehr viel. Es verbindet sich über ssh mit dem entfernten System und startet (stopt, etc.) den Homebridge Dienst. Hinweis: es wird sshpass benötigt, welches das Script bei bedarf versucht zu installieren.<br />
<br />
== Dankeschön ==<br />
Ein Dankeschön geht an die Entwicklergemeinde rund um Homebridge und dem FHEM Plugin für die Homebridge.<br />
<br />
Ein besonderes Dankeschön an ''No Legend'' der die zugrunde liegende Idee und Lösung in diesem Artikel beschrieben hat.</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=FHEM_Tablet_UI&diff=19290FHEM Tablet UI2017-02-02T10:54:53Z<p>Hauswart: /* Widgets -- Beispiele */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Oberfläche für FHEM<br />
|ModType=x<br />
|ModFTopic=34233<br />
|ModForumArea=Frontends<br />
|ModTechName=n.a.<br />
|ModOwner=setstate ({{Link2FU|7023|Forum}})<br />
}}<br />
[[Datei:tablet_ui.png|200px|thumb|right|Fhem Tablet UI]]<br />
FHEM Tablet UI ist ein leichtgewichtiges aber funktionsreiches Framework zum Steuern und Überwachen von in FHEM integrierten Geräten. Zahlreiche Widgets können sehr flexibel und leicht per HTML Code konfiguriert werden.<br />
<br />
In dieser Anleitung wird die Installation und Konfiguration des FHEM Tablet UI beschrieben.<br />
<br />
{{Todo|alle Widgets hier übernehmen, Übersetzung, weitere Beispiele aus dem Forum einfügen (evtl. mit Link!?)}} <br />
<br />
<br />
== Voraussetzungen ==<br />
Das User Interface hat sehr wenige Anforderungen für den Betrieb. Es benötigt <u>keine</u> zusätzliche Frameworks, wie z.B. PHP oder MySQL.<br />
<br />
Voraussetzungen ist eine FHEM Installation mit HTTPSRV Modul. Das UI kann mit den gängigen Browsern Betriebssystem unabhängig genutzt werden oder mit dem Webviewcontrol.<br />
Das Interface wird dabei in dem FHEM eigenen Webserver ausgeführt. Mit wenigen Anpassungen ist es auch möglich das UI auf anderen Webservern (Apache, u.a.) zu betreiben, dann kann FHEM und UI auch auf getrennten Systemen ausgeführt werden.<br />
<br />
== Installation ==<br />
* Im Befehls-Eingabefeld eingeben: <code><nowiki>update all https://raw.githubusercontent.com/knowthelist/fhem-tablet-ui/master/controls_fhemtabletui.txt</nowiki></code><br />
* Im Befehls-Eingabefeld eingeben: <code>define TABLETUI HTTPSRV ftui/ ./www/tablet Tablet-UI</code><br />
* Im Verzeichnis ./fhem/www/tablet die Datei index-example.html in index.html umbenennen oder eine neue index.html erzeugen und diese index.html wie nachfolgend beschrieben editieren.<br />
<br />
Das UI ist über den Link "Tablet-UI" auf der FHEM-Hauptseite oder durch Direktaufruf der URL "<nowiki>http://<Fhem-url>:8083/fhem/tablet/index.html</nowiki>" zu erreichen.<br />
<br />
Hinweise zu einer manuellen Installation und weitere Infos sind auf der Projektseite https://github.com/knowthelist/fhem-tablet-ui zu finden.<br />
<br />
== Update ==<br />
* Prüfen der Änderungen seit dem letzten Download/Update durch Eingabe von: <code><nowiki>update check https://raw.githubusercontent.com/knowthelist/fhem-tablet-ui/master/controls_fhemtabletui.txt</nowiki></code><br />
* Update des UI durch Eingabe von: <code><nowiki>update all https://raw.githubusercontent.com/knowthelist/fhem-tablet-ui/master/controls_fhemtabletui.txt</nowiki></code><br />
<br />
Über <br />
<code><nowiki>update add https://raw.githubusercontent.com/knowthelist/fhem-tablet-ui/master/controls_fhemtabletui.txt</nowiki></code><br />
kann seit dem 24.12.2015 die URL zum normalen Updatebefehl von FHEM hinzugefügt werden. Mit einen "update check" sieht man dann gleich alle Updates aus beiden "Welten".<br />
<br />
== Weitere Widgets ==<br />
<br />
=== Widgets for Fhem-tablet-ui ===<br />
{{Hinweis|'''Achtung''': die nesges-Widgets sind nicht mehr kompatibel mit der aktuellen FHEM Tablet UI Version. Aktuell bitte kein Installation aus dieser Quelle mehr durchführen.}}<br />
Zusätzlich zu den bei der Installation des Tablet UI direkt zur Verfügung stehenden Widgets, gibt es eine weitere Widget-Quelle von nesges unter https://github.com/nesges/Widgets-for-fhem-tablet-ui. Die Widgets aus dieser Quelle müssen für eine Nutzung separat installiert werden.<br />
<br />
Dazu folgenden Befehl in die FHEM-Befehlszeile eingeben: <code><nowiki>update all https://raw.githubusercontent.com/nesges/Widgets-for-fhem-tablet-ui/master/controls_widgets-for-fhem-tablet-ui.txt</nowiki></code>. <br />
<br />
Näheres zur Installation unter [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/Installation Wiki: Installation]. <br />
<br />
Die Dokumentation der einzelnen Widgets befindet sich ebenfalls [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki im Github-Wiki].<br />
<br />
== Konfiguration ==<br />
'''META-Parameter'''<br />
<br />
Das Tablet UI lässt sich über die META-Parameter konfigurieren. Mit den meisten META-Parametern kann das verhalten des UI beeinflusst werden. Diese Parameter befinden sich in der jeweiligen '''.html''' Datei (z.B. index.html) im Abschnitt '''<head>'''. Nachfolgend sind die verschiedenen Konfigurationsparameter aufgeführt. Die Parameter sind immer gleich aufgebaut.<br />
<br />
:<code><meta name="<META-Parameter>" content="<Wert>"></code><br />
<br />
{| class="wikitable"<br />
|-<br />
! META-Parameter !! Wert / Beispiel !! Erklärung<br />
|-<br />
| longpoll || 1 oder 0 || Refresh sofort, alle 15 Minuten ein voller Refresh (shortpoll) statt alle 30 Sekunden ein voller Refresh.<br />
|-<br />
| gridster_disable || 1 oder 0 || Drag&Drop der Gridster-Elemente auf der Seite deaktivieren.<br />
|-<br />
| toast || 1 oder 0 || Toast messages deaktivieren<br />
|-<br />
| fhemweb_url || http://meinFhemServer:8083/fhem || Wird benötigt wenn der Webserver des TabletUI nicht auf dem FHEM Server läuft.Default: "/fhem/"<br />
|-<br />
| widget_margin || 1 bis 9999 || Abstände der Gridsterelemente verändern.<br />
|-<br />
| widget_base_width || 1 bis 9999 || Größe des Basis-Rasters (data-sizey=1/data-sizex=1) verändern.<br />
|-<br />
| widget_base_height || 1 bis 9999 || Größe des Basis-Rasters (data-sizey=1/data-sizex=1) verändern.<br />
|-<br />
| gridster_cols || 1 bis 9999 || Anzahl der Spalten.<br />
|-<br />
| gridster_rows || 1 bis 9999 || Anzahl der Reihen.<br />
|-<br />
| lang || de || Sprache der Visualisierung (derzeit nur DE vorhanden).<br />
|}<br />
<br />
''Layout''<br />
<br />
Seit Version 2.5 werden die Gridster Kachel-Grössen, die Anzahl der Spalten und die Anzahl der Reihen dynamisch anhand der Bildschirmgrösse berechnet.<br />
<br />
Möchte man die Anzahl der Spalten und Reihen fest vorgeben:<br />
<br />
<pre><meta name="gridster_cols" content="12"><br />
<meta name="gridster_rows" content="9"></pre><br />
<br />
Mit folgendem Code kann man die Kachelgrössen fix definieren:<br />
<br />
<pre><meta name="widget_base_width" content="116"><br />
<meta name="widget_base_height" content="131"></pre><br />
<br />
''FHEM URL''<br />
<br />
Werden die FTUI Seiten von einem anderen Server als FHEM-HTTPSRV bereitgestellt, muss man die URL, unter der FHEM angesprochen wird, anpassen:<br />
<br />
<pre><meta name="fhemweb_url" content="/fhem/"></pre><br />
<br />
'''CSS-Styles'''<br />
<br />
Das Layout und das Aussehen des UI kann durch diverse vorgegebene CSS-Klassen beeinflusst werden. Die verfügbaren Klassen sind im Abschnitt [[#CSS Class description|CSS Class description]] oder [[#Positioning|Positioning]] aufgeführt. Es besteht auch die Möglichkeit eine eigene CSS Datei zu erstellen und darüber Änderungen am aussehen des UI vorzunehmen. Die eigenen CSS Datei würde bei einem Update unverändert bleiben. Daher ist abzuraten ein CSS Datei die mit dem UI Update verteilt wird zu modifizieren. Die eigene CSS Datei ist unter '''/fhem/tablet/css''' mit dem Namen '''fhem-tablet-ui-user.css''' zu finden. Sollte diese nicht vorhanden sein kann die Datei manuell erstellt werden.<br />
Wird keine eigene CSS-Datei verwendet empfiehlt es sich den folgenden Eintrag im <head> der jeweiligen .html Datei zu entfernen, bzw. in Kommentar gesetzt werden um Probleme beim Laden der Seite zu verhindern.<br />
<br />
:<code><link rel="stylesheet" href="/fhem/tablet/css/fhem-tablet-ui-user.css" /></code><br />
<br />
== Farbe ==<br />
Es besteht die Möglichkeit, die Farbwerte in hexadezimaler Form oder als RGB-Wert anzugeben. Zum Beispiel: Hex: #A3CFA3 RBG: rgb(163, 207, 163).<br />
<br />
Knallige Farben wie #ff0000 für Rot oder #00ff00 für Grün sollten vermieden werden. Es ist besser unterhalb von #D0 (208) für die Grundfarben zu bleiben.<br />
<br />
Hilfreich bei der Suche nach den Farbwerten ist der color picker: http://www.w3schools.com/tags/ref_colorpicker.asp oder diese Quelle: https://flatuicolors.com<br />
<br />
== CSS Class description ==<br />
<br />
Not all widgets support all classes<br />
<br />
* readonly : changing of state is not allowed<br />
* wider : 25px extra space for the widget to the top<br />
* narrow : shorter distant to the widget above<br />
* w1x, w2x, w3x : set the widget to a fix width: 1x, 2x, 3x width<br />
* mini : lowest diameter for volume widget<br />
* small : font 80% size (label), small diameter for volume widget<br />
* medium : font 120% size<br />
* large : font 150% size<br />
* big : font 200% size<br />
* bigplus : font 270% size<br />
* bigger : font 320% size<br />
* bigger.thin : font 450% size<br />
* grande : font 600% size<br />
* gigantic: font 144px size + 120px line-height<br />
* thin : font thin<br />
* darker : forecolor in gray<br />
* hue-tick : draw ticks in color range<br />
* hue-front : draw handle in color range<br />
* hue-back : draw background in color range<br />
* dim-tick : draw ticks in brightness range<br />
* dim-front : draw handle in brightness range<br />
* dim-back : draw background in brightness range<br />
* red : foreground color red<br />
* green : foreground color green<br />
* blue : foreground color blue<br />
* doublebox-v : container to place 2 small widgets (e.g. switch) one above the other<br />
* doublebox-h : container to place 2 small widgets (e.g. switch) side by side<br />
* timestamp : deliver the date time for the reading instead the value<br />
* inline : positioning elements in a row, no line break<br />
* top-space : 15px extra on top (top-space-2x -> 30px; top-space-3x -> 45px)<br />
* left-space : 15px extra on left (left-space-2x -> 30px; left-space-3x -> 45px)<br />
* right-space : 15px extra on right (right-space-2x -> 30px; right-space-3x -> 45px)<br />
* blink : blink animatation for label or symbol widget<br />
* verticalLine : Vertikale Line am rechten Rand<br />
<br />
== Positioning ==<br />
<br />
*container : new box or new row<br />
*col-x-y : new column with x/y of width (col-1-3,col-2-3,col-1-2,col-1-4,col-1-8,col-1-5,col-2-5,col-3-5,col-4-5)<br />
*inline : positioning elements in a row, no line break<br />
*top-space : 15px extra on top (top-space-2x -> 30px; top-space-3x -> 45px)<br />
*left-space : 15px extra on left (left-space-2x -> 30px; left-space-3x -> 45px)<br />
*right-space : 15px extra on right (right-space-2x -> 30px; right-space-3x -> 45px)<br />
*top-narrow : -15px closer on top (top-narrow-2x -> -30px; top-narrow-10 -> -10px)<br />
*centered : horizontal centered<br />
*left-align : align text left<br />
*left : floating left<br />
*right-align : align text right<br />
*right : floating right<br />
*wider : 15px extra space for the widget all around<br />
*narrow : shorter distant to the widget above<br />
*fullsize : 100% in width and height<br />
<br />
== Widgets -- Konfiguration ==<br />
<br />
Teilweise dokumentierte Widgets:<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/button button]: Variante der push und switch Widgets, die entweder einen URL ansteuern oder einen FHEM-Befehl absetzen kann.<br />
* [[#chart|chart]]: chart with similar capabilities as the FHEM plots <br />
* checkbox:<br />
* [[#circlemenu|circlemenu]]: Mehrere Widgets hinter einem Widget verborgen, trotz des 'circle' im Namen kann das Menue jetzt auch horizontal oder vertikal ausgeklappt werden <br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/clicksound clicksound]: Mit dem Widget "clicksound" können Sounds an Click-Events von Elementen gebunden werden. <br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/clock clock]: Das Widget "clock" stellt eine einfach Uhr zur verfügung.<br />
* colorwheel:<br />
* daytimepicker:<br />
* [[#departure|departure]]: show timetable of public transport provider<br />
* [[#dimmer|dimmer]]: toogle button with a setter for on value<br />
* eventmonitor:<br />
* highchart:<br />
* [[#homestatus|homestatus]]: selector for 4 states (1=home, 2=night, 3=away, 4=holiday)<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/iframe iframe]]: Widget zum Einbinden externer Inhalte in einem Iframe. <br />
* [[#image|image]]: insert an image, the URL is given by a reading<br />
* input:<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/itunes_artwork itunes_artwork]: itunes_artwork durchsucht die iTunes-Datenbank anhand eines Arrays von beliebigen Suchworten nach einem Cover-Artwork und zeigt dieses an. <br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/javascript javascript]: Ermöglicht die Ausführung beliebigen Javascript-Codes aus einem Reading.<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/joinedlabel joinedlabel]: verbindet mehrere Readings zu einem Feld<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/klimatrend klimatrend]: wandelt Daten aus dem statistics-Modul in einen Pfeil um, der den aktuellen Trend anzeigt. <br />
* Knob:<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/kodinowplaying kodinowplaying]: zeigt Informationen zu grade in KODI gespielten Medien in Form eines Labels an.<br />
* [[#label|label]]: STATE als Text anzeigen<br />
* [[#level|level]]: vertical/horizontal bar to show values between min/max value<br />
* link:<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/mpdnowplaying mpdnowplaying]: zeigt Titelinformationen eines per MPD-Modul angebundenen Music Player Daemon an. <br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/multistatebutton multistatebutton]: Variante des push-Widgets das den set-Befehl abhängig vom gelesenen Status ändert.<br />
* [[#pagetab|pagetab]]: Element to smoothly exchange the whole page with another page<br />
* pagebutton:<br />
* [[#playstream|playstream]]: Abspielen eines Webradio-Streams per Button<br />
* [[#popup|popup]]: a popup dialog which open on click on another widget <br />
* [[#progress|progress]]: round symbolic display for percent values<br />
* [[#push|push]]: send any command to FHEM e.g. up / down<br />
* range:<br />
* readingsgroup:<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/reload reload]: auslösen eine Pagereloads<br />
* [[#rotor|rotor]]: Umschalten von zwei oder mehr Widgets an einer Position<br />
* [[#select|select]]: Combobox to provide a list for selection<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/settimer settimer]: zum anzeigen und einstellen einer Uhrzeit.<br />
* [[#simplechart|simplechart]]: simple XY line chart for one value (reads directly from FHEM log file) <br />
* [[#slider|slider]]: vertical slider to select between min/max value<br />
* spinner:<br />
* swiper:<br />
* [[#switch|switch]]: Toggle any command to FHEM (e.g. on / off)<br />
* [[#symbol|symbol]]: State als Symbol darstellen (z.B. Fenster offen)<br />
* [[#thermostat|thermostat]]: dial for heater thermostates to set desired value and show current value<br />
* [[#volume|volume]]: dial to set a single value (e.g. 0-60)<br />
* [[#weather|weather]]: insert an icon or image, represending a weather literal<br />
* [https://github.com/svenson08/ftui-weekdaytimer-widget weekdaytimer]: Visualisierung des [[WeekdayTimer]] Modul<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/wind_direction wind_direction]: Zeigt die Windrichtung auf einer Windrose an. <br />
<br />
<br />
Ein Demo der Widgets findet ihr [http://knowthelist.github.io/fhem/tablet/demo_widgets.html Hier].<br />
----------------------------------<br />
<br />
Für alle Widgets gilt:<br />
{| class="wikitable"<br />
|+allgemeine Attribute<br />
|-<br />
!align="right" |data-type<br />
|Widget-Typ<br />
|-<br />
!align="right" |data-device<br />
|FHEM-Name des Gerätes (mit dem Befehl 'list' bekommt man im FHEM die kpl. Liste)<br />
|-<br />
!align="right" |class<br />
|CSS-Klassen für Aussehen und Formatierung des Widgets<br />
|-<br />
|}<br />
<br />
{| class="wikitable"<br />
|+Daten Empfangen<br />
|-<br />
!align="right" |data-get<br />
|Reading Name<br />
|-<br />
!align="right" |data-get-on<br />
|Wert für den Status on<br />
|-<br />
!align="right" |data-get-off<br />
|Wert für den Status off<br />
|-<br />
|}<br />
<br />
{| class="wikitable"<br />
|+Daten Senden<br />
|-<br />
!align="right" |data-set<br />
|Reading Name<br />
|-<br />
!align="right" |data-set-on<br />
|Wert für den Status on<br />
|-<br />
!align="right" |data-set-off<br />
|Wert für den Status off<br />
|-<br />
|}<br />
<br />
<div id="chart">'''CHART'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-logdevice<br />
|name of the logdevice (e.g. FileLog_WohnzimmerHeizung) or array of names if more than one graph shall be displayed<br />
|-<br />
|-<br />
!align="right" |data-logfile<br />
|name of the logfile (e.g. WohnzimmerHeizung-2015.log) or or array of names if more than one graph shall be displayed<br />
|'-' or omitting this data means current logfile<br />
|-<br />
!align="right" |data-columnspec<br />
|definition for how to find the values (e.g. "4:meas.*:1:int") or or array of columnspecs if more than one graph shall be displayed<br />
|-<br />
|-<br />
!align="right" |data-style<br />
|name of the graph style to be used (e.g. 'SVGplot l0' or 'ftui l0dash') or or array of styles if more than one graph shall be displayed using different stlyes. The standard fhem plot styles can be used furthermore there are some more predefined styles existing (details see css file). Own styles can be specified e.g. in the fhem-table-ui-user.css file.<br />
|-<br />
|-<br />
!align="right" |data-ptype<br />
|name of the plot type (e.g. 'lines' or 'fa-cog') or or array of plottypes if more than one graph shall be displayed. All fhem plot styles are supported. Additionally it is possible to specify symbols (currently supported are font awesome ('fa-...'), open automation ('oa-...') and fhem symbols ('fs-...')). Can also be something like 'icon:1' in which case the respective columnspec should result in links to icons (e.g. for weather forecast) and the y-value is taken from the graph number 1 <br />
|'lines'<br />
|-<br />
!align="right" |data-uaxis<br />
|name of the axis to be used ('primary' or 'secondary') or or array of axis' to be used if more than one graph shall be displayed. The 'primary' axis is labelled on the left side, the 'secondary' axis is labelled on the right side<br />
|'primary'<br />
|-<br />
!align="right" |data-legend<br />
|caption of the graph (used in the legend and at the cursor) or an array of legend texts if more than one graph shall be displayed.<br />
|-<br />
|-<br />
!align="right" |data-minvalue<br />
|min Y value to Show or an array of values for dynamic minY for primary axis. A value of 'auto' means that the value is calculated from the data displayed dynamically<br />
|10<br />
|-<br />
!align="right" |data-minvalue_sec<br />
|min Y value to Show or an array of values for dynamic minY for secondary axis. A value of 'auto' means that the value is calculated from the data displayed dynamically<br />
|'auto'<br />
|-<br />
!align="right" |data-maxvalue<br />
|max Y value to Show or an array of values for dynamic maxY for primary axis. A value of 'auto' means that the value is calculated from the data displayed dynamically<br />
|30<br />
|-<br />
!align="right" |data-maxvalue_sec<br />
|max Y value to Show or an array of values for dynamic maxY for secondary axis. A value of 'auto' means that the value is calculated from the data displayed dynamically<br />
|'auto'<br />
|-<br />
!align="right" |data-yticks<br />
|value distance between Y tick lines (related to primary axis). A value of 'auto' means that the value is calculated from the data displayed dynamically. Can be an array containing value pairs in order to have arbitrary text for given values (e.g. data-yticks='[[0,"open"],[1,"closed"]]')<br />
|'auto'<br />
|-<br />
!align="right" |data-yticks_sec<br />
|value distance between Y tick lines (related to secondary axis). A value of 'auto' means that the value is calculated from the data displayed dynamically.Can be an array containing value pairs in order to have arbitrary text for given values (e.g. data-yticks_sec='[[0,"open"],[1,"closed"]]')<br />
|'auto'<br />
|-<br />
!align="right" |data-xticks<br />
|time range between each X tick lines (in minutes). A value of 'auto' means that the value is calculated from the data displayed dynamically<br />
|'auto'<br />
|-<br />
!align="right" |data-daysago_start<br />
|number of days back from now for the start of the plot (0 means the plot starts from today 0:00). Additionally the x-axis start value can be set here unsing standard data formats like ('2013-10-23'), the time portion of the string is only used when <code>data-nofulldays</code> is 'true'. If the setting ends with 'w', 'W', 'm', 'M', 'y', 'Y' the nuber given is interpreted as week, month or year respectively (capital letters mean rounding to full weeks, months years) (e.g. '2Y' means that, if current date is 3.6.2015, the graph will start 1.1.2013).<br />
|0<br />
|-<br />
!align="right" |data-daysago_end<br />
|number of days back from now for the end of the plot (-1 means the plot ends today 24:00). Additionally the x-axis end value can be set here unsing standard data formats like ('2013-10-23'), the time portion of the string is only used when <code>data-nofulldays</code> is 'true'. If the setting ends with 'w', 'W', 'm', 'M', 'y', 'Y' the nuber given is interpreted as week, month or year respectively (capital letters mean rounding to full weeks, months years) (e.g. '2Y' means that, if current date is 3.6.2015, the graph will end 31.12.2013).<br />
|-1<br />
|-<br />
!align="right" |data-timeformat<br />
|setting for the formatting of the x-tick text. The format can be configured in a quite flexible way. Several format classifiers are supported which are separated by special characters ('-', '.', '/', ' ', ':', ',', '\'). All characters despite '\' will be displayed in the final output.<br />
The following is a list of supported classifiers:<br />
* 'LF'enters a linefeed<br />
* 'mm' - displays minutes as 2 digits<br />
* 'hh' - displays hours as 2 digits<br />
* 'dd' - displays day of the month as 2 digits<br />
* 'MM' - displays months as 2 digits (e.g. 02 for February)<br />
* 'MMM' - displays months as 3 characters (e.g. Dec for December)<br />
* 'MMMM' - displays monhts as full names (e.g. March)<br />
* 'ee' - displays weekdays as 2 digits (e.g. 00 for Sunday)<br />
* 'eee' - displays weekdays as 3 characters (e.g. Mon for Monday)<br />
* 'eeee' - displays weekdays as full names (e.g. Tuesday)<br />
* 'yy' - displays years as 2 digits (e.g. 16 as 2016)<br />
* 'yyyy' - displays years as 4 digits<br />
For example a string given as 'MMM\LF\yyyy' will display 'Jan' in one line and '2016' in a second one. A string given as 'MM.dd 2016' will display '03.05 2016'.<br />
|-<br />
|-<br />
!align="right" |data-nofulldays<br />
|switch to activate/deactivate rounding of the xaxis start and end values to full days ('true' or 'false')<br />
|'false'<br />
|-<br />
!align="right" |data-ytext<br />
|text to be shown besides the primary y axis.<br />
|-<br />
|-<br />
!align="right" |data-ytext_sec<br />
|text to be shown besides the secondary y axis.<br />
|-<br />
|-<br />
!align="right" |data-yunit<br />
|unit of the value to show beside of each Y ticks for primary y axis.<br />
|-<br />
|-<br />
!align="right" |data-crosshair<br />
|switch to activate/deactivate the crosshair cursor ('true' or 'false')<br />
|'false'<br />
|-<br />
!align="right" |data-cursorgroup<br />
|number to define coupling of the crosshair cursor. The cursors of all charts having the same number are coupled and move together.<br />
|-<br />
|-<br />
!align="right" |data-scrollgroup<br />
|number to define coupling of the scrolling (shift and zoom). All charts having the same number are scrolled (shifted and zoomed) together.<br />
|-<br />
|-<br />
!align="right" |data-showlegend<br />
|switch to activate/deactivate the initial display of the legend window ('true' or 'false')<br />
|'false'<br />
|-<br />
!align="right" |data-legendpos<br />
|array of two values (horizontal and vertical) to set the initial position of the legend window. Allowed values are "left", "right" or a number giving the position in percent for the first parameter (horizontal position) and 'top', 'bottom' or a number giving the position in percent for the second parameter (vertical position). <br />
|'["top","right"]'<br />
|-<br />
!align="right" |data-yunit_sec<br />
|unit of the value to show beside of each Y ticks for secondary y axis.<br />
|-<br />
|-<br />
!align="right" |data-width<br />
|fixed size for width (in&nbsp;% or px)<br />
|-<br />
|-<br />
!align="right" |data-height<br />
|fixed size for height (in&nbsp;% or px)<br />
|-<br />
|-<br />
!align="right" |data-graphsshown<br />
|boolean to define if graphs are activated (shown) initially or an array of booleans if more than one graph shall be displayed.<br />
|-<br />
|-<br />
!align="right" |data-ddd<br />
|setting for 3D display. Array with 3 angles for rotation of the 3D chart in x, y, z (z not yet supported) (e.g. '["40","60","0"]'). If the array is existing, there will be 2 additional buttons on top for changing rotation in x and y.<br />
|-<br />
|-<br />
!align="right" |data-dddspace<br />
|setting for the space between different graphs in y direction if 3D is activated (space given in pixels).<br />
|15<br />
|-<br />
!align="right" |data-dddwidth<br />
|setting for the width of the graphs if 3D is activated (width given in pixels).<br />
|10<br />
|-<br />
!align="right" |data-title<br />
|setting for inclusion of chart title on top of the chart. Includes the possibility for calculation of values like in SVG Plots (e.g. data-title="Min: $data{mindate4}, Max: $data{maxdate4}, Last: $data{currdate4}"). Supported are:<br />
* min1: minimum value of graph 1 (first graph in the given list). Number can be any graph or omitted if calculation shall be done over all graphs.<br />
* max1: maximum value of graph 1 (first graph in the given list)<br />
* avg1: average value of graph 1 (first graph in the given list)<br />
* cnt1: number of values of graph 1 (first graph in the given list)<br />
* currval1: last (current) value of graph 1 (first graph in the given list)<br />
* mindate1: minimum x value of graph 1 (first graph in the given list)<br />
* maxdate1: maximum x value of graph 1 (first graph in the given list)<br />
* currdate1: last (current) x value of graph 1 (first graph in the given list)<br />
|''<br />
|-<br />
!align="right" |class<br />
|fullsize, noticks, nobuttons, small, normal, big<br />
|-<br />
|-<br />
|}<br />
<br />
<code>data-logfile</code> can be omitted in this case the default value "-" will be used. This means that the current logfile is going to be used.<br />
<br />
There are several buttons that control the dynamic behaviour of the chart. The <-, ->, + and - buttons shift and zoom the displayed data. The "legend" and "cursor" buttons are switching on and off the display of the legend window and the crosshair cursor respectively. If 3D display is activated (see above) 2 more buttons control the rotation in x and y.<br />
<br />
When the legend window is displayed, a click on the legend text shows/hides the respective graph. The legend window can be dragged to other positions on desktop browsers (currently not yet working for iOS and Android).<br />
<br />
The crosshair cursor currently only works dynamically on desktop browsers. On iOS and Android you have to tap on the screen to set the cursor to a new position.<br />
<br />
Three classes define default values for the texts (small, normal, big). Additionally there is a number of css styles that control the visible appearance of the chart. The following classes are supported:<br />
<br />
{| class="wikitable"<br />
!CSS class name<br />
!Description<br />
|-<br />
!.chart-background<br />
|Color etc. for the chart background<br />
|-<br />
!.text.axes<br />
|Font and color for the chart axes<br />
|-<br />
!.buttons<br />
|Size and color for the buttons (shift etc.)<br />
|-<br />
!.gridlines<br />
|Size and color for gridlines generally<br />
|-<br />
!.xaxis<br />
|Font, size and color for xaxis<br />
|-<br />
!.yaxis<br />
|Font, size and color for yaxis<br />
|-<br />
!.xticks<br />
|Font, size and color for xticks<br />
|-<br />
!.yticks<br />
|Font, size and color for yticks<br />
|-<br />
!.crosshair<br />
|Font, size and color (foreground/background) for the crosshair cursor<br />
|-<br />
!.caption<br />
|Font, size and color for text buttons for legend and cursor switching<br />
|-<br />
!.legend<br />
|Font, size and background color for legend window<br />
|-<br />
|-<br />
|}<br />
<br />
[[#Beispiel_chart|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="circlemenu">'''CIRCLEMENU'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-item-diameter<br />
|diameter of the circle<br />
|52<br />
|-<br />
!align="right" |data-circle-radius<br />
|radius of each item, in pixel<br />
|70<br />
|-<br />
!align="right" |data-direction<br />
|position of the items in relation to the center<br />
|'full'<br />
|-<br />
!align="right" |data-close-after<br />
|closing time of the circle-menu<br />
|(item-count + 1s) or a minimum of 4s<br />
|-<br />
!align="right" |class<br />
|keepopen<br />
|<br />
|-<br />
|}<br />
<br />
Optionen für data-direction: top | right | bottom | left | top-right | top-left | bottom-right | bottom-left | top-half | right-half | bottom-half | left-half | full | vertical | horizontal<br />
<br />
[[#Beispiel_circlemenu|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="departure">'''DEPARTURE'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-type<br />
|widget-type; must be departure<br />
|<br />
|-<br />
!align="right" |data-device<br />
|name of the device to get data from<br />
|<br />
|-<br />
!align="right" |data-get<br />
|name of the reading of device to get data from<br />
|<br />
|-<br />
!align="right" |data-icon<br />
|define icon for widget<br />
|<br />
|-<br />
!align="right" |data-interval<br />
|interval to reload automatically<br />
|<br />
|-<br />
!align="right" |class<br />
|choose style of widget; see example<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_departure|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="dimmer">'''DIMMER'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from FHEM<br />
|'STATE'<br />
|-<br />
!align="right" |data-get-on<br />
|value for ON status to get<br />
|'on'<br />
|-<br />
!align="right" |data-get-off<br />
|value for OFF status to get<br />
|'off'<br />
|-<br />
!align="right" |data-set<br />
|(<command> <device> <reading> <value>) <br />
|<br />
|-<br />
!align="right" |data-set-on<br />
|value for ON status to set<br />
|value of data-get-on<br />
|-<br />
!align="right" |data-set-off<br />
|value for OFF status to set<br />
|value of data-get-off<br />
|-<br />
!align="right" |data-cmd<br />
|name of the command (<command> <device> <value>) (e.g. setstate, set, setreading, trigger)<br />
|'set'<br />
|-<br />
!align="right" |data-dim<br />
|name of the reading responsible for dim (<command> <device> <reading> <value>) <br />
|value of data-get-on<br />
|-<br />
!align="right" |data-icon<br />
|name of the font-awesome icon<br />
|fa-lightbulb-o<br />
|-<br />
|}<br />
<br />
[[#Beispiel_dimmer|Link zu einem Beispiel]]<br />
<br />
<div id="homestatus">'''HOMESTATUS'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from FHEM<br />
|'STATE'<br />
|-<br />
!align="right" |data-set<br />
|command to send to FHEM (<code>set <device> <command> <value></code>)<br />
|''<br />
|-<br />
!align="right" |data-get-on<br />
|array of states using for get<br />
|['1','2','3','4']<br />
|-<br />
!align="right" |data-set-on<br />
|array of states using for set.<br />
|value of data-get-on<br />
|-<br />
!align="right" |data-alias<br />
|array of fix names to show only in the UI as an alias to the real states<br />
|''<br />
|-<br />
!align="right" |data-icons<br />
|array of icons related to the data-get-on array<br />
|''<br />
|-<br />
!align="right" |data-version<br />
|name of the status model e.g. 'residents','roommate','guest' <br />
|(default NULL)<br />
|-<br />
|}<br />
<br />
The default version has 4 states: '1','2','3','4' The default aliases are 'Home','Night','Away','Holiday'; data-version='residents' or 'roommate' or 'guest' has 5 states ('home','asleep','absent','gone','gotosleep') They have these aliases 'Home','Night','Away','Holiday','Retire'<br />
<br />
[[#Beispiel_homestatus|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="image">'''IMAGE'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get an URL from FHEM<br />
|'STATE'<br />
|-<br />
!align="right" |data-size<br />
|width of the image in px or %, the height scales proportionally<br />
|50%<br />
|-<br />
!align="right" |data-url<br />
|URL of the image to show (use data-url or data-device + data-get, not both)<br />
|<br />
|-<br />
!align="right" |data-refresh<br />
|Interval in seconds for image refresh for usage together with data-url<br />
|900<br />
|-<br />
|}<br />
<br />
[[#Beispiel_image|Link zu einem Beispiel]]<br />
<br />
=== Widget LABEL ===<br />
<div id="label">'''LABEL'''</div><br />
<br />
Mit dem LABEL Widget kann der STATUS eines Device in Textform angezeigt werden. Dabei kann das die Farbe des Anzeigetext abhängig von dessen Wert festgelegt werden. <br />
<br />
Neben den '''allgemeine Attribute''' besitzt das LABEL-Widget die nachfolgenden Attribute.<br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get <br />
|Name des Readings in FHEM <br />
|<br />
|-<br />
!align="right" |data-fix <br />
|Eine bestimmte Anzahl an Dezimalstellen <br />
|'-1' -> non-numeric <br />
|-<br />
!align="right" |data-part <br />
|split position of the space separated value to show or an RegEx <br />
| <br />
|-<br />
!align="right" |data-color <br />
| fix color attribute or DEVICE:READING for dynamic setting of label color <br />
| ''<br />
|-<br />
!align="right" |data-colors <br />
|a array of color values to affect the colour of the label according to the limit value <br />
| <br />
|-<br />
!align="right" |data-limits-get <br />
|name of the DEVICE:Reading to colorize the label <br />
|data-device:data-get <br />
|-<br />
!align="right" |data-limits <br />
|an array of numeric values to affect the colour of the Label <br />
| <br />
|-<br />
!align="right" |data-limits-part <br />
|part number of the space separated value to show or a RegEx <br />
|'-1' -> all <br />
|-<br />
!align="right" |data-unit <br />
|add a unit after a numeric value. use encoded strings e.g. "%B0C%0A" <br />
| <br />
|-<br />
!align="right" |data-substitution <br />
|regex-substitution to apply on the value. Standard regex notation (s/regex/subst/modifier) is expected <br />
| <br />
|-<br />
!align="right" |data-hide <br />
|string to compare with current value. hide element when it's value equals data-hide <br />
|<br />
|-<br />
!align="right" |data-hideparents <br />
|jquery selector to hide element's parents too <br />
|<br />
|-<br />
!align="right" |class <br />
|small, large, big, bigger, thin, red, green, blue, darker, timestamp, w1x, w2x, w3x, fixedlabel, icon, bg-limit <br />
| <br />
|}<br />
<br />
Mit der Class 'fixedlabel' kann man Label einbauen, die einen festen Text (direkt im HTML) haben, aber trotzdem die Farbe per Reading Value beeinflusst werden könnte.<br><br />
Mit der Class 'icon' kann man Label einbauen, die wie Icons aussehen. Als Hintergrund gibt es 'icon round' (rund), 'icon square' (Rechteck mit abgerundeten Ecken) und 'icon squareborder' (Rechteck mit abgerundeten Ecken und einem zusätzlichen Rand).<br><br />
Mit der Class 'bg-limit' wird der Hintergrund des Icon auf grün oder rot gesetzt, passend zum on/off Status des data-limits.<br />
Use data-color OR data-colors + data-limits, not both.<br />
<br />
With class="bg-limit" it changes the background color not the forecolor according data-limits<br />
<br />
class="icon square" or class="icon round" forces the label to a fix width and height in icon style<br />
<br />
Special layout can be achieved by overwriting of following classes in the fhem-tablet-ui-user.css:<br />
<br />
.label-precomma .label-comma .label-aftercomma .label-unit<br />
<br />
e.g.: .label-aftercomma{ font-size:40%; left: 4px; top: -25px; position: relative; }<br />
<br />
Functions for data-substitution:<br />
<br />
Array of replacements<br />
RegEx-substitution to apply on the value. Standard regex notation (s/regex/subst/modifier) is expected<br />
data-substitution="weekdayshort"<br />
JS functions data-substitution="toDate().ddmm()" - convert to day:month<br />
data-substitution="toDate().hhmm()" - convert to hour:minutes<br />
<br />
data-substitution="toDate().hhmmss()" - convert to hour:minutes:secondes<br />
<br />
data-substitution="toDate().eeee()" - convert to name of the week day<br />
<br />
data-substitution="toDate().ago()" - convert to time span<br />
<br />
[[#Beispiel_label|Link zu einem Beispiel]]<br />
<br />
=== Widget LEVEL ===<br />
<div id="level">'''LEVEL'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from FHEM<br />
|'STATE'<br />
|-<br />
!align="right" |data-min<br />
|minimal value to set<br />
|'0'<br />
|-<br />
!align="right" |data-max<br />
|maximal value to set<br />
|'100'<br />
|-<br />
!align="right" |data-on<br />
|value where the slider moves to max<br />
|'on'<br />
|-<br />
!align="right" |data-off<br />
|value where the slider moves to min<br />
|'off'<br />
|-<br />
!align="right" |data-part<br />
|part number of the space separated value to show or an RegEx<br />
|<br />
|-<br />
!align="right" |data-colors<br />
|a array of color values to affect the colour of the label according to the limit value<br />
|<br />
|-<br />
!align="right" |data-limits<br />
|a array of numeric or RegEx values to affect the colour of the label<br />
|<br />
|-<br />
!align="right" |class<br />
|mini, horizontal<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_level|Link zu einem Beispiel]] (fehlt noch)<br />
<br />
<div id="pagetab">'''PAGETAB'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-url<br />
|URL of the new page to show<br />
|<br />
|-<br />
!align="right" |data-icon<br />
|name of the font-awesome icon<br />
|'fa-power-off'<br />
|-<br />
!align="right" |data-background-icon<br />
|name of the font-awesome icon for background <br />
|''<br />
|-<br />
!align="right" |data-on-background-color<br />
|color of ON state<br />
|'#aa6900'<br />
|-<br />
!align="right" |data-off-background-color<br />
|color of OFF state<br />
|'#505050'<br />
|-<br />
!align="right" |data-on-color<br />
|color of ON state<br />
|'#aa6900'<br />
|-<br />
!align="right" |data-off-color<br />
|color of Off state<br />
|'#505050'<br />
|-<br />
!align="right" |data-get-on<br />
|array of status to assign a special icon-list from data-icons<br />
|<br />
|-<br />
!align="right" |data-icons<br />
|array of icons related to the a data-get-on array<br />
|<br />
|-<br />
!align="right" |class<br />
|warn, activate (as additionals for data-icons)<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_pagetab|Link zu einem Beispiel]]<br />
<br />
<div id="playstream">'''PLAYSTREAM'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-url<br />
|URL des Radio-Streams<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get the control state from FHEM<br />
|'STATE'<br />
|-<br />
!align="right" |data-get-on<br />
|value for PLAY status to get. <br />
|'on'<br />
|-<br />
!align="right" |data-get-off<br />
|value for STOP status to get. <br />
|'off'<br />
|-<br />
!align="right" |data-volume<br />
|name of the reading to get the volume value (0-100) <br />
|volume<br />
|-<br />
|}<br />
<br />
[[#Beispiel_playstream|Link zu einem Beispiel]]<br />
<br />
<div id="popup">'''POPUP'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading where to get the alert value from<br />
|'STATE'<br />
|-<br />
!align="right" |data-get-on<br />
|value which trigger to open the dialog<br />
|'on'<br />
|-<br />
!align="right" |data-off<br />
|value which trigger to close the dialog <br />
|'off'<br />
|-<br />
!align="right" |data-width<br />
|fixe size for width (in % or px)<br />
|<br />
|-<br />
!align="right" |data-height<br />
|fixe size for height (in % or px)<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_popup|Link zu einem Beispiel]]<br />
<br />
<div id="progress">'''PROGRESS'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from FHEM<br />
|'STATE'<br />
|-<br />
!align="right" |data-max<br />
|maximal value to set or name of the reading which helds the max value<br />
|100<br />
|-<br />
!align="right" |class<br />
|novalue, percent<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_progress|Link zu einem Beispiel]] (fehlt noch)<br />
<br />
<div id="push">'''PUSH'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default-Wert<br />
|-<br />
!align="right" |data-set<br />
| name of the reading to set on FHEM (<command> <device> <reading> <value>) <br />
|<br />
|-<br />
!align="right" |data-set-on<br />
|value to send when the the button get pressed oder ein Array zwischen dessen Werten umgeschaltet werden kann<br />
|<br />
|-<br />
!align="right" |data-icon<br />
|name of the font-awesome icon<br />
|<br />
|-<br />
!align="right" |data-background-icon<br />
|name of the font-awesome icon for background <br />
|'fa-circle'<br />
|-<br />
!align="right" |data-cmd<br />
|name of the command (<command> <device> <value>) (e.g. setstate, set, setreading, trigger)<br />
|'set'<br />
|-<br />
!align="right" |data-doubleclick<br />
|timeout to wait for a second click or touch. '0' disables the doubleclick feature. <br />
|0<br />
|-<br />
!align="right" |data-countdown<br />
|secondes for the countdown progress control <br />
|autodetect from 'on-for-timer' command<br />
|-<br />
!align="right" |data-background-icon<br />
|name of the font-awesome icon for background <br />
|<br />
|-<br />
!align="right" |data-off-background-color<br />
|fix color attribute for OFF state or DEVICE:READING for dynamic setting <br />
|#505050<br />
|-<br />
!align="right" |data-off-color<br />
|fix color attribute for Off state or DEVICE:READING for dynamic setting<br />
|#505050<br />
|-<br />
|}<br />
<br />
'data-set-on' can also be an array of values to toggle between this values<br />
<br />
[[#Beispiel_push|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="rotor">'''ROTOR'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" | data-delay<br />
|time in millisecondes to wait until next list item get shown<br />
|3500<br />
|-<br />
!align="right" |class<br />
|fade, rotate<br />
|'' <br />
|-<br />
|}<br />
Ohne Angabe von class erfolgt keine Animation.<br />
<br />
[[#Beispiel_rotor|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="select">'''SELECT'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading that get the selected item of the list<br />
|<br />
|-<br />
!align="right" |data-set<br />
|name of the reading to set on FHEM (<command> <device> <reading> <value>)<br />
|''<br />
|-<br />
!align="right" |data-list<br />
|name of the reading to get a :-separated list from FHEM<br />
|''<br />
|-<br />
!align="right" |data-items<br />
|an array of fix items to show in the selection box (alternative if data-list is empty)<br />
|<br />
|-<br />
!align="right" |data-alias<br />
|an array of fix names to show only in the selection box as an alias to the real items<br />
|<br />
|-<br />
!align="right" |data-cmd<br />
|name of the command to send to FHEM (<command> <device> <reading> <value>) (e.g. setstate, set, setreading, trigger)<br />
|'set'<br />
|-<br />
!align="right" |data-quote<br />
|characters to enclose the send value<br />
|<br />
|-<br />
!align="right" |class<br />
|wider, w1x, w2x, w3x, large, big<br />
|<br />
|-<br />
|} <br />
<br />
[[#Beispiel_select|Link zu einem Beispiel]]<br />
<br />
<div id="simplechart">'''SIMPLECHART'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-logdevice<br />
|name of the logdevice (e.g. FileLog_WohnzimmerHeizung)<br />
|<br />
|-<br />
!align="right" |data-logfile<br />
|name of the logfile (e.g. WohnzimmerHeizung-2015.log)<br />
|'-' means current logfile<br />
|-<br />
!align="right" |data-columnspec<br />
|definition for how to find the values (e.g. "4:meas.*:1:int")<br />
|''<br />
|-<br />
!align="right" |data-minvalue<br />
|min Y value to Show or an array of values for dynamic minY <br />
|10<br />
|-<br />
!align="right" |data-maxvalue<br />
|max Y value to Show or an array of values for dynamic maxY <br />
|30<br />
|-<br />
!align="right" |data-yticks<br />
|value distance between Y tick lines<br />
|5<br />
|-<br />
!align="right" |data-xticks<br />
|time range between each X tick line (in Minuten)<br />
|360 minutes<br />
|-<br />
!align="right" |data-daysago<br />
|number of days back from now <br />
|0<br />
|-<br />
!align="right" |data-caption<br />
|name of the chart to show as text <br />
|<br />
|-<br />
!align="right" |data-yunit<br />
|unit of the value to show beside of each Y ticks<br />
|<br />
|-<br />
!align="right" |data-width<br />
|fixe size for width (in % or px)<br />
|<br />
|-<br />
!align="right" |data-height<br />
|fixe size for height (in % or px)<br />
|<br />
|-<br />
!align="right" |class<br />
|fullsize, noticks<br />
|<br />
|-<br />
|} <br />
<br />
[[#Beispiel_simplechart|Link zu einem Beispiel]] (fehlt noch)<br />
<br />
<code>data-logfile</code> kann man auch weglassen, dann greift der Defaultwert "-". Damit wird das neuste Logfile gelesen.<br />
<br />
<br />
<div id="slider">'''SLIDER'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from FHEM<br />
|'STATE'<br />
|-<br />
!align="right" |data-set<br />
|command to send to FHEM (<code>set <device> <command> <value></code>)<br />
|''<br />
|-<br />
!align="right" |data-cmd<br />
|name of the command (<command> <device> <value>) (e.g. setstate, set, setreading, trigger)<br />
|'set'<br />
|-<br />
!align="right" |data-min<br />
|minimal value to set<br />
|0<br />
|-<br />
!align="right" |data-max<br />
|maximal value to set<br />
|100<br />
|-<br />
!align="right" |data-step<br />
|step value<br />
|1<br />
|-<br />
!align="right" |data-on<br />
|value where the slider moves to max<br />
|'on'<br />
|-<br />
!align="right" |data-off<br />
|value where the slider moves to min<br />
|'off'<br />
|-<br />
!align="right" |data-get-value<br />
|RegEx to retrieve the value or part number of the space separated input to get the value<br />
|'-1': all of the input<br />
|-<br />
!align="right" |data-set-value<br />
|Format of the value to send to FHEM<br />
|'$v': the value only<br />
|-<br />
!align="right" |data-width<br />
|width for horizontal sliders<br />
|'120px', for mini '60px'<br />
|-<br />
!align="right" |data-height<br />
|height for vertical sliders <br />
|'120px', for mini '60px'<br />
|-<br />
!align="right" |data-color<br />
|color for quantity range<br />
|'#aa6900'<br />
|-<br />
!align="right" |data-background-color<br />
|color for range bar<br />
|#404040<br />
|-<br />
!align="right" |class<br />
|Aussehen/Ausrichtung<br />
|<br />
|-<br />
|}<br />
<br />
Für class steht mini, horizontal und negated (0 liegt oben) zur Verfügung.<br />
<br />
[[#Beispiel_slider|Link zu einem Beispiel]]<br />
<br />
<div id="switch">'''SWITCH'''</div><br />
<br />
{| class="wikitable"<br />
!HTML-Attribut<br />
!Beschreibung<br />
!Default-Wert<br />
|-<br />
!align="right" |data-get<br />
|Name des Reading, was gelesen werden soll<br />
|'STATE'<br />
|-<br />
!align="right" |data-set<br />
|Name des Reading, was gelesen werden soll<br />
|'STATE'<br />
|-<br />
!align="right" |data-cmd<br />
|Kommando Name (<command> <device> <value>) <br />(z.B setstate, set, setreading, trigger) <br />
|'set'<br />
|-<br />
!align="right" |data-doubleclick<br />
|timeout to wait for x millisecondes click or touch. '0' disables the doubleclick feature.<br />
|'0'<br />
|-<br />
|}<br />
Einstellung bei zwei Werten<br />
<br />
{| class="wikitable"<br />
!HTML-Attribut<br />
!Beschreibung<br />
!Default-Wert<br />
|-<br />
!align="right" |data-get-on<br />
|Wert, bei dem zum Status ON geschaltet werden soll. <br />
|'on'<br />
|-<br />
!align="right" |data-get-off<br />
|Wert, bei dem zum Status OFF geschaltet werden soll. <br />
|'off'<br />
|-<br />
!align="right" |data-set-on<br />
|Wert, der zu FHEM gesendet werden soll, wenn das Widget auf ON geschaltet wurde <br />
|Wert von data-get-on<br />
|-<br />
!align="right" |data-set-off<br />
|Wert, der zu FHEM gesendet werden soll, wenn das Widget auf OFF geschaltet wurde <br />
|Wert von data-get-off<br />
|-<br />
!align="right" |data-icon<br />
|Name des Font-Awesome Icon. <br />
|'fa-lightbulb-o'<br />
|-<br />
!align="right" |data-background-icon<br />
|Name des Font-Awesome Hintergrund Icon. <br />
|'fa-circle'<br />
|-<br />
!align="right" |data-on-background-color<br />
|Hintergrundfarbe beim Status on oder DEVICE:Reading bei dynamischen Einstellungen<br />
|'#aa6900'<br />
|-<br />
!align="right" |data-off-background-color<br />
|Hintergrundfarbe beim Status off oder DEVICE:Reading bei dynamischen Einstellungen<br />
|'#505050'<br />
|-<br />
!align="right" |data-on-color<br />
|Widget Farbe beim Status ON <br />
|'#aa6900'<br />
|-<br />
!align="right" |data-off-color<br />
|Widget Farbe beim Status OFF <br />
|'#505050'<br />
|-<br />
|}<br />
<br />
Einstellung bei mehreren Werten<br />
{| class="wikitable"<br />
!HTML-Attribut<br />
!Beschreibung<br />
!Default-Wert<br />
|-<br />
!align="right" |data-states<br />
|Array mit Status Angaben <br />
|<br />
|-<br />
!align="right" |data-set-states<br />
|Array mit Status Angaben, die gesetzt werden sollen<br />
|<br />
|-<br />
!align="right" |data-icons<br />
|Array Icons zum zuvor definierten Status<br />
|<br />
|-<br />
!align="right" |data-background-icons<br />
|Array mit Hintergrund Icons zum zuvor definierten Status <br />
|<br />
|-<br />
!align="right" |data-colors<br />
|Array mit Farben zum zuvor definierten Status <br />
|<br />
|-<br />
!align="right" |data-background-colors<br />
|Array mit Hintergrund Farben zum zuvor definierten Status <br />
|<br />
|-<br />
!align="right" |class : readonly<br />
|Es wird nur der Status angezeigt und kann nicht geändert werden<br />
|<br />
|-<br />
|}<br />
<br />
<code>data-get-on</code> and <code>data-get-off</code> accept also RegEx values. e.g. data-get-on="[0-9]{1,3}|on" means set switch on if STATE is a numeric value or 'on'. data-get-off="!on" means accept all but the data-get-on value (negation)<br />
<br />
[[#Beispiel_switch|Link zu einem Beispiel]]<br />
<br />
=== Widget SYMBOL ===<br />
<div id="symbol">'''SYMBOL'''</div><br />
<br />
Mit dem SYMBOL Widget kann der STATUS eines Device dargestellt werden. Dabei kann das angezeigte Symbol und dessen Farbe bestimmt werden. Wie bei anderen Widgets kann das Symbol und die Farbe vom State abhängig konfiguriert werden. Das SYMBOL-Widget dient nur zur Anzeige eines STATUS, es besitzt kein Möglichkeit der Interaktion.<br />
<br />
Neben den '''allgemeine Attribute''' besitzt das SYMBOL-Widget die nachfolgenden Attribute.<br />
<br />
dual state notation<br />
{| class="wikitable"<br />
! HTML Attribut !! Beschreibung !! Default Wert<br />
|-<br />
| data-get || Name des Reading, was gelesen werden soll || 'STATE' <br />
|}<br />
<br />
Einstellung bei zwei Werten<br />
{| class="wikitable"<br />
!HTML-Attribut !! Beschreibung !! Default-Wert<br />
|-<br />
|'''data-get-on''' ||Wert für on ||'open'<br />
|-<br />
|'''data-get-off''' ||Wert für off ||'closed'<br />
|-<br />
|'''data-get-warn''' ||?????? ||'-1'<br />
|-<br />
|'''data-icon''' ||Name des Symbols ||'ftui-window'<br />
|-<br />
|'''data-background-icon''' ||Hintergrundsymbol ||'''leer'''<br />
|-<br />
|'''data-on-background-color''' ||Farbe für ON-Zustand. ||'#aa6900'<br />
|-<br />
|'''data-off-background-color''' ||Farbe für OFF-Zustand. ||'#505050'<br />
|-<br />
|'''data-on-color''' ||Farbe für ON-Zustand. ||'#aa6900'<br />
|-<br />
|'''data-off-color''' ||Farbe für OFF-Zustand. ||'#505050'<br />
|-<br />
|}<br />
<br />
Einstellung bei mehreren Werten<br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-states<br />
|Array für states. <br />
|<br />
|-<br />
!align="right" |data-icons<br />
|Array mit Icons zu data-states Array<br />
|<br />
|-<br />
!align="right" |data-background-icons<br />
|Array mit Icons zu data-states Array<br />
|<br />
|-<br />
!align="right" |data-colors<br />
|Array mit Farben zu data-states aArray<br />
|''<br />
|-<br />
!align="right" |data-background-colors<br />
|Array mit Hintergrundfarben zu data-states array<br />
|''<br />
|-<br />
|}<br />
<br />
data-get-on,data-get-off and data-states accept also RegEx values. The value for one icon can also contain an additional animatation CSS name, e.g. "fa-exclamation-triangle fa-blink" for a blinking Symbol<br />
<br />
[[#Beispiel_symbol|Link zu einem Beispiel]]<br />
<br />
=== Widget THERMOSTAT===<br />
<div id="thermostat">'''THERMOSTAT'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from FHEM<br />
|'desired-temp'<br />
|-<br />
!align="right" |data-temp<br />
|reading for measured temperature of thermostates<br />
|'measured-temp'<br />
|-<br />
!align="right" |data-set<br />
|command to send to FHEM (set <device> <command> <value>)<br />
|'desired-temp'<br />
|-<br />
!align="right" |data-valve<br />
|reading for valve position of thermostates<br />
|<br />
|-<br />
!align="right" |data-min<br />
|minimal value to set<br />
| 10<br />
|-<br />
!align="right" |data-max<br />
|maximal value to set<br />
| 30<br />
|-<br />
!align="right" |data-minColor<br />
|Farbe des Keises für Min<br />
| #4477FF<br />
|-<br />
!align="right" |data-maxColor<br />
|Farbe des Kreises für Max, zwischen Min und Max wird linear interpoliert <br />
| #FF0000<br />
|-<br />
!align="right" |data-step<br />
|step size for value adjustment e.g. 0.5 <br />
|1<br />
|-<br />
!align="right" |data-bgColor<br />
|Die Farbe der Kreises zwischen den ticks<br />
|'transparent'<br />
|-<br />
!align="right" |data-fgColor<br />
|Die Farbe der zahl im Kreismittelpunkt<br />
|#bbbbbb<br />
|-<br />
!align="right" |data-tkColor<br />
|Die Farbe der ticks<br />
|#696969<br />
|-<br />
|-<br />
!align="right" |data-angleOffset<br />
|Start der ticks im Kreis (in Winkelgraden, 0 = oben)<br />
| -120<br />
|-<br />
!align="right" |data-angleArc<br />
|Bereich der ticks im Kreis (in Winkelgraden)<br />
|240<br />
|-<br />
!align="right" |class<br />
|big, readonly<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_thermostat|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="volume">'''VOLUME'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from FHEM <br />
|'STATE'<br />
|-<br />
!align="right" |data-set<br />
|command to send to FHEM (set <device> <command> <value>)<br />
|''<br />
|-<br />
!align="rigth" |data-cmd<br />
|name of the command (<command> <device> <value>) (e.g. setstate, set, setreading, trigger) <br />
|'set'<br />
|-<br />
!align="right" |data-min<br />
|minimal value to set<br />
|0<br />
|-<br />
!align="right" |data-max<br />
|maximal value to set<br />
|70<br />
|-<br />
!align="right" |data-get-value<br />
|RegEx to retrieve the value or part number of the space separated input to get the value<br />
|'-1': all of the input<br />
|-<br />
!align="right" |data-set-value<br />
|Format of the value to send to FHEM<br />
|'$v': the value only<br />
|-<br />
!align="right" |data-tickstep<br />
|distance between ticks<br />
|4|20<br />
|-<br />
!align="right" |data-unit<br />
|add a unit after the desired value.<br />
|<br />
|-<br />
!align="right" |class<br />
|mini, small, big, bigger, hue-tick, hue-front, hue-back, dim-tick ,dim-front, dim-back, readonly<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_volume|Link zu einem Beispiel]] (fehlt noch)<br />
<br />
<br />
<div id="weather">'''WEATHER'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get the weather literal from FHEM<br />
|'STATE'<br />
|-<br />
!align="right" |data-imageset<br />
|collection of images to display current weather situation. Possible values: 'meteocons', 'kleinklima'<br />
|'meteocons'<br />
|-<br />
!align="right" |data-image-path<br />
|path to the images of the selected imageset<br />
|/images/weather/<br />
|-<br />
|}<br />
<br />
[[#Beispiel_weather|Link zu einem Beispiel]]<br />
<br />
== Widgets -- Beispiele ==<br />
<br />
<div id="Beispiel_chart">'''Chart'''</div><br />
<br />
Display a chart with similar capabilities as the FHEM plots<br />
<br />
<pre><br />
<div data-type="chart"<br />
data-logdevice='["Log.Garden","Log.Garden","Log.Garden","Log.Predicted"]'<br />
data-columnspec='["4:Garden.T:15:","10:Garden.T:0:delta-h","10:Garden.T:0:delta-d","4:predicted.*:15:"]'<br />
data-style='["ftui l0fill","ftui l1fill","ftui l2","ftui l3dot"]'<br />
data-ptype='["lines","histeps","histeps","cubic"]'<br />
data-uaxis='["primary","secondary","secondary","primary"]'<br />
data-legend='["Temperature","Rain/hour","Rain/day","Predicted Temp."]'<br />
data-yunit="°C"<br />
data-ytext="Temperature"<br />
data-minvalue="auto"<br />
data-maxvalue="auto"<br />
data-yunit_sec="mm"<br />
data-ytext_sec="Rain (mm)"<br />
data-height="250"<br />
data-yticks="auto"<br />
data-minvalue_sec="auto"<br />
data-maxvalue_sec="auto"<br />
data-nofulldays="true"<br />
data-daysago_start="2013-08-13T00:00:00"<br />
data-daysago_end="2013-08-14T00:00:00"<br />
data-cursorgroup="1"<br />
data-scrollgroup="1"<br />
data-xticks="auto"><br />
</div><br />
</pre><br />
<br />
[[Datei:chart_tabletUI.png]]<br />
<br />
<br />
<div id="Beispiel_circlemenu">'''Circlemenu'''</div><br />
<br />
Cover a lot of other button behind one single button<br />
<br />
<pre><br />
<div class="left"><br />
<div data-type="circlemenu" class="cell circlemenu"><br />
<ul class="menu"><br />
<li><div data-type="push" data-icon="fa-wrench"></div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level -6" <br />
data-icon="">-6</div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level -2" <br />
data-icon="">-2</div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level 0" <br />
data-icon="">0</div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level +3" <br />
data-icon="">2</div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level +9" <br />
data-icon="">9</div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level +C" <br />
data-icon="">12</div></li><br />
</ul><br />
</div><br />
<div data-type="label" class="cell">Woofer</div><br />
</div><br />
</pre><br />
<br />
[[Datei:circlemenu_tabletUI.png]]<br />
<br />
<br />
<div id="Beispiel_departure">'''Departure'''</div><br />
<br />
Departure Widget Beispiel<br />
<br />
Minimalvariante<br />
<pre> <br />
<div data-type="departure"<br />
data-device="vvs"<br />
data-get="SSB-Zentrum"<br />
data-icon="fa-train"<br />
data-interval="0"><br />
</div><br />
</pre><br />
<br />
Optionen für class<br />
<pre><br />
class="" : default Style (grau)<br />
class="DVB" anderer Style (gelb)<br />
class="VVO" : anderer Style (blau)<br />
class="alternate" : alternierender Hintergrund<br />
class="deptime" : Abfahrtszeit statt Minuten<br />
</pre><br />
<br />
weiteres Beispiel<br />
<pre><br />
<div data-type="departure"<br />
data-device="vvs"<br />
data-get="SSB-Zentrum"<br />
data-icon="fa-train"<br />
data-interval="0"<br />
class="DVB deptime alternate"><br />
</div><br />
</pre><br />
<br />
<br />
<div id="Beispiel_dimmer">'''Dimmer'''</div><br />
<br />
Dimmer Widget Beispiel für Philips Hue<br />
<br />
Minimalvariante<br />
<pre> <br />
<div data-type="dimmer" data-device="HUEDevice1"<br />
data-get-on="!off" data-get-off="off"<br />
data-set="pct"></div><br />
</pre><br />
<br />
Mit Anzeige der Dimstufe<br />
<pre><br />
<div data-type="dimmer" data-device="HUEDevice1"<br />
data-get="onoff"<br />
data-get-on="1" data-get-off="0"<br />
data-set=""<br />
data-set-on="on" data-set-off="off"<br />
data-dim="pct"><br />
</div><br />
</pre><br />
<br />
Dimmer Widget für MilightDevice<br />
<br />
<pre><br />
<div data-type="dimmer"<br />
data-device="SonstWas"<br />
data-get="brightness"<br />
data-get-off="0"<br />
data-get-on="[1-9][0-9]*"<br />
data-set-on="on"<br />
data-set-off="off"<br />
data-dim="dim"<br />
data-min="0"<br />
data-max="100"<br />
></div><br />
</pre><br />
<br />
<br />
<div id="Beispiel_homestatus">'''Homestatus'''</div><br />
<br />
Beispiel rechts im Bild:<br />
<pre><br />
<div data-type="homestatus" data-device='dummy1'<br />
data-get-on='["1","2","3","4"]'<br />
data-alias='["Home","Night","Away","Holiday"]'<br />
data-icons='["fa-home","fa-bed","fa-car","fa-suitcase"]'><br />
</div><br />
</pre><br />
<br />
Beispiel links im Bild:<br />
<pre><br />
<div data-type="homestatus" data-device='dummy1'<br />
data-get-on='["home","asleep","absent","gone","gotosleep"]'<br />
data-alias='["Home","Night","Away","Holiday","Retire"]'<br />
data-icons='["fa-fire","fa-film","fa-plus","fa-car","fa-tint"]'<br />
data-version='residents'><br />
</div><br />
</pre><br />
<br />
[[Datei:homestatus_tabletUI.png]]<br />
<br />
<br />
<br />
<div id="Beispiel_image">'''Image'''</div><br />
<br />
<br />
Erzeugt ein Widget mit einem Bild aus dem www, das alle 5 Sekunden aktualisiert wird (hier eine Wetterkarte vom DWD).<br />
<br />
<pre><br />
<div data-type="image"<br />
data-size="80%"<br />
data-url="http://www.dwd.de/wundk/wetter/de/Deutschland.jpg"<br />
</div><br />
</pre><br />
<br />
[[Datei:image_tabletUI.jpg]]<br />
<br />
<br />
Example for how to add an image to the dashboard which its URL is delivered by a FHEM module like PROPLANTA:<br />
<br />
<pre><br />
<div data-type="image" data-device="Wetter1" <br />
data-get="fc0_weatherDayIcon" <br />
data-size="40px" <br />
class="cell"><br />
</div><br />
</pre><br />
<br />
<br />
<div id="Beispiel_label">'''Label'''</div><br />
<br />
Example for HM-WDS40-TH-I Funk-Temperatur-/Feuchtesensor innen<br />
<br />
<pre><br />
STATE T: 20.0 H: 61<br />
</pre><br />
<pre><br />
<div data-type="label" data-device="THSensorWZ" <br />
data-part="2" data-unit="%B0C%0A" class="cell big"></div><br />
<div data-type="label" class="cell">Temperatur</div><br />
<div data-type="label" data-device="THSensorWZ" data-part="4" <br />
data-unit="%" class="cell big"></div><br />
<div data-type="label" class="cell">Luftfeuchte</div><br />
</pre><br />
<br />
But the same result can reached by getting single readings:<br />
<pre><br />
humidity 58<br />
temperature 20.1<br />
</pre><br />
<br />
<pre><br />
<div data-type="label" data-device="THSensorWZ" <br />
data-get="temperature" data-unit="%B0C%0A" class="cell big"></div><br />
<div data-type="label" class="cell">Temperatur</div><br />
<div data-type="label" data-device="THSensorWZ" <br />
data-get="humidity" data-unit="%" class="cell big"></div><br />
<div data-type="label" class="cell">Luftfeuchte</div><br />
</pre><br />
<br />
Example for how to influence the color of the label according to value limits<br />
<pre><br />
<div data-type="label" <br />
data-device="OutTemp" <br />
data-limits='[-73,10,23]' <br />
data-colors='["#6699FF","#AA6900","#FF0000"]' <br />
data-unit="%B0C%0A" <br />
class="cell big"><br />
</div><br />
</pre><br />
<br />
Example for how to create a widget for shutter via push: show state and set up/down<br />
<pre><br />
<div data-type="switch" <br />
data-device="wzRollo" <br />
data-get-on="up" <br />
data-get-off="down" <br />
data-icon="fa-bars" <br />
class="cell" ><br />
</div><br />
<div data-type="label" <br />
class="cell">Rollo</div><br />
</pre><br />
<br />
Example for how to create a label for a time value in short format with usage of RegEx.<br />
<br />
<pre><br />
<div data-type="label" <br />
data-device="dummy1" <br />
data-part="(\d\d\.\d\d\.).*" <br />
class="cell"><br />
</div><br />
</pre><br />
<br />
Example for how to show two labels in one line.<br />
<br />
<pre><br />
<div class=""><br />
<div type="label" device="OnSunrise" class="inline"></div>bis<br />
<div type="label" device="OnSunset" class="inline"></div><br />
</div><br />
</pre><br />
<br />
Beispiel für die Anzeige des UV-Indexes und der Abhängigkeit der anzuzeigenden Farbe.<br />
<br />
<pre><br />
<div data-type="label" class="wider cell bigger" data-device="ProVorhersage"<br />
data-get="fc0_uv"<br />
data-limits="[-2, 2, 5, 7, 10]" <br />
data-colors='["#66FF33","#FFFF00","#FF6600","#FF0000","#993399"]'></div><br />
<div data-type="label" class="cell" data-device="ProVorhersage" data-get="fc0_date"></div><br />
<div data-type="label" class="wider cell bigger" data-device="ProVorhersage"<br />
data-get="fc1_uv"<br />
data-limits="[-2, 2, 5, 7, 10]"<br />
data-colors='["#66FF33","#FFFF00","#FF6600","#FF0000","#993399"]'></div><br />
<div data-type="label" class="cell" data-device="ProVorhersage" data-get="fc1_date"></div><br />
</pre><br />
<br />
[[Datei:label_tabletUI.jpg]]<br />
<br />
Beispiel für die Anzeige des Labels als Icon.<br />
<pre><br />
<div class="cell"><br />
<div data-type="label" data-device="AvReceiver" data-get="input" class="icon round bg-red cell"></div><br />
<div data-type="label" data-device="AvReceiver" data-get="input" class="icon square bg-blue cell"></div><br />
<div data-type="label" data-device="AvReceiver" data-get="input" class="icon squareborder cell"></div><br />
<div data-type="label" data-device="PowerAV_Sw" data-colors='["red","green"]' data-limits='["off","on"]' class="icon round bg-limit cell"></div><br />
</div><br />
</pre><br />
<br />
[[Datei:Label_tabletUI_icon.png]]<br />
<br />
<div id="Beispiel_pagetab">'''Pagetab'''</div><br />
<br />
Example for a tab menu to switch smoothly between multiple pages. Multiple pagetabs in a template file: menu.html<br />
<br />
<pre><br />
<html><br />
<body><br />
<header>MENU</header><br />
<div class="cell"><br />
<div data-type="pagetab" data-url="index.html" data-icon="fa-home" class="cell"></div><br />
<div data-type="pagetab" data-url="index_2.html" data-icon="fa-sliders" class="cell"></div><br />
<div data-type="pagetab" data-url="index_3.html" data-icon="fa-music" class="cell"></div><br />
<div data-type="pagetab" data-url="index_4.html" data-icon="fa-hotel" class="cell"></div><br />
<div data-type="pagetab" data-url="index_5.html" data-icon="fa-music" class="cell"></div><br />
<div data-type="pagetab" data-url="index_6.html" data-icon="fa-database" class="cell"></div><br />
<div data-type="pagetab" data-url="index_7.html" data-icon="fa-fax" class="cell"></div><br />
</div><br />
</body><br />
</html><br />
</pre><br />
<br />
<br />
<div id="Beispiel_playstream">'''Playstream'''</div><br />
<br />
Erzeugt einen Knopf zum direkten Abspielen eines Webradio-Streams.<br />
<br />
<pre><br />
<div data-type="playstream" data-url="http://radioeins.de/stream"></div><br />
<div data-type="label" class="darker">Radio eins</div><br />
</pre><br />
<br />
<br />
<div id="Beispiel_push">'''Push'''</div><br />
<br />
Example for how to create a push button widget to trigger all devices on:<br />
<br />
<pre><br />
<div data-type="push" <br />
data-device="LightAll" <br />
data-cmd="trigger" <br />
data-set="on" <br />
class="cell"><br />
</div><br />
</pre><br />
<br />
<br />
Beispiel für zwei horizontale Buttons:<br />
<br />
<pre><br />
<div class="cell"><br />
<div class="doublebox-h"><br />
<div data-type="push" data-device="Rollo" <br />
data-icon="fa-angle-up" data-background-icon="fa-square-o" <br />
data-set="up"><br />
</div><br />
<div data-type="push" data-device="Rollo" <br />
data-icon="fa-angle-down" data-background-icon="fa-square-o" <br />
data-set="down"><br />
</div><br />
</div><br />
</div><br />
</pre><br />
<br />
[[Datei:push1.png]]<br />
<br />
<br />
Beispiel für zwei quadratische vertikale Buttons:<br />
<br />
<pre><br />
<div class="cell"><br />
<div class="doublebox-v"><br />
<div data-type="push" data-device="Rollo" <br />
data-icon="fa-chevron-up" data-background-icon="fa-square-o" <br />
data-set="up"><br />
</div><br />
<div data-type="push" data-device="Rollo" <br />
data-icon="fa-chevron-down" data-background-icon="fa-square-o" <br />
data-set="down"><br />
</div><br />
</div><br />
</div><br />
</pre><br />
<br />
[[Datei:push2.png]]<br />
<br />
<br />
<div id="Beispiel_rotor">'''Rotor'''</div><br />
<br />
Example for a rotor widget, which switches between to days of weather forecast<br />
<br />
<pre><br />
<div data-type="rotor" class="fade"><br />
<ul><br />
<li><br />
<div data-type="label" class="darker">Heute</div><br />
<div data-type="weather" data-device="AgroWeather" data-get="fc0_weatherDay" class="big"></div><br />
<div data-type="label" data-device="AgroWeather" data-get="fc0_weatherDay" class=""></div><br />
<div data-type="label" data-device="AgroWeather" data-get="fc0_tempMax" data-unit="%B0C%0A" class="large"></div><br />
</li><br />
<li><br />
<div data-type="label" class="darker">Morgen</div><br />
<div data-type="weather" data-device="AgroWeather" data-get="fc1_weatherDay" class="big"></div><br />
<div data-type="label" data-device="AgroWeather" data-get="fc1_weatherDay" class=""></div><br />
<div data-type="label" data-device="AgroWeather" data-get="fc1_tempMax" data-unit="%B0C%0A" class="large"></div><br />
</li><br />
</ul><br />
</div><br />
</pre><br />
<br />
<br />
<br />
<div id="Beispiel_select">'''Select'''</div><br />
<br />
Erzeugt zwei Comboboxen zur Auswahl des Eingang eines 2-Zonen-AV-Receivers. Die Liste für Zone2 ist fest, die Liste für Zone1 wird von FHEM übergeben.<br />
<br />
<pre><br />
<div class="cell wider"><br />
<div data-type="label" class="inline wider">Zone2</div><br />
<div data-type="select" data-device="AvReceiverZ2" data-items='["Airplay","Webradio","BD/DVD","PHONO"]' data-get="input" data-set="input" class="cell w2x" ></div><br />
<div></div><br />
<div data-type="label" class="inline">Zone1</div><br />
<div data-type="select" data-device="AvReceiver" data-list="inputs" data-get="input" data-set="input" class="cell w2x" ></div><br />
</div><br />
</pre><br />
<br />
[[Datei:select_tabeltUI.png]]<br />
<br />
<br />
<div id="Beispiel_slider">'''Slider'''</div><br />
<br />
<br />
Slider mit einstellbaren Werten von 10 bis 90:<br />
<br />
<pre><br />
<div data-type="slider" <br />
data-device='Dummy1' <br />
data-min="10" <br />
data-max="90" <br />
class="cell" ><br />
</div><br />
<div data-type="label" class="cell">Light1</div><br />
</pre><br />
<br />
[[Datei:slider_tabletUI.png]]<br />
<br />
<br />
Horizontal angeordneter Slider:<br />
<br />
<pre><br />
<div data-type="slider"<br />
data-device='Dummy1' <br />
data-min="0" <br />
data-max="100" <br />
class="horizontal" <br />
</div><br />
</pre><br />
<br />
[[Datei:slider_tabletUI2.jpg]]<br />
<br />
<br />
<div id="Beispiel_switch">'''Switch'''</div><br />
<br />
Schalter. Usage of RegEx pattern for state request:<br />
<br />
<pre><br />
<div data-type="switch" class="cell" <br />
data-device="MILIGHT_Zone1_Wohnzimmer" <br />
data-get-on="on.*"<br />
data-get-off="off"></div><br />
</pre><br />
<br />
[[Datei:switch.png]]<br />
<br />
Beispiel für eine Gruppe von Schaltern, um zwischen vier verschiedenen Werten eines device umzuschalten:<br />
<br />
<pre><br />
<div class="cell left"><br />
<div data-type="switch" data-device="dummy1" <br />
data-get-off="((?!Wert1).)*" <br />
data-get-on="Wert1" class="cell" ></div><br />
<div data-type="label" class="cell">Wert1</div><br />
<div data-type="switch" data-device="dummy1" <br />
data-get-off="((?!Wert2).)*" <br />
data-get-on="Wert2" class="cell" ></div><br />
<div data-type="label" class="cell">Wert2</div><br />
<div data-type="switch" data-device="dummy1" <br />
data-get-off="((?!Wert3).)*" <br />
data-get-on="Wert3" class="cell" ></div><br />
<div data-type="label" class="cell">Wert3</div><br />
<div data-type="switch" data-device="dummy1" <br />
data-get-off="((?!Wert4).)*" <br />
data-get-on="Wert4" class="cell" ></div><br />
<div data-type="label" class="cell">Wert4</div><br />
</div><br />
</pre><br />
<br />
[[Datei:switch4.png]]<br />
<br />
<br />
<div id="Beispiel_symbol">'''Symbol'''</div><br />
<br />
Example for a tristate icon<br />
<br />
<pre><br />
<div data-type="symbol" data-device="dummy1" <br />
data-get-on='["wert1","wert2","wert3"]' <br />
data-icons='["fa-arrow-up","fa-user","fa-arrow-down"]' <br />
data-on-colors='["SeaGreen","SlateBlue","IndianRed"]' <br />
class="cell big"><br />
</div><br />
</pre><br />
<br />
<br />
Example for a tristate icon with blink and spin animation<br />
<br />
<pre><br />
<div data-type="symbol" data-device="dummy1" <br />
data-icons='["fa-exclamation-triangle fa-blink","fa-exclamation-circle","fa-cog fa-spin"]' <br />
data-on-colors='["Crimson","GoldenRod","SeaGreen"]' <br />
data-get-on='["Wert1","Wert2","Wert3"]' ><br />
</div><br />
</pre><br />
<br />
<br />
Example for a battery level control with RegEx<br />
<br />
<pre><br />
<div data-type="symbol" data-device="BadHeizung" data-get="batteryLevel"<br />
data-icons='["oa-measure_battery_100","oa-measure_battery_75","oa-measure_battery_50","oa-measure_battery_25","oa-measure_battery_0"]'<br />
data-get-on='["3\\.[0-9]","2\\.[789]","2\\.[456]","2\\.[123]","((2\\.0)|([01]\\.[0-9]))"]'<br />
data-on-colors='["#505050","#505050","#505050","#ad3333","#ad3333"]'><br />
</div><br />
</pre><br />
<br />
<br />
<br />
Example for a battery level control with greater-equal compare and 90° rotated symbols<br />
<br />
<pre><br />
<div data-type="symbol" data-device="BadHeizung" data-get="batteryLevel"<br />
data-icons='["oa-measure_battery_0 fa-rotate-90","oa-measure_battery_25 fa-rotate-90","oa-measure_battery_50 fa-rotate-90","oa-measure_battery_75 fa-rotate-90","oa-measure_battery_0 fa-rotate-90"]'<br />
data-get-on='["0","2","2.4","2.7","3.0"]'<br />
data-on-colors='["#ad3333","#ad3333","#505050","#505050","#505050"]'><br />
</div><br />
</pre><br />
<br />
<br />
<div id="Beispiel_thermostat">'''Thermostat'''</div><br />
<br />
Configure as data-device='...' that item which delivers temp and desired-temp as reading.<br />
<br />
Default parameters are:<br />
<pre><br />
data-get="desired-temp" data-temp="measured-temp" data-set="desired-temp"<br />
</pre><br />
<br />
Therefor for HomaMatic HM-CC-RT-DN this is sufficient.<br />
<br />
<pre><br />
<div data-type="thermostat" data-device='KH_Clima' class="cell"></div><br />
</pre><br />
<br />
The long format looks like this:<br />
<br />
<pre><br />
<div data-type="thermostat" <br />
data-device="KH_Clima" <br />
data-valve="ValvePosition"<br />
data-get="desired-temp" <br />
data-temp="measured-temp" <br />
class="cell"><br />
</div><br />
</pre><br />
<br />
<br />
Example for MAX!:<br />
<pre><br />
<div data-type="thermostat" data-device="HZ_Tuer" <br />
data-valve="valveposition" <br />
data-get="desiredTemperature" <br />
data-temp="temperature" <br />
data-set="desiredTemperature" <br />
class="cell"><br />
</div><br />
</pre><br />
<br />
The wigets will show the valve value only in case of a valid data-valve attribute. The default for data-valve ist null. That means, a empty data-valve attribute hides the valve label for the widget.<br />
<br />
[[Datei:thermostat.png]]<br />
<br />
<br />
<div id="Beispiel_weather">'''Weather'''</div><br />
<br />
Das Widget fügt ein dem Wetter entsprechendes Bild ein. Die Daten können durch FHEM-Module wie [[PROPLANTA]], [[OPENWEATHER]] und [[Weather]] bereitgestellt werden. <br />
Add 'big' or 'bigger' to CSS class to get a bigger weather icon.<br />
<br />
Beispiel:<br />
<pre><br />
<div data-type="weather" <br />
data-device="Weather" <br />
data-get="fc0_weatherDay" <br />
class="cell big"><br />
</div><br />
</pre><br />
<br />
[[Datei:weather.png]]<br />
<br />
== Icon-Konfiguration ==<br />
<br />
* Eingebaute Icons: Diese haben das ftui-Präfix. Zurzeit sind folgende verfügbar: ftui-window, ftui-door<br />
<br />
* Mehr als 500 Icons von "http://fortawesome.github.io/Font-Awesome/icons" verfügbar. Einfach den Icon-Namen angeben (Präfix "fa-" nicht vergessen, Z.B. <code>data-icon="fa-volume-up"</code><br />
<br />
* Es stehen auch Openautomation Font-Files zur Verfügung. Wer sie nutzen möchte, muss folgende Stylesheets in die index.html hinzufügen.<br />
<pre><br />
<link rel="stylesheet" href="/fhem/tablet/lib/openautomation.css" /><br />
<link rel="stylesheet" href="/fhem/tablet/lib/fhemSVG.css" /><br />
</pre><br />
<br />
Diese font icons haben das Präfix 'fs-' bzw. 'oa-'.<br />
<br />
Beispiel bei einem Schalter:<br />
<pre><div data-type="switch" data-device='dummy1' data-icon="oa-secur_locked"></div></pre><br />
<br />
<br />
Und so als großes Symbol:<br />
<pre><br />
<div data-type="symbol" data-device='dummy1'<br />
data-icon="oa-status_frost"<br />
data-on-color="#bb3232"<br />
data-get-on="on"<br />
data-get-off="!on"<br />
class="bigger"><br />
</div><br />
</pre><br />
<br />
<br />
Die Icons kann man auch etwas dicker darstellen mit den Zusatz bold: <code>data-icon="oa-secur_locked bold"</code><br />
<br />
<br />
Die Namen der verfügbaren Icons findet man auch in den CSS Files (openautomation.css / fhemSVG.css)<br />
<br />
== Spezial ==<br />
Folgender Befehl setzt einen direkten Befehl an FHEM ab (<code>set dummy1 off</code>):<br />
<pre><br />
<div onclick="ftui.setFhemStatus('set dummy1 off')">All off!</div><br />
</pre><br />
<br />
== FAQ ==<br />
Häufig gestellte Fragen zum FHEM Tablet UI sind in der [[FHEM_Tablet_UI/FAQ|FHEM Tablet UI FAQ]] zusammengestellt.<br />
<br />
== Links ==<br />
* [http://forum.fhem.de/index.php/topic,34233.0.html Forums-Beitrag]<br />
* [https://github.com/knowthelist/fhem-tablet-ui Projekt auf Github]<br />
* [http://forum.fhem.de/index.php/topic,37378.0.html User-Demos]<br />
* [https://github.com/ovibox/fhem-ftui-user-demos Download der User-Demo-Dateien]<br />
<br />
[[Kategorie:FHEM Tablet UI]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=DbLog&diff=19288DbLog2017-02-02T08:43:22Z<p>Hauswart: /* Dateigroesse mitloggen */</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 />
}}<br />
<br />
<br />
== Einleitung ==<br />
Mit der Zeit entstehen im fhem recht umfangreiche Log-Daten für die verschiedensten konfigurierten Devices. Die übliche Einstiegs-[[Konfiguration]] sieht vor, dass die Logs als [http://fhem.de/commandref_DE.html#FileLog FileLog] gespeichert werden - je nach Einstellung in wenigen sehr großen oder vielen kleineren Dateien. Der Datei-basierte Zugriff ist allerdings nicht wirklick 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 [http://fhem.de/commandref_DE.html#DbLog 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 />
<br />
== Konfiguration ==<br />
=== Datenbank-Anbindung mittels db.conf ===<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 />
<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 />
=== 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 2 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 />
<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. [http://fhem.de/commandref_DE.html#event-on-update-reading commandref])<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 commandref.<br />
<br />
== Datenbank ==<br />
Unterstützte Datenbanksysteme (Auswahl):<br />
* Sqlite<br />
* MySQL<br />
* PostGreSql<br />
<br />
=== Tabellen ===<br />
* current<br />
* history<br />
<br />
<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 />
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.<br />
<br />
=== Tabellenlayout ===<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 />
== 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 />
<pre><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 />
</pre><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/ http://www.tatsch-it.de/fhem-dblog/])<br />
<ol><br />
<li><br />
''Installation von SQLite:''<br />
<pre>sudo aptitude install sqlite3 libdbi-perl libdbd-sqlite3-perl</pre><br />
</li><br />
<li><br />
''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, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(512), READING varchar(32), VALUE varchar(32), UNIT varchar(32));<br />
CREATE TABLE 'current' (TIMESTAMP TIMESTAMP, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(512), READING varchar(32), VALUE varchar(32), UNIT varchar(32));<br />
</pre><br />
Die Kommandozeile verlässt man mit <code>.exit</code>.<br />
</li><br />
<li><br />
''Anpassen des Besitzers und der Rechte der Datenbank-Datei:''<br />
<pre><br />
sudo chown fhem /opt/fhem/fhem.db<br />
sudo chmod 666 /opt/fhem/fhem.db<br />
</pre><br />
</li><br />
<li><br />
''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><br />
''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><br />
''FHEM neu starten:''<br />
<pre><br />
sudo service fhem stop<br />
sudo service fhem start<br />
</pre><br />
</li><br />
<li><br />
''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><br />
''Anpassung der glot-Dateien:'' siehe [[#Anpassen der gplot-Konfigurationen]]<br />
</li><br />
</ol><br />
<br />
<br />
== Beispiel: Anlegen und Nutzung einer Mysql-Datenbank ==<br />
Unter Ubuntu: <br />
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 />
<br />
nun zu mysql verbinden:<br />
mysql -p -u root<br />
Enter password:<br />
<br />
Jetzt die Tabellenstruktur anlegen. <br />
Hierfür kann nach Bedarf in der Datei /opt/fhem/contrib/dblog/db_create_mysql.sql das Passwort und der Benutzername geändert werden.<br />
Dann wird die Datei eingelesen: <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 />
vim /opt/fhem/contrib/dblog/db.conf<br />
<br />
Jetzt kann ein DbLog-Device angelegt werden: <br />
define logdb DbLog ./contrib/dblog/db.conf .*:.* # loggt ALLES!<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 />
<source 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 current; # Achtung, kann sehr groß werden .... #<br />
</source><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 />
<source lang="perl"><br />
sub X_Initialize($)<br />
{<br />
my ($hash) = @_;<br />
...<br />
$hash->{DbLog_splitFn} = "X_DbLog_splitFn";<br />
}<br />
</source><br />
<br />
Die genaue Aufrufsyntax und Funktionweise einer DbLog_split-Funktion findet man [[DevelopmentModuleIntro#X_DbLog_split|hier]].<br />
<br />
== Bekannte Probleme ==<br />
Beim Anlegen der Datenbank per script wird die Value-Spalte nur als Varchar(32) definiert. Dieses kann dazu führen, dass besonders lange Readings (z.b. vom Modul sysmon) abgeschnitten werden und nicht in der Datenbank landen. Dieses lässt sich leicht beheben, indem man die Spalte auf Varchar(64) ändert (siehe auch {{Link2Forum|Topic=25648|Message=252433|LinkText=diesen Forenbeitrag}}).<br />
<br />
mysql> ALTER TABLE current MODIFY VALUE VARCHAR(64);<br />
mysql> ALTER TABLE history MODIFY VALUE VARCHAR(64);<br />
<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 insb. auch dann hilfreich, wenn man eigenen Funktionen, Notifys oder spezielle Plots entwirft, bei denen man auf Logdaten zugreifen möchte.<br />
<br />
Grundsätzlich beschrieben ist dies in der [http://fhem.de/commandref_DE.html#DbLog commandref#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 den fhem ausmacht um Datenfehler zu vermeiden). Eine Datenbank kann bearbeitet werden ohne den fhem abschalten zu müssen. <br />
<br />
Datenbanken kann man ohne weiter 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 />
<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 />
=== 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><br />
DB öffnen:<br />
<pre>sudo sqlite3 fhem.db</pre><br />
</li><br />
<li><br />
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><br />
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><br />
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><br />
Spätestens jetzt fhem stoppen:<br />
<pre>sudo service fhem stop</pre><br />
</li><br />
<li><br />
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><br />
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><br />
fhem wieder starten (und natürlich kontrollieren):<br />
<pre>sudo service fhem start</pre><br />
</li><br />
</ol><br />
<br />
<br />
<br />
== Nützliche Codeschnipsel ==<br />
Anbei ein paar nützliche Codeschnipsel rund um DbLog<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:lastReduceLogResult.* { (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 />
== Links ==<br />
* [[Heizleistung_und_Gasverbrauch|Beispiel das DbLog-Daten für SVG-Plots verwendet]]<br />
* [[SVG-Plots von FileLog auf DbLog umstellen]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=DbLog&diff=19287DbLog2017-02-02T08:38:56Z<p>Hauswart: /* Tabellenlayout */</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 />
}}<br />
<br />
<br />
== Einleitung ==<br />
Mit der Zeit entstehen im fhem recht umfangreiche Log-Daten für die verschiedensten konfigurierten Devices. Die übliche Einstiegs-[[Konfiguration]] sieht vor, dass die Logs als [http://fhem.de/commandref_DE.html#FileLog FileLog] gespeichert werden - je nach Einstellung in wenigen sehr großen oder vielen kleineren Dateien. Der Datei-basierte Zugriff ist allerdings nicht wirklick 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 [http://fhem.de/commandref_DE.html#DbLog 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 />
<br />
== Konfiguration ==<br />
=== Datenbank-Anbindung mittels db.conf ===<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 />
<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 />
=== 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 2 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 />
<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. [http://fhem.de/commandref_DE.html#event-on-update-reading commandref])<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 commandref.<br />
<br />
== Datenbank ==<br />
Unterstützte Datenbanksysteme (Auswahl):<br />
* Sqlite<br />
* MySQL<br />
* PostGreSql<br />
<br />
=== Tabellen ===<br />
* current<br />
* history<br />
<br />
<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 />
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.<br />
<br />
=== Tabellenlayout ===<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 />
== 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 />
<pre><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 />
</pre><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/ http://www.tatsch-it.de/fhem-dblog/])<br />
<ol><br />
<li><br />
''Installation von SQLite:''<br />
<pre>sudo aptitude install sqlite3 libdbi-perl libdbd-sqlite3-perl</pre><br />
</li><br />
<li><br />
''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, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(512), READING varchar(32), VALUE varchar(32), UNIT varchar(32));<br />
CREATE TABLE 'current' (TIMESTAMP TIMESTAMP, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(512), READING varchar(32), VALUE varchar(32), UNIT varchar(32));<br />
</pre><br />
Die Kommandozeile verlässt man mit <code>.exit</code>.<br />
</li><br />
<li><br />
''Anpassen des Besitzers und der Rechte der Datenbank-Datei:''<br />
<pre><br />
sudo chown fhem /opt/fhem/fhem.db<br />
sudo chmod 666 /opt/fhem/fhem.db<br />
</pre><br />
</li><br />
<li><br />
''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><br />
''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><br />
''FHEM neu starten:''<br />
<pre><br />
sudo service fhem stop<br />
sudo service fhem start<br />
</pre><br />
</li><br />
<li><br />
''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><br />
''Anpassung der glot-Dateien:'' siehe [[#Anpassen der gplot-Konfigurationen]]<br />
</li><br />
</ol><br />
<br />
<br />
== Beispiel: Anlegen und Nutzung einer Mysql-Datenbank ==<br />
Unter Ubuntu: <br />
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 />
<br />
nun zu mysql verbinden:<br />
mysql -p -u root<br />
Enter password:<br />
<br />
Jetzt die Tabellenstruktur anlegen. <br />
Hierfür kann nach Bedarf in der Datei /opt/fhem/contrib/dblog/db_create_mysql.sql das Passwort und der Benutzername geändert werden.<br />
Dann wird die Datei eingelesen: <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 />
vim /opt/fhem/contrib/dblog/db.conf<br />
<br />
Jetzt kann ein DbLog-Device angelegt werden: <br />
define logdb DbLog ./contrib/dblog/db.conf .*:.* # loggt ALLES!<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 />
<source 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 current; # Achtung, kann sehr groß werden .... #<br />
</source><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 />
<source lang="perl"><br />
sub X_Initialize($)<br />
{<br />
my ($hash) = @_;<br />
...<br />
$hash->{DbLog_splitFn} = "X_DbLog_splitFn";<br />
}<br />
</source><br />
<br />
Die genaue Aufrufsyntax und Funktionweise einer DbLog_split-Funktion findet man [[DevelopmentModuleIntro#X_DbLog_split|hier]].<br />
<br />
== Bekannte Probleme ==<br />
Beim Anlegen der Datenbank per script wird die Value-Spalte nur als Varchar(32) definiert. Dieses kann dazu führen, dass besonders lange Readings (z.b. vom Modul sysmon) abgeschnitten werden und nicht in der Datenbank landen. Dieses lässt sich leicht beheben, indem man die Spalte auf Varchar(64) ändert (siehe auch {{Link2Forum|Topic=25648|Message=252433|LinkText=diesen Forenbeitrag}}).<br />
<br />
mysql> ALTER TABLE current MODIFY VALUE VARCHAR(64);<br />
mysql> ALTER TABLE history MODIFY VALUE VARCHAR(64);<br />
<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 insb. auch dann hilfreich, wenn man eigenen Funktionen, Notifys oder spezielle Plots entwirft, bei denen man auf Logdaten zugreifen möchte.<br />
<br />
Grundsätzlich beschrieben ist dies in der [http://fhem.de/commandref_DE.html#DbLog commandref#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 den fhem ausmacht um Datenfehler zu vermeiden). Eine Datenbank kann bearbeitet werden ohne den fhem abschalten zu müssen. <br />
<br />
Datenbanken kann man ohne weiter 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 />
<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 />
=== 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><br />
DB öffnen:<br />
<pre>sudo sqlite3 fhem.db</pre><br />
</li><br />
<li><br />
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><br />
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><br />
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><br />
Spätestens jetzt fhem stoppen:<br />
<pre>sudo service fhem stop</pre><br />
</li><br />
<li><br />
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><br />
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><br />
fhem wieder starten (und natürlich kontrollieren):<br />
<pre>sudo service fhem start</pre><br />
</li><br />
</ol><br />
<br />
<br />
<br />
== Nützliche Codeschnipsel ==<br />
Anbei ein paar nützliche Codeschnipsel rund um DbLog<br />
<br />
=== Dateigroesse mitloggen ===<br />
Da die Datenbank ins Unermessliche wachsen kann, empfiehlt es sich - je nach Speicherplatz - ab einer bestimmten Groesse taetig zu werden. Dazu muss diese Groesse alledings ermittelt werden. Diese geschieht mittels des Userreadings, welches man vorteilshafterweise mit im DbLog-device anlegt:<br />
<br />
<pre>attr myDbLog userReadings DbFileSize:lastReduceLogResult.* { (split(' ',`du -m fhem.db`))[0] }</pre><br />
<br />
Mittels dieses Attributs wird die Groesse 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 />
== Links ==<br />
* [[Heizleistung_und_Gasverbrauch|Beispiel das DbLog-Daten für SVG-Plots verwendet]]<br />
* [[SVG-Plots von FileLog auf DbLog umstellen]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Somfy_via_SIGNALduino&diff=19233Somfy via SIGNALduino2017-02-01T07:20:16Z<p>Hauswart: /* SIGNALduino */</p>
<hr />
<div>== SIGNALduino ==<br />
Der SIGNALduino hat gegenüber anderen Lösungen (z.B. CUL, FHEMduino) den Vorteil, dass das SOMFY Protokoll empfangen und gesendet werden kann.<br />
Alternative Hardware Lösungen (Stand Januar 2017) können entweder senden (z.B. CUL) oder Emfpangen (z.B. FHEMduino)<br />
Weitergehende Informationen zur Variante mit '''Standard Transmitter und Receiver''' sind in der [[SIGNALduino]] Wiki dokumentiert.<br />
Für das SOMFY System ist wichtig, dass die passende HW Variante gewählt wird: <br />
<br />
=== HW-Variante mit Standard 433,92Mhz Transmitter und Receiver (z.B. STX882 und RXB6) ===<br />
SOMFY Systeme senden auf 433,42Mhz. SIGNALduino Aufbauten mit den billig Transmitter/Receivern sind fest auf 433,92Mhz eingestellt und nicht wirklich geeignet um SOMFY Systeme mit 433,42 Mhz zu steuern. Grundsätzlich kann die Funkverbindung funktionieren, als Ergebnis werden sich jedoch drastische Reichweitenprobleme ergeben (je nach Streuung der Bauteile)<br />
<br />
'''Fazit:''' diese HW Variante sollte für das SOMFY System '''nicht''' genutzt werden<br />
<br />
=== HW-Variante mit CC1101 Transceiver ===<br />
Eine SIGNALduino Hardware kann auch mit CC1101 Transceiver aufgebaut werden (wird von der Firmware erkannt und unterstützt).<br />
Der CC1101 ist bzgl. Sende- und Empfangsfrequenz programmierbar und kann also z.b. zwischen 433,92Mhz (beliebte Frequenz bei z.B. Funkthermometer etc.) und anderen Frequenzen (z.B. 433,42Mhz bei SOMFY Anlagen) umgeschaltet werden. Deshalb ist diese Hardware die erste Wahl.<br />
Die Hardware selbst ist identisch zum NanoCUL [[Selbstbau_CUL#Schaltplan]]. Der Aufbau und die Inbetriebnahme ist im [[SIGNALduino]] Wiki erklärt.<br />
<br />
=== Erstinbetriebnahme mit Arduino IDE ===<br />
Sollte auf einem Steckboard erfolgen (siehe "Bekannte Probleme")<br />
<br />
''Beitrag wird noch vervollständigt''<br />
<br />
<br />
=== Bekannte Probleme bei der Inbetriebnahme des SIGNALduino mit CC1101 ===<br />
Lässt sich der SIGNALduino mit verbautem CC1101 in FHEM nicht initialisieren, dann die MOSI Leitung von D11 des Adruino Nano abtrennen (nicht den kompletten CC1101 entfernen, sonst wird der CC1101 nicht erkannt und der Befehl unten nicht akzeptiert). Danach sollte sich der SIGNALduino initialisieren lassen. Danach in FHEM beim SIGNALduino Device den Befehl:<br />
<pre>get sduino raw e</pre><br />
eingeben und die MOSI Leitung wieder verbinden.<br />
<br />
=== Tipps und Tricks ===<br />
''An dieser Stelle sollen noch Tipps und Tricks bzgl. Inbetriebnahme des SINGALduino-CC1101 entstehen. Noch besser wäre die Tipps und Tricks werden in der SINGALduino Wiki direkt dokumentiert, ich werde das bei gegebener Zeit mit dem Author klären.''<br />
<br />
== SOMFY via SIGNALduino ==<br />
<br />
=== Installation unter FHEM ===<br />
Damit SOMFY via SIGNALduino in FHEM unterstütz wird muss FHEM die neueste SIGNALduiono FW und SW Module unterstützen.<br />
Dazu in die FHEM Commandozeile folgende Befehle eingeben:<br />
<pre>update add https://raw.githubusercontent.com/RFD-FHEM/RFFHEM/dev-r33/controls_signalduino.txt</pre><br />
''Damit werden bei einem FHEM Update künftig auch die aktuellen SIGNALduino Module geladen''<br />
<pre>update</pre><br />
''Startet einen FHEM Update Vorgang''<br />
<pre>shutdown restart</pre><br />
''Neustart von FHEM damit die akutellen SIGNALduino Module aktiv werden''<br />
<br />
=== Definition des SIGNALduino Devices ===<br />
* SIGNALduino an FHEM Server (im Beipiel hier Raspberry PI)anschliessen<br />
* USB ID des SIGNALduino Devices ermitteln<br />
<pre> ls -l /dev/serial/by-id </pre><br />
Ergebnis: ''lrwxrwxrwx 1 root root 13 Jan 31 00:02 usb-1a86_USB2.0-Serial-if00-port0 -> ../../ttyUSB0<br />
''<br />
* In FHEM damit z.B. das Device "sduino" definieren<br />
<pre> define sduino SIGNALduino /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0@57600 </pre><br />
<pre> attr sduino flashCommand avrdude -c arduino -b 57600 -P [PORT] -p atmega328p -vv -U flash:w:[HEXFILE] 2>[LOGFILE] </pre><br />
<pre> attr sduino hardware nanoCC1101 </pre><br />
<br />
<br />
=== Definition des SOMFY Devices (z.B. Rolladen) sowie setzten der Attribute ===<br />
''Beitrag wird noch erstellt''<br />
<br />
=== Update der SIGNALduino Firmware via FHEM ===<br />
''Beitrag wird noch erstellt''<br />
<br />
<br />
<br />
2017-01-31: So der Anfang ist gemacht, ich werde den Beitrag die nächsten Tage erweitern / fertigstellen<br />
<br />
<br />
<br />
<br />
[[Kategorie:HOWTOS]]<br />
[[Kategorie:Other Components]]<br />
<!-- Ich sehe derzeit keinen Bedarf für eine eigene Kategorie SOMFY, daher<br />
[[Kategorie:SOMFY]]<br />
entfernt (auskommentiert) und ersetzt durch Other Components<br />
... ebenso SIGNALduino - geändert auf Arduino, die Kategorie, in der auch die SIGNALduino einsortiert ist --><br />
[[Kategorie:Arduino]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=ABFALL&diff=19214ABFALL2017-01-31T14:26:52Z<p>Hauswart: /* Pushbullet Beispiel */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Filtern von (Abfall-)Terminen aus einem Calendar.<br />
|ModType=x<br />
|ModFTopic=48237<br />
|ModForumArea=Codeschnipsel<br />
|ModTechName=57_ABFALL.pm<br />
|ModOwner=Constantin / {{Link2FU|14026|uniqueck}}<br />
}}<br />
<br />
[[ABFALL]] ist ein (inoffizielles, nicht Bestandteil der Distribution) Hilfsmodul, das bestimmte Termine aus einem bestehenden Kalender des Moduls [[Calendar]] in Readings übernimmt. <br />
<br />
== Voraussetzungen ==<br />
Es muss ein Calendar-Objekt definiert sein. Der dabei benutzte Name muss in der Definition des ABFALL-Objekts spezifiziert werden.<br />
Es können auch mehrere Calendar Objekte übergeben werden.<br />
<br />
Sonderzeichen aus dem Namen der Termine, werden entfernt um die Namen der generierten Readings FHEM tauglich zu machen, für die Werte der Readings bleiben diese allerdings erhalten.<br />
<br />
== Anwendung ==<br />
=== Installation ===<br />
Mit folgendem Befehl kann das Modul direkt in den Standard FHEM Update Prozess eingeklinkt werden.<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
Um es nur zu installieren, kann auch einfach nur das Command<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
eingegeben werden.<br />
<br />
=== Entwicklungsstrang ===<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
bzw.<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
<br />
=== Define ===<br />
:<code>define <Name> ABFALL <calendarname>,<calendarname2>,...</code><br />
<br />
Erläuterung der Parameter im '''define''':<br />
;<calendarname><br />
:Name des '''Calendar''' Kalenders <br />
<br />
Beispiel:<br />
:<code>define myAbfall ABFALL AbfallGoogleCalender</code><br />
<br />
=== Werte aktualisieren ===<br />
Die Werte aktualisieren sich abhängig vom [[notify]] der entsprechenden Calendar Instanz, welche im define angegeben wurde(n).<br />
<br />
=== Weitere Attribute ===<br />
<br />
{| class="wikitable"<br />
!Attribut<br />
!Werteliste<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |calendarname_praefix<br />
|0 und 1<br />
|soll der Kalendername als praefix dem Reading vorangestellt werden, sollte bei nur einem Kalender auf 0 gesetzt werden<br />
|1 - praefix wird vorangestellt<br />
|-<br />
!align="right" |abfall_clear_reading_regex<br />
|<br />
|regex zum Entfernen von Anteilen aus dem Termin, dieser wird vor dem Entfernen von Sonderzeichen aus den Namen der Termine angewandt.<br />
|<br />
|-<br />
!align="right" |disable<br />
|0 und 1<br />
|deaktiviert das Modul<br />
|0<br />
|-<br />
!align="right" |weekday_mapping<br />
|<br />
|Mapping, wie die Readings der Tage angezeigt werden sollen, zum Beispiel So Mo Di Mi Do Fr Sa<br />
|Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag<br />
|-<br />
!align="right" |delimiter_text_reading<br />
|<br />
|Wenn zwei Abholungen an ein und demselben Tag existieren, wird dieses Trennzeichen genutzt, um die beiden (oder mehrere) Werte zu einem Text zu verbinden. Nur relevant für die Readings next_text und now_text<br />
|und<br />
|-<br />
!align="right" |delimiter_reading<br />
|<br />
|wie attribute delimiter_text_reading, allerdings nur für die readings next und now<br />
|<br />
|-<br />
!align="right" |filter<br />
|<br />
|regex zum Filtern der Namen der Termine aus den Kalendern, so dass nur solche genutzt werden, welche diesem Filter entsprechen<br />
|<br />
|-<br />
|}<br />
<br />
== Anwendungsbeispiel(e) ==<br />
=== Einbindung ins Tablet UI ===<br />
<pre><div data-device="myABFALL" data-type="symbol" class="bigger warn wider" <br />
data-get="next" data-get-warn=".*(\d+).*" <br />
data-get-on='["Restmuell_.*","Wertstoff_.*"]'<br />
data-on-colors='["#000","#6EB54C"]' <br />
data-icons='["fa-trash-o","fa-trash-o"]'></div></pre><br />
<br />
=== Einbindung ins Tablet UI, erweitert ===<br />
Fallen die Leerungen zweier verschiedener Tonnen nicht auf den selben Tag, reicht es normalerweise, nur ein Symbol auf der Oberfläche zu platzieren und dieses dann dynamisch zu befüllen. In folgendem Beispiel werden folgende Anforderungen umgesetzt:<br />
* Anzeige unterschiedlicher Symbole bzw. Farben für Papiertonne, Restmülltonne, Biotonne und gelbe Säcke<br />
* Anzeige der verbleibenden Tage bis zur Leerung als "Warn"-Marker in Rot, aber nur, wenn die Leerung innerhalb der nächsten 2 Tage ist<br />
* Blinken des Symbols, wenn die nächste Leerung morgen ansteht<br />
* Rotation des Symbols, wenn die nächste Leerung noch am selben Tag ansteht. Nach einer bestimmten Uhrzeit (z.B. 9 Uhr morgens) soll dann auf die nächste Tonne geschaltet werden<br />
* Anzeige des Datums bzw. von "heute" oder "morgen" unter dem Symbol als Label<br />
<br />
Zur Datumsanzeige wird eine kleine Hilfsfunktion in die 99_myUtils eingebaut. <br />
<source lang="perl"><br />
sub datumHeuteMorgen($){<br />
my $compareDate = shift;<br />
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);<br />
$year += 1900; $mon += 1; <br />
my $heute = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time+86400);<br />
$year += 1900; $mon += 1;<br />
my $morgen = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
return "heute" if $compareDate eq $heute;<br />
return "morgen" if $compareDate eq $morgen;<br />
return $compareDate;<br />
}<br />
</source><br />
Diese Funktion wird in den userReadings des Abfall-Moduls verwendet. Das Abfallmodul erzeugt eine Gruppe von Readings mit dem Namen now_*, wenn die Leerung am selben Tag ansteht, bzw. genau dann, wenn der Termin im zu Grunde liegenden Kalender gerade aktiv ist. In diesem Beispiel liegt dem Kalender-Modul ein Google-Kalender zu Grunde, bei dem die Termine immer von 0 Uhr bis 9 Uhr morgens eingetragen sind. Dadurch wird erreicht, dass die Anzeige nach 9 Uhr weiterspringt, weil dann die now-Readings verschwinden.<br />
<br />
Folgende userReadings werden zum Abfallmodul hinzugefügt, welches in diesem Beispiel "abf.abfall" genannt ist:<br />
<source lang="perl"><br />
attr abf.abfall userReadings ftui_datum {ReadingsVal("abf.abfall","now_text","") eq "" ? datumHeuteMorgen(ReadingsVal("abf.abfall","next_datum","")) : "heute";},ftui_next {ReadingsVal("abf.abfall","now_text","") eq "" ? ReadingsVal("abf.abfall","next","") : ReadingsVal("abf.abfall","now","")."_0";}<br />
</source><br />
Das Reading "ftui_next" bildet die Grundlage für das Symbol in TabletUI, das Reading "ftui_datum" wird für das Label genutzt. <br />
<br />
Somit lässt sich ganze in FTUI wie folgt darstellen:<br />
<source lang="html"><br />
<div data-device="abf.abfall" <br />
data-type="symbol"<br />
data-get="ftui_next"<br />
data-get-on='["Biotonne_0$","Biotonne_1$","Biotonne_.*","GelberSack_0$","GelberSack_1$","GelberSack_.*","Papiertonne_0$","Papiertonne_1$","Papiertonne_.*","Restmuelltonne_0$","Restmuelltonne_1$","Restmuelltonne_.*"]'<br />
data-get-warn=".*([0|1|2]).*"<br />
data-on-colors='["#8B4513","#8B4513","#8B4513","#f4e946","#f4e946","#f4e946","#2d9e1c","#2d9e1c","#2d9e1c","#696969","#696969","#696969"]'<br />
class="large warn"<br />
data-icons='["fa-trash-o fa-spin","fa-trash-o blink","fa-trash-o","fs-bag fa-spin","fs-bag blink","fs-bag","fs-dustbin fa-spin","fs-dustbin blink","fs-dustbin","fa-trash fa-spin","fa-trash blink","fa-trash"]'<br />
/><br />
<div data-device="abf.abfall" data-get="ftui_datum" data-type="label"/><br />
</source><br />
Für Jede Tonne werden hier drei Zustände unterschieden und einzeln in "data-get-on", "data-on-colors" und "data-icons" zugeordnet. Daher haben diese Listen jeweils 12 Einträge. <br />
<br />
=== Benachrichtigung ===<br />
==== DOIF ====<br />
<pre>[Abfall:next_tage] == 1) ( set fhemBot message Morgen wird [Abfall:next_text] abgeholt)<br />
[Abfall:now_text] ne "") ( set fhemBot message Heute wird [Abfall:now_text] abgeholt)</pre><br />
<br />
====== Pushbullet Beispiel ======<br />
<br />
Die morgigen Leerungen per Push um 19:30 mittels Pushbullet:<br />
<br />
<code>define dAbfallmorgen doif ([19:30] and [Abfall:next_tage] == 1) ( msg |Morgen wird [Abfall:next_text] abgeholt)<br />
<br />
attr dAbfallmorgen do always</code><br />
<br />
Die heutigen Leerungen per Push um 07:00 mittels Pushbullet:<br />
<br />
<code>define dAbfallheute doif ([07:00] and [Abfall:now_text] ne "") ( msg |Heute wird [Abfall:now_text] abgeholt)<br />
<br />
attr dAbfallheute do always</code><br />
<br />
=== Links ===<br />
* Forenthema {{Link2Forum|Topic=50177|LinkText=Abfall Visualisierung mit Bilderrahmen}}</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=ABFALL&diff=19213ABFALL2017-01-31T14:26:38Z<p>Hauswart: /* Pushbullet Beispiel */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Filtern von (Abfall-)Terminen aus einem Calendar.<br />
|ModType=x<br />
|ModFTopic=48237<br />
|ModForumArea=Codeschnipsel<br />
|ModTechName=57_ABFALL.pm<br />
|ModOwner=Constantin / {{Link2FU|14026|uniqueck}}<br />
}}<br />
<br />
[[ABFALL]] ist ein (inoffizielles, nicht Bestandteil der Distribution) Hilfsmodul, das bestimmte Termine aus einem bestehenden Kalender des Moduls [[Calendar]] in Readings übernimmt. <br />
<br />
== Voraussetzungen ==<br />
Es muss ein Calendar-Objekt definiert sein. Der dabei benutzte Name muss in der Definition des ABFALL-Objekts spezifiziert werden.<br />
Es können auch mehrere Calendar Objekte übergeben werden.<br />
<br />
Sonderzeichen aus dem Namen der Termine, werden entfernt um die Namen der generierten Readings FHEM tauglich zu machen, für die Werte der Readings bleiben diese allerdings erhalten.<br />
<br />
== Anwendung ==<br />
=== Installation ===<br />
Mit folgendem Befehl kann das Modul direkt in den Standard FHEM Update Prozess eingeklinkt werden.<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
Um es nur zu installieren, kann auch einfach nur das Command<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
eingegeben werden.<br />
<br />
=== Entwicklungsstrang ===<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
bzw.<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
<br />
=== Define ===<br />
:<code>define <Name> ABFALL <calendarname>,<calendarname2>,...</code><br />
<br />
Erläuterung der Parameter im '''define''':<br />
;<calendarname><br />
:Name des '''Calendar''' Kalenders <br />
<br />
Beispiel:<br />
:<code>define myAbfall ABFALL AbfallGoogleCalender</code><br />
<br />
=== Werte aktualisieren ===<br />
Die Werte aktualisieren sich abhängig vom [[notify]] der entsprechenden Calendar Instanz, welche im define angegeben wurde(n).<br />
<br />
=== Weitere Attribute ===<br />
<br />
{| class="wikitable"<br />
!Attribut<br />
!Werteliste<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |calendarname_praefix<br />
|0 und 1<br />
|soll der Kalendername als praefix dem Reading vorangestellt werden, sollte bei nur einem Kalender auf 0 gesetzt werden<br />
|1 - praefix wird vorangestellt<br />
|-<br />
!align="right" |abfall_clear_reading_regex<br />
|<br />
|regex zum Entfernen von Anteilen aus dem Termin, dieser wird vor dem Entfernen von Sonderzeichen aus den Namen der Termine angewandt.<br />
|<br />
|-<br />
!align="right" |disable<br />
|0 und 1<br />
|deaktiviert das Modul<br />
|0<br />
|-<br />
!align="right" |weekday_mapping<br />
|<br />
|Mapping, wie die Readings der Tage angezeigt werden sollen, zum Beispiel So Mo Di Mi Do Fr Sa<br />
|Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag<br />
|-<br />
!align="right" |delimiter_text_reading<br />
|<br />
|Wenn zwei Abholungen an ein und demselben Tag existieren, wird dieses Trennzeichen genutzt, um die beiden (oder mehrere) Werte zu einem Text zu verbinden. Nur relevant für die Readings next_text und now_text<br />
|und<br />
|-<br />
!align="right" |delimiter_reading<br />
|<br />
|wie attribute delimiter_text_reading, allerdings nur für die readings next und now<br />
|<br />
|-<br />
!align="right" |filter<br />
|<br />
|regex zum Filtern der Namen der Termine aus den Kalendern, so dass nur solche genutzt werden, welche diesem Filter entsprechen<br />
|<br />
|-<br />
|}<br />
<br />
== Anwendungsbeispiel(e) ==<br />
=== Einbindung ins Tablet UI ===<br />
<pre><div data-device="myABFALL" data-type="symbol" class="bigger warn wider" <br />
data-get="next" data-get-warn=".*(\d+).*" <br />
data-get-on='["Restmuell_.*","Wertstoff_.*"]'<br />
data-on-colors='["#000","#6EB54C"]' <br />
data-icons='["fa-trash-o","fa-trash-o"]'></div></pre><br />
<br />
=== Einbindung ins Tablet UI, erweitert ===<br />
Fallen die Leerungen zweier verschiedener Tonnen nicht auf den selben Tag, reicht es normalerweise, nur ein Symbol auf der Oberfläche zu platzieren und dieses dann dynamisch zu befüllen. In folgendem Beispiel werden folgende Anforderungen umgesetzt:<br />
* Anzeige unterschiedlicher Symbole bzw. Farben für Papiertonne, Restmülltonne, Biotonne und gelbe Säcke<br />
* Anzeige der verbleibenden Tage bis zur Leerung als "Warn"-Marker in Rot, aber nur, wenn die Leerung innerhalb der nächsten 2 Tage ist<br />
* Blinken des Symbols, wenn die nächste Leerung morgen ansteht<br />
* Rotation des Symbols, wenn die nächste Leerung noch am selben Tag ansteht. Nach einer bestimmten Uhrzeit (z.B. 9 Uhr morgens) soll dann auf die nächste Tonne geschaltet werden<br />
* Anzeige des Datums bzw. von "heute" oder "morgen" unter dem Symbol als Label<br />
<br />
Zur Datumsanzeige wird eine kleine Hilfsfunktion in die 99_myUtils eingebaut. <br />
<source lang="perl"><br />
sub datumHeuteMorgen($){<br />
my $compareDate = shift;<br />
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);<br />
$year += 1900; $mon += 1; <br />
my $heute = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time+86400);<br />
$year += 1900; $mon += 1;<br />
my $morgen = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
return "heute" if $compareDate eq $heute;<br />
return "morgen" if $compareDate eq $morgen;<br />
return $compareDate;<br />
}<br />
</source><br />
Diese Funktion wird in den userReadings des Abfall-Moduls verwendet. Das Abfallmodul erzeugt eine Gruppe von Readings mit dem Namen now_*, wenn die Leerung am selben Tag ansteht, bzw. genau dann, wenn der Termin im zu Grunde liegenden Kalender gerade aktiv ist. In diesem Beispiel liegt dem Kalender-Modul ein Google-Kalender zu Grunde, bei dem die Termine immer von 0 Uhr bis 9 Uhr morgens eingetragen sind. Dadurch wird erreicht, dass die Anzeige nach 9 Uhr weiterspringt, weil dann die now-Readings verschwinden.<br />
<br />
Folgende userReadings werden zum Abfallmodul hinzugefügt, welches in diesem Beispiel "abf.abfall" genannt ist:<br />
<source lang="perl"><br />
attr abf.abfall userReadings ftui_datum {ReadingsVal("abf.abfall","now_text","") eq "" ? datumHeuteMorgen(ReadingsVal("abf.abfall","next_datum","")) : "heute";},ftui_next {ReadingsVal("abf.abfall","now_text","") eq "" ? ReadingsVal("abf.abfall","next","") : ReadingsVal("abf.abfall","now","")."_0";}<br />
</source><br />
Das Reading "ftui_next" bildet die Grundlage für das Symbol in TabletUI, das Reading "ftui_datum" wird für das Label genutzt. <br />
<br />
Somit lässt sich ganze in FTUI wie folgt darstellen:<br />
<source lang="html"><br />
<div data-device="abf.abfall" <br />
data-type="symbol"<br />
data-get="ftui_next"<br />
data-get-on='["Biotonne_0$","Biotonne_1$","Biotonne_.*","GelberSack_0$","GelberSack_1$","GelberSack_.*","Papiertonne_0$","Papiertonne_1$","Papiertonne_.*","Restmuelltonne_0$","Restmuelltonne_1$","Restmuelltonne_.*"]'<br />
data-get-warn=".*([0|1|2]).*"<br />
data-on-colors='["#8B4513","#8B4513","#8B4513","#f4e946","#f4e946","#f4e946","#2d9e1c","#2d9e1c","#2d9e1c","#696969","#696969","#696969"]'<br />
class="large warn"<br />
data-icons='["fa-trash-o fa-spin","fa-trash-o blink","fa-trash-o","fs-bag fa-spin","fs-bag blink","fs-bag","fs-dustbin fa-spin","fs-dustbin blink","fs-dustbin","fa-trash fa-spin","fa-trash blink","fa-trash"]'<br />
/><br />
<div data-device="abf.abfall" data-get="ftui_datum" data-type="label"/><br />
</source><br />
Für Jede Tonne werden hier drei Zustände unterschieden und einzeln in "data-get-on", "data-on-colors" und "data-icons" zugeordnet. Daher haben diese Listen jeweils 12 Einträge. <br />
<br />
=== Benachrichtigung ===<br />
==== DOIF ====<br />
<pre>[Abfall:next_tage] == 1) ( set fhemBot message Morgen wird [Abfall:next_text] abgeholt)<br />
[Abfall:now_text] ne "") ( set fhemBot message Heute wird [Abfall:now_text] abgeholt)</pre><br />
<br />
====== Pushbullet Beispiel ======<br />
<br />
Die morgigen Leerungen per Push um 19:30 mittels Pushbullet:<br />
<br />
<code>define dAbfallmorgen doif ([19:30] and [Abfall:next_tage] == 1) ( msg |Morgen wird [Abfall:next_text] abgeholt)<br />
attr dAbfallmorgen do always</code><br />
<br />
Die heutigen Leerungen per Push um 07:00 mittels Pushbullet:<br />
<br />
<code>define dAbfallheute doif ([07:00] and [Abfall:now_text] ne "") ( msg |Heute wird [Abfall:now_text] abgeholt)<br />
attr dAbfallheute do always</code><br />
<br />
=== Links ===<br />
* Forenthema {{Link2Forum|Topic=50177|LinkText=Abfall Visualisierung mit Bilderrahmen}}</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=ABFALL&diff=19212ABFALL2017-01-31T14:25:27Z<p>Hauswart: /* Pushbullet Beispiel */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Filtern von (Abfall-)Terminen aus einem Calendar.<br />
|ModType=x<br />
|ModFTopic=48237<br />
|ModForumArea=Codeschnipsel<br />
|ModTechName=57_ABFALL.pm<br />
|ModOwner=Constantin / {{Link2FU|14026|uniqueck}}<br />
}}<br />
<br />
[[ABFALL]] ist ein (inoffizielles, nicht Bestandteil der Distribution) Hilfsmodul, das bestimmte Termine aus einem bestehenden Kalender des Moduls [[Calendar]] in Readings übernimmt. <br />
<br />
== Voraussetzungen ==<br />
Es muss ein Calendar-Objekt definiert sein. Der dabei benutzte Name muss in der Definition des ABFALL-Objekts spezifiziert werden.<br />
Es können auch mehrere Calendar Objekte übergeben werden.<br />
<br />
Sonderzeichen aus dem Namen der Termine, werden entfernt um die Namen der generierten Readings FHEM tauglich zu machen, für die Werte der Readings bleiben diese allerdings erhalten.<br />
<br />
== Anwendung ==<br />
=== Installation ===<br />
Mit folgendem Befehl kann das Modul direkt in den Standard FHEM Update Prozess eingeklinkt werden.<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
Um es nur zu installieren, kann auch einfach nur das Command<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
eingegeben werden.<br />
<br />
=== Entwicklungsstrang ===<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
bzw.<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
<br />
=== Define ===<br />
:<code>define <Name> ABFALL <calendarname>,<calendarname2>,...</code><br />
<br />
Erläuterung der Parameter im '''define''':<br />
;<calendarname><br />
:Name des '''Calendar''' Kalenders <br />
<br />
Beispiel:<br />
:<code>define myAbfall ABFALL AbfallGoogleCalender</code><br />
<br />
=== Werte aktualisieren ===<br />
Die Werte aktualisieren sich abhängig vom [[notify]] der entsprechenden Calendar Instanz, welche im define angegeben wurde(n).<br />
<br />
=== Weitere Attribute ===<br />
<br />
{| class="wikitable"<br />
!Attribut<br />
!Werteliste<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |calendarname_praefix<br />
|0 und 1<br />
|soll der Kalendername als praefix dem Reading vorangestellt werden, sollte bei nur einem Kalender auf 0 gesetzt werden<br />
|1 - praefix wird vorangestellt<br />
|-<br />
!align="right" |abfall_clear_reading_regex<br />
|<br />
|regex zum Entfernen von Anteilen aus dem Termin, dieser wird vor dem Entfernen von Sonderzeichen aus den Namen der Termine angewandt.<br />
|<br />
|-<br />
!align="right" |disable<br />
|0 und 1<br />
|deaktiviert das Modul<br />
|0<br />
|-<br />
!align="right" |weekday_mapping<br />
|<br />
|Mapping, wie die Readings der Tage angezeigt werden sollen, zum Beispiel So Mo Di Mi Do Fr Sa<br />
|Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag<br />
|-<br />
!align="right" |delimiter_text_reading<br />
|<br />
|Wenn zwei Abholungen an ein und demselben Tag existieren, wird dieses Trennzeichen genutzt, um die beiden (oder mehrere) Werte zu einem Text zu verbinden. Nur relevant für die Readings next_text und now_text<br />
|und<br />
|-<br />
!align="right" |delimiter_reading<br />
|<br />
|wie attribute delimiter_text_reading, allerdings nur für die readings next und now<br />
|<br />
|-<br />
!align="right" |filter<br />
|<br />
|regex zum Filtern der Namen der Termine aus den Kalendern, so dass nur solche genutzt werden, welche diesem Filter entsprechen<br />
|<br />
|-<br />
|}<br />
<br />
== Anwendungsbeispiel(e) ==<br />
=== Einbindung ins Tablet UI ===<br />
<pre><div data-device="myABFALL" data-type="symbol" class="bigger warn wider" <br />
data-get="next" data-get-warn=".*(\d+).*" <br />
data-get-on='["Restmuell_.*","Wertstoff_.*"]'<br />
data-on-colors='["#000","#6EB54C"]' <br />
data-icons='["fa-trash-o","fa-trash-o"]'></div></pre><br />
<br />
=== Einbindung ins Tablet UI, erweitert ===<br />
Fallen die Leerungen zweier verschiedener Tonnen nicht auf den selben Tag, reicht es normalerweise, nur ein Symbol auf der Oberfläche zu platzieren und dieses dann dynamisch zu befüllen. In folgendem Beispiel werden folgende Anforderungen umgesetzt:<br />
* Anzeige unterschiedlicher Symbole bzw. Farben für Papiertonne, Restmülltonne, Biotonne und gelbe Säcke<br />
* Anzeige der verbleibenden Tage bis zur Leerung als "Warn"-Marker in Rot, aber nur, wenn die Leerung innerhalb der nächsten 2 Tage ist<br />
* Blinken des Symbols, wenn die nächste Leerung morgen ansteht<br />
* Rotation des Symbols, wenn die nächste Leerung noch am selben Tag ansteht. Nach einer bestimmten Uhrzeit (z.B. 9 Uhr morgens) soll dann auf die nächste Tonne geschaltet werden<br />
* Anzeige des Datums bzw. von "heute" oder "morgen" unter dem Symbol als Label<br />
<br />
Zur Datumsanzeige wird eine kleine Hilfsfunktion in die 99_myUtils eingebaut. <br />
<source lang="perl"><br />
sub datumHeuteMorgen($){<br />
my $compareDate = shift;<br />
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);<br />
$year += 1900; $mon += 1; <br />
my $heute = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time+86400);<br />
$year += 1900; $mon += 1;<br />
my $morgen = sprintf('%02d.%02d.%04d', $mday, $mon, $year);<br />
return "heute" if $compareDate eq $heute;<br />
return "morgen" if $compareDate eq $morgen;<br />
return $compareDate;<br />
}<br />
</source><br />
Diese Funktion wird in den userReadings des Abfall-Moduls verwendet. Das Abfallmodul erzeugt eine Gruppe von Readings mit dem Namen now_*, wenn die Leerung am selben Tag ansteht, bzw. genau dann, wenn der Termin im zu Grunde liegenden Kalender gerade aktiv ist. In diesem Beispiel liegt dem Kalender-Modul ein Google-Kalender zu Grunde, bei dem die Termine immer von 0 Uhr bis 9 Uhr morgens eingetragen sind. Dadurch wird erreicht, dass die Anzeige nach 9 Uhr weiterspringt, weil dann die now-Readings verschwinden.<br />
<br />
Folgende userReadings werden zum Abfallmodul hinzugefügt, welches in diesem Beispiel "abf.abfall" genannt ist:<br />
<source lang="perl"><br />
attr abf.abfall userReadings ftui_datum {ReadingsVal("abf.abfall","now_text","") eq "" ? datumHeuteMorgen(ReadingsVal("abf.abfall","next_datum","")) : "heute";},ftui_next {ReadingsVal("abf.abfall","now_text","") eq "" ? ReadingsVal("abf.abfall","next","") : ReadingsVal("abf.abfall","now","")."_0";}<br />
</source><br />
Das Reading "ftui_next" bildet die Grundlage für das Symbol in TabletUI, das Reading "ftui_datum" wird für das Label genutzt. <br />
<br />
Somit lässt sich ganze in FTUI wie folgt darstellen:<br />
<source lang="html"><br />
<div data-device="abf.abfall" <br />
data-type="symbol"<br />
data-get="ftui_next"<br />
data-get-on='["Biotonne_0$","Biotonne_1$","Biotonne_.*","GelberSack_0$","GelberSack_1$","GelberSack_.*","Papiertonne_0$","Papiertonne_1$","Papiertonne_.*","Restmuelltonne_0$","Restmuelltonne_1$","Restmuelltonne_.*"]'<br />
data-get-warn=".*([0|1|2]).*"<br />
data-on-colors='["#8B4513","#8B4513","#8B4513","#f4e946","#f4e946","#f4e946","#2d9e1c","#2d9e1c","#2d9e1c","#696969","#696969","#696969"]'<br />
class="large warn"<br />
data-icons='["fa-trash-o fa-spin","fa-trash-o blink","fa-trash-o","fs-bag fa-spin","fs-bag blink","fs-bag","fs-dustbin fa-spin","fs-dustbin blink","fs-dustbin","fa-trash fa-spin","fa-trash blink","fa-trash"]'<br />
/><br />
<div data-device="abf.abfall" data-get="ftui_datum" data-type="label"/><br />
</source><br />
Für Jede Tonne werden hier drei Zustände unterschieden und einzeln in "data-get-on", "data-on-colors" und "data-icons" zugeordnet. Daher haben diese Listen jeweils 12 Einträge. <br />
<br />
=== Benachrichtigung ===<br />
==== DOIF ====<br />
<pre>[Abfall:next_tage] == 1) ( set fhemBot message Morgen wird [Abfall:next_text] abgeholt)<br />
[Abfall:now_text] ne "") ( set fhemBot message Heute wird [Abfall:now_text] abgeholt)</pre><br />
<br />
====== Pushbullet Beispiel ======<br />
<br />
Die morgigen Leerungen per Push um 19:30 mittels Pushbullet:<br />
<br />
<code>define dAbfallmorgen doif ([19:30] and [Abfall:next_tage] == 1) ( msg |Morgen wird [Abfall:next_text] abgeholt)</code><br />
<br />
Die heutigen Leerungen per Push um 07:00 mittels Pushbullet:<br />
<br />
<code>define dAbfallheute doif ([07:00] and [Abfall:now_text] ne "") ( msg |Heute wird [Abfall:now_text] abgeholt)</code><br />
<br />
=== Links ===<br />
* Forenthema {{Link2Forum|Topic=50177|LinkText=Abfall Visualisierung mit Bilderrahmen}}</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=FHEM_Tablet_UI&diff=18766FHEM Tablet UI2017-01-24T13:39:38Z<p>Hauswart: /* Konfiguration */ V 2.5 Layout</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Oberfläche für Fhem<br />
|ModType=x<br />
|ModFTopic=34233<br />
|ModForumArea=Frontends<br />
|ModTechName=n.a.<br />
|ModOwner=setstate ({{Link2FU|7023|Forum}})<br />
}}<br />
[[Datei:tablet_ui.png|200px|thumb|right|Fhem Tablet UI]]<br />
FHEM Tablet UI ist ein leichtgewichtiges aber funktionsreiches Framework zum Steuern und Überwachen von in Fhem integrierten Geräten. Zahlreiche Widgets können sehr flexibel und leicht per HTML Code konfiguriert werden.<br />
<br />
In dieser Anleitung wird die Installation und Konfiguration des FHEM Tablet UI beschrieben.<br />
<br />
{{Todo|alle Widgets hier übernehmen, Übersetzung, weitere Beispiele aus dem Forum einfügen (evtl. mit Link!?)}} <br />
<br />
<br />
== Voraussetzungen ==<br />
Das User Interface hat sehr wenige Anforderungen für den Betrieb. Es benötigt <u>keine</u> zusätzliche Frameworks, wie z.B. PHP oder MySQL.<br />
<br />
Voraussetzungen ist eine Fhem Installation mit HTTPSRV Modul. Das UI kann mit den gängigen Browsern Betriebssystem unabhängig genutzt werden oder mit dem Webviewcontrol.<br />
Das Interface wird dabei in dem FHEM eigenen Webserver ausgeführt. Mit wenigen Anpassungen ist es auch möglich das UI auf anderen Webservern (Apache, u.a.) zu betreiben, dann kann FHEM und UI auch auf getrennten Systemen ausgeführt werden.<br />
<br />
== Installation ==<br />
* Im Befehls-Eingabefeld eingeben: <code><nowiki>update all https://raw.githubusercontent.com/knowthelist/fhem-tablet-ui/master/controls_fhemtabletui.txt</nowiki></code><br />
* Im Befehls-Eingabefeld eingeben: <code>define TABLETUI HTTPSRV ftui/ ./www/tablet Tablet-UI</code><br />
* Im Verzeichnis ./fhem/www/tablet die Datei index-example.html in index.html umbenennen oder eine neue index.html erzeugen und diese index.html wie nachfolgend beschrieben editieren.<br />
<br />
Das UI ist über den Link "Tablet-UI" auf der Fhem-Hauptseite oder durch Direktaufruf der URL "<nowiki>http://<Fhem-url>:8083/fhem/tablet/index.html</nowiki>" zu erreichen.<br />
<br />
Hinweise zu einer manuellen Installation und weitere Infos sind auf der Projektseite https://github.com/knowthelist/fhem-tablet-ui zu finden.<br />
<br />
== Update ==<br />
* Prüfen der Änderungen seit dem letzten Download/Update durch Eingabe von: <code><nowiki>update check https://raw.githubusercontent.com/knowthelist/fhem-tablet-ui/master/controls_fhemtabletui.txt</nowiki></code><br />
* Update des UI durch Eingabe von: <code><nowiki>update all https://raw.githubusercontent.com/knowthelist/fhem-tablet-ui/master/controls_fhemtabletui.txt</nowiki></code><br />
<br />
Über <br />
<code><nowiki>update add https://raw.githubusercontent.com/knowthelist/fhem-tablet-ui/master/controls_fhemtabletui.txt</nowiki></code><br />
kann seit dem 24.12.2015 die URL zum normalen Updatebefehl von FHEM hinzugefügt werden. Mit einen "update check" sieht man dann gleich alle Updates aus beiden "Welten".<br />
<br />
== Weitere Widgets ==<br />
<br />
=== Widgets for Fhem-tablet-ui ===<br />
<br />
'''Achtung''': die nesges-Widgets sind nicht mehr kompatibel mit der aktuellen FHEM Tablet UI Version. Aktuell bitte kein Installation aus dieser Quelle mehr durchführen. <br />
<br />
Zusätzlich zu den bei der Installation des Tablet UI direkt zur Verfügung stehenden Widgets, gibt es eine weitere Widget-Quelle von nesges unter https://github.com/nesges/Widgets-for-fhem-tablet-ui. Die Widgets aus dieser Quelle müssen für eine Nutzung separat installiert werden.<br />
<br />
Dazu folgenden Befehl in die Fhem-Befehlszeile eingeben: <code><nowiki>update all https://raw.githubusercontent.com/nesges/Widgets-for-fhem-tablet-ui/master/controls_widgets-for-fhem-tablet-ui.txt</nowiki></code>. <br />
<br />
Näheres zur Installation unter [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/Installation Wiki: Installation]. <br />
<br />
Die Dokumentation der einzelnen Widgets befindet sich ebenfalls [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki im Github-Wiki].<br />
<br />
== Konfiguration ==<br />
'''META-Parameter'''<br />
<br />
Das Tablet UI lässt sich über die META-Parameter konfigurieren. Mit den meisten META-Parametern kann das verhalten des UI beeinflusst werden. Diese Parameter befinden sich in der jeweiligen '''.html''' Datei (z.B. index.html) im Abschnitt '''<head>'''. Nachfolgend sind die verschiedenen Konfigurationsparameter aufgeführt. Die Parameter sind immer gleich aufgebaut.<br />
<br />
:<code><meta name="<META-Parameter>" content="<Wert>"></code><br />
<br />
{| class="wikitable"<br />
|-<br />
! META-Parameter !! Wert / Beispiel !! Erklärung<br />
|-<br />
| longpoll || 1 oder 0 || Refresh sofort, alle 15 Minuten ein voller Refresh (shortpoll) statt alle 30 Sekunden ein voller Refresh.<br />
|-<br />
| gridster_disable || 1 oder 0 || Drag&Drop der Gridster-Elemente auf der Seite deaktivieren.<br />
|-<br />
| toast || 1 oder 0 || Toast messages deaktivieren<br />
|-<br />
| fhemweb_url || http://meinFhemServer:8083/fhem || Wird benötigt wenn der Webserver des TabletUI nicht auf dem FHEM Server läuft.Default: "/fhem/"<br />
|-<br />
| widget_margin || 1 bis 9999 || Abstände der Gridsterelemente verändern.<br />
|-<br />
| widget_base_width || 1 bis 9999 || Größe des Basis-Rasters (data-sizey=1/data-sizex=1) verändern.<br />
|-<br />
| widget_base_height || 1 bis 9999 || Größe des Basis-Rasters (data-sizey=1/data-sizex=1) verändern.<br />
|-<br />
| gridster_cols || 1 bis 9999 || Anzahl der Spalten.<br />
|-<br />
| gridster_rows || 1 bis 9999 || Anzahl der Reihen.<br />
|-<br />
| lang || de || Sprache der Visualisierung (derzeit nur DE vorhanden).<br />
|}<br />
<br />
''Layout''<br />
<br />
Seit Version 2.5 werden die Gridster Kachel-Grössen, die Anzahl der Spalten und die Anzahl der Reihen dynamisch anhand der Bildschirmgrösse berechnet.<br />
<br />
Möchte man die Anzahl der Spalten und Reihen fest vorgeben:<br />
<br />
<pre><meta name="gridster_cols" content="12"><br />
<meta name="gridster_rows" content="9"></pre><br />
<br />
Mit folgendem Code kann man die Kachelgrössen fix definieren:<br />
<br />
<pre><meta name="widget_base_width" content="116"><br />
<meta name="widget_base_height" content="131"></pre><br />
<br />
''FHEM URL''<br />
<br />
Werden die FTUI Seiten von einem anderen Server als FHEM-HTTPSRV bereitgestellt, muss man die URL, unter der FHEM angesprochen wird, anpassen:<br />
<br />
<pre><meta name="fhemweb_url" content="/fhem/"></pre><br />
<br />
'''CSS-Styles'''<br />
<br />
Das Layout und das Aussehen des UI kann durch diverse vorgegebene CSS-Klassen beeinflusst werden. Die verfügbaren Klassen sind im Abschnitt [[#CSS Class description|CSS Class description]] oder [[#Positioning|Positioning]] aufgeführt. Es besteht auch die Möglichkeit eine eigene CSS Datei zu erstellen und darüber Änderungen am aussehen des UI vorzunehmen. Die eigenen CSS Datei würde bei einem Update unverändert bleiben. Daher ist abzuraten ein CSS Datei die mit dem UI Update verteilt wird zu modifizieren. Die eigene CSS Datei ist unter '''/fhem/tablet/css''' mit dem Namen '''fhem-tablet-ui-user.css''' zu finden. Sollte diese nicht vorhanden sein kann die Datei manuell erstellt werden.<br />
Wird keine eigene CSS-Datei verwendet empfiehlt es sich den folgenden Eintrag im <head> der jeweiligen .html Datei zu entfernen, bzw. in Kommentar gesetzt werden um Probleme beim Laden der Seite zu verhindern.<br />
<br />
:<code><link rel="stylesheet" href="/fhem/tablet/css/fhem-tablet-ui-user.css" /></code><br />
<br />
== Farbe ==<br />
Es besteht die Möglichkeit, die Farbwerte in hexadezimaler Form oder als RGB-Wert anzugeben. Zum Beispiel: Hex: #A3CFA3 RBG: rgb(163, 207, 163).<br />
<br />
Knallige Farben wie #ff0000 für Rot oder #00ff00 für Grün sollten vermieden werden. Es ist besser unterhalb von #D0 (208) für die Grundfarben zu bleiben.<br />
<br />
Hilfreich bei der Suche nach den Farbwerten ist der color picker: http://www.w3schools.com/tags/ref_colorpicker.asp oder diese Quelle: https://flatuicolors.com<br />
<br />
== CSS Class description ==<br />
<br />
Not all widgets support all classes<br />
<br />
* readonly : changing of state is not allowed<br />
* wider : 25px extra space for the widget to the top<br />
* narrow : shorter distant to the widget above<br />
* w1x, w2x, w3x : set the widget to a fix width: 1x, 2x, 3x width<br />
* mini : lowest diameter for volume widget<br />
* small : font 80% size (label), small diameter for volume widget<br />
* medium : font 120% size<br />
* large : font 150% size<br />
* big : font 200% size<br />
* bigplus : font 270% size<br />
* bigger : font 320% size<br />
* bigger.thin : font 450% size<br />
* grande : font 600% size<br />
* gigantic: font 144px size + 120px line-height<br />
* thin : font thin<br />
* darker : forecolor in gray<br />
* hue-tick : draw ticks in color range<br />
* hue-front : draw handle in color range<br />
* hue-back : draw background in color range<br />
* dim-tick : draw ticks in brightness range<br />
* dim-front : draw handle in brightness range<br />
* dim-back : draw background in brightness range<br />
* red : foreground color red<br />
* green : foreground color green<br />
* blue : foreground color blue<br />
* doublebox-v : container to place 2 small widgets (e.g. switch) one above the other<br />
* doublebox-h : container to place 2 small widgets (e.g. switch) side by side<br />
* timestamp : deliver the date time for the reading instead the value<br />
* inline : positioning elements in a row, no line break<br />
* top-space : 15px extra on top (top-space-2x -> 30px; top-space-3x -> 45px)<br />
* left-space : 15px extra on left (left-space-2x -> 30px; left-space-3x -> 45px)<br />
* right-space : 15px extra on right (right-space-2x -> 30px; right-space-3x -> 45px)<br />
* blink : blink animatation for label or symbol widget<br />
* verticalLine : Vertikale Line am rechten Rand<br />
<br />
== Positioning ==<br />
<br />
*container : new box or new row<br />
*col-x-y : new column with x/y of width (col-1-3,col-2-3,col-1-2,col-1-4,col-1-8,col-1-5,col-2-5,col-3-5,col-4-5)<br />
*inline : positioning elements in a row, no line break<br />
*top-space : 15px extra on top (top-space-2x -> 30px; top-space-3x -> 45px)<br />
*left-space : 15px extra on left (left-space-2x -> 30px; left-space-3x -> 45px)<br />
*right-space : 15px extra on right (right-space-2x -> 30px; right-space-3x -> 45px)<br />
*top-narrow : -15px closer on top (top-narrow-2x -> -30px; top-narrow-10 -> -10px)<br />
*centered : horizontal centered<br />
*left-align : align text left<br />
*left : floating left<br />
*right-align : align text right<br />
*right : floating right<br />
*wider : 15px extra space for the widget all around<br />
*narrow : shorter distant to the widget above<br />
*fullsize : 100% in width and height<br />
<br />
== Widgets -- Konfiguration ==<br />
<br />
Teilweise dokumentierte Widgets:<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/button button]: Variante der push und switch Widgets, die entweder einen URL ansteuern oder einen Fhem-Befehl absetzen kann.<br />
* [[#chart|chart]]: chart with similar capabilities as the FHEM plots <br />
* checkbox:<br />
* [[#circlemenu|circlemenu]]: Mehrere Widgets hinter einem Widget verborgen, trotz des 'circle' im Namen kann das Menue jetzt auch horizontal oder vertikal ausgeklappt werden <br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/clicksound clicksound]: Mit dem Widget "clicksound" können Sounds an Click-Events von Elementen gebunden werden. <br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/clock clock]: Das Widget "clock" stellt eine einfach Uhr zur verfügung.<br />
* colorwheel:<br />
* daytimepicker:<br />
* [[#departure|departure]]: show timetable of public transport provider<br />
* [[#dimmer|dimmer]]: toogle button with a setter for on value<br />
* eventmonitor:<br />
* highchart:<br />
* [[#homestatus|homestatus]]: selector for 4 states (1=home, 2=night, 3=away, 4=holiday)<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/iframe iframe]]: Widget zum Einbinden externer Inhalte in einem Iframe. <br />
* [[#image|image]]: insert an image, the URL is given by a reading<br />
* input:<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/itunes_artwork itunes_artwork]: itunes_artwork durchsucht die iTunes-Datenbank anhand eines Arrays von beliebigen Suchworten nach einem Cover-Artwork und zeigt dieses an. <br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/javascript javascript]: Ermöglicht die Ausführung beliebigen Javascript-Codes aus einem Reading.<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/joinedlabel joinedlabel]: verbindet mehrere Readings zu einem Feld<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/klimatrend klimatrend]: wandelt Daten aus dem statistics-Modul in einen Pfeil um, der den aktuellen Trend anzeigt. <br />
* Knob:<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/kodinowplaying kodinowplaying]: zeigt Informationen zu grade in KODI gespielten Medien in Form eines Labels an.<br />
* [[#label|label]]: STATE als Text anzeigen<br />
* [[#level|level]]: vertical/horizontal bar to show values between min/max value<br />
* link:<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/mpdnowplaying mpdnowplaying]: zeigt Titelinformationen eines per MPD-Modul angebundenen Music Player Daemon an. <br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/multistatebutton multistatebutton]: Variante des push-Widgets das den set-Befehl abhängig vom gelesenen Status ändert.<br />
* [[#pagetab|pagetab]]: Element to smoothly exchange the whole page with another page<br />
* pagebutton:<br />
* [[#playstream|playstream]]: Abspielen eines Webradio-Streams per Button<br />
* [[#popup|popup]]: a popup dialog which open on click on another widget <br />
* [[#progress|progress]]: round symbolic display for percent values<br />
* [[#push|push]]: send any command to Fhem e.g. up / down<br />
* range:<br />
* readingsgroup:<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/reload reload]: auslösen eine Pagereloads<br />
* [[#rotor|rotor]]: Umschalten von zwei oder mehr Widgets an einer Position<br />
* [[#select|select]]: Combobox to provide a list for selection<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/settimer settimer]: zum anzeigen und einstellen einer Uhrzeit.<br />
* [[#simplechart|simplechart]]: simple XY line chart for one value (reads directly from Fhem log file) <br />
* [[#slider|slider]]: vertical slider to select between min/max value<br />
* spinner:<br />
* swiper:<br />
* [[#switch|switch]]: Toggle any command to Fhem (e.g. on / off)<br />
* [[#symbol|symbol]]: State als Symbol darstellen (z.B. Fenster offen)<br />
* [[#thermostat|thermostat]]: dial for heater thermostates to set desired value and show current value<br />
* [[#volume|volume]]: dial to set a single value (e.g. 0-60)<br />
* [[#weather|weather]]: insert an icon or image, represending a weather literal<br />
* [https://github.com/svenson08/ftui-weekdaytimer-widget weekdaytimer]: Visualisierung des [[WeekdayTimer]] Modul<br />
* [https://github.com/nesges/Widgets-for-fhem-tablet-ui/wiki/wind_direction wind_direction]: Zeigt die Windrichtung auf einer Windrose an. <br />
<br />
<br />
Ein Demo der Widgets findet ihr [http://knowthelist.github.io/fhem/tablet/demo_widgets.html Hier].<br />
----------------------------------<br />
<br />
Für alle Widgets gilt:<br />
{| class="wikitable"<br />
|+allgemeine Attribute<br />
|-<br />
!align="right" |data-type<br />
|Widget-Typ<br />
|-<br />
!align="right" |data-device<br />
|Fhem-Name des Gerätes (mit dem Befehl 'list' bekommt man im Fhem die kpl. Liste)<br />
|-<br />
!align="right" |class<br />
|CSS-Klassen für Aussehen und Formatierung des Widgets<br />
|-<br />
|}<br />
<br />
{| class="wikitable"<br />
|+Daten Empfangen<br />
|-<br />
!align="right" |data-get<br />
|Reading Name<br />
|-<br />
!align="right" |data-get-on<br />
|Wert für den Status on<br />
|-<br />
!align="right" |data-get-off<br />
|Wert für den Status off<br />
|-<br />
|}<br />
<br />
{| class="wikitable"<br />
|+Daten Senden<br />
|-<br />
!align="right" |data-set<br />
|Reading Name<br />
|-<br />
!align="right" |data-set-on<br />
|Wert für den Status on<br />
|-<br />
!align="right" |data-set-off<br />
|Wert für den Status off<br />
|-<br />
|}<br />
<br />
<div id="chart">'''CHART'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-logdevice<br />
|name of the logdevice (e.g. FileLog_WohnzimmerHeizung) or array of names if more than one graph shall be displayed<br />
|-<br />
|-<br />
!align="right" |data-logfile<br />
|name of the logfile (e.g. WohnzimmerHeizung-2015.log) or or array of names if more than one graph shall be displayed<br />
|'-' or omitting this data means current logfile<br />
|-<br />
!align="right" |data-columnspec<br />
|definition for how to find the values (e.g. "4:meas.*:1:int") or or array of columnspecs if more than one graph shall be displayed<br />
|-<br />
|-<br />
!align="right" |data-style<br />
|name of the graph style to be used (e.g. 'SVGplot l0' or 'ftui l0dash') or or array of styles if more than one graph shall be displayed using different stlyes. The standard fhem plot styles can be used furthermore there are some more predefined styles existing (details see css file). Own styles can be specified e.g. in the fhem-table-ui-user.css file.<br />
|-<br />
|-<br />
!align="right" |data-ptype<br />
|name of the plot type (e.g. 'lines' or 'fa-cog') or or array of plottypes if more than one graph shall be displayed. All fhem plot styles are supported. Additionally it is possible to specify symbols (currently supported are font awesome ('fa-...'), open automation ('oa-...') and fhem symbols ('fs-...')). Can also be something like 'icon:1' in which case the respective columnspec should result in links to icons (e.g. for weather forecast) and the y-value is taken from the graph number 1 <br />
|'lines'<br />
|-<br />
!align="right" |data-uaxis<br />
|name of the axis to be used ('primary' or 'secondary') or or array of axis' to be used if more than one graph shall be displayed. The 'primary' axis is labelled on the left side, the 'secondary' axis is labelled on the right side<br />
|'primary'<br />
|-<br />
!align="right" |data-legend<br />
|caption of the graph (used in the legend and at the cursor) or an array of legend texts if more than one graph shall be displayed.<br />
|-<br />
|-<br />
!align="right" |data-minvalue<br />
|min Y value to Show or an array of values for dynamic minY for primary axis. A value of 'auto' means that the value is calculated from the data displayed dynamically<br />
|10<br />
|-<br />
!align="right" |data-minvalue_sec<br />
|min Y value to Show or an array of values for dynamic minY for secondary axis. A value of 'auto' means that the value is calculated from the data displayed dynamically<br />
|'auto'<br />
|-<br />
!align="right" |data-maxvalue<br />
|max Y value to Show or an array of values for dynamic maxY for primary axis. A value of 'auto' means that the value is calculated from the data displayed dynamically<br />
|30<br />
|-<br />
!align="right" |data-maxvalue_sec<br />
|max Y value to Show or an array of values for dynamic maxY for secondary axis. A value of 'auto' means that the value is calculated from the data displayed dynamically<br />
|'auto'<br />
|-<br />
!align="right" |data-yticks<br />
|value distance between Y tick lines (related to primary axis). A value of 'auto' means that the value is calculated from the data displayed dynamically. Can be an array containing value pairs in order to have arbitrary text for given values (e.g. data-yticks='[[0,"open"],[1,"closed"]]')<br />
|'auto'<br />
|-<br />
!align="right" |data-yticks_sec<br />
|value distance between Y tick lines (related to secondary axis). A value of 'auto' means that the value is calculated from the data displayed dynamically.Can be an array containing value pairs in order to have arbitrary text for given values (e.g. data-yticks_sec='[[0,"open"],[1,"closed"]]')<br />
|'auto'<br />
|-<br />
!align="right" |data-xticks<br />
|time range between each X tick lines (in minutes). A value of 'auto' means that the value is calculated from the data displayed dynamically<br />
|'auto'<br />
|-<br />
!align="right" |data-daysago_start<br />
|number of days back from now for the start of the plot (0 means the plot starts from today 0:00). Additionally the x-axis start value can be set here unsing standard data formats like ('2013-10-23'), the time portion of the string is only used when <code>data-nofulldays</code> is 'true'. If the setting ends with 'w', 'W', 'm', 'M', 'y', 'Y' the nuber given is interpreted as week, month or year respectively (capital letters mean rounding to full weeks, months years) (e.g. '2Y' means that, if current date is 3.6.2015, the graph will start 1.1.2013).<br />
|0<br />
|-<br />
!align="right" |data-daysago_end<br />
|number of days back from now for the end of the plot (-1 means the plot ends today 24:00). Additionally the x-axis end value can be set here unsing standard data formats like ('2013-10-23'), the time portion of the string is only used when <code>data-nofulldays</code> is 'true'. If the setting ends with 'w', 'W', 'm', 'M', 'y', 'Y' the nuber given is interpreted as week, month or year respectively (capital letters mean rounding to full weeks, months years) (e.g. '2Y' means that, if current date is 3.6.2015, the graph will end 31.12.2013).<br />
|-1<br />
|-<br />
!align="right" |data-timeformat<br />
|setting for the formatting of the x-tick text. The format can be configured in a quite flexible way. Several format classifiers are supported which are separated by special characters ('-', '.', '/', ' ', ':', ',', '\'). All characters despite '\' will be displayed in the final output.<br />
The following is a list of supported classifiers:<br />
* 'LF'enters a linefeed<br />
* 'mm' - displays minutes as 2 digits<br />
* 'hh' - displays hours as 2 digits<br />
* 'dd' - displays day of the month as 2 digits<br />
* 'MM' - displays months as 2 digits (e.g. 02 for February)<br />
* 'MMM' - displays months as 3 characters (e.g. Dec for December)<br />
* 'MMMM' - displays monhts as full names (e.g. March)<br />
* 'ee' - displays weekdays as 2 digits (e.g. 00 for Sunday)<br />
* 'eee' - displays weekdays as 3 characters (e.g. Mon for Monday)<br />
* 'eeee' - displays weekdays as full names (e.g. Tuesday)<br />
* 'yy' - displays years as 2 digits (e.g. 16 as 2016)<br />
* 'yyyy' - displays years as 4 digits<br />
For example a string given as 'MMM\LF\yyyy' will display 'Jan' in one line and '2016' in a second one. A string given as 'MM.dd 2016' will display '03.05 2016'.<br />
|-<br />
|-<br />
!align="right" |data-nofulldays<br />
|switch to activate/deactivate rounding of the xaxis start and end values to full days ('true' or 'false')<br />
|'false'<br />
|-<br />
!align="right" |data-ytext<br />
|text to be shown besides the primary y axis.<br />
|-<br />
|-<br />
!align="right" |data-ytext_sec<br />
|text to be shown besides the secondary y axis.<br />
|-<br />
|-<br />
!align="right" |data-yunit<br />
|unit of the value to show beside of each Y ticks for primary y axis.<br />
|-<br />
|-<br />
!align="right" |data-crosshair<br />
|switch to activate/deactivate the crosshair cursor ('true' or 'false')<br />
|'false'<br />
|-<br />
!align="right" |data-cursorgroup<br />
|number to define coupling of the crosshair cursor. The cursors of all charts having the same number are coupled and move together.<br />
|-<br />
|-<br />
!align="right" |data-scrollgroup<br />
|number to define coupling of the scrolling (shift and zoom). All charts having the same number are scrolled (shifted and zoomed) together.<br />
|-<br />
|-<br />
!align="right" |data-showlegend<br />
|switch to activate/deactivate the initial display of the legend window ('true' or 'false')<br />
|'false'<br />
|-<br />
!align="right" |data-legendpos<br />
|array of two values (horizontal and vertical) to set the initial position of the legend window. Allowed values are "left", "right" or a number giving the position in percent for the first parameter (horizontal position) and 'top', 'bottom' or a number giving the position in percent for the second parameter (vertical position). <br />
|'["top","right"]'<br />
|-<br />
!align="right" |data-yunit_sec<br />
|unit of the value to show beside of each Y ticks for secondary y axis.<br />
|-<br />
|-<br />
!align="right" |data-width<br />
|fixed size for width (in&nbsp;% or px)<br />
|-<br />
|-<br />
!align="right" |data-height<br />
|fixed size for height (in&nbsp;% or px)<br />
|-<br />
|-<br />
!align="right" |data-graphsshown<br />
|boolean to define if graphs are activated (shown) initially or an array of booleans if more than one graph shall be displayed.<br />
|-<br />
|-<br />
!align="right" |data-ddd<br />
|setting for 3D display. Array with 3 angles for rotation of the 3D chart in x, y, z (z not yet supported) (e.g. '["40","60","0"]'). If the array is existing, there will be 2 additional buttons on top for changing rotation in x and y.<br />
|-<br />
|-<br />
!align="right" |data-dddspace<br />
|setting for the space between different graphs in y direction if 3D is activated (space given in pixels).<br />
|15<br />
|-<br />
!align="right" |data-dddwidth<br />
|setting for the width of the graphs if 3D is activated (width given in pixels).<br />
|10<br />
|-<br />
!align="right" |data-title<br />
|setting for inclusion of chart title on top of the chart. Includes the possibility for calculation of values like in SVG Plots (e.g. data-title="Min: $data{mindate4}, Max: $data{maxdate4}, Last: $data{currdate4}"). Supported are:<br />
* min1: minimum value of graph 1 (first graph in the given list). Number can be any graph or omitted if calculation shall be done over all graphs.<br />
* max1: maximum value of graph 1 (first graph in the given list)<br />
* avg1: average value of graph 1 (first graph in the given list)<br />
* cnt1: number of values of graph 1 (first graph in the given list)<br />
* currval1: last (current) value of graph 1 (first graph in the given list)<br />
* mindate1: minimum x value of graph 1 (first graph in the given list)<br />
* maxdate1: maximum x value of graph 1 (first graph in the given list)<br />
* currdate1: last (current) x value of graph 1 (first graph in the given list)<br />
|''<br />
|-<br />
!align="right" |class<br />
|fullsize, noticks, nobuttons, small, normal, big<br />
|-<br />
|-<br />
|}<br />
<br />
<code>data-logfile</code> can be omitted in this case the default value "-" will be used. This means that the current logfile is going to be used.<br />
<br />
There are several buttons that control the dynamic behaviour of the chart. The <-, ->, + and - buttons shift and zoom the displayed data. The "legend" and "cursor" buttons are switching on and off the display of the legend window and the crosshair cursor respectively. If 3D display is activated (see above) 2 more buttons control the rotation in x and y.<br />
<br />
When the legend window is displayed, a click on the legend text shows/hides the respective graph. The legend window can be dragged to other positions on desktop browsers (currently not yet working for iOS and Android).<br />
<br />
The crosshair cursor currently only works dynamically on desktop browsers. On iOS and Android you have to tap on the screen to set the cursor to a new position.<br />
<br />
Three classes define default values for the texts (small, normal, big). Additionally there is a number of css styles that control the visible appearance of the chart. The following classes are supported:<br />
<br />
{| class="wikitable"<br />
!CSS class name<br />
!Description<br />
|-<br />
!.chart-background<br />
|Color etc. for the chart background<br />
|-<br />
!.text.axes<br />
|Font and color for the chart axes<br />
|-<br />
!.buttons<br />
|Size and color for the buttons (shift etc.)<br />
|-<br />
!.gridlines<br />
|Size and color for gridlines generally<br />
|-<br />
!.xaxis<br />
|Font, size and color for xaxis<br />
|-<br />
!.yaxis<br />
|Font, size and color for yaxis<br />
|-<br />
!.xticks<br />
|Font, size and color for xticks<br />
|-<br />
!.yticks<br />
|Font, size and color for yticks<br />
|-<br />
!.crosshair<br />
|Font, size and color (foreground/background) for the crosshair cursor<br />
|-<br />
!.caption<br />
|Font, size and color for text buttons for legend and cursor switching<br />
|-<br />
!.legend<br />
|Font, size and background color for legend window<br />
|-<br />
|-<br />
|}<br />
<br />
[[#Beispiel_chart|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="circlemenu">'''CIRCLEMENU'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-item-diameter<br />
|diameter of the circle<br />
|52<br />
|-<br />
!align="right" |data-circle-radius<br />
|radius of each item, in pixel<br />
|70<br />
|-<br />
!align="right" |data-direction<br />
|position of the items in relation to the center<br />
|'full'<br />
|-<br />
!align="right" |data-close-after<br />
|closing time of the circle-menu<br />
|(item-count + 1s) or a minimum of 4s<br />
|-<br />
!align="right" |class<br />
|keepopen<br />
|<br />
|-<br />
|}<br />
<br />
Optionen für data-direction: top | right | bottom | left | top-right | top-left | bottom-right | bottom-left | top-half | right-half | bottom-half | left-half | full | vertical | horizontal<br />
<br />
[[#Beispiel_circlemenu|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="departure">'''DEPARTURE'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-type<br />
|widget-type; must be departure<br />
|<br />
|-<br />
!align="right" |data-device<br />
|name of the device to get data from<br />
|<br />
|-<br />
!align="right" |data-get<br />
|name of the reading of device to get data from<br />
|<br />
|-<br />
!align="right" |data-icon<br />
|define icon for widget<br />
|<br />
|-<br />
!align="right" |data-interval<br />
|interval to reload automatically<br />
|<br />
|-<br />
!align="right" |class<br />
|choose style of widget; see example<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_departure|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="dimmer">'''DIMMER'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from Fhem<br />
|'STATE'<br />
|-<br />
!align="right" |data-get-on<br />
|value for ON status to get<br />
|'on'<br />
|-<br />
!align="right" |data-get-off<br />
|value for OFF status to get<br />
|'off'<br />
|-<br />
!align="right" |data-set<br />
|(<command> <device> <reading> <value>) <br />
|<br />
|-<br />
!align="right" |data-set-on<br />
|value for ON status to set<br />
|value of data-get-on<br />
|-<br />
!align="right" |data-set-off<br />
|value for OFF status to set<br />
|value of data-get-off<br />
|-<br />
!align="right" |data-cmd<br />
|name of the command (<command> <device> <value>) (e.g. setstate, set, setreading, trigger)<br />
|'set'<br />
|-<br />
!align="right" |data-dim<br />
|name of the reading responsible for dim (<command> <device> <reading> <value>) <br />
|value of data-get-on<br />
|-<br />
!align="right" |data-icon<br />
|name of the font-awesome icon<br />
|fa-lightbulb-o<br />
|-<br />
|}<br />
<br />
[[#Beispiel_dimmer|Link zu einem Beispiel]]<br />
<br />
<div id="homestatus">'''HOMESTATUS'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from Fhem<br />
|'STATE'<br />
|-<br />
!align="right" |data-set<br />
|command to send to Fhem (<code>set <device> <command> <value></code>)<br />
|''<br />
|-<br />
!align="right" |data-get-on<br />
|array of states using for get<br />
|['1','2','3','4']<br />
|-<br />
!align="right" |data-set-on<br />
|array of states using for set.<br />
|value of data-get-on<br />
|-<br />
!align="right" |data-alias<br />
|array of fix names to show only in the UI as an alias to the real states<br />
|''<br />
|-<br />
!align="right" |data-icons<br />
|array of icons related to the data-get-on array<br />
|''<br />
|-<br />
!align="right" |data-version<br />
|name of the status model e.g. 'residents','roommate','guest' <br />
|(default NULL)<br />
|-<br />
|}<br />
<br />
The default version has 4 states: '1','2','3','4' The default aliases are 'Home','Night','Away','Holiday'; data-version='residents' or 'roommate' or 'guest' has 5 states ('home','asleep','absent','gone','gotosleep') They have these aliases 'Home','Night','Away','Holiday','Retire'<br />
<br />
[[#Beispiel_homestatus|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="image">'''IMAGE'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get an URL from Fhem<br />
|'STATE'<br />
|-<br />
!align="right" |data-size<br />
|width of the image in px or %, the height scales proportionally<br />
|50%<br />
|-<br />
!align="right" |data-url<br />
|URL of the image to show (use data-url or data-device + data-get, not both)<br />
|<br />
|-<br />
!align="right" |data-refresh<br />
|Interval in seconds for image refresh for usage together with data-url<br />
|900<br />
|-<br />
|}<br />
<br />
[[#Beispiel_image|Link zu einem Beispiel]]<br />
<br />
=== Widget LABEL ===<br />
<div id="label">'''LABEL'''</div><br />
<br />
Mit dem LABEL Widget kann der STATUS eines Device in Textform angezeigt werden. Dabei kann das die Farbe des Anzeigetext abhängig von dessen Wert festgelegt werden. <br />
<br />
Neben den '''allgemeine Attribute''' besitzt das LABEL-Widget die nachfolgenden Attribute.<br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get <br />
|Name des Readings in FHEM <br />
|<br />
|-<br />
!align="right" |data-fix <br />
|Eine bestimmte Anzahl an Dezimalstellen <br />
|'-1' -> non-numeric <br />
|-<br />
!align="right" |data-part <br />
|split position of the space separated value to show or an RegEx <br />
| <br />
|-<br />
!align="right" |data-color <br />
| fix color attribute or DEVICE:READING for dynamic setting of label color <br />
| ''<br />
|-<br />
!align="right" |data-colors <br />
|a array of color values to affect the colour of the label according to the limit value <br />
| <br />
|-<br />
!align="right" |data-limits-get <br />
|name of the DEVICE:Reading to colorize the label <br />
|data-device:data-get <br />
|-<br />
!align="right" |data-limits <br />
|an array of numeric values to affect the colour of the Label <br />
| <br />
|-<br />
!align="right" |data-limits-part <br />
|part number of the space separated value to show or a RegEx <br />
|'-1' -> all <br />
|-<br />
!align="right" |data-unit <br />
|add a unit after a numeric value. use encoded strings e.g. "%B0C%0A" <br />
| <br />
|-<br />
!align="right" |data-substitution <br />
|regex-substitution to apply on the value. Standard regex notation (s/regex/subst/modifier) is expected <br />
| <br />
|-<br />
!align="right" |data-hide <br />
|string to compare with current value. hide element when it's value equals data-hide <br />
|<br />
|-<br />
!align="right" |data-hideparents <br />
|jquery selector to hide element's parents too <br />
|<br />
|-<br />
!align="right" |class <br />
|small, large, big, bigger, thin, red, green, blue, darker, timestamp, w1x, w2x, w3x, fixedlabel, icon, bg-limit <br />
| <br />
|}<br />
<br />
Mit der Class 'fixedlabel' kann man Label einbauen, die einen festen Text (direkt im HTML) haben, aber trotzdem die Farbe per Reading Value beeinflusst werden könnte.<br><br />
Mit der Class 'icon' kann man Label einbauen, die wie Icons aussehen. Als Hintergrund gibt es 'icon round' (rund), 'icon square' (Rechteck mit abgerundeten Ecken) und 'icon squareborder' (Rechteck mit abgerundeten Ecken und einem zusätzlichen Rand).<br><br />
Mit der Class 'bg-limit' wird der Hintergrund des Icon auf grün oder rot gesetzt, passend zum on/off Status des data-limits.<br />
Use data-color OR data-colors + data-limits, not both.<br />
<br />
With class="bg-limit" it changes the background color not the forecolor according data-limits<br />
<br />
class="icon square" or class="icon round" forces the label to a fix width and height in icon style<br />
<br />
Special layout can be achieved by overwriting of following classes in the fhem-tablet-ui-user.css:<br />
<br />
.label-precomma .label-comma .label-aftercomma .label-unit<br />
<br />
e.g.: .label-aftercomma{ font-size:40%; left: 4px; top: -25px; position: relative; }<br />
<br />
Functions for data-substitution:<br />
<br />
Array of replacements<br />
RegEx-substitution to apply on the value. Standard regex notation (s/regex/subst/modifier) is expected<br />
data-substitution="weekdayshort"<br />
JS functions data-substitution="toDate().ddmm()" - convert to day:month<br />
data-substitution="toDate().hhmm()" - convert to hour:minutes<br />
<br />
data-substitution="toDate().hhmmss()" - convert to hour:minutes:secondes<br />
<br />
data-substitution="toDate().eeee()" - convert to name of the week day<br />
<br />
data-substitution="toDate().ago()" - convert to time span<br />
<br />
[[#Beispiel_label|Link zu einem Beispiel]]<br />
<br />
=== Widget LEVEL ===<br />
<div id="level">'''LEVEL'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from Fhem<br />
|'STATE'<br />
|-<br />
!align="right" |data-min<br />
|minimal value to set<br />
|'0'<br />
|-<br />
!align="right" |data-max<br />
|maximal value to set<br />
|'100'<br />
|-<br />
!align="right" |data-on<br />
|value where the slider moves to max<br />
|'on'<br />
|-<br />
!align="right" |data-off<br />
|value where the slider moves to min<br />
|'off'<br />
|-<br />
!align="right" |data-part<br />
|part number of the space separated value to show or an RegEx<br />
|<br />
|-<br />
!align="right" |data-colors<br />
|a array of color values to affect the colour of the label according to the limit value<br />
|<br />
|-<br />
!align="right" |data-limits<br />
|a array of numeric or RegEx values to affect the colour of the label<br />
|<br />
|-<br />
!align="right" |class<br />
|mini, horizontal<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_level|Link zu einem Beispiel]] (fehlt noch)<br />
<br />
<div id="pagetab">'''PAGETAB'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-url<br />
|URL of the new page to show<br />
|<br />
|-<br />
!align="right" |data-icon<br />
|name of the font-awesome icon<br />
|'fa-power-off'<br />
|-<br />
!align="right" |data-background-icon<br />
|name of the font-awesome icon for background <br />
|''<br />
|-<br />
!align="right" |data-on-background-color<br />
|color of ON state<br />
|'#aa6900'<br />
|-<br />
!align="right" |data-off-background-color<br />
|color of OFF state<br />
|'#505050'<br />
|-<br />
!align="right" |data-on-color<br />
|color of ON state<br />
|'#aa6900'<br />
|-<br />
!align="right" |data-off-color<br />
|color of Off state<br />
|'#505050'<br />
|-<br />
!align="right" |data-get-on<br />
|array of status to assign a special icon-list from data-icons<br />
|<br />
|-<br />
!align="right" |data-icons<br />
|array of icons related to the a data-get-on array<br />
|<br />
|-<br />
!align="right" |class<br />
|warn, activate (as additionals for data-icons)<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_pagetab|Link zu einem Beispiel]]<br />
<br />
<div id="playstream">'''PLAYSTREAM'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-url<br />
|URL des Radio-Streams<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get the control state from FHEM<br />
|'STATE'<br />
|-<br />
!align="right" |data-get-on<br />
|value for PLAY status to get. <br />
|'on'<br />
|-<br />
!align="right" |data-get-off<br />
|value for STOP status to get. <br />
|'off'<br />
|-<br />
!align="right" |data-volume<br />
|name of the reading to get the volume value (0-100) <br />
|volume<br />
|-<br />
|}<br />
<br />
[[#Beispiel_playstream|Link zu einem Beispiel]]<br />
<br />
<div id="popup">'''POPUP'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading where to get the alert value from<br />
|'STATE'<br />
|-<br />
!align="right" |data-get-on<br />
|value which trigger to open the dialog<br />
|'on'<br />
|-<br />
!align="right" |data-off<br />
|value which trigger to close the dialog <br />
|'off'<br />
|-<br />
!align="right" |data-width<br />
|fixe size for width (in % or px)<br />
|<br />
|-<br />
!align="right" |data-height<br />
|fixe size for height (in % or px)<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_popup|Link zu einem Beispiel]]<br />
<br />
<div id="progress">'''PROGRESS'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from Fhem<br />
|'STATE'<br />
|-<br />
!align="right" |data-max<br />
|maximal value to set or name of the reading which helds the max value<br />
|100<br />
|-<br />
!align="right" |class<br />
|novalue, percent<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_progress|Link zu einem Beispiel]] (fehlt noch)<br />
<br />
<div id="push">'''PUSH'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default-Wert<br />
|-<br />
!align="right" |data-set<br />
| name of the reading to set on FHEM (<command> <device> <reading> <value>) <br />
|<br />
|-<br />
!align="right" |data-set-on<br />
|value to send when the the button get pressed oder ein Array zwischen dessen Werten umgeschaltet werden kann<br />
|<br />
|-<br />
!align="right" |data-icon<br />
|name of the font-awesome icon<br />
|<br />
|-<br />
!align="right" |data-background-icon<br />
|name of the font-awesome icon for background <br />
|'fa-circle'<br />
|-<br />
!align="right" |data-cmd<br />
|name of the command (<command> <device> <value>) (e.g. setstate, set, setreading, trigger)<br />
|'set'<br />
|-<br />
!align="right" |data-doubleclick<br />
|timeout to wait for a second click or touch. '0' disables the doubleclick feature. <br />
|0<br />
|-<br />
!align="right" |data-countdown<br />
|secondes for the countdown progress control <br />
|autodetect from 'on-for-timer' command<br />
|-<br />
!align="right" |data-background-icon<br />
|name of the font-awesome icon for background <br />
|<br />
|-<br />
!align="right" |data-off-background-color<br />
|fix color attribute for OFF state or DEVICE:READING for dynamic setting <br />
|#505050<br />
|-<br />
!align="right" |data-off-color<br />
|fix color attribute for Off state or DEVICE:READING for dynamic setting<br />
|#505050<br />
|-<br />
|}<br />
<br />
'data-set-on' can also be an array of values to toggle between this values<br />
<br />
[[#Beispiel_push|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="rotor">'''ROTOR'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" | data-delay<br />
|time in millisecondes to wait until next list item get shown<br />
|3500<br />
|-<br />
!align="right" |class<br />
|fade, rotate<br />
|'' <br />
|-<br />
|}<br />
Ohne Angabe von class erfolgt keine Animation.<br />
<br />
[[#Beispiel_rotor|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="select">'''SELECT'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading that get the selected item of the list<br />
|<br />
|-<br />
!align="right" |data-set<br />
|name of the reading to set on Fhem (<command> <device> <reading> <value>)<br />
|''<br />
|-<br />
!align="right" |data-list<br />
|name of the reading to get a :-separated list from Fhem<br />
|''<br />
|-<br />
!align="right" |data-items<br />
|an array of fix items to show in the selection box (alternative if data-list is empty)<br />
|<br />
|-<br />
!align="right" |data-alias<br />
|an array of fix names to show only in the selection box as an alias to the real items<br />
|<br />
|-<br />
!align="right" |data-cmd<br />
|name of the command to send to Fhem (<command> <device> <reading> <value>) (e.g. setstate, set, setreading, trigger)<br />
|'set'<br />
|-<br />
!align="right" |data-quote<br />
|characters to enclose the send value<br />
|<br />
|-<br />
!align="right" |class<br />
|wider, w1x, w2x, w3x, large, big<br />
|<br />
|-<br />
|} <br />
<br />
[[#Beispiel_select|Link zu einem Beispiel]]<br />
<br />
<div id="simplechart">'''SIMPLECHART'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-logdevice<br />
|name of the logdevice (e.g. FileLog_WohnzimmerHeizung)<br />
|<br />
|-<br />
!align="right" |data-logfile<br />
|name of the logfile (e.g. WohnzimmerHeizung-2015.log)<br />
|'-' means current logfile<br />
|-<br />
!align="right" |data-columnspec<br />
|definition for how to find the values (e.g. "4:meas.*:1:int")<br />
|''<br />
|-<br />
!align="right" |data-minvalue<br />
|min Y value to Show or an array of values for dynamic minY <br />
|10<br />
|-<br />
!align="right" |data-maxvalue<br />
|max Y value to Show or an array of values for dynamic maxY <br />
|30<br />
|-<br />
!align="right" |data-yticks<br />
|value distance between Y tick lines<br />
|5<br />
|-<br />
!align="right" |data-xticks<br />
|time range between each X tick line (in Minuten)<br />
|360 minutes<br />
|-<br />
!align="right" |data-daysago<br />
|number of days back from now <br />
|0<br />
|-<br />
!align="right" |data-caption<br />
|name of the chart to show as text <br />
|<br />
|-<br />
!align="right" |data-yunit<br />
|unit of the value to show beside of each Y ticks<br />
|<br />
|-<br />
!align="right" |data-width<br />
|fixe size for width (in % or px)<br />
|<br />
|-<br />
!align="right" |data-height<br />
|fixe size for height (in % or px)<br />
|<br />
|-<br />
!align="right" |class<br />
|fullsize, noticks<br />
|<br />
|-<br />
|} <br />
<br />
[[#Beispiel_simplechart|Link zu einem Beispiel]] (fehlt noch)<br />
<br />
<code>data-logfile</code> kann man auch weglassen, dann greift der Defaultwert "-". Damit wird das neuste Logfile gelesen.<br />
<br />
<br />
<div id="slider">'''SLIDER'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from Fhem<br />
|'STATE'<br />
|-<br />
!align="right" |data-set<br />
|command to send to Fhem (<code>set <device> <command> <value></code>)<br />
|''<br />
|-<br />
!align="right" |data-cmd<br />
|name of the command (<command> <device> <value>) (e.g. setstate, set, setreading, trigger)<br />
|'set'<br />
|-<br />
!align="right" |data-min<br />
|minimal value to set<br />
|0<br />
|-<br />
!align="right" |data-max<br />
|maximal value to set<br />
|100<br />
|-<br />
!align="right" |data-step<br />
|step value<br />
|1<br />
|-<br />
!align="right" |data-on<br />
|value where the slider moves to max<br />
|'on'<br />
|-<br />
!align="right" |data-off<br />
|value where the slider moves to min<br />
|'off'<br />
|-<br />
!align="right" |data-get-value<br />
|RegEx to retrieve the value or part number of the space separated input to get the value<br />
|'-1': all of the input<br />
|-<br />
!align="right" |data-set-value<br />
|Format of the value to send to FHEM<br />
|'$v': the value only<br />
|-<br />
!align="right" |data-width<br />
|width for horizontal sliders<br />
|'120px', for mini '60px'<br />
|-<br />
!align="right" |data-height<br />
|height for vertical sliders <br />
|'120px', for mini '60px'<br />
|-<br />
!align="right" |data-color<br />
|color for quantity range<br />
|'#aa6900'<br />
|-<br />
!align="right" |data-background-color<br />
|color for range bar<br />
|#404040<br />
|-<br />
!align="right" |class<br />
|Aussehen/Ausrichtung<br />
|<br />
|-<br />
|}<br />
<br />
Für class steht mini, horizontal und negated (0 liegt oben) zur Verfügung.<br />
<br />
[[#Beispiel_slider|Link zu einem Beispiel]]<br />
<br />
<div id="switch">'''SWITCH'''</div><br />
<br />
{| class="wikitable"<br />
!HTML-Attribut<br />
!Beschreibung<br />
!Default-Wert<br />
|-<br />
!align="right" |data-get<br />
|Name des Reading, was gelesen werden soll<br />
|'STATE'<br />
|-<br />
!align="right" |data-set<br />
|Name des Reading, was gelesen werden soll<br />
|'STATE'<br />
|-<br />
!align="right" |data-cmd<br />
|Kommando Name (<command> <device> <value>) <br />(z.B setstate, set, setreading, trigger) <br />
|'set'<br />
|-<br />
!align="right" |data-doubleclick<br />
|timeout to wait for x millisecondes click or touch. '0' disables the doubleclick feature.<br />
|'0'<br />
|-<br />
|}<br />
Einstellung bei zwei Werten<br />
<br />
{| class="wikitable"<br />
!HTML-Attribut<br />
!Beschreibung<br />
!Default-Wert<br />
|-<br />
!align="right" |data-get-on<br />
|Wert, bei dem zum Status ON geschaltet werden soll. <br />
|'on'<br />
|-<br />
!align="right" |data-get-off<br />
|Wert, bei dem zum Status OFF geschaltet werden soll. <br />
|'off'<br />
|-<br />
!align="right" |data-set-on<br />
|Wert, der zu Fhem gesendet werden soll, wenn das Widget auf ON geschaltet wurde <br />
|Wert von data-get-on<br />
|-<br />
!align="right" |data-set-off<br />
|Wert, der zu Fhem gesendet werden soll, wenn das Widget auf OFF geschaltet wurde <br />
|Wert von data-get-off<br />
|-<br />
!align="right" |data-icon<br />
|Name des Font-Awesome Icon. <br />
|'fa-lightbulb-o'<br />
|-<br />
!align="right" |data-background-icon<br />
|Name des Font-Awesome Hintergrund Icon. <br />
|'fa-circle'<br />
|-<br />
!align="right" |data-on-background-color<br />
|Hintergrundfarbe beim Status on oder DEVICE:Reading bei dynamischen Einstellungen<br />
|'#aa6900'<br />
|-<br />
!align="right" |data-off-background-color<br />
|Hintergrundfarbe beim Status off oder DEVICE:Reading bei dynamischen Einstellungen<br />
|'#505050'<br />
|-<br />
!align="right" |data-on-color<br />
|Widget Farbe beim Status ON <br />
|'#aa6900'<br />
|-<br />
!align="right" |data-off-color<br />
|Widget Farbe beim Status OFF <br />
|'#505050'<br />
|-<br />
|}<br />
<br />
Einstellung bei mehreren Werten<br />
{| class="wikitable"<br />
!HTML-Attribut<br />
!Beschreibung<br />
!Default-Wert<br />
|-<br />
!align="right" |data-states<br />
|Array mit Status Angaben <br />
|<br />
|-<br />
!align="right" |data-set-states<br />
|Array mit Status Angaben, die gesetzt werden sollen<br />
|<br />
|-<br />
!align="right" |data-icons<br />
|Array Icons zum zuvor definierten Status<br />
|<br />
|-<br />
!align="right" |data-background-icons<br />
|Array mit Hintergrund Icons zum zuvor definierten Status <br />
|<br />
|-<br />
!align="right" |data-colors<br />
|Array mit Farben zum zuvor definierten Status <br />
|<br />
|-<br />
!align="right" |data-background-colors<br />
|Array mit Hintergrund Farben zum zuvor definierten Status <br />
|<br />
|-<br />
!align="right" |class : readonly<br />
|Es wird nur der Status angezeigt und kann nicht geändert werden<br />
|<br />
|-<br />
|}<br />
<br />
<code>data-get-on</code> and <code>data-get-off</code> accept also RegEx values. e.g. data-get-on="[0-9]{1,3}|on" means set switch on if STATE is a numeric value or 'on'. data-get-off="!on" means accept all but the data-get-on value (negation)<br />
<br />
[[#Beispiel_switch|Link zu einem Beispiel]]<br />
<br />
=== Widget SYMBOL ===<br />
<div id="symbol">'''SYMBOL'''</div><br />
<br />
Mit dem SYMBOL Widget kann der STATUS eines Device dargestellt werden. Dabei kann das angezeigte Symbol und dessen Farbe bestimmt werden. Wie bei anderen Widgets kann das Symbol und die Farbe vom State abhängig konfiguriert werden. Das SYMBOL-Widget dient nur zur Anzeige eines STATUS, es besitzt kein Möglichkeit der Interaktion.<br />
<br />
Neben den '''allgemeine Attribute''' besitzt das SYMBOL-Widget die nachfolgenden Attribute.<br />
<br />
dual state notation<br />
{| class="wikitable"<br />
! HTML Attribut !! Beschreibung !! Default Wert<br />
|-<br />
| data-get || Name des Reading, was gelesen werden soll || 'STATE' <br />
|}<br />
<br />
Einstellung bei zwei Werten<br />
{| class="wikitable"<br />
!HTML-Attribut !! Beschreibung !! Default-Wert<br />
|-<br />
|'''data-get-on''' ||Wert für on ||'open'<br />
|-<br />
|'''data-get-off''' ||Wert für off ||'closed'<br />
|-<br />
|'''data-get-warn''' ||?????? ||'-1'<br />
|-<br />
|'''data-icon''' ||Name des Symbols ||'ftui-window'<br />
|-<br />
|'''data-background-icon''' ||Hintergrundsymbol ||'''leer'''<br />
|-<br />
|'''data-on-background-color''' ||Farbe für ON-Zustand. ||'#aa6900'<br />
|-<br />
|'''data-off-background-color''' ||Farbe für OFF-Zustand. ||'#505050'<br />
|-<br />
|'''data-on-color''' ||Farbe für ON-Zustand. ||'#aa6900'<br />
|-<br />
|'''data-off-color''' ||Farbe für OFF-Zustand. ||'#505050'<br />
|-<br />
|}<br />
<br />
Einstellung bei mehreren Werten<br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-states<br />
|Array für states. <br />
|<br />
|-<br />
!align="right" |data-icons<br />
|Array mit Icons zu data-states Array<br />
|<br />
|-<br />
!align="right" |data-background-icons<br />
|Array mit Icons zu data-states Array<br />
|<br />
|-<br />
!align="right" |data-colors<br />
|Array mit Farben zu data-states aArray<br />
|''<br />
|-<br />
!align="right" |data-background-colors<br />
|Array mit Hintergrundfarben zu data-states array<br />
|''<br />
|-<br />
|}<br />
<br />
data-get-on,data-get-off and data-states accept also RegEx values. The value for one icon can also contain an additional animatation CSS name, e.g. "fa-exclamation-triangle fa-blink" for a blinking Symbol<br />
<br />
[[#Beispiel_symbol|Link zu einem Beispiel]]<br />
<br />
=== Widget THERMOSTAT===<br />
<div id="thermostat">'''THERMOSTAT'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from Fhem<br />
|'desired-temp'<br />
|-<br />
!align="right" |data-temp<br />
|reading for measured temperature of thermostates<br />
|'measured-temp'<br />
|-<br />
!align="right" |data-set<br />
|command to send to Fhem (set <device> <command> <value>)<br />
|'desired-temp'<br />
|-<br />
!align="right" |data-valve<br />
|reading for valve position of thermostates<br />
|<br />
|-<br />
!align="right" |data-min<br />
|minimal value to set<br />
| 10<br />
|-<br />
!align="right" |data-max<br />
|maximal value to set<br />
| 30<br />
|-<br />
!align="right" |data-minColor<br />
|Farbe des Keises für Min<br />
| #4477FF<br />
|-<br />
!align="right" |data-maxColor<br />
|Farbe des Kreises für Max, zwischen Min und Max wird linear interpoliert <br />
| #FF0000<br />
|-<br />
!align="right" |data-step<br />
|step size for value adjustment e.g. 0.5 <br />
|1<br />
|-<br />
!align="right" |data-bgColor<br />
|Die Farbe der Kreises zwischen den ticks<br />
|'transparent'<br />
|-<br />
!align="right" |data-fgColor<br />
|Die Farbe der zahl im Kreismittelpunkt<br />
|#bbbbbb<br />
|-<br />
!align="right" |data-tkColor<br />
|Die Farbe der ticks<br />
|#696969<br />
|-<br />
|-<br />
!align="right" |data-angleOffset<br />
|Start der ticks im Kreis (in Winkelgraden, 0 = oben)<br />
| -120<br />
|-<br />
!align="right" |data-angleArc<br />
|Bereich der ticks im Kreis (in Winkelgraden)<br />
|240<br />
|-<br />
!align="right" |class<br />
|big, readonly<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_thermostat|Link zu einem Beispiel]]<br />
<br />
<br />
<div id="volume">'''VOLUME'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get from Fhem <br />
|'STATE'<br />
|-<br />
!align="right" |data-set<br />
|command to send to Fhem (set <device> <command> <value>)<br />
|''<br />
|-<br />
!align="rigth" |data-cmd<br />
|name of the command (<command> <device> <value>) (e.g. setstate, set, setreading, trigger) <br />
|'set'<br />
|-<br />
!align="right" |data-min<br />
|minimal value to set<br />
|0<br />
|-<br />
!align="right" |data-max<br />
|maximal value to set<br />
|70<br />
|-<br />
!align="right" |data-get-value<br />
|RegEx to retrieve the value or part number of the space separated input to get the value<br />
|'-1': all of the input<br />
|-<br />
!align="right" |data-set-value<br />
|Format of the value to send to FHEM<br />
|'$v': the value only<br />
|-<br />
!align="right" |data-tickstep<br />
|distance between ticks<br />
|4|20<br />
|-<br />
!align="right" |data-unit<br />
|add a unit after the desired value.<br />
|<br />
|-<br />
!align="right" |class<br />
|mini, small, big, bigger, hue-tick, hue-front, hue-back, dim-tick ,dim-front, dim-back, readonly<br />
|<br />
|-<br />
|}<br />
<br />
[[#Beispiel_volume|Link zu einem Beispiel]] (fehlt noch)<br />
<br />
<br />
<div id="weather">'''WEATHER'''</div><br />
<br />
{| class="wikitable"<br />
!HTML Attribut<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |data-get<br />
|name of the reading to get the weather literal from Fhem<br />
|'STATE'<br />
|-<br />
!align="right" |data-imageset<br />
|collection of images to display current weather situation. Possible values: 'meteocons', 'kleinklima'<br />
|'meteocons'<br />
|-<br />
!align="right" |data-image-path<br />
|path to the images of the selected imageset<br />
|/images/weather/<br />
|-<br />
|}<br />
<br />
[[#Beispiel_weather|Link zu einem Beispiel]]<br />
<br />
== Widgets -- Beispiele ==<br />
<br />
<div id="Beispiel_chart">'''Chart'''</div><br />
<br />
Display a chart with similar capabilities as the FHEM plots<br />
<br />
<pre><br />
<div data-type="chart"<br />
data-logdevice='["Log.Garden","Log.Garden","Log.Garden","Log.Predicted"]'<br />
data-columnspec='["4:Garden.T:15:","10:Garden.T:0:delta-h","10:Garden.T:0:delta-d","4:predicted.*:15:"]'<br />
data-style='["ftui l0fill","ftui l1fill","ftui l2","ftui l3dot"]'<br />
data-ptype='["lines","histeps","histeps","cubic"]'<br />
data-uaxis='["primary","secondary","secondary","primary"]'<br />
data-legend='["Temperature","Rain/hour","Rain/day","Predicted Temp."]'<br />
data-yunit="°C"<br />
data-ytext="Temperature"<br />
data-minvalue="auto"<br />
data-maxvalue="auto"<br />
data-yunit_sec="mm"<br />
data-ytext_sec="Rain (mm)"<br />
data-height="250"<br />
data-yticks="auto"<br />
data-minvalue_sec="auto"<br />
data-maxvalue_sec="auto"<br />
data-nofulldays="true"<br />
data-daysago_start="2013-08-13T00:00:00"<br />
data-daysago_end="2013-08-14T00:00:00"<br />
data-cursorgroup="1"<br />
data-scrollgroup="1"<br />
data-xticks="auto"><br />
</div><br />
</pre><br />
<br />
[[Datei:chart_tabletUI.png]]<br />
<br />
<br />
<div id="Beispiel_circlemenu">'''Circlemenu'''</div><br />
<br />
Cover a lot of other button behind one single button<br />
<br />
<pre><br />
<div class="left"><br />
<div data-type="circlemenu" class="cell circlemenu"><br />
<ul class="menu"><br />
<li><div data-type="push" data-icon="fa-wrench"></div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level -6" <br />
data-icon="">-6</div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level -2" <br />
data-icon="">-2</div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level 0" <br />
data-icon="">0</div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level +3" <br />
data-icon="">2</div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level +9" <br />
data-icon="">9</div></li><br />
<li><div data-type="push" data-device="AvReceiver" <br />
data-set="remoteControl subwoofer-temporary-level +C" <br />
data-icon="">12</div></li><br />
</ul><br />
</div><br />
<div data-type="label" class="cell">Woofer</div><br />
</div><br />
</pre><br />
<br />
[[Datei:circlemenu_tabletUI.png]]<br />
<br />
<br />
<div id="Beispiel_departure">'''Departure'''</div><br />
<br />
Departure Widget Beispiel<br />
<br />
Minimalvariante<br />
<pre> <br />
<div data-type="departure"<br />
data-device="vvs"<br />
data-get="SSB-Zentrum"<br />
data-icon="fa-train"<br />
data-interval="0"><br />
</div><br />
</pre><br />
<br />
Optionen für class<br />
<pre><br />
class="" : default Style (grau)<br />
class="DVB" anderer Style (gelb)<br />
class="VVO" : anderer Style (blau)<br />
class="alternate" : alternierender Hintergrund<br />
class="deptime" : Abfahrtszeit statt Minuten<br />
</pre><br />
<br />
weiteres Beispiel<br />
<pre><br />
<div data-type="departure"<br />
data-device="vvs"<br />
data-get="SSB-Zentrum"<br />
data-icon="fa-train"<br />
data-interval="0"<br />
class="DVB deptime alternate"><br />
</div><br />
</pre><br />
<br />
<br />
<div id="Beispiel_dimmer">'''Dimmer'''</div><br />
<br />
Dimmer Widget Beispiel für Philips Hue<br />
<br />
Minimalvariante<br />
<pre> <br />
<div data-type="dimmer" data-device="HUEDevice1"<br />
data-get-on="!off" data-get-off="off"<br />
data-set="pct"</div><br />
</pre><br />
<br />
Mit Anzeige der Dimstufe<br />
<pre><br />
<div data-type="dimmer" data-device="HUEDevice1"<br />
data-get="onoff"<br />
data-get-on="1" data-get-off="0"<br />
data-set=""<br />
data-set-on="on" data-set-off="off"<br />
data-dim="pct"><br />
</div><br />
</pre><br />
<br />
Dimmer Widget für MilightDevice<br />
<br />
<pre><br />
<div data-type="dimmer"<br />
data-device="SonstWas"<br />
data-get="brightness"<br />
data-get-off="0"<br />
data-get-on="[1-9][0-9]*"<br />
data-set-on="on"<br />
data-set-off="off"<br />
data-dim="dim"<br />
data-min="0"<br />
data-max="100"<br />
></div><br />
</pre><br />
<br />
<br />
<div id="Beispiel_homestatus">'''Homestatus'''</div><br />
<br />
Beispiel rechts im Bild:<br />
<pre><br />
<div data-type="homestatus" data-device='dummy1'<br />
data-get-on='["1","2","3","4"]'<br />
data-alias='["Home","Night","Away","Holiday"]'<br />
data-icons='["fa-home","fa-bed","fa-car","fa-suitcase"]'><br />
</div><br />
</pre><br />
<br />
Beispiel links im Bild:<br />
<pre><br />
<div data-type="homestatus" data-device='dummy1'<br />
data-get-on='["home","asleep","absent","gone","gotosleep"]'<br />
data-alias='["Home","Night","Away","Holiday","Retire"]'<br />
data-icons='["fa-fire","fa-film","fa-plus","fa-car","fa-tint"]'<br />
data-version='residents'><br />
</div><br />
</pre><br />
<br />
[[Datei:homestatus_tabletUI.png]]<br />
<br />
<br />
<br />
<div id="Beispiel_image">'''Image'''</div><br />
<br />
<br />
Erzeugt ein Widget mit einem Bild aus dem www, das alle 5 Sekunden aktualisiert wird (hier eine Wetterkarte vom DWD).<br />
<br />
<pre><br />
<div data-type="image"<br />
data-size="80%"<br />
data-url="http://www.dwd.de/wundk/wetter/de/Deutschland.jpg"<br />
</div><br />
</pre><br />
<br />
[[Datei:image_tabletUI.jpg]]<br />
<br />
<br />
Example for how to add an image to the dashboard which its URL is delivered by a Fhem module like PROPLANTA:<br />
<br />
<pre><br />
<div data-type="image" data-device="Wetter1" <br />
data-get="fc0_weatherDayIcon" <br />
data-size="40px" <br />
class="cell"><br />
</div><br />
</pre><br />
<br />
<br />
<div id="Beispiel_label">'''Label'''</div><br />
<br />
Example for HM-WDS40-TH-I Funk-Temperatur-/Feuchtesensor innen<br />
<br />
<pre><br />
STATE T: 20.0 H: 61<br />
</pre><br />
<pre><br />
<div data-type="label" data-device="THSensorWZ" <br />
data-part="2" data-unit="%B0C%0A" class="cell big"></div><br />
<div data-type="label" class="cell">Temperatur</div><br />
<div data-type="label" data-device="THSensorWZ" data-part="4" <br />
data-unit="%" class="cell big"></div><br />
<div data-type="label" class="cell">Luftfeuchte</div><br />
</pre><br />
<br />
But the same result can reached by getting single readings:<br />
<pre><br />
humidity 58<br />
temperature 20.1<br />
</pre><br />
<br />
<pre><br />
<div data-type="label" data-device="THSensorWZ" <br />
data-get="temperature" data-unit="%B0C%0A" class="cell big"></div><br />
<div data-type="label" class="cell">Temperatur</div><br />
<div data-type="label" data-device="THSensorWZ" <br />
data-get="humidity" data-unit="%" class="cell big"></div><br />
<div data-type="label" class="cell">Luftfeuchte</div><br />
</pre><br />
<br />
Example for how to influence the color of the label according to value limits<br />
<pre><br />
<div data-type="label" <br />
data-device="OutTemp" <br />
data-limits='[-73,10,23]' <br />
data-colors='["#6699FF","#AA6900","#FF0000"]' <br />
data-unit="%B0C%0A" <br />
class="cell big"><br />
</div><br />
</pre><br />
<br />
Example for how to create a widget for shutter via push: show state and set up/down<br />
<pre><br />
<div data-type="switch" <br />
data-device="wzRollo" <br />
data-get-on="up" <br />
data-get-off="down" <br />
data-icon="fa-bars" <br />
class="cell" ><br />
</div><br />
<div data-type="label" <br />
class="cell">Rollo</div><br />
</pre><br />
<br />
Example for how to create a label for a time value in short format with usage of RegEx.<br />
<br />
<pre><br />
<div data-type="label" <br />
data-device="dummy1" <br />
data-part="(\d\d\.\d\d\.).*" <br />
class="cell"><br />
</div><br />
</pre><br />
<br />
Example for how to show two labels in one line.<br />
<br />
<pre><br />
<div class=""><br />
<div type="label" device="OnSunrise" class="inline"></div>bis<br />
<div type="label" device="OnSunset" class="inline"></div><br />
</div><br />
</pre><br />
<br />
Beispiel für die Anzeige des UV-Indexes und der Abhängigkeit der anzuzeigenden Farbe.<br />
<br />
<pre><br />
<div data-type="label" class="wider cell bigger" data-device="ProVorhersage"<br />
data-get="fc0_uv"<br />
data-limits="[-2, 2, 5, 7, 10]" <br />
data-colors='["#66FF33","#FFFF00","#FF6600","#FF0000","#993399"]'></div><br />
<div data-type="label" class="cell" data-device="ProVorhersage" data-get="fc0_date"></div><br />
<div data-type="label" class="wider cell bigger" data-device="ProVorhersage"<br />
data-get="fc1_uv"<br />
data-limits="[-2, 2, 5, 7, 10]"<br />
data-colors='["#66FF33","#FFFF00","#FF6600","#FF0000","#993399"]'></div><br />
<div data-type="label" class="cell" data-device="ProVorhersage" data-get="fc1_date"></div><br />
</pre><br />
<br />
[[Datei:label_tabletUI.jpg]]<br />
<br />
Beispiel für die Anzeige des Labels als Icon.<br />
<pre><br />
<div class="cell"><br />
<div data-type="label" data-device="AvReceiver" data-get="input" class="icon round bg-red cell"></div><br />
<div data-type="label" data-device="AvReceiver" data-get="input" class="icon square bg-blue cell"></div><br />
<div data-type="label" data-device="AvReceiver" data-get="input" class="icon squareborder cell"></div><br />
<div data-type="label" data-device="PowerAV_Sw" data-colors='["red","green"]' data-limits='["off","on"]' class="icon round bg-limit cell"></div><br />
</div><br />
</pre><br />
<br />
[[Datei:Label_tabletUI_icon.png]]<br />
<br />
<div id="Beispiel_pagetab">'''Pagetab'''</div><br />
<br />
Example for a tab menu to switch smoothly between multiple pages. Multiple pagetabs in a template file: menu.html<br />
<br />
<pre><br />
<html><br />
<body><br />
<header>MENU</header><br />
<div class="cell"><br />
<div data-type="pagetab" data-url="index.html" data-icon="fa-home" class="cell"></div><br />
<div data-type="pagetab" data-url="index_2.html" data-icon="fa-sliders" class="cell"></div><br />
<div data-type="pagetab" data-url="index_3.html" data-icon="fa-music" class="cell"></div><br />
<div data-type="pagetab" data-url="index_4.html" data-icon="fa-hotel" class="cell"></div><br />
<div data-type="pagetab" data-url="index_5.html" data-icon="fa-music" class="cell"></div><br />
<div data-type="pagetab" data-url="index_6.html" data-icon="fa-database" class="cell"></div><br />
<div data-type="pagetab" data-url="index_7.html" data-icon="fa-fax" class="cell"></div><br />
</div><br />
</body><br />
</html><br />
</pre><br />
<br />
<br />
<div id="Beispiel_playstream">'''Playstream'''</div><br />
<br />
Erzeugt einen Knopf zum direkten Abspielen eines Webradio-Streams.<br />
<br />
<pre><br />
<div data-type="playstream" data-url="http://radioeins.de/stream"></div><br />
<div data-type="label" class="darker">Radio eins</div><br />
</pre><br />
<br />
<br />
<div id="Beispiel_push">'''Push'''</div><br />
<br />
Example for how to create a push button widget to trigger all devices on:<br />
<br />
<pre><br />
<div data-type="push" <br />
data-device="LightAll" <br />
data-cmd="trigger" <br />
data-set="on" <br />
class="cell"><br />
</div><br />
</pre><br />
<br />
<br />
Beispiel für zwei horizontale Buttons:<br />
<br />
<pre><br />
<div class="cell"><br />
<div class="doublebox-h"><br />
<div data-type="push" data-device="Rollo" <br />
data-icon="fa-angle-up" data-background-icon="fa-square-o" <br />
data-set="up"><br />
</div><br />
<div data-type="push" data-device="Rollo" <br />
data-icon="fa-angle-down" data-background-icon="fa-square-o" <br />
data-set="down"><br />
</div><br />
</div><br />
</div><br />
</pre><br />
<br />
[[Datei:push1.png]]<br />
<br />
<br />
Beispiel für zwei quadratische vertikale Buttons:<br />
<br />
<pre><br />
<div class="cell"><br />
<div class="doublebox-v"><br />
<div data-type="push" data-device="Rollo" <br />
data-icon="fa-chevron-up" data-background-icon="fa-square-o" <br />
data-set="up"><br />
</div><br />
<div data-type="push" data-device="Rollo" <br />
data-icon="fa-chevron-down" data-background-icon="fa-square-o" <br />
data-set="down"><br />
</div><br />
</div><br />
</div><br />
</pre><br />
<br />
[[Datei:push2.png]]<br />
<br />
<br />
<div id="Beispiel_rotor">'''Rotor'''</div><br />
<br />
Example for a rotor widget, which switches between to days of weather forecast<br />
<br />
<pre><br />
<div data-type="rotor" class="fade"><br />
<ul><br />
<li><br />
<div data-type="label" class="darker">Heute</div><br />
<div data-type="weather" data-device="AgroWeather" data-get="fc0_weatherDay" class="big"></div><br />
<div data-type="label" data-device="AgroWeather" data-get="fc0_weatherDay" class=""></div><br />
<div data-type="label" data-device="AgroWeather" data-get="fc0_tempMax" data-unit="%B0C%0A" class="large"></div><br />
</li><br />
<li><br />
<div data-type="label" class="darker">Morgen</div><br />
<div data-type="weather" data-device="AgroWeather" data-get="fc1_weatherDay" class="big"></div><br />
<div data-type="label" data-device="AgroWeather" data-get="fc1_weatherDay" class=""></div><br />
<div data-type="label" data-device="AgroWeather" data-get="fc1_tempMax" data-unit="%B0C%0A" class="large"></div><br />
</li><br />
</ul><br />
</div><br />
</pre><br />
<br />
<br />
<br />
<div id="Beispiel_select">'''Select'''</div><br />
<br />
Erzeugt zwei Comboboxen zur Auswahl des Eingang eines 2-Zonen-AV-Receivers. Die Liste für Zone2 ist fest, die Liste für Zone1 wird von Fhem übergeben.<br />
<br />
<pre><br />
<div class="cell wider"><br />
<div data-type="label" class="inline wider">Zone2</div><br />
<div data-type="select" data-device="AvReceiverZ2" data-items='["Airplay","Webradio","BD/DVD","PHONO"]' data-get="input" data-set="input" class="cell w2x" ></div><br />
<div></div><br />
<div data-type="label" class="inline">Zone1</div><br />
<div data-type="select" data-device="AvReceiver" data-list="inputs" data-get="input" data-set="input" class="cell w2x" ></div><br />
</div><br />
</pre><br />
<br />
[[Datei:select_tabeltUI.png]]<br />
<br />
<br />
<div id="Beispiel_slider">'''Slider'''</div><br />
<br />
<br />
Slider mit einstellbaren Werten von 10 bis 90:<br />
<br />
<pre><br />
<div data-type="slider" <br />
data-device='Dummy1' <br />
data-min="10" <br />
data-max="90" <br />
class="cell" ><br />
</div><br />
<div data-type="label" class="cell">Light1</div><br />
</pre><br />
<br />
[[Datei:slider_tabletUI.png]]<br />
<br />
<br />
Horizontal angeordneter Slider:<br />
<br />
<pre><br />
<div data-type="slider"<br />
data-device='Dummy1' <br />
data-min="0" <br />
data-max="100" <br />
class="horizontal" <br />
</div><br />
</pre><br />
<br />
[[Datei:slider_tabletUI2.jpg]]<br />
<br />
<br />
<div id="Beispiel_switch">'''Switch'''</div><br />
<br />
Schalter. Usage of RegEx pattern for state request:<br />
<br />
<pre><br />
<div data-type="switch" class="cell" <br />
data-device="MILIGHT_Zone1_Wohnzimmer" <br />
data-get-on="on.*"<br />
data-get-off="off"></div><br />
</pre><br />
<br />
[[Datei:switch.png]]<br />
<br />
Beispiel für eine Gruppe von Schaltern, um zwischen vier verschiedenen Werten eines device umzuschalten:<br />
<br />
<pre><br />
<div class="cell left"><br />
<div data-type="switch" data-device="dummy1" <br />
data-get-off="((?!Wert1).)*" <br />
data-get-on="Wert1" class="cell" ></div><br />
<div data-type="label" class="cell">Wert1</div><br />
<div data-type="switch" data-device="dummy1" <br />
data-get-off="((?!Wert2).)*" <br />
data-get-on="Wert2" class="cell" ></div><br />
<div data-type="label" class="cell">Wert2</div><br />
<div data-type="switch" data-device="dummy1" <br />
data-get-off="((?!Wert3).)*" <br />
data-get-on="Wert3" class="cell" ></div><br />
<div data-type="label" class="cell">Wert3</div><br />
<div data-type="switch" data-device="dummy1" <br />
data-get-off="((?!Wert4).)*" <br />
data-get-on="Wert4" class="cell" ></div><br />
<div data-type="label" class="cell">Wert4</div><br />
</div><br />
</pre><br />
<br />
[[Datei:switch4.png]]<br />
<br />
<br />
<div id="Beispiel_symbol">'''Symbol'''</div><br />
<br />
Example for a tristate icon<br />
<br />
<pre><br />
<div data-type="symbol" data-device="dummy1" <br />
data-get-on='["wert1","wert2","wert3"]' <br />
data-icons='["fa-arrow-up","fa-user","fa-arrow-down"]' <br />
data-on-colors='["SeaGreen","SlateBlue","IndianRed"]' <br />
class="cell big"><br />
</div><br />
</pre><br />
<br />
<br />
Example for a tristate icon with blink and spin animation<br />
<br />
<pre><br />
<div data-type="symbol" data-device="dummy1" <br />
data-icons='["fa-exclamation-triangle fa-blink","fa-exclamation-circle","fa-cog fa-spin"]' <br />
data-on-colors='["Crimson","GoldenRod","SeaGreen"]' <br />
data-get-on='["Wert1","Wert2","Wert3"]' ><br />
</div><br />
</pre><br />
<br />
<br />
Example for a battery level control with RegEx<br />
<br />
<pre><br />
<div data-type="symbol" data-device="BadHeizung" data-get="batteryLevel"<br />
data-icons='["oa-measure_battery_100","oa-measure_battery_75","oa-measure_battery_50","oa-measure_battery_25","oa-measure_battery_0"]'<br />
data-get-on='["3\\.[0-9]","2\\.[789]","2\\.[456]","2\\.[123]","((2\\.0)|([01]\\.[0-9]))"]'<br />
data-on-colors='["#505050","#505050","#505050","#ad3333","#ad3333"]'><br />
</div><br />
</pre><br />
<br />
<br />
<br />
Example for a battery level control with greater-equal compare and 90° rotated symbols<br />
<br />
<pre><br />
<div data-type="symbol" data-device="BadHeizung" data-get="batteryLevel"<br />
data-icons='["oa-measure_battery_0 fa-rotate-90","oa-measure_battery_25 fa-rotate-90","oa-measure_battery_50 fa-rotate-90","oa-measure_battery_75 fa-rotate-90","oa-measure_battery_0 fa-rotate-90"]'<br />
data-get-on='["0","2","2.4","2.7","3.0"]'<br />
data-on-colors='["#ad3333","#ad3333","#505050","#505050","#505050"]'><br />
</div><br />
</pre><br />
<br />
<br />
<div id="Beispiel_thermostat">'''Thermostat'''</div><br />
<br />
Configure as data-device='...' that item which delivers temp and desired-temp as reading.<br />
<br />
Default parameters are:<br />
<pre><br />
data-get="desired-temp" data-temp="measured-temp" data-set="desired-temp"<br />
</pre><br />
<br />
Therefor for HomaMatic HM-CC-RT-DN this is sufficient.<br />
<br />
<pre><br />
<div data-type="thermostat" data-device='KH_Clima' class="cell"></div><br />
</pre><br />
<br />
The long format looks like this:<br />
<br />
<pre><br />
<div data-type="thermostat" <br />
data-device="KH_Clima" <br />
data-valve="ValvePosition"<br />
data-get="desired-temp" <br />
data-temp="measured-temp" <br />
class="cell"><br />
</div><br />
</pre><br />
<br />
<br />
Example for MAX!:<br />
<pre><br />
<div data-type="thermostat" data-device="HZ_Tuer" <br />
data-valve="valveposition" <br />
data-get="desiredTemperature" <br />
data-temp="temperature" <br />
data-set="desiredTemperature" <br />
class="cell"><br />
</div><br />
</pre><br />
<br />
The wigets will show the valve value only in case of a valid data-valve attribute. The default for data-valve ist null. That means, a empty data-valve attribute hides the valve label for the widget.<br />
<br />
[[Datei:thermostat.png]]<br />
<br />
<br />
<div id="Beispiel_weather">'''Weather'''</div><br />
<br />
Das Widget fügt ein dem Wetter entsprechendes Bild ein. Die Daten können durch Fhem-Module wie [[PROPLANTA]], [[OPENWEATHER]] und [[Weather]] bereitgestellt werden. <br />
Add 'big' or 'bigger' to CSS class to get a bigger weather icon.<br />
<br />
Beispiel:<br />
<pre><br />
<div data-type="weather" <br />
data-device="Weather" <br />
data-get="fc0_weatherDay" <br />
class="cell big"><br />
</div><br />
</pre><br />
<br />
[[Datei:weather.png]]<br />
<br />
== Icon-Konfiguration ==<br />
<br />
* Eingebaute Icons: Diese haben das ftui-Präfix. Zurzeit sind folgende verfügbar: ftui-window, ftui-door<br />
<br />
* Mehr als 500 Icons von "http://fortawesome.github.io/Font-Awesome/icons" verfügbar. Einfach den Icon-Namen angeben (Präfix "fa-" nicht vergessen, Z.B. <code>data-icon="fa-volume-up"</code><br />
<br />
* Es stehen auch Openautomation Font-Files zur Verfügung. Wer sie nutzen möchte, muss folgende Stylesheets in die index.html hinzufügen.<br />
<pre><br />
<link rel="stylesheet" href="/fhem/tablet/lib/openautomation.css" /><br />
<link rel="stylesheet" href="/fhem/tablet/lib/fhemSVG.css" /><br />
</pre><br />
<br />
Diese font icons haben das Präfix 'fs-' bzw. 'oa-'.<br />
<br />
Beispiel bei einem Schalter:<br />
<pre><div data-type="switch" data-device='dummy1' data-icon="oa-secur_locked"></div></pre><br />
<br />
<br />
Und so als großes Symbol:<br />
<pre><br />
<div data-type="symbol" data-device='dummy1'<br />
data-icon="oa-status_frost"<br />
data-on-color="#bb3232"<br />
data-get-on="on"<br />
data-get-off="!on"<br />
class="bigger"><br />
</div><br />
</pre><br />
<br />
<br />
Die Icons kann man auch etwas dicker darstellen mit den Zusatz bold: <code>data-icon="oa-secur_locked bold"</code><br />
<br />
<br />
Die Namen der verfügbaren Icons findet man auch in den CSS Files (openautomation.css / fhemSVG.css)<br />
<br />
== Spezial ==<br />
Folgender Befehl setzt einen direkten Befehl an Fhem ab (<code>set dummy1 off</code>):<br />
<pre><br />
<div onclick="ftui.setFhemStatus('set dummy1 off')">All off!</div><br />
</pre><br />
<br />
== FAQ ==<br />
Häufig gestellte Fragen zum FHEM Tablet UI sind in der [[FHEM_Tablet_UI/FAQ|FHEM Tablet UI FAQ]] zusammengestellt.<br />
<br />
== Links ==<br />
* [http://forum.fhem.de/index.php/topic,34233.0.html Forums-Beitrag]<br />
* [https://github.com/knowthelist/fhem-tablet-ui Projekt auf Github]<br />
* [http://forum.fhem.de/index.php/topic,37378.0.html User-Demos]<br />
* [https://github.com/ovibox/fhem-ftui-user-demos Download der User-Demo-Dateien]<br />
<br />
[[Kategorie:FHEM Tablet UI]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=ABFALL&diff=18547ABFALL2017-01-18T07:34:52Z<p>Hauswart: /* DOIF */</p>
<hr />
<div>{{Infobox Modul<br />
|ModPurpose=Filtern von (Abfall-)Terminen aus einem Calendar.<br />
|ModType=x<br />
|ModFTopic=48237<br />
|ModForumArea=Codeschnipsel<br />
|ModTechName=57_ABFALL.pm<br />
|ModOwner=Constantin / {{Link2FU|14026|uniqueck}}<br />
}}<br />
<br />
[[ABFALL]] ist ein (inoffizielles, nicht Bestandteil der Distribution) Hilfsmodul, das bestimmte Termine aus einem bestehenden Kalender des Moduls [[Calendar]] in Readings übernimmt. <br />
<br />
== Voraussetzungen ==<br />
Es muss ein Calendar-Objekt definiert sein. Der dabei benutzte Name muss in der Definition des ABFALL-Objekts spezifiziert werden.<br />
Es können auch mehrere Calendar Objekte übergeben werden.<br />
<br />
Sonderzeichen aus dem Namen der Termine, werden entfernt um die Namen der generierten Readings FHEM tauglich zu machen, für die Werte der Readings bleiben diese allerdings erhalten.<br />
<br />
== Anwendung ==<br />
=== Installation ===<br />
Mit folgendem Befehl kann das Modul direkt in den Standard FHEM Update Prozess eingeklinkt werden.<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
Um es nur zu installieren, kann auch einfach nur das Command<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/master/controls_fhemabfall.txt</code><br />
eingegeben werden.<br />
<br />
=== Entwicklungsstrang ===<br />
:<code>update add https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
bzw.<br />
:<code>update all https://raw.githubusercontent.com/uniqueck/fhem-abfall/develop/controls_fhemabfall.txt</code><br />
<br />
=== Define ===<br />
:<code>define <Name> ABFALL <calendarname>,<calendarname2>,...</code><br />
<br />
Erläuterung der Parameter im '''define''':<br />
;<calendarname><br />
:Name des '''Calendar''' Kalenders <br />
<br />
Beispiel:<br />
:<code>define myAbfall ABFALL AbfallGoogleCalender</code><br />
<br />
=== Werte aktualisieren ===<br />
Die Werte aktualisieren sich abhängig vom [[notify]] der entsprechenden Calendar Instanz, welche im define angegeben wurde(n).<br />
<br />
=== Weitere Attribute ===<br />
<br />
{| class="wikitable"<br />
!Attribut<br />
!Werteliste<br />
!Beschreibung<br />
!Default Wert<br />
|-<br />
!align="right" |calendarname_praefix<br />
|0 und 1<br />
|soll der Kalendername als praefix dem Reading vorangestellt werden, sollte bei nur einem Kalender auf 0 gesetzt werden<br />
|1 - praefix wird vorangestellt<br />
|-<br />
!align="right" |abfall_clear_reading_regex<br />
|<br />
|regex zum Entfernen von Anteilen aus dem Termin, dieser wird vor dem Entfernen von Sonderzeichen aus den Namen der Termine angewandt.<br />
|<br />
|-<br />
!align="right" |disable<br />
|0 und 1<br />
|deaktiviert das Modul<br />
|0<br />
|-<br />
!align="right" |weekday_mapping<br />
|<br />
|Mapping, wie die Readings der Tage angezeigt werden sollen, zum Beispiel So Mo Di Mi Do Fr Sa<br />
|Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag<br />
|-<br />
!align="right" |delimiter_text_reading<br />
|<br />
|Wenn zwei Abholungen an ein und demselben Tag existieren, wird dieses Trennzeichen genutzt, um die beiden (oder mehrere) Werte zu einem Text zu verbinden. Nur relevant für die Readings next_text und now_text<br />
|und<br />
|-<br />
!align="right" |delimiter_reading<br />
|<br />
|wie attribute delimiter_text_reading, allerdings nur für die readings next und now<br />
|<br />
|-<br />
!align="right" |filter<br />
|<br />
|regex zum Filtern der Namen der Termine aus den Kalendern, so dass nur solche genutzt werden, welche diesem Filter entsprechen<br />
|<br />
|-<br />
|}<br />
<br />
== Anwendungsbeispiel(e) ==<br />
=== Einbindung ins Tablet UI ===<br />
<pre><div data-device="myABFALL" data-type="symbol" class="bigger warn wider" <br />
data-get="next" data-get-warn=".*(\d+).*" <br />
data-get-on='["Restmuell_.*","Wertstoff_.*"]'<br />
data-on-colors='["#000","#6EB54C"]' <br />
data-icons='["fa-trash-o","fa-trash-o"]'></div></pre><br />
<br />
=== Benachrichtigung ===<br />
==== DOIF ====<br />
<pre>[Abfall:next_tage] == 1) ( set fhemBot message Morgen wird [Abfall:next_text] abgeholt)<br />
[Abfall:now_text] ne "") ( set fhemBot message Heute wird [Abfall:now_text] abgeholt)</pre><br />
<br />
====== Pushbullet Beispiel ======<br />
<br />
Die morgigen Leerungen per Push mittels Pushbullet:<br />
<br />
<code>define dAbfallmorgen doif ([Abfall:next_tage] == 1) ( msg |Morgen wird [Abfall:next_text] abgeholt)</code><br />
<br />
Die heutigen Leerungen per Push mittels Pushbullet:<br />
<br />
<code>define dAbfallheute doif ([Abfall:now_text] ne "") ( msg |Heute wird [Abfall:now_text] abgeholt)</code><br />
<br />
=== Links ===<br />
* Forenthema {{Link2Forum|Topic=50177|LinkText=Abfall Visualisierung mit Bilderrahmen}}</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Anwesenheitserkennung&diff=18532Anwesenheitserkennung2017-01-17T06:56:20Z<p>Hauswart: /* Das PRESENCE Modul */</p>
<hr />
<div>Viele Benutzer führen bereits eine eigene '''Anwesenheitserkennung''' durch. Diese basiert in den meisten Fällen auf Ping Checks oder bei [[AVM Fritz!Box|FritzBoxen]] auf dem Befehl ''ctlmgr_ctl''. Diese Lösungen können aber je nach Aufbau und Funktion FHEM massiv beeinträchtigen. Aufgrund des Aufbaus vom FHEM kann dieses dadurch für mehrere Sekunden zum völligen Stillstand gebracht werden.<br />
<br />
In FHEM gibt es mittlerweile mehrere Module, die eine zuverlässige Anwesenheitserkennung bieten, ohne dabei FHEM bei der Ausführung zu beeinträchtigen.<br />
<br />
Eine erweiterte Funktion der Anwesenheitserkennung ist die Standortverfolgung, die sich nicht nur auf ein oder sehr wenige mit (eigenem) WLAN versorgte Gebiete beschränkt.<br />
<br />
== Vorüberlegungen ==<br />
Generell gibt es mehrere Ansätze um Anwesenheitserkennung mit Handys/Smartphones durchzuführen.<br />
<br />
* via PING Checks im gesamten WLAN<br />
* Aktivitätsprüfung auf einer FritzBox<br />
* Bluetooth Checks in der gesamten Wohnung<br />
* eigene Perl-Funktion<br />
* aktive Benachrichtigung des Smartphones, ausgelöst z.B. über Geo-Lokation/Geofence<br />
<br />
Dabei gilt bei der Auswahl der Art darauf zu achten wie sich das jeweilige Device verhält. Aufgrund der Vielfältigkeit kann man hier keine allgemeine Vorgehensweise empfehlen. Als einfacher Start (zumindest für Nicht-Apfel Telefone) eignet sich die Ping-Überprüfung und die FritzBox-Abfrage sehr gut.<br />
<br />
=== Randbedingungen ===<br />
Es gibt Geräte, die ihr WLAN/Bluetooth auch im Standby ständig aktiv haben und auf Anfragen antworten können (fast alle Android-Geräte). Gerade bei Tests über WLAN kann sich das aber signifikant auf die Akku Leistung auswirken.<br />
<br />
Andere Geräte wiederum schalten WLAN im Standby Betrieb aus, um Akkukapazität zu sparen. Bluetooth hingegen bleibt weiterhin aktiviert und kann auf Anfragen reagieren. (iPhone)<br />
<br />
Wenn man bei einem iPhone die Funktion "über WLAN synchronisieren" aktiviert hat, so ist dies auch im Standby jederzeit pingbar, wenn der Recher auf dem iTunes zum synchroniseren läuft auch an ist. Ansonsten ist bei iPhone Geräten nur die Aktivitätsprüfung mit einer FritzBox oder das überwachen der DHCP Lease auf einer Airport Basestation wirklich zuverlässig.<br />
<br />
Auch wenn Bluetooth aktiviert ist, so bleiben einige Mobiltelefone erst dann empfangsbereit, wenn sie bereits zu irgend einem Bluetoothgerät gekoppelt wurden. Sind diese Geräte noch nie gekoppelt worden, deaktivieren diese ihren Bluetooth Empfänger beim verlassen des Bluetooth-Menüs im Gerät (iPhone).<br />
<br />
Hier gilt es vor allem auszuprobieren, wie stark der Akku durch eine Anwesenheitserkennung belastet wird. Entscheidend ist hier, in welchem Abstand man eine Anwesenheitserkennung durchführt. Viele Abfragen wirken sich stärker auf den Akku aus als wenige. Wenige Abfragen bieten aber keine zuverlässige und zeitnahe Erkennung.<br />
<br />
Als Alternative, unabhängig vom WLAN und der Erkennung, ob ein Gerät dort eingebucht ist oder nicht, bzw. unabhängig von Bluetooth kann zumindest bei einem iPhone die seit iOS 7 nochmals stark verbesserte Geo-Lokation (Geofencing) genutzt werden. Die iPhone Apps [http://geofency.com/ Geofency] oder [http://geofancy.com/ Geofancy] werden über das FHEM-Modul GEOFANCY angebunden und übertragen ihren Status immer dann, wenn ein definierter Standort betreten oder verlassen wird. Gekoppelt mit entsprechenden Notify und/oder Watchdog Kommandos ist so ebenfalls eine sehr zuverlässige Anwesenheitserkennung möglich (und das nicht nur für das eigene Zuhause).<br />
<br />
== Das PRESENCE Modul ==<br />
Das [[PRESENCE]] Modul bietet für die Anwesenheitserkennung mehrere Varianten an. Diese sind aktuell folgende:<br />
<br />
* '''lan-ping''' - Das Überwachen via PING Checks, die durch den FHEM Server versandt werden.<br />
* '''fritzbox''' - Das Überwachen von Geräten auf einer FritzBox via ctlmgr_ctl (Nur auf einer FritzBox möglich)<br />
* '''local-bluetooth''' - Das Überwachen via Bluetooth Checks, die vom FHEM Server direkt durchgeführt werden (angeschlossener Bluetooth-Stick und die Software bluez voraussgesetzt)<br />
* '''lan-bluetooth''' - Das Überwachen von Bluetoothgeräte, über Netzwerk. Auf einer oder mehreren Maschinen im Netzwerk (z.B. [[:Kategorie:Raspberry Pi|Raspberry Pi]]) läuft ein Presence-Daemon, der nach Bluetooth-Geräten sucht. Um mehrere Presence-Daemon mit FHEM zu verbinden, gibt es den Collector-Daemon, der sich zu allen Presence-Damons im Netzwerk verbindet und das Ergebnis von allen zusammenfasst.<br />
* '''function''' - Das Überwachen mithilfe einer selbst geschrieben Perl-Funktion, die den Anwesenheitsstatus zurückgibt (0 oder 1)<br />
* '''shell-script''' - Das Überwachen mithilfe eines selbst geschriebenen Shell-Programms/Skript, das eine 0 oder 1 ausgibt, um den Anwesenheitsstatus mitzuteilen.<br />
<br />
=== Ping-Überwachung von Geräten im WLAN/LAN ===<br />
{{Randnotiz|RNText=Um diese Methode auf einer FritzBox nutzen zu können, muss FHEM mit root-Rechten laufen. Dies ist standardmäßig nicht der Fall. Bitte dazu den Wiki Artikel [[FritzBox: fhem unter root starten]] beachten.}}<br />
Um ein Gerät via Ping zu überwachen, muss folgende Definition durchgeführt werden:<br />
:<code>define Handy PRESENCE lan-ping 192.168.0.30</code><br />
<br />
Dadurch wird die IP-Addresse 192.168.0.30 alle 30&nbsp;Sekunden geprüft, ob sie erreichbar ist. Wenn sie erreichbar ist, ist der Status "present" (anwesend), ansonsten "absent" (abwesend).<br />
<br />
Der Timeout kann verändert werden, indem ein Wert (in Sekunden) an das Define anhängt wird:<br />
:<code>define Handy PRESENCE lan-ping 192.168.0.30 '''60'''</code><br />
<br />
Nun würde das Handy alle 60 Sekunden geprüft werden.<br />
<br />
Nur wenn bei einem iPhone/iPad die Funktion "über WLAN synchronisieren" aktiviert ist, ist es auch im Standby zuverlässig pingbar. Standardmäßig deaktivieren Apple-Geräte ihr WLAN im Standby-Betrieb um die Akkulaufzeit zu verlängern.<br />
<br />
Sollte die Fehlermeldung <br />
:<code> PRESENCE (Handy) - ping command returned with output: ping: icmp open socket: Operation not permitted </code> <br />
im Log auftauchen und lan-ping dadurch nicht funktionieren, liegt ein Berechtigungsproblem vor. Kein Grund den User fhem zu root zu machen!<br />
So sollten die Berechtigungen aussehen<br />
:<code>sudo ls -la /bin/ping</code><br />
unter Jessie<br />
:<code>-rwxr-xr-x 1 root root 38844 Feb 12 2014 /bin/ping</code><br />
unter Wheezy<br />
:<code>-rwsr-xr-x 1 root root 33220 Mär 30 2012 /bin/ping</code><br />
Sollte es trotzdem unter Jessie nicht funktionieren kann man auch dort die Berechtigung analog wheezy setzen:<br />
:<code>sudo chmod u+s /bin/ping</code><br />
<br />
=== FritzBox: direktes Abfragen der Aktivität via ctlmgr_ctl ===<br />
{{Randnotiz|RNText=Um diese Methode auf einer FritzBox nutzen zu können, muss FHEM mit root-Rechten laufen. Dies ist standardmäßig nicht der Fall. Bitte dazu den Wiki Artikel [[FritzBox: fhem unter root starten]] beachten.}}<br />
Eine sehr häufige und auch zuverlässige Methode ist auf einer FritzBox die Abfrage mittels ctlmgr_ctl Befehl. Über diesen lassen sich alle Geräte abfragen ob sie aktiv sind. Ist ein Gerät aktiv, so gilt es als anwesend.<br />
<br />
Dieser Modus kann allerdings nur in FHEM Installationen direkt auf einer FritzBox verwendet werden. Des weiteren muss FHEM unter dem User root laufen. Um ein Gerät zu überwachen, wird lediglich der Gerätename benötigt, so wie er unter dem Menüpunkt "Heimnetz" auftaucht. <br />
<br />
Die erforderliche Definition:<br />
:<code>define Handy PRESENCE fritzbox iPhone-4S</code><br />
<br />
=== Bluetooth-Überwachung von Geräten durch den FHEM Server ===<br />
[[Datei:Bluetooth-Adresse-iPhone.png|thumb|Bluetooth-Adresse eines iPhones]]<br />
Jenach Aufstellungsort des FHEM Servers kann es sinnvoll sein, eine Bluetooth-Überwachung direkt durch den FHEM Server durchzuführen. Hierbei gilt allerdings zu beachten, dass Bluetooth nicht für große Reichweiten gedacht ist und in den meisten Fällen keine Wände überwinden kann. Das heisst, dass in den meisten Fällen damit nur ein Raum überwacht werden kann.<br />
<br />
Je nach Einsatzzweck kann das auch so gewollt sein. Bluetooth USB Sticks, die bereits Bluetooth 4.0 unterstützen, können höhere Reichweiten über Zimmerwände hinaus erreichen. Vorausgesetzt, das Mobilgerät unterstützt Bluetooth 4.0.<br />
<br />
Um eine Überwachung per Bluetooth durchführen zu können, benötigt man die Bluetooth-Adresse eines Gerätes. Diese ähnelt vom Aufbau einer MAC-Adresse. Generell wird die Adresse in den Telefon-Informationen bei Smartphones angezeigt.<br />
<br />
Um eine Anwesenheitserkennung via Bluetooth durchzuführen, wird folgende Definition in der [[Konfiguration]] benötigt:<br />
:<code>define Handy PRESENCE local-bluetooth XX:XX:XX:XX:XX:XX</code><br />
<br />
=== Bluetooth-Überwachung von Geräten durch verteilte Agenten in der Wohnung (presencd/collectord) ===<br />
[[Datei:Raspberry-Pi-mit-WLAN-und-Bluetooth-Stick.jpg|thumb|left|Raspberry Pi mit Bluetooth- und WLAN-USB-Stick]]<br />
Um eine zuverlässige und flächendeckende Bluetooth-Anwesenheitserkennung durchzuführen, ist es unerlässlich, mehrere Bluetooth-Empfänger zu verwenden, die auf mehrere oder alle Räume verteilt sind.<br />
<br />
Hierfür bietet sich zum Beispiel ein [[Raspberry Pi]] mit einem Mini-Bluetooth-USB-Stick und evtl. einem WLAN-USB-Stick an. Jeder Raum wird mit solch einem Raspberry ausgestattet und ist im WLAN Netz verfügbar.<br />
<br />
Dieses Netz aus Raspberrys wird mit dem presenced (Download-Link ist in der [http://fhem.de/commandref_DE.html#PRESENCE Commandref] zum Modul enthalten) ausgestattet. Es stehen bereits entsprechende Pakete für den Raspberry zur Verfügung.<br />
<br />
Beide Programme (presenced/collectord) sind Perl-Skripte, die als Daemon im Hintergrund laufen und auf Anfragen via Netzwerk warten. Es wird lediglich eine vollständige Perl-Grundinstallation mit Standardmodulen benötigt. Nach Installation der *.deb Pakete sollten diese noch angewiesen werden, automatisch beim Rechner-Neustart gestartet zu werden:<br />
<br />
<pre><br />
sudo update-rc.d presenced defaults<br />
sudo update-rc.d collectord defaults<br />
</pre><br />
<br />
Eine detaillierte Benutzung von presenced ist in der [http://fhem.de/commandref_DE.html#PRESENCE Commandref] Beschreibung zum PRESENCE Modul enthalten.<br />
<br />
==== Jeden Raum einzeln ansprechen (presenced) ====<br />
Nun kann zuallererst jeder Raum einzeln angesprochen werden. Dabei ist zu beachten, dass pro Definition in der Konfiguration nur ein Gerät in einem Raum spezifisch überwacht werden kann.<br />
<br />
Eine Definition sieht dabei folgendermaßen aus:<br />
:<code>define Handy_Wohnzimmer PRESENCE lan-bluetooth XX:XX:XX:XX:XX:XX 192.168.0.10:5111</code><br />
<br />
Damit wird nun das Gerät nur im Wohnzimmer (Raspberry mit IP 192.168.0.10) überwacht.<br />
<br />
==== Alle Räume gemeinsam ansprechen (collectord) ====<br />
Um jedoch alle Räume gemeinsam zu verwenden, gibt es den Collector-Daemon. Dieser kennt alle presenced-Installationen im Netzwerk und führt eine koordinierte Suche nach den gewünschten Geräten durch. Sobald ein Gerät in einem Raum erkannt wurde, meldet der collectord den Status einschließlich der Angabe des Raumes, in dem das Gerät erkannt wurde.<br />
<br />
Um alle Räume zu kennen, müssen diese mit einem Config-File dem collectord mitgeteilt werden. Dieses sieht folgendermaßen aus:<br />
<br />
<pre><br />
[Schlafzimmer] # Name des Raumes (wird in FHEM als Reading angezeigt)<br />
address=192.168.179.31 # IP-Adresse oder Hostname des presenced<br />
port=5111 # TCP Port, der verwendet werden soll (standardmäßig Port 5111)<br />
presence_timeout=120 # Prüfinterval, das verwendet werden soll, wenn ein Gerät anwesend ist<br />
absence_timeout=20 # Prüfinterval, das verwendet werden soll, wenn ein Gerät abwesend ist<br />
<br />
[Wohnzimmer]<br />
address=192.168.179.34<br />
port=5111<br />
presence_timeout=180<br />
absence_timeout=20<br />
</pre><br />
<br />
Standardmäßig ist dieses Config-File unter /etc/collectord.conf zu finden. Mit dieser Konfiguration kann der Collectord gestartet werden. Es empfiehlt sich diesen mit auf dem FHEM Server zu betreiben. Die erforderliche Definition in der Fhem-Konfiguration:<br />
:<code>define Handy PRESENCE lan-bluetooth XX:XX:XX:XX:XX:XX 127.0.0.1:5222</code><br />
<br />
Sobald das Handy irgendwo in der Wohnung erkannt wurde, meldet der Collectord dies sofort an FHEM und teilt den Raum mit.<br />
<br />
Eine detaillierte Benutzung von collectord findet man in der [http://fhem.de/commandref.html#PRESENCE Commandref zum PRESENCE Modul].<br />
<br />
=== Überwachung von Geräten mit Perl-Code ===<br />
Es ist möglich zum Überwachen von Geräten eine eigene Perl-Funktion zu verwenden die dann vom PRESENCE Modul im Hintergrund aufgerufen wird.<br />
<br />
define <name> PRESENCE function {...} [ <check-interval> [ <present-check-interval> ] ]<br />
<br />
Sobald die Funktion den Rückgabewert 1 hat, ist das Gerät anwesend, bei 0 abwesend.<br />
<br />
==== Beispiel DHCP Überwachung auf Airport Basestation ====<br />
Die hier vorgestellte Überwachung der DHCP Lease auf Airport Basestations per SNMP ist absolut robust gegenüber dem Ruhezustand von iOS und setzt keine weitere Konfiguration auf dem iPhone voraus. Das Abmelden beim Verlassen des Empfangsbereiches der Basestation geschieht mit etwa 5-10 Minuten Verzögerung und ist somit auch vor kurzzeitigen Empfangsproblemen sicher. Das nebenstehende Bild (???) verdeutlicht noch mal die Unterschiede zwischen einer IP-Basierten Ping-Überwachung und der Überwachung auf Ebene der Basestation oder FritzBox.<br />
<br />
Bevor der folgende Code verwendet werden kann ist das Perl Modul Net:SNMP zu installieren (z.&nbsp;B. mit: <code>cpan install use Net::SNMP</code>).<br />
<br />
Zuerst ist folgender Code in 99_myUtils.pl einzufügen:<br />
<br />
<pre><br />
use Net::SNMP;<br />
sub<br />
snmpCheck($$)<br />
{<br />
my ($airport,$client)= @_;<br />
<br />
my $community = "public";<br />
my $host = $airport;<br />
my $oid = ".1.3.6.1.2.1.3.1.1.2";<br />
#my $oid = ".1.3.6.1.2.1.3.1.1.2.25.1.10.0.1";<br />
<br />
my ( $session, $error ) = Net::SNMP->session(<br />
-hostname => $host,<br />
-community => $community,<br />
-port => 161,<br />
-version => 1<br />
);<br />
<br />
if( !defined($session) ) {<br />
return 0;<br />
return "Can't connect to host $host.";<br />
}<br />
<br />
my @snmpoids = ();<br />
<br />
my $response = $session->get_next_request($oid);<br />
my @nextid = keys %$response;<br />
while ( @nextid && $nextid[0] && $nextid[0] =~ m/^$oid/ ) {<br />
push( @snmpoids, $nextid[0] );<br />
<br />
$response = $session->get_next_request( $nextid[0] );<br />
@nextid = keys %$response;<br />
}<br />
<br />
if( !defined($response = $session->get_request( @snmpoids ) ) ) {<br />
return 0;<br />
}<br />
<br />
foreach my $value (values %$response) {<br />
return 1 if( $value eq $client )<br />
}<br />
<br />
return 0;<br />
}<br />
</pre><br />
<br />
Danach lässt sich das Mobilgerät so überwachen:<br />
:<code>define iPhone PRESENCE function {snmpCheck("10.0.1.1","0x44d77429f35c")} 30 30</code><br />
<br />
wobei 10.0.1.1 durch die IP-Adresse der Basestation und 0x44d77429f35c durch die MAC Adresse des Geräts als HEX-Zahl ersetzt werden muss.<br />
<br />
==== Beispiel Anwesenheitserkennung mittels UniFi Controller ====<br />
<br />
Die Anwesenheitserkennung bei Geräten in Verbindung mit UniFi-Produkten funktioniert selbst dann, wenn sich die Geräte im PowerSave-Modus befinden. <br />
<br />
Beachte: Die Geräte werden erst ungefähr nach 5 Minuten, nachdem das Gerät das WLAN verlassen hat als disconnected angezeigt.<br />
<br />
<code>define <NAME> PRESENCE function {ReadingsVal("<UniFi>","<NamedDevice>","") eq "connected" ? 1:0}</code><br />
<br />
=== Eventbasierte Anwesenheitserkennung am Beispiel mittels UniFi Controller ===<br />
Der Vorteil gegenüber der Function-Variante ist, dass diese Variante ohne Blocking.pm-Overhead direkt ausgeführt werden kann und in "Echtzeit" abläuft.[https://forum.fhem.de/index.php/topic,40287.msg562823.html#msg562823]<br />
<br />
<code>define <NAME> PRESENCE event UniFi:NamedDevice:.disconnected UniFi:NamedDevice:.connected</code><br />
<br />
== Das GEOFANCY Modul ==<br />
Das Modul ermöglicht über einen sogenannten Webhook Mechanismus (umgangssprachlich oft auch als "Push" benannt) das aktive Melden des aktuellen Standortes. Die iPhone Apps [http://geofency.com/ Geofency] und [http://geofancy.com/ Geofancy] können dann aktiv und quasi in dem Moment, wo man den Wohnbereich betritt oder verlässt, benachrichtigen. Android Nutzern können [https://play.google.com/store/apps/details?id=de.egi.geofence.geozone&hl=de EgiGeoZone Geofence] nutzen. Das geht nochmals um einiges schneller, als die Erkennung im WLAN, bei der die Anwesenheit nur in (engen) Zyklen aktiv geprüft werden muss. Gleichzeitig werden Ressourcen in FHEM geschont. Die aktuelle Implementierung im iPhone 5S mit dediziert für das Tracking zuständigem Chip ist so gut, dass der Akku ebenfalls sehr geschont wird.<br />
<br />
=== Modul in FHEM einrichten ===<br />
Das Modul ist mit einer einfachen Definition sofort betriebsbereit:<br />
:<code>define geofancy GEOFANCY geo</code><br />
<br />
Damit nimmt FHEM unter <nowiki>http://192.168.178.1:8083/fhem/geo</nowiki> entsprechende Meldungen des iPhones entgegen. Damit das nicht nur über das lokale WLAN funktioniert, bedarf es allerdings noch einiger zusätzlicher Maßnahmen. FHEM muss vom Internet erreichbar gemacht werden, dabei sollte unbedingt an die Absicherung des Zugriffs gedacht werden.<br />
<br />
Zunächst einmal habe ich bei mir eine eigene FHEMWEB Instanz dafür angelegt:<br />
<pre><br />
define WEBhook FHEMWEB 8088 global<br />
attr WEBhook column Alarms: Apartment: Living: Bedroom: Kitchen: Sonos: Residents: Weather: Bathroom: Logs: Statistics: DashboardRoom: System: hidden: all:<br />
attr WEBhook hiddenroom input,detail,save,Unsorted,Everything,CUL_HM,FS20,Commandref,style,Edit files,Select style,Logfile,Floorplans,Remote doc,FileLogs,Apartment,Bathroom,Bedroom,Kitchen,Living,Residents,System,Weather,Event monitor,NEW<br />
attr WEBhook room hidden<br />
attr WEBhook webname webhook<br />
</pre><br />
<br />
Damit ist unter der URL <nowiki>http://192.168.178.1:8088/webhook/geo</nowiki> das GEOFANCY Modul erreichbar. Ich verstecke in dieser Ansicht noch alle Räume, die ich so habe. Wer die Raumnamen allerdings kennt, kann sie trotzdem aufrufen. Die Anzeige in den Räumen kann man mit dem Attribut column und entsprechend leeren Definitionen verstecken. Nun muss man explizit den Devicenamen kennen, um noch etwas über die Konfiguration in Erfahrung bringen zu können.<br />
Auch wenn das Security-by-Obscurity ist - ich fühle mich wohler damit.<br />
<br />
=== Webhook weiter absichern ===<br />
Mit Hilfe eines [http://fhem.de/commandref.html#allowed allowed]-Devices lässt sich die FHEMWEB Instanz noch weiter absichern indem nur die tatsächlich benötigten Kommandos erlaubt werden (in diesem Fall keine) und damit alle anderen nicht erlaubten (attr,define,get,set,...) automatisch nicht mehr zur Verfügung stehen: <br />
<pre><br />
define allowedWEBhook allowed<br />
attr allowedWEBhook allowedCommands ,<br />
attr allowedWEBhook allowedDevices ,<br />
attr allowedWEBhook validFor WEBhook<br />
</pre><br />
<br />
Außerdem ist dringend zu empfehlen, den Zugriff über TLS/SSL und HTTP Basic-Authentication weiter abzusichern. Läuft FHEM auf einem Raspberry&nbsp;Pi, dann empfehle ich dazu die Konfiguration eines ReverseProxy (vorzugsweise HAproxy, Pound oder Varnish, notfalls auch Nginx oder Apache); damit ist man am flexibelsten und kann auch alle FHEMWEB Instanzen direkt über einen einzigen Port (meist 443, der HTTPS Standard Port) zusammenfassen. Ich möchte hier allerdings beschreiben, wie weit man mit FHEM Bordmitteln kommt und nehme das Beispiel einer Installation auf einer Fritzbox.<br />
<br />
Wie TLS aktiviert wird, steht in der Commandref für [[FHEMWEB]]. Um die Kommandos auf der Fritzbox ausführen zu können, muss zuerst Telnet aktiviert werden (bitte Google benutzen). Anschließend wechselt man auf der Fritzbox ins Verzeichnis /var/media/ftp/fhem und kann dann den Hinweisen aus der [http://fhem.de/commandref.html#FHEMWEB Commandref] unter dem Punkt HTTPS folgen. Letztlich fehlt noch das entsprechende Attribut:<br />
<br />
<pre><br />
attr WEBhook HTTPS<br />
</pre><br />
<br />
Als nächstes aktivieren wir Benutzername+Passwort für den Zugriff. Die commandref für allowed gibt auch hier unter dem Punkt basicAuth entsprechende Hinweise. Wir fügen hier einfach mal einen Benutzer "webhook" mit dem Passwort "Geofancy" hinzu, das sieht dann so aus:<br />
<br />
<pre><br />
attr allowedWEBhook basicAuth { "$user:$password" eq "webhook:Geofancy" }<br />
</pre><br />
<br />
Weitere Infos zur Absicherung gibt auch [[FritzBox Webzugriff absichern]].<br />
<br />
Um zu testen, ob unsere Absicherung erfolgreich war, kann man die URL <nowiki>https://192.168.178.1:8088/webhook/geo</nowiki> aufrufen (wichtig ist, dass man jetzt https und nicht mehr http eingibt; ansonsten bekommt man keine Antwort). Eine Zertifikatswarnung kann getrost ignoriert werden, verschlüsselt wird trotzdem. Es sollte auch eine Passwort Abfrage kommen und die Eingabe der entsprechenden Daten sollte dann zu einer entsprechenden Meldung vom GEOFANCY Modul führen:<br />
<br />
<pre><br />
NOK No data received, see API information on http://wiki.geofancy.com<br />
</pre><br />
<br />
Das ist ok, schließlich sind wir keine App, sondern der Mensch, der nur mal eben prüfen will :-)<br />
<br />
=== Zugriff vom Internet ermöglichen ===<br />
Das ist je nach Fritzbox und Software Version unterschiedlich. Grundsätzlich gilt: Eine Weiterleitung des ports 8088 vom Internet auf das laufende FHEM auf Port 8088 intern ist von AVM so nicht vorgesehen.<br />
Bei mir führte folgendes zum Erfolg:<br />
<br />
* Einloggen per Telnet auf der Fritzbox (ich habe FritzOS 6 installiert)<br />
* Konfiguration editieren mittels "nvi /var/flash/ar7.cfg"<br />
* Suchen nach richtiger Zeile durch Eingabe von "/internet_forwardrules" und Enter<br />
* Hinzufügen einer weiteren Zeile (Vorsicht, die bestehende Zeile endet mit ; und das muss in , umgeändert werden, so dass das ; schließlich am Ende der Zeile steht.<br />
<br />
So sieht es bei mir vorher aus:<br />
:<code>internet_forwardrules = "tcp 0.0.0.0:488 0.0.0.0:488 0";</code><br />
Hinterher:<br />
:<code>internet_forwardrules = "tcp 0.0.0.0:488 0.0.0.0:488 0", "tcp 0.0.0.0:8088 0.0.0.0:8088 0";</code><br />
<br />
Danach mittels ":x" abspeichern und sofort per "reboot" die Box neu starten, um diese Änderungen zu aktivieren. Das ist wichtig; ansonsten zeigt die Erfahrung, dass die Änderung nicht dauerhaft erhalten bleibt und die gerade gemachten Änderungen verloren gehen.<br />
<br />
Wer die Einstellungen zu "internet_forwardrules" bei sich nicht finden kann, hat womöglich eine andere Version als ich oder ein leicht anderes Gerät und bemüht am besten Google, was er tun kann, um das Gleiche zu erreichen. Möglicherweise tauchen die Einträge auch erst auf, wenn man mal über das Webinterface ein Forwarding eingerichtet hatte.<br />
<br />
Hat man einen DynDNS Dienst oder myFritz auf der Fritzbox aktiviert, so kann man jetzt auch von draußen auf den Webhook zugreifen. Das kann man prüfen, indem man das iPhone aus dem WLAN ausbucht und einmal die externe Adresse eingibt, also z.B. https://meindyndns.org:8088/webhook/geo.<br />
<br />
=== Weitere Alternativen für den Zugriff aus dem Internet ===<br />
Als Alternative zum Port Forwarding kann man sich auch per VPN in das lokale Netzwerk einwählen. iOS bietet dazu auch eine automatische Aktivierung des VPN (VPN on Demand), wie z.B. [http://forum.loxone.com/dede/netzwerk-firewall-and-security/8121-vpn-demand-ios-8-1-1-fritz-box-kleine-how.html hier] beschrieben wird.<br />
<br />
Auch eine Alternative ist, das Portforwarding nicht direkt an FHEM einzurichten, sondern an einem im Netzwerk laufenden Reverse-Proxy, der dann seinerseits die Anfragen an FHEM weiterleitet. Dies kann z.B. Apache, Nginx oder am besten HAproxy sein.<br />
Letzterer ist dabei sehr flexibel, allerdings nicht unbedingt einfach zu konfigurieren. Ein paar Inspirationen diesbezüglich gibt es z.B. [https://github.com/Hoanoho/HSE/tree/develop/lib/cfg/any/stat/etc/haproxy hier] und [https://github.com/Hoanoho/HSE/tree/develop/lib/cfg/any/dyn/etc/haproxy hier]. Wer pfSense nutzt, findet [http://loredo.me/post/116633549315/geeking-out-with-haproxy-on-pfsense-the-ultimate diesen Artikel] womöglich auch interessant. Er zeigt auch, dass mit HAproxy noch weit mehr möglich ist.<br />
Der Reverse-Proxy sollte dabei auch unbedingt der TLS Termination Point sein (TLS Offloading). Nicht nur spart man sich dann die Aktivierung von TLS in FHEM, sondern man hat auch mehr Einfluss darauf, wie TLS arbeitet (z.B. Deaktivierung von SSLv3, forcieren von TLSv1.2, nur als sicher eingestufte Cipher Suite... siehe auch Infos auf der [https://wiki.mozilla.org/Security/Server_Side_TLS Mozilla Website]).<br />
<br />
=== Einrichten in der Geof[e|a]ncy.app ===<br />
Hat das alles soweit geklappt, können endlich in der Geofency.app bzw. Geofancy.app am iPhone die gewünschten Bereiche definiert werden. Am Besten zuvor in den Global Settings die folgenden Einstellungen hinterlegen:<br />
<br />
* URL: https://meindyndns.org:8088/webhook/geo<br />
* POST (oder GET, ist egal - das FHEM Modul kann beides)<br />
* HTTP Basic Authentication: EIN (entsprechend Username und Password eintragen)<br />
<br />
Anfänglich ist es empfehlenswert noch "Notification on success" und "Notification on Failure" einzuschalten. Ersteres kann man ausmachen wenn man weiß, dass es soweit funktioniert. Über "Send Test-Request" kann man einmal einen Test schicken und erhält das Ergebnis entsprechend dargestellt. Es sollte sowas kommen wie<br />
:<code>POST Success: test OK</code>. In Geofancy.app gibt es keine Rückmeldung über den Erfolg des Testrequests. In FHEM sollten sich durch den Testrequest jedoch die Readings sofort aktualisieren (Ggf. ist ein Reload der FHEMWEB-Seite nötig da zusätzliche Tabellenzeilen nicht via Longpoll ergänzt werden). <br />
<br />
Funktioniert das soweit, kann man eine neue Lokation als sein Zuhause anlegen. Es empfiehlt sich einen ID-Namen zu setzen; dieser ist dann in FHEM als Name für die Lokation sichtbar. Für die eigene Wohnung empfiehlt sich hier "home" (da dies auch direkt vom RESIDENTS Modul so verwendet werden kann). Man kann auch Trigger für andere Standorte anlegen. FHEM weiß dann sogar, wenn ihr im Büro seid und könnte sich dabei auch unterschiedlich verhalten, als wenn ihr "auf Achse" seid. Bei letzterem ist der Status im GEOFANCY Modul "underway", was so viel heißt wie "unbekannter Aufenthaltsort".<br />
<br />
Hinweis: Zumindest für Geofancy.app liefert ein Testrequest wohl zufällige Locations zurück. Die eigenen Location-IDs werden also nicht übergeben, selbst wenn man sich in einem Geofence befindet. Um zu testen muss man sich wohl oder übel selbst bewegen ;-).<br />
<br />
=== GEOFANCY Modul individualisieren ===<br />
Die im GEOFANCY Modul dargestellten Readings sind nun in etwa so, wenn ihr euch bewegt:<br />
<br />
<pre><br />
Readings:<br />
2014-01-18 14:37:42 lastDevice -<br />
2014-01-18 14:37:42 lastDeviceUUID 51F23894-AAAA-BBBB-CCCC-0123456789AB<br />
2014-01-18 14:37:42 state dev:51F23894-AAAA-BBBB-CCCC-0123456789AB trig:test id:home lat:48.9999 long:11.9999<br />
</pre><br />
<br />
Wer genauer hinschaut sieht: Mein iPhone heißt wohl 51F23894-AAAA-BBBB-CCCC-0123456789AB.<br />
Damit nun die Readings für mein iPhone richtig angelegt werden, muss ein Device Alias gesetzt werden. Sinnvoll erscheint mir der Vorname des Besitzers:<br />
:<code>attr geofancy devAlias 51F23894-AAAA-BBBB-CCCC-0123456789AB:Julian</code><br />
<br />
Weitere Alias-Namen können mit Leerzeichen einfach angehängt werden.<br />
Jetzt werden weitere Readings angelegt, sobald GEOFANCY entsprechende Daten vom Mobilgerät empfängt:<br />
<br />
<pre><br />
Readings:<br />
2014-01-18 14:37:42 Julian arrived home<br />
2014-01-18 14:37:42 currLocLat_Julian 48.9999<br />
2014-01-18 14:37:42 currLocLong_Julian 11.9999<br />
2014-01-18 14:37:42 currLocTime_Julian 2014-01-18 14:37:42<br />
2014-01-18 14:37:42 currLoc_Julian home<br />
2014-01-17 19:18:23 lastArr Julian home<br />
2014-01-17 18:41:46 lastDep Julian Office<br />
2014-01-18 14:37:42 lastDevice Julian<br />
2014-01-18 14:37:42 lastDeviceUUID 51F23894-AAAA-BBBB-CCCC-0123456789AB<br />
2014-01-17 18:41:46 lastLocArr_Julian 2014-01-17 08:58:37<br />
2014-01-17 18:41:46 lastLocDep_Julian 2014-01-17 18:41:46<br />
2014-01-17 18:41:46 lastLocLat_Julian 48.1111<br />
2014-01-17 18:41:46 lastLocLong_Julian 11.1111<br />
2014-01-17 18:41:46 lastLoc_Julian Office<br />
2014-01-18 14:37:42 state dev:Julian trig:test id:home lat:48.9999 long:11.9999<br />
</pre><br />
<br />
Möchte man nun etwas bestimmtes tun, wenn man nach Hause kommt oder das Heim verlässt, kann man am Besten ein entsprechendes Notify auf das Reading currLoc_Name setzen. Ich aktualisiere lediglich zwei Dummies, durch die dann alle weiteren Notifies ausgelöst werden:<br />
<br />
<pre><br />
define n_Julian.Presence notify geofancy:currLoc_Julian:.home set Julian.homestatus:FILTER=STATE!=home home<br />
attr n_Julian.Presence room Residents<br />
define n_Julian.absence notify geofancy:currLoc_Julian:.underway {\<br />
if (Value("Julian.homestatus") ne "gone") {\<br />
fhem("set Julian.homestatus:FILTER=STATE!=absent absent");;\<br />
}\<br />
}<br />
define n_Julian.whereabout notify geofancy:currLoc_Julian:.* set Julian.whereabout:FILTER=STATE!=$EVTPART1 $EVTPART1<br />
</pre><br />
<br />
Wer es noch einfacher möchte (bzw. auch noch mehr Features) schaut sich einmal die neue Modulfamilie aus RESIDENTS[http://fhem.de/commandref_DE.html#RESIDENTS], ROOMMATE[http://fhem.de/commandref_DE.html#ROOMMATE] und GUEST[http://fhem.de/commandref_DE.html#GUEST] an. Diese sind direkt auf GEOFANCY abgestimmt. Dabei kann das devAlias Attribut entfallen und man hinterlegt die UUID stattdessen direkt im ROOMMATE oder GUEST Device (Attribut r*_geofenceUUIDs). Das erspart es für jeden Bewohner und jedes Device zig unterschiedliche Devices der Typen Notify, DOIF oder Watchdog anlegen und pflegen zu müssen.<br />
<br />
Wer mehr Kontrolle möchte kann natürlich bei notify, DOIF und Co. bleiben: <code>define n_rr_Julian.location notify geofancy:currLoc_Julian:.* set rr_Julian:FILTER=location!=$EVTPART1 location $EVTPART1</code>. Wobei "Julian" dabei als devAlias in GEOFANCY eingtragen wurde, rr_Julian der Name des ROOMMATE aus RESIDENTS ist. Außerdem wurden die Location-IDs in der Geofency.app bzw. Geofancy.app so gewählt, dass diese direkt einem ROOMMATE-Status entsprechen (also z.B. home, wayhome...).<br />
<br />
== Beispiele für die Nutzung der Anwesenheitserkennung ==<br />
Hier sollen Beispiele für den Nutzen von Anwesenheitserkennung aufgezeigt werden.<br />
<br />
=== Abschalten aller Verbraucher (Licht, Musikanlage) beim Verlassen der Wohnung ===<br />
Typisches Szenario: Man geht ausser Haus, aber hat vergessen im Bad das Licht aus zu machen. Allerdings geht man heutzutage fast garnicht mehr ohne Handy aus dem Haus.<br />
<br />
Nun soll FHEM in der gesamten Wohnung das Licht, sowie sonstige Verbraucher ausschalten, wenn ich länger als 15 Minuten ausser Haus bin. Dazu benötigt man zuerst eine structure, die alle Verbraucher und sonstigen Devices, die das betrifft, zusammenfasst.<br />
<br />
<pre><br />
define Gesamte_Wohnung structure Gesamtes_Licht Licht_Wohnzimmer Licht_Kueche LED_Kueche Licht_Bad Licht_Schlafzimmer AV_Receiver TV_Steckdose<br />
attr Gesamte_Wohnung room Wohnung<br />
</pre><br />
<br />
Nun kann man mittels eines watchdogs eine Überwachung für sein Handy anlegen:<br />
<br />
<pre><br />
# Überwachen der gesamten Wohnung mittels collectord sowie presenced in jedem Raum<br />
define Handy PRESENCE lan-bluetooth XX:XX:XX:XX:XX:XX 127.0.0.1:5222<br />
attr Handy event-on-change-reading state # Ein Event soll nur bei der Änderung des Anwesenheitsstatus (Reading: status) erfolgen. Wichtig für den watchdog!!!<br />
<br />
# Nach 15 Minuten Abwesenheit (Handy im Status "absent") soll die gesamte Wohnung ausgeschaltet werden.<br />
define watchdog_Anwesenheit watchdog Handy:absent 00:15 Handy:present set Gesamte_Wohnung off ; trigger watchdog_Anwesenheit .<br />
attr watchdog_Anwesenheit regexp1WontReactivate 1<br />
</pre><br />
<br />
=== Benachrichtigung bei Batteriewechsel ===<br />
Mit Hilfe des PRESENCE-Moduls kann man auch bei batteriebetriebenen Geräten eine Meldung ausgeben, sobald ein Batteriewechsel ansteht. Hier im Beispiel wird der Eve-Room-Sensor von Elgato eingebunden und anschließend mit einer DOIF-Nachricht ausgestattet.<br />
Die Bluetooth-Adresse des Sensors kann mittels eines BLE-Scanners ermittelt werden.<br />
<br />
<pre><br />
# PRESENCE-Modul für Elgato Eve Room Sensor mit Aktualisierung aller 6 Minuten<br />
define Eve_Room_BLE lan-bluetooth <Bluetooth-Adresse> 127.0.0.1:5333 360<br />
</pre><br />
<br />
Anschließend wird eine DOIF-Regel definiert, die eine Nachricht an die installiere [[FHEM_APP|FHEM App]] absendet:<br />
<pre><br />
define Eve_Room_BLE_Battery_Msg DOIF ([Eve_Room_BLE] eq "absent") (set Msg_iPhone message 'Batteriewechsel beim Eve Room Sensor im Wohnzimmer.')<br />
attr Eve_Room_BLE_Battery_Msg wait 600<br />
</pre><br />
<br />
Die Aktualisierung des PRESENCE-Eintrages sollte nicht größer sein als das WAIT-Attribut der DOIF-Regel. Ansonsten könnte eine kurze Systemstörung zum Fehlalarm führen.<br />
<br />
== Anwesenheitserkennung Bluetooth PebbleBee mit PRESENCE Modul ==<br />
Im Forum gibt es einen {{Link2Forum|Topic=28753|LinkText=langen Beitrag}} über die Einrichtung eines BT-Tag an einem RaspberryPI mit FHEM. Dabei werden Skripte wie blescan.pl und lepresenced genannt.<br />
Da mittlerweile viele neue Informationen zusammen gekommen sind wurde der Wiki Eintrag erstellt.<br />
<br />
Im Folgenden wird die Konfiguration für '''LE Deviced (z.B. Gtags,Pebbles etc.)''' und '''NICHT LE Device (z.B. IPhone)''' beschreiben.<br />
<br />
'''Wo finde ich denn lepresenced?'''<br />
<br />
lepresenced kann über Github heruntergeladen werden (Link weiter unten)<br />
<br />
'''Was ist der Vorteil gegenüber blescan.pl?'''<br />
<br />
{{Randnotiz|RNText=Beide hier beschriebenen Wege (presenced/lepresenced) können parallel auf dem selben BT-Dongle laufen, da sich die Ports unterscheiden!}}<br />
blescan.pl hat u. a. das Problem, dass dank der wundervollen Bluetooth-Implementierung unter Linux ab und zu der Scan fehlschlägt und das Interface resettet werden muss. Das tut blescan.pl auch mit aller Gewalt. Dazu kommt, dass bei längeren Scanzeiten und vielen Tags sich die Prozesse anstauen, weil immer nur auf einen Tag "gewartet" wird. Außerdem wurden mit der Einführung von lepresenced sämtliche Supportverträge gekündigt lepresenced läuft dauerhaft und merkt sich bei allen sendenden Tags den Zeitstempel des letzten Empfangs. <br />
<br />
<br />
<br />
=== Getestete Hardware/Software===<br />
* '''Raspbian System''' - wheezy, Jessie<br />
* '''BT-Dongle''' - CSL NET BT USB2.0 Stick, Bluetooth V4.0, Nano <br />'''Achtung''': Es muss ein BT V4.0 oder höher verwendet werden. Nur dieser unterstützt ''LowEnergy''<br />
* '''BT-TAG''' - Gtag von Gigaset, TrackR, UDOO Neo, PebbleBee, iTag von Unitec, X4-LIFE Multifunkti BL-Anhänger, iTag Wireless Anti, Trackr bravo<br />
<br />
=== BT Dongel am PI installieren ===<br />
<br />
Um den BT Dongle ''(hier: CSL NET BT USB2.0)'' am PI verwenden zu können, müssen die notwendigen Pakete über die Paketverwaltung von debain nachinstalliert werden.<br />
Wer bereits ein BT-Dongle installiert hat, kann diesen Schritt überspringen.<br />
<pre><br />
apt-get install bluetooth<br />
</pre><br />
Nach erfolgreicher Installation der Pakete sollte der RaspberryPI neu gestartet werden.<br />
<pre><br />
sudo reboot<br />
</pre><br />
<br />
Nach dem erfolgten Reboot bitte das Log des Raspberry auf folgende Einträge prüfen:<br />
<pre><br />
Feb 12 19:52:55 fhem kernel: [ 4.773600] Bluetooth: Core ver 2.20<br />
Feb 12 19:52:55 fhem kernel: [ 4.773748] NET: Registered protocol family 31<br />
Feb 12 19:52:55 fhem kernel: [ 4.773765] Bluetooth: HCI device and connection manager initialized<br />
Feb 12 19:52:55 fhem kernel: [ 4.773797] Bluetooth: HCI socket layer initialized<br />
Feb 12 19:52:55 fhem kernel: [ 4.773821] Bluetooth: L2CAP socket layer initialized<br />
Feb 12 19:52:55 fhem kernel: [ 4.773890] Bluetooth: SCO socket layer initialized<br />
Feb 12 19:52:55 fhem kernel: [ 4.797531] usbcore: registered new interface driver btusb<br />
</pre><br />
Sobald der BT-Dongle erkannt wurde ''leuchtet'' (wenn vorhanden) auch die ''blaue/gelbe'' LED am Dongle auf.<br />
<br />
=== BT-Tags aktivieren ===<br />
Jetzt kann der BT-Tag aktiviert werden. Bei einigen Tags muss dafür die '''Batteriesicherung''' gezogen werden.<br />
<br />
Einen Tag wird mit folgendem Befehl auf der Konsole gesucht:<br />
<source lang="bash"><br />
sudo hcitool lescan<br />
<br />
Ausgabe z.B.:<br />
LE Scan ...<br />
7C:2F:80:A1:XA:XD (unknown)<br />
7C:2F:80:A1:XA:XD Gigaset G-tag<br />
7C:2F:80:A1:X4:X1 (unknown)</source><br />
Eine Übersicht über die möglichen Befehle von hcitool gibt es mit der Eingabe von:<br />
<pre><br />
sudo hcitool<br />
<br />
Ausgabe z.B.:<br />
hcitool - HCI Tool ver 5.23<br />
Usage:<br />
hcitool [options] <command> [command parameters]<br />
Options:<br />
--help Display help<br />
-i dev HCI device<br />
Commands:<br />
dev Display local devices<br />
inq Inquire remote devices<br />
scan Scan for remote devices<br />
name Get name from remote device<br />
info Get information from remote device<br />
spinq Start periodic inquiry<br />
epinq Exit periodic inquiry<br />
cmd Submit arbitrary HCI commands<br />
con Display active connections<br />
cc Create connection to remote device<br />
dc Disconnect from remote device<br />
sr Switch master/slave role<br />
cpt Change connection packet type<br />
rssi Display connection RSSI<br />
lq Display link quality<br />
tpl Display transmit power level<br />
afh Display AFH channel map<br />
lp Set/display link policy settings<br />
lst Set/display link supervision timeout<br />
auth Request authentication<br />
enc Set connection encryption<br />
key Change connection link key<br />
clkoff Read clock offset<br />
clock Read local or remote clock<br />
lescan Start LE scan<br />
lewladd Add device to LE White List<br />
lewlrm Remove device from LE White List<br />
lewlsz Read size of LE White List<br />
lewlclr Clear LE White list<br />
lecc Create a LE Connection<br />
ledc Disconnect a LE Connection<br />
lecup LE Connection Update <br />
</pre><br />
<br />
Falls beim SCAN kein Tag gefunden wird, sollte das BT Interface neu gestartet werden. Dazu ist kein Reboot des PI notwendig.<br />
<source lang="bash"><br />
sudo hciconfig hci0 down<br />
sudo hciconfig hci0 up<br />
sudo hcitool dev<br />
</source><br />
<br />
=== Anleitung für ein LE Device (z.B. Gtags,Pebbles etc.) ===<br />
<br />
Herunterladen des Skripts lepresenced.<br />
<pre><br />
https://github.com/mhop/fhem-mirror/blob/master/fhem/contrib/PRESENCE/lepresenced<br />
</pre><br />
<br />
Zur "Installation" des Skripts folgendermaßen vorgehen:<br />
Unter /fhem manuell den Ordner „script“ anlegen:<br />
<pre><br />
mkdir script<br />
</pre><br />
Datei lepresenced reinkopieren und ausführbar machen:<br />
<pre><br />
sudo chmod +x /opt/fhem/script/lepresenced<br />
sudo chgrp -cR dialout lepresenced<br />
</pre><br />
Skript erstmalig starten:<br />
<pre><br />
sudo ./lepresenced --loglevel LOG_EMERG -d<br />
</pre><br />
Kommt beim Starten des Skript eine Fehlermeldung, müssen die Abhängigkeiten aufgelöst werden.<br />
<pre><br />
Can't locate Net/Server/Daemonize.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 / usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl .) at /opt/fhem/lepresenced line 17.<br />
BEGIN failed--compilation aborted at /opt/fhem/lepresenced line 17.<br />
</pre><br />
Um die Abhängigkeiten aufzulösen muss folgendes nachinstalliert werden und anschließend ein Reboot durchgeführt werden.<br />
<pre><br />
sudo apt-get install libnet-server-*<br />
</pre><br />
<br />
<br />
Nach dem letzten Schritt sind alle Bedingungen für eine abschließende Konfiguration der BT-Tags in FHEM abgeschlossen worden.<br />
Jetzt kann der Tag dem FHEM-Server bekannt gemacht werden.<br />
<pre><br />
-- Name Modul Modus MAC vom Gtag IP vom PI Port Abfragezeit in Sekunden<br />
define MeinGtAG PRESENCE lan-bluetooth xx:xx:xx:xx:xx:xx 127.0.0.1:5333 120<br />
</pre><br />
<br />
Den absent und present Mode kann man einfach testen, in dem man den Gtag mit Alufolie einwickelt.<br />
<br />
=== Anleitung für ein NICHT LE Device (z.B. IPhone) ===<br />
Die Installation kann (wie in der commanref beschrieben) über Debian Pakete erfolgen.<br />
<pre><br />
.deb package for Debian (noarch): presenced-1.3.deb http://svn.code.sf.net/p/fhem/code/trunk/fhem/contrib/PRESENCE/deb/presenced-1.3.deb<br />
<br />
.deb package for Raspberry Pi (raspbian): presenced-rpi-1.3.deb http://svn.code.sf.net/p/fhem/code/trunk/fhem/contrib/PRESENCE/deb/presenced-rpi-1.3.deb<br />
</pre><br />
<br />
<pre><br />
sudo dpkg -i presenced-rpi-1.3.de<br />
</pre><br />
<br />
Installation perl script file (Auszug commanref)<br />
<pre><br />
direct perl script file: presenced http://svn.code.sf.net/p/fhem/code/trunk/fhem/contrib/PRESENCE/presenced<br />
</pre><br />
<br />
Nach dem letzten Schritt sind alle Bedingungen für eine abschließende Konfiguration der BT-Tags in FHEM abgeschlossen worden.<br />
Jetzt kann der Tag dem FHEM-Server bekannt gemacht werden.<br />
{{Randnotiz|RNText=Wenn man mit collectord arbeitet muß man die Erkennung bei allen Devices auf port 5222 setzen.<br />
lan-bluetooth xx:xx:80:xx:xx:AC 127.0.0.1:5222 20 120}}<br />
<pre><br />
-- Name Modul Modus MAC vom Gtag IP vom PI Port Abfragezeit in Sekunden<br />
define MeinGtAG PRESENCE lan-bluetooth xx:xx:xx:xx:xx:xx 127.0.0.1:5333 120<br />
</pre><br />
<br />
=== Automatischer Start ===<br />
<br />
Damit das leprecend Skript beim Systemstart mitgestartet wird, sollte eine Crontab Eintrag gesetzt werden. Alternativ die rc.local anpassen.<br />
Ersteres würde so aussehen:<br />
<br />
Ein sh-Skript mit dem Inhalt:<br />
<pre><br />
sudo start-stop-daemon -d /opt/fhem/script -S -x /opt/fhem/script/lepresenced<br />
</pre><br />
unter dem Verzeichnis /home/pi ablegen, welches sich init_start.sh nennt.<br />
<br />
Das Skript dann unter: sudo crontab -e einhängen mit folgender Folge:<br />
<pre><br />
@reboot /home/pi/init_start.sh<br />
</pre><br />
<br />
Zweiteres so:<br />
<pre><br />
sudo nano /etc/rc.local<br />
</pre><br />
<br />
Datei rc.local, freie Stelle suchen, vor "exit 0":<br />
<br />
<pre><br />
# Start lepresenced<br />
/opt/fhem/script/lepresenced --loglevel LOG_EMERG -d<br />
exit 0<br />
</pre><br />
<br />
=== Batterieüberwachung (aktuell nur G-Tags) ===<br />
<br />
Leider überträgt der G-Tag nach der Einrichtung als Device in FHEM kein Reading mit seinem aktuellen Batteriestatus.<br />
Dem wurde mit Hilfe des Forum Abhilfe geschaffen.<br />
Im Folgenden wird erläutert wie die Batterieüberwachung eingerichtet werden kann.<br />
<br />
'''Voraussetzung:'''<br />
<br />
bc - Basiscalculator [https://packages.debian.org/de/sid/bc Bc-Paket]<br />
<pre> sudo apt-get install bc </pre><br />
<br />
Anlegen eines Shellskript auf dem Raspberry System. <br />
Die Parameter <<MAC-Adresse>> und <<TagName>> müssen durch die Werte des auszulesenden G-Tags ersetzt werden.<br />
<pre><br />
#!/bin/bash<br />
stringZ=$(sudo gatttool -b 5C:2B:80:C1:14:41 --char-read --handle=0x001b)<br />
stringZ=${stringZ:33:2}<br />
stringZ=$(echo "$stringZ" | tr a-f A-F)<br />
decimal=$(echo "ibase=16; $stringZ" | bc)<br />
perl /opt/fhem/fhem.pl 7072 "setreading MeinGtag Batterie $decimal"<br />
</pre><br />
<br />
Dem Device in FHEM (hier MeinGtag) ein userReading mit dem Namen '''Batterie''' hinzufügen.<br />
Das Shellskript mit folgendem Befehl starten:<br />
<pre><br />
./GtagBatterie.sh<br />
</pre><br />
'''Wichtig ist hierbei,''' dass Skript mit "./" und nicht mit "sh" aufzurufen. Beim Aufruf mit "sh GtagBatterie.sh" produziert es einen Fehler<br />
<pre>GtagBatterie.sh: 3: GtagBatterie.sh: Bad substitution </pre><br />
<br />
Das Reading wird auf den ausgelesenen Wert der Batterie gesetzt. <br />
<br />
Hinweis: Es sollte für jeden G-Tag ein eigenes Skript abgelegt werden. Das Skript kann per crontab oder fhem Kommando (system) regelmäßig aufgerufen werden.<br />
<br />
=== Batterieüberwachung (alle Devices vom Typ "MODE=lan-bluetooth") ===<br />
<br />
Es gibt eine weitere Möglichkeit um den Batteriestatus von LE Devices abzurufen und in FHEM als Reading darzustellen.<br />
Dabei wird der Batteriezustand für alle LE Devices, die bereits in FHEM konfiguriert sind und per lepresenced überwacht werden, automatisch in einem shell-Script ermittelt.<br />
Näheres dazu im Forumartikel [https://forum.fhem.de/index.php/topic,56960.0.html [Erweiterung]: Anwesenheitserkennung/Batterieüberwachung].<br />
<br />
Vorteile:<br />
* Automatische Ermittlung aller in FHEM konfigurierten LE Devices<br />
* Möglichkeit, diese Devices alternativ manuell im Script einzutragen<br />
* Es werden nur Devices abgefragt, die im Status "present" sind, also mit ziemlicher Sicherheit auch verfügbar sind<br />
* Ein eventuell auf dem FHEM telnet-Port gesetztes Passwort kann im Script hinterlegt werden<br />
<br />
'''Voraussetzung:'''<br />
<br />
'''Funktionierendes lepresenced''' - siehe [[Anwesenheitserkennung#Anleitung_f.C3.BCr_ein_LE_Device_.28z.B._Gtags.2CPebbles_etc..29|Anleitung für ein LE Device (z.B. Gtags,Pebbles etc.)]]<br />
<br />
'''socat''' - TCP port forwarder<br />
<pre><br />
sudo apt-get update && sudo apt-get install socat<br />
</pre><br />
<br />
'''gatttool''' - Bestandteil von bluez <br />
<br />
gatttool ist auf den meisten Distributionen im bluez-Paket, allerdings nicht bei Opensuse. Dort muss man das Sourcepaket von bluez installieren und selbst kompilieren.<br />
gatttool sollte dann nach /usr/bin oder /usr/local/bin kopiert werden,<br />
<br />
<br />
Zusätzlich zu den notwendigen Erweiterungen werden für die Ausführung von gatttool '''Root-Rechte benötigt'''!<br />
<br />
Das Script selbst gibt es hier: [https://raw.githubusercontent.com/micky0867/lebattery/master/lebattery lebattery]<br />
<br />
Am Besten unter /opt/fhem/script/lebattery speichern und ausführbar machen:<br />
<source lang="bash"><br />
sudo su -<br />
mkdir /opt/fhem/script<br />
cd /opt/fhem/script<br />
wget https://raw.githubusercontent.com/micky0867/lebattery/master/lebattery<br />
chmod 755 lebattery<br />
</source><br />
<br />
Je nach Bedarf können im Script noch die folgenden 3 Parameter angepasst werden:<br />
<source lang="bash"><br />
# If allowed_telnetPort is protected by a password, add the password here<br />
TELNETPASSWORD=""<br />
# Attribute for batterylevel in FHEM<br />
ATTRIBUT="batterylevel"<br />
# Use this, if you dont want the script to determine the tags on its own<br />
LETAGS=""<br />
</source><br />
<br />
Das Skript wird dann unter root folgendermaßen gestartet:<br />
<pre><br />
/opt/fhem/script/lebattery -v<br />
</pre><br />
<br />
Ausgabe des Skripts, wenn es mit dem Verbose Parameter -v gestartet wird.<br />
<br />
Beide Devices sind vom Typ NUT mini, das Device mit dem FHEM-Namen '''nut_Micky''' ist im Status '''absent'''. Das zweite Device ist im Status '''present'''.<br />
<pre><br />
Determining address for nut_Micky ...<br />
nut_Micky is in state absent, no further action required<br />
<br />
Determining address for nut_Test ...<br />
Fetching batterylevel for nut_Test (F3:44:04:81:54:89) ...<br />
Setting batterylevel for nut_Test to 100%<br />
</pre><br />
<br />
Mein crontab-Eintrag (User root) sieht so aus:<br />
<pre><br />
3 3 * * * /opt/fhem/script/lebattery -v >/opt/fhem/script/lebattery.log 2>&1<br />
</pre><br />
Damit wird jeden Morgen um 3 Minuten nach 3 Uhr der Zustand der Batterien aller Devices ermittelt und in FHEM abgespeichert.<br> <br />
Bevor man das mit crontab macht, sollte man allerdings zunächst sicher stellen, dass es auch ohne crontab funktioniert....<br />
<br />
Bei Problemen kann man auch erstmal schauen, ob das mit dem gattool überhaupt funktioniert:<br />
<pre><br />
gatttool -t random -b <MAC-Adresse> --char-read --uuid 0x2a19<br />
<br />
handle: 0x0017 value: 64<br />
</pre><br />
In diesem Fall hat die Batterie noch 100% (hex 64).<br />
<br />
<br />
=== Anwesenheitserkennung / Anwesenheitsbenachrichtigung mit G-Tags ===<br />
<br />
Ein Skript zur Nutzung der Gigaset G-TAGs zur Alarmierung bei öffnen und schließen von Türen und zur Anwesenheitserkennung, um die Alarmierung zu aktivieren bzw. deaktivieren. <br />
Es kann verwendet werden um die Anwesenheit von mehrern Personen im Haushalt zu erkennen. Dabei wird eingeschränkt, dass nur bestimmte Personen die Alarmierung aktivieren können ( Eltern/Kind -Beziehung ).<br />
Des Weiteren werden im Beispiel die Eltern benachrichtigt wenn eins der Kinder das Haus verlässt und die Eltern nicht anwesend sind.<br />
<br />
{{Randnotiz|RNText= Namen der G-Tags in den Skripten bitte Anpassen!}}<br />
<br />
Für die ''Notify'' und die ''RESIDENTS-Erweiterung'' wird ein Dummy benötigt.<br />
<pre><br />
define Alarm dummy<br />
attr Alarm devStateIcon aktiv:secur_locked@red inaktiv:secur_open@lightgreen<br />
attr Alarm eventMap on:aktiv off:inaktiv<br />
attr Alarm setList on off<br />
attr Alarm webCmd aktiv:inaktiv<br />
attr Alarm room Alarm<br />
</pre><br />
<br />
<br />
====Mit Notify ====<br />
<pre><br />
gtag.*.presence:.* {Anwesenheit_check("$EVTPART1", "$NAME")}<br />
</pre><br />
<br />
Code für die 99_myUtils.pm<br />
<pre><br />
### GTAG ANWESENHEITS CHECK<br />
sub Anwesenheit_check($$) {<br />
my ($EVENT, $NAME) = @_;<br />
my $ALIASNAME = AttrVal($NAME,'alias',$NAME); # ALIAS des GTAGs auslesen<br />
my $GTAG1 = Value('gtag_rot'); # ELTERN<br />
my $GTAG2 = Value('gtag_schwarz'); # ELTERN<br />
<br />
Log 1, "$ALIASNAME ist $EVENT."; # LOG Eintrag erzeugen<br />
<br />
if (($EVENT eq "anwesend" && Value("Alarm") eq "aktiv") && ($NAME eq "gtag_gruen" xor $NAME eq "gtag_orange")) {<br />
fhem("set Infopush msg 'ALARMIERUNG BLEIBT AKTIV' '$ALIASNAME ist da...'");<br />
}<br />
elsif (($EVENT eq "anwesend" && Value("Alarm") eq "aktiv") && ($NAME eq "gtag_rot" xor $NAME eq "gtag_schwarz")) {<br />
fhem("set Infopush msg 'ALARMIERUNG INAKTIV' '$ALIASNAME ist da...'; set Alarm inaktiv");<br />
}<br />
elsif (($EVENT eq "unterwegs" && Value("Alarm") eq "aktiv") && ($NAME eq "gtag_gruen" xor $NAME eq "gtag_orange")) {<br />
fhem("set Infopush msg 'ALARMIERUNG BLEIBT AKTIV' '$ALIASNAME hat das Haus verlassen.'");<br />
} <br />
elsif (($EVENT eq "unterwegs" && Value("Alarm") eq "inaktiv") && ($GTAG1 eq "unterwegs" && $GTAG2 eq "unterwegs")) {<br />
fhem("set Alarm aktiv; set Infopush msg 'ALARMIERUNG AKTIV' '$ALIASNAME hat als letztes das Haus verlassen.' '' 0 ''");<br />
}<br />
}<br />
</pre><br />
<br />
<br><br />
====Mit Notify und Integration des RESIDENTS-MODUL====<br />
<br />
Der hier beschriebene Code erweitert die Funktionen unter dem Punkt 5.93.<br />
Das Notify muss daher mit der folgenden Zeile erweitert werden.<br />
<br />
<pre><br />
define Alarm_AnwesenheitCheck notify gtag.*.presence:.* { Anwesenheit_check("$EVTPART1", "$NAME"), Anwesenheit_check_resi("$NAME") }<br />
</pre><br />
<br />
Zusätzlicher Code für die 99_myUtils.pm um die RESIDENTS Funktion nutzen zu können:<br />
<pre><br />
### RESIDENTS<br />
sub Anwesenheit_check_resi($) {<br />
my ($NAME) = @_;<br />
my $ALIASNAME = AttrVal($NAME,'alias',$NAME); # ALIASNAME des GTAGs auslesen<br />
my $RESIUSER = "rr_"; # rr_ Residents Roommate rg_ für Residents Guest<br />
my $ROOMMATE = ("$RESIUSER" . "$ALIASNAME"); # Residentsname zusammenbauen<br />
<br />
if (ReadingsVal($NAME,'presence',$NAME) eq "absent") {<br />
fhem("set $ROOMMATE absent"); # Resisents Status von Roommates setzen<br />
}<br />
elsif(ReadingsVal($NAME,'presence',$NAME) eq "present") {<br />
fhem("set $ROOMMATE home"); # Resisents Status von Roommates setzen<br />
}<br />
}<br />
</pre><br />
<br />
Da bei Residents die Benutzernamen unterschiedlich sind für Bewohner (beginnend mit "rr_") und Gäste (beginnend mit "rg_") wurden nur die Bewohner berücksichtigt.<br />
<br><br />
<br />
====Mit Notify und Fenster/Tür. -Kontakt Überwachung====<br />
<br />
Erweiterung für die Überwachung von Fenster/Tür. -Kontakten. Dazu sind zwei weitere Notifys notwendig die auf die Trigger der Kontakte regagieren<br />
und so eine weitere Funktion in der 99_myUtils.pm ansprechen. Die Notifys triggern auf Kontakte die mit dem Namen Kontakt* beginnen.<br />
Sollten die eigenen Fenster/Tür. -Kontakt anderen Namen besitzen, müssen die Skripte dementsprechend angepasst werden.<br />
<pre><br />
define Alarm_Kontaktmeldung notify Kontakt.*:contact:.* {Kontakt_Meldung("$EVTPART1", "$NAME")}<br />
</pre><br />
<pre><br />
define Alarm_Sabotagealarm notify Kontakt.*.sabotageError:.on {Kontakt_Sabotage("$EVTPART1", "$NAME")}<br />
</pre><br />
<br />
Zusätzlicher Code für die 99_myUtils.pm um die TÜRKONTAKTE-Meldung nutzen zu können:<br />
<pre><br />
### TÜRKONTAKTE-Meldung/Zustand<br />
sub Kontakt_Meldung($$) {<br />
my ($EVENT, $NAME) = @_;<br />
my $ALIASNAME = AttrVal($NAME,'alias',$NAME);<br />
Log 1, "$ALIASNAME wurde $EVENT";<br />
if (ReadingsVal("Alarm", "state", "on") eq "on") {<br />
fhem("set teleBot send $ALIASNAME wurde $EVENT"); # Nachricht über Telegram<br />
# fhem("set Infopush msg '$ALIASNAME' '$ALIASNAME wurde $EVENT'"); # Nachricht über Pushover<br />
}<br />
}<br />
<br />
### TÜRKONTAKTE-Sabotagealarm<br />
<br />
sub Kontakt_Sabotage($$) {<br />
my ($EVENT, $NAME) = @_;<br />
my $ALIASNAME = AttrVal($NAME,'alias',$NAME);<br />
Log 1, "$ALIASNAME meldet Sabotagealarm";<br />
fhem("set teleBot send Alarm: $ALIASNAME meldet Sabotagealarm"); # Nachricht über Telegram<br />
# fhem("set Infopush msg 'Alarmanlage' '$ALIASNAME meldet Sabotagealarm' '' 2 ' ' 60 600 "); # Nachricht über Pushover<br />
}<br />
</pre><br />
<br><br />
<br />
==== Hinweis zur Benutzung / Fehlerhandling ====<br />
<br />
Der Alarm dummy hat den Zustand on:off. Die Bezeichnungen und Namen müssen 1:1 übernommen werden damit das Script funktioniert.<br />
Andernfalls müssen die Bezeichnungen für z.B. absent:unterwegs und present:anwesend - angepasst werden.<br />
Die Benachrichtigung kann aktuell per ''Telegram'' sowie ''Pushover'' ('''Achtung mit zweiterem sind Abokosten verbunden!''') realisiert werden.<br />
Diskussion zum Thema im Forum unter: [[https://forum.fhem.de/index.php/topic,64080.0.html]]<br />
<br><br />
<br />
=== Problemlösungen ===<br />
Falls es Probleme beim Starten des Skripts gibt bzw. man das Skript ohne Reboot des Systems neustarten möchte, kann man dies per kill Befehl erledigen.<br />
<source lang="bash"><br />
ps -ef | grep lepresenced<br />
sudo kill <pid><br />
</source><br />
<br />
Debuglevel lepresenced setzen:<br />
{{Randnotiz|RNText=Um Debug-Meldungen zu bekommen (Vorsicht bei SD-Karten-Systemen wie dem RPi) - Hierbei werden die Schreibzyklen auf die SD-Karte erhöht.}}<br />
<pre><br />
lepresenced --loglevel LOG_DEBUG<br />
</pre><br />
Nur das wichtigste Loggen:<br />
<pre><br />
lepresenced --loglevel LOG_WARNING<br />
</pre><br />
Keinerlei LOG-Einträge<br />
<pre><br />
lepresenced --loglevel LOG_EMERG<br />
</pre><br />
<br />
==== Ansprechpartner ====<br />
# {{Link2FU|5068|PatrikR}} (Patrick) für lepresenced <br />
# [[Benutzer Diskussion:Devender|Devender]] ({{Link2FU|20043|Dirk}}) für Wiki und Doku<br />
<br />
[[Kategorie:Code Snippets]]<br />
[[Kategorie:Glossary]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Anwesenheitserkennung&diff=18499Anwesenheitserkennung2017-01-16T06:28:19Z<p>Hauswart: </p>
<hr />
<div>Viele Benutzer führen bereits eine eigene '''Anwesenheitserkennung''' durch. Diese basiert in den meisten Fällen auf Ping Checks oder bei [[AVM Fritz!Box|FritzBoxen]] auf dem Befehl ''ctlmgr_ctl''. Diese Lösungen können aber je nach Aufbau und Funktion FHEM massiv beeinträchtigen. Aufgrund des Aufbaus vom FHEM kann dieses dadurch für mehrere Sekunden zum völligen Stillstand gebracht werden.<br />
<br />
In FHEM gibt es mittlerweile mehrere Module, die eine zuverlässige Anwesenheitserkennung bieten, ohne dabei FHEM bei der Ausführung zu beeinträchtigen.<br />
<br />
Eine erweiterte Funktion der Anwesenheitserkennung ist die Standortverfolgung, die sich nicht nur auf ein oder sehr wenige mit (eigenem) WLAN versorgte Gebiete beschränkt.<br />
<br />
== Vorüberlegungen ==<br />
Generell gibt es mehrere Ansätze um Anwesenheitserkennung mit Handys/Smartphones durchzuführen.<br />
<br />
* via PING Checks im gesamten WLAN<br />
* Aktivitätsprüfung auf einer FritzBox<br />
* Bluetooth Checks in der gesamten Wohnung<br />
* eigene Perl-Funktion<br />
* aktive Benachrichtigung des Smartphones, ausgelöst z.B. über Geo-Lokation/Geofence<br />
<br />
Dabei gilt bei der Auswahl der Art darauf zu achten wie sich das jeweilige Device verhält. Aufgrund der Vielfältigkeit kann man hier keine allgemeine Vorgehensweise empfehlen. Als einfacher Start (zumindest für Nicht-Apfel Telefone) eignet sich die Ping-Überprüfung und die FritzBox-Abfrage sehr gut.<br />
<br />
=== Randbedingungen ===<br />
Es gibt Geräte, die ihr WLAN/Bluetooth auch im Standby ständig aktiv haben und auf Anfragen antworten können (fast alle Android-Geräte). Gerade bei Tests über WLAN kann sich das aber signifikant auf die Akku Leistung auswirken.<br />
<br />
Andere Geräte wiederum schalten WLAN im Standby Betrieb aus, um Akkukapazität zu sparen. Bluetooth hingegen bleibt weiterhin aktiviert und kann auf Anfragen reagieren. (iPhone)<br />
<br />
Wenn man bei einem iPhone die Funktion "über WLAN synchronisieren" aktiviert hat, so ist dies auch im Standby jederzeit pingbar, wenn der Recher auf dem iTunes zum synchroniseren läuft auch an ist. Ansonsten ist bei iPhone Geräten nur die Aktivitätsprüfung mit einer FritzBox oder das überwachen der DHCP Lease auf einer Airport Basestation wirklich zuverlässig.<br />
<br />
Auch wenn Bluetooth aktiviert ist, so bleiben einige Mobiltelefone erst dann empfangsbereit, wenn sie bereits zu irgend einem Bluetoothgerät gekoppelt wurden. Sind diese Geräte noch nie gekoppelt worden, deaktivieren diese ihren Bluetooth Empfänger beim verlassen des Bluetooth-Menüs im Gerät (iPhone).<br />
<br />
Hier gilt es vor allem auszuprobieren, wie stark der Akku durch eine Anwesenheitserkennung belastet wird. Entscheidend ist hier, in welchem Abstand man eine Anwesenheitserkennung durchführt. Viele Abfragen wirken sich stärker auf den Akku aus als wenige. Wenige Abfragen bieten aber keine zuverlässige und zeitnahe Erkennung.<br />
<br />
Als Alternative, unabhängig vom WLAN und der Erkennung, ob ein Gerät dort eingebucht ist oder nicht, bzw. unabhängig von Bluetooth kann zumindest bei einem iPhone die seit iOS 7 nochmals stark verbesserte Geo-Lokation (Geofencing) genutzt werden. Die iPhone Apps [http://geofency.com/ Geofency] oder [http://geofancy.com/ Geofancy] werden über das FHEM-Modul GEOFANCY angebunden und übertragen ihren Status immer dann, wenn ein definierter Standort betreten oder verlassen wird. Gekoppelt mit entsprechenden Notify und/oder Watchdog Kommandos ist so ebenfalls eine sehr zuverlässige Anwesenheitserkennung möglich (und das nicht nur für das eigene Zuhause).<br />
<br />
== Das PRESENCE Modul ==<br />
Das [[PRESENCE]] Modul bietet für die Anwesenheitserkennung mehrere Varianten an. Diese sind aktuell folgende:<br />
<br />
* '''lan-ping''' - Das Überwachen via PING Checks, die durch den FHEM Server versandt werden.<br />
* '''fritzbox''' - Das Überwachen von Geräten auf einer FritzBox via ctlmgr_ctl (Nur auf einer FritzBox möglich)<br />
* '''local-bluetooth''' - Das Überwachen via Bluetooth Checks, die vom FHEM Server direkt durchgeführt werden (angeschlossener Bluetooth-Stick und die Software bluez voraussgesetzt)<br />
* '''lan-bluetooth''' - Das Überwachen von Bluetoothgeräte, über Netzwerk. Auf einer oder mehreren Maschinen im Netzwerk (z.B. [[:Kategorie:Raspberry Pi|Raspberry Pi]]) läuft ein Presence-Daemon, der nach Bluetooth-Geräten sucht. Um mehrere Presence-Daemon mit FHEM zu verbinden, gibt es den Collector-Daemon, der sich zu allen Presence-Damons im Netzwerk verbindet und das Ergebnis von allen zusammenfasst.<br />
* '''function''' - Das Überwachen mithilfe einer selbst geschrieben Perl-Funktion, die den Anwesenheitsstatus zurückgibt (0 oder 1)<br />
* '''shell-script''' - Das Überwachen mithilfe eines selbst geschriebenen Shell-Programms/Skript, das eine 0 oder 1 ausgibt, um den Anwesenheitsstatus mitzuteilen.<br />
<br />
=== Ping-Überwachung von Geräten im WLAN/LAN ===<br />
{{Randnotiz|RNText=Um diese Methode auf einer FritzBox nutzen zu können, muss FHEM mit root-Rechten laufen. Dies ist standardmäßig nicht der Fall. Bitte dazu den Wiki Artikel [[FritzBox: fhem unter root starten]] beachten.}}<br />
Um ein Gerät via Ping zu überwachen, muss folgende Definition durchgeführt werden:<br />
:<code>define Handy PRESENCE lan-ping 192.168.0.30</code><br />
<br />
Dadurch wird die IP-Addresse 192.168.0.30 alle 30&nbsp;Sekunden geprüft, ob sie erreichbar ist. Wenn sie erreichbar ist, ist der Status "present" (anwesend), ansonsten "absent" (abwesend).<br />
<br />
Der Timeout kann verändert werden, indem ein Wert (in Sekunden) an das Define anhängt wird:<br />
:<code>define Handy PRESENCE lan-ping 192.168.0.30 '''60'''</code><br />
<br />
Nun würde das Handy alle 60 Sekunden geprüft werden.<br />
<br />
Nur wenn bei einem iPhone/iPad die Funktion "über WLAN synchronisieren" aktiviert ist, ist es auch im Standby zuverlässig pingbar. Standardmäßig deaktivieren Apple-Geräte ihr WLAN im Standby-Betrieb um die Akkulaufzeit zu verlängern.<br />
<br />
Sollte die Fehlermeldung <br />
:<code> PRESENCE (Handy) - ping command returned with output: ping: icmp open socket: Operation not permitted </code> <br />
im Log auftauchen und lan-ping dadurch nicht funktionieren, liegt ein Berechtigungsproblem vor. Kein Grund den User fhem zu root zu machen!<br />
So sollten die Berechtigungen aussehen<br />
:<code>sudo ls -la /bin/ping</code><br />
unter Jessie<br />
:<code>-rwxr-xr-x 1 root root 38844 Feb 12 2014 /bin/ping</code><br />
unter Wheezy<br />
:<code>-rwsr-xr-x 1 root root 33220 Mär 30 2012 /bin/ping</code><br />
Sollte es trotzdem unter Jessie nicht funktionieren kann man auch dort die Berechtigung analog wheezy setzen:<br />
:<code>sudo chmod u+s /bin/ping</code><br />
<br />
=== FritzBox: direktes Abfragen der Aktivität via ctlmgr_ctl ===<br />
{{Randnotiz|RNText=Um diese Methode auf einer FritzBox nutzen zu können, muss FHEM mit root-Rechten laufen. Dies ist standardmäßig nicht der Fall. Bitte dazu den Wiki Artikel [[FritzBox: fhem unter root starten]] beachten.}}<br />
Eine sehr häufige und auch zuverlässige Methode ist auf einer FritzBox die Abfrage mittels ctlmgr_ctl Befehl. Über diesen lassen sich alle Geräte abfragen ob sie aktiv sind. Ist ein Gerät aktiv, so gilt es als anwesend.<br />
<br />
Dieser Modus kann allerdings nur in FHEM Installationen direkt auf einer FritzBox verwendet werden. Des weiteren muss FHEM unter dem User root laufen. Um ein Gerät zu überwachen, wird lediglich der Gerätename benötigt, so wie er unter dem Menüpunkt "Heimnetz" auftaucht. <br />
<br />
Die erforderliche Definition:<br />
:<code>define Handy PRESENCE fritzbox iPhone-4S</code><br />
<br />
=== Bluetooth-Überwachung von Geräten durch den FHEM Server ===<br />
[[Datei:Bluetooth-Adresse-iPhone.png|thumb|Bluetooth-Adresse eines iPhones]]<br />
Jenach Aufstellungsort des FHEM Servers kann es sinnvoll sein, eine Bluetooth-Überwachung direkt durch den FHEM Server durchzuführen. Hierbei gilt allerdings zu beachten, dass Bluetooth nicht für große Reichweiten gedacht ist und in den meisten Fällen keine Wände überwinden kann. Das heisst, dass in den meisten Fällen damit nur ein Raum überwacht werden kann.<br />
<br />
Je nach Einsatzzweck kann das auch so gewollt sein. Bluetooth USB Sticks, die bereits Bluetooth 4.0 unterstützen, können höhere Reichweiten über Zimmerwände hinaus erreichen. Vorausgesetzt, das Mobilgerät unterstützt Bluetooth 4.0.<br />
<br />
Um eine Überwachung per Bluetooth durchführen zu können, benötigt man die Bluetooth-Adresse eines Gerätes. Diese ähnelt vom Aufbau einer MAC-Adresse. Generell wird die Adresse in den Telefon-Informationen bei Smartphones angezeigt.<br />
<br />
Um eine Anwesenheitserkennung via Bluetooth durchzuführen, wird folgende Definition in der [[Konfiguration]] benötigt:<br />
:<code>define Handy PRESENCE local-bluetooth XX:XX:XX:XX:XX:XX</code><br />
<br />
=== Bluetooth-Überwachung von Geräten durch verteilte Agenten in der Wohnung (presencd/collectord) ===<br />
[[Datei:Raspberry-Pi-mit-WLAN-und-Bluetooth-Stick.jpg|thumb|left|Raspberry Pi mit Bluetooth- und WLAN-USB-Stick]]<br />
Um eine zuverlässige und flächendeckende Bluetooth-Anwesenheitserkennung durchzuführen, ist es unerlässlich, mehrere Bluetooth-Empfänger zu verwenden, die auf mehrere oder alle Räume verteilt sind.<br />
<br />
Hierfür bietet sich zum Beispiel ein [[Raspberry Pi]] mit einem Mini-Bluetooth-USB-Stick und evtl. einem WLAN-USB-Stick an. Jeder Raum wird mit solch einem Raspberry ausgestattet und ist im WLAN Netz verfügbar.<br />
<br />
Dieses Netz aus Raspberrys wird mit dem presenced (Download-Link ist in der [http://fhem.de/commandref_DE.html#PRESENCE Commandref] zum Modul enthalten) ausgestattet. Es stehen bereits entsprechende Pakete für den Raspberry zur Verfügung.<br />
<br />
Beide Programme (presenced/collectord) sind Perl-Skripte, die als Daemon im Hintergrund laufen und auf Anfragen via Netzwerk warten. Es wird lediglich eine vollständige Perl-Grundinstallation mit Standardmodulen benötigt. Nach Installation der *.deb Pakete sollten diese noch angewiesen werden, automatisch beim Rechner-Neustart gestartet zu werden:<br />
<br />
<pre><br />
sudo update-rc.d presenced defaults<br />
sudo update-rc.d collectord defaults<br />
</pre><br />
<br />
Eine detaillierte Benutzung von presenced ist in der [http://fhem.de/commandref_DE.html#PRESENCE Commandref] Beschreibung zum PRESENCE Modul enthalten.<br />
<br />
==== Jeden Raum einzeln ansprechen (presenced) ====<br />
Nun kann zuallererst jeder Raum einzeln angesprochen werden. Dabei ist zu beachten, dass pro Definition in der Konfiguration nur ein Gerät in einem Raum spezifisch überwacht werden kann.<br />
<br />
Eine Definition sieht dabei folgendermaßen aus:<br />
:<code>define Handy_Wohnzimmer PRESENCE lan-bluetooth XX:XX:XX:XX:XX:XX 192.168.0.10:5111</code><br />
<br />
Damit wird nun das Gerät nur im Wohnzimmer (Raspberry mit IP 192.168.0.10) überwacht.<br />
<br />
==== Alle Räume gemeinsam ansprechen (collectord) ====<br />
Um jedoch alle Räume gemeinsam zu verwenden, gibt es den Collector-Daemon. Dieser kennt alle presenced-Installationen im Netzwerk und führt eine koordinierte Suche nach den gewünschten Geräten durch. Sobald ein Gerät in einem Raum erkannt wurde, meldet der collectord den Status einschließlich der Angabe des Raumes, in dem das Gerät erkannt wurde.<br />
<br />
Um alle Räume zu kennen, müssen diese mit einem Config-File dem collectord mitgeteilt werden. Dieses sieht folgendermaßen aus:<br />
<br />
<pre><br />
[Schlafzimmer] # Name des Raumes (wird in FHEM als Reading angezeigt)<br />
address=192.168.179.31 # IP-Adresse oder Hostname des presenced<br />
port=5111 # TCP Port, der verwendet werden soll (standardmäßig Port 5111)<br />
presence_timeout=120 # Prüfinterval, das verwendet werden soll, wenn ein Gerät anwesend ist<br />
absence_timeout=20 # Prüfinterval, das verwendet werden soll, wenn ein Gerät abwesend ist<br />
<br />
[Wohnzimmer]<br />
address=192.168.179.34<br />
port=5111<br />
presence_timeout=180<br />
absence_timeout=20<br />
</pre><br />
<br />
Standardmäßig ist dieses Config-File unter /etc/collectord.conf zu finden. Mit dieser Konfiguration kann der Collectord gestartet werden. Es empfiehlt sich diesen mit auf dem FHEM Server zu betreiben. Die erforderliche Definition in der Fhem-Konfiguration:<br />
:<code>define Handy PRESENCE lan-bluetooth XX:XX:XX:XX:XX:XX 127.0.0.1:5222</code><br />
<br />
Sobald das Handy irgendwo in der Wohnung erkannt wurde, meldet der Collectord dies sofort an FHEM und teilt den Raum mit.<br />
<br />
Eine detaillierte Benutzung von collectord findet man in der [http://fhem.de/commandref.html#PRESENCE Commandref zum PRESENCE Modul].<br />
<br />
=== Überwachung von Geräten mit Perl-Code ===<br />
Es ist möglich zum Überwachen von Geräten eine eigene Perl-Funktion zu verwenden die dann vom PRESENCE Modul im Hintergrund aufgerufen wird.<br />
<br />
define <name> PRESENCE function {...} [ <check-interval> [ <present-check-interval> ] ]<br />
<br />
Sobald die Funktion den Rückgabewert 1 hat, ist das Gerät anwesend, bei 0 abwesend.<br />
<br />
==== Beispiel DHCP Überwachung auf Airport Basestation ====<br />
Die hier vorgestellte Überwachung der DHCP Lease auf Airport Basestations per SNMP ist absolut robust gegenüber dem Ruhezustand von iOS und setzt keine weitere Konfiguration auf dem iPhone voraus. Das Abmelden beim Verlassen des Empfangsbereiches der Basestation geschieht mit etwa 5-10 Minuten Verzögerung und ist somit auch vor kurzzeitigen Empfangsproblemen sicher. Das nebenstehende Bild (???) verdeutlicht noch mal die Unterschiede zwischen einer IP-Basierten Ping-Überwachung und der Überwachung auf Ebene der Basestation oder FritzBox.<br />
<br />
Bevor der folgende Code verwendet werden kann ist das Perl Modul Net:SNMP zu installieren (z.&nbsp;B. mit: <code>cpan install use Net::SNMP</code>).<br />
<br />
Zuerst ist folgender Code in 99_myUtils.pl einzufügen:<br />
<br />
<pre><br />
use Net::SNMP;<br />
sub<br />
snmpCheck($$)<br />
{<br />
my ($airport,$client)= @_;<br />
<br />
my $community = "public";<br />
my $host = $airport;<br />
my $oid = ".1.3.6.1.2.1.3.1.1.2";<br />
#my $oid = ".1.3.6.1.2.1.3.1.1.2.25.1.10.0.1";<br />
<br />
my ( $session, $error ) = Net::SNMP->session(<br />
-hostname => $host,<br />
-community => $community,<br />
-port => 161,<br />
-version => 1<br />
);<br />
<br />
if( !defined($session) ) {<br />
return 0;<br />
return "Can't connect to host $host.";<br />
}<br />
<br />
my @snmpoids = ();<br />
<br />
my $response = $session->get_next_request($oid);<br />
my @nextid = keys %$response;<br />
while ( @nextid && $nextid[0] && $nextid[0] =~ m/^$oid/ ) {<br />
push( @snmpoids, $nextid[0] );<br />
<br />
$response = $session->get_next_request( $nextid[0] );<br />
@nextid = keys %$response;<br />
}<br />
<br />
if( !defined($response = $session->get_request( @snmpoids ) ) ) {<br />
return 0;<br />
}<br />
<br />
foreach my $value (values %$response) {<br />
return 1 if( $value eq $client )<br />
}<br />
<br />
return 0;<br />
}<br />
</pre><br />
<br />
Danach lässt sich das Mobilgerät so überwachen:<br />
:<code>define iPhone PRESENCE function {snmpCheck("10.0.1.1","0x44d77429f35c")} 30 30</code><br />
<br />
wobei 10.0.1.1 durch die IP-Adresse der Basestation und 0x44d77429f35c durch die MAC Adresse des Geräts als HEX-Zahl ersetzt werden muss.<br />
<br />
==== Beispiel Anwesenheitserkennung mittels UniFi Controller ====<br />
<br />
Die Anwesenheitserkennung bei Geräten in Verbindung mit UniFi-Produkten funktioniert selbst dann, wenn sich die Geräte im PowerSave-Modus befinden. <br />
<br />
Beachte: Die Geräte werden erst ungefähr nach 5 Minuten, nachdem das Gerät das WLAN verlassen hat als disconnected angezeigt.<br />
<br />
define <name> PRESENCE function {ReadingsVal("<name UniFi Controller>","<name überwachendes Device>","") eq "connected" ? 1:0}<br />
<br />
== Das GEOFANCY Modul ==<br />
Das Modul ermöglicht über einen sogenannten Webhook Mechanismus (umgangssprachlich oft auch als "Push" benannt) das aktive Melden des aktuellen Standortes. Die iPhone Apps [http://geofency.com/ Geofency] und [http://geofancy.com/ Geofancy] können dann aktiv und quasi in dem Moment, wo man den Wohnbereich betritt oder verlässt, benachrichtigen. Android Nutzern können [https://play.google.com/store/apps/details?id=de.egi.geofence.geozone&hl=de EgiGeoZone Geofence] nutzen. Das geht nochmals um einiges schneller, als die Erkennung im WLAN, bei der die Anwesenheit nur in (engen) Zyklen aktiv geprüft werden muss. Gleichzeitig werden Ressourcen in FHEM geschont. Die aktuelle Implementierung im iPhone 5S mit dediziert für das Tracking zuständigem Chip ist so gut, dass der Akku ebenfalls sehr geschont wird.<br />
<br />
=== Modul in FHEM einrichten ===<br />
Das Modul ist mit einer einfachen Definition sofort betriebsbereit:<br />
:<code>define geofancy GEOFANCY geo</code><br />
<br />
Damit nimmt FHEM unter <nowiki>http://192.168.178.1:8083/fhem/geo</nowiki> entsprechende Meldungen des iPhones entgegen. Damit das nicht nur über das lokale WLAN funktioniert, bedarf es allerdings noch einiger zusätzlicher Maßnahmen. FHEM muss vom Internet erreichbar gemacht werden, dabei sollte unbedingt an die Absicherung des Zugriffs gedacht werden.<br />
<br />
Zunächst einmal habe ich bei mir eine eigene FHEMWEB Instanz dafür angelegt:<br />
<pre><br />
define WEBhook FHEMWEB 8088 global<br />
attr WEBhook column Alarms: Apartment: Living: Bedroom: Kitchen: Sonos: Residents: Weather: Bathroom: Logs: Statistics: DashboardRoom: System: hidden: all:<br />
attr WEBhook hiddenroom input,detail,save,Unsorted,Everything,CUL_HM,FS20,Commandref,style,Edit files,Select style,Logfile,Floorplans,Remote doc,FileLogs,Apartment,Bathroom,Bedroom,Kitchen,Living,Residents,System,Weather,Event monitor,NEW<br />
attr WEBhook room hidden<br />
attr WEBhook webname webhook<br />
</pre><br />
<br />
Damit ist unter der URL <nowiki>http://192.168.178.1:8088/webhook/geo</nowiki> das GEOFANCY Modul erreichbar. Ich verstecke in dieser Ansicht noch alle Räume, die ich so habe. Wer die Raumnamen allerdings kennt, kann sie trotzdem aufrufen. Die Anzeige in den Räumen kann man mit dem Attribut column und entsprechend leeren Definitionen verstecken. Nun muss man explizit den Devicenamen kennen, um noch etwas über die Konfiguration in Erfahrung bringen zu können.<br />
Auch wenn das Security-by-Obscurity ist - ich fühle mich wohler damit.<br />
<br />
=== Webhook weiter absichern ===<br />
Mit Hilfe eines [http://fhem.de/commandref.html#allowed allowed]-Devices lässt sich die FHEMWEB Instanz noch weiter absichern indem nur die tatsächlich benötigten Kommandos erlaubt werden (in diesem Fall keine) und damit alle anderen nicht erlaubten (attr,define,get,set,...) automatisch nicht mehr zur Verfügung stehen: <br />
<pre><br />
define allowedWEBhook allowed<br />
attr allowedWEBhook allowedCommands ,<br />
attr allowedWEBhook allowedDevices ,<br />
attr allowedWEBhook validFor WEBhook<br />
</pre><br />
<br />
Außerdem ist dringend zu empfehlen, den Zugriff über TLS/SSL und HTTP Basic-Authentication weiter abzusichern. Läuft FHEM auf einem Raspberry&nbsp;Pi, dann empfehle ich dazu die Konfiguration eines ReverseProxy (vorzugsweise HAproxy, Pound oder Varnish, notfalls auch Nginx oder Apache); damit ist man am flexibelsten und kann auch alle FHEMWEB Instanzen direkt über einen einzigen Port (meist 443, der HTTPS Standard Port) zusammenfassen. Ich möchte hier allerdings beschreiben, wie weit man mit FHEM Bordmitteln kommt und nehme das Beispiel einer Installation auf einer Fritzbox.<br />
<br />
Wie TLS aktiviert wird, steht in der Commandref für [[FHEMWEB]]. Um die Kommandos auf der Fritzbox ausführen zu können, muss zuerst Telnet aktiviert werden (bitte Google benutzen). Anschließend wechselt man auf der Fritzbox ins Verzeichnis /var/media/ftp/fhem und kann dann den Hinweisen aus der [http://fhem.de/commandref.html#FHEMWEB Commandref] unter dem Punkt HTTPS folgen. Letztlich fehlt noch das entsprechende Attribut:<br />
<br />
<pre><br />
attr WEBhook HTTPS<br />
</pre><br />
<br />
Als nächstes aktivieren wir Benutzername+Passwort für den Zugriff. Die commandref für allowed gibt auch hier unter dem Punkt basicAuth entsprechende Hinweise. Wir fügen hier einfach mal einen Benutzer "webhook" mit dem Passwort "Geofancy" hinzu, das sieht dann so aus:<br />
<br />
<pre><br />
attr allowedWEBhook basicAuth { "$user:$password" eq "webhook:Geofancy" }<br />
</pre><br />
<br />
Weitere Infos zur Absicherung gibt auch [[FritzBox Webzugriff absichern]].<br />
<br />
Um zu testen, ob unsere Absicherung erfolgreich war, kann man die URL <nowiki>https://192.168.178.1:8088/webhook/geo</nowiki> aufrufen (wichtig ist, dass man jetzt https und nicht mehr http eingibt; ansonsten bekommt man keine Antwort). Eine Zertifikatswarnung kann getrost ignoriert werden, verschlüsselt wird trotzdem. Es sollte auch eine Passwort Abfrage kommen und die Eingabe der entsprechenden Daten sollte dann zu einer entsprechenden Meldung vom GEOFANCY Modul führen:<br />
<br />
<pre><br />
NOK No data received, see API information on http://wiki.geofancy.com<br />
</pre><br />
<br />
Das ist ok, schließlich sind wir keine App, sondern der Mensch, der nur mal eben prüfen will :-)<br />
<br />
=== Zugriff vom Internet ermöglichen ===<br />
Das ist je nach Fritzbox und Software Version unterschiedlich. Grundsätzlich gilt: Eine Weiterleitung des ports 8088 vom Internet auf das laufende FHEM auf Port 8088 intern ist von AVM so nicht vorgesehen.<br />
Bei mir führte folgendes zum Erfolg:<br />
<br />
* Einloggen per Telnet auf der Fritzbox (ich habe FritzOS 6 installiert)<br />
* Konfiguration editieren mittels "nvi /var/flash/ar7.cfg"<br />
* Suchen nach richtiger Zeile durch Eingabe von "/internet_forwardrules" und Enter<br />
* Hinzufügen einer weiteren Zeile (Vorsicht, die bestehende Zeile endet mit ; und das muss in , umgeändert werden, so dass das ; schließlich am Ende der Zeile steht.<br />
<br />
So sieht es bei mir vorher aus:<br />
:<code>internet_forwardrules = "tcp 0.0.0.0:488 0.0.0.0:488 0";</code><br />
Hinterher:<br />
:<code>internet_forwardrules = "tcp 0.0.0.0:488 0.0.0.0:488 0", "tcp 0.0.0.0:8088 0.0.0.0:8088 0";</code><br />
<br />
Danach mittels ":x" abspeichern und sofort per "reboot" die Box neu starten, um diese Änderungen zu aktivieren. Das ist wichtig; ansonsten zeigt die Erfahrung, dass die Änderung nicht dauerhaft erhalten bleibt und die gerade gemachten Änderungen verloren gehen.<br />
<br />
Wer die Einstellungen zu "internet_forwardrules" bei sich nicht finden kann, hat womöglich eine andere Version als ich oder ein leicht anderes Gerät und bemüht am besten Google, was er tun kann, um das Gleiche zu erreichen. Möglicherweise tauchen die Einträge auch erst auf, wenn man mal über das Webinterface ein Forwarding eingerichtet hatte.<br />
<br />
Hat man einen DynDNS Dienst oder myFritz auf der Fritzbox aktiviert, so kann man jetzt auch von draußen auf den Webhook zugreifen. Das kann man prüfen, indem man das iPhone aus dem WLAN ausbucht und einmal die externe Adresse eingibt, also z.B. https://meindyndns.org:8088/webhook/geo.<br />
<br />
=== Weitere Alternativen für den Zugriff aus dem Internet ===<br />
Als Alternative zum Port Forwarding kann man sich auch per VPN in das lokale Netzwerk einwählen. iOS bietet dazu auch eine automatische Aktivierung des VPN (VPN on Demand), wie z.B. [http://forum.loxone.com/dede/netzwerk-firewall-and-security/8121-vpn-demand-ios-8-1-1-fritz-box-kleine-how.html hier] beschrieben wird.<br />
<br />
Auch eine Alternative ist, das Portforwarding nicht direkt an FHEM einzurichten, sondern an einem im Netzwerk laufenden Reverse-Proxy, der dann seinerseits die Anfragen an FHEM weiterleitet. Dies kann z.B. Apache, Nginx oder am besten HAproxy sein.<br />
Letzterer ist dabei sehr flexibel, allerdings nicht unbedingt einfach zu konfigurieren. Ein paar Inspirationen diesbezüglich gibt es z.B. [https://github.com/Hoanoho/HSE/tree/develop/lib/cfg/any/stat/etc/haproxy hier] und [https://github.com/Hoanoho/HSE/tree/develop/lib/cfg/any/dyn/etc/haproxy hier]. Wer pfSense nutzt, findet [http://loredo.me/post/116633549315/geeking-out-with-haproxy-on-pfsense-the-ultimate diesen Artikel] womöglich auch interessant. Er zeigt auch, dass mit HAproxy noch weit mehr möglich ist.<br />
Der Reverse-Proxy sollte dabei auch unbedingt der TLS Termination Point sein (TLS Offloading). Nicht nur spart man sich dann die Aktivierung von TLS in FHEM, sondern man hat auch mehr Einfluss darauf, wie TLS arbeitet (z.B. Deaktivierung von SSLv3, forcieren von TLSv1.2, nur als sicher eingestufte Cipher Suite... siehe auch Infos auf der [https://wiki.mozilla.org/Security/Server_Side_TLS Mozilla Website]).<br />
<br />
=== Einrichten in der Geof[e|a]ncy.app ===<br />
Hat das alles soweit geklappt, können endlich in der Geofency.app bzw. Geofancy.app am iPhone die gewünschten Bereiche definiert werden. Am Besten zuvor in den Global Settings die folgenden Einstellungen hinterlegen:<br />
<br />
* URL: https://meindyndns.org:8088/webhook/geo<br />
* POST (oder GET, ist egal - das FHEM Modul kann beides)<br />
* HTTP Basic Authentication: EIN (entsprechend Username und Password eintragen)<br />
<br />
Anfänglich ist es empfehlenswert noch "Notification on success" und "Notification on Failure" einzuschalten. Ersteres kann man ausmachen wenn man weiß, dass es soweit funktioniert. Über "Send Test-Request" kann man einmal einen Test schicken und erhält das Ergebnis entsprechend dargestellt. Es sollte sowas kommen wie<br />
:<code>POST Success: test OK</code>. In Geofancy.app gibt es keine Rückmeldung über den Erfolg des Testrequests. In FHEM sollten sich durch den Testrequest jedoch die Readings sofort aktualisieren (Ggf. ist ein Reload der FHEMWEB-Seite nötig da zusätzliche Tabellenzeilen nicht via Longpoll ergänzt werden). <br />
<br />
Funktioniert das soweit, kann man eine neue Lokation als sein Zuhause anlegen. Es empfiehlt sich einen ID-Namen zu setzen; dieser ist dann in FHEM als Name für die Lokation sichtbar. Für die eigene Wohnung empfiehlt sich hier "home" (da dies auch direkt vom RESIDENTS Modul so verwendet werden kann). Man kann auch Trigger für andere Standorte anlegen. FHEM weiß dann sogar, wenn ihr im Büro seid und könnte sich dabei auch unterschiedlich verhalten, als wenn ihr "auf Achse" seid. Bei letzterem ist der Status im GEOFANCY Modul "underway", was so viel heißt wie "unbekannter Aufenthaltsort".<br />
<br />
Hinweis: Zumindest für Geofancy.app liefert ein Testrequest wohl zufällige Locations zurück. Die eigenen Location-IDs werden also nicht übergeben, selbst wenn man sich in einem Geofence befindet. Um zu testen muss man sich wohl oder übel selbst bewegen ;-).<br />
<br />
=== GEOFANCY Modul individualisieren ===<br />
Die im GEOFANCY Modul dargestellten Readings sind nun in etwa so, wenn ihr euch bewegt:<br />
<br />
<pre><br />
Readings:<br />
2014-01-18 14:37:42 lastDevice -<br />
2014-01-18 14:37:42 lastDeviceUUID 51F23894-AAAA-BBBB-CCCC-0123456789AB<br />
2014-01-18 14:37:42 state dev:51F23894-AAAA-BBBB-CCCC-0123456789AB trig:test id:home lat:48.9999 long:11.9999<br />
</pre><br />
<br />
Wer genauer hinschaut sieht: Mein iPhone heißt wohl 51F23894-AAAA-BBBB-CCCC-0123456789AB.<br />
Damit nun die Readings für mein iPhone richtig angelegt werden, muss ein Device Alias gesetzt werden. Sinnvoll erscheint mir der Vorname des Besitzers:<br />
:<code>attr geofancy devAlias 51F23894-AAAA-BBBB-CCCC-0123456789AB:Julian</code><br />
<br />
Weitere Alias-Namen können mit Leerzeichen einfach angehängt werden.<br />
Jetzt werden weitere Readings angelegt, sobald GEOFANCY entsprechende Daten vom Mobilgerät empfängt:<br />
<br />
<pre><br />
Readings:<br />
2014-01-18 14:37:42 Julian arrived home<br />
2014-01-18 14:37:42 currLocLat_Julian 48.9999<br />
2014-01-18 14:37:42 currLocLong_Julian 11.9999<br />
2014-01-18 14:37:42 currLocTime_Julian 2014-01-18 14:37:42<br />
2014-01-18 14:37:42 currLoc_Julian home<br />
2014-01-17 19:18:23 lastArr Julian home<br />
2014-01-17 18:41:46 lastDep Julian Office<br />
2014-01-18 14:37:42 lastDevice Julian<br />
2014-01-18 14:37:42 lastDeviceUUID 51F23894-AAAA-BBBB-CCCC-0123456789AB<br />
2014-01-17 18:41:46 lastLocArr_Julian 2014-01-17 08:58:37<br />
2014-01-17 18:41:46 lastLocDep_Julian 2014-01-17 18:41:46<br />
2014-01-17 18:41:46 lastLocLat_Julian 48.1111<br />
2014-01-17 18:41:46 lastLocLong_Julian 11.1111<br />
2014-01-17 18:41:46 lastLoc_Julian Office<br />
2014-01-18 14:37:42 state dev:Julian trig:test id:home lat:48.9999 long:11.9999<br />
</pre><br />
<br />
Möchte man nun etwas bestimmtes tun, wenn man nach Hause kommt oder das Heim verlässt, kann man am Besten ein entsprechendes Notify auf das Reading currLoc_Name setzen. Ich aktualisiere lediglich zwei Dummies, durch die dann alle weiteren Notifies ausgelöst werden:<br />
<br />
<pre><br />
define n_Julian.Presence notify geofancy:currLoc_Julian:.home set Julian.homestatus:FILTER=STATE!=home home<br />
attr n_Julian.Presence room Residents<br />
define n_Julian.absence notify geofancy:currLoc_Julian:.underway {\<br />
if (Value("Julian.homestatus") ne "gone") {\<br />
fhem("set Julian.homestatus:FILTER=STATE!=absent absent");;\<br />
}\<br />
}<br />
define n_Julian.whereabout notify geofancy:currLoc_Julian:.* set Julian.whereabout:FILTER=STATE!=$EVTPART1 $EVTPART1<br />
</pre><br />
<br />
Wer es noch einfacher möchte (bzw. auch noch mehr Features) schaut sich einmal die neue Modulfamilie aus RESIDENTS[http://fhem.de/commandref_DE.html#RESIDENTS], ROOMMATE[http://fhem.de/commandref_DE.html#ROOMMATE] und GUEST[http://fhem.de/commandref_DE.html#GUEST] an. Diese sind direkt auf GEOFANCY abgestimmt. Dabei kann das devAlias Attribut entfallen und man hinterlegt die UUID stattdessen direkt im ROOMMATE oder GUEST Device (Attribut r*_geofenceUUIDs). Das erspart es für jeden Bewohner und jedes Device zig unterschiedliche Devices der Typen Notify, DOIF oder Watchdog anlegen und pflegen zu müssen.<br />
<br />
Wer mehr Kontrolle möchte kann natürlich bei notify, DOIF und Co. bleiben: <code>define n_rr_Julian.location notify geofancy:currLoc_Julian:.* set rr_Julian:FILTER=location!=$EVTPART1 location $EVTPART1</code>. Wobei "Julian" dabei als devAlias in GEOFANCY eingtragen wurde, rr_Julian der Name des ROOMMATE aus RESIDENTS ist. Außerdem wurden die Location-IDs in der Geofency.app bzw. Geofancy.app so gewählt, dass diese direkt einem ROOMMATE-Status entsprechen (also z.B. home, wayhome...).<br />
<br />
== Beispiele für die Nutzung der Anwesenheitserkennung ==<br />
Hier sollen Beispiele für den Nutzen von Anwesenheitserkennung aufgezeigt werden.<br />
<br />
=== Abschalten aller Verbraucher (Licht, Musikanlage) beim Verlassen der Wohnung ===<br />
Typisches Szenario: Man geht ausser Haus, aber hat vergessen im Bad das Licht aus zu machen. Allerdings geht man heutzutage fast garnicht mehr ohne Handy aus dem Haus.<br />
<br />
Nun soll FHEM in der gesamten Wohnung das Licht, sowie sonstige Verbraucher ausschalten, wenn ich länger als 15 Minuten ausser Haus bin. Dazu benötigt man zuerst eine structure, die alle Verbraucher und sonstigen Devices, die das betrifft, zusammenfasst.<br />
<br />
<pre><br />
define Gesamte_Wohnung structure Gesamtes_Licht Licht_Wohnzimmer Licht_Kueche LED_Kueche Licht_Bad Licht_Schlafzimmer AV_Receiver TV_Steckdose<br />
attr Gesamte_Wohnung room Wohnung<br />
</pre><br />
<br />
Nun kann man mittels eines watchdogs eine Überwachung für sein Handy anlegen:<br />
<br />
<pre><br />
# Überwachen der gesamten Wohnung mittels collectord sowie presenced in jedem Raum<br />
define Handy PRESENCE lan-bluetooth XX:XX:XX:XX:XX:XX 127.0.0.1:5222<br />
attr Handy event-on-change-reading state # Ein Event soll nur bei der Änderung des Anwesenheitsstatus (Reading: status) erfolgen. Wichtig für den watchdog!!!<br />
<br />
# Nach 15 Minuten Abwesenheit (Handy im Status "absent") soll die gesamte Wohnung ausgeschaltet werden.<br />
define watchdog_Anwesenheit watchdog Handy:absent 00:15 Handy:present set Gesamte_Wohnung off ; trigger watchdog_Anwesenheit .<br />
attr watchdog_Anwesenheit regexp1WontReactivate 1<br />
</pre><br />
<br />
=== Benachrichtigung bei Batteriewechsel ===<br />
Mit Hilfe des PRESENCE-Moduls kann man auch bei batteriebetriebenen Geräten eine Meldung ausgeben, sobald ein Batteriewechsel ansteht. Hier im Beispiel wird der Eve-Room-Sensor von Elgato eingebunden und anschließend mit einer DOIF-Nachricht ausgestattet.<br />
Die Bluetooth-Adresse des Sensors kann mittels eines BLE-Scanners ermittelt werden.<br />
<br />
<pre><br />
# PRESENCE-Modul für Elgato Eve Room Sensor mit Aktualisierung aller 6 Minuten<br />
define Eve_Room_BLE lan-bluetooth <Bluetooth-Adresse> 127.0.0.1:5333 360<br />
</pre><br />
<br />
Anschließend wird eine DOIF-Regel definiert, die eine Nachricht an die installiere [[FHEM_APP|FHEM App]] absendet:<br />
<pre><br />
define Eve_Room_BLE_Battery_Msg DOIF ([Eve_Room_BLE] eq "absent") (set Msg_iPhone message 'Batteriewechsel beim Eve Room Sensor im Wohnzimmer.')<br />
attr Eve_Room_BLE_Battery_Msg wait 600<br />
</pre><br />
<br />
Die Aktualisierung des PRESENCE-Eintrages sollte nicht größer sein als das WAIT-Attribut der DOIF-Regel. Ansonsten könnte eine kurze Systemstörung zum Fehlalarm führen.<br />
<br />
== Anwesenheitserkennung Bluetooth PebbleBee mit PRESENCE Modul ==<br />
Im Forum gibt es einen {{Link2Forum|Topic=28753|LinkText=langen Beitrag}} über die Einrichtung eines BT-Tag an einem RaspberryPI mit FHEM. Dabei werden Skripte wie blescan.pl und lepresenced genannt.<br />
Da mittlerweile viele neue Informationen zusammen gekommen sind wurde der Wiki Eintrag erstellt.<br />
<br />
Im Folgenden wird die Konfiguration für '''LE Deviced (z.B. Gtags,Pebbles etc.)''' und '''NICHT LE Device (z.B. IPhone)''' beschreiben.<br />
<br />
'''Wo finde ich denn lepresenced?'''<br />
<br />
lepresenced kann über Github heruntergeladen werden (Link weiter unten)<br />
<br />
'''Was ist der Vorteil gegenüber blescan.pl?'''<br />
<br />
{{Randnotiz|RNText=Beide hier beschriebenen Wege (presenced/lepresenced) können parallel auf dem selben BT-Dongle laufen, da sich die Ports unterscheiden!}}<br />
blescan.pl hat u. a. das Problem, dass dank der wundervollen Bluetooth-Implementierung unter Linux ab und zu der Scan fehlschlägt und das Interface resettet werden muss. Das tut blescan.pl auch mit aller Gewalt. Dazu kommt, dass bei längeren Scanzeiten und vielen Tags sich die Prozesse anstauen, weil immer nur auf einen Tag "gewartet" wird. Außerdem wurden mit der Einführung von lepresenced sämtliche Supportverträge gekündigt lepresenced läuft dauerhaft und merkt sich bei allen sendenden Tags den Zeitstempel des letzten Empfangs. <br />
<br />
<br />
<br />
=== Getestete Hardware/Software===<br />
* '''Raspbian System''' - wheezy, Jessie<br />
* '''BT-Dongle''' - CSL NET BT USB2.0 Stick, Bluetooth V4.0, Nano <br />'''Achtung''': Es muss ein BT V4.0 oder höher verwendet werden. Nur dieser unterstützt ''LowEnergy''<br />
* '''BT-TAG''' - Gtag von Gigaset, TrackR, UDOO Neo, PebbleBee, iTag von Unitec, X4-LIFE Multifunkti BL-Anhänger, iTag Wireless Anti, Trackr bravo<br />
<br />
=== BT Dongel am PI installieren ===<br />
<br />
Um den BT Dongle ''(hier: CSL NET BT USB2.0)'' am PI verwenden zu können, müssen die notwendigen Pakete über die Paketverwaltung von debain nachinstalliert werden.<br />
Wer bereits ein BT-Dongle installiert hat, kann diesen Schritt überspringen.<br />
<pre><br />
apt-get install bluetooth<br />
</pre><br />
Nach erfolgreicher Installation der Pakete sollte der RaspberryPI neu gestartet werden.<br />
<pre><br />
sudo reboot<br />
</pre><br />
<br />
Nach dem erfolgten Reboot bitte das Log des Raspberry auf folgende Einträge prüfen:<br />
<pre><br />
Feb 12 19:52:55 fhem kernel: [ 4.773600] Bluetooth: Core ver 2.20<br />
Feb 12 19:52:55 fhem kernel: [ 4.773748] NET: Registered protocol family 31<br />
Feb 12 19:52:55 fhem kernel: [ 4.773765] Bluetooth: HCI device and connection manager initialized<br />
Feb 12 19:52:55 fhem kernel: [ 4.773797] Bluetooth: HCI socket layer initialized<br />
Feb 12 19:52:55 fhem kernel: [ 4.773821] Bluetooth: L2CAP socket layer initialized<br />
Feb 12 19:52:55 fhem kernel: [ 4.773890] Bluetooth: SCO socket layer initialized<br />
Feb 12 19:52:55 fhem kernel: [ 4.797531] usbcore: registered new interface driver btusb<br />
</pre><br />
Sobald der BT-Dongle erkannt wurde ''leuchtet'' (wenn vorhanden) auch die ''blaue/gelbe'' LED am Dongle auf.<br />
<br />
=== BT-Tags aktivieren ===<br />
Jetzt kann der BT-Tag aktiviert werden. Bei einigen Tags muss dafür die '''Batteriesicherung''' gezogen werden.<br />
<br />
Einen Tag wird mit folgendem Befehl auf der Konsole gesucht:<br />
<source lang="bash"><br />
sudo hcitool lescan<br />
<br />
Ausgabe z.B.:<br />
LE Scan ...<br />
7C:2F:80:A1:XA:XD (unknown)<br />
7C:2F:80:A1:XA:XD Gigaset G-tag<br />
7C:2F:80:A1:X4:X1 (unknown)</source><br />
Eine Übersicht über die möglichen Befehle von hcitool gibt es mit der Eingabe von:<br />
<pre><br />
sudo hcitool<br />
<br />
Ausgabe z.B.:<br />
hcitool - HCI Tool ver 5.23<br />
Usage:<br />
hcitool [options] <command> [command parameters]<br />
Options:<br />
--help Display help<br />
-i dev HCI device<br />
Commands:<br />
dev Display local devices<br />
inq Inquire remote devices<br />
scan Scan for remote devices<br />
name Get name from remote device<br />
info Get information from remote device<br />
spinq Start periodic inquiry<br />
epinq Exit periodic inquiry<br />
cmd Submit arbitrary HCI commands<br />
con Display active connections<br />
cc Create connection to remote device<br />
dc Disconnect from remote device<br />
sr Switch master/slave role<br />
cpt Change connection packet type<br />
rssi Display connection RSSI<br />
lq Display link quality<br />
tpl Display transmit power level<br />
afh Display AFH channel map<br />
lp Set/display link policy settings<br />
lst Set/display link supervision timeout<br />
auth Request authentication<br />
enc Set connection encryption<br />
key Change connection link key<br />
clkoff Read clock offset<br />
clock Read local or remote clock<br />
lescan Start LE scan<br />
lewladd Add device to LE White List<br />
lewlrm Remove device from LE White List<br />
lewlsz Read size of LE White List<br />
lewlclr Clear LE White list<br />
lecc Create a LE Connection<br />
ledc Disconnect a LE Connection<br />
lecup LE Connection Update <br />
</pre><br />
<br />
Falls beim SCAN kein Tag gefunden wird, sollte das BT Interface neu gestartet werden. Dazu ist kein Reboot des PI notwendig.<br />
<source lang="bash"><br />
sudo hciconfig hci0 down<br />
sudo hciconfig hci0 up<br />
sudo hcitool dev<br />
</source><br />
<br />
=== Anleitung für ein LE Device (z.B. Gtags,Pebbles etc.) ===<br />
<br />
Herunterladen des Skripts lepresenced.<br />
<pre><br />
https://github.com/mhop/fhem-mirror/blob/master/fhem/contrib/PRESENCE/lepresenced<br />
</pre><br />
<br />
Zur "Installation" des Skripts folgendermaßen vorgehen:<br />
Unter /fhem manuell den Ordner „script“ anlegen:<br />
<pre><br />
mkdir script<br />
</pre><br />
Datei lepresenced reinkopieren und ausführbar machen:<br />
<pre><br />
sudo chmod +x /opt/fhem/script/lepresenced<br />
sudo chgrp -cR dialout lepresenced<br />
</pre><br />
Skript erstmalig starten:<br />
<pre><br />
sudo ./lepresenced --loglevel LOG_EMERG -d<br />
</pre><br />
Kommt beim Starten des Skript eine Fehlermeldung, müssen die Abhängigkeiten aufgelöst werden.<br />
<pre><br />
Can't locate Net/Server/Daemonize.pm in @INC (@INC contains: /etc/perl /usr/local/lib/perl/5.14.2 /usr/local/share/perl/5.14.2 /usr/lib/perl5 /usr/share/perl5 / usr/lib/perl/5.14 /usr/share/perl/5.14 /usr/local/lib/site_perl .) at /opt/fhem/lepresenced line 17.<br />
BEGIN failed--compilation aborted at /opt/fhem/lepresenced line 17.<br />
</pre><br />
Um die Abhängigkeiten aufzulösen muss folgendes nachinstalliert werden und anschließend ein Reboot durchgeführt werden.<br />
<pre><br />
sudo apt-get install libnet-server-*<br />
</pre><br />
<br />
<br />
Nach dem letzten Schritt sind alle Bedingungen für eine abschließende Konfiguration der BT-Tags in FHEM abgeschlossen worden.<br />
Jetzt kann der Tag dem FHEM-Server bekannt gemacht werden.<br />
<pre><br />
-- Name Modul Modus MAC vom Gtag IP vom PI Port Abfragezeit in Sekunden<br />
define MeinGtAG PRESENCE lan-bluetooth xx:xx:xx:xx:xx:xx 127.0.0.1:5333 120<br />
</pre><br />
<br />
Den absent und present Mode kann man einfach testen, in dem man den Gtag mit Alufolie einwickelt.<br />
<br />
=== Anleitung für ein NICHT LE Device (z.B. IPhone) ===<br />
Die Installation kann (wie in der commanref beschrieben) über Debian Pakete erfolgen.<br />
<pre><br />
.deb package for Debian (noarch): presenced-1.3.deb http://svn.code.sf.net/p/fhem/code/trunk/fhem/contrib/PRESENCE/deb/presenced-1.3.deb<br />
<br />
.deb package for Raspberry Pi (raspbian): presenced-rpi-1.3.deb http://svn.code.sf.net/p/fhem/code/trunk/fhem/contrib/PRESENCE/deb/presenced-rpi-1.3.deb<br />
</pre><br />
<br />
<pre><br />
sudo dpkg -i presenced-rpi-1.3.de<br />
</pre><br />
<br />
Installation perl script file (Auszug commanref)<br />
<pre><br />
direct perl script file: presenced http://svn.code.sf.net/p/fhem/code/trunk/fhem/contrib/PRESENCE/presenced<br />
</pre><br />
<br />
Nach dem letzten Schritt sind alle Bedingungen für eine abschließende Konfiguration der BT-Tags in FHEM abgeschlossen worden.<br />
Jetzt kann der Tag dem FHEM-Server bekannt gemacht werden.<br />
{{Randnotiz|RNText=Wenn man mit collectord arbeitet muß man die Erkennung bei allen Devices auf port 5222 setzen.<br />
lan-bluetooth xx:xx:80:xx:xx:AC 127.0.0.1:5222 20 120}}<br />
<pre><br />
-- Name Modul Modus MAC vom Gtag IP vom PI Port Abfragezeit in Sekunden<br />
define MeinGtAG PRESENCE lan-bluetooth xx:xx:xx:xx:xx:xx 127.0.0.1:5333 120<br />
</pre><br />
<br />
=== Automatischer Start ===<br />
<br />
Damit das leprecend Skript beim Systemstart mitgestartet wird, sollte eine Crontab Eintrag gesetzt werden. Alternativ die rc.local anpassen.<br />
Ersteres würde so aussehen:<br />
<br />
Ein sh-Skript mit dem Inhalt:<br />
<pre><br />
sudo start-stop-daemon -d /opt/fhem/script -S -x /opt/fhem/script/lepresenced<br />
</pre><br />
unter dem Verzeichnis /home/pi ablegen, welches sich init_start.sh nennt.<br />
<br />
Das Skript dann unter: sudo crontab -e einhängen mit folgender Folge:<br />
<pre><br />
@reboot /home/pi/init_start.sh<br />
</pre><br />
<br />
Zweiteres so:<br />
<pre><br />
sudo nano /etc/rc.local<br />
</pre><br />
<br />
Datei rc.local, freie Stelle suchen, vor "exit 0":<br />
<br />
<pre><br />
# Start lepresenced<br />
/opt/fhem/script/lepresenced --loglevel LOG_EMERG -d<br />
exit 0<br />
</pre><br />
<br />
=== Batterieüberwachung (aktuell nur G-Tags) ===<br />
<br />
Leider überträgt der G-Tag nach der Einrichtung als Device in FHEM kein Reading mit seinem aktuellen Batteriestatus.<br />
Dem wurde mit Hilfe des Forum Abhilfe geschaffen.<br />
Im Folgenden wird erläutert wie die Batterieüberwachung eingerichtet werden kann.<br />
<br />
'''Voraussetzung:'''<br />
<br />
bc - Basiscalculator [https://packages.debian.org/de/sid/bc Bc-Paket]<br />
<pre> sudo apt-get install bc </pre><br />
<br />
Anlegen eines Shellskript auf dem Raspberry System. <br />
Die Parameter <<MAC-Adresse>> und <<TagName>> müssen durch die Werte des auszulesenden G-Tags ersetzt werden.<br />
<pre><br />
#!/bin/bash<br />
stringZ=$(sudo gatttool -b 5C:2B:80:C1:14:41 --char-read --handle=0x001b)<br />
stringZ=${stringZ:33:2}<br />
stringZ=$(echo "$stringZ" | tr a-f A-F)<br />
decimal=$(echo "ibase=16; $stringZ" | bc)<br />
perl /opt/fhem/fhem.pl 7072 "setreading MeinGtag Batterie $decimal"<br />
</pre><br />
<br />
Dem Device in FHEM (hier MeinGtag) ein userReading mit dem Namen '''Batterie''' hinzufügen.<br />
Das Shellskript mit folgendem Befehl starten:<br />
<pre><br />
./GtagBatterie.sh<br />
</pre><br />
'''Wichtig ist hierbei,''' dass Skript mit "./" und nicht mit "sh" aufzurufen. Beim Aufruf mit "sh GtagBatterie.sh" produziert es einen Fehler<br />
<pre>GtagBatterie.sh: 3: GtagBatterie.sh: Bad substitution </pre><br />
<br />
Das Reading wird auf den ausgelesenen Wert der Batterie gesetzt. <br />
<br />
Hinweis: Es sollte für jeden G-Tag ein eigenes Skript abgelegt werden. Das Skript kann per crontab oder fhem Kommando (system) regelmäßig aufgerufen werden.<br />
<br />
=== Batterieüberwachung (alle Devices vom Typ "MODE=lan-bluetooth") ===<br />
<br />
Es gibt eine weitere Möglichkeit um den Batteriestatus von LE Devices abzurufen und in FHEM als Reading darzustellen.<br />
Dabei wird der Batteriezustand für alle LE Devices, die bereits in FHEM konfiguriert sind und per lepresenced überwacht werden, automatisch in einem shell-Script ermittelt.<br />
Näheres dazu im Forumartikel [https://forum.fhem.de/index.php/topic,56960.0.html [Erweiterung]: Anwesenheitserkennung/Batterieüberwachung].<br />
<br />
Vorteile:<br />
* Automatische Ermittlung aller in FHEM konfigurierten LE Devices<br />
* Möglichkeit, diese Devices alternativ manuell im Script einzutragen<br />
* Es werden nur Devices abgefragt, die im Status "present" sind, also mit ziemlicher Sicherheit auch verfügbar sind<br />
* Ein eventuell auf dem FHEM telnet-Port gesetztes Passwort kann im Script hinterlegt werden<br />
<br />
'''Voraussetzung:'''<br />
<br />
'''Funktionierendes lepresenced''' - siehe [[Anwesenheitserkennung#Anleitung_f.C3.BCr_ein_LE_Device_.28z.B._Gtags.2CPebbles_etc..29|Anleitung für ein LE Device (z.B. Gtags,Pebbles etc.)]]<br />
<br />
'''socat''' - TCP port forwarder<br />
<pre><br />
sudo apt-get update && sudo apt-get install socat<br />
</pre><br />
<br />
'''gatttool''' - Bestandteil von bluez <br />
<br />
gatttool ist auf den meisten Distributionen im bluez-Paket, allerdings nicht bei Opensuse. Dort muss man das Sourcepaket von bluez installieren und selbst kompilieren.<br />
gatttool sollte dann nach /usr/bin oder /usr/local/bin kopiert werden,<br />
<br />
<br />
Zusätzlich zu den notwendigen Erweiterungen werden für die Ausführung von gatttool '''Root-Rechte benötigt'''!<br />
<br />
Das Script selbst gibt es hier: [https://raw.githubusercontent.com/micky0867/lebattery/master/lebattery lebattery]<br />
<br />
Am Besten unter /opt/fhem/script/lebattery speichern und ausführbar machen:<br />
<source lang="bash"><br />
sudo su -<br />
mkdir /opt/fhem/script<br />
cd /opt/fhem/script<br />
wget https://raw.githubusercontent.com/micky0867/lebattery/master/lebattery<br />
chmod 755 lebattery<br />
</source><br />
<br />
Je nach Bedarf können im Script noch die folgenden 3 Parameter angepasst werden:<br />
<source lang="bash"><br />
# If allowed_telnetPort is protected by a password, add the password here<br />
TELNETPASSWORD=""<br />
# Attribute for batterylevel in FHEM<br />
ATTRIBUT="batterylevel"<br />
# Use this, if you dont want the script to determine the tags on its own<br />
LETAGS=""<br />
</source><br />
<br />
Das Skript wird dann unter root folgendermaßen gestartet:<br />
<pre><br />
/opt/fhem/script/lebattery -v<br />
</pre><br />
<br />
Ausgabe des Skripts, wenn es mit dem Verbose Parameter -v gestartet wird.<br />
<br />
Beide Devices sind vom Typ NUT mini, das Device mit dem FHEM-Namen '''nut_Micky''' ist im Status '''absent'''. Das zweite Device ist im Status '''present'''.<br />
<pre><br />
Determining address for nut_Micky ...<br />
nut_Micky is in state absent, no further action required<br />
<br />
Determining address for nut_Test ...<br />
Fetching batterylevel for nut_Test (F3:44:04:81:54:89) ...<br />
Setting batterylevel for nut_Test to 100%<br />
</pre><br />
<br />
Mein crontab-Eintrag (User root) sieht so aus:<br />
<pre><br />
3 3 * * * /opt/fhem/script/lebattery -v >/opt/fhem/script/lebattery.log 2>&1<br />
</pre><br />
Damit wird jeden Morgen um 3 Minuten nach 3 Uhr der Zustand der Batterien aller Devices ermittelt und in FHEM abgespeichert.<br> <br />
Bevor man das mit crontab macht, sollte man allerdings zunächst sicher stellen, dass es auch ohne crontab funktioniert....<br />
<br />
Bei Problemen kann man auch erstmal schauen, ob das mit dem gattool überhaupt funktioniert:<br />
<pre><br />
gatttool -t random -b <MAC-Adresse> --char-read --uuid 0x2a19<br />
<br />
handle: 0x0017 value: 64<br />
</pre><br />
In diesem Fall hat die Batterie noch 100% (hex 64).<br />
<br />
<br />
=== Anwesenheitserkennung / Anwesenheitsbenachrichtigung mit G-Tags ===<br />
<br />
Ein Skript zur Nutzung der Gigaset G-TAGs zur Alarmierung bei öffnen und schließen von Türen und zur Anwesenheitserkennung, um die Alarmierung zu aktivieren bzw. deaktivieren. <br />
Es kann verwendet werden um die Anwesenheit von mehrern Personen im Haushalt zu erkennen. Dabei wird eingeschränkt, dass nur bestimmte Personen die Alarmierung aktivieren können ( Eltern/Kind -Beziehung ).<br />
Des Weiteren werden im Beispiel die Eltern benachrichtigt wenn eins der Kinder das Haus verlässt und die Eltern nicht anwesend sind.<br />
<br />
{{Randnotiz|RNText= Namen der G-Tags in den Skripten bitte Anpassen!}}<br />
<br />
Für die ''Notify'' und die ''RESIDENTS-Erweiterung'' wird ein Dummy benötigt.<br />
<pre><br />
define Alarm dummy<br />
attr Alarm devStateIcon aktiv:secur_locked@red inaktiv:secur_open@lightgreen<br />
attr Alarm eventMap on:aktiv off:inaktiv<br />
attr Alarm setList on off<br />
attr Alarm webCmd aktiv:inaktiv<br />
attr Alarm room Alarm<br />
</pre><br />
<br />
<br />
====Mit Notify ====<br />
<pre><br />
gtag.*.presence:.* {Anwesenheit_check("$EVTPART1", "$NAME")}<br />
</pre><br />
<br />
Code für die 99_myUtils.pm<br />
<pre><br />
### GTAG ANWESENHEITS CHECK<br />
sub Anwesenheit_check($$) {<br />
my ($EVENT, $NAME) = @_;<br />
my $ALIASNAME = AttrVal($NAME,'alias',$NAME); # ALIAS des GTAGs auslesen<br />
my $GTAG1 = Value('gtag_rot'); # ELTERN<br />
my $GTAG2 = Value('gtag_schwarz'); # ELTERN<br />
<br />
Log 1, "$ALIASNAME ist $EVENT."; # LOG Eintrag erzeugen<br />
<br />
if (($EVENT eq "anwesend" && Value("Alarm") eq "aktiv") && ($NAME eq "gtag_gruen" xor $NAME eq "gtag_orange")) {<br />
fhem("set Infopush msg 'ALARMIERUNG BLEIBT AKTIV' '$ALIASNAME ist da...'");<br />
}<br />
elsif (($EVENT eq "anwesend" && Value("Alarm") eq "aktiv") && ($NAME eq "gtag_rot" xor $NAME eq "gtag_schwarz")) {<br />
fhem("set Infopush msg 'ALARMIERUNG INAKTIV' '$ALIASNAME ist da...'; set Alarm inaktiv");<br />
}<br />
elsif (($EVENT eq "unterwegs" && Value("Alarm") eq "aktiv") && ($NAME eq "gtag_gruen" xor $NAME eq "gtag_orange")) {<br />
fhem("set Infopush msg 'ALARMIERUNG BLEIBT AKTIV' '$ALIASNAME hat das Haus verlassen.'");<br />
} <br />
elsif (($EVENT eq "unterwegs" && Value("Alarm") eq "inaktiv") && ($GTAG1 eq "unterwegs" && $GTAG2 eq "unterwegs")) {<br />
fhem("set Alarm aktiv; set Infopush msg 'ALARMIERUNG AKTIV' '$ALIASNAME hat als letztes das Haus verlassen.' '' 0 ''");<br />
}<br />
}<br />
</pre><br />
<br />
<br><br />
====Mit Notify und Integration des RESIDENTS-MODUL====<br />
<br />
Der hier beschriebene Code erweitert die Funktionen unter dem Punkt 5.93.<br />
Das Notify muss daher mit der folgenden Zeile erweitert werden.<br />
<br />
<pre><br />
define Alarm_AnwesenheitCheck notify gtag.*.presence:.* { Anwesenheit_check("$EVTPART1", "$NAME"), Anwesenheit_check_resi("$NAME") }<br />
</pre><br />
<br />
Zusätzlicher Code für die 99_myUtils.pm um die RESIDENTS Funktion nutzen zu können:<br />
<pre><br />
### RESIDENTS<br />
sub Anwesenheit_check_resi($) {<br />
my ($NAME) = @_;<br />
my $ALIASNAME = AttrVal($NAME,'alias',$NAME); # ALIASNAME des GTAGs auslesen<br />
my $RESIUSER = "rr_"; # rr_ Residents Roommate rg_ für Residents Guest<br />
my $ROOMMATE = ("$RESIUSER" . "$ALIASNAME"); # Residentsname zusammenbauen<br />
<br />
if (ReadingsVal($NAME,'presence',$NAME) eq "absent") {<br />
fhem("set $ROOMMATE absent"); # Resisents Status von Roommates setzen<br />
}<br />
elsif(ReadingsVal($NAME,'presence',$NAME) eq "present") {<br />
fhem("set $ROOMMATE home"); # Resisents Status von Roommates setzen<br />
}<br />
}<br />
</pre><br />
<br />
Da bei Residents die Benutzernamen unterschiedlich sind für Bewohner (beginnend mit "rr_") und Gäste (beginnend mit "rg_") wurden nur die Bewohner berücksichtigt.<br />
<br><br />
<br />
====Mit Notify und Fenster/Tür. -Kontakt Überwachung====<br />
<br />
Erweiterung für die Überwachung von Fenster/Tür. -Kontakten. Dazu sind zwei weitere Notifys notwendig die auf die Trigger der Kontakte regagieren<br />
und so eine weitere Funktion in der 99_myUtils.pm ansprechen. Die Notifys triggern auf Kontakte die mit dem Namen Kontakt* beginnen.<br />
Sollten die eigenen Fenster/Tür. -Kontakt anderen Namen besitzen, müssen die Skripte dementsprechend angepasst werden.<br />
<pre><br />
define Alarm_Kontaktmeldung notify Kontakt.*:contact:.* {Kontakt_Meldung("$EVTPART1", "$NAME")}<br />
</pre><br />
<pre><br />
define Alarm_Sabotagealarm notify Kontakt.*.sabotageError:.on {Kontakt_Sabotage("$EVTPART1", "$NAME")}<br />
</pre><br />
<br />
Zusätzlicher Code für die 99_myUtils.pm um die TÜRKONTAKTE-Meldung nutzen zu können:<br />
<pre><br />
### TÜRKONTAKTE-Meldung/Zustand<br />
sub Kontakt_Meldung($$) {<br />
my ($EVENT, $NAME) = @_;<br />
my $ALIASNAME = AttrVal($NAME,'alias',$NAME);<br />
Log 1, "$ALIASNAME wurde $EVENT";<br />
if (ReadingsVal("Alarm", "state", "on") eq "on") {<br />
fhem("set teleBot send $ALIASNAME wurde $EVENT"); # Nachricht über Telegram<br />
# fhem("set Infopush msg '$ALIASNAME' '$ALIASNAME wurde $EVENT'"); # Nachricht über Pushover<br />
}<br />
}<br />
<br />
### TÜRKONTAKTE-Sabotagealarm<br />
<br />
sub Kontakt_Sabotage($$) {<br />
my ($EVENT, $NAME) = @_;<br />
my $ALIASNAME = AttrVal($NAME,'alias',$NAME);<br />
Log 1, "$ALIASNAME meldet Sabotagealarm";<br />
fhem("set teleBot send Alarm: $ALIASNAME meldet Sabotagealarm"); # Nachricht über Telegram<br />
# fhem("set Infopush msg 'Alarmanlage' '$ALIASNAME meldet Sabotagealarm' '' 2 ' ' 60 600 "); # Nachricht über Pushover<br />
}<br />
</pre><br />
<br><br />
<br />
==== Hinweis zur Benutzung / Fehlerhandling ====<br />
<br />
Der Alarm dummy hat den Zustand on:off. Die Bezeichnungen und Namen müssen 1:1 übernommen werden damit das Script funktioniert.<br />
Andernfalls müssen die Bezeichnungen für z.B. absent:unterwegs und present:anwesend - angepasst werden.<br />
Die Benachrichtigung kann aktuell per ''Telegram'' sowie ''Pushover'' ('''Achtung mit zweiterem sind Abokosten verbunden!''') realisiert werden.<br />
Diskussion zum Thema im Forum unter: [[https://forum.fhem.de/index.php/topic,64080.0.html]]<br />
<br><br />
<br />
=== Problemlösungen ===<br />
Falls es Probleme beim Starten des Skripts gibt bzw. man das Skript ohne Reboot des Systems neustarten möchte, kann man dies per kill Befehl erledigen.<br />
<source lang="bash"><br />
ps -ef | grep lepresenced<br />
sudo kill <pid><br />
</source><br />
<br />
Debuglevel lepresenced setzen:<br />
{{Randnotiz|RNText=Um Debug-Meldungen zu bekommen (Vorsicht bei SD-Karten-Systemen wie dem RPi) - Hierbei werden die Schreibzyklen auf die SD-Karte erhöht.}}<br />
<pre><br />
lepresenced --loglevel LOG_DEBUG<br />
</pre><br />
Nur das wichtigste Loggen:<br />
<pre><br />
lepresenced --loglevel LOG_WARNING<br />
</pre><br />
Keinerlei LOG-Einträge<br />
<pre><br />
lepresenced --loglevel LOG_EMERG<br />
</pre><br />
<br />
==== Ansprechpartner ====<br />
# {{Link2FU|5068|PatrikR}} (Patrick) für lepresenced <br />
# [[Benutzer Diskussion:Devender|Devender]] ({{Link2FU|20043|Dirk}}) für Wiki und Doku<br />
<br />
[[Kategorie:Code Snippets]]<br />
[[Kategorie:Glossary]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Diskussion:CUL&diff=18384Diskussion:CUL2017-01-09T13:09:13Z<p>Hauswart: Die Seite wurde geleert.</p>
<hr />
<div></div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Diskussion:CUL&diff=18383Diskussion:CUL2017-01-09T13:03:32Z<p>Hauswart: Die Seite wurde neu angelegt: „Ist der Kommentar zur Sendestärke einstellen nicht falsch? Laut Dokumentation: http://culfw.de/commandref.html#cmd_X Sind genau die ersten 5 Werte (00-04) o…“</p>
<hr />
<div>Ist der Kommentar zur Sendestärke einstellen nicht falsch?<br />
<br />
Laut Dokumentation: http://culfw.de/commandref.html#cmd_X<br />
<br />
Sind genau die ersten 5 Werte (00-04) ohne Ramping und 05-09 mit Ramping?<br />
<br />
Standard ist 03 (5db) und nicht 09</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Knxd&diff=17558Knxd2016-11-28T13:08:30Z<p>Hauswart: </p>
<hr />
<div>= knxd mit einem IP Gateway einrichten =<br />
Damit fhem auf den KNX Bus zugreifen kann, benötigt man ein passendes Interface<br />
<br />
Es gibt:<br />
<br />
* RS232<br />
* USB<br />
* IP<br />
<br />
Ich beschreibe die Einrichtung von knxd mit einem IP Gateway auf einen Raspberry Pi2 mit Wheezy oder Jessie.<br />
<br />
== Installation ==<br />
<br />
<br />
'''1. als erstes müssen folgende Pakete installiert werden (Referenz Debian Jessie):'''<br />
<source lang="bash"><br />
sudo apt-get install cdbs automake libtool libusb-1.0.0-dev<br />
sudo apt-get install libsystemd-daemon-dev dh-systemd<br />
</source><br />
(Bei Debian Jessie-Lite fehlt noch mehr)<br />
<br />
<br />
'''2. lib pthsem herunterladen und installieren'''<br />
<source lang="bash"><br />
wget https://www.auto.tuwien.ac.at/~mkoegler/pth/pthsem_2.0.8.tar.gz<br />
tar xzf pthsem_2.0.8.tar.gz<br />
cd pthsem-2.0.8<br />
dpkg-buildpackage -b -uc<br />
cd ..<br />
sudo dpkg -i libpthsem*.deb<br />
</source><br />
<br />
'''3. knxd herunterladen und installieren'''<br />
<source lang="bash"><br />
git clone https://github.com/knxd/knxd.git<br />
cd knxd<br />
dpkg-buildpackage -b -uc<br />
# auf BananaPi<br />
# dpkg-buildpackage -b -uc -d<br />
cd ..<br />
sudo dpkg -i knxd_*.deb knxd-tools_*.deb<br />
</source><br />
<br />
== Konfiguration ==<br />
'''1. Ohne sytemd'''<br />
<br />
es muss als nächstes die Konfigurationsdatei editiert werden.<br />
<br />
das geht mit:<br />
<source lang="bash"><br />
sudo nano /etc/default/knxd <br />
</source><br />
dann folgende Einträge anpassen:<br />
<source lang="bash"><br />
DAEMON_ARGS="-u /tmp/eib -u /var/run/knx -i -b ipt:192.168.188.XX"<br />
</source><br />
und<br />
<source lang="bash"><br />
START_KNXD=YES<br />
</source><br />
'''2. Mit systemd z. B. für Debian Jessie'''<br />
<br />
Die Konfigurationsdatei bei Jessie hat sich wegen der Nutzung von systemd geändert:<br />
<source lang="bash"><br />
sudo nano /etc/knxd.conf <br />
</source><br />
dann folgende Einträge anpassen:<br />
<source lang="bash"><br />
KNXD_OPTS=="-u /tmp/eib -u /var/run/knx -i -b ipt:192.168.188.XX"<br />
</source><br />
und<br />
<source lang="bash"><br />
START_KNXD=YES<br />
</source><br />
== knxd Status überprüfen ==<br />
<source lang="bash"><br />
/etc/init.d/knxd status<br />
</source><br />
<br />
== Links ==<br />
[[Benutzer:Marthinx]]<br />
<br />
[https://github.com/knxd/knxd Github knxd]<br />
<br />
<br />
[[Kategorie:Examples]]<br />
[[Kategorie:EIB/KNX]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Knxd&diff=17557Knxd2016-11-28T12:53:09Z<p>Hauswart: </p>
<hr />
<div>= knxd mit einem IP Gateway einrichten =<br />
Damit fhem auf den KNX Bus zugreifen kann, benötigt man ein passendes Interface<br />
<br />
Es gibt:<br />
<br />
* RS232<br />
* USB<br />
* IP<br />
<br />
Ich beschreibe die Einrichtung von knxd mit einem IP Gateway auf einen Raspberry Pi2 mit Wheezy oder Jessie.<br />
<br />
== Installation ==<br />
<br />
<br />
'''1. als erstes müssen folgende Pakete installiert werden (Referenz Debian Jessie):'''<br />
<source lang="bash"><br />
sudo apt-get install cdbs automake libtool libusb-1.0.0-dev<br />
sudo apt-get install libsystemd-daemon-dev dh-systemd<br />
</source><br />
(Bei Debian Jessie-Lite fehlt noch mehr)<br />
<br />
<br />
'''2. lib pthsem herunterladen und installieren'''<br />
<source lang="bash"><br />
wget https://www.auto.tuwien.ac.at/~mkoegler/pth/pthsem_2.0.8.tar.gz<br />
tar xzf pthsem_2.0.8.tar.gz<br />
cd pthsem-2.0.8<br />
dpkg-buildpackage -b -uc<br />
cd ..<br />
sudo dpkg -i libpthsem*.deb<br />
</source><br />
<br />
'''3. knxd herunterladen und installieren'''<br />
<source lang="bash"><br />
git clone https://github.com/knxd/knxd.git<br />
cd knxd<br />
dpkg-buildpackage -b -uc<br />
# auf BananaPi<br />
# dpkg-buildpackage -b -uc -d<br />
cd ..<br />
sudo dpkg -i knxd_*.deb knxd-tools_*.deb<br />
</source><br />
<br />
'''4. knxd konfigurieren'''<br />
<br />
es muss als nächstes die Konfigurationsdatei editiert werden.<br />
<br />
das geht mit:<br />
<source lang="bash"><br />
sudo nano /etc/default/knxd <br />
</source><br />
dann folgende Einträge anpassen:<br />
<source lang="bash"><br />
DAEMON_ARGS="-u /tmp/eib -u /var/run/knx -i -b ipt:192.168.188.XX"<br />
</source><br />
<br />
'''4a. knxd für Debian Jessie konfigurieren:'''<br />
<br />
Die Konfigurationsdatei bei Jessie hat sich wegen der Nutzung von systemd geändert:<br />
<source lang="bash"><br />
sudo nano /etc/knxd.conf <br />
</source><br />
dann folgende Einträge anpassen:<br />
<source lang="bash"><br />
KNXD_OPTS=="-u /tmp/eib -u /var/run/knx -i -b ipt:192.168.188.XX"<br />
</source><br />
'''5. knxd Status überprüfen'''<br />
<source lang="bash"><br />
/etc/init.d/knxd status<br />
</source><br />
<br />
'''6. knxd autostart einrichten'''<br />
<source lang="bash"><br />
sudo nano /etc/default/knxd <br />
</source><br />
dann folgende Einträge anpassen:<br />
<source lang="bash"><br />
START_KNXD=YES<br />
</source><br />
== Links ==<br />
[[Benutzer:Marthinx]]<br />
<br />
[https://github.com/knxd/knxd Github knxd]<br />
<br />
<br />
[[Kategorie:Examples]]<br />
[[Kategorie:EIB/KNX]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Homebridge_einrichten&diff=16812Homebridge einrichten2016-10-28T10:12:57Z<p>Hauswart: </p>
<hr />
<div>Dieses HOWTO zeigt die Installation und Erstinbetriebnahme von Homebridge. <br />
<br />
Damit kann Siri benutzt werden, um FHEM-Devices zu steuern. So können Devices angesprochen werden, die offiziell HomeKit nicht unterstützen (die Vorgehensweise wurde auf einem Intel NUC mit Ubuntu Server 14.04 LTS und auf einem Raspberry Pi mit Raspian getestet). Der WIKI-Eintrag bezieht sich hauptsächlich auf eine {{Link2Forum|Topic=32652|LinkText=Diskussion im FHEM-Forum}}. Ein Riesendank gilt vor allem {{Link2FU|430|Andre (justme1968)}}.<br />
<br />
Die Konfiguration der inzwischen aktuellen zweiten Version des Homekit-Plugins ist in einem neuen {{Link2Forum|Topic= 48558 |LinkText=Thread im FHEM-Forum}} beschrieben. Hinzugekommen ist vor allem die freie Konfigurierbarkeit der Zuordnung zwischen FHEM Device und Homekit Accessory/Service, zwischen FHEM Reading und Homekit Characteristic, das mapping vom FHEM Readingwerten zu Homekit Werten sowie das Mapping von Homekit Werten zu FHEM Set-Kommandos und Werten.<br />
<br />
Eine Sammlung funktionsfähiger Homebridge FHEM Konfiguration kann hier gefunden werden: [[Homebridge User Configs]]. Die Sammlung befindet sich noch im Aufbau.<br />
<br />
= Vorbereitung der Umgebung =<br />
<br />
== NodeJS installieren ==<br />
''Die nachfolgenden Befehle sind alle mit "sudo" prefixed. Wenn du unter "root" arbeitest oder deine Distribution einen anderen Mechanismus verwendet, so kannst du dies natürlich weglassen.''<br />
<br />
Zunächst wird das Betriebssystem (in diesem Falle Debian oder Ubuntu) auf den aktuellen Stand gebracht:<br />
<source lang="bash" style="width:50%;"><br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
sudo apt-get install build-essential libssl-dev</source><br />
<br />
Nun muss NodeJS installiert werden. Leider ist die Version im Debian Repository deutlich zu alt, daher wird mit den folgenden Befehlen das Node Repository hinzugefügt und NodeJS (in der LTS Version) entsprechend installiert:<br />
<br />
'''NodeJS V4'''<br />
<source lang="bash" style="width:50%;"><br />
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
{{Randnotiz|RNTyp=y|RNText=Bei Installation von NodeJS auf einem "alten" RasPi (B) bitte die besonderen Hinweise in {{Link2Forum|Topic=32652|Message=419325|LinkText=diesem Forenbeitrag}} beachten.}}<br />
'''NodeJS V5'''<br />
<source lang="bash" style="width:50%"><br />
curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
'''NodeJS V6'''<br />
<source lang="bash" style="width:50%"><br />
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
Damit ist NodeJS installiert.<br />
<br />
== Python, g++, MDNS installieren ==<br />
<source lang="bash" style="width:50%;"><br />
sudo apt-get install python g++ libavahi-compat-libdnssd-dev<br />
</source><br />
<br />
Nun sind alle Voraussetzungen geschaffen.<br />
<br />
= Installation von Homebridge & notwendiger Shims =<br />
Im Nachfolgenden Absatz wird die Installation von Homebridge sowie des notwendigen Plugins (Shim) für FHEM erläutert. <br />
Eventuell muss vor die Befehle ein<br />
<source lang="bash" style="width:50%;"><br />
sudo<br />
</source><br />
vorangestellt werden.<br />
== Homebridge installieren ==<br />
Die aktuelle Homebridge version wird mit<br />
<source lang="bash" style="width:50%;"><br />
npm install -g --unsafe-perm homebridge<br />
</source><br />
installiert, was eine Weile dauert. Anschließend wird der FHEM platform shim mit:<br />
<source lang="bash" style="width:60%;"><br />
npm install -g homebridge-fhem<br />
</source><br />
installiert.<br />
<br />
=== Fehler während der Installation ===<br />
Bei folgendem Fehler ist das Abrufen von Github nicht möglich.<br />
<pre>npm ERR! git clone --template=/home/hs-server-admin/.npm/_git-remotes/_templates --mirror <br />
git://github.com/KhaosT/ed25519.git /home/hs-server-admin/.npm/_git-remotes/git-github-com-KhaosT-ed25519-git-d8bdee1d: <br />
github.com[0: 192.30.252.128]: errno=Die Wartezeit für die Verbindung ist abgelaufen</pre><br />
Fehler könnte hier durch eine aktive Firewall verursacht werden.<br />
<br />
Kommt eine DNS Fehlermeldung fehlt meistens der AVAHI-DAEMON, zu installieren via<br />
<source lang="bash" style="width=50%"><br />
sudo apt-get install avahi-daemon<br />
</source><br />
<br />
Wenn npm beim Kompilieren von mdns mit der Meldung abbricht, dass "dns_sd.h" nicht gefunden wird, fehlt das Paket libavahi-compat-libdnssd-dev, zu installieren via<br />
<source lang="bash" style="width=50%"><br />
sudo apt-get install libavahi-compat-libdnssd-dev<br />
</source><br />
<br />
== Homebridge aktualisieren ==<br />
Prüfen, ob es Updates gibt:<br />
<source lang="bash" style="width:50%;"><br />
npm -g outdated<br />
</source><br />
Die aktuelle Homebridge version wird mit<br />
<source lang="bash" style="width:50%;"><br />
npm -g update homebridge<br />
</source><br />
installiert, was eine Weile dauert. Anschließend wird der FHEM platform shim mit:<br />
<source lang="bash" style="width:60%;"><br />
npm -g update homebridge-fhem<br />
</source><br />
installiert.<br />
<br />
Sollte dies nicht funktionieren, kann mit<br />
<source lang="bash" style="width:60%;"><br />
npm -g install homebridge<br />
</source><br />
bzw. <br />
<source lang="bash" style="width:60%;"><br />
npm -g install homebridge-fhem<br />
</source><br />
das Update installiert werden.<br />
<br />
= Homebridge konfigurieren =<br />
''Wichtig: Für die weiteren Schritte sollte man nicht root verwenden, sondern beispielsweise einen dedizierten Nutzer für homebridge oder der Einfachheit halber den Nutzer, unter dem auch FHEM läuft (meist "fhem").''<br />
<br />
== Einstellungen für homebridge ==<br />
Zunächst wird das Verzeichnis für die Konfigurationsdatei erstellt und in dieses gewechselt:<br />
<source lang="bash" style="width:50%;"><br />
mkdir -p ~/.homebridge<br />
cd ~/.homebridge/<br />
</source><br />
<br />
Nun muss darin noch die config.json erstellt bzw. angepasst werden:<br />
<source lang="bash" style="width:50%;"><br />
nano ~/.homebridge/config.json<br />
</source><br />
<br />
Hinweise zur Konfiguration:<br />
* "''bridge''":<br />
** "''username''": Sollte so belassen werden. Sollte später auf dem iOS Device keine Homebridge gefunden werden, so kann man hier beispielsweise den String auf 31 statt 30 enden lassen um so eine neue Homebridge vorzutäuschen.<br />
** "''port''": Sollte so belassen werden<br />
** "''pin''": Der PIN kann beliebig in dem Format xxx-xx-xxx angepasst werden. Dieser muss nur einmal bei der Einrichtung in iOS eingegeben werden.<br />
* "''platforms''": <br />
** "''platform''": Hier muss "FHEM" beibehalten werden.<br />
** "''server''": Hier muss die IP des FHEM-Servers eingetragen werden. Dabei muss Homebridge nicht auf dem selben Server laufen wie FHEM, kann aber. Wenn es auf dem gleichen Rechner läuft, dann bietet es sich an, die IP 127.0.0.1 zu verwenden.<br />
** "''port''": Hier muss der Port des gewählten FHEMWEBS eingetragen werden (muss nicht das "normale" sein, kann eine extra Instanz sein)<br />
** "''auth''": Ist FHEM nicht mit Nutzername/Password abgesichert, so kann man diese Zeile einfach entfernen.<br />
** "''filter''": Damit nicht alle Devices von Homebridge berücksichtigt werden, bietet es sich an, die Devices zu filtern. In diesem Beispiel wurden alle Devices, die über Siri steuerbar sein sollen, zusätzlich in den Raum Homekit konfiguriert.<br />
<source lang="javascript" style="width:50%;"><br />
{<br />
"bridge": {<br />
"name": "Homebridge",<br />
"username": "CC:22:3D:E3:CE:30",<br />
"port": 51826,<br />
"pin": "031-45-154"<br />
},<br />
<br />
"platforms": [<br />
{<br />
"platform": "FHEM",<br />
"name": "FHEM",<br />
"server": "127.0.0.1",<br />
"port": "8083",<br />
"auth": {"user": "FhemUser", "pass": "XXX"},<br />
"filter": "room=Homekit"<br />
}<br />
],<br />
<br />
"accessories": []<br />
}<br />
</source><br />
<br />
Wenn für FHEMWEB kein user/password vergeben ist muss die "auth" Zeile weg gelassen werden.<br />
Wird FHEM mit SSL abgesichert, so muss zusätzlich in der Sektion "platforms" noch diese Zeile (nach "port") eingefügt werden:<br />
<source lang="javascript" style="width:50%;"><br />
"ssl": true,<br />
</source><br />
<br />
Natürlich kann man auch nach beliebigen anderen Kriterien filtern. z.b. nach Device TYPE, nach subtype Attribut, ... Es können mehrere FHEM platforms Abschnitte mit eigenem Filter im config file stehen (dabei das Komma zwischen den einzelnen abschnitten nicht vergessen!) . Auch Geräte auf die mehr als ein Filterausdruck matched werden dabei nur ein mal hinzugefügt.<br />
<br />
= FHEM konfigurieren =<br />
Die benötigten Attribute werden inzwischen beim ersten Start des von hombridge-fhem automatisch auf FHEM Seite eingetragen.<br />
<br />
Mehr zu den inzwischen verfügbaren Konfigurationsmöglichkeiten findet sich auf den github und npmjs Seiten des Plugins und im ersten Beitrag des zugehörigen Thread im {{Link2Forum|Topic= 48558 |LinkText=Diskussion im FHEM-Forum}}<br />
<br />
= Start von Homebridge =<br />
<br />
== Hinweis ==<br />
Nach allen Änderungen die in FHEM gemacht werden, welche Homebridge betreffen, muss Homebridge neu gestartet werden. Wie der Neustart erfolgen muss, ist abhängig davon, wie man Homebridge gestartet hat. Bitte den entsprechenden Methoden entnehmen.<br />
<br />
== Einmaliger Manueller Start ==<br />
<source lang="bash" style="width:50%;"><br />
homebridge<br />
</source><br />
<br />
Homebridge sollte nun laufen. Hier kann man die Kommunikation nachverfolgen. Abbrechen kann das ganze mit CTRL+c (es dann auch keine Befehle mehr mit Siri möglich). Damit Siri auch Befehle ohne ständig offenes Terminal bearbeiten kann, bitten nächsten Punkt beachten.<br />
<br />
=== Fehler während des Manuellen Starts ===<br />
Kommt ein Fehler der ähnlich aussieht wie folgender, sollte zu erst die Nodesversion geprüft werden.<br />
Die Nodes version kann durch ein System Update auf eine niedrigere Version wie benötigt gedowngraded werden<br />
<source lang="bash" style="width=50%"><br />
Error: Module version mismatch. Expected 47, got 46.<br />
at Error (native)<br />
at Object.Module._extensions..node (module.js:450:18)<br />
at Module.load (module.js:356:32)<br />
at Function.Module._load (module.js:313:12)<br />
at Module.require (module.js:366:17)<br />
at require (module.js:385:17)<br />
at Object.<anonymous> (/usr/lib/node_modules/homebridge/node_modules/mdns/lib/dns_sd.js:24:20)<br />
at Module._compile (module.js:425:26)<br />
at Object.Module._extensions..js (module.js:432:10)<br />
at Module.load (module.js:356:32)<br />
</source><br />
Geprüft werden kann die Nodes Version mit:<br />
<source lang="bash" style="width=50%">node -v zeigt mir: v0.10.28, nodejs -v: v5.11.1</source><br />
Hier ist die Version v0.10.28 wobei v0.12 Mindestvorraussetzung ist.<br />
Die installation der richtigen Nodes Version kann oben am Anhang des Wiki Artikels entnommen werden.<br />
<br />
<br />
== Homebridge automatisch starten ==<br />
Es gibt verschiedene Methoden, Homebridge automatisch zu starten.<br />
<br />
=== Steuerung via FHEM ===<br />
Auf Basis der unten stehenden ''Alternativen Methode'' wurde eine Version entwickelt, mit der man auch den Status einsehen und den Restart des Dienstes aus FHEM heraus erledigen kann. Diese Version ist auf der Seite [[Homebridge Start und Status in FHEM]] im Detail beschrieben.<br />
<br />
=== Alternative Methode ===<br />
Dies startet homebridge als einen Service.<br />
<br />
==== Service anlegen ====<br />
<code><br />
sudo nano /etc/init.d/homebridge<br />
</code><br />
<br />
Code einfügen (startet den Homebridge Server als Benutzer "pi" und nimmt an, dass sich .homebridge/config.json in seinem Homeverzeichnis unter /home/pi/ befindet):<br />
<br />
<source lang=bash><br />
#!/bin/sh<br />
### BEGIN INIT INFO<br />
# Provides: homebridge<br />
# Required-Start: $network $remote_fs $syslog<br />
# Required-Stop: $remote_fs $syslog<br />
# Default-Start: 2 3 4 5<br />
# Default-Stop: 0 1 6<br />
# Short-Description: Start daemon at boot time for homebridge<br />
# Description: Enable service provided by daemon.<br />
### END INIT INFO<br />
export PATH=$PATH:/usr/local/bin<br />
export NODE_PATH=$NODE_PATH:/usr/local/lib/node_modules<br />
PID=`pidof homebridge`<br />
case "$1" in<br />
start)<br />
if ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is already running"<br />
else<br />
su - pi -c "homebridge > /dev/null 2>&1 &"<br />
echo "Homebridge starting"<br />
$0 status<br />
fi<br />
;;<br />
stop)<br />
if ! ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is not running"<br />
else<br />
kill $PID<br />
echo "Homebridge closed"<br />
fi<br />
;;<br />
restart)<br />
if ! ps -p $PID > /dev/null 2>&1; then<br />
$0 start<br />
else<br />
$0 stop<br />
$0 start<br />
fi<br />
;;<br />
status)<br />
if ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is running PID $PID"<br />
else<br />
echo "Homebridge is not running"<br />
fi<br />
;;<br />
*)<br />
echo "Usage: $0 {start|stop|status|restart}"<br />
exit 1<br />
;;<br />
esac<br />
exit 0<br />
</source><br />
<br />
==== Autostart aktivieren ====<br />
<br />
<code><br />
sudo chmod 755 /etc/init.d/homebridge<br />
<br />
sudo update-rc.d homebridge defaults<br />
</code><br />
<br />
Nun kann man mit <br />
<br />
<code><br />
sudo service homebridge start<br />
</code><br />
<br />
bzw.<br />
<br />
<code><br />
sudo /etc/init.d/homebridge start<br />
</code><br />
<br />
den Dienst starten<br />
<br />
== FHEM Device Einstellungen ==<br />
Damit die zu schaltenden Geräte überhaupt in der Homebridge aufgenommen werden muss man sie im Raum Homekit hinzufügen.<br />
<br />
Um HM-CC-RT-DN Thermostate steuern zu können, muss wie oben beschrieben folgendes attribute gesetzt werden (hier als Beispiel das Device "Heizung"):<br />
# attr Heizung subtype thermostat<br />
Für einen Dummy muss man den genericDeviceType setzen, also beispielsweise:<br />
# attr Dummy genericDeviceType switch<br />
# attr Dummy setList on off<br />
<br />
Wie bereits vorher angemerkt: fügt man ein Device hinzu oder führt eine Änderung an einem Device durch, so sollte homebridge neu gestartet werden.<br />
<br />
= HomeKit in iOS =<br />
<br />
== Einrichtung ==<br />
Um FHEM über Homebridge in iOS nutzen zu können, muss HomeKit eingerichtet werden. <br />
<br />
Es gibt verschiedene Apps. Im Folgenden wird die App EVE von Elgato empfohlen, die aus dem App-Store geladen werden muss.<br />
In der App auf:<br />
<pre style="width:50%;"><br />
Gerät hinzufügen<br />
</pre><br />
Es sollte ein Gerät mit der Bezeichnung "Homebridge" zur Auswahl erscheinen. Zur Ersteinrichtung auf PIN manuell eingeben gehen und (falls in der config.json nicht geändert):<br />
<pre style="width:50%;"><br />
031-45-154<br />
</pre><br />
eingeben.<br />
<br />
Im Anschluss können die Devices nach Belieben in verschiedene Räume zugeteilt werden, sowie Szenen und Bereiche erstellt werden.<br />
<br />
== Schalten mit Siri ==<br />
'''HolyMoly''' aus dem FHEM-Forum hat ein paar Beispiele gegeben, wie man Siri dazu bringt Devices zu schalten:<br />
<pre style="width:50%;"><br />
"Schalte alle Lampen im Obergeschoss ein."<br />
"Schalte Chloes Licht aus."<br />
"Dimme das Licht in der Küche."<br />
"Dimme das Licht im Esszimmer auf 50 %."<br />
"Stelle das Licht in der Küche am hellsten ein."<br />
"Stelle die Temperatur im Tahoe-Haus auf 22 °C ein."<br />
"Stelle das Thermostat im Erdgeschoss auf 21 °C ein.<br />
"Schalte den Drucker im Büro ein."<br />
"Siri, bereite alles für eine Party vor."<br />
"Bereite das Ambiente fürs Abendessen vor."<br />
"Aktiviere den Nachtruhemodus."<br />
</pre><br />
<br />
Mittlerweile kann Siri auch noch die Lichtfarbe von LEDs ändern.<br />
<br />
= Hinweise =<br />
<br />
== Unterstützte Geräte ==<br />
Das Fhem Plugin von {{Link2FU|430|Andre (justme1968)}} unterstützt automatisch mindestens die folgenden Geräte:<br />
<br />
switches (devices with set on and set off commands)<br />
lights (devices with set on and set off commands)<br />
HomeMatic, FS20 and ZWave dimmers (devices with set on, set off and set dim or set pct commands)<br />
HUE, WifiLight, MilightDevice, SWAP_0000002200000003 (hue, sat, bri, rgb)<br />
homematic, max and pid20 thermostats<br />
homematic, DUOFERN and FS20/IT(?) blinds<br />
homematic, MAX and FHTTK contact sensors (door, window)<br />
HM-SEC-WIN, HM-SEC-KEY<br />
presence, ROOMMATE<br />
SONOS (power, volume)<br />
harmony scenes<br />
temperaturecw and humidity sensors<br />
CO20 air quality sensor<br />
probably some more ...<br />
<br />
Über eine entsprechende Konfiguration lässt sich darüber hinaus jedes mit FHEM steuerbare Gerät auf die unterstützten Homekit typen abbilden.<br />
<br />
Die aktuelle Liste und eine Beschreibung der Konfigurationsmöglichkeiten findet sich [https://www.npmjs.com/package/homebridge-fhem auf den npmjs seiten] bzw. [https://github.com/justme-1968/homebridge-fhem auf github].<br />
<br />
== Zusätzliche Plugins ==<br />
Für manche der über FHEM steuerbaren Geräte wie z.b. MiiLight, Harmony Hub, Phillips Hue, Sonos,... gibt es eigene homekit plugins. Wenn immer möglich, empfiehlt es sich aber diese '''nicht''' zu verwenden, sondern die Steuerung über die FHEM-Integration zu realisieren, da<br />
* diese in der Regel sehr viel mächtiger und frei konfigurierbar ist<br />
* es FHEM erlaubt, als zentrale Instanz den Überblick über den aktuellen Gesamtzustand zu haben (wichtig bei Geräten, die gepollt werden) <br />
* die Ressourcen auf den angesteuerten Geräten schont, da Werte optimal gecached werden und nur eine einzige Verbindung aufgebaut wird<br />
<br />
== Hinweis für alte homebridge Versionen ==<br />
UPDATE: Homebridge funktioniert mit einer kleinen Einschränkung nun auch mit node 4.0.0. Laut<br />
[https://github.com/cflurin/homebridge-shims/wiki/Minimalist-Homebridge-on-a-Raspberry-Pi Homebridge on a Raspberry Pi] müssen die folgenden Abhängigkeiten (Dependencies) aus der '''package.json''' entfernt werden:<br />
<pre><br />
"harmonyhubjs-client": "^1.1.4",<br />
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git"<br />
</pre><br />
<br />
== Hinweis zur Geschwindigkeitsoptimierung auf einem Raspberry PI ==<br />
<br />
Damit es auf einem Raspberry schneller läuft, wird darüber hinaus empfohlen, auch diverse Abhängigkeiten aus der '''package.json''' zu entfernen:<br />
<pre><br />
"ad2usb": "git+https://github.com/alistairg/node-ad2usb.git#local",<br />
"carwingsjs": "0.0.x",<br />
"chokidar": "^1.0.5",<br />
"eibd": "^0.3.1",<br />
"elkington": "kevinohara80/elkington",<br />
"harmonyhubjs-client": "^1.1.4",<br />
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git",<br />
"lifx-api": "^1.0.1",<br />
"lifx": "git+https://github.com/magicmonkey/lifxjs.git",<br />
"node-hue-api": "^1.0.5",<br />
"node-icontrol": "^0.1.4",<br />
"node-milight-promise": "0.0.x",<br />
"tough-cookie": "^2.0.0",<br />
"sonos": "0.8.x",<br />
"telldus-live": "0.2.x",<br />
"teslams": "1.0.1",<br />
"unofficial-nest-api": "git+https://github.com/hachidorii/unofficial_nodejs_nest.git#d8d48edc952b049ff6320ef99afa7b2f04cdee98",<br />
"wemo": "0.2.x",<br />
"wink-js": "0.0.5",<br />
"komponist" : "0.1.0",<br />
"yamaha-nodejs": "0.4.x",<br />
</pre><br />
<br />
Daher zunächst ein ein Backup der Datei anlegen <br />
<pre>sudo cp package.json package.json.bkp </pre><br />
Am einfachsten geht das entfernen der Zeilen mit einem Editor, beispielsweise nano oder vi.<br />
<pre>sudo nano package.json</pre><br />
<br />
Das config file sollte dann wie folgt aussehen: Achtung vor den letzten zwei "}" am Ende darf kein Komma sein.<br />
<source lang="javascript"><br />
{<br />
"name": "homebridge",<br />
"description": "HomeKit support for the impatient",<br />
"version": "0.1.1",<br />
"scripts": {<br />
"start": "DEBUG=* node app.js || true"<br />
},<br />
"repository": {<br />
"type": "git",<br />
"url": "git://github.com/nfarina/homebridge.git"<br />
},<br />
"license": "ISC",<br />
"dependencies": {<br />
"async": "^1.4.2",<br />
"color": "0.10.x",<br />
"debug": "^2.2.0",<br />
"hap-nodejs": "^0.0.2",<br />
"isy-js": "",<br />
"mdns": "^2.2.4",<br />
"netatmo": "1.3.0",<br />
"node-cache": "3.0.0",<br />
"node-persist": "0.0.x",<br />
"node-xmpp-client": "1.0.0-alpha23",<br />
"q": "1.4.x",<br />
"queue": "^3.1.0",<br />
"request": "2.49.x",<br />
"xml2js": "0.4.x",<br />
"xmldoc": "0.1.x"<br />
}<br />
}<br />
</source><br />
<br />
== Links ==<br />
* [https://github.com/nfarina/homebridge Github homebridge]<br />
* [https://github.com/justme-1968/homebridge-fhem Github homebridge-fhem]<br />
* [https://www.npmjs.com/package/homebridge NPM homebridge]<br />
* [https://www.npmjs.com/package/homebridge-fhem NPM homebridge-fhem]<br />
<br />
[[Kategorie:HOWTOS]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Homebridge_einrichten&diff=16811Homebridge einrichten2016-10-28T10:11:57Z<p>Hauswart: /* Homebridge aktualisieren */</p>
<hr />
<div>Dieses HOWTO zeigt die Installation und Erstinbetriebnahme von Homebridge. <br />
<br />
Damit kann Siri benutzt werden, um FHEM-Devices zu steuern. So können Devices angesprochen werden, die offiziell HomeKit nicht unterstützen (die Vorgehensweise wurde auf einem Intel NUC mit Ubuntu Server 14.04 LTS und auf einem Raspberry Pi mit Raspian getestet). Der WIKI-Eintrag bezieht sich hauptsächlich auf eine {{Link2Forum|Topic=32652|LinkText=Diskussion im FHEM-Forum}}. Ein Riesendank gilt vor allem {{Link2FU|430|Andre (justme1968)}}.<br />
<br />
Die Konfiguration der inzwischen aktuellen zweiten Version des Homekit-Plugins ist in einem neuen {{Link2Forum|Topic= 48558 |LinkText=Thread im FHEM-Forum}} beschrieben. Hinzugekommen ist vor allem die freie Konfigurierbarkeit der Zuordnung zwischen FHEM Device und Homekit Accessory/Service, zwischen FHEM Reading und Homekit Characteristic, das mapping vom FHEM Readingwerten zu Homekit Werten sowie das Mapping von Homekit Werten zu FHEM Set-Kommandos und Werten.<br />
<br />
Eine Sammlung funktionsfähiger Homebridge FHEM Konfiguration kann hier gefunden werden: [[Homebridge User Configs]]. Die Sammlung befindet sich noch im Aufbau.<br />
<br />
= Vorbereitung der Umgebung =<br />
<br />
== NodeJS installieren ==<br />
''Die nachfolgenden Befehle sind alle mit "sudo" prefixed. Wenn du unter "root" arbeitest oder deine Distribution einen anderen Mechanismus verwendet, so kannst du dies natürlich weglassen.''<br />
<br />
Zunächst wird das Betriebssystem (in diesem Falle Debian oder Ubuntu) auf den aktuellen Stand gebracht:<br />
<source lang="bash" style="width:50%;"><br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
sudo apt-get install build-essential libssl-dev</source><br />
<br />
Nun muss NodeJS installiert werden. Leider ist die Version im Debian Repository deutlich zu alt, daher wird mit den folgenden Befehlen das Node Repository hinzugefügt und NodeJS (in der LTS Version) entsprechend installiert:<br />
<br />
'''NodeJS V4'''<br />
<source lang="bash" style="width:50%;"><br />
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
{{Randnotiz|RNTyp=y|RNText=Bei Installation von NodeJS auf einem "alten" RasPi (B) bitte die besonderen Hinweise in {{Link2Forum|Topic=32652|Message=419325|LinkText=diesem Forenbeitrag}} beachten.}}<br />
'''NodeJS V5'''<br />
<source lang="bash" style="width:50%"><br />
curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
'''NodeJS V6'''<br />
<source lang="bash" style="width:50%"><br />
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
Damit ist NodeJS installiert.<br />
<br />
== Python, g++, MDNS installieren ==<br />
<source lang="bash" style="width:50%;"><br />
sudo apt-get install python g++ libavahi-compat-libdnssd-dev<br />
</source><br />
<br />
Nun sind alle Voraussetzungen geschaffen.<br />
<br />
= Installation von Homebridge & notwendiger Shims =<br />
Im Nachfolgenden Absatz wird die Installation von Homebridge sowie des notwendigen Plugins (Shim) für FHEM erläutert. <br />
Eventuell muss vor die Befehle ein<br />
<source lang="bash" style="width:50%;"><br />
sudo<br />
</source><br />
vorangestellt werden.<br />
== Homebridge installieren ==<br />
Die aktuelle Homebridge version wird mit<br />
<source lang="bash" style="width:50%;"><br />
npm install -g --unsafe-perm homebridge<br />
</source><br />
installiert, was eine Weile dauert. Anschließend wird der FHEM platform shim mit:<br />
<source lang="bash" style="width:60%;"><br />
npm install -g homebridge-fhem<br />
</source><br />
installiert.<br />
<br />
== Homebridge aktualisieren ==<br />
Prüfen, ob es Updates gibt:<br />
<source lang="bash" style="width:50%;"><br />
npm -g outdated<br />
</source><br />
Die aktuelle Homebridge version wird mit<br />
<source lang="bash" style="width:50%;"><br />
npm -g update homebridge<br />
</source><br />
installiert, was eine Weile dauert. Anschließend wird der FHEM platform shim mit:<br />
<source lang="bash" style="width:60%;"><br />
npm -g update homebridge-fhem<br />
</source><br />
installiert.<br />
<br />
Sollte dies nicht funktionieren, kann mit<br />
<source lang="bash" style="width:60%;"><br />
npm -g install homebridge<br />
</source><br />
bzw. <br />
<source lang="bash" style="width:60%;"><br />
npm -g install homebridge-fhem<br />
</source><br />
das Update installiert werden.<br />
<br />
=== Fehler während der Installation ===<br />
Bei folgendem Fehler ist das Abrufen von Github nicht möglich.<br />
<pre>npm ERR! git clone --template=/home/hs-server-admin/.npm/_git-remotes/_templates --mirror <br />
git://github.com/KhaosT/ed25519.git /home/hs-server-admin/.npm/_git-remotes/git-github-com-KhaosT-ed25519-git-d8bdee1d: <br />
github.com[0: 192.30.252.128]: errno=Die Wartezeit für die Verbindung ist abgelaufen</pre><br />
Fehler könnte hier durch eine aktive Firewall verursacht werden.<br />
<br />
Kommt eine DNS Fehlermeldung fehlt meistens der AVAHI-DAEMON, zu installieren via<br />
<source lang="bash" style="width=50%"><br />
sudo apt-get install avahi-daemon<br />
</source><br />
<br />
Wenn npm beim Kompilieren von mdns mit der Meldung abbricht, dass "dns_sd.h" nicht gefunden wird, fehlt das Paket libavahi-compat-libdnssd-dev, zu installieren via<br />
<source lang="bash" style="width=50%"><br />
sudo apt-get install libavahi-compat-libdnssd-dev<br />
</source><br />
<br />
= Homebridge konfigurieren =<br />
''Wichtig: Für die weiteren Schritte sollte man nicht root verwenden, sondern beispielsweise einen dedizierten Nutzer für homebridge oder der Einfachheit halber den Nutzer, unter dem auch FHEM läuft (meist "fhem").''<br />
<br />
== Einstellungen für homebridge ==<br />
Zunächst wird das Verzeichnis für die Konfigurationsdatei erstellt und in dieses gewechselt:<br />
<source lang="bash" style="width:50%;"><br />
mkdir -p ~/.homebridge<br />
cd ~/.homebridge/<br />
</source><br />
<br />
Nun muss darin noch die config.json erstellt bzw. angepasst werden:<br />
<source lang="bash" style="width:50%;"><br />
nano ~/.homebridge/config.json<br />
</source><br />
<br />
Hinweise zur Konfiguration:<br />
* "''bridge''":<br />
** "''username''": Sollte so belassen werden. Sollte später auf dem iOS Device keine Homebridge gefunden werden, so kann man hier beispielsweise den String auf 31 statt 30 enden lassen um so eine neue Homebridge vorzutäuschen.<br />
** "''port''": Sollte so belassen werden<br />
** "''pin''": Der PIN kann beliebig in dem Format xxx-xx-xxx angepasst werden. Dieser muss nur einmal bei der Einrichtung in iOS eingegeben werden.<br />
* "''platforms''": <br />
** "''platform''": Hier muss "FHEM" beibehalten werden.<br />
** "''server''": Hier muss die IP des FHEM-Servers eingetragen werden. Dabei muss Homebridge nicht auf dem selben Server laufen wie FHEM, kann aber. Wenn es auf dem gleichen Rechner läuft, dann bietet es sich an, die IP 127.0.0.1 zu verwenden.<br />
** "''port''": Hier muss der Port des gewählten FHEMWEBS eingetragen werden (muss nicht das "normale" sein, kann eine extra Instanz sein)<br />
** "''auth''": Ist FHEM nicht mit Nutzername/Password abgesichert, so kann man diese Zeile einfach entfernen.<br />
** "''filter''": Damit nicht alle Devices von Homebridge berücksichtigt werden, bietet es sich an, die Devices zu filtern. In diesem Beispiel wurden alle Devices, die über Siri steuerbar sein sollen, zusätzlich in den Raum Homekit konfiguriert.<br />
<source lang="javascript" style="width:50%;"><br />
{<br />
"bridge": {<br />
"name": "Homebridge",<br />
"username": "CC:22:3D:E3:CE:30",<br />
"port": 51826,<br />
"pin": "031-45-154"<br />
},<br />
<br />
"platforms": [<br />
{<br />
"platform": "FHEM",<br />
"name": "FHEM",<br />
"server": "127.0.0.1",<br />
"port": "8083",<br />
"auth": {"user": "FhemUser", "pass": "XXX"},<br />
"filter": "room=Homekit"<br />
}<br />
],<br />
<br />
"accessories": []<br />
}<br />
</source><br />
<br />
Wenn für FHEMWEB kein user/password vergeben ist muss die "auth" Zeile weg gelassen werden.<br />
Wird FHEM mit SSL abgesichert, so muss zusätzlich in der Sektion "platforms" noch diese Zeile (nach "port") eingefügt werden:<br />
<source lang="javascript" style="width:50%;"><br />
"ssl": true,<br />
</source><br />
<br />
Natürlich kann man auch nach beliebigen anderen Kriterien filtern. z.b. nach Device TYPE, nach subtype Attribut, ... Es können mehrere FHEM platforms Abschnitte mit eigenem Filter im config file stehen (dabei das Komma zwischen den einzelnen abschnitten nicht vergessen!) . Auch Geräte auf die mehr als ein Filterausdruck matched werden dabei nur ein mal hinzugefügt.<br />
<br />
= FHEM konfigurieren =<br />
Die benötigten Attribute werden inzwischen beim ersten Start des von hombridge-fhem automatisch auf FHEM Seite eingetragen.<br />
<br />
Mehr zu den inzwischen verfügbaren Konfigurationsmöglichkeiten findet sich auf den github und npmjs Seiten des Plugins und im ersten Beitrag des zugehörigen Thread im {{Link2Forum|Topic= 48558 |LinkText=Diskussion im FHEM-Forum}}<br />
<br />
= Start von Homebridge =<br />
<br />
== Hinweis ==<br />
Nach allen Änderungen die in FHEM gemacht werden, welche Homebridge betreffen, muss Homebridge neu gestartet werden. Wie der Neustart erfolgen muss, ist abhängig davon, wie man Homebridge gestartet hat. Bitte den entsprechenden Methoden entnehmen.<br />
<br />
== Einmaliger Manueller Start ==<br />
<source lang="bash" style="width:50%;"><br />
homebridge<br />
</source><br />
<br />
Homebridge sollte nun laufen. Hier kann man die Kommunikation nachverfolgen. Abbrechen kann das ganze mit CTRL+c (es dann auch keine Befehle mehr mit Siri möglich). Damit Siri auch Befehle ohne ständig offenes Terminal bearbeiten kann, bitten nächsten Punkt beachten.<br />
<br />
=== Fehler während des Manuellen Starts ===<br />
Kommt ein Fehler der ähnlich aussieht wie folgender, sollte zu erst die Nodesversion geprüft werden.<br />
Die Nodes version kann durch ein System Update auf eine niedrigere Version wie benötigt gedowngraded werden<br />
<source lang="bash" style="width=50%"><br />
Error: Module version mismatch. Expected 47, got 46.<br />
at Error (native)<br />
at Object.Module._extensions..node (module.js:450:18)<br />
at Module.load (module.js:356:32)<br />
at Function.Module._load (module.js:313:12)<br />
at Module.require (module.js:366:17)<br />
at require (module.js:385:17)<br />
at Object.<anonymous> (/usr/lib/node_modules/homebridge/node_modules/mdns/lib/dns_sd.js:24:20)<br />
at Module._compile (module.js:425:26)<br />
at Object.Module._extensions..js (module.js:432:10)<br />
at Module.load (module.js:356:32)<br />
</source><br />
Geprüft werden kann die Nodes Version mit:<br />
<source lang="bash" style="width=50%">node -v zeigt mir: v0.10.28, nodejs -v: v5.11.1</source><br />
Hier ist die Version v0.10.28 wobei v0.12 Mindestvorraussetzung ist.<br />
Die installation der richtigen Nodes Version kann oben am Anhang des Wiki Artikels entnommen werden.<br />
<br />
<br />
== Homebridge automatisch starten ==<br />
Es gibt verschiedene Methoden, Homebridge automatisch zu starten.<br />
<br />
=== Steuerung via FHEM ===<br />
Auf Basis der unten stehenden ''Alternativen Methode'' wurde eine Version entwickelt, mit der man auch den Status einsehen und den Restart des Dienstes aus FHEM heraus erledigen kann. Diese Version ist auf der Seite [[Homebridge Start und Status in FHEM]] im Detail beschrieben.<br />
<br />
=== Alternative Methode ===<br />
Dies startet homebridge als einen Service.<br />
<br />
==== Service anlegen ====<br />
<code><br />
sudo nano /etc/init.d/homebridge<br />
</code><br />
<br />
Code einfügen (startet den Homebridge Server als Benutzer "pi" und nimmt an, dass sich .homebridge/config.json in seinem Homeverzeichnis unter /home/pi/ befindet):<br />
<br />
<source lang=bash><br />
#!/bin/sh<br />
### BEGIN INIT INFO<br />
# Provides: homebridge<br />
# Required-Start: $network $remote_fs $syslog<br />
# Required-Stop: $remote_fs $syslog<br />
# Default-Start: 2 3 4 5<br />
# Default-Stop: 0 1 6<br />
# Short-Description: Start daemon at boot time for homebridge<br />
# Description: Enable service provided by daemon.<br />
### END INIT INFO<br />
export PATH=$PATH:/usr/local/bin<br />
export NODE_PATH=$NODE_PATH:/usr/local/lib/node_modules<br />
PID=`pidof homebridge`<br />
case "$1" in<br />
start)<br />
if ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is already running"<br />
else<br />
su - pi -c "homebridge > /dev/null 2>&1 &"<br />
echo "Homebridge starting"<br />
$0 status<br />
fi<br />
;;<br />
stop)<br />
if ! ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is not running"<br />
else<br />
kill $PID<br />
echo "Homebridge closed"<br />
fi<br />
;;<br />
restart)<br />
if ! ps -p $PID > /dev/null 2>&1; then<br />
$0 start<br />
else<br />
$0 stop<br />
$0 start<br />
fi<br />
;;<br />
status)<br />
if ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is running PID $PID"<br />
else<br />
echo "Homebridge is not running"<br />
fi<br />
;;<br />
*)<br />
echo "Usage: $0 {start|stop|status|restart}"<br />
exit 1<br />
;;<br />
esac<br />
exit 0<br />
</source><br />
<br />
==== Autostart aktivieren ====<br />
<br />
<code><br />
sudo chmod 755 /etc/init.d/homebridge<br />
<br />
sudo update-rc.d homebridge defaults<br />
</code><br />
<br />
Nun kann man mit <br />
<br />
<code><br />
sudo service homebridge start<br />
</code><br />
<br />
bzw.<br />
<br />
<code><br />
sudo /etc/init.d/homebridge start<br />
</code><br />
<br />
den Dienst starten<br />
<br />
== FHEM Device Einstellungen ==<br />
Damit die zu schaltenden Geräte überhaupt in der Homebridge aufgenommen werden muss man sie im Raum Homekit hinzufügen.<br />
<br />
Um HM-CC-RT-DN Thermostate steuern zu können, muss wie oben beschrieben folgendes attribute gesetzt werden (hier als Beispiel das Device "Heizung"):<br />
# attr Heizung subtype thermostat<br />
Für einen Dummy muss man den genericDeviceType setzen, also beispielsweise:<br />
# attr Dummy genericDeviceType switch<br />
# attr Dummy setList on off<br />
<br />
Wie bereits vorher angemerkt: fügt man ein Device hinzu oder führt eine Änderung an einem Device durch, so sollte homebridge neu gestartet werden.<br />
<br />
= HomeKit in iOS =<br />
<br />
== Einrichtung ==<br />
Um FHEM über Homebridge in iOS nutzen zu können, muss HomeKit eingerichtet werden. <br />
<br />
Es gibt verschiedene Apps. Im Folgenden wird die App EVE von Elgato empfohlen, die aus dem App-Store geladen werden muss.<br />
In der App auf:<br />
<pre style="width:50%;"><br />
Gerät hinzufügen<br />
</pre><br />
Es sollte ein Gerät mit der Bezeichnung "Homebridge" zur Auswahl erscheinen. Zur Ersteinrichtung auf PIN manuell eingeben gehen und (falls in der config.json nicht geändert):<br />
<pre style="width:50%;"><br />
031-45-154<br />
</pre><br />
eingeben.<br />
<br />
Im Anschluss können die Devices nach Belieben in verschiedene Räume zugeteilt werden, sowie Szenen und Bereiche erstellt werden.<br />
<br />
== Schalten mit Siri ==<br />
'''HolyMoly''' aus dem FHEM-Forum hat ein paar Beispiele gegeben, wie man Siri dazu bringt Devices zu schalten:<br />
<pre style="width:50%;"><br />
"Schalte alle Lampen im Obergeschoss ein."<br />
"Schalte Chloes Licht aus."<br />
"Dimme das Licht in der Küche."<br />
"Dimme das Licht im Esszimmer auf 50 %."<br />
"Stelle das Licht in der Küche am hellsten ein."<br />
"Stelle die Temperatur im Tahoe-Haus auf 22 °C ein."<br />
"Stelle das Thermostat im Erdgeschoss auf 21 °C ein.<br />
"Schalte den Drucker im Büro ein."<br />
"Siri, bereite alles für eine Party vor."<br />
"Bereite das Ambiente fürs Abendessen vor."<br />
"Aktiviere den Nachtruhemodus."<br />
</pre><br />
<br />
Mittlerweile kann Siri auch noch die Lichtfarbe von LEDs ändern.<br />
<br />
= Hinweise =<br />
<br />
== Unterstützte Geräte ==<br />
Das Fhem Plugin von {{Link2FU|430|Andre (justme1968)}} unterstützt automatisch mindestens die folgenden Geräte:<br />
<br />
switches (devices with set on and set off commands)<br />
lights (devices with set on and set off commands)<br />
HomeMatic, FS20 and ZWave dimmers (devices with set on, set off and set dim or set pct commands)<br />
HUE, WifiLight, MilightDevice, SWAP_0000002200000003 (hue, sat, bri, rgb)<br />
homematic, max and pid20 thermostats<br />
homematic, DUOFERN and FS20/IT(?) blinds<br />
homematic, MAX and FHTTK contact sensors (door, window)<br />
HM-SEC-WIN, HM-SEC-KEY<br />
presence, ROOMMATE<br />
SONOS (power, volume)<br />
harmony scenes<br />
temperaturecw and humidity sensors<br />
CO20 air quality sensor<br />
probably some more ...<br />
<br />
Über eine entsprechende Konfiguration lässt sich darüber hinaus jedes mit FHEM steuerbare Gerät auf die unterstützten Homekit typen abbilden.<br />
<br />
Die aktuelle Liste und eine Beschreibung der Konfigurationsmöglichkeiten findet sich [https://www.npmjs.com/package/homebridge-fhem auf den npmjs seiten] bzw. [https://github.com/justme-1968/homebridge-fhem auf github].<br />
<br />
== Zusätzliche Plugins ==<br />
Für manche der über FHEM steuerbaren Geräte wie z.b. MiiLight, Harmony Hub, Phillips Hue, Sonos,... gibt es eigene homekit plugins. Wenn immer möglich, empfiehlt es sich aber diese '''nicht''' zu verwenden, sondern die Steuerung über die FHEM-Integration zu realisieren, da<br />
* diese in der Regel sehr viel mächtiger und frei konfigurierbar ist<br />
* es FHEM erlaubt, als zentrale Instanz den Überblick über den aktuellen Gesamtzustand zu haben (wichtig bei Geräten, die gepollt werden) <br />
* die Ressourcen auf den angesteuerten Geräten schont, da Werte optimal gecached werden und nur eine einzige Verbindung aufgebaut wird<br />
<br />
== Hinweis für alte homebridge Versionen ==<br />
UPDATE: Homebridge funktioniert mit einer kleinen Einschränkung nun auch mit node 4.0.0. Laut<br />
[https://github.com/cflurin/homebridge-shims/wiki/Minimalist-Homebridge-on-a-Raspberry-Pi Homebridge on a Raspberry Pi] müssen die folgenden Abhängigkeiten (Dependencies) aus der '''package.json''' entfernt werden:<br />
<pre><br />
"harmonyhubjs-client": "^1.1.4",<br />
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git"<br />
</pre><br />
<br />
== Hinweis zur Geschwindigkeitsoptimierung auf einem Raspberry PI ==<br />
<br />
Damit es auf einem Raspberry schneller läuft, wird darüber hinaus empfohlen, auch diverse Abhängigkeiten aus der '''package.json''' zu entfernen:<br />
<pre><br />
"ad2usb": "git+https://github.com/alistairg/node-ad2usb.git#local",<br />
"carwingsjs": "0.0.x",<br />
"chokidar": "^1.0.5",<br />
"eibd": "^0.3.1",<br />
"elkington": "kevinohara80/elkington",<br />
"harmonyhubjs-client": "^1.1.4",<br />
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git",<br />
"lifx-api": "^1.0.1",<br />
"lifx": "git+https://github.com/magicmonkey/lifxjs.git",<br />
"node-hue-api": "^1.0.5",<br />
"node-icontrol": "^0.1.4",<br />
"node-milight-promise": "0.0.x",<br />
"tough-cookie": "^2.0.0",<br />
"sonos": "0.8.x",<br />
"telldus-live": "0.2.x",<br />
"teslams": "1.0.1",<br />
"unofficial-nest-api": "git+https://github.com/hachidorii/unofficial_nodejs_nest.git#d8d48edc952b049ff6320ef99afa7b2f04cdee98",<br />
"wemo": "0.2.x",<br />
"wink-js": "0.0.5",<br />
"komponist" : "0.1.0",<br />
"yamaha-nodejs": "0.4.x",<br />
</pre><br />
<br />
Daher zunächst ein ein Backup der Datei anlegen <br />
<pre>sudo cp package.json package.json.bkp </pre><br />
Am einfachsten geht das entfernen der Zeilen mit einem Editor, beispielsweise nano oder vi.<br />
<pre>sudo nano package.json</pre><br />
<br />
Das config file sollte dann wie folgt aussehen: Achtung vor den letzten zwei "}" am Ende darf kein Komma sein.<br />
<source lang="javascript"><br />
{<br />
"name": "homebridge",<br />
"description": "HomeKit support for the impatient",<br />
"version": "0.1.1",<br />
"scripts": {<br />
"start": "DEBUG=* node app.js || true"<br />
},<br />
"repository": {<br />
"type": "git",<br />
"url": "git://github.com/nfarina/homebridge.git"<br />
},<br />
"license": "ISC",<br />
"dependencies": {<br />
"async": "^1.4.2",<br />
"color": "0.10.x",<br />
"debug": "^2.2.0",<br />
"hap-nodejs": "^0.0.2",<br />
"isy-js": "",<br />
"mdns": "^2.2.4",<br />
"netatmo": "1.3.0",<br />
"node-cache": "3.0.0",<br />
"node-persist": "0.0.x",<br />
"node-xmpp-client": "1.0.0-alpha23",<br />
"q": "1.4.x",<br />
"queue": "^3.1.0",<br />
"request": "2.49.x",<br />
"xml2js": "0.4.x",<br />
"xmldoc": "0.1.x"<br />
}<br />
}<br />
</source><br />
<br />
== Links ==<br />
* [https://github.com/nfarina/homebridge Github homebridge]<br />
* [https://github.com/justme-1968/homebridge-fhem Github homebridge-fhem]<br />
* [https://www.npmjs.com/package/homebridge NPM homebridge]<br />
* [https://www.npmjs.com/package/homebridge-fhem NPM homebridge-fhem]<br />
<br />
[[Kategorie:HOWTOS]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=MAX!_Zwischenstecker&diff=16605MAX! Zwischenstecker2016-10-12T11:47:12Z<p>Hauswart: </p>
<hr />
<div>{{Infobox Hardware|Bild=MaxZwischenstecker.jpg<br />
|Bildbeschreibung=MAX! Zwischenstecker<br />
|HWProtocol=Max <br />
|HWType=Aktor<br />
|HWCategory=MAX!<br />
|HWComm=868,3MHz<br />
|HWChannels=1<br />
|HWVoltage=230V<br />
|HWPowerConsumption=0,5W (Standby)<br />
|HWPoweredBy=Netz<br />
|HWSize=62x124x40 mm<br />
|HWDeviceFHEM=[http://fhem.de/commandref.html#MAX MAX]<br />
|HWManufacturer=eQ-3}}<br />
<br />
Der '''MAX! Zwischenstecker''' ist ein Schaltaktor für das [[MAX|MAX!]] Heizungssteuerungssystem. Der Schaltaktor hat die Bauform eines Zwischensteckers.<br />
<br />
== Features ==<br />
* Schaltleistung bis zu 2400W<br />
* ...<br />
<br />
== Hinweise zum Betrieb mit FHEM ==<br />
...<br />
<br />
=== Definition(en) in fhem.cfg ===<br />
:<code>define <name> MAX <type> <addr> </code><br />
<br />
=== Readings ===<br />
Der Zwischenstecker wird über "desiredTemperature on" bzw. "desiredTemperature off" an- bzw. abgeschaltet, der aktuelle Status ist aus der "valveposition" des Zwischensteckers ersichtlich (0=Schalter aus, 100=Schalter an).<br />
<br />
== Bekannte Probleme ==<br />
Der Zwischenstecker erscheint in Fhem (derzeit noch?) als "HeatingThermostat".<br />
<br />
== Weblinks ==<br />
* [http://forum.fhem.de/index.php/topic,15825.msg102795.html Anwendungsbeispiel] zur Einbindung in eine (MAX!) Heizungssteuerung<br />
* [http://www.elv-downloads.de/Assets/Produkte/13/1303/130305/Downloads/130305_zwischenstecker_data.pdf Datenblatt] (ELV)<br />
* [http://www.eq-3.de/Downloads/eq3/downloads_produktkatalog/max/bda/BC-TS-Sw-Pl_UM_GE_eQ-3_130415.pdf Bedienungsanleitung] (ELV)<br />
<br />
<!-- spezielle Sortierung in der Kategorie MAX erzwingen --><br />
{{SORTIERUNG:Zwischenstecker, MAX}}<br />
[[Kategorie:MAX|Zwischenstecker, MAX!]]<br />
[[Kategorie:Schalter (Empfänger)]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=MAX!_Zwischenstecker&diff=16604MAX! Zwischenstecker2016-10-12T11:46:54Z<p>Hauswart: Link korrigiert</p>
<hr />
<div>{{Infobox Hardware|Bild=MaxZwischenstecker.jpg<br />
|Bildbeschreibung=MAX! Zwischenstecker<br />
|HWProtocol=Max <br />
|HWType=Aktor<br />
|HWCategory=MAX!<br />
|HWComm=868,3MHz<br />
|HWChannels=1<br />
|HWVoltage=230V<br />
|HWPowerConsumption=0,5W (Standby)<br />
|HWPoweredBy=Netz<br />
|HWSize=62x124x40 mm<br />
|HWDeviceFHEM=[http://fhem.de/commandref.html#MAX MAX]<br />
|HWManufacturer=eQ-3}}<br />
<br />
Der '''MAX! Zwischenstecker''' ist ein Schaltaktor für das [[MAX|MAX!]] Heizungssteuerungssystem. Der Schaltaktor hat die Bauform eines Zwischensteckers.<br />
<br />
== Features ==<br />
* Schaltleistung bis zu 2400W<br />
* ...<br />
<br />
== Hinweise zum Betrieb mit FHEM ==<br />
...<br />
<br />
=== Definition(en) in fhem.cfg ===<br />
:<code>define <name> MAX <type> <addr> </code><br />
<br />
=== Readings ===<br />
Der Zwischenstecker wird über "desiredTemperature on" bzw. "desiredTemperature off" an- bzw. abgeschaltet, der aktuelle Status ist aus der "valveposition" des Zwischensteckers ersichtlich (0=Schalter aus, 100=Schalter an).<br />
<br />
== Bekannte Probleme ==<br />
Der Zwischenstecker erscheint in Fhem (derzeit noch?) als "HeatingThermostat".<br />
<br />
== Weblinks ==<br />
* [http://forum.fhem.de/index.php/topic,15825.msg102795.html Anwendungsbeispiel] zur Einbindung in eine (MAX!) Heizungssteuerung<br />
* [http://www.elv-downloads.de/Assets/Produkte/13/1303/130305/Downloads/130305_zwischenstecker_data.pdf Datenblatt] (ELV)<br />
* http://www.eq-3.de/Downloads/eq3/downloads_produktkatalog/max/bda/BC-TS-Sw-Pl_UM_GE_eQ-3_130415.pdf Bedienungsanleitung] (ELV)<br />
<br />
<!-- spezielle Sortierung in der Kategorie MAX erzwingen --><br />
{{SORTIERUNG:Zwischenstecker, MAX}}<br />
[[Kategorie:MAX|Zwischenstecker, MAX!]]<br />
[[Kategorie:Schalter (Empfänger)]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Homebridge_einrichten&diff=16397Homebridge einrichten2016-09-19T07:06:02Z<p>Hauswart: /* Installation von Homebridge & notwendiger Shims */ https://github.com/nfarina/homebridge/commit/4eabc4ad52c629a63377b0c92f8b83369749a274</p>
<hr />
<div>Dieses HOWTO zeigt die Installation und Erstinbetriebnahme von Homebridge. <br />
<br />
Damit kann Siri benutzt werden, um FHEM-Devices zu steuern. So können Devices angesprochen werden, die offiziell HomeKit nicht unterstützen (die Vorgehensweise wurde auf einem Intel NUC mit Ubuntu Server 14.04 LTS und auf einem Raspberry Pi mit Raspian getestet). Der WIKI-Eintrag bezieht sich hauptsächlich auf eine {{Link2Forum|Topic=32652|LinkText=Diskussion im FHEM-Forum}}. Ein Riesendank gilt vor allem {{Link2FU|430|Andre (justme1968)}}.<br />
<br />
Die Konfiguration der inzwischen aktuellen zweiten Version des Homekit-Plugins ist in einem neuen {{Link2Forum|Topic= 48558 |LinkText=Thread im FHEM-Forum}} beschrieben. Hinzugekommen ist vor allem die freie Konfigurierbarkeit der Zuordnung zwischen FHEM Device und Homekit Accessory/Service, zwischen FHEM Reading und Homekit Characteristic, das mapping vom FHEM Readingwerten zu Homekit Werten sowie das Mapping von Homekit Werten zu FHEM Set-Kommandos und Werten.<br />
<br />
Eine Sammlung funktionsfähiger Homebridge FHEM Konfiguration kann hier gefunden werden: [[Homebridge User Configs]]. Die Sammlung befindet sich noch im Aufbau.<br />
<br />
= Vorbereitung der Umgebung =<br />
<br />
== NodeJS installieren ==<br />
''Die nachfolgenden Befehle sind alle mit "sudo" prefixed. Wenn du unter "root" arbeitest oder deine Distribution einen anderen Mechanismus verwendet, so kannst du dies natürlich weglassen.''<br />
<br />
Zunächst wird das Betriebssystem (in diesem Falle Debian oder Ubuntu) auf den aktuellen Stand gebracht:<br />
<source lang="bash" style="width:50%;"><br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
sudo apt-get install build-essential libssl-dev</source><br />
<br />
Nun muss NodeJS installiert werden. Leider ist die Version im Debian Repository deutlich zu alt, daher wird mit den folgenden Befehlen das Node Repository hinzugefügt und NodeJS (in der LTS Version) entsprechend installiert:<br />
<br />
'''NodeJS V4'''<br />
<source lang="bash" style="width:50%;"><br />
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
{{Randnotiz|RNTyp=y|RNText=Bei Installation von NodeJS auf einem "alten" RasPi (B) bitte die besonderen Hinweise in {{Link2Forum|Topic=32652|Message=419325|LinkText=diesem Forenbeitrag}} beachten.}}<br />
'''NodeJS V5'''<br />
<source lang="bash" style="width:50%"><br />
curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
'''NodeJS V6'''<br />
<source lang="bash" style="width:50%"><br />
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
Damit ist NodeJS installiert.<br />
<br />
== Python, g++, MDNS installieren ==<br />
<source lang="bash" style="width:50%;"><br />
sudo apt-get install python g++ libavahi-compat-libdnssd-dev<br />
</source><br />
<br />
Nun sind alle Voraussetzungen geschaffen.<br />
<br />
= Installation von Homebridge & notwendiger Shims =<br />
Im Nachfolgenden Absatz wird die Installation von Homebridge sowie des notwendigen Plugins (Shim) für FHEM erläutert. <br />
Eventuell muss vor die Befehle ein<br />
<source lang="bash" style="width:50%;"><br />
sudo<br />
</source><br />
vorangestellt werden.<br />
== Homebridge installieren ==<br />
Die aktuelle Homebridge version wird mit<br />
<source lang="bash" style="width:50%;"><br />
npm install -g --unsafe-perm homebridge<br />
</source><br />
installiert, was eine Weile dauert. Anschließend wird der FHEM platform shim mit:<br />
<source lang="bash" style="width:60%;"><br />
npm install -g homebridge-fhem<br />
</source><br />
installiert.<br />
<br />
== Homebridge aktualisieren ==<br />
Die aktuelle Homebridge version wird mit<br />
<source lang="bash" style="width:50%;"><br />
npm update -g homebridge<br />
</source><br />
installiert, was eine Weile dauert. Anschließend wird der FHEM platform shim mit:<br />
<source lang="bash" style="width:60%;"><br />
npm update -g homebridge-fhem<br />
</source><br />
installiert.<br />
<br />
=== Fehler während der Installation ===<br />
Bei folgendem Fehler ist das Abrufen von Github nicht möglich.<br />
<pre>npm ERR! git clone --template=/home/hs-server-admin/.npm/_git-remotes/_templates --mirror <br />
git://github.com/KhaosT/ed25519.git /home/hs-server-admin/.npm/_git-remotes/git-github-com-KhaosT-ed25519-git-d8bdee1d: <br />
github.com[0: 192.30.252.128]: errno=Die Wartezeit für die Verbindung ist abgelaufen</pre><br />
Fehler könnte hier durch eine aktive Firewall verursacht werden.<br />
<br />
Kommt eine DNS Fehlermeldung fehlt meistens der AVAHI-DAEMON, zu installieren via<br />
<source lang="bash" style="width=50%"><br />
sudo apt-get install avahi-daemon<br />
</source><br />
<br />
Wenn npm beim Kompilieren von mdns mit der Meldung abbricht, dass "dns_sd.h" nicht gefunden wird, fehlt das Paket libavahi-compat-libdnssd-dev, zu installieren via<br />
<source lang="bash" style="width=50%"><br />
sudo apt-get install libavahi-compat-libdnssd-dev<br />
</source><br />
<br />
= Homebridge konfigurieren =<br />
''Wichtig: Für die weiteren Schritte sollte man nicht root verwenden, sondern beispielsweise einen dedizierten Nutzer für homebridge oder der Einfachheit halber den Nutzer, unter dem auch FHEM läuft (meist "fhem").''<br />
<br />
== Einstellungen für homebridge ==<br />
Zunächst wird das Verzeichnis für die Konfigurationsdatei erstellt und in dieses gewechselt:<br />
<source lang="bash" style="width:50%;"><br />
mkdir -p ~/.homebridge<br />
cd ~/.homebridge/<br />
</source><br />
<br />
Nun muss darin noch die config.json erstellt bzw. angepasst werden:<br />
<source lang="bash" style="width:50%;"><br />
nano ~/.homebridge/config.json<br />
</source><br />
<br />
Hinweise zur Konfiguration:<br />
* "''bridge''":<br />
** "''username''": Sollte so belassen werden. Sollte später auf dem iOS Device keine Homebridge gefunden werden, so kann man hier beispielsweise den String auf 31 statt 30 enden lassen um so eine neue Homebridge vorzutäuschen.<br />
** "''port''": Sollte so belassen werden<br />
** "''pin''": Der PIN kann beliebig in dem Format xxx-xx-xxx angepasst werden. Dieser muss nur einmal bei der Einrichtung in iOS eingegeben werden.<br />
* "''platforms''": <br />
** "''platform''": Hier muss "FHEM" beibehalten werden.<br />
** "''server''": Hier muss die IP des FHEM-Servers eingetragen werden. Dabei muss Homebridge nicht auf dem selben Server laufen wie FHEM, kann aber. Wenn es auf dem gleichen Rechner läuft, dann bietet es sich an, die IP 127.0.0.1 zu verwenden.<br />
** "''port''": Hier muss der Port des gewählten FHEMWEBS eingetragen werden (muss nicht das "normale" sein, kann eine extra Instanz sein)<br />
** "''auth''": Ist FHEM nicht mit Nutzername/Password abgesichert, so kann man diese Zeile einfach entfernen.<br />
** "''filter''": Damit nicht alle Devices von Homebridge berücksichtigt werden, bietet es sich an, die Devices zu filtern. In diesem Beispiel wurden alle Devices, die über Siri steuerbar sein sollen, zusätzlich in den Raum Homekit konfiguriert.<br />
<source lang="javascript" style="width:50%;"><br />
{<br />
"bridge": {<br />
"name": "Homebridge",<br />
"username": "CC:22:3D:E3:CE:30",<br />
"port": 51826,<br />
"pin": "031-45-154"<br />
},<br />
<br />
"platforms": [<br />
{<br />
"platform": "FHEM",<br />
"name": "FHEM",<br />
"server": "127.0.0.1",<br />
"port": "8083",<br />
"auth": {"user": "FhemUser", "pass": "XXX"},<br />
"filter": "room=Homekit"<br />
}<br />
],<br />
<br />
"accessories": []<br />
}<br />
</source><br />
<br />
Wird FHEM mit SSL abgesichert, so muss zusätzlich in der Sektion "platforms" noch diese Zeile (nach "port") eingefügt werden:<br />
<source lang="javascript" style="width:50%;"><br />
"ssl": true,<br />
</source><br />
<br />
= FHEM konfigurieren =<br />
Die benötigten Attribute werden inzwischen beim ersten Start des von hombridge-fhem automatisch auf FHEM Seite eingetragen.<br />
<br />
Mehr zu den inzwischen verfügbaren Konfigurationsmöglichkeiten findet sich auf den github und npmjs Seiten des Plugins und im ersten Beitrag des zugehörigen Thread im {{Link2Forum|Topic= 48558 |LinkText=Diskussion im FHEM-Forum}}<br />
<br />
= Start von Homebridge =<br />
<br />
== Hinweis ==<br />
Nach allen Änderungen die in FHEM gemacht werden, welche Homebridge betreffen, muss Homebridge neu gestartet werden. Wie der Neustart erfolgen muss, ist abhängig davon, wie man Homebridge gestartet hat. Bitte den entsprechenden Methoden entnehmen.<br />
<br />
== Einmaliger Manueller Start ==<br />
<source lang="bash" style="width:50%;"><br />
homebridge<br />
</source><br />
<br />
Homebridge sollte nun laufen. Hier kann man die Kommunikation nachverfolgen. Abbrechen kann das ganze mit CTRL+c (es dann auch keine Befehle mehr mit Siri möglich). Damit Siri auch Befehle ohne ständig offenes Terminal bearbeiten kann, bitten nächsten Punkt beachten.<br />
<br />
=== Fehler während des Manuellen Starts ===<br />
Kommt ein Fehler der ähnlich aussieht wie folgender, sollte zu erst die Nodesversion geprüft werden.<br />
Die Nodes version kann durch ein System Update auf eine niedrigere Version wie benötigt gedowngraded werden<br />
<source lang="bash" style="width=50%"><br />
Error: Module version mismatch. Expected 47, got 46.<br />
at Error (native)<br />
at Object.Module._extensions..node (module.js:450:18)<br />
at Module.load (module.js:356:32)<br />
at Function.Module._load (module.js:313:12)<br />
at Module.require (module.js:366:17)<br />
at require (module.js:385:17)<br />
at Object.<anonymous> (/usr/lib/node_modules/homebridge/node_modules/mdns/lib/dns_sd.js:24:20)<br />
at Module._compile (module.js:425:26)<br />
at Object.Module._extensions..js (module.js:432:10)<br />
at Module.load (module.js:356:32)<br />
</source><br />
Geprüft werden kann die Nodes Version mit:<br />
<source lang="bash" style="width=50%">node -v zeigt mir: v0.10.28, nodejs -v: v5.11.1</source><br />
Hier ist die Version v0.10.28 wobei v0.12 Mindestvorraussetzung ist.<br />
Die installation der richtigen Nodes Version kann oben am Anhang des Wiki Artikels entnommen werden.<br />
<br />
<br />
== Homebridge automatisch starten ==<br />
Es gibt verschiedene Methoden, Homebridge automatisch zu starten.<br />
<br />
=== Steuerung via FHEM ===<br />
Auf Basis der unten stehenden ''Alternativen Methode'' wurde eine Version entwickelt, mit der man auch den Status einsehen und den Restart des Dienstes aus FHEM heraus erledigen kann. Diese Version ist auf der Seite [[Homebridge Start und Status in FHEM]] im Detail beschrieben.<br />
<br />
=== Alternative Methode ===<br />
Dies startet homebridge als einen Service.<br />
<br />
==== Service anlegen ====<br />
<code><br />
sudo nano /etc/init.d/homebridge<br />
</code><br />
<br />
Code einfügen (startet den Homebridge Server als Benutzer "pi" und nimmt an, dass sich .homebridge/config.json in seinem Homeverzeichnis unter /home/pi/ befindet):<br />
<br />
<source lang=bash><br />
#!/bin/sh<br />
### BEGIN INIT INFO<br />
# Provides: homebridge<br />
# Required-Start: $network $remote_fs $syslog<br />
# Required-Stop: $remote_fs $syslog<br />
# Default-Start: 2 3 4 5<br />
# Default-Stop: 0 1 6<br />
# Short-Description: Start daemon at boot time for homebridge<br />
# Description: Enable service provided by daemon.<br />
### END INIT INFO<br />
export PATH=$PATH:/usr/local/bin<br />
export NODE_PATH=$NODE_PATH:/usr/local/lib/node_modules<br />
PID=`pidof homebridge`<br />
case "$1" in<br />
start)<br />
if ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is already running"<br />
else<br />
su - pi -c "homebridge > /dev/null 2>&1 &"<br />
echo "Homebridge starting"<br />
$0 status<br />
fi<br />
;;<br />
stop)<br />
if ! ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is not running"<br />
else<br />
kill $PID<br />
echo "Homebridge closed"<br />
fi<br />
;;<br />
restart)<br />
if ! ps -p $PID > /dev/null 2>&1; then<br />
$0 start<br />
else<br />
$0 stop<br />
$0 start<br />
fi<br />
;;<br />
status)<br />
if ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is running PID $PID"<br />
else<br />
echo "Homebridge is not running"<br />
fi<br />
;;<br />
*)<br />
echo "Usage: $0 {start|stop|status|restart}"<br />
exit 1<br />
;;<br />
esac<br />
exit 0<br />
</source><br />
<br />
==== Autostart aktivieren ====<br />
<br />
<code><br />
sudo chmod 755 /etc/init.d/homebridge<br />
<br />
sudo update-rc.d homebridge defaults<br />
</code><br />
<br />
Nun kann man mit <br />
<br />
<code><br />
sudo service homebridge start<br />
</code><br />
<br />
bzw.<br />
<br />
<code><br />
sudo /etc/init.d/homebridge start<br />
</code><br />
<br />
den Dienst starten<br />
<br />
== FHEM Device Einstellungen ==<br />
Damit die zu schaltenden Geräte überhaupt in der Homebridge aufgenommen werden muss man sie im Raum Homekit hinzufügen.<br />
<br />
Um HM-CC-RT-DN Thermostate steuern zu können, muss wie oben beschrieben folgendes attribute gesetzt werden (hier als Beispiel das Device "Heizung"):<br />
# attr Heizung subtype thermostat<br />
Für einen Dummy muss man den genericDeviceType setzen, also beispielsweise:<br />
# attr Dummy genericDeviceType switch<br />
# attr Dummy setList on off<br />
<br />
Wie bereits vorher angemerkt: fügt man ein Device hinzu oder führt eine Änderung an einem Device durch, so sollte homebridge neu gestartet werden.<br />
<br />
= HomeKit in iOS =<br />
<br />
== Einrichtung ==<br />
Um FHEM über Homebridge in iOS nutzen zu können, muss HomeKit eingerichtet werden. <br />
<br />
Es gibt verschiedene Apps. Im Folgenden wird die App EVE von Elgato empfohlen, die aus dem App-Store geladen werden muss.<br />
In der App auf:<br />
<pre style="width:50%;"><br />
Gerät hinzufügen<br />
</pre><br />
Es sollte ein Gerät mit der Bezeichnung "Homebridge" zur Auswahl erscheinen. Zur Ersteinrichtung auf PIN manuell eingeben gehen und (falls in der config.json nicht geändert):<br />
<pre style="width:50%;"><br />
031-45-154<br />
</pre><br />
eingeben.<br />
<br />
Im Anschluss können die Devices nach Belieben in verschiedene Räume zugeteilt werden, sowie Szenen und Bereiche erstellt werden.<br />
<br />
== Schalten mit Siri ==<br />
'''HolyMoly''' aus dem FHEM-Forum hat ein paar Beispiele gegeben, wie man Siri dazu bringt Devices zu schalten:<br />
<pre style="width:50%;"><br />
"Schalte alle Lampen im Obergeschoss ein."<br />
"Schalte Chloes Licht aus."<br />
"Dimme das Licht in der Küche."<br />
"Dimme das Licht im Esszimmer auf 50 %."<br />
"Stelle das Licht in der Küche am hellsten ein."<br />
"Stelle die Temperatur im Tahoe-Haus auf 22 °C ein."<br />
"Stelle das Thermostat im Erdgeschoss auf 21 °C ein.<br />
"Schalte den Drucker im Büro ein."<br />
"Siri, bereite alles für eine Party vor."<br />
"Bereite das Ambiente fürs Abendessen vor."<br />
"Aktiviere den Nachtruhemodus."<br />
</pre><br />
<br />
Mittlerweile kann Siri auch noch die Lichtfarbe von LEDs ändern.<br />
<br />
= Hinweise =<br />
<br />
== Unterstützte Geräte ==<br />
Das Fhem Plugin von {{Link2FU|430|Andre (justme1968)}} unterstützt automatisch mindestens die folgenden Geräte:<br />
<br />
switches (devices with set on and set off commands)<br />
lights (devices with set on and set off commands)<br />
HomeMatic, FS20 and ZWave dimmers (devices with set on, set off and set dim or set pct commands)<br />
HUE, WifiLight, MilightDevice, SWAP_0000002200000003 (hue, sat, bri, rgb)<br />
homematic, max and pid20 thermostats<br />
homematic, DUOFERN and FS20/IT(?) blinds<br />
homematic, MAX and FHTTK contact sensors (door, window)<br />
HM-SEC-WIN, HM-SEC-KEY<br />
presence, ROOMMATE<br />
SONOS (power, volume)<br />
harmony scenes<br />
temperaturecw and humidity sensors<br />
CO20 air quality sensor<br />
probably some more ...<br />
<br />
Über eine entsprechende Konfiguration lässt sich darüber hinaus jedes mit FHEM steuerbare Gerät auf die unterstützten Homekit typen abbilden.<br />
<br />
Die aktuelle Liste und eine Beschreibung der Konfigurationsmöglichkeiten findet sich [https://www.npmjs.com/package/homebridge-fhem auf den npmjs seiten] bzw. [https://github.com/justme-1968/homebridge-fhem auf github].<br />
<br />
== Zusätzliche Plugins ==<br />
Für manche der über FHEM steuerbaren Geräte wie z.b. MiiLight, Harmony Hub, Phillips Hue, Sonos,... gibt es eigene homekit plugins. Wenn immer möglich, empfiehlt es sich aber diese '''nicht''' zu verwenden, sondern die Steuerung über die FHEM-Integration zu realisieren, da<br />
* diese in der Regel sehr viel mächtiger und frei konfigurierbar ist<br />
* es FHEM erlaubt, als zentrale Instanz den Überblick über den aktuellen Gesamtzustand zu haben (wichtig bei Geräten, die gepollt werden) <br />
* die Ressourcen auf den angesteuerten Geräten schont, da Werte optimal gecached werden und nur eine einzige Verbindung aufgebaut wird<br />
<br />
== Hinweis für alte homebridge Versionen ==<br />
UPDATE: Homebridge funktioniert mit einer kleinen Einschränkung nun auch mit node 4.0.0. Laut<br />
[https://github.com/cflurin/homebridge-shims/wiki/Minimalist-Homebridge-on-a-Raspberry-Pi Homebridge on a Raspberry Pi] müssen die folgenden Abhängigkeiten (Dependencies) aus der '''package.json''' entfernt werden:<br />
<pre><br />
"harmonyhubjs-client": "^1.1.4",<br />
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git"<br />
</pre><br />
<br />
== Hinweis zur Geschwindigkeitsoptimierung auf einem Raspberry PI ==<br />
<br />
Damit es auf einem Raspberry schneller läuft, wird darüber hinaus empfohlen, auch diverse Abhängigkeiten aus der '''package.json''' zu entfernen:<br />
<pre><br />
"ad2usb": "git+https://github.com/alistairg/node-ad2usb.git#local",<br />
"carwingsjs": "0.0.x",<br />
"chokidar": "^1.0.5",<br />
"eibd": "^0.3.1",<br />
"elkington": "kevinohara80/elkington",<br />
"harmonyhubjs-client": "^1.1.4",<br />
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git",<br />
"lifx-api": "^1.0.1",<br />
"lifx": "git+https://github.com/magicmonkey/lifxjs.git",<br />
"node-hue-api": "^1.0.5",<br />
"node-icontrol": "^0.1.4",<br />
"node-milight-promise": "0.0.x",<br />
"tough-cookie": "^2.0.0",<br />
"sonos": "0.8.x",<br />
"telldus-live": "0.2.x",<br />
"teslams": "1.0.1",<br />
"unofficial-nest-api": "git+https://github.com/hachidorii/unofficial_nodejs_nest.git#d8d48edc952b049ff6320ef99afa7b2f04cdee98",<br />
"wemo": "0.2.x",<br />
"wink-js": "0.0.5",<br />
"komponist" : "0.1.0",<br />
"yamaha-nodejs": "0.4.x",<br />
</pre><br />
<br />
Daher zunächst ein ein Backup der Datei anlegen <br />
<pre>sudo cp package.json package.json.bkp </pre><br />
Am einfachsten geht das entfernen der Zeilen mit einem Editor, beispielsweise nano oder vi.<br />
<pre>sudo nano package.json</pre><br />
<br />
Das config file sollte dann wie folgt aussehen: Achtung vor den letzten zwei "}" am Ende darf kein Komma sein.<br />
<source lang="javascript"><br />
{<br />
"name": "homebridge",<br />
"description": "HomeKit support for the impatient",<br />
"version": "0.1.1",<br />
"scripts": {<br />
"start": "DEBUG=* node app.js || true"<br />
},<br />
"repository": {<br />
"type": "git",<br />
"url": "git://github.com/nfarina/homebridge.git"<br />
},<br />
"license": "ISC",<br />
"dependencies": {<br />
"async": "^1.4.2",<br />
"color": "0.10.x",<br />
"debug": "^2.2.0",<br />
"hap-nodejs": "^0.0.2",<br />
"isy-js": "",<br />
"mdns": "^2.2.4",<br />
"netatmo": "1.3.0",<br />
"node-cache": "3.0.0",<br />
"node-persist": "0.0.x",<br />
"node-xmpp-client": "1.0.0-alpha23",<br />
"q": "1.4.x",<br />
"queue": "^3.1.0",<br />
"request": "2.49.x",<br />
"xml2js": "0.4.x",<br />
"xmldoc": "0.1.x"<br />
}<br />
}<br />
</source><br />
<br />
== Links ==<br />
* [https://github.com/nfarina/homebridge Github homebridge]<br />
* [https://github.com/justme-1968/homebridge-fhem Github homebridge-fhem]<br />
* [https://www.npmjs.com/package/homebridge NPM homebridge]<br />
* [https://www.npmjs.com/package/homebridge-fhem NPM homebridge-fhem]<br />
<br />
[[Kategorie:HOWTOS]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=PanStamp_FensterkontaktSensor&diff=15805PanStamp FensterkontaktSensor2016-07-06T09:59:43Z<p>Hauswart: Typo</p>
<hr />
<div>{{SEITENTITEL:panStamp Fenster und Türkontakt Sensor}}<br />
<br />
{{Infobox Hardware<br />
|Bild=panStamp.jpg<br />
|Bildbeschreibung=panStamp<br />
|HWProtocol=SWAP<br />
|HWType=Sensor<br />
|HWCategory=HardwareMods<br />
|HWComm=868MHz (433/915MHz)<br />
|HWChannels=1<br />
|HWVoltage=4-36V <br />
|HWPowerConsumption= max. 120mW<br />
|HWPoweredBy=permanent, line-powered<br />
|HWSize=50 x 50 mm<br />
|HWDeviceFHEM=[http://fhem.de/commandref.html#panStamp 34_panStamp.pm] [http://fhem.de/commandref.html#SWAP 34_SWAP.pm]<br />
|ModOwner=für diesen Sketch: [http://forum.fhem.de/index.php?action=profile;u=118 Tobias]<br />
|HWManufacturer=panStamp<br />
}}<br />
<br />
<br />
[http://www.panstamp.com/home panStamps] sind [[Arduino]] Clones, die ein CC1101 Funkmodul beinhalten. Mit ihnen lassen sich Sensoren und Aktoren drahtlos an FHEM anbinden. Sie lassen sich genau wie Arduinos über die Arduino IDE oder mit dem ino Kommandozeilen Binary programmieren. Dieser bildet das Herzstück des Umweltsensors<br />
<br />
Dieser Wiki Artikel bezieht auf den panstamp NRG 2<br />
Weiterführende Information zu panStamps und den grundlegenden Modulen um sie mit Fhem zu integrieren finden sich im zugehörigen [[panStamp|Wiki Artikel]].<br />
<br />
== Beschreibung ==<br />
Dieser Sensor ist mit seiner Firmware spezialisert auf die Zustandserfassung von Fenster- und Türkontakten. Es können Gruppen gebildet werden mit Hilfe dessen 3 Zustände erfasst und an FHEM übermittelt werden können:<br />
* Offen (open)<br />
* Angeklappt (tilted)<br />
* Geschlossen (closed)<br />
<br />
Der auf dem panStamp NRG2 basierende Fensterkontaktsensor hat die folgenden Eigenschaften:<br />
<br />
'''Hardware:'''<br />
* 8x ReedkontaktEingänge<br />
* 3 LowCurrent LEDs zur Zustandsanzeige (Rot/Gelb/Grün)<br />
* Eingangsspannung von 4-36V, empfohlen wird eine Eingangsspannung von 5V aufgrund der Verlustleistung des Linearreglers<br />
* passt alles in eine 68mm Unterputzdose<br />
<br />
'''Software:'''<br />
* Konfiguration des Sendeintervalls<br />
* Konfiguration der Gruppen<br />
* Konfiguration der Blink- und Leuchtintervalls der LEDs<br />
* Übermittlung von allen 8 Eingängen<br />
* Übermittlung des Gruppenstatus<br />
<br />
<br />
===LED Verhalten===<br />
Die LEDs zeigen folgende Zustände an, es kann immer nur eine LED gleichzeitig leuchten:<br />
* Rot = mindestens eine definierte Gruppe haben den Status '''Offen'''<br />
* Gelb = mindestens eine definierte Gruppe hat den Status '''Angeklappt''', keine Gruppe ist Offen<br />
* Green = alle definierten Gruppen haben den Status '''Geschlossen'''<br />
<br />
Im Detail: Die Priorität ist die folgende:<br />
Offen -> Angeklappt -> Geschlossen<br />
Rot -> Gelb -> Grün<br />
<br />
<br />
Über die Konfiguration kann folgendes eingestellt werden:<br />
* Anzahl in Millisekunden, wie lange eine LED nach einem Event dauerhaft leuchten soll<br />
* Anzahl in Millisekunden, wie lange nach 1) die LED ausgeschaltet ist<br />
* Anzahl in Millisekunden, wie lange nach 1) und 2) die LED eingeschaltet ist<br />
<br />
<br />
zb: 30000 , 15000, 50 <br><br />
Nach einem Event (Fenster wurde betätigt) leuchtet die passende LED 30sekunden dauerhaft, danach mit einem 50ms Blinken alle 15sek<br />
<br />
<br />
Alle benötigten Dateien sind [ToDo hier] zu finden:<br />
* Sketch<br />
* EnvironmentSensor.xml<br />
* Target3001 Dateien<br />
<br />
Unbestückte Platinen können beim [http://forum.fhem.de/index.php?action=profile;u=118 Ersteller], falls vorrätig, angefragt und erworben werden.<br />
<br />
'''WICHTIG!''' Schaltplan und Platinen sind für den Panstamp NRG 2.<br />
<br />
== Schaltplan und Bauteilliste ==<br />
[[Datei:Panstamp_Fensterkontaktsensor_v1.0_Schaltplan.jpg|200px|thumb|right|Schaltplan]]<br />
[[Datei:Panstamp_Fensterkontaktsensor_v1.0_Platine_Oben.jpg|200px|thumb|right|Platinenlayout Oberseite]]<br />
[[Datei:Panstamp_Fensterkontaktsensor_v1.0_Platine_Unten.jpg|200px|thumb|right|Platinenlayout Unterseite]]<br />
[[Datei:Panstamp_Fensterkontaktsensor_v1.0_Fertig.jpg|200px|thumb|right|fertiger Aufbau]]<br />
<br />
Bauteilliste:<br />
<br />
{| class="wikitable"<br />
! Bauteil<br />
! Bezeichnung<br />
! Shop<br />
! BauteilNr<br />
|- <br />
| C1<br />
| Keramikkondensator Typ:X7R 100nF<br />
| Reichelt<br />
| X7R-G0805 100N<br />
|- <br />
| X1, X2<br />
| Keramikkondensator Typ:X7R 2,2uF<br />
| Reichelt<br />
| X7R-G0805 2,2/25<br />
|- <br />
| IC2<br />
| Linearregler LP2985<br />
| Reichelt<br />
| LP 2985 IM5-3,3<br />
|- <br />
| K1-K9 (9x)<br />
| Anreihklemme 3,5mm 2Pol <br />
| IT-WNS<br />
| AK-3.5-2-GY<br />
|- <br />
| R2, R3, R4<br />
| SMD Widerstand 1k <br />
| Reichelt<br />
IT-WNS<br />
| SMD-0805 1K<br />
R-1K-0805-1<br />
|- <br />
| X3-X10 (8x)<br />
| Keramikkondensator Typ:X7R/X5R 4,7uF<br />
| Reichelt<br />
IT-WNS<br />
| X7R-G0805 4,7/25<br />
C-4U7-0805<br />
|- <br />
| J1<br />
| Stiftleiste 1x20 pol. gewinkelt, 2,54mm <br />
| IT-WNS<br />
| SL-1x20-254-G<br />
|-<br />
| S1<br />
| SMD Mikrotaster, Drucktaster, Print Miniatur 5x5x1,5mm<br />
| Ebay<br />
|<br />
|-<br />
| IC1<br />
| panStamp NRG2<br />
| panstamp.com<br />
| panStamp NRG2<br />
|}<br />
<br />
== Hinweise zum Aufbau==<br />
<br />
<br />
<br />
== Hinweise zum Betrieb mit FHEM ==<br />
===Configuration===<br />
Nach upload des Sketches auf den Panstamp ist zuerst die korrekte Kennung über das Register 09 sowie der gewünschte Sendezyklus über das Register 0A zu setzen (siehe [[panStamp#Neue_panStamps_in_Betrieb_nehmen|Inbetriebname im Wiki Artikel]] zum den panStamps).<br />
Anschließend ist die Konfiguration mittels Register 0B zu setzen:<br />
{| class="wikitable"<br />
! Bezeichnung<br />
! Länge<br />
! Position<br />
! Beschreibung<br />
|-<br />
| Gruppe_Pin10<br />
| 1 Byte<br />
| 0<br />
| Nummer der Gruppe für den ReedEingang D10, Erlaubt: 1-7, 0 ist deaktiviert<br />
|-<br />
| Gruppe_Pin11<br />
| 1 Byte<br />
| 1<br />
| Nummer der Gruppe für den ReedEingang D11, Erlaubt: 1-7, 0 ist deaktiviert<br />
|-<br />
| Gruppe_Pin12<br />
| 1 Byte<br />
| 2<br />
| Nummer der Gruppe für den ReedEingang D12, Erlaubt: 1-7, 0 ist deaktiviert<br />
|-<br />
| Gruppe_Pin13<br />
| 1 Byte<br />
| 3<br />
| Nummer der Gruppe für den ReedEingang D13, Erlaubt: 1-7, 0 ist deaktiviert<br />
|-<br />
| Gruppe_Pin14<br />
| 1 Byte<br />
| 4<br />
| Nummer der Gruppe für den ReedEingang D14, Erlaubt: 1-7, 0 ist deaktiviert<br />
|-<br />
| Gruppe_Pin15<br />
| 1 Byte<br />
| 5<br />
| Nummer der Gruppe für den ReedEingang D15, Erlaubt: 1-7, 0 ist deaktiviert<br />
|-<br />
| Gruppe_Pin16<br />
| 1 Byte<br />
| 6<br />
| Nummer der Gruppe für den ReedEingang D16, Erlaubt: 1-7, 0 ist deaktiviert<br />
|-<br />
| Gruppe_Pin17<br />
| 1 Byte<br />
| 7<br />
| Nummer der Gruppe für den ReedEingang D17, Erlaubt: 1-7, 0 ist deaktiviert<br />
|-<br />
| BlinkOnEvtTime<br />
| 2 Byte <br />
| 8-9<br />
| Dauer in ms, wie lange die LED nach einem Event dauerleuchten soll<br />
|-<br />
| BlinkOnIdleTime<br />
| 2 Byte <br />
| 10-11<br />
| Dauer in ms, wie lange die LED im Idle-Modus dauerleuchten soll<br />
|-<br />
| BlinkOffTime<br />
| 2 Byte <br />
| 12-13<br />
| Dauer in ms, wie lange die LED im Idle-Modus aus sein soll<br />
|}<br />
<br />
<br />
===Setzen der Konfiguration===<br />
Ein Register ist als Hex-Wert zu setzen. Folgende Tabelle zeigt eine exemplarische Konfiguration:<br />
{| class="wikitable"<br />
! SubRegister<br />
! Wert<br />
! Binär Wert<br />
! Hex Wert<br />
! Comments<br />
|-<br />
| Gruppe_Pin10<br />
| 1<br />
| 1<br />
| 01<br />
| Zuordnung D10 zur Gruppe 1<br />
|-<br />
| Gruppe_Pin11<br />
| 1<br />
| 1<br />
| 01<br />
| Zuordnung D11 zur Gruppe 1<br />
|-<br />
| Gruppe_Pin12<br />
| 2<br />
| 2<br />
| 02<br />
| Zuordnung D12 zur Gruppe 2<br />
|-<br />
| Gruppe_Pin13<br />
| 2<br />
| 2<br />
| 02<br />
| Zuordnung D13 zur Gruppe 2<br />
|-<br />
| Gruppe_Pin14<br />
| 3<br />
| 3<br />
| 03<br />
| Zuordnung D14 zur Gruppe 3<br />
|-<br />
| Gruppe_Pin15<br />
| 0<br />
| 0<br />
| 00<br />
| Deaktivierung D15<br />
|-<br />
| Gruppe_Pin16<br />
| 0<br />
| 0<br />
| 00<br />
| Deaktivierung D16<br />
|-<br />
| Gruppe_Pin17<br />
| 0<br />
| 0<br />
| 00<br />
| Deaktivierung D17<br />
|-<br />
| BlinkOnEvtTime<br />
| 5000<br />
| 1001110001000<br />
| 1388<br />
| Bei einem Event leuchtet die LED 5sek dauerhaft<br />
|-<br />
| BlinkOnIdleTime<br />
| 50<br />
| 110010<br />
| 0032<br />
| Im Idle Mode leuchtet die LED 50ms<br />
|-<br />
| BlinkOffTime<br />
| 10000<br />
| 10011100010000<br />
| 2710<br />
| Im Idle Mode leuchtet die LED nur alle 10sek<br />
|}<br />
<br />
<br />
In obigem Fall ist das Konfigurationsregister wie folgt aufgebaut: ''2710 0032 1388 00 00 00 03 02 02 01 01''<br><br />
Aufgrunddessen wird die Konfiguration folgendermaßen gesetzt:<br />
set <MySwapDevice> regSet 0B2710003213880000000302020101<br />
<br />
Es ist auch möglich die einzelnen Endpoints unabhängig voneinander zu setzen. z.B.:<br />
set <MySwapDevice> regSet 0B.2 02<br />
<br />
Diese Konfiguration bedeutet folgendes:<br />
* D10 und D11 gehören zur Gruppe 01<br />
* D12 und D13 gehören zur Gruppe 02<br />
* D14 gehört alleine zur Gruppe 03<br />
* D15,D16,D17 gehören zur 0-Gruppe ist sind damit deaktiviert. Die Binarstati werden zwar regelmäßig mit übertragen, in der Gruppenauswertung spielen diese Pins aber keine Rolle.<br />
<br />
Der Gruppenstatus würde dann wie folgt gesetzt:<br />
* Wenn D10 und D11 offen ist hat die Gruppe ebenfalls den Status '''Offen'''<br />
* Wenn D10 und D11 geschlossen ist hat die Gruppe den Status ebenfalls '''Geschlossen'''<br />
* Wenn D10 und D11 unterschiedlichen Status haben ist ist die Gruppe '''Angeklappt'''<br />
* Analog dazu D12/D13 mit der Gruppe 02<br />
* Wenn D14 offen ist, hat die Gruppe 03 den Status '''Offen'''<br />
* Wenn D14 geschlossen ist, hat die Gruppe 03 den Status '''Geschlossen'''<br />
* Die Gruppe 03 kann NICHT den Status '''Angeklappt''' annehmen, da nur ein Pin dieser Gruppe zugeordnet ist<br />
<br />
Die LEDs würden sich dann wie folgt verhalten:<br />
* Nach einem Event leuchtet die entsprechende LED 5sek dauerhaft, danach blinkt sie für 50ms alle 10sek<br />
<br />
== bereitgestellte Readings ==<br />
Folgende Readings werden zusätzlich zu den Konfigurations-Readings in FHEM bereitgestellt:<br />
<br />
{| class="wikitable"<br />
! Name des Reading<br />
! Datentyp <br />
! Beschreibung<br />
|-<br />
| 0C.0-Binary_0 -> 0C.7-Binary_7<br />
| [0-1]<br />
| aktueller Status des ReedEingangs D10-D17<br />
0 -> Reedkontakt geschlossen<br><br />
1 -> Reedkontakt offen<br />
|-<br />
| 0D.0-Gruppe_1 -> 0D.7-Gruppe_8<br />
| [0-2]<br />
| aktueller Status der Gruppe 1-7<br />
0 -> Geschlossen<br><br />
1 -> Angeklappt<br> <br />
2 -> Offen<br />
|}<br />
<br />
== Beschreibung des Gruppenverhaltens ==<br />
Mehrere Eingänge können zu einer Gruppe zugeordnet werden.<br />
Der Status einer Gruppe wird nach folgendem Verhalten festgelegt:<br />
* Sind alle Reed-Kontakte der zugeordneten Pins einer Gruppe geschlossen, so ist der Status der Gruppe: '''Geschlossen'''<br />
* Sind alle Reed-Kontakte der zugeordneten Pins einer Gruppe offen, so ist der Status der Gruppe: '''Offen'''<br />
* Sind die einzelnen Stati der Reed-Kontakte der zugeordneten Pins einer Gruppe sowohl geschlossen als auch offen, so ist der Status der Gruppe: '''Angeklappt'''<br />
* Wurde nur ein Pin einer Gruppe zugeordnet, so nimmt die Gruppe nur den Status '''Offen'''/'''Geschlossen''' an<br />
<br />
== Beschreibung des Sendeverhaltens ==<br />
Der aktuelle Status der Pins als auch der Status der Gruppen werden bei folgenden Events volständig übertragen:<br />
* gemäß TX-Intervall eingestelltes Sendeintervall<br />
* sofort bei Auftreten eines Events (Änderung eines Status an einem Pin)<br />
<br />
== Weitere Hinweise ==<br />
Keine.<br />
<br />
== Links ==<br />
<br />
<br />
[[Kategorie:panStamp]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Enigma2_Receiver_(Dreambox,_VUplus_etc.)_steuern&diff=15736Enigma2 Receiver (Dreambox, VUplus etc.) steuern2016-06-28T07:05:43Z<p>Hauswart: </p>
<hr />
<div>Für Kabel- und Satelliten Receiver, die auf der Linux Firmware ENIGMA2 basieren, gibt es in FHEM bereits ein entsprechendes Modul zur Steuerung.<br />
Damit können z.B. folgende Receiver gesteuert werden:<br />
<br />
* Dreambox 500 HD / 7020 HD / 7025+ / 800 HD PVR / 800 HD se / 8000 HD PVR<br />
* Gigablue HD 800 SE<br />
* Telestar Starsat LX (openATV-Image)<br />
* VUplus Solo (4K) / Duo / Uno / Ultimo / Solo2 / Duo2<br />
<br />
Für den Raspberry Pi bzw. Raspbian muss vorher grundsätzlich das "XML::Simple" Modul wie folgt installiert werden:<br />
<source lang="bash">sudo apt-get install libxml-simple-perl</source><br />
<br />
Für die genaue Benutzung des Moduls in FHEM gibt es eine Beschreibung in der Kommando-Referenz[http://fhem.de/commandref.html#ENIGMA2].<br />
<br />
== Links ==<br />
<br />
* [http://fhem.de/commandref.html#ENIGMA2 commandref-Eintrag zu ENIGMA2]<br />
* [http://www.dream-multimedia-tv.de Herstellerseite von dream-multimedia]<br />
* [http://www.vuplus.com Herstellerseite von VuPlus]<br />
<br />
[[Kategorie:Unterhaltungselektronik]]<br />
[[Kategorie:IP_Components]]</div>Hauswarthttp://wiki.fhem.de/w/index.php?title=Homebridge_einrichten&diff=15608Homebridge einrichten2016-06-20T17:10:48Z<p>Hauswart: /* NodeJS installieren */</p>
<hr />
<div>Dieses HOWTO zeigt die Installation und Erstinbetriebnahme von Homebridge. <br />
<br />
Damit kann Siri benutzt werden, um FHEM-Devices zu steuern. So können Devices angesprochen werden, die offiziell HomeKit nicht unterstützen (die Vorgehensweise wurde auf einem Intel NUC mit Ubuntu Server 14.04 LTS und auf einem Raspberry Pi mit Raspian getestet). Der WIKI-Eintrag bezieht sich hauptsächlich auf eine {{Link2Forum|Topic=32652|LinkText=Diskussion im FHEM-Forum}}. Ein Riesendank gilt vor allem {{Link2FU|430|Andre (justme1968)}}.<br />
<br />
Die Konfiguration der inzwischen aktuellen zweiten Version des Homekit-Plugins ist in einem neuen {{Link2Forum|Topic= 48558 |LinkText=Thread im FHEM-Forum}} beschrieben. Hinzugekommen ist vor allem die freie Konfigurierbarkeit der Zuordnung zwischen FHEM Device und Homekit Accessory/Service, zwischen FHEM Reading und Homekit Characteristic, das mapping vom FHEM Readingwerten zu Homekit Werten sowie das Mapping von Homekit Werten zu FHEM Set-Kommandos und Werten.<br />
<br />
Eine Sammlung funktionsfähiger Homebridge FHEM Konfiguration kann hier gefunden werden: [[Homebridge User Configs]]. Die Sammlung befindet sich noch im Aufbau.<br />
<br />
= Vorbereitung der Umgebung =<br />
<br />
== NodeJS installieren ==<br />
''Die nachfolgenden Befehle sind alle mit "sudo" prefixed. Wenn du unter "root" arbeitest oder deine Distribution einen anderen Mechanismus verwendet, so kannst du dies natürlich weglassen.''<br />
<br />
Zunächst wird das Betriebssystem (in diesem Falle Debian oder Ubuntu) auf den aktuellen Stand gebracht:<br />
<source lang="bash" style="width:50%;"><br />
sudo apt-get update<br />
sudo apt-get upgrade<br />
sudo apt-get install build-essential libssl-dev</source><br />
<br />
Nun muss NodeJS installiert werden. Leider ist die Version im Debian Repository deutlich zu alt, daher wird mit den folgenden Befehlen das Node Repository hinzugefügt und NodeJS (in der LTS Version) entsprechend installiert:<br />
<br />
'''NodeJS V4'''<br />
<source lang="bash" style="width:50%;"><br />
curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
{{Randnotiz|RNTyp=y|RNText=Bei Installation von NodeJS auf einem "alten" RasPi (B) bitte die besonderen Hinweise in {{Link2Forum|Topic=32652|Message=419325|LinkText=diesem Forenbeitrag}} beachten.}}<br />
'''NodeJS V5'''<br />
<source lang="bash" style="width:50%"><br />
curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
'''NodeJS V6'''<br />
<source lang="bash" style="width:50%"><br />
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -<br />
sudo apt-get install -y nodejs<br />
</source><br />
<br />
Damit ist NodeJS installiert.<br />
<br />
== Python, g++, MDNS installieren ==<br />
<source lang="bash" style="width:50%;"><br />
sudo apt-get install python g++ libavahi-compat-libdnssd-dev<br />
</source><br />
<br />
Nun sind alle Voraussetzungen geschaffen.<br />
<br />
= Installation von Homebridge & notwendiger Shims =<br />
Im Nachfolgenden Absatz wird die Installation von Homebridge sowie des notwendigen Plugins (Shim) für FHEM erläutert.<br />
<br />
== Homebridge installieren ==<br />
Die aktuelle Homebridge version wird mit<br />
<source lang="bash" style="width:50%;"><br />
npm install -g homebridge<br />
</source><br />
installiert, was eine Weile dauert. Anschließend wird der FHEM platform shim mit:<br />
<source lang="bash" style="width:60%;"><br />
npm install -g homebridge-fhem<br />
</source><br />
installiert.<br />
<br />
== Homebridge aktualisieren ==<br />
Die aktuelle Homebridge version wird mit<br />
<source lang="bash" style="width:50%;"><br />
npm update -g homebridge<br />
</source><br />
installiert, was eine Weile dauert. Anschließend wird der FHEM platform shim mit:<br />
<source lang="bash" style="width:60%;"><br />
npm update -g homebridge-fhem<br />
</source><br />
installiert.<br />
<br />
=== Fehler während der Installation ===<br />
Bei folgendem Fehler ist das Abrufen von Github nicht möglich.<br />
<pre>npm ERR! git clone --template=/home/hs-server-admin/.npm/_git-remotes/_templates --mirror <br />
git://github.com/KhaosT/ed25519.git /home/hs-server-admin/.npm/_git-remotes/git-github-com-KhaosT-ed25519-git-d8bdee1d: <br />
github.com[0: 192.30.252.128]: errno=Die Wartezeit für die Verbindung ist abgelaufen</pre><br />
Fehler könnte hier durch eine aktive Firewall verursacht werden.<br />
<br />
Kommt eine DNS Fehlermeldung fehlt meistens der AVAHI-DAEMON, zu installieren via<br />
<source lang="bash" style="width=50%"><br />
sudo apt-get install avahi-daemon<br />
</source><br />
<br />
Wenn npm beim Kompilieren von mdns mit der Meldung abbricht, dass "dns_sd.h" nicht gefunden wird, fehlt das Paket libavahi-compat-libdnssd-dev, zu installieren via<br />
<source lang="bash" style="width=50%"><br />
sudo apt-get install libavahi-compat-libdnssd-dev<br />
</source><br />
<br />
= Homebridge konfigurieren =<br />
''Wichtig: Für die weiteren Schritte sollte man nicht root verwenden, sondern beispielsweise einen dedizierten Nutzer für homebridge oder der Einfachheit halber den Nutzer, unter dem auch FHEM läuft (meist "fhem").''<br />
<br />
== Einstellungen für homebridge ==<br />
Zunächst wird das Verzeichnis für die Konfigurationsdatei erstellt und in dieses gewechselt:<br />
<source lang="bash" style="width:50%;"><br />
mkdir -p ~/.homebridge<br />
cd ~/.homebridge/<br />
</source><br />
<br />
Nun muss darin noch die config.json erstellt bzw. angepasst werden:<br />
<source lang="bash" style="width:50%;"><br />
nano ~/.homebridge/config.json<br />
</source><br />
<br />
Hinweise zur Konfiguration:<br />
* "''bridge''":<br />
** "''username''": Sollte so belassen werden. Sollte später auf dem iOS Device keine Homebridge gefunden werden, so kann man hier beispielsweise den String auf 31 statt 30 enden lassen um so eine neue Homebridge vorzutäuschen.<br />
** "''port''": Sollte so belassen werden<br />
** "''pin''": Der PIN kann beliebig in dem Format xxx-xx-xxx angepasst werden. Dieser muss nur einmal bei der Einrichtung in iOS eingegeben werden.<br />
* "''platforms''": <br />
** "''platform''": Hier muss "FHEM" beibehalten werden.<br />
** "''server''": Hier muss die IP des FHEM-Servers eingetragen werden. Dabei muss Homebridge nicht auf dem selben Server laufen wie FHEM, kann aber. Wenn es auf dem gleichen Rechner läuft, dann bietet es sich an, die IP 127.0.0.1 zu verwenden.<br />
** "''port''": Hier muss der Port des gewählten FHEMWEBS eingetragen werden (muss nicht das "normale" sein, kann eine extra Instanz sein)<br />
** "''auth''": Ist FHEM nicht mit Nutzername/Password abgesichert, so kann man diese Zeile einfach entfernen.<br />
** "''filter''": Damit nicht alle Devices von Homebridge berücksichtigt werden, bietet es sich an, die Devices zu filtern. In diesem Beispiel wurden alle Devices, die über Siri steuerbar sein sollen, zusätzlich in den Raum Homekit konfiguriert.<br />
<source lang="javascript" style="width:50%;"><br />
{<br />
"bridge": {<br />
"name": "Homebridge",<br />
"username": "CC:22:3D:E3:CE:30",<br />
"port": 51826,<br />
"pin": "031-45-154"<br />
},<br />
<br />
"platforms": [<br />
{<br />
"platform": "FHEM",<br />
"name": "FHEM",<br />
"server": "127.0.0.1",<br />
"port": "8083",<br />
"auth": {"user": "FhemUser", "pass": "XXX"},<br />
"filter": "room=Homekit"<br />
}<br />
],<br />
<br />
"accessories": []<br />
}<br />
</source><br />
<br />
Wird FHEM mit SSL abgesichert, so muss zusätzlich in der Sektion "platforms" noch diese Zeile (nach "port") eingefügt werden:<br />
<source lang="javascript" style="width:50%;"><br />
"ssl": true,<br />
</source><br />
<br />
= FHEM konfigurieren =<br />
Die benötigten Attribute werden inzwischen beim ersten Start des von hombridge-fhem automatisch auf FHEM Seite eingetragen.<br />
<br />
Mehr zu den inzwischen verfügbaren Konfigurationsmöglichkeiten findet sich auf den github und npmjs Seiten des Plugins und im ersten Beitrag des zugehörigen Thread im {{Link2Forum|Topic= 48558 |LinkText=Diskussion im FHEM-Forum}}<br />
<br />
= Start von Homebridge =<br />
<br />
== Hinweis ==<br />
Nach allen Änderungen die in FHEM gemacht werden, welche Homebridge betreffen, muss Homebridge neu gestartet werden. Wie der Neustart erfolgen muss, ist abhängig davon, wie man Homebridge gestartet hat. Bitte den entsprechenden Methoden entnehmen.<br />
<br />
== Einmaliger Manueller Start ==<br />
<source lang="bash" style="width:50%;"><br />
homebridge<br />
</source><br />
<br />
Homebridge sollte nun laufen. Hier kann man die Kommunikation nachverfolgen. Abbrechen kann das ganze mit CTRL+c (es dann auch keine Befehle mehr mit Siri möglich). Damit Siri auch Befehle ohne ständig offenes Terminal bearbeiten kann, bitten nächsten Punkt beachten.<br />
<br />
=== Fehler während des Manuellen Starts ===<br />
Kommt ein Fehler der ähnlich aussieht wie folgender, sollte zu erst die Nodesversion geprüft werden.<br />
Die Nodes version kann durch ein System Update auf eine niedrigere Version wie benötigt gedowngraded werden<br />
<source lang="bash" style="width=50%"><br />
Error: Module version mismatch. Expected 47, got 46.<br />
at Error (native)<br />
at Object.Module._extensions..node (module.js:450:18)<br />
at Module.load (module.js:356:32)<br />
at Function.Module._load (module.js:313:12)<br />
at Module.require (module.js:366:17)<br />
at require (module.js:385:17)<br />
at Object.<anonymous> (/usr/lib/node_modules/homebridge/node_modules/mdns/lib/dns_sd.js:24:20)<br />
at Module._compile (module.js:425:26)<br />
at Object.Module._extensions..js (module.js:432:10)<br />
at Module.load (module.js:356:32)<br />
</source><br />
Geprüft werden kann die Nodes Version mit:<br />
<source lang="bash" style="width=50%">node -v zeigt mir: v0.10.28, nodejs -v: v5.11.1</source><br />
Hier ist die Version v0.10.28 wobei v0.12 Mindestvorraussetzung ist.<br />
Die installation der richtigen Nodes Version kann oben am Anhang des Wiki Artikels entnommen werden.<br />
<br />
<br />
== Homebridge automatisch starten ==<br />
Es gibt verschiedene Methoden, Homebridge automatisch zu starten.<br />
<br />
=== Steuerung via FHEM ===<br />
Auf Basis der unten stehenden ''Alternativen Methode'' wurde eine Version entwickelt, mit der man auch den Status einsehen und den Restart des Dienstes aus FHEM heraus erledigen kann. Diese Version ist auf der Seite [[Homebridge Start und Status in FHEM]] im Detail beschrieben.<br />
<br />
=== Alternative Methode ===<br />
Dies startet homebridge als einen Service.<br />
<br />
==== Service anlegen ====<br />
<code><br />
sudo nano /etc/init.d/homebridge<br />
</code><br />
<br />
Code einfügen (startet den Homebridge Server als Benutzer "pi" und nimmt an, dass sich .homebridge/config.json in seinem Homeverzeichnis unter /home/pi/ befindet):<br />
<br />
<source lang=bash><br />
#!/bin/sh<br />
### BEGIN INIT INFO<br />
# Provides: homebridge<br />
# Required-Start: $network $remote_fs $syslog<br />
# Required-Stop: $remote_fs $syslog<br />
# Default-Start: 2 3 4 5<br />
# Default-Stop: 0 1 6<br />
# Short-Description: Start daemon at boot time for homebridge<br />
# Description: Enable service provided by daemon.<br />
### END INIT INFO<br />
export PATH=$PATH:/usr/local/bin<br />
export NODE_PATH=$NODE_PATH:/usr/local/lib/node_modules<br />
PID=`pidof homebridge`<br />
case "$1" in<br />
start)<br />
if ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is already running"<br />
else<br />
su - pi -c "homebridge > /dev/null 2>&1 &"<br />
echo "Homebridge starting"<br />
$0 status<br />
fi<br />
;;<br />
stop)<br />
if ! ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is not running"<br />
else<br />
kill $PID<br />
echo "Homebridge closed"<br />
fi<br />
;;<br />
restart)<br />
if ! ps -p $PID > /dev/null 2>&1; then<br />
$0 start<br />
else<br />
$0 stop<br />
$0 start<br />
fi<br />
;;<br />
status)<br />
if ps -p $PID > /dev/null 2>&1; then<br />
echo "Homebridge is running PID $PID"<br />
else<br />
echo "Homebridge is not running"<br />
fi<br />
;;<br />
*)<br />
echo "Usage: $0 {start|stop|status|restart}"<br />
exit 1<br />
;;<br />
esac<br />
exit 0<br />
</source><br />
<br />
==== Autostart aktivieren ====<br />
<br />
<code><br />
sudo chmod 755 /etc/init.d/homebridge<br />
<br />
sudo update-rc.d homebridge defaults<br />
</code><br />
<br />
Nun kann man mit <br />
<br />
<code><br />
sudo service homebridge start<br />
</code><br />
<br />
bzw.<br />
<br />
<code><br />
sudo /etc/init.d/homebridge start<br />
</code><br />
<br />
den Dienst starten<br />
<br />
== FHEM Device Einstellungen ==<br />
Damit die zu schaltenden Geräte überhaupt in der Homebridge aufgenommen werden muss man sie im Raum Homekit hinzufügen.<br />
<br />
Um HM-CC-RT-DN Thermostate steuern zu können, muss wie oben beschrieben folgendes attribute gesetzt werden (hier als Beispiel das Device "Heizung"):<br />
# attr Heizung subtype thermostat<br />
Für einen Dummy muss man den genericDeviceType setzen, also beispielsweise:<br />
# attr Dummy genericDeviceType switch<br />
# attr Dummy setList on off<br />
<br />
Wie bereits vorher angemerkt: fügt man ein Device hinzu oder führt eine Änderung an einem Device durch, so sollte homebridge neu gestartet werden.<br />
<br />
= HomeKit in iOS =<br />
<br />
== Einrichtung ==<br />
Um FHEM über Homebridge in iOS nutzen zu können, muss HomeKit eingerichtet werden. <br />
<br />
Es gibt verschiedene Apps. Im Folgenden wird die App EVE von Elgato empfohlen, die aus dem App-Store geladen werden muss.<br />
In der App auf:<br />
<pre style="width:50%;"><br />
Gerät hinzufügen<br />
</pre><br />
Es sollte ein Gerät mit der Bezeichnung "Homebridge" zur Auswahl erscheinen. Zur Ersteinrichtung auf PIN manuell eingeben gehen und (falls in der config.json nicht geändert):<br />
<pre style="width:50%;"><br />
031-45-154<br />
</pre><br />
eingeben.<br />
<br />
Im Anschluss können die Devices nach Belieben in verschiedene Räume zugeteilt werden, sowie Szenen und Bereiche erstellt werden.<br />
<br />
== Schalten mit Siri ==<br />
'''HolyMoly''' aus dem FHEM-Forum hat ein paar Beispiele gegeben, wie man Siri dazu bringt Devices zu schalten:<br />
<pre style="width:50%;"><br />
"Schalte alle Lampen im Obergeschoss ein."<br />
"Schalte Chloes Licht aus."<br />
"Dimme das Licht in der Küche."<br />
"Dimme das Licht im Esszimmer auf 50 %."<br />
"Stelle das Licht in der Küche am hellsten ein."<br />
"Stelle die Temperatur im Tahoe-Haus auf 22 °C ein."<br />
"Stelle das Thermostat im Erdgeschoss auf 21 °C ein.<br />
"Schalte den Drucker im Büro ein."<br />
"Siri, bereite alles für eine Party vor."<br />
"Bereite das Ambiente fürs Abendessen vor."<br />
"Aktiviere den Nachtruhemodus."<br />
</pre><br />
<br />
Mittlerweile kann Siri auch noch die Lichtfarbe von LEDs ändern.<br />
<br />
= Hinweise =<br />
<br />
== Unterstützte Geräte ==<br />
Das Fhem Plugin von {{Link2FU|430|Andre (justme1968)}} unterstützt automatisch mindestens die folgenden Geräte:<br />
<br />
switches (devices with set on and set off commands)<br />
lights (devices with set on and set off commands)<br />
HomeMatic, FS20 and ZWave dimmers (devices with set on, set off and set dim or set pct commands)<br />
HUE, WifiLight, MilightDevice, SWAP_0000002200000003 (hue, sat, bri, rgb)<br />
homematic, max and pid20 thermostats<br />
homematic, DUOFERN and FS20/IT(?) blinds<br />
homematic, MAX and FHTTK contact sensors (door, window)<br />
HM-SEC-WIN, HM-SEC-KEY<br />
presence, ROOMMATE<br />
SONOS (power, volume)<br />
harmony scenes<br />
temperaturecw and humidity sensors<br />
CO20 air quality sensor<br />
probably some more ...<br />
<br />
Über eine entsprechende Konfiguration lässt sich darüber hinaus jedes mit FHEM steuerbare Gerät auf die unterstützten Homekit typen abbilden.<br />
<br />
Die aktuelle Liste und eine Beschreibung der Konfigurationsmöglichkeiten findet sich [https://www.npmjs.com/package/homebridge-fhem auf den npmjs seiten] bzw. [https://github.com/justme-1968/homebridge-fhem auf github].<br />
<br />
== Zusätzliche Plugins ==<br />
Für manche der über FHEM steuerbaren Geräte wie z.b. MiiLight, Harmony Hub, Phillips Hue, Sonos,... gibt es eigene homekit plugins. Wenn immer möglich, empfiehlt es sich aber diese '''nicht''' zu verwenden, sondern die Steuerung über die FHEM-Integration zu realisieren, da<br />
* diese in der Regel sehr viel mächtiger und frei konfigurierbar ist<br />
* es FHEM erlaubt, als zentrale Instanz den Überblick über den aktuellen Gesamtzustand zu haben (wichtig bei Geräten, die gepollt werden) <br />
* die Ressourcen auf den angesteuerten Geräten schont, da Werte optimal gecached werden und nur eine einzige Verbindung aufgebaut wird<br />
<br />
== Hinweis für alte homebridge Versionen ==<br />
UPDATE: Homebridge funktioniert mit einer kleinen Einschränkung nun auch mit node 4.0.0. Laut<br />
[https://github.com/cflurin/homebridge-shims/wiki/Minimalist-Homebridge-on-a-Raspberry-Pi Homebridge on a Raspberry Pi] müssen die folgenden Abhängigkeiten (Dependencies) aus der '''package.json''' entfernt werden:<br />
<pre><br />
"harmonyhubjs-client": "^1.1.4",<br />
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git"<br />
</pre><br />
<br />
== Hinweis zur Geschwindigkeitsoptimierung auf einem Raspberry PI ==<br />
<br />
Damit es auf einem Raspberry schneller läuft, wird darüber hinaus empfohlen, auch diverse Abhängigkeiten aus der '''package.json''' zu entfernen:<br />
<pre><br />
"ad2usb": "git+https://github.com/alistairg/node-ad2usb.git#local",<br />
"carwingsjs": "0.0.x",<br />
"chokidar": "^1.0.5",<br />
"eibd": "^0.3.1",<br />
"elkington": "kevinohara80/elkington",<br />
"harmonyhubjs-client": "^1.1.4",<br />
"harmonyhubjs-discover": "git+https://github.com/swissmanu/harmonyhubjs-discover.git",<br />
"lifx-api": "^1.0.1",<br />
"lifx": "git+https://github.com/magicmonkey/lifxjs.git",<br />
"node-hue-api": "^1.0.5",<br />
"node-icontrol": "^0.1.4",<br />
"node-milight-promise": "0.0.x",<br />
"tough-cookie": "^2.0.0",<br />
"sonos": "0.8.x",<br />
"telldus-live": "0.2.x",<br />
"teslams": "1.0.1",<br />
"unofficial-nest-api": "git+https://github.com/hachidorii/unofficial_nodejs_nest.git#d8d48edc952b049ff6320ef99afa7b2f04cdee98",<br />
"wemo": "0.2.x",<br />
"wink-js": "0.0.5",<br />
"komponist" : "0.1.0",<br />
"yamaha-nodejs": "0.4.x",<br />
</pre><br />
<br />
Daher zunächst ein ein Backup der Datei anlegen <br />
<pre>sudo cp package.json package.json.bkp </pre><br />
Am einfachsten geht das entfernen der Zeilen mit einem Editor, beispielsweise nano oder vi.<br />
<pre>sudo nano package.json</pre><br />
<br />
Das config file sollte dann wie folgt aussehen: Achtung vor den letzten zwei "}" am Ende darf kein Komma sein.<br />
<source lang="javascript"><br />
{<br />
"name": "homebridge",<br />
"description": "HomeKit support for the impatient",<br />
"version": "0.1.1",<br />
"scripts": {<br />
"start": "DEBUG=* node app.js || true"<br />
},<br />
"repository": {<br />
"type": "git",<br />
"url": "git://github.com/nfarina/homebridge.git"<br />
},<br />
"license": "ISC",<br />
"dependencies": {<br />
"async": "^1.4.2",<br />
"color": "0.10.x",<br />
"debug": "^2.2.0",<br />
"hap-nodejs": "^0.0.2",<br />
"isy-js": "",<br />
"mdns": "^2.2.4",<br />
"netatmo": "1.3.0",<br />
"node-cache": "3.0.0",<br />
"node-persist": "0.0.x",<br />
"node-xmpp-client": "1.0.0-alpha23",<br />
"q": "1.4.x",<br />
"queue": "^3.1.0",<br />
"request": "2.49.x",<br />
"xml2js": "0.4.x",<br />
"xmldoc": "0.1.x"<br />
}<br />
}<br />
</source><br />
<br />
== Links ==<br />
* [https://github.com/nfarina/homebridge Github homebridge]<br />
* [https://github.com/justme-1968/homebridge-fhem Github homebridge-fhem]<br />
* [https://www.npmjs.com/package/homebridge NPM homebridge]<br />
* [https://www.npmjs.com/package/homebridge-fhem NPM homebridge-fhem]<br />
<br />
[[Kategorie:HOWTOS]]</div>Hauswart