Volkszaehler EMH eHZ

Der Raspberry Pi ist ein Netzwerk fähiger Linux Computer, in der Größe eines Smartphones, der an einen LCD Fernseher/Monitor per HDMI/DVI angeschlossen werden kann, und mit USB PC Tastatur und USB Maus bedient werden kann. Er kann auch per Netzwerk ferngesteuert werden, per SSH Verbinndung (Kommandozeile) oder VNC-Client (grafische Benutzer Oberfläche). Er ist vergleichbar mit einem einfachen PC, und kann auch mit einer grafischen Bedienoberfläche genutzt werden. Auch das abspielen von Multimedia Dateien ist möglich.

In diesem Fall wird der Raspberry Pi als Datensammler (Volkszaehler) für einen elektronischer Haushalts Zähler (eHZ) benutzt, der die Daten (Verbrauchswerte) auf einem eigenen Web-Server interaktiv visualisieren kann (über Datum / Uhrzeit). Bei dieser Anwendung benötigt der Raspberry Pi kein Bildschirm, Tastatur und Maus, sondern wird nur per Netzwerk angesprochen.

Der Stromzähler EMH eHZ arbeitet mit einer seriellen Infrarot Schnittstelle mit Protokoll SML (Smart Message Language).

Das Datenvolumen der mysql Datenbank wächst in 35 Stunden um 638 KB (/var/lib/ibdata1), bei einem Auslesen alle 3 Minuten. Das sind auf das Jahr hochgerechnet 160 MB. Bei der eingesetzten 8 GB SD-Card (class 10) sind nach der Installation noch 4494 MB frei. Also sollte eine Datenmenge von 10 Jahren auf dem Datenträger, inklusive log-files Platz haben. Ob die eingesetzte SD-Card das häufige Schreiben über 10 Jahre mitmacht, ist eine andere Sache. Der Hersteller Sandisk gibt für die Ultra SDHC Card (SDSDU-008G-U46) jedenfalls eine 10 Jahre Garantie.

Die Installation ist beschrieben bei Volkszaehler auf dem Raspberry Pi installieren. Hier werden dann nur noch Besonderheiten und Testhilfen dokumentiert.

Wenn man WLAN einsetzen möchte, muss man berücksichtigen, dass sich bei dem DHCP Betrieb die IP-Nummer vom Router ändert, da eine andere MAC Nummer, vom WLAN Stick, zum Einsatz kommt. Außerdem muss die WLAN SSID und das Passwort im Konfigurationsfile eingegeben werden. Ein weiterer Nachteil ist, dass dann an dem noch freien USB Port nur noch die Tastatur angeschlossen werden kann, oder man muss einen USB-Hub für Tastatur und Maus verwenden, oder man muss eine Funk Maus und Funk Tastatur anschließen (z.B. X1800 von RAPOO), oder man benutzt einen VNC Client (z.B. RealVNC) um Bildschirm, Maus und Tastatur von einem anderen Rechner per Netzwerk zu nutzen.

Das Web Frontend wurde getestet auf gute Funktion mit folgenden Web Browsern:

Diese Dokumentation ist auch lokal auf dem Raspberry Pi aufrufbar unter http://localhost:8080.

attachment:vz_EMH_eHZ_Lesekopf_DSC05266.jpg

Stromzähler EMH eHZ

Es gibt leider verschiedene intelligente Stromzähler. Hier wird jetzt die Benutzung des Stromzählers EHM eHZ beschrieben, siehe Bild rechts (Maus Klick auf das Bild zum vergrößern).

Rechts oben auf dem Stromzähler ist der Infrarot Lesekopf mit Ringmagnet aufgesetzt. Er haftet durch den Magneten am Zähler. Das Kabel geht zum USB Anschluss des Raspberry Pi. Dabei wird eine serielle Schnittstelle emuliert (Device /dev/ttyUSB0).

Computer Raspberry Pi

Am Besten gewöhnt man sich gleich an die Kommandozeile im Terminal, per SSH-Netzwerk Verbindung zum Raspberry Pi. Als Hilfestellung für den Raspberry Pi gibt es die HowTo Seite

$ ssh pi@192.168.17.187  # eigene IP-Nummer verwenden
Password: raspberry  # oder eigenes Passwort

attachment:vz_RaspberryPi_DSC05267.jpg

$ sudo raspi-config
# Die volle SD-Karte nutzen:
1. Expand Filesystem

4. Internationalisation Options
   I1 Change Locale
      In der Liste herunterscrollen, bis de_DE.UTF-8 UTF-8, dann mit Leertaste eine Stern setzen (markieren)
      Mit TAB auf "OK" springen, ENTER
      Abfrage: Default locale for the system environment: de_DE.UTF-8
      Mit TAB auf "OK" springen, ENTER
   I2 Change Timezone
      Geographic area: Europe, Berlin auswählen (ENTER)
   I3 Change Keyboard Layout
   
Mit TAB auf "finish" ENTER   

$ sudo apt-get update

$ sudo apt-get dist-upgrade
y

Dienstprogramme, zusätzlich

Zusätzlich zu den bereits installierten Dienstprogrammen (Utilities) erleichtert es die Einrichtung und Fehlersuche, wenn man folgende Dienstprogramme zusätzlich installiert:

# Installation per Internet Anschluss
$ sudo apt-get install mc minicom nmap

Benutzung der Programme im Terminal (Kommandozeile):

# Um den eingebauten Editor zu nutzen muss man einstellen:
# Menü Optionen/Konfiguration/Weitere Optionen/Eingebauten Editor verwenden:
  Mit Zwischenraum Taste ein "x" setzen, mit "TAB" auf <OK> gehen, und "ENTER" drücken.

# zuerst Konfiguration einrichten:
$ sudo minicom -s
# mit den Cursor Tasten und "ENTER" auswählen:
Einstellungen zum seriellen Anschluss

Welchen Parameter möchten Sie ändern?
A - Serieller Anschluss: /dev/modem -> /dev/ttyUSB0 ENTER

E - Bps/Par/Bits: 
  Welche Einstellung? (<Enter> zum verlassen)
  C: 9600
  F - Hardware Flow Control: Ja -> Nein
  ENTER

Speichern als "dfl" (default = Voreinstellung) ENTER
Minicom beenden ENTER

$ nmap localhost

Starting Nmap 6.00 ( http://nmap.org ) at 2014-04-22 08:06 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0061s latency).
Other addresses for localhost (not scanned): 127.0.0.1
Not shown: 992 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
139/tcp  open  netbios-ssn
445/tcp  open  microsoft-ds
3306/tcp open  mysql
5901/tcp open  vnc-1
6001/tcp open  X11:1
8080/tcp open  http-proxy

Mit diesem Programm kann man unter anderem prüfen, welche TCP Ports geöffnet sind, das heißt, ob ein Dienst (Server) auf diesem Port angesprochen werden kann.

In unserem Fall sind das im besonderen:

Wenn dieser Raspberry Pi mit TCP Port Freigaben, z.B. Port 22 (SSH, Fernzugriff auf den Rechner), über einen Router am Internet angeschlossen wird, sollte man ihn absichern, zum Beispiel mit dem Programm fail2ban, um einen Missbrauch des Rechners zu verhindern.

USB-IR Schreib-Lesekopf

Der Stromzähler EMH-eHZ hat eine Infrarot Schnittstelle mit der Übertragungsgeschwindigkeit 9600 Baud 8N1 (8 Datenbits, No parity, 1 Stopbit). Damit das beim Kaltstart des Raspberry Pi immer eingestellt wird, kommt in die Datei /etc/rc.local die Zeile:

stty -F /dev/ttyUSB0 9600 -parity -cstopb

# -parity = kein Paritätsbit
# -cstopb = kein Stopbit

Der Schreib-Lesekopf von Udo wird mit seinem Magneten auf die Metallplatte rechts oben am Zähler angeheftet. Das Kabel sollte nach unten zeigen. Der USB Stecker wird bei dem Raspberry Pi eingesteckt. Da der Raspberry Pi normal per SSH Netzwerk Verbindung angesprochen wird, ist dann noch eine USB Buchse frei.

Normalerweise wird die serielle Schnittstelle unter Linux mit dem Device-Namen /dev/ttyUSB0 angemeldet. Wenn man aber den USB Stecker im laufenden Betrieb zieht und steckt, bekommt die Schnittstelle den Namen /dev/ttyUSB1. Dann funktioniert die Datenerfassung nicht mehr. Besser ist es, über eine udev Regel einen eindeutigen Namen zu vergeben (/dev/lesekopf0), zum einrichten siehe bei Linux support.

Hier ein praktisches Beispiel:

# zeige die Attribute
$ /sbin/udevadm info -a -n /dev/ttyUSB0
...
looking at parent device '/devices/platform/bcm2708_usb/usb1/1-1/1-1.3':
    KERNELS=="1-1.3"
    SUBSYSTEMS=="usb"
...
    ATTRS{serial}=="00799BD5"
    ATTRS{product}=="CP2104 USB to UART Bridge Controller"
...

# Edit new file /etc/udev/rules.d/99-lesekopf.rules
$ cat /etc/udev/rules.d/99-lesekopf.rules
SUBSYSTEMS=="usb", ATTRS{product}=="CP2104 USB to UART Bridge Controller", ATTRS{serial}=="00799BD5", NAME="lesekopf0", GROUP="dialout", MODE="0666"

# generate new device name "lesekopf0"
$ sudo udevadm trigger

# test device name
$ ls /dev/le*
/dev/lesekopf0

Der Nachteil davon ist aber, dass bei einem Wechsel von dem Lesekopf, das Device nicht mehr erkannt ist, weil die Seriennummer sich geändert hat. Man könnte auch nur den product string zur Erkennung benutzen, wenn dann aber ein gleicher CP2104 USB to UART Bridge Controller eingesteckt wird, funktioniert das Prinzip nicht mehr.

Software einrichten

Die Daten nehmen folgenden Weg:

Fehlersuche:

$ xxd </dev/ttyUSB0
0000000: 011b 1b1b 1b01 0101 0176 0700 1e00 03d2  .........v......
0000010: 2d62 0062 0072 6301 0176 0101 0700 1e00  -b.b.rc..v......
0000020: 6e46 0f0b 0645 4d48 0104 c569 6e92 0101  nF...EMH...in...
0000030: 6397 5200 7607 001e 0003 d22e 6200 6200  c.R.v.......b.b.
0000040: 7263 0701 7701 0b06 454d 4801 04c5 696e  rc..w...EMH...in
0000050: 9207 0100 620a ffff 7262 0165 006e 5ce6  ....b...rb.e.n\.
0000060: 7777 0781 81c7 8203 ff01 0101 0104 454d  ww............EM
0000070: 4801 7707 0100 0000 09ff 0101 0101 0b06  H.w.............
0000080: 454d 4801 04c5 696e 9201 7707 0100 0108  EMH...in..w.....
0000090: 00ff 6400 0182 0162 1e52 ff56 0000 53fe  ..d....b.R.V..S.
00000a0: ad01 7707 0100 0108 01ff 0101 621e 52ff  ..w.........b.R.
00000b0: 5600 0053 fe75 0177 0701 0001 0802 ff01  V..S.u.w........
00000c0: 0162 1e52 ff56 0000 0000 3801 7707 0100  .b.R.V....8.w...
00000d0: 1007 00ff 0101 621b 52ff 5500 0003 7101  ......b.R.U...q.
00000e0: 7707 8181 c782 05ff 0172 6201 6500 6e5c  w........rb.e.n\
00000f0: e701 0183 02e2 9cb7 1ba0 c8fa 2d18 72f2  ............-.r.
0000100: d386 22aa 51af aaaa 2c74 df50 3cea c440  ..".Q...,t.P<..@
0000110: 241a 92c8 8b10 f428 e001 f80d 46c3 f84b  $......(....F..K
0000120: a426 f07e ab01 0101 6324 6e00 7607 001e  .&.~....c$n.v...
0000130: 0003 d231 6200 6200 7263 0201 7101 6367  ...1b.b.rc..q.cg

# mit Zeichen "strg C" abbrechen

$ stty -a -F /dev/ttyUSB0
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S;
susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

# Wichtig ist: speed 9600 baud, cread, -crtscts, cs8, -cstopb, -parenb, -ixon, -echo

# Hilfe Information mit:
$ man stty

Die Daten mit der Beschreibung vergleichen.

$ ps -Af | grep vzlogger
root      6930     1  0 Apr09 ?        00:32:28 /usr/bin/vzlogger -d

# wenn nichts zu sehen ist, prozess im Vordergrund starten:
$ sudo /etc/init.d/vzlogger start
[Mar 31 09:40:18][mtr0] Creating new meter with protocol sml.
[Mar 31 09:40:18][mtr0] Meter configured. enabled
[Mar 31 09:40:18]       New meter initialized (protocol=sml)
[Mar 31 09:40:18]       Configure channel.
[Mar 31 09:40:18][chn0] New channel initialized (uuid=...fc41c6 protocol=volkszaehler id=1-0:1.8.0)
[Mar 31 09:40:18]       Have 1 meters.
[Mar 31 09:40:18][main] foreground=0, daemon=1, local=1
[Mar 31 09:40:18]       Daemonize process...

# prüfe log Daten (/etc/vzlogger.conf, "verbosity" : 15,):
$ cat /var/log/vzlogger.log | tail
[Mar 31 09:04:32][chn0] CURL: Connection #0 to host localhost left intact
[Mar 31 09:04:32][chn0] CURL Request succeeded with code: 200
[Mar 31 09:04:35]       terminating on signal 2.
[Mar 31 09:04:35]       Closing connections to terminate
# Warum "terminating on signal 2"?

$ vzlogger -f
[Mar 31 09:04:29][mtr0] Creating new meter with protocol sml.
[Mar 31 09:04:29][mtr0] Meter configured. enabled
[Mar 31 09:04:29]       New meter initialized (protocol=sml)
[Mar 31 09:04:29]       Configure channel.
[Mar 31 09:04:29][chn0] New channel initialized (uuid=...fc41c6 protocol=volkszaehler id=1-0:1.8.0)
[Mar 31 09:04:29]       Have 1 meters.
[Mar 31 09:04:29][main] foreground=1, daemon=1, local=1
[Mar 31 09:04:29]       NOT Daemonize process...
[Mar 31 09:04:29]       Opened logfile /var/log/vzlogger.log
[Mar 31 09:04:29][]     ===> Start meters.
[Mar 31 09:04:29][mtr0] Meter connection established
[Mar 31 09:04:29][mtr0] Meter thread started
[Mar 31 09:04:29][mtr0] meter is opened. Start channels.
[Mar 31 09:04:29][chn0] Logging thread started
[Mar 31 09:04:29][]     Startup done.
[Mar 31 09:04:29][mtr0] Number of readers: 32
[Mar 31 09:04:29][mtr0] Config.daemon: 1
[Mar 31 09:04:29][mtr0] Config.local: 1
[Mar 31 09:04:29][chn0] Start logging thread for volkszaehler-api. Running as daemon: yes
[Mar 31 09:04:29][chn0] Using default api:
error: unknown type in sml_value_to_double
error: unknown type in sml_value_to_double
error: unknown type in sml_value_to_double
[Mar 31 09:04:32][mtr0] Got 8 new readings from meter:
[Mar 31 09:04:32][mtr0] Reading: id=129-129:199.130.3*255/ObisItentifier:129-129:199.130.3*255 value=0.00 ts=1396249472.625
[Mar 31 09:04:32][mtr0] Reading: id=1-0:0.0.9*255/ObisItentifier:1-0:0.0.9*255 value=0.00 ts=1396249472.625
[Mar 31 09:04:32][mtr0] Reading: id=1-0:1.8.0*255/ObisItentifier:1-0:1.8.0*255 value=550504.60 ts=1396249472.625
[Mar 31 09:04:32][mtr0] Reading: id=1-0:1.8.1*255/ObisItentifier:1-0:1.8.1*255 value=550499.00 ts=1396249472.625
[Mar 31 09:04:32][mtr0] Reading: id=1-0:1.8.2*255/ObisItentifier:1-0:1.8.2*255 value=5.60 ts=1396249472.625
[Mar 31 09:04:32][mtr0] Reading: id=1-0:16.7.0*255/ObisItentifier:1-0:16.7.0*255 value=86.00 ts=1396249472.625
[Mar 31 09:04:32][mtr0] Reading: id=129-129:199.130.5*255/ObisItentifier:129-129:199.130.5*255 value=0.00 ts=7234184.000
[Mar 31 09:04:32][mtr0] Reading: id=0-0:0.0.0*0/ObisItentifier:0-0:0.0.0*0 value=0.00 ts=0.000
[Mar 31 09:04:32][chn0] Adding reading to queue (value=550504.60 ts=1396249472.625)
[Mar 31 09:04:32][chn0] ==> number of tuples: 1
[Mar 31 09:04:32][chn0] compare: 0 1396249472625 1396249472625.282959
[Mar 31 09:04:32][chn0] JSON request body: [ [ 1396249472625.282959, 550504.600000 ] ]
[Mar 31 09:04:32][chn0] Buffer dump (size=0 keep=5): {}
[Mar 31 09:04:32][mtr0] Next reading in 120 seconds
[Mar 31 09:04:32][chn0] CURL: About to connect() to localhost port 80 (#0)
[Mar 31 09:04:32][chn0] CURL:   Trying 127.0.0.1...
[Mar 31 09:04:32][chn0] CURL: connected
[Mar 31 09:04:32][chn0] CURL: Connected to localhost (127.0.0.1) port 80 (#0)
[Mar 31 09:04:32][chn0] CURL: Sent 43 bytes..
[Mar 31 09:04:32][chn0] CURL: Sent '[ [ 1396249472625.282959, 550504.600000 ] ]' bytes
[Mar 31 09:04:32][chn0] CURL: upload completely sent off: 43 out of 43 bytes
[Mar 31 09:04:32][chn0] CURL: additional stuff not fine transfer.c:1037: 0 0
[Mar 31 09:04:32][chn0] CURL: HTTP 1.1 or later with persistent connection, pipelining supported
[Mar 31 09:04:32][chn0] CURL: Received 28 bytes
[Mar 31 09:04:32][chn0] CURL: Received '11
{"version":"0.3"}
0

' bytes
[Mar 31 09:04:32][chn0] CURL: Connection #0 to host localhost left intact
[Mar 31 09:04:32][chn0] CURL Request succeeded with code: 200
^C[Mar 31 09:04:35]       terminating on signal 2.
[Mar 31 09:04:35]       Closing connections to terminate
*** glibc detected *** vzlogger: free(): corrupted unsorted chunks: 0x01e83038 ***

# Taste "strg C" zum beenden drücken
Abgebrochen

attachment:volkszaehler_phpmyadmin_data.png

Anwendung Volkszaehler

Mit dem Web Browser (z.B. Firefox) auf die IP Adresse des Raspberry Pi gehen, z.B. http://www.192.168.17.187.

attachment:volkszaehler_PC_24h_910.png

Im Diagramm oben sieht man verschiedene Leistung Niveaus, in Addition:

vzlogger

vzlogger ist das Datenerfassung Programm. Die Aktivität wird über den Konfigurationsfile /etc/vzlogger.conf gesteuert. In diesem Fall werden die Daten von der USB Schnittstelle gelesen und in die Datenbank geschrieben.

Zuerst wird die serielle Schnittstelle konfiguriert, das dann immer beim Start des Rechners ausgeführt wird.

# Datei /etc/rc.local mit "sudo" editieren, mit "nano" oder "mc"
# VOR dem Befehl "exit 0" einfügen:
stty -F /dev/ttyUSB0 9600 -parity -cstopb

# abspeichern, und manuell konfigurieren:
$ stty -F /dev/ttyUSB0 9600 -parity -cstopb

Die Konfiguration von dem Datenerfassungsprogramm sieht so aus:

$ cat /etc/vzlogger.conf
/**
 * vzlogger configuration
 * use proper encoded JSON with javascript comments
 * take a look at the wiki for detailed information:
 * http://wiki.volkszaehler.org/software/controller/vzlogger#configuration
 */

{
"retry" : 30,           /* how long to sleep between failed requests, in seconds */
"daemon": true,         /* run periodically */
//"foreground" : true,  /* dont run in background (prevents forking) */
"verbosity" : 1,        /* between 0 and 15 */
"log" : "/var/log/vzlogger.log", /* path to logfile, optional */

"local" : {
//      "enabled" : false,      /* should we start the local HTTPd for serving live readings? */
        "port" : 8080,          /* the TCP port for the local HTTPd */
        "index" : true,         /* should we provide a index listing of available channels if no UUID was requested? */
        "timeout" : 30,         /* timeout for long polling comet requests, 0 disables comet, in seconds */
        "buffer" : 600          /* how long to buffer readings for the local interface, in seconds */
},

"meters" : [{
        "enabled" : true,
        "protocol" : "sml",
        "device" : "/dev/ttyUSB0",  // baudrate: 9600, parity: 8N1  Documentation
        //"interval" : 180,  /* alternative to aggrgate */
        "aggtime" : 180, /* aggregate all signals and give one update to middleware every 'aggtime' seconds */
        "aggfixedinterval" : true, /* round all timestamps to middleware to nearest aggtime */
        "channel" : {
                "uuid" : "c0afc3e0-b811-11e3-a56c-1bfcfdfc41c6",
                "middleware" : "http://localhost/middleware.php",
                "identifier" : "1-0:1.8.0", /* Wirkleistung */
                "aggmode" : "MAX" /* add all s0 intervals in the aggregation. Possible Modes: SUM, AVG, MAXIMUM and NONE*/
                } // channel
        }] // meters
} // end of config

Um den vzlogger zu testen, ist es sinnvoll, ihn im Vordergrund aufzurufen:

$ vzlogger -f

vzlogger Parameter

Da der nützliche Parameter aggregate leider im Wiki nicht so ausführlich dokumentiert ist, folgend eine Info von Hansi:

Nach einer Parameter Änderung im File /etc/vzlogger.conf muss das Programm vzlogger neu gestartet werden:

$ sudo service vzlogger restart
[....] Restarting smartmetering server: vzlogger
. ok

vzlogger debuggen

Leider wird das Program vzlogger beim Kaltstart vom Raspberry Pi nicht im Hintergrund gestartet, obwohl es so aussieht.

$ sudo sh -x /etc/init.d/vzlogger start
+ PATH=/sbin:/usr/sbin:/bin:/usr/bin
+ DESC=smartmetering server
+ NAME=vzlogger
+ DAEMON=/usr/bin/vzlogger
+ DAEMON_ARGS=-d
+ PIDFILE=/var/run/vzlogger.pid
+ SCRIPTNAME=/etc/init.d/vzlogger
+ USER=vzlogger
+ GROUP=vzlogger
+ [ -x /usr/bin/vzlogger ]
+ [ -r /etc/default/vzlogger ]
+ . /lib/init/vars.sh
+ TMPTIME=0
+ SULOGIN=no
+ DELAYLOGIN=no
+ UTC=yes
+ VERBOSE=no
+ FSCKFIX=no
+ [ -f /etc/default/rcS ]
+ . /etc/default/rcS
+ unset EDITMOTD
+ unset RAMRUN
+ unset RAMLOCK
+ [ -r /proc/cmdline ]
+ cat /proc/cmdline
+ [  ]
+ . /lib/lsb/init-functions
+ run-parts --lsbsysinit --list /lib/lsb/init-functions.d
+ [ -r /lib/lsb/init-functions.d/20-left-info-blocks ]
+ . /lib/lsb/init-functions.d/20-left-info-blocks
+ FANCYTTY=
+ [ -e /etc/lsb-base-logging.sh ]
+ true
+ [ no != no ]
+ do_start
+ start-stop-daemon --start --chuid vzlogger --group vzlogger --quiet --pidfile /var/run/vzlogger.pid --exec /usr/bin/vzlogger --test
+ start-stop-daemon --start --chuid vzlogger --group vzlogger --quiet --pidfile /var/run/vzlogger.pid --exec /usr/bin/vzlogger -- -d
[Apr 01 18:02:50][mtr0] Creating new meter with protocol sml.
[Apr 01 18:02:50][mtr0] Meter configured. enabled
[Apr 01 18:02:50]       New meter initialized (protocol=sml)
[Apr 01 18:02:50]       Configure channel.
[Apr 01 18:02:50][chn0] New channel initialized (uuid=...fc41c6 protocol=volkszaehler id=1-0:1.8.0)
[Apr 01 18:02:50]       Have 1 meters.
[Apr 01 18:02:50][main] foreground=0, daemon=1, local=1
[Apr 01 18:02:50]       Daemonize process...
+ [ no != no ]
+ :
pi@raspberrypi ~ $ ps -A | grep vzlogger
# kein laufender Prozess vzlogger
# kein file /var/run/vzlogger.pid
# kein file /var/log/vzlogger.log

Es fällt mir auf, dass USER und GROUP auf vzlogger gesetzt werden.

Wenn man die GROUP auf root setzt, ändert sich nichts. Erst wenn auch der USER auf root gesetzt wird, läuft der vzlogger als daemon im Hintergrund.

Im Zweifelsfall kann man das Programm vzlogger neu starten:

# Stop
$ sudo killall vzlogger

# Lösche den Logfile
$ sudo rm /var/log/vzlogger.log  

# Starte vzlogger neu:
$ sudo vzlogger 

WLAN

Der Raspberry Pi kann auch mit WLAN betrieben werden. Das ist ausführlich hier beschrieben.

Am einfachsten funktioniert es mit dem Edimax: EDIMAX EW-7811UN Wireless USB Adapter, 150 Mbit/s, IEEE802.11b/g/n, der bei Amazon für circa 10 EUR zu haben ist.

Wenn man den Adapter beim Raspberry Pi einsteckt, sollte man folgende System Meldung sehen:

$ dmesg | tail
[    2.538109] usb 1-1.2: New USB device found, idVendor=7392, idProduct=7811
[    2.543058] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[    2.547901] usb 1-1.2: Product: 802.11n WLAN Adapter
[    2.552673] usb 1-1.2: Manufacturer: Realtek
[    2.557516] usb 1-1.2: SerialNumber: 00e04c000001
               usbcore: registered new interface driver rtl8192cu

$ lsmod | grep 8192
8192cu                550816  0

dann sollte man auch das neue Netzwerk Interface sehen:

$ ifconfig
...
wlan0     Link encap:Ethernet  Hardware Adresse 80:1f:02:82:2e:84
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metrik:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          Kollisionen:0 Sendewarteschlangenlänge:1000
          RX bytes:0 (0.0 KiB)  TX bytes:0 (0.0 KiB)

Die Stromsparfunktion des Edimax Treibers sollte ausgeschaltet werden. Andernfalls wird eine Verbindung bei Inaktivität unterbrochen. Dazu muss eine Konfigurationsdatei angelegt werden:

$ sudo nano /etc/modprobe.d/8192cu.conf
# Inhalt
options 8192cu rtw_power_mgnt=0 rtw_enusbss=0

# Rechner Neustart

In den Netzwerk Einstellungen muss von dem WLAN Router die SSID und das Passwort eingetragen werden:

$ sudo nano /etc/network/interfaces
auto lo

iface lo inet loopback
iface eth0 inet dhcp

auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-ap-scan 1
wpa-scan-ssid 1
# folgend zutreffende Werte eingeben
wpa-ssid <SSID>
wpa-psk <password>

Dann muss das Netzwerk neu gestartet werden:

$ sudo service networking restart
# oder
$ sudo reboot

Die IP Adresse findet man entweder über den WLAN Router, oder mit dem Terminal:

$ ifconfig
wlan0     Link encap:Ethernet  Hardware Adresse 80:1f:02:82:2e:84
          inet Adresse:192.168.17.184  Bcast:192.168.17.255  Maske:255.255.255.0
...

VNC Server

Virtual Network Computing (VNC) erlaubt es, den Bildschirminhalt eines entfernten Rechners (VNC Server) auf einem lokalen Rechner (VNC Client) anzuzeigen, und dazu Tastatur- und Mausbewegungen des lokalen Rechners an den entfernten Rechner zu senden. Damit kann man auf einem entfernten Rechner arbeiten, der keinen eigenen Bildschirm, Maus und Tastatur hat.

Zuerst muss man auf dem Raspberry Pi einen VNC Server installieren, am Besten den tightvncserver:

# zuerst das software Repository updaten
$ sudo apt-get update

$ sudo apt-get install tightvncserver

# start server
$ vncserver :1
You will require a password to access your desktops.

Password: raspberr     # max 8 Zeichen, z.B. raspberr
Verify:
Would you like to enter a view-only password (y/n)? n

New 'X' desktop is raspberrypi:1

Creating default startup script /home/pi/.vnc/xstartup
Starting applications specified in /home/pi/.vnc/xstartup
Log file is /home/pi/.vnc/raspberrypi:1.log

# VNC server beenden
$ vncserver -kill :1

Zum automatischen starten muss man einen Script aufsetzen, siehe bei den Links.

# Hole den script
$ wget http://www.penguintutor.com/otherfiles/tightvncserver-init.txt

# kopiere in den Start Ordner
$ sudo cp tightvncserver-init.txt /etc/init.d/tightvncserver

# Man muss den Benutzer Namen in Zeile 16 überprüfen und eventuell ändern. Zur Zeit ist "pi" eingetragen.
# Der Benutzer Name sollte aber aus Sicherheitsgründen nicht "root" sein.

# Benutzer für Start Script anpassen
$ sudo chown root:root /etc/init.d/tightvncserver

# Rechte für Start Script anpassen (execute)
$ sudo chmod 755 /etc/init.d/tightvncserver 

# Start Script in die "run level" eintragen
$ sudo update-rc.d tightvncserver defaults

# Manuell starten
$ sudo /etc/init.d/tightvncserver start

# Manuell stoppen
$ sudo /etc/init.d/tightvncserver stop

# Prüfe, ob der Prozess läuft
$ ps -Af | grep vnc
pi        5135     1  0 06:42 ?        00:00:05 Xtightvnc :1 -desktop X -auth /home/pi/.Xauthority -geometry 1024x768 -depth 24 -rfbwait 120000 -rfbauth /home/pi/.vnc/passwd -rfbport 5901 -fp /usr/share/fonts/X11/misc/,/usr/share/fonts/X11/Type1/,/usr/share/fonts/X11/75dpi/,/usr/share/fonts/X11/100dpi/ -co /etc/X11/rgb

Leider funktioniert die Zwischenablage (clipboard) damit nur in einer Richtung. Das kann aber mit dem Programm autocutsel auf dem Raspberry Pi behoben werden:

# Programm zum synchronisieren der Zwischenablage installieren
$ sudo apt-get install autocutsel

# zum automatischen Start beim Rechner Start
# edit /home/pi/.vnc/xstartup
# dritte Zeile einfügen:
autocutsel -fork
xrdb $HOME/.Xresources
...

# wenn der VNC Server bereits läuft, stoppen
$ sudo /etc/init.d/tightvncserver stop

# dann mit "autocutsel" wieder starten
$ sudo /etc/init.d/tightvncserver start

Jetzt kann man von einem VNC client viewer darauf zugreifen.

SD-card installieren

Zuerst das Volkszaehler Image von Rainer herunterladen, in den Ordner Download.

Am einfachsten ist die Installation eines fertigen Linux (Debian, Raspbian) auf der SD-card per Programm ApplePi-Baker (siehe bei den Links). Damit kann man auch den Inhalt der SD-card auf Festplatte sichern.

Es geht auch per Kommando Zeile im Terminal durchzuführen:

# in den Ordner Download wechseln
$ cd Download
# File Name zum Beispiel: 2014-03-29-raspbian-vz-05-3G.img.zip
# Archiv auspacken durch Doppelklick darauf.

# Leere SD-card mit FAT32 Filesystem in einen Leser einschieben.
# Disk Name feststellen
$ diskutil list
...
/dev/disk3
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *7.9 GB     disk3
   1:                 DOS_FAT_32 NO NAME                 7.9 GB     disk3s1
# An der Partitionsgröße (7.9 GB) und Name (NO NAME) kann man die SD-card erkennen.

# Partition (IDENTIFIER) unmount
$ diskutil unmount /dev/disk3s1

# Volkszaehler Image kopieren, anstatt /dev/disk3 -> /dev/rdisk3 verwenden (höhere Geschwindigkeit)
$ sudo dd if=2014-03-29-raspbian-vz-05-3G.img of=/dev/rdisk3 bs=1m
# Kopierzeit: circa 1 min. pro GB, bei class 10 SD-card

# SD-card auswerfen
$ diskutil eject /dev/rdisk3
Disk /dev/rdisk3 ejected
# SD-card aus dem Lesegerät nehmen.

Am besten zum installieren das Programm Win32DiskImager benutzen, download hier.

Wenn man mit der SD-card den Raspberry Pi gebootet hat, kann man noch ein Software upgrade machen:

# aktuelle Software Paketlisten holen.
$ sudo apt-get update

# Software upgrade auf den aktuellen Stand machen.
$ sudo apt-get upgrade

Webmaske, Export

Rechts oben in der Volkszaehler Webmaske ist ein Auswahlfeld mit dem Text Export.

# source: volkszaehler.org
# version: 0.3

# uuid: 0af2cbe0-9642-11e3-bf0b-274d1fdbb6da
# title: Aussen
# from: 1399345804044
# to: 1399433103944
# min: 1399347603862 => 8
# max: 1399386904275 => 22.6
# average: 16.601
# rows: 292
1399346103434;8.1;1
1399346403748;8.1;1
...

<volkszaehler version="0.3">
<data><uuid>0af2cbe0-9642-11e3-bf0b-274d1fdbb6da</uuid>
<from>1399345804044</from>
<to>1399433103944</to>
<min timestamp="1399347603862" value="8"/>
<max timestamp="1399386904275" value="22.6"/>
<average>16.601</average>
<rows>292</rows>
<tuples><tuple timestamp="1399346103434" value="8.1" count="1"/>
<tuple timestamp="1399346403748" value="8.1" count="1"/>
...

Diese Funktionen findet man in der Software unter volkszaehler.org/lib/volkszaehler/View.

Wenn man den Timestamp [ms] in Datum/Uhrzeit umrechnen will geht das mit einem Einzeiler:

$ date -d @$(echo "<Timestamp>/1000" | bc) +"%Y-%m-%d %H:%M:%S"

wobei man den Timestamp sinnvollerweise über die Zwischenablage einkopiert. Man kann dafür aber auch einen Shell Script aufsetzen:

$ cat ms2time.sh
#!/bin/sh
# convert unix ms time to date/time
# use: ms2time.sh <Timestamp>
date -d @$(echo "$1/1000" | bc) +"%Y-%m-%d %H:%M:%S"

# Beispiel:
$ ./ms2time.sh 1399346245967
2014-05-06 05:17:25

# umgekehrt von Datum/Uhrzeit zu Sekunden geht es so:
$ date -d "2014-05-06 05:17:25" +%s
1399346245
# um Millisekunden zu bekommen, hängt man noch "000" an.

attachment:vz_RaspberryPI_RAM_micron.jpg

Tipps

# "sudo" für administrative Rechte
$ sudo raspi-config

attachment:vz_read_strom.png

Stromzähler Wert auslesen

Um Monatswerte des Stromzählers zum Vergleich zu dokumentieren, ist es sinnvoll an jedem 1sten des Monats den absoluten Zählerwert zu notieren.

Um den absoluten Stromzähler Wert auszulesen, muss man die Datenbank abfragen. Damit das komfortabel über einen Web Browser gemacht werden kann, habe ich einen PHP Script entwickelt. Nach dem Aufruf im Web Browser erscheint eine Ausgabe, siehe Bild rechts. Ohne Auswahl von Monat und Jahr wird der Zähler Wert zum 1sten des aktuellen Monats angezeigt. Durch Auswahl von Monat und Jahr und anklicken des Knopfes submit wird der entsprechende Wert angezeigt.

Zum eigenen Gebrauch müssen noch die Datenbank Variablen angepasst werden: $username, $password, $channel_id.

Der File muss auf dem Web Server in den Volkszaehler Pfad im Ordner htdocs gespeichert werden.

Web Adresse im lokalen Netzwert: <IP-Adresse>/vz_read_strom.php

   1 <?php // program "vz_read_strom.php", 2014-05-09 RudolfReuter 
   2 // Version Zaehler EMH eHZ
   3 ?>
   4 <h3>Stromzaehler auslesen</h3>
   5 <?php
   6 if (isset($_GET['month']) && isset($_GET['year'])) {
   7     $month = $_GET['month'];
   8     $year = $_GET['year'];
   9 }
  10 else {
  11     $month = date("m");
  12     //echo "actual date \n";
  13     $year = date("Y");
  14 }
  15 ?>
  16 <form id="user_form" action="vz_read_strom.php" method="get">
  17     <fieldset>
  18         <select name="month">
  19             <option value="01">Januar</option>
  20             <option value="02">Februar</option>
  21             <option value="03">Maerz</option>
  22             <option value="04">April</option>
  23             <option value="05">Mai</option>
  24             <option value="06">Juni</option>
  25             <option value="07">Juli</option>
  26             <option value="08">August</option>
  27             <option value="09">September</option>
  28             <option value="10">Oktober</option>
  29             <option value="11">November</option>
  30             <option value="12">Dezember</option>
  31         </select>
  32         <select name="year">
  33             <option value="2014">2014</option>
  34             <option value="2015">2015</option>
  35             <option value="2016">2016</option>
  36             <option value="2017">2017</option>
  37             <option value="2018">2018</option>
  38             <option value="2019">2019</option>
  39             <option value="2020">2020</option>
  40             <option value="2021">2021</option>
  41             <option value="2022">2022</option>
  42             <option value="2023">2023</option>
  43         </select>
  44         <input type="submit" name="submit" value="submit">
  45     </fieldset>
  46 </form>
  47 <?php
  48     $str_from = "$year-$month-01 08:00:00";
  49     $date1 = new DateTime($str_from);
  50     //echo $date1->format('Y-m-d H:i:s') . "\n";
  51     $time_from = $date1->getTimestamp() * 1000;
  52     //echo $time_from . "\n";
  53 
  54     $str_to = "$year-$month-01 08:15:00";
  55     $date2 =  new DateTime($str_to);
  56     $time_to = $date2->getTimestamp() * 1000;
  57     //echo $time_to . "\n";
  58 
  59     $username="root";
  60     $password="raspberry";
  61     $channel_id="11";
  62     $str_sql = "SELECT value FROM data WHERE channel_id=$channel_id AND timestamp BETWEEN $time_from AND $time_to LIMIT 0, 1";
  63     //echo $str_sql . "\n";
  64     $db = mysql_connect('localhost', $username, $password);
  65     if (!$db) {
  66         die('Verbindung schlug fehl: ' . mysql_error());
  67     }
  68     $db_vz = mysql_select_db('volkszaehler', $db);
  69     $sql_res = mysql_query($str_sql);
  70     $row = mysql_fetch_assoc($sql_res);
  71     echo ($row["value"]/1000) . " KWh, ";
  72     echo "$year-$month-01 08:00 \n";
  73 ?>

Volkszaehler Update mit git

Es gibt zwar eine Web Seite HowTo git mit Erklärungen zur git Nutzung. Daraus ist aber schwierig abzuleiten, wie eine volkszaehler.org Installation ein Update bekommen kann. Ich dokumentiere jetzt mal meinen Weg (Server: Ubuntu 12.04):

$ cd /var/www
# Datensicherung
$ sudo mv volkszaehler.org vz.org.bak

# Wenn mit git installiert wurde:

# Test auf Aktualität
$ cd /var/www/volkszaehler.org
$ git status
nothing added to commit

# Update von volkszaehler.org machen
$ cd /var/www/volkszaehler.org
$ sudo git pull
Already up-to-date.

# Falls es ein Problem mit der neuen Version gibt, Rückkehr zur letzten Version:
$ sudo git checkout HEAD~1  # ACHTUNG: HEAD Schlangelinie 1

* Neue Installation, wenn nicht mit git installiert wurde:

$ sudo git clone git://github.com/volkszaehler/volkszaehler.org.git /var/www/volkszaehler.org

# Ergänzung mit Konfiguration und Hilfsprogrammen
$ cd /var/www/vz.org.bak/etc/
$ sudo cp volkszaehler.conf.php ../../volkszaehler.org/etc/
$ cd ..
$ sudo cp -R vendor ../volkszaehler.org/
# Korrektur der Rechte
$ sudo chown -R www-data /var/www/volkszaehler.org

$ sudo composer install

List of pages in this category:

-- RudolfReuter 2014-03-30 08:11:15


Go back to CategoryVolkszaehler or Startseite

VolkszaehlerEMHeHZ (last edited 2014-07-21 06:34:53 by RudolfReuter)