Energie-Funk-Mess-System EM 1000
Zum Überwachen des Gas- und Stromverbrauchs nutze ich seit Januar 2009 das ELV Energie-Funk-Mess-System EM 1000. Ferner soll auch der variable Verbrauch meiner IT-TK-Infrastruktur dokumentiert werden, da dieser zuweilen für wüste Spekulationen Grundlage war.
Hardware
Das Empfangs-/Anzeigegerät EM 1010 verfügt über einen USB-Port über welchen wir später die Messwerte auslesen und in unsere MySQL-Datenbank speichern wollen.
CentOS 7.x
Informationen über den Energie-Monitor können wir mit Hilfe des Befehls usb-devices
aus dem RPM-Paket usbutils dem System abverlangen.
# usb-devices
... T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0403 ProdID=e0ef Rev=02.00 S: Manufacturer=ELV AG S: Product=ELV EM 1010 PC C: #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=44mA I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=ftdi_sio ...
Mit dem Befehl lshw
können wir uns ebenso anzeigen lassen, ob das Energie-Funk-Mess-System angesteckt und erkannt wird. Da der USB-Stick unter die Klasse generic
fällt suchen wir gezielt nach diesen Geräte-Typus.
# lshw -C generic
*-usb description: Generic USB device product: ELV EM 1010 PC vendor: ELV AG physical id: 2 bus info: usb@2:2 version: 2.00 capabilities: usb-1.10 configuration: driver=ftdi_sio maxpower=44mA speed=12Mbit/s ...
Mit Hilfe des Befehls lsusb
aus dem RPM-Paket usbutils können wir auch die Produkt- und Hersteller-Identifikationsnummer des Energie-Monitors ermitteln.
# lsusb
Bus 002 Device 002: ID 0403:e0ef Future Technology Devices International, Ltd
Zur Kommunikation mit dem Messadapter erfolgt über die zugehörig angelegte Geräte-Datei /dev/ttyUSBx
- in unserem Konfigurationsbeispeil ist dies ttyUSB0.
# ls -alF /dev/ttyUSB*
crw-rw----. 1 root dialout 188, 0 Oct 7 21:15 /dev/ttyUSB0
Software
Perl Bibliotheken
Zum Kommunikation unseres Servers mit dem Energie-Funk-Mess-System EM 1000 verwenden wir das Projekt FHEM. Eine sehr gute Einstiegslektüre ist hierbei das verlinkte Dokument Heimautomatisierungmit fhem - Für Einsteiger –. Zum Auslesen des Datenloggers benötigen wir noch ein paart Perl-Bibliotheken, die wir uns nun noch installieren wollen.
# yum install perl-Device-SerialPort perl-Time-HiRes perl-Compress-Zlib -y
Da wir später die Messergebnisse auch in unserer MariaDB Datenbank speichern wollen benötigen wir noch die passenden Perl-Bibliotheken, welche wir nun auch noch installieren werden.
# yum install perl-DBI perl-DBD-MySQL -y
FHEM
Download
Als erstes laden wir uns das aktuelle Programmarchiv von der FHEM Downloadseite auf unseren Rechner.
Hierzu legen wir uns erst noch den entsprechenden Zielordner an, falls noch nicht erfolgt.
# mkdir /usr/local/src/packages
Dann wechseln wir in das Verzeichnis.
# cd /usr/local/src/packages
Im nächsten Schritt holen wir uns nun mit Hilfe von wget das entsprechende Programmarchiv.
# wget http://fhem.de/fhem-6.0.tar.gz
Zu gute Letzt entpacken wir das Archiv, verschieben den Ordner an Ort und Stelle und verlinken diesen entsprechend noch.
# tar zxvf fhem-6.0.tar.gz -C /usr/local/src
# ln -s /usr/local/src/fhem-6.0 /usr/local/src/fhem
System-Konfiguration
Zunächst legen wir uns einen Systemuser an, unter dem später der Daemon mit den passenden Rechten laufen wird. Die uid
wählen wir passend zu unsere Systemumgebung - in diesem Konfigurationsbeispiel ist das die Nummer 977. Als Gruppe verwenden wir die Systemgruppe dialout
da wir so ohne Probleme die richtigen Gruppenrechte zum Ansprechen der Gerätedatei des USB-Devices nutzen können.
# adduser --no-create-home --gid dialout --uid 977 --shell /sbin/nologin fhem
# ls -alF /dev/ttyUSB*
crw-rw----. 1 root dialout 188, 0 Oct 7 21:15 /dev/ttyUSB0
Für die Logdateien legen wir ein zugehöriges Verzeichnis an und weisen die Rechte dem System-User fhem
zu.
# mkdir /var/log/fhem/ # chown fhem:dialout /var/log/fhem/
Stationswerte abfragen
Für die ersten Schritte scheint das Paket FHEM recht geeignet. Zumindest können wir schon mal damit die ersten (Meß-)Werte auslesen.
Einen ersten Testabruf der Stationsdaten erfolgt mittels em1010.pl
; dieses befindet sich unter /usr/local/src/fhem/contrib/em1010.pl.
# /usr/local/src/fhem/contrib/em1010.pl
Usage: perl em1010.pl serial-device command args
Unseren ersten Stromzähler - der mit der ID 1 - fragen wir also wie folgt ab:
# /usr/local/src/fhem/contrib/em1010.pl /dev/ttyUSB0 getDevStatus 1
Readings (off 2): 567 Nr devs (off 6): 1 puls/5min (off 13): 7 puls.max/5min (off 15): 416 cur.energy(off ): 0.047 kWh cur.power ( ): 0.560 kW cur.power max ( ): 0.000 kW energy h (off 33): 0.593 kWh (h) energy d (off 37): 11.393 kWh (d) energy w (off 41): 22.633 kWh (w) total energy (off 7): 22.633 kWh (total) Alarm PA (off 45): 0 W Price CF (off 47): 0.15 EUR/kWh R/kW EC (off 49): 150 RAW 0300 3702 0000 0143 0d00 0035 2307 00a0 RAW 0180 aeb7 b9ab b997 b300 00ae b98b b98b RAW b959 0000 00ad 0600 0043 0d00 0000 00dc RAW 05dc 05
FHEM - GPL'd Server für die Haus Automation
Im weiteren Verlauf betrachten wie nun das Softwareprojekt FHEM etwas genauer. Schließlich wollen wir ja unsere Meßpunkte
- Haus-Stromzähler
- EDV-Schrank-Stromzähler
- Gaszähler
laufend abfragen und die Meßwerte in unsere vorhandene MySQL-Datenbank ablegen und später graphisch aufbereiten.
Konfiguration
erste Konfiguration
Als erstes passen wir die mitgelieferte Konfigurationsdatei unseren individuellen Gegebenheiten an:
# cp /usr/local/src/fhem/fhem.cfg /etc/fhem.cfg # vim /etc/fhem.cfg
- /etc/fhem.cfg
# Logdatei mit vollständigem Pfad attr global logfile /var/log/fhem/fhem-%Y-%m.log # FHEM Arbeits-Verzeichnis attr global modpath /usr/local/src/fhem/ # "normal" verbosity (min 1, max 5) attr global verbose 3 # statefile in dem die Stati der Geräte gesichert werden attr global statefile /var/log/fhem/fhem.save # FHEM-MOTD deaktiviert attr global motd none # Globaler Port der WEB-GUI define WEB FHEMWEB 8083 global # WEB-GUI absichern define allowedWEB allowed attr allowedWEB validFor WEB,WEBphone,WEBtablet attr allowedWEB basicAuth { "$user:$password" eq "admin:streng-geheimes-Passwort" } attr allowedWEB allowedCommands set,get # Fake FileLog Eintrag, für denm Zugriff über die WEB-GUI FHEMWEB define Logfile FileLog ./log/fhem-%Y-%m.log fakelog define autocreate autocreate attr autocreate filelog ./log/%NAME-%Y.log define eventTypes eventTypes ./log/eventTypes.txt # Disable this to avoid looking for new USB devices on startup define initialUsbCheck notify global:INITIALIZED usb create # Definitionen der Messpunkte define EM EM /dev/ttyUSB0 # Serieller (ttyUSB)-Port des FHZ 1000 PC define Hauptzaehler EMWZ 1 define Gaszaehler EMGZ 9 define EDV_Schrank EMEM 5
Paketfilter/Firewall
Damit wir später von den berechtigten Hosts Verbindungen zu unserem FHEM-Daemon aufbauen können, müssen wir für diese noch Änderungen am Paketfilter firewalld vornehmen.
Unter CentOS 7 wird als Standard-Firewall die dynamische firewalld verwendet. Ein großer Vorteil der dynamischen Paketfilterregeln ist unter anderem, dass zur Aktivierung der neuen Firewall-Regel(n) nicht der Daemon durchgestartet werden muss und somit alle aktiven Verbindungen kurz getrennt werden. Sondern unsere Änderungen können on-the-fly aktiviert oder auch wieder deaktiviert werden.
In unserem Konfigurationsbeispiel hat unser Server, an dem der Energie-Monitor via USB-Kabel angeschlossen ist die IP-Adresse 10.0.0.27
und der WEB-Server die 10.0.0.107
. Wir brauchen also eine Firewall-Definition, die ausschließlich Verbindungen von der Source-IP 10.0.0.107 auf die Destination-IP 10.0.0.27 auf Port 8083 gestattet.
Mit Hilfe des Programms firewall-cmd legen wir nun eine permanente Regel in der Zone public, dies entspricht in unserem Beispiel das Netzwerk-Interface eth0 mit der IP 10.0.0.27 an. Als Source-IP geben wir die IP-Adresse unseres WEB-/Proxy-Servers also die 10.0.0.107 an. Genug der Vorrede, mit nachfolgendem Befehl wird diese restriktive Regel angelegt.
# firewall-cmd --permanent --zone=external --add-rich-rule="rule family="ipv4" source address="10.0.0.107/32" port protocol="tcp" port="8083" destination address="10.0.0.27/32" accept"
Zum Aktivieren brauchen wir nun nur einen reload des Firewall-Daemon vornehmen.
# firewall-cmd --reload
Fragen wir nun den Regelsatz unserer iptables-basieten Firewall ab, finden wir in der Chain IN_public_allow unsere aktive Regel.
# iptables -nvL IN_external_allow
Chain IN_external_allow (1 references) pkts bytes target prot opt in out source destination 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW,UNTRACKED 12 720 ACCEPT tcp -- * * 10.0.0.107 10.0.0.27 tcp dpt:8083 ctstate NEW,UNTRACKED
Programmstart
Wir starten nunmehr zum ersten mal FHEM.
# perl /usr/local/src/fhem/fhem.pl /etc/fhem.cfg
Im Logfile /var/log/fhem/fhem-2020-10.log wird uns der Start entsprechend quittiert:
2020.10.07 22:37:17 1: Including /etc/fhem.cfg 2020.10.07 22:37:18 3: WEB: port 8083 opened 2020.10.07 22:37:18 1: define Logfile FileLog ./log/fhem-%Y-%m.log fakelog: Can't open ./log/fhem-2020-10.log: Permission denied 2020.10.07 22:37:18 2: eventTypes: loaded 0 events from ./log/eventTypes.txt 2020.10.07 22:37:18 3: EM opening device /dev/ttyUSB0 2020.10.07 22:37:18 3: EM opened device /dev/ttyUSB0
In der Prozessliste finden wir das laufende Programm ebenso:
# ps aux | grep fhem
fhem 12347 0.5 1.1 180008 21296 pts/1 S 22:37 0:00 perl /usr/local/src/fhem/fhem.pl /etc/fhem.cfg
Mit dem Befehl netstat -tulpen können wir auch noch überprüfen, ob die Ports 8083, 8084 und 8085 auch geöffnet wurden.
# netstat -tulpen | grep 808
tcp 0 0 0.0.0.0:8083 0.0.0.0:* LISTEN 977 161400 12347/perl63/perl
Nun rufen wir die Statusseite von FHEM in unserem bevorzugten Browser auf.
$ firefox http://10.0.0.27:8083/fhem
Über den Menüpunkt [Everything] können wir uns die Detail zu unserem Gerät anzeigen lassen.
Über den FHEM-Befehl shutdown können wir unseren ersten Test beenden.
Im Logfile wird uns dies entsprechend quittiert:
2020.10.07 22:47:46 0: Server shutdown
Der status unseres FHEM-Gerätes wurde in der Logdatei /var/log/fhem/fhem.save gesichert.
# cat /var/log/fhem/fhem.save
setstate EDV_Schrank 0.29 kW
setstate EDV_Schrank 2020-10-07 22:44:10 5min_pulses 29
setstate EDV_Schrank 2020-10-07 22:44:10 5min_pulses_max 32
setstate EDV_Schrank 2020-10-07 22:44:10 alarm_PA_W 0
setstate EDV_Schrank 2020-10-07 22:44:10 energy_kWh 429.247
setstate EDV_Schrank 2020-10-07 22:44:10 energy_kWh_d 7.140
setstate EDV_Schrank 2020-10-07 22:44:10 energy_kWh_h 0.296
setstate EDV_Schrank 2020-10-07 22:44:10 energy_kWh_w 49.657
setstate EDV_Schrank 2020-10-07 22:44:10 power_kW 0.290
setstate EDV_Schrank 2020-10-07 22:44:10 power_kW_max 0.320
setstate EDV_Schrank 2020-10-07 22:44:10 price_CF 0.150
setstate Gaszaehler 0 m3ph
setstate Gaszaehler 2020-10-07 22:44:10 5min_pulses 0
setstate Gaszaehler 2020-10-07 22:44:10 Rperm3_EC 100
setstate Gaszaehler 2020-10-07 22:44:10 act_flow_m3 0.000
setstate Gaszaehler 2020-10-07 22:44:10 alarm_PA 0 Watt
setstate Gaszaehler 2020-10-07 22:44:10 cum_m3 0.000
setstate Gaszaehler 2020-10-07 22:44:10 m3ph 0.000
setstate Gaszaehler 2020-10-07 22:44:10 price_CF 0.630
setstate Hauptzaehler 0.56 kW
setstate Hauptzaehler 2020-10-07 22:44:10 5min_pulses 7
setstate Hauptzaehler 2020-10-07 22:44:10 RperKW_EC 150
setstate Hauptzaehler 2020-10-07 22:44:10 alarm_PA 0 Watt
setstate Hauptzaehler 2020-10-07 22:44:10 cum_kWh 0.047
setstate Hauptzaehler 2020-10-07 22:44:10 energy 0.047
setstate Hauptzaehler 2020-10-07 22:44:10 power 0.560
setstate Hauptzaehler 2020-10-07 22:44:10 price_CF 0.150
setstate Hauptzaehler 2020-10-07 22:44:10 summary Pulses: 7 Energy: 0.047 Power: 0.560 Cum: 0.047
setstate Logfile active
setstate WEB 2020-10-07 22:44:07 state Initialized
setstate allowedWEB validFor:WEB,WEBphone,WEBtablet
setstate allowedWEB 2020-10-07 22:44:07 state validFor:WEB,WEBphone,WEBtablet
setstate autocreate active
setstate eventTypes active
setstate global no definition
setstate initialUsbCheck 2020-10-07 22:44:10
setstate initialUsbCheck 2020-10-07 22:44:07 state active
erweiterte Konfiguration
Startscript
systemd-Startscript
Zum (automatischen) Starten des Daemon benötigen wir noch ein passendes systemd-Script. Dieses legen wir im Verzeichnis /etc/systemd/system/
an.
# vim /etc/systemd/system/fhem.service
- /etc/systemd/system/fhem.service
[Unit] Description=FHEM service After=network.target [Service] Type=forking User=fhem Group=dialout WorkingDirectory=/usr/local/src/fhem ExecStart=/usr/bin/perl /usr/local/src/fhem/fhem.pl /etc/fhem.cfg [Install] WantedBy=multi-user.target
Nun machen wir das Script noch dem System bekannt.
# systemctl daemon-reload
Den FHEM-Daemon starten wir nun ganz einfach.
# systemctl start fhem.service
Der Start wird im Logfile des Datenbankservers /var/log/fhem/fhem-2020-10.log entsprechend dokumentiert.
# less /var/log/fhem/fhem-2020-10.log
2020.10.08 08:49:23 1: Including /etc/fhem.cfg 2020.10.08 08:49:23 3: WEB: port 8083 opened 2020.10.08 08:49:23 2: eventTypes: loaded 25 events from ./log/eventTypes.txt 2020.10.08 08:49:23 3: EM opening device /dev/ttyUSB0 2020.10.08 08:49:23 3: EM opened device /dev/ttyUSB0 2020.10.08 08:49:49 1: Including /var/log/fhem/fhem.save 2020.10.08 08:49:49 1: usb create starting 2020.10.08 08:49:49 3: Probing CUL device /dev/ttyS0 2020.10.08 08:49:49 3: Probing CUL device /dev/ttyS1 2020.10.08 08:49:49 1: PERL WARNING: can't getattr: Input/output error at /usr/local/src/fhem//FHEM/DevIo.pm line 426. 2020.10.08 08:49:49 1: CUL: Can't open /dev/ttyS1: Input/output error 2020.10.08 08:49:49 3: Probing CUL device /dev/ttyS2 2020.10.08 08:49:49 1: CUL: Can't open /dev/ttyS2: Input/output error 2020.10.08 08:49:49 3: Probing CUL device /dev/ttyS3 2020.10.08 08:49:49 1: CUL: Can't open /dev/ttyS3: Input/output error 2020.10.08 08:49:49 1: usb create end 2020.10.08 08:49:49 0: Featurelevel: 6 2020.10.08 08:49:49 0: Server started with 11 defined entities (fhem.pl:21056/2020-01-26 perl:5.016003 os:linux user:fhem pid:29810)
Möchten wir überprüfen, ob der FHEM-Daemon läuft, haben wir mehrere Möglichkeiten.
- systemctl
# systemctl status fhem.service -l
● fhem.service - FHEM service Loaded: loaded (/etc/systemd/system/fhem.service; disabled; vendor preset: disabled) Active: active (running) since Thu 2020-10-08 08:49:23 CEST; 2min 19s ago Process: 29809 ExecStart=/usr/bin/perl /usr/local/src/fhem/fhem.pl /etc/fhem.cfg (code=exited, status=0/SUCCESS) Main PID: 29810 (perl) CGroup: /system.slice/fhem.service └─29810 /usr/bin/perl /usr/local/src/fhem/fhem.pl /etc/fhem.cfg Oct 08 08:49:23 vml000027.dmz.nausch.org systemd[1]: Starting FHEM service... Oct 08 08:49:23 vml000027.dmz.nausch.org systemd[1]: Started FHEM service.
- ps
# ps aux | grep fhem
fhem 29810 0.0 1.1 180392 22032 ? S 08:49 0:00 /usr/bin/perl /usr/local/src/fhem/fhem.pl /etc/fhem.cfg root 30096 0.0 0.0 112812 936 pts/0 S+ 08:53 0:00 grep --color=auto fhem
- netstat
# netstat -tulpn
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8083 0.0.0.0:* LISTEN 29810/perl tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1152/sshd ...
automatisches Starten des Dienste beim Systemstart
Damit nun unser MariaDBL-Server beim Booten automatisch gestartet wird, nehmen wir noch folgenden Konfigurationsschritt vor.
# systemctl enable fhem.service
Created symlink from /etc/systemd/system/multi-user.target.wants/fhem.service to /etc/systemd/system/fhem.service.
Wollen wir überprüfen, ob der Datenbank-Daemon beim Serverstart automatisch gestartet wird, fragen wir dies mit folgendem Befehl ab.
# systemctl is-enabled fhem.service
enabled
Startet der FHEM-Daemon nicht automatisch, wird ein disabled zurück gemeldet.
Nun können wir bequem den FHEM-Daemon starten und Stoppen.
# service fhem start
Starting FHEM: [ OK ]
Oder eben stoppen:
# service fhem stop
Stopping FHEM: [ OK ]
Damit nun der Daemon beim Starten des Systems automatisch gestartet werden kann, legen wir die notwendigen Symlinks automatisch an.
# chkconfig fhem on
Wenn wir uns unsicher sind, ob der Daemon beim Systemstart in den entsprechenden Runleveln auch gestartet wird, vergewissern wir uns mit folgendem Aufruf.
# chkconfig --list | grep fhem
fhem 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Apache V-Host mit Authentifizierung
In der Regel wollen wir ja nicht, dass jedermann, also quasi Hinz & Kunz auf unsere FHEM-Web-Seite zugreifen kann. FHEM selbst stellt uns hierzu keine Einstellungsoptionen zur Verfügung. Wir greifen daher auf die Dienste unseres Apache-Webservers zurück.
Neben der Benutzerauthentifizierung gegen unseren zentralen LDAP-Server sichern wir noch die Übertragung mit Hilfe eines SSL-Zertifikats ab.
In die Konfigurationsdatei fü unsere vHosts /etc/httpd/conf.d/vhosts.conf tragen wir hierzu ein.
# vim /etc/httpd/conf.d/vhosts.conf
- /etc/httpd/conf.d/vhosts.conf
# # FHEM : fhem.nausch.org # <VirtualHost *:80> ServerAdmin webmaster@nausch.org ServerName fhem.nausch.org ServerAlias www.fhem.nausch.org ServerPath / <Location /> Options -Indexes FollowSymLinks Order deny,allow Deny from all Allow from 127.0.0.1 Allow from 10.0.0.27/32 Allow from 10.0.0.0/26 </Location> Redirect / https://fhem.nausch.org/ ErrorLog logs/fhem_error.log CustomLog logs/fhem_access.log combined </VirtualHost> <VirtualHost *:443> ServerAdmin webmaster@nausch.org ServerName fhem.nausch.org ServerAlias www.fhem.nausch.org ServerPath / <Location /> Options -Indexes FollowSymLinks AuthType Basic AuthName "FHEM Home Automation on vml000090 - nausch.org" AuthBasicProvider ldap AuthzLDAPAuthoritative On AuthLDAPURL "ldap://ldap.dmz.nausch.org:389/ou=People,dc=nausch,dc=org?uid" AuthLDAPBindDN "cn=TechnischerUser,dc=nausch,dc=org" AuthLDAPBindPassword "Das_streng_geheime_Passwort_das_keiner_kennt" Require ldap-user django michael Order deny,allow Deny from all Allow from 127.0.0.1 Allow from 10.0.0.20/32 Allow from 10.0.10.0/26 </Location> ProxyRequests Off ProxyPreserveHost On ProxyPass /fhem http://10.0.0.27:8083/fhem ProxyPassReverse /fhem http://10.0.0.27:8083/fhem ErrorLog logs/fhem_error.log CustomLog logs/fhem_access.log combined </VirtualHost>
Bevor wir den Apache-Webserver durchstarten überprüfen wir noch die Konfigurationsdatei auf schreib und Tipp-Fehler.
# apachectl -t
Syntax OK
Da kein Fehler enthalten ist, starten wir nun zur Aktivierung den Webserver einmal durch.
# systemctl restart httpd.service
Wir erreichen nun unseren vHost für FHEM ganz einfach via fhem.nausch.org. Geben wir beim Verbindungsprotokoll „nur“ http statt https ein, werden wir direkt zur verschlüsselten Seite weitergeleitet.
$ firefox http://fhem.nausch.org
Datenbank-Konfiguration
Im Verzeichnis /usr/local/src/fhem/contrib/dblog/ werden uns Vorlagen für unsere Datenbankeinstellung mitgeliefert, die wir nun nachfolgend zu Rate ziehen werden.
Datenbankdefinition
Die Konfiguration der nötigen Tabellen nehmen wir mit Hilfe der von FHEM mitgelieferten Schematas vor. Dazu nutzen wir entweder direkt den Konsolenzugang, oder wir verwenden phpMyAdmin.
- Datenbank anlegen
Als erstes legen wir die Datenbank an. MySQL frägt uns bei den nachfolgenden Definitionen nach dem Passwort unseres mysql-Superusers root.# mysql -h 127.0.0.1 -u root -p
Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 37 Server version: 5.1.61 Source distribution Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> create database fhem; Query OK, 1 row affected (0.11 sec)
- neuen Benutzer anlegen
Mit folgendem Befehl legen wir uns einen neuen Nutzer an:mysql> CREATE USER 'fhemdatabaseuser'@'vml000020.dmz.nausch.org' IDENTIFIED BY 'databasepassword'; Query OK, 0 rows affected (0.00 sec) mysql>
sowie
mysql> CREATE USER 'fhemdatabaseuser'@'10.0.0.20' IDENTIFIED BY 'databasepassword'; Query OK, 0 rows affected (0.00 sec) mysql>
- Benutzerprivilegien setzen und zuweisen
Anschließend setzen wir die Benutzerrechte unseres gerade angelegten Datenbanknutzers.mysql> GRANT ALL PRIVILEGES ON fhem.* TO 'fhemdatabaseuser'@'vml000020.dmz.nausch.org' IDENTIFIED BY 'databasepassword' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0; Query OK, 0 rows affected (0.01 sec) mysql>
und
mysql> GRANT ALL PRIVILEGES ON fhem.* TO 'fhemdatabaseuser'@'10.0.0.20' IDENTIFIED BY 'databasepassword' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0; Query OK, 0 rows affected (0.01 sec) mysql>
- Rechte des Nutzers in der Datenbank neu laden
Im letzten Schritt laden wir nun die Rechte unseres neuen Datenbankusers.mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) mysql>
- mySQL-Datenbanktabellen anlegen
Aus der Vorlagedatei /usr/local/src/fhem/contrib/dblog/fhemdb_create.sql übernehmen wir nun die Tabellendefinition und legen diese an. Zuvor benutzen wir noch die richtige Datenbank fhem, wie wir zuvor angelegt haben.mysql> use fhem; Database changed
Anschließend legen wir die beiden Tabellen an.
mysql> CREATE TABLE history (TIMESTAMP TIMESTAMP, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(64), READING varchar(32), VALUE varchar(32), UNIT varchar(32)); Query OK, 0 rows affected (0.08 sec)
und
mysql> CREATE TABLE current (TIMESTAMP TIMESTAMP, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(64), READING varchar(32), VALUE varchar(32), UNIT varchar(32)); Query OK, 0 rows affected (0.13 sec)
- mySQL-Datenbankverbindung beenden
Unsere Konfiguration unseres neuen Datenbanknutzers ist hiermit beendet und wir können die Verbindung zur Datenbank wieder schließen.mysql> exit Bye
Zugangstest
Als nächstes überprüfen wir, ob der zuvor angelegt User/Zugang auch funktioniert.
# mysql -D fhem -u fhemuser -h mysql-host -p
Enter password: Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2034 Server version: 5.1.61 Source distribution Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show tables; +----------------+ | Tables_in_fhem | +----------------+ | current | | history | +----------------+ 2 rows in set (0.00 sec) mysql> quit Bye
erweiterte Konfiguration
In der README unter /usr/local/src/fhem-4.5/contrib/dblog finden wir weitere Angaben zur Konfiguration:
# less /usr/local/src/fhem/contrib/dblog/README
- /usr/local/src/fhem-4.5/contrib/dblog/README
For usage instruction see commandref.html, section define 2007-12-30bn - 93_DbLog.pm copy this file into <modpath>/FHEM - db.conf sample database configuration file - fhemdb_create.sql sample sql command to create a mysql database for logging purposes - fhemdb_get.pl sample perl script for retrieving the current (latest) data from the logging database
- Wir kopieren also die Datei 93_DbLog.pm in unseren modpath.
# cp /usr/local/src/fhem/contrib/dblog/93_DbLog.pm /usr/share/fhem/FHEM/<code> - Anschließend kopieren wir die Datenbank-Konfigurationsdatei nach //**/etc/**//. <code> # cp /usr/local/src/fhem/contrib/dblog/db.conf /etc/fhem_db.conf
- Dann bearbeiten wir die gerade kopierte Konfigurationsdatei und tragen dort unsere benutzerspezifischen Änderungen ein.
# vim /etc/fhem_db.conf
- /etc/fhem_db.conf
# # database configuration file # # # %dbconfig= ( connection => "mysql:database=fhem;host=databasehost;port=3306", user => "fhemdatabaseuser", password => "databasepassword", );
- Abschließend erweitern wir nun noch unsere Hauptkonfigurationsdatei von FHEM /etc/fhem.cfg um nachfolgende Definitionen.
# vim /etc/fhem.cfg
Unser Hauptkonfigurationsdatei /usr/local/etc&fhem/fhem.cfg erweitern wir um folgende Definitionen:
Definition der beiden Strommessstellen
define Hauptzaehler EMWZ 1
define EDV_Schrank EMEM 5
# Erst einmal alle Meldungen in die Datenbank schreiben
define logdb DbLog /usr/local/etc/fhem/db.conf .*:.*
Nach dem Start unseres Serverdienstes fhem.pl erhalten wir eine entsprechende positive Meldung im Logfile.
# fhem.pl /etc/fhem.conf
2012.07.27 20:35:39 2: Telnet port 7072 opened 2012.07.27 20:35:39 2: FHEMWEB port 8083 opened 2012.07.27 20:35:39 2: FHEMWEB port 8084 opened 2012.07.27 20:35:39 2: FHEMWEB port 8085 opened 2012.07.27 20:35:39 3: EM opening device /dev/ttyUSB0 2012.07.27 20:35:39 3: EM opened device /dev/ttyUSB0 2012.07.27 20:36:46 3: Connecting to database mysql:database=fhem;host=10.0.0.30;port=3306 with user fhemdatenbankuser 2012.07.27 20:36:46 3: Connection to db mysql:database=fhem;host=datenbankhost.dmz.nausch.org;port=3306 established 2012.07.27 20:36:46 0: Server started (version 5.2 from 2011-12-31 ($Id: fhem.pl 1159 2011-12-31 13:31:58Z rudolfkoenig $), pid 1955)
In unserer MySQL-Datenbanktabelle tauchen die entsprechenden Werte auf:
Ebenso werden in der Statusübersicht im Browserfenster die beiden definierten Meßpunkte angezeigt:
Zum Abfragen der MySQL-Datenbank kann das mitgelieferte Programm fhemdb_get.pl benutzt werden. Dieses kopieren wir als erstes nach /usr/local/bin
# cp /usr/local/src/fhem/contrib/dblog/fhemdb_get.pl /usr/local/bin/
Anschließend passen wir noch die Datenbankdefinitionen in dem Script unseren lokalen Bedürfnissen nach an.
# vim /usr/local/bin/fhemdb_get.pl
- /usr/local/bin/fhemdb_get.pl
#!/usr/bin/perl # ################################################################ # # Copyright notice # # (c) 2007 Copyright: Dr. Boris Neubert (omega at online dot de) # All rights reserved # # This script free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # The GNU General Public License can be found at # http://www.gnu.org/copyleft/gpl.html. # A copy is found in the textfile GPL.txt and important notices to the license # from the author is found in LICENSE.txt distributed with these scripts. # # This script is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # This copyright notice MUST APPEAR in all copies of the script! # ################################################################ # # this script returns the current reading for a device stored in # the fhem logging database # # Usage: # fhemdb_get.pl <device> <reading> [<reading> ...] # Example: # fhemdb_get.pl ext.ks300 temperature humidity # # # # global configuration # my $dbconn = "mysql:database=fhem;host=datenbankhost.dmz.nausch.org;port=3306"; my $dbuser = "fhemdatenbankuser"; my $dbpassword = "fhemdatenbankpassword"; # # nothing to change below this line # use strict; use warnings; use DBI; (@ARGV>=2) || die "Usage: fhemdb_get.pl <device> <reading> [<reading> ... ]"; my $device= $ARGV[0]; my @readings=@ARGV; shift @readings; my $set= join(",", map({"\'" . $_ . "\'"} @readings)); my $dbh= DBI->connect_cached("dbi:$dbconn", $dbuser, $dbpassword) || die "Cannot connect to $dbconn: $DBI::errstr"; my $stm= "SELECT READING, VALUE FROM current WHERE (DEVICE='$device') AND (READING IN ($set))"; my $sth= $dbh->prepare($stm) || die "Cannot prepare statement $stm: $DBI::errstr"; my $rc= $sth->execute() || die "Cannot execute statement $stm: $DBI::errstr"; my %rs; my $reading; my $value; while( ($reading,$value)= $sth->fetchrow_array) { $rs{$reading}= $value; } foreach $reading (@readings) { $value= $rs{$reading}; $value= "NULL" if(!defined($value)); print "$reading:$value "; } print "\n"; die $sth->errstr if $sth->err; $dbh->disconnect();
Zum Abfragen des aktuellen Zählerverbrauchswert unseres Hauptzählers verwenden wir folgende Syntax: fhemdb_get.pl <device> <reading> [<reading> …], also zum Beispiel:
# fhemdb_get.pl Hauptzaehler cum_kWh power
cum_kWh:5.656 power:0.720
Datenbank-Loglevel anpassen
Für die ersten Test ist die Angaben von .*:.* in der Konfigurationsdatei sicher hilfreich, jedoch für den laufenden Betrieb kontraproduktiv. Wir geben also über eine passende REXEXP an, welche Werte wir zukünftig nur noch in der MySQL-Tabelle archivieren wollen.
Unser Konfigurationsdatei /etc/fhem.conf erweitern wir daher um folgende Definitionen:
# vim /etc/fhem.conf
- /etc/fhem.conf
# # pgm2 / autocreate configfile. Take a look at the other examples for more. # attr global logfile /var/log/fhem/fhem-%Y-%m.log attr global modpath /usr/share/fhem # where our FHEM directory is attr global port 7072 global # our TCP/IP port attr global statefile /var/log/fhem/fhem.save # where to save the state of the devices attr global verbose 3 # "normal" verbosity (min 1, max 5) define WEB FHEMWEB 8083 global define WEBphone FHEMWEB 8084 global attr WEBphone smallscreen define WEBtablet FHEMWEB 8085 global attr WEBtablet touchpad # Fake FileLog entry, to access the fhem log from FHEMWEB define Logfile FileLog /var/log/fhem/fhem-%Y-%m.log fakelog define autocreate autocreate attr autocreate autosave attr autocreate device_room %TYPE attr autocreate filelog /var/log/fhem/%NAME-%Y.log attr autocreate weblink attr autocreate weblink_room Plots # Disable this to avoid looking for new USB devices on startup # Django : 2012-07-27 # initialUsbCheck disabled # define initialUsbCheck notify global:INITIALIZED usb create # If the above notify did not helped, then you probably have to enable some of # the following lines. Verify first that /dev/xxx ist correct. #define FHZ FHZ /dev/USB0 #define CUL CUL /dev/ttyACM0@9600 1234 #attr CUL rfmode HomeMatic #define EUL TCM 310 /dev/ttyACM0@57600 #define BscBor TCM 120 /dev/ttyUSB0@9600 #define BscSmartConnect TCM 310 /dev/ttyUSB0@57600 # Django : 2012-07-27 define EM EM /dev/ttyUSB0 # the serial port of an FHZ 1000 PC define Hauptzaehler EMWZ 1 define Gaszaehler EMGZ 9 define EDV_Schrank EMEM 5 # Django : 2012-07-27 # Erst einmal alle Meldungen in die Datenbank schreiben #define logdb DbLog /etc/fhem_db.conf .*:.* # Django : 2012-07-27 # Nur noch die aktuellen verbrauchswerte in die MySQL schreiben define logdb DbLog /etc/fhem_db.conf Hauptzaehler:power.*|EDV_Schrank:power_kW\b.*|Gaszaehler:act_flow_m3.*
Mit einem rereadcfg veranlassen wir nun, dass die neue Konfigurationseinstellung(en) aktiv werden.
Graphische Datenaufbereitung mit cacti
Die optische Aufbereitung der hinterlegten Verbrauchswerte in der MySQL-Datenbank nehmen wir mit Hilfe von Cacti vor. Die hierzu notwendige Installation von Cacti ist im Dokuwiki unter Serverüberwachung mittels SNMP, RRD-Tool und Cacti ausführlich beschrieben.
Die Konfiguration(en) zum Darstellen unserer Energieverbrauchswerte (Gas und Strom) setzt auf einen funktionstüchtigen Cacti-Server auf und ist im Kapitel Energieverbrauch bei den Cacti Beispielskonfigurationen beschrieben .
Gaszähler
Die optische Erkennung der Walzendrehungen haben mit dem von ELV mitgelieferten „optischen Auge“ nie so recht funktioniert - da die Erkennung wohl nur in einer sehr eingegrenzten Drehgeschwindigkeit zuverlässig funktioniert. Ich habe mir daher bei der Firma Ernst Heitland für meinen Gaszähler einen passenden Reedkontakt (ACTARIS 951-858-06 08 30/1004) besorgt.
Der Anschluß des Reedkontaktes erfolgt an den Funk-Sensor Gaszähler EM 1000-GZ und EM 1000-GZS ohne Netzteil. Das Gerät ist auch als Bausatz: Funk-Sensor Gaszähler EM 1000-GZ und EM 1000-GZS erhältlich. Den Schließkontakt des Heitland-Reed-Kontaktes habe ich dabei einfach zwischen ST6 und ST3, und den Öffner zwischen ST5 und ST4 geklemmt und die originale Sensoreinheit entsorgt. Die Klemmen bezeichnen dabei die Anschlussklemmen der Sensoreinheit EM 1000-GZS. Bild 5 auf Seite 5 des vorgenannten PDFs illustriert die Klemmpunkte.
Die Definition des Ausgabegraphen ist hier dokumentiert:
(Haupt)-Stromzähler
Zum Erfassen des Stromverbrauches nutze ich den EM 1000-WZ, der an Hand der roten Markierung der Drehscheibe am Zähler den Verbrauch erfassen kann.
Die Definition des Ausgabegraphen ist hier dokumentiert:
(EDV)-Stromzähler
Zum Erfassen des Stromverbrauches nutze ich den EM 1000-HSM, der direkt im Stromkreis der Zuleitung zum EDV-Schrank hängt, den Verbrauch misst und weiter gibt.
Die Definition des Ausgabegraphen ist hier dokumentiert: