Hallo
-hat sich das Warten gelohnt?
Ich werde es rausfinden!
EMH-Zähler und VolksKopf vorhanden!
Grüße,
Lio
-hat sich das Warten gelohnt?
Ich werde es rausfinden!
EMH-Zähler und VolksKopf vorhanden!
Grüße,
Lio
print LOG ("\n",$year+1900,"-",$mon+1,"-",$mday," ",$hour,":",$min,":",$sec," ; ",$value);
print LOG $s;
#!/usr/bin/perl # Zählerabfrage für Zähler nach Protokoll IEC 62056-21 / OBIS # Ein Anfrage-Telegramm ist mit 300 Baud, 7 Bit, 1 Stoppbit # und gerader Paritaet zu senden. Das ist der Initialmodus von Geraeten, # die das Protokoll IEC 62056-21 implementieren. # Das Script ist angepasst auf EMH ITZ. Weitere Zaehler wie z.B. Elster AS1440, Siemens TD-3511 müssen # angepasst werden (Obis-Key). # !!! Wiederholung nur alle 3 Minuten da der Zähler nach Ende des Scriptes weiter sendet !!! # Basis des Scripts von volkszaehler.org / Autor: Andreas Schulze & Bugfix: Eric Schanze # DPT9 sub: makki / www.knx-user-forum.de # Erweiterung um RRD,KNX-Anbindung und gezielte Wertsuche auf Wiregate: JuMi2006 / www.knx-user-forum.de # Version: 0.1.2 # Datum: 15.04.2012 use warnings; use strict; use Device::SerialPort; use RRDs; ### KONFIGURATION ### my $device="/dev/ttyUSB-1-4"; #Schnittstelle my $request = "/?!\r\n"; #Anforderungstelegramm "/?!" \r\n entspricht CR-LF my $ga = "0/0/4"; #Gruppenadresse DPT9 my $obiskey="1.8.0("; #Schlüssel vor Anabe des Zählerstandes z.B. "1.8.0(0001234.5 kWh)" my $file = "/var/tmp/Zaehler.log"; #Logdatei wird automatisch angelegt! my $rrd_V24h = "/var/www/rrd/Verbrauch_24h.rrd"; #Verbrauch pro 24h my $rrd_V1h = "/var/www/rrd/Verbrauch_1h.rrd"; #Verbrauch pro 1h my $rrd_V15min = "/var/www/rrd/Verbrauch_15min.rrd"; #Verbrauch pro 15min ### ENDE KONFIGURATION ### ### RRD-Erstellen unless (-e $rrd_V24h) { RRDs::create ($rrd_V24h,"DS:value:COUNTER:86500:0:10000000000","RRA:AVERAGE:0.5:1:365","RRA:AVERAGE:0.5:7:300","-s 86400"); } unless (-e $rrd_V1h) { RRDs::create ($rrd_V1h,"DS:value:COUNTER:3650:0:10000000000","RRA:AVERAGE:0.5:1:2400","RRA:AVERAGE:0.5:24:300","-s 3600"); } unless (-e $rrd_V15min) { RRDs::create ($rrd_V15min,"DS:value:COUNTER:300:0:10000000000","RRA:AVERAGE:0.5:1:2400","RRA:AVERAGE:0.5:12:300"); } ### Seriellen Port initialisieren my $port = new Device::SerialPort($device) || die "can't open $device: $!"; $port->baudrate(300) || die 'fail setting baudrate'; $port->databits(7) || die 'fail setting databits'; $port->stopbits(1) || die 'fail setting stopbits'; $port->parity("even") || die 'fail setting parity'; $port->write_settings || die 'fail write settings'; $port->rts_active(1); $port->dtr_active(1); $port->read_char_time(500); # 0.5 seconds for each character $port->read_const_time(3000); # 3 second per unfulfilled "read" call ### Anforderungstelegramm senden my $num_out = $port->write($request); die "write failed\n" unless ($num_out); die "write inclomplete\n" unless ($num_out == length($request)); print "$num_out Bytes written\n"; ### AUSLESEN my $STALL_DEFAULT=5; # how many seconds to wait for new input my $timeout=$STALL_DEFAULT; my $chars=0; my $buffer=""; while ($timeout>0) { my ($count,$saw)=$port->read(255); # Liest 255 Zeichen je Durchlauf aus if ($count > 0) { $chars+=$count; $buffer.=$saw; print $buffer; # Ausgabe der eingelesenen Daten ### FILTER if ($buffer =~ /\Q$obiskey\E/) # \Q \E entwertet alle Sonderzeichen dazwischen { my $pos=index($buffer,$obiskey); # Anfangsposition des OBIS-Key finden #print ("Position: $pos","\n"); # Kontrolldruck der Anfangsposition my $value=substr($buffer,$pos+6,9); # Wert extrahieren (OBIS-Key=6 Zeichen lang,Wert=9 Zeichen lang) print ($value," kWh","\n"); # Kontrolldruck Zählerstand my $val1 = int(substr $value,0,7); ### separiert die ersten 7 Zahlen im String z.B. "0001234"->1234 my $val2 = int(substr $value,8); ### spariert die letzte Zahl im String (bei 9 Stellen) z.B. ".5"->5 print ("val1: ",$val1,"\n"); ### Zur Kontrolle in der Konsole print ("val2: ",$val2,"\n"); ### Zur Kontrolle in der Konsole ### Wert in DPT9 umwandeln und in Konsole ausgeben my @hexdec = encode_dpt9($value); my $hexval = sprintf("%x", $hexdec[0]) . " " . sprintf("%x", $hexdec[1]); print ($hexval,"\n"); ### Wert an Gruppenadresse und RRD senden system("groupwrite ip:localhost $ga $hexval"); #Zählerstand auf Bus my $valrrd_V24h = int($value*86400); # Verbrauch 24h my $valrrd_V1h = int($value*3600); # Verbrauch 1h my $valrrd_V15min = int($value*900); # Verbrauch 15 min RRDs::update("$rrd_V24h", "N:$valrrd_V24h"); RRDs::update("$rrd_V1h", "N:$valrrd_V1h"); RRDs::update("$rrd_V15min", "N:$valrrd_V15min"); ### Log der Zählerausgabe my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time); my $timestamp = printf "%4d-%02d-%02d %02d:%02d:%02d\n",$year+1900,$mon+1,$mday,$hour,$min,$sec; open(LOG,'>>',$file) || die "Fehler $!"; print LOG ("\n",$year+1900,"-",$mon+1,"-",$mday," ",$hour,":",$min,":",$sec," \; ",$value); close LOG; $port->close || die "can't close $device: $!"; # Port schließen last; # Schleife verlassen ### ENDE FILTER } } else { $timeout--; } } if ($timeout<=0) { $port->close || die "can't close $device: $!"; print "Waited $STALL_DEFAULT seconds and never saw what I wanted\n"; } ### SUBS sub encode_dpt9 { # 2byte signed float my $state = shift; my $data; my $sign = ($state <0 ? 0x8000 : 0); my $exp = 0; my $mant = 0; $mant = int($state * 100.0); while (abs($mant) > 2047) { $mant /= 2; $exp++; } $data = $sign | ($exp << 11) | ($mant & 0x07ff); return $data >> 8, $data & 0xff; }
Wir verarbeiten personenbezogene Daten über die Nutzer unserer Website mithilfe von Cookies und anderen Technologien, um unsere Dienste bereitzustellen. Weitere Informationen findest Du in unserer Datenschutzerklärung.
Indem Du unten auf "ICH stimme zu" klickst, stimmst Du unserer Datenschutzerklärung und unseren persönlichen Datenverarbeitungs- und Cookie-Praktiken zu, wie darin beschrieben. Du erkennst außerdem an, dass dieses Forum möglicherweise außerhalb Deines Landes gehostet wird und bist damit einverstanden, dass Deine Daten in dem Land, in dem dieses Forum gehostet wird, gesammelt, gespeichert und verarbeitet werden.
Kommentar