Der IR-Schreib-Lesekopf wird oben rechts am Zähler, mit dem Kabel nach unten, angebracht.
Schnittstellenparameter und Daten sind mit dem EMH eHz identisch.
Prinzipiell ist es möglich verschiedene Werte am Display ausgeben zu lassen. Dies wird erst möglich, wenn Sie durch die Eingabe der PIN, welche Sie durch Ihren Energieversorgen erhalten haben, möglich. Danach stehen Ihnen außer den Grundanzeigen wie z.B. Zählerstände zu einzelenen Tarifen, auch Leistung und Verbräuche aus den letzten 24 h, 7,30 und 365 Tagen zur Verfügung.
Aktivieren können Sie das Menü des Zählers mit einer handelsüblichen TASCHENLAMPE. Mit dieser wird einfach der „Lichtsensor“ am EDL21 eHZ angeleuchtet.
Eine exemplarische vzlogger.conf:
{ "retry" : 3, "verbosity" : 0, "log" : "/var/log/vzlogger/vzlogger.log", "local" : { "enabled" : false, "port" : 8081, "index" : true, "timeout" : 30, "buffer" : 600 }, "meters" : [{ "protocol" : "sml", "enabled" : true, "device" : "/dev/ttyUSB0", "parity" : "8N1", "baudrate" : 9600, "aggtime" : -1, "aggfixedinterval" : true, "channels": [{ "uuid" : "6836dd20-00d5-11e0-bab1-856ed5f959ae", "middleware" : "http://localhost/middleware.php", "identifier" : "1-0:1.8.0", "aggmode" : "MAX" }] } ]}
Die Daten aus einer „vzlogger.log“ von einem Zweirichtungszähler:
[mtr0] Got 10 new readings from meter: [mtr0] Reading: id=129-129:199.130.3*255 value=0.00 ts=1332150460.171 [mtr0] Reading: id=1-0:0.0.9*255 value=0.00 ts=1332150460.171 [mtr0] Reading: id=1-0:1.8.0*255 value=1288046.90 ts=1332150460.171 [mtr0] Reading: id=1-0:2.8.0*255 value=2423148.00 ts=1332150460.171 [mtr0] Reading: id=1-0:1.8.1*255 value=957322.20 ts=1332150460.171 [mtr0] Reading: id=1-0:2.8.1*255 value=2423148.00 ts=1332150460.171 [mtr0] Reading: id=1-0:1.8.2*255 value=330724.70 ts=1332150460.171 [mtr0] Reading: id=1-0:15.7.0*255 value=708.30 ts=1332150460.171 [mtr0] Reading: id=1-0:15.7.0*255 value=708.30 ts=1332150460.171 [mtr0] Reading: id=129-129:199.130.5*255 value=0.00 ts=1332150460.171 [mtr0] Reading: id=0-0:0.0.0*0 value=0.00 ts=0.000
Wie Ihr seht kommen 10 IDs an.
Hier ein Auszug aus der „vzlogger.log“ eines Einrichtungszähler (Einspeisung):
[mtr1] Got 7 new readings from meter: [mtr1] Reading: id=129-129:199.130.3*255 value=0.00 ts=1332150462.601 [mtr1] Reading: id=1-0:0.0.9*255 value=0.00 ts=1332150462.601 [mtr1] Reading: id=1-0:2.8.0*255 value=3093725.50 ts=1332150462.601 [mtr1] Reading: id=1-0:2.8.1*255 value=3093725.50 ts=1332150462.601 [mtr1] Reading: id=1-0:15.7.0*255 value=908.60 ts=1332150462.601 [mtr1] Reading: id=129-129:199.130.5*255 value=0.00 ts=1332150462.601 [mtr1] Reading: id=0-0:0.0.0*0 value=0.00 ts=0.000
Die Rohdaten wurden mit dem Tool „Hterm“ gemessen um dabei die SML Botschaft zu überprüfen. Dabei wird sichtbar, dass der Aufbau der SML Botschaft der Spezifikation der SML entspricht. beispiel_3emh_ehz_fw8e2a50bak2
Beginnend mit dem Start „1B 1B 1B 1B“ und Ende „1B 1B 1B 1B“.
1B 1B 1B 1B 01 01 01 01 76 07 00 09 03 7B 4F 6F 62 00 62 00 72 63 01 01 76 01 01 07 00 09 01 37 1A 7C 0B 06 45 4D 48 01 02 71 54 2B 20 01 01 63 C0 61 00 76 07 00 09 03 7B 4F 70 62 00 62 00 72 63 07 01 77 01 0B 06 45 4D 48 01 02 71 54 2B 20 01 72 62 01 65 01 37 46 19 79 77 07 81 81 C7 82 03 FF 01 01 01 01 04 45 4D 48 01 77 07 01 00 00 00 09 FF 01 01 01 01 0B 06 45 4D 48 01 02 71 54 2B 20 01 77 07 01 00 01 08 00 FF 63 01 82 01 62 1E 52 FF 56 00 00 B9 5A 9D 01 77 07 01 00 02 08 00 FF 63 01 82 01 62 1E 52 FF 56 00 01 58 45 D2 01 77 07 01 00 01 08 01 FF 01 01 62 1E 52 FF 56 00 00 8A 90 CD 01 77 07 01 00 02 08 01 FF 01 01 62 1E 52 FF 56 00 01 58 45 D2 01 77 07 01 00 01 08 02 FF 01 01 62 1E 52 FF 56 00 00 2E C9 D0 01 77 07 01 00 0F 07 00 FF 01 01 62 1B 52 FF 55 00 00 08 41 01 77 07 81 81 C7 82 05 FF 01 01 01 01 83 02 F6 77 BE E9 2A 25 71 60 40 FC A3 DB A7 62 C0 B3 90 35 96 2D 34 44 01 CF DC 44 E8 83 72 A8 16 16 34 13 D4 5E 5D 81 72 84 D8 D7 A5 0C 43 21 40 61 01 01 01 63 3B F9 00 76 07 00 09 03 7B 4F 71 62 00 62 00 72 63 02 01 71 01 63 E1 FF 00 00 1B 1B 1B 1B
Als Alternative für den zvlogger kann das folgene Per-Script verwendet werden:
Das Script habe ich unter /root/bin/getZaehler
abgespeichert.
Mit crontab -e können dann im Intervall die Daten ausgelesen werden und in der Datenbank gespeichert werden. Achtung: Leerzeile am Ende nicht vergessen. Das Script wird mit der folgenden Einstellung alle 1min ausgeführt.
# m h dom mon dow command */1 * * * * /root/bin/getZaehler >/dev/null 2>&1
Jetzt wird nur noch die Datei /var/log/auth.log
vollgeschrieben. Wie man dies umgehen kann steht auf http://crycode.de/linux/64-cron-spam-aus-auth-log-fernhalten.
In der Datei /etc/default/cron
sollte noch das Logging angepasst werden:
# For quick reference, the currently available log levels are: # 0 no logging (errors are logged regardless) # 1 log start of jobs # 2 log end of jobs # 4 log jobs with exit status != 0 # 8 log the process identifier of child process (in all logs) # EXTRA_OPTS="-L 0"
Einen Teil des Scripts stammt aus der Mailingliste http://volkszaehler.org/pipermail/volkszaehler-users/2012-September/000451.html
Die uuid müssen entsprechend den erstellten Kanälen durch das Webinterface geändert werden.
Es wird das perl-Paket für die serielle Schnittstelle benötigt:
„apt-get install libdevice-serialport-perl“
#!/usr/bin/perl # # Holt die Daten vom SML-Zaehler Easymeter Q3C # es wird die obere optische Schnittstelle ausgelesen # dort liefert der Zaehler alle 2sec. einen Datensatz # wird von CRON jede Minute aufgerufen # http://wiki.volkszaehler.org/software/sml # 03.2012 by NetFritz # 07.2013 by Ollir # ======================================== sub hexstr_to_signed32int { my ($hexstr) = @_; die "Invalid hex string: $hexstr" if $hexstr !~ /^[0-9A-Fa-f]/; #if $hexstr !~ /^[0-9A-Fa-f]{1,8}$/; my $num = hex($hexstr); return $num >> 31 ? $num - 2 ** 32 : $num; } # ======================================== # use Device::SerialPort; my $port = Device::SerialPort->new("/dev/ttyAMA0") || die $!; $port->databits(8); $port->baudrate(9600); $port->parity("none"); $port->stopbits(1); $port->handshake("none"); $port->write_settings; $port->purge_all(); $port->read_char_time(0); # don't wait for each character $port->read_const_time(1000); # 1 second per unfulfilled "read" call # # OBIS-Kennzahl und Anzahl der Zeichen von Anfang OBIS bis Messwert, # Messwertwertlaenge 8-10 Zeichen %channel = ( '56c94300-f188-11e2-aa85-eb712aefabf9' => ['070100010800FF',20,10], # 1-0:1.8.0 /* kWh aufgenommen */ 'dbc081e0-f188-11e2-8e30-3dd74b6c6043' => ['070100020800FF',20,10], # 1-0:2.8.0 /* kWh rueckgespeis*/ 'a301d8d0-903b-1234-94bb-d943d061b6a8' => ['070100100700FF',14,8] # 1-0:16.7.0 /* Wirkleistung aktuell */ ); # von der schnittstelle lesen for($i=0;$i<=5;$i++) { # wenn 540 chars gelesen werden wird mit last # abgebrochen, wenn nicht wird Schleife 2 mal widerholt my ($count,$saw)=$port->read(540); # will read 540 chars if ($count >300) { #print "read $count chars\n"; my $x=uc(unpack('H*',$saw)); # nach hex wandeln # print "$count <> $x\n"; # gibt die empfangenen Daten in Hex aus while (($uuid) = each(%channel)){ $key = $channel{$uuid}[0] ; $pos = $channel{$uuid}[1] ; $len = $channel{$uuid}[2] ; #print "uuid=$uuid , key=$key, pos=$pos, len=$len\n" ; # Stringpos raussuchen $pos1=index($x,$key); # grob rausschneiden $val1 = substr( $x , $pos1 , 50); #print $key . " = " . $val1 . "\n"; # Messwert selber $val2 = substr( $val1 , length($key) + $pos , $len); # Wert umwandeln $val3 = hexstr_to_signed32int($val2)/10; print $uuid . " : " . $val3 . "\n"; # Wert im Hash ablegen $channel{$uuid}[3] = $val3 ; } last; # while verlassen } else { #print "Schnittstellenlesefehler redu = $i ; count = $count <> \n"; } } # ======================================== # Daten per post an den Server senden # http://xmodulo.com/2013/05/how-to-send-http-get-or-post-request-in-perl.html # http://wiki.volkszaehler.org/development/api/reference # das geht: curl -d "" http://localhost/middleware.php/data/5ae94780-ecc7-11e2-91b8-33a3b9ebc717.json?value=24.9 use LWP::UserAgent; $timestamp = time() * 1000 ; # msec seit 1.1.1970 while (($uuid) = each(%channel)){ $val = $channel{$uuid}[3] ; print $uuid . " : " . $timestamp . " : " . $val . "\n"; my $server_endpoint = "http://localhost/middleware.php/data/${uuid}.json?value=" . $val; print "ss=" . $server_endpoint . "\n"; my $ua = LWP::UserAgent->new; # set custom HTTP request header fields my $req = HTTP::Request->new(POST => $server_endpoint); $req->header('content-type' => 'application/json'); $req->header('x-auth-token' => 'kfksj48sdfj4jd9d'); # add POST data to HTTP request body $req->content(" "); my $ua = LWP::UserAgent->new; my $resp = $ua->request($req); if ($resp->is_success) { my $message = $resp->decoded_content; print "Received reply: $message\n"; } else { print "HTTP GET error code: ", $resp->code, "\n"; print "HTTP GET error message: ", $resp->message, "\n"; } }