Difference between revisions of "Nutzung in FHEM (Deutsch)"
m (→HD44780 Punktmatrixdisplays) |
|||
(39 intermediate revisions by 3 users not shown) | |||
Line 3: | Line 3: | ||
[http://www.fhemwiki.de/wiki/Hauptseite FHEM] ist ein Hausautomations-Server von Rudolf Koenig et al. in Perl geschrieben, um diverse per Funk und Kabel angebundene Komponenten aus dem Bereich der Hausautomation zu steuern. Er ist lizensiert unter der GPL v2. | [http://www.fhemwiki.de/wiki/Hauptseite FHEM] ist ein Hausautomations-Server von Rudolf Koenig et al. in Perl geschrieben, um diverse per Funk und Kabel angebundene Komponenten aus dem Bereich der Hausautomation zu steuern. Er ist lizensiert unter der GPL v2. | ||
− | Das AVR-Net-IO von [http://www.pollin.de Pollin] mit [[Ethersex]] dient [http://www.fhemwiki.de/wiki/AVR-NET-IO | + | Das [http://www.pollin.de/shop/suchergebnis.html?S_TEXT=810+058 AVR-Net-IO] von [http://www.pollin.de Pollin] mit [[Ethersex]] dient als [http://www.fhemwiki.de/wiki/AVR-NET-IO preisgünstiger Einstieg in die Hausautomatisierung]. Verwendbar ist aber auch jede andere [[Supported_Boards_(Deutsch) | Hardware]], die von Ethersex unterstützt wird (Arduino, eigene Entwicklungen, etc.). Über [[ECMD]] lassen sich dabei theoretisch alle in [[Ethersex]] vorhandenen [[ECMD_Protocols_%28Deutsch%29 | Möglichkeiten]] nutzen, sofern in FHEM entsprechende [http://fhem.de/commandref.html#ECMD ECMD-Devices] definiert und eingebunden werden, die passende Klassendefinition exisitert und die Aktion ausgelöst wird. |
− | == | + | == Grundlagen == |
− | + | Ausgehend von einem fertigen und per Telnet erreichbaren Ethersex muss in FHEM zuerst das entsprechende Device definiert werden. | |
+ | <pre> | ||
+ | define NETIO_WZ ECMD telnet 192.168.3.81:2701 | ||
+ | </pre> | ||
+ | Eine serielle Anbindung kann mit ''define <name> ECMD serial <SerialDevice>[<@BaudRate>]'' alternativ erfolgen. | ||
+ | |||
+ | Anschließend werden die erstellten .classdef-Konfigurationsdateien der einzelnen Funktionen dem System bekannt gemacht. In diesen .classdef-Dateien (Name und Endung sind frei wählbar!) wird die Schnittstelle zwischen FHEM und ECMD/Ethersex definiert. Dabei können mit perl übergebene Parameter und empfangene Daten bearbeitet sowie die in FHEM gebräuchlichen Readings erstellt werden. | ||
+ | <pre> | ||
+ | attr NETIO_WZ classdefs RFM12_2272=/opt/fhem/FHEM/rfm12_2272.classdef:RFM12_IT=/opt/fhem/FHEM/rfm12_it.classdef:LCD=/opt/fhem/FHEM/lcd.classdef:DHT22=/opt/fhem/FHEM/dht22.classdef:1WIRE=/opt/fhem/FHEM/1wire.classdef | ||
+ | </pre> | ||
+ | Die Definitionen für IC2272, Intertechno, HD44780-LCD, DHT22 und 1wire sind nun eingebunden. In den folgenden Abschnitten wird auf die einzelnen Devices näher eingegangen. Generell sind Pfade und IP-Adressen sowie übergebene Parameter noch entsprechend der eigenen Konfiguration anzupassen. | ||
+ | |||
+ | == [[Onewire_(Deutsch) | 1-Wire Temperatursensoren]] == | ||
+ | |||
+ | [[File:DS18B20.jpg|150px|thumb|right|DS18B20-Sensoren]] | ||
+ | Die 1wire-Temperatursensoren DS18B20 oder DS18S20 werden im [[Onewire_(Deutsch)#Polling_Modus | Polling Modus]] abgefragt. Das macht die zyklische Abfrage aus FHEM heraus wesentlich einfacher. Eine Polling-Zeit von mindestens 30 Sekunden ist absolut ausreichend.Im Vorfeld sollte man sich die [[Onewire_(Deutsch)#Benennung_von_Sensoren | ROM-Codes der Sensoren]] notieren, da diese nachher benötigt werden. | ||
+ | |||
+ | 1w-temp.classdef erstellen: | ||
+ | <source lang="perl"> | ||
+ | # Uebergabeparameter Onewire Rom-Code | ||
+ | params devID | ||
+ | # Umsetzung in ECMD Befehle 1w get = Temperatur auslesen | ||
+ | get 1W cmd {"1w get %devID\n"} | ||
+ | get 1W expect "\d+.\d+\n" | ||
+ | get 1W postproc {\ | ||
+ | s/\n//g;\ | ||
+ | my $hash = $defs{%NAME};\ | ||
+ | my $temperature = $_;\ | ||
+ | my $state = "T: $temperature";\ | ||
+ | \ | ||
+ | readingsSingleUpdate($hash, "temperature", $temperature, 1);\ | ||
+ | readingsSingleUpdate($hash, "state", $state, 1);\ | ||
+ | \ | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Die classdef wird eingebunden: | ||
+ | <pre> | ||
+ | define NETIO_KU ECMD telnet 192.168.3.82:2701 | ||
+ | attr NETIO_KU classdefs 1W-TEMP=/opt/fhem/FHEM/1w-temp.classdef | ||
+ | </pre> | ||
+ | |||
+ | Die Sensoren werden anhand des ROM-Code definiert: | ||
+ | <pre> | ||
+ | define HZ_WW ECMDDevice 1W-TEMP 284c8820050003d4 | ||
+ | attr HZ_WW IODev NETIO_KU | ||
+ | define HZ_VL ECMDDevice 1W-TEMP 2890a520050003d7 | ||
+ | attr HZ_VL IODev NETIO_KU | ||
+ | </pre> | ||
+ | Eine zyklische Messung pro Minute lässt sich in dieser Form auslösen: | ||
+ | <pre> | ||
+ | define Messung_1w at +*00:01 get HZ_WW 1W;; get HZ_VL 1W | ||
+ | attr Messung_1w verbose 0 | ||
+ | </pre> | ||
== [[DHT|DHT22 Temperatur-/Feuchtesensoren]] == | == [[DHT|DHT22 Temperatur-/Feuchtesensoren]] == | ||
+ | |||
+ | [[File:DHT22.jpg|150px|thumb|right|DHT22-Sensoren]] | ||
+ | [[Ethersex]] unterstützt die preiswerten Temperatur-/Feuchtesensoren [[DHT|DHT11 und DHT22]], wobei letztere [[DHT#DHT11_vs_DHT22|um einiges genauer sind]]. | ||
+ | |||
+ | Die Sensoren benötigen 5V Betriebsspannung und kommunizieren über je einen Pin mit dem Prozessor. Der Preis pro Stück liegt derzeit bei etwa 3.50 Euro (ebay/China). Wer die Trägheit und Ungenauigkeit der S300TH oder TX29DTH kennt, wünscht sich vermutlich Besseres; vor allem bei Berechnung von [http://de.wikipedia.org/wiki/Taupunkt Taupunkt] und [http://de.wikipedia.org/wiki/Luftfeuchtigkeit#Absolute_Luftfeuchtigkeit absoluter Feuchte], welche von der Genauigkeit der gemessenen Eingangsgrößen sehr profitieren. Berechnungen von Hand kann man beim [http://www.wetterochs.de/wetter/feuchte.html Wetterochs] durchführen. Die automatische Berechnung der absoluten Feuchte in FHEM wird im [http://forum.fhem.de/index.php/topic,21458.0.html Forum] erklärt. | ||
+ | |||
+ | |||
+ | '''Einbindung in FHEM''' | ||
+ | |||
+ | dht22m.classdef erstellen: | ||
+ | <source lang="perl"> | ||
+ | # Uebergabeparameter DHT22 ID 0...n | ||
+ | params devID | ||
+ | # Umsetzung in ECMD Befehle fuer DHT22 | ||
+ | get DHT cmd {"dht temp %devID\n\000dht humid %devID\n"} | ||
+ | get DHT expect "-?\d+.\d\n" | ||
+ | get DHT postproc {\ | ||
+ | s/(.*)\n(.*)\n/T: $1 H: $2/;\ | ||
+ | my $hash = $defs{%NAME};\ | ||
+ | my $temperature = $1;\ | ||
+ | my $humidity = $2;\ | ||
+ | my $state = $_;\ | ||
+ | \ | ||
+ | readingsSingleUpdate($hash, "temperature", $temperature, 1);\ | ||
+ | readingsSingleUpdate($hash, "humidity", $humidity, 1);\ | ||
+ | readingsSingleUpdate($hash, "state", $state, 1);\ | ||
+ | \ | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Die classdef wird eingebunden: | ||
+ | <pre> | ||
+ | define NETIO_TEST ECMD telnet 192.168.3.89:2701 | ||
+ | attr NETIO_TEST classdefs DHT22M=/opt/fhem/FHEM/dht22m.classdef | ||
+ | </pre> | ||
+ | |||
+ | Die Sensoren werden definiert: | ||
+ | <pre> | ||
+ | define Test0 ECMDDevice DHT22M 0 | ||
+ | attr Test0 IODev NETIO_TEST | ||
+ | define Test1 ECMDDevice DHT22M 1 | ||
+ | attr Test1 IODev NETIO_TEST | ||
+ | define Test2 ECMDDevice DHT22M 2 | ||
+ | attr Test2 IODev NETIO_TEST | ||
+ | define Test3 ECMDDevice DHT22M 3 | ||
+ | attr Test3 IODev NETIO_TEST | ||
+ | </pre> | ||
+ | |||
+ | Eine zyklische Messung alle 4 Minuten könnte so aussehen: | ||
+ | <pre> | ||
+ | |||
+ | define Messung_DHT at +*00:04 get Test0 DHT;; get Test1 DHT;; get Test2 DHT;; get Test3 DHT | ||
+ | attr Messung_DHT verbose 0 | ||
+ | </pre> | ||
+ | Fünfzehn Messwerte pro Stunde genügen den allermeisten Anforderungen. | ||
+ | |||
+ | == [[BMP085 | BMP085/BMP180 Luftdrucksensor]] == | ||
+ | |||
+ | |||
+ | [[File:BMP180.jpg|150px|thumb|right|BMP180 (unten links)]] | ||
+ | |||
+ | Ethersex unterstützt den BMP085 (bzw. den BMP180; der Code ist identisch) über das [[I2C_(Deutsch) | I2C]]-Interface. Da der Sensor für 3.3V Betriebsspannung ausgelegt ist, muss entweder der I2C-Pegel angepasst oder der ATMega auf 3.3V adaptiert werden. Weiterhin sollte die Höhe über Null bekannt sein. Beispiel: Eine Abfrage per [[ECMD]] mit ''bmp085 pressnn 59000'' bedeutet, das ich 590m (59000cm) über NN wohne. Sollte der Befehl ''bmp085 pressnn'' aus Platzgründen nicht mehr in Image passen, kann man die Umrechnung auf Normal Null alternativ auch in der classdef erledigen. | ||
+ | |||
+ | Die im Sensor verfügbare Temperatur wird parallel ausgelesen. | ||
+ | |||
+ | '''Einbindung in FHEM''' | ||
+ | |||
+ | bmp085.classdef erstellen, falls ''presnn'' unterstützt wird (59000 durch eigene Höhe in cm ersetzen!): | ||
+ | <source lang="perl"> | ||
+ | get BMP cmd {"bmp085 temp\n\000bmp085 pressnn 59000\n"} | ||
+ | get BMP expect ".*" | ||
+ | get BMP postproc {\ | ||
+ | s/(.*)\n(.*)\n/T: $1 P: $2/;\ | ||
+ | my $hash = $defs{%NAME};\ | ||
+ | my $temperature = $1/10;\ | ||
+ | my $pressure = sprintf("%.1f",$2/100);\ | ||
+ | my $state = "T: $temperature P: $pressure";\ | ||
+ | \ | ||
+ | readingsSingleUpdate($hash, "temperature", $temperature, 1);\ | ||
+ | readingsSingleUpdate($hash, "pressure", $pressure, 1);\ | ||
+ | readingsSingleUpdate($hash, "state", $state, 1);\ | ||
+ | \ | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Die Temperatur wird in °C mit einer Nachkommastelle gelesen, der Luftdruck in hPa bzw. mbar auf eine Nachkommastelle gerundet. Passende Readings werden erstellt. Das expect .* kann noch angepasst werden, um bei fehlerhaften Messwerten entsprechend zu reagieren. | ||
+ | |||
+ | Die classdef wird in FHEM eingebunden (mehrere .classdef mit Doppelpunkt trennen: siehe [[Nutzung_in_FHEM_(Deutsch)#Grundlagen | Grundlagen]]): | ||
+ | <pre> | ||
+ | define NETIO_STK ECMD telnet 192.168.3.89:2701 | ||
+ | attr NETIO_STK classdefs BMP=/opt/fhem/FHEM/bmp085.classdef | ||
+ | </pre> | ||
+ | |||
+ | Der Sensor wird definiert: | ||
+ | <pre> | ||
+ | define BMP180 ECMDDevice BMP | ||
+ | attr BMP180 IODev NETIO_STK | ||
+ | </pre> | ||
+ | |||
+ | Das STATE ''kann'' mit Maßeinheiten versehen werden: | ||
+ | <pre> | ||
+ | attr BMP180 stateFormat { sprintf("%s°C %shPa", ReadingsVal("BMP180","temperature",0), ReadingsVal("BMP180","pressure",0)) ;; } | ||
+ | </pre> | ||
+ | |||
+ | Eine zyklische Messung alle 4 Minuten erfolgt wieder mit ''at'': | ||
+ | <pre> | ||
+ | define Messung_BMP at +*00:04 get BMP180 BMP | ||
+ | attr Messung_BMP verbose 0 | ||
+ | </pre> | ||
+ | Dabei unterdrückt verbose 0 einen zusätzlichen (doppelten) Logeintrag des Messvorganges. | ||
+ | |||
+ | |||
+ | Alternative bmp085.classdef, die die Umrechnung auf Normal Null in Perl macht (590 durch eigene Höhe in m ersetzen): | ||
+ | <source lang="perl"> | ||
+ | get pressure cmd {"bmp085 apress\n"} | ||
+ | get pressure expect "\d+\n" | ||
+ | get pressure postproc { s/(..)\n/.$1/; $_/=(1-(590/44330.7692))**5.255; $_ } | ||
+ | get temp cmd {"bmp085 temp\n"} | ||
+ | get temp expect "\d+\n" | ||
+ | get temp postproc { s/(.)\n/.$1/; $_ } | ||
+ | </source> | ||
+ | |||
+ | Bei diesem Beispiel können Temperatur und Druck separat ausgelesen werden, hier ein Beispiel für das zyklische Auslesen beider Werte: | ||
+ | <pre> | ||
+ | define Messung_BMP at +*00:04 get BMP180 pressure ;; get BMP180 temp | ||
+ | </pre> | ||
+ | |||
+ | == analoge Eingänge abfragen == | ||
+ | |||
+ | Die analogen Eingänge des ATMega sind recht simpel abzufragen. Dabei werden die hexadezimalen Werte gleich dezimal gewandelt, um die Weiterverarbeitung zu erleichtern. | ||
+ | |||
+ | '''Einbindung in FHEM''' | ||
+ | |||
+ | adc.classdef erstellen: | ||
+ | <source lang="perl"> | ||
+ | get value cmd {"adc get %PortID\n"} | ||
+ | params PortID | ||
+ | get value expect ".*" | ||
+ | get value postproc {\ | ||
+ | my $hexval = hex(trim("$_"));\ | ||
+ | my $hash = $defs{%NAME};\ | ||
+ | readingsSingleUpdate($hash, "state", $hexval, 1);\ | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Die classdef wird eingebunden: | ||
+ | <pre> | ||
+ | define NETIO_KU ECMD telnet 192.168.3.89:2701 | ||
+ | attr NETIO_KU classdefs ADC=/opt/fhem/FHEM/adc.classdef | ||
+ | </pre> | ||
+ | |||
+ | Die Sensoren an den ersten beiden Ports werden definiert: | ||
+ | <pre> | ||
+ | define MP_0 ECMDDevice ADC 0 | ||
+ | attr MP_0 IODev NETIO_KU | ||
+ | define MP_1 ECMDDevice ADC 1 | ||
+ | attr MP_1 IODev NETIO_KU | ||
+ | </pre> | ||
+ | |||
+ | Eine zyklische Messung alle 60 Sekunden funktioniert damit: | ||
+ | <pre> | ||
+ | define Messung_adc at +*00:01 get MP_0 value;; get MP_1 value | ||
+ | attr Messung_adc verbose 0 | ||
+ | </pre> | ||
+ | |||
+ | == digitale Eingänge abfragen == | ||
todo | todo | ||
− | == | + | == digitale Eingänge - proaktiv == |
− | + | Kontakte, die bei Zustandsänderung sofort in FHEM eine Meldung erzeugen sollen, kann man nicht zeitnah mit Polling abfragen. Diese Ereignisse, welche auch aus einem Control6-Script heraus generiert sein können, sollen selbst Meldung machen. Hierbei wird die ESEND-Funktion benutzt, mit welcher auch mehrere Ethersex'e untereinander kommunizieren können. Dabei ist es nicht relevant, ob das Device in FHEM per ECMDDevice bereits eingebunden wurde. Zuerst muss FHEM auf Port 2701 für Telnet-Verbindungen empfänglich werden: | |
+ | <pre> | ||
+ | define telnetECMD telnet 2701 global | ||
+ | </pre> | ||
+ | Mit ''Watch io changes and react'' lässt sich per menuconfig bereits auf einfache Weise eine Abfrage von Portpins mit Generierung eines ESEND-Befehles bewerkstelligen. Das Beispiel soll zeigen, wie bei entsprechender Zustandsänderung an Pin PA0 an 192.168.178.10 ein FHEM-Befehl gesendet wird: | ||
+ | <pre> | ||
+ | ECMDTCP(PA0, RISING, 192.168.178.10, set Lampe on\n\n) | ||
+ | ECMDTCP(PA0, FALLING, 192.168.178.10, set Lampe off\n\n) | ||
+ | </pre> | ||
+ | Jede Sequenz muss mit \n\n abgeschlossen werden, damit FHEM für weitere Befehle empfangsbereit bleibt. Falls man in FHEM flexibler bei der Weiterverarbeitung sein möchte, bietet sich eine dummy-notify-Kombination an. | ||
+ | |||
+ | == [[Porterweiterungen_%28Deutsch%29#D.2FA-Wandler_mit_LTC1257 | LTC1257 D/A-Wandler]] == | ||
+ | |||
+ | [[File:LTC1257.jpg|150px|thumb|right|LTC1257 Digital-Analog-Wandler innerhalb einer Schaltung]] | ||
+ | Die 12bit Digital-Analog-Wandler von LINEAR TECHNOLOGY werden mit drei Pins bedient. Er wandelt (bei interner Referenzspannung) einen digital übermittelten Wert in eine Spannung von 0-2,048V um. Ein nachgeschalteter OPV als nichtinvertierender Verstärker kann diesen Bereich entsprechend skalieren. | ||
+ | |||
+ | ltc1257.classdef erstellen: | ||
+ | <source lang="perl"> | ||
+ | # Umsetzung in ECMD Befehle | ||
+ | # Ein Uebergabeparameter -> Sollwert | ||
+ | set setDAC params dacValue | ||
+ | set setDAC cmd {"ltc1257_set %dacValue\n"} | ||
+ | set setDAC expect "OK\n" | ||
+ | # Keine Uebergabeparameter | ||
+ | set init cmd {"ltc1257_init\n"} | ||
+ | set init expect "OK\n" | ||
+ | # | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Die classdef wird eingebunden: | ||
+ | <pre> | ||
+ | define NETIO_KU ECMD telnet 192.168.3.82:2701 | ||
+ | attr NETIO_KU classdefs LTC1257=/opt/fhem/FHEM/ltc1257.classdef | ||
+ | </pre> | ||
+ | |||
+ | Der LTC wird entsprechend definiert: | ||
+ | <pre> | ||
+ | define HZ_DAC ECMDDevice LTC1257 | ||
+ | attr HZ_DAC IODev NETIO_KU | ||
+ | </pre> | ||
+ | Nun lässt sich mit einem '''set HZ_DAC init''' der LTC initialisieren (die gemessene Ausgangsspannung sollte 0V sein) und mit '''set HZ_DAC setDAC [0...4095]''' der gewünschte Wert setzen. Hier muss vorab experimentell entsprechend der nachfolgenden Beschaltung die tatsächliche Spannung ermittelt werden. | ||
+ | |||
+ | == [[HD44780 | HD44780 LCD Punktmatrixdisplays]] == | ||
+ | |||
+ | [[File:HD44780.jpg|150px|thumb|right|verschiedene HD44780 Displays (16x1 bis 40x4)]] | ||
+ | Die beliebten Punktmatrix-Displays auf Basis [http://de.wikipedia.org/wiki/HD44780 HD44780] können vollumfänglich in FHEM beschrieben werden. | ||
+ | |||
+ | '''Einbindung in FHEM''' | ||
+ | |||
+ | lcd.classdef erstellen: | ||
+ | <source lang="perl"> | ||
+ | # Umsetzung der ECMD Befehle | ||
+ | set write params line col text | ||
+ | set write cmd {"lcd goto %line %col\n\000lcd write %text\n"} | ||
+ | set write expect "OK\n" | ||
+ | set write postproc {s/([OK\n|;]*)/success/; "$_" eq "success" ? "ok" : "error";} | ||
+ | set clear params col | ||
+ | set clear cmd {"lcd clear %col\n"} | ||
+ | set clear expect "OK\n" | ||
+ | set clear postproc {s/([OK\n|;]*)/success/; "$_" eq "success" ? "ok" : "error";} | ||
+ | set clear_all cmd {"lcd clear\n"} | ||
+ | set clear_all expect "OK\n" | ||
+ | set clear_all postproc {s/([OK\n|;]*)/success/; "$_" eq "success" ? "ok" : "error";} | ||
+ | set lcd_bl params state | ||
+ | set lcd_bl cmd {"lcd backlight %state\n"} | ||
+ | set lcd_bl expect "OK\n" | ||
+ | set lcd_bl postproc {s/([OK\n|;]*)/success/; "$_" eq "success" ? "ok" : "error";} | ||
+ | </source> | ||
+ | |||
+ | Die classdef wird eingebunden: | ||
+ | <pre> | ||
+ | define NETIO_TEST ECMD telnet 192.168.3.89:2701 | ||
+ | attr NETIO_TEST classdefs LCD=/opt/fhem/FHEM/lcd.classdef | ||
+ | </pre> | ||
+ | |||
+ | Das Display wird definiert: | ||
+ | <pre> | ||
+ | define WZ_LCD ECMDDevice LCD | ||
+ | attr WZ_LCD IODev NETIO_TEST | ||
+ | </pre> | ||
+ | |||
+ | Es stehen in FHEM folgende Befehle für das LCD bereit: | ||
+ | {| border='1' | ||
+ | | ''Befehl'' | ||
+ | | ''Funktion'' | ||
+ | |- | ||
+ | | set WZ_LCD clear [ZEILE] | ||
+ | | löscht den Inhalt einer ZEILE (0...3) | ||
+ | |- | ||
+ | | set WZ_LCD clear_all | ||
+ | | löscht den Inhalt aller Zeilen | ||
+ | |- | ||
+ | | set WZ_LCD lcd_bl STATE | ||
+ | | schaltet die Hintergrundbeleuchtung ein oder aus (STATE on oder off) | ||
+ | |- | ||
+ | | set WZ_LCD write [ZEILE] [SPALTE] [TEXT] | ||
+ | | schreibt einen TEXT auf Position ZEILE SPALTE (0...n) | ||
+ | |- | ||
+ | |} | ||
− | + | Da ein im TEXT übergebenes Leerzeichen als weiterer Befehl interpretiert wird und zu einer Fehlermeldung führt, ist eine Übergabe nur mit \x20 im Text möglich. | |
+ | Das gilt auch für Umlaute. Anhand der [http://de.wikipedia.org/wiki/HD44780#Schrift_und_Zeichensatz Zeichensatztabelle] lassen sich ä durch \xE1, ü durch \xF5 und ö durch \xEF darstellen. Das ß wird mit \xE2 erreicht. Die Tabelle kann für manche Displays abweichend sein.<br /> | ||
+ | Beispiel: ''set WZ_LCD write 0 0 Fenster\x20schlie\xE2en'' schreibt ein '''Fenster schließen''' auf's LCD. | ||
− | |||
− | |||
− | + | '''Komfortable Nutzung in FHEM mit DLCD''' | |
− | == | + | Mit dem DLCD-Modul ([http://www.fhemwiki.de/wiki/DLCD Wiki-Beitrag] / [http://forum.fhem.de/index.php/topic,24519.0.html Foren-Beitrag]) für FHEM lässt sich jedes Display auf einfache Weise beschreiben. Dabei lassen sich bequem Readings von allen Devices nutzen, aufbereiten (formatieren, umrechnen, etc.) und entsprechend darstellen. Eine genaue Beschreibung hält der Wiki-Beitrag bereit; hier soll ein Beispiel gezeigt werden. Ziel war es, auf einem 16x1 LCD wechselweise ''Datum/Zeit => Klimadaten Keller => Datum/Zeit => Klimadaten Garten'' darzustellen. Die Anzeige rotiert im 15-Sekunden-Takt, so das zu 50% Datum/Zeit und je 25% die Werte aus dem Garten und dem Keller angezeigt werden. Es wird bereits im Modul jedes Leerzeichen mit \x20 übersetzt. Der Außensensor ist ein [http://www.elv.de/elv-funk-kombi-wettersensor-ks-300-2-br-inkl-hochwertigem-2-m-edelstahlmast-br-und-qualitaetsbatterien.html KS300] (bzw. KS200) von ELV. Mit etwas Formatierung und ein paar Leerzeichen lässt sich eine stets gleiche Positionierung der Daten erreichen, da die Zeile nicht explizit gelöscht wird. |
− | + | Auszug aus der fhem.cfg: | |
+ | <pre> | ||
+ | define DLCD_WZ DLCD | ||
+ | attr DLCD_WZ dlcdBlankspaceReplace \x20 | ||
+ | attr DLCD_WZ dlcdCols 16 | ||
+ | attr DLCD_WZ dlcdLine1 %date_WD_ger% %date_D%.%date_M_ger% %time_h%:%time_m% | ||
+ | attr DLCD_WZ dlcdLine2 Keller:%1%/%2% | ||
+ | attr DLCD_WZ dlcdLine3 %date_WD_ger% %date_D%.%date_M_ger% %time_h%:%time_m% | ||
+ | attr DLCD_WZ dlcdLine4 Garten: %3%/%4% | ||
+ | attr DLCD_WZ dlcdPhysicalRows 1 | ||
+ | attr DLCD_WZ dlcdPollInterval 15 | ||
+ | attr DLCD_WZ dlcdRows 4 | ||
+ | attr DLCD_WZ dlcdScrolling 1 | ||
+ | attr DLCD_WZ dlcdTriggerCmd set WZ_LCD write %L% 0 %T% | ||
+ | attr DLCD_WZ dlcdVal1 Keller:temperature | ||
+ | attr DLCD_WZ dlcdVal1formatnum 3+1 | ||
+ | attr DLCD_WZ dlcdVal2 Keller:humidity | ||
+ | attr DLCD_WZ dlcdVal2formatnum 3+1 | ||
+ | attr DLCD_WZ dlcdVal3 KS300:temperature | ||
+ | attr DLCD_WZ dlcdVal3formatnum 3+1+- | ||
+ | attr DLCD_WZ dlcdVal4 KS300:humidity | ||
+ | attr DLCD_WZ dlcdVal4formatnum 2+0 | ||
+ | </pre> | ||
+ | Das Ergebnis kann so aussehen: | ||
+ | <gallery> | ||
+ | DLCD_1.jpg|Zustand 1.-15. Sekunde | ||
+ | DLCD_2.jpg|Zustand 16.-30. Sekunde | ||
+ | DLCD_3.jpg|Zustand 31.-45. Sekunde | ||
+ | DLCD_4.jpg|Zustand 46.-60. Sekunde | ||
+ | </gallery> | ||
+ | Die Formatierung bewirkt eine immer identische Platzierung der Daten. Der Außensensor hat keine Zehntelwerte bei der Feuchte, muss dafür aber negative Temperaturen darstellen. Der Innensensor zeigt Zehntelwerte, womit sich Tendenzen eher erkennen lassen. | ||
− | == Intertechno schalten mit RFM12 == | + | == [[RFM12_ASK_(Deutsch) | Intertechno schalten mit RFM12]] == |
todo | todo | ||
− | == IC2272 schalten mit RFM12 == | + | == [[RFM12_ASK_(Deutsch) | IC2272 schalten mit RFM12]] == |
todo | todo | ||
[[Category:Application|Application]] | [[Category:Application|Application]] |
Latest revision as of 14:26, 22 January 2017
FHEM ist ein Hausautomations-Server von Rudolf Koenig et al. in Perl geschrieben, um diverse per Funk und Kabel angebundene Komponenten aus dem Bereich der Hausautomation zu steuern. Er ist lizensiert unter der GPL v2.
Das AVR-Net-IO von Pollin mit Ethersex dient als preisgünstiger Einstieg in die Hausautomatisierung. Verwendbar ist aber auch jede andere Hardware, die von Ethersex unterstützt wird (Arduino, eigene Entwicklungen, etc.). Über ECMD lassen sich dabei theoretisch alle in Ethersex vorhandenen Möglichkeiten nutzen, sofern in FHEM entsprechende ECMD-Devices definiert und eingebunden werden, die passende Klassendefinition exisitert und die Aktion ausgelöst wird.
Contents
- 1 Grundlagen
- 2 1-Wire Temperatursensoren
- 3 DHT22 Temperatur-/Feuchtesensoren
- 4 BMP085/BMP180 Luftdrucksensor
- 5 analoge Eingänge abfragen
- 6 digitale Eingänge abfragen
- 7 digitale Eingänge - proaktiv
- 8 LTC1257 D/A-Wandler
- 9 HD44780 LCD Punktmatrixdisplays
- 10 Intertechno schalten mit RFM12
- 11 IC2272 schalten mit RFM12
Grundlagen
Ausgehend von einem fertigen und per Telnet erreichbaren Ethersex muss in FHEM zuerst das entsprechende Device definiert werden.
define NETIO_WZ ECMD telnet 192.168.3.81:2701
Eine serielle Anbindung kann mit define <name> ECMD serial <SerialDevice>[<@BaudRate>] alternativ erfolgen.
Anschließend werden die erstellten .classdef-Konfigurationsdateien der einzelnen Funktionen dem System bekannt gemacht. In diesen .classdef-Dateien (Name und Endung sind frei wählbar!) wird die Schnittstelle zwischen FHEM und ECMD/Ethersex definiert. Dabei können mit perl übergebene Parameter und empfangene Daten bearbeitet sowie die in FHEM gebräuchlichen Readings erstellt werden.
attr NETIO_WZ classdefs RFM12_2272=/opt/fhem/FHEM/rfm12_2272.classdef:RFM12_IT=/opt/fhem/FHEM/rfm12_it.classdef:LCD=/opt/fhem/FHEM/lcd.classdef:DHT22=/opt/fhem/FHEM/dht22.classdef:1WIRE=/opt/fhem/FHEM/1wire.classdef
Die Definitionen für IC2272, Intertechno, HD44780-LCD, DHT22 und 1wire sind nun eingebunden. In den folgenden Abschnitten wird auf die einzelnen Devices näher eingegangen. Generell sind Pfade und IP-Adressen sowie übergebene Parameter noch entsprechend der eigenen Konfiguration anzupassen.
1-Wire Temperatursensoren
Die 1wire-Temperatursensoren DS18B20 oder DS18S20 werden im Polling Modus abgefragt. Das macht die zyklische Abfrage aus FHEM heraus wesentlich einfacher. Eine Polling-Zeit von mindestens 30 Sekunden ist absolut ausreichend.Im Vorfeld sollte man sich die ROM-Codes der Sensoren notieren, da diese nachher benötigt werden.
1w-temp.classdef erstellen:
# Uebergabeparameter Onewire Rom-Code
params devID
# Umsetzung in ECMD Befehle 1w get = Temperatur auslesen
get 1W cmd {"1w get %devID\n"}
get 1W expect "\d+.\d+\n"
get 1W postproc {\
s/\n//g;\
my $hash = $defs{%NAME};\
my $temperature = $_;\
my $state = "T: $temperature";\
\
readingsSingleUpdate($hash, "temperature", $temperature, 1);\
readingsSingleUpdate($hash, "state", $state, 1);\
\
}
Die classdef wird eingebunden:
define NETIO_KU ECMD telnet 192.168.3.82:2701 attr NETIO_KU classdefs 1W-TEMP=/opt/fhem/FHEM/1w-temp.classdef
Die Sensoren werden anhand des ROM-Code definiert:
define HZ_WW ECMDDevice 1W-TEMP 284c8820050003d4 attr HZ_WW IODev NETIO_KU define HZ_VL ECMDDevice 1W-TEMP 2890a520050003d7 attr HZ_VL IODev NETIO_KU
Eine zyklische Messung pro Minute lässt sich in dieser Form auslösen:
define Messung_1w at +*00:01 get HZ_WW 1W;; get HZ_VL 1W attr Messung_1w verbose 0
DHT22 Temperatur-/Feuchtesensoren
Ethersex unterstützt die preiswerten Temperatur-/Feuchtesensoren DHT11 und DHT22, wobei letztere um einiges genauer sind.
Die Sensoren benötigen 5V Betriebsspannung und kommunizieren über je einen Pin mit dem Prozessor. Der Preis pro Stück liegt derzeit bei etwa 3.50 Euro (ebay/China). Wer die Trägheit und Ungenauigkeit der S300TH oder TX29DTH kennt, wünscht sich vermutlich Besseres; vor allem bei Berechnung von Taupunkt und absoluter Feuchte, welche von der Genauigkeit der gemessenen Eingangsgrößen sehr profitieren. Berechnungen von Hand kann man beim Wetterochs durchführen. Die automatische Berechnung der absoluten Feuchte in FHEM wird im Forum erklärt.
Einbindung in FHEM
dht22m.classdef erstellen:
# Uebergabeparameter DHT22 ID 0...n
params devID
# Umsetzung in ECMD Befehle fuer DHT22
get DHT cmd {"dht temp %devID\n\000dht humid %devID\n"}
get DHT expect "-?\d+.\d\n"
get DHT postproc {\
s/(.*)\n(.*)\n/T: $1 H: $2/;\
my $hash = $defs{%NAME};\
my $temperature = $1;\
my $humidity = $2;\
my $state = $_;\
\
readingsSingleUpdate($hash, "temperature", $temperature, 1);\
readingsSingleUpdate($hash, "humidity", $humidity, 1);\
readingsSingleUpdate($hash, "state", $state, 1);\
\
}
Die classdef wird eingebunden:
define NETIO_TEST ECMD telnet 192.168.3.89:2701 attr NETIO_TEST classdefs DHT22M=/opt/fhem/FHEM/dht22m.classdef
Die Sensoren werden definiert:
define Test0 ECMDDevice DHT22M 0 attr Test0 IODev NETIO_TEST define Test1 ECMDDevice DHT22M 1 attr Test1 IODev NETIO_TEST define Test2 ECMDDevice DHT22M 2 attr Test2 IODev NETIO_TEST define Test3 ECMDDevice DHT22M 3 attr Test3 IODev NETIO_TEST
Eine zyklische Messung alle 4 Minuten könnte so aussehen:
define Messung_DHT at +*00:04 get Test0 DHT;; get Test1 DHT;; get Test2 DHT;; get Test3 DHT attr Messung_DHT verbose 0
Fünfzehn Messwerte pro Stunde genügen den allermeisten Anforderungen.
BMP085/BMP180 Luftdrucksensor
Ethersex unterstützt den BMP085 (bzw. den BMP180; der Code ist identisch) über das I2C-Interface. Da der Sensor für 3.3V Betriebsspannung ausgelegt ist, muss entweder der I2C-Pegel angepasst oder der ATMega auf 3.3V adaptiert werden. Weiterhin sollte die Höhe über Null bekannt sein. Beispiel: Eine Abfrage per ECMD mit bmp085 pressnn 59000 bedeutet, das ich 590m (59000cm) über NN wohne. Sollte der Befehl bmp085 pressnn aus Platzgründen nicht mehr in Image passen, kann man die Umrechnung auf Normal Null alternativ auch in der classdef erledigen.
Die im Sensor verfügbare Temperatur wird parallel ausgelesen.
Einbindung in FHEM
bmp085.classdef erstellen, falls presnn unterstützt wird (59000 durch eigene Höhe in cm ersetzen!):
get BMP cmd {"bmp085 temp\n\000bmp085 pressnn 59000\n"}
get BMP expect ".*"
get BMP postproc {\
s/(.*)\n(.*)\n/T: $1 P: $2/;\
my $hash = $defs{%NAME};\
my $temperature = $1/10;\
my $pressure = sprintf("%.1f",$2/100);\
my $state = "T: $temperature P: $pressure";\
\
readingsSingleUpdate($hash, "temperature", $temperature, 1);\
readingsSingleUpdate($hash, "pressure", $pressure, 1);\
readingsSingleUpdate($hash, "state", $state, 1);\
\
}
Die Temperatur wird in °C mit einer Nachkommastelle gelesen, der Luftdruck in hPa bzw. mbar auf eine Nachkommastelle gerundet. Passende Readings werden erstellt. Das expect .* kann noch angepasst werden, um bei fehlerhaften Messwerten entsprechend zu reagieren.
Die classdef wird in FHEM eingebunden (mehrere .classdef mit Doppelpunkt trennen: siehe Grundlagen):
define NETIO_STK ECMD telnet 192.168.3.89:2701 attr NETIO_STK classdefs BMP=/opt/fhem/FHEM/bmp085.classdef
Der Sensor wird definiert:
define BMP180 ECMDDevice BMP attr BMP180 IODev NETIO_STK
Das STATE kann mit Maßeinheiten versehen werden:
attr BMP180 stateFormat { sprintf("%s°C %shPa", ReadingsVal("BMP180","temperature",0), ReadingsVal("BMP180","pressure",0)) ;; }
Eine zyklische Messung alle 4 Minuten erfolgt wieder mit at:
define Messung_BMP at +*00:04 get BMP180 BMP attr Messung_BMP verbose 0
Dabei unterdrückt verbose 0 einen zusätzlichen (doppelten) Logeintrag des Messvorganges.
Alternative bmp085.classdef, die die Umrechnung auf Normal Null in Perl macht (590 durch eigene Höhe in m ersetzen):
get pressure cmd {"bmp085 apress\n"}
get pressure expect "\d+\n"
get pressure postproc { s/(..)\n/.$1/; $_/=(1-(590/44330.7692))**5.255; $_ }
get temp cmd {"bmp085 temp\n"}
get temp expect "\d+\n"
get temp postproc { s/(.)\n/.$1/; $_ }
Bei diesem Beispiel können Temperatur und Druck separat ausgelesen werden, hier ein Beispiel für das zyklische Auslesen beider Werte:
define Messung_BMP at +*00:04 get BMP180 pressure ;; get BMP180 temp
analoge Eingänge abfragen
Die analogen Eingänge des ATMega sind recht simpel abzufragen. Dabei werden die hexadezimalen Werte gleich dezimal gewandelt, um die Weiterverarbeitung zu erleichtern.
Einbindung in FHEM
adc.classdef erstellen:
get value cmd {"adc get %PortID\n"}
params PortID
get value expect ".*"
get value postproc {\
my $hexval = hex(trim("$_"));\
my $hash = $defs{%NAME};\
readingsSingleUpdate($hash, "state", $hexval, 1);\
}
Die classdef wird eingebunden:
define NETIO_KU ECMD telnet 192.168.3.89:2701 attr NETIO_KU classdefs ADC=/opt/fhem/FHEM/adc.classdef
Die Sensoren an den ersten beiden Ports werden definiert:
define MP_0 ECMDDevice ADC 0 attr MP_0 IODev NETIO_KU define MP_1 ECMDDevice ADC 1 attr MP_1 IODev NETIO_KU
Eine zyklische Messung alle 60 Sekunden funktioniert damit:
define Messung_adc at +*00:01 get MP_0 value;; get MP_1 value attr Messung_adc verbose 0
digitale Eingänge abfragen
todo
digitale Eingänge - proaktiv
Kontakte, die bei Zustandsänderung sofort in FHEM eine Meldung erzeugen sollen, kann man nicht zeitnah mit Polling abfragen. Diese Ereignisse, welche auch aus einem Control6-Script heraus generiert sein können, sollen selbst Meldung machen. Hierbei wird die ESEND-Funktion benutzt, mit welcher auch mehrere Ethersex'e untereinander kommunizieren können. Dabei ist es nicht relevant, ob das Device in FHEM per ECMDDevice bereits eingebunden wurde. Zuerst muss FHEM auf Port 2701 für Telnet-Verbindungen empfänglich werden:
define telnetECMD telnet 2701 global
Mit Watch io changes and react lässt sich per menuconfig bereits auf einfache Weise eine Abfrage von Portpins mit Generierung eines ESEND-Befehles bewerkstelligen. Das Beispiel soll zeigen, wie bei entsprechender Zustandsänderung an Pin PA0 an 192.168.178.10 ein FHEM-Befehl gesendet wird:
ECMDTCP(PA0, RISING, 192.168.178.10, set Lampe on\n\n) ECMDTCP(PA0, FALLING, 192.168.178.10, set Lampe off\n\n)
Jede Sequenz muss mit \n\n abgeschlossen werden, damit FHEM für weitere Befehle empfangsbereit bleibt. Falls man in FHEM flexibler bei der Weiterverarbeitung sein möchte, bietet sich eine dummy-notify-Kombination an.
LTC1257 D/A-Wandler
Die 12bit Digital-Analog-Wandler von LINEAR TECHNOLOGY werden mit drei Pins bedient. Er wandelt (bei interner Referenzspannung) einen digital übermittelten Wert in eine Spannung von 0-2,048V um. Ein nachgeschalteter OPV als nichtinvertierender Verstärker kann diesen Bereich entsprechend skalieren.
ltc1257.classdef erstellen:
# Umsetzung in ECMD Befehle
# Ein Uebergabeparameter -> Sollwert
set setDAC params dacValue
set setDAC cmd {"ltc1257_set %dacValue\n"}
set setDAC expect "OK\n"
# Keine Uebergabeparameter
set init cmd {"ltc1257_init\n"}
set init expect "OK\n"
#
}
Die classdef wird eingebunden:
define NETIO_KU ECMD telnet 192.168.3.82:2701 attr NETIO_KU classdefs LTC1257=/opt/fhem/FHEM/ltc1257.classdef
Der LTC wird entsprechend definiert:
define HZ_DAC ECMDDevice LTC1257 attr HZ_DAC IODev NETIO_KU
Nun lässt sich mit einem set HZ_DAC init der LTC initialisieren (die gemessene Ausgangsspannung sollte 0V sein) und mit set HZ_DAC setDAC [0...4095] der gewünschte Wert setzen. Hier muss vorab experimentell entsprechend der nachfolgenden Beschaltung die tatsächliche Spannung ermittelt werden.
HD44780 LCD Punktmatrixdisplays
Die beliebten Punktmatrix-Displays auf Basis HD44780 können vollumfänglich in FHEM beschrieben werden.
Einbindung in FHEM
lcd.classdef erstellen:
# Umsetzung der ECMD Befehle
set write params line col text
set write cmd {"lcd goto %line %col\n\000lcd write %text\n"}
set write expect "OK\n"
set write postproc {s/([OK\n|;]*)/success/; "$_" eq "success" ? "ok" : "error";}
set clear params col
set clear cmd {"lcd clear %col\n"}
set clear expect "OK\n"
set clear postproc {s/([OK\n|;]*)/success/; "$_" eq "success" ? "ok" : "error";}
set clear_all cmd {"lcd clear\n"}
set clear_all expect "OK\n"
set clear_all postproc {s/([OK\n|;]*)/success/; "$_" eq "success" ? "ok" : "error";}
set lcd_bl params state
set lcd_bl cmd {"lcd backlight %state\n"}
set lcd_bl expect "OK\n"
set lcd_bl postproc {s/([OK\n|;]*)/success/; "$_" eq "success" ? "ok" : "error";}
Die classdef wird eingebunden:
define NETIO_TEST ECMD telnet 192.168.3.89:2701 attr NETIO_TEST classdefs LCD=/opt/fhem/FHEM/lcd.classdef
Das Display wird definiert:
define WZ_LCD ECMDDevice LCD attr WZ_LCD IODev NETIO_TEST
Es stehen in FHEM folgende Befehle für das LCD bereit:
Befehl | Funktion |
set WZ_LCD clear [ZEILE] | löscht den Inhalt einer ZEILE (0...3) |
set WZ_LCD clear_all | löscht den Inhalt aller Zeilen |
set WZ_LCD lcd_bl STATE | schaltet die Hintergrundbeleuchtung ein oder aus (STATE on oder off) |
set WZ_LCD write [ZEILE] [SPALTE] [TEXT] | schreibt einen TEXT auf Position ZEILE SPALTE (0...n) |
Da ein im TEXT übergebenes Leerzeichen als weiterer Befehl interpretiert wird und zu einer Fehlermeldung führt, ist eine Übergabe nur mit \x20 im Text möglich.
Das gilt auch für Umlaute. Anhand der Zeichensatztabelle lassen sich ä durch \xE1, ü durch \xF5 und ö durch \xEF darstellen. Das ß wird mit \xE2 erreicht. Die Tabelle kann für manche Displays abweichend sein.
Beispiel: set WZ_LCD write 0 0 Fenster\x20schlie\xE2en schreibt ein Fenster schließen auf's LCD.
Komfortable Nutzung in FHEM mit DLCD
Mit dem DLCD-Modul (Wiki-Beitrag / Foren-Beitrag) für FHEM lässt sich jedes Display auf einfache Weise beschreiben. Dabei lassen sich bequem Readings von allen Devices nutzen, aufbereiten (formatieren, umrechnen, etc.) und entsprechend darstellen. Eine genaue Beschreibung hält der Wiki-Beitrag bereit; hier soll ein Beispiel gezeigt werden. Ziel war es, auf einem 16x1 LCD wechselweise Datum/Zeit => Klimadaten Keller => Datum/Zeit => Klimadaten Garten darzustellen. Die Anzeige rotiert im 15-Sekunden-Takt, so das zu 50% Datum/Zeit und je 25% die Werte aus dem Garten und dem Keller angezeigt werden. Es wird bereits im Modul jedes Leerzeichen mit \x20 übersetzt. Der Außensensor ist ein KS300 (bzw. KS200) von ELV. Mit etwas Formatierung und ein paar Leerzeichen lässt sich eine stets gleiche Positionierung der Daten erreichen, da die Zeile nicht explizit gelöscht wird.
Auszug aus der fhem.cfg:
define DLCD_WZ DLCD attr DLCD_WZ dlcdBlankspaceReplace \x20 attr DLCD_WZ dlcdCols 16 attr DLCD_WZ dlcdLine1 %date_WD_ger% %date_D%.%date_M_ger% %time_h%:%time_m% attr DLCD_WZ dlcdLine2 Keller:%1%/%2% attr DLCD_WZ dlcdLine3 %date_WD_ger% %date_D%.%date_M_ger% %time_h%:%time_m% attr DLCD_WZ dlcdLine4 Garten: %3%/%4% attr DLCD_WZ dlcdPhysicalRows 1 attr DLCD_WZ dlcdPollInterval 15 attr DLCD_WZ dlcdRows 4 attr DLCD_WZ dlcdScrolling 1 attr DLCD_WZ dlcdTriggerCmd set WZ_LCD write %L% 0 %T% attr DLCD_WZ dlcdVal1 Keller:temperature attr DLCD_WZ dlcdVal1formatnum 3+1 attr DLCD_WZ dlcdVal2 Keller:humidity attr DLCD_WZ dlcdVal2formatnum 3+1 attr DLCD_WZ dlcdVal3 KS300:temperature attr DLCD_WZ dlcdVal3formatnum 3+1+- attr DLCD_WZ dlcdVal4 KS300:humidity attr DLCD_WZ dlcdVal4formatnum 2+0
Das Ergebnis kann so aussehen:
Die Formatierung bewirkt eine immer identische Platzierung der Daten. Der Außensensor hat keine Zehntelwerte bei der Feuchte, muss dafür aber negative Temperaturen darstellen. Der Innensensor zeigt Zehntelwerte, womit sich Tendenzen eher erkennen lassen.
Intertechno schalten mit RFM12
todo
IC2272 schalten mit RFM12
todo