den Fehler hatte ich auch,
kam meistens wenn der reguläre Ausdruck nichts gefunden hat. Damit war $1 leer und dann ging er auf die Bretter. (Müsste man mal abfangen ;-) )
Lass Dir mal über Print die Variable ($sml_val) vor Anwendung des regulären Ausrucks anzeigen und dann $1. Dan kannst Du quasi von Hand schauen ob das passen würde - oder hier Posten.
Grüße
Gunnar
Ankündigung
Einklappen
Keine Ankündigung bisher.
Zählerabfrage als Wiregate Plugin
Einklappen
Dieses Thema ist geschlossen.
X
X
-
Häng mal noch das script mit an Deinen Post, damit man die Zeilen zuordnen kann.
Einen Kommentar schreiben:
-
da scheint was im code zu sein
Code:#!/usr/bin/perl use warnings; use strict; use Device::SerialPort; use feature "switch"; use EIBConnection; use RRDs; use Fcntl qw(:DEFAULT :flock); #0701000F0700FF = 7.0 FIXME !!! [0F]0700 #070100010801FF = 1.8.1 #070100010800FF = 1.8.1 # Lock setzen damit Skript nur einmal startet open *{0} or die "What!? $0:$!"; flock *{0}, LOCK_EX|LOCK_NB or die "$0 is already running somewhere!\n"; my $eib_url = "local:/tmp/eib"; #for local eibd "local:/tmp/eib" for eibd in LAN: "ip:192.168.2.220:6720" my $device = "/dev/usbserial-A601NKCL"; my $repeat = 20; # Wiederholung alle x Sekunden my $rrdpath = "/var/www/rrd"; my $debug = 1; my @obis; push @obis,{obis=>"1.8.0", fact=>10000, ga =>"14/7/51", dpt => 14, rrd_name => "Zaehler_Verbrauch", rrd => "c" }; #rrd: c=counter ; g=gauge push @obis,{obis=>"15.7.0", fact=>10, ga =>"14/7/50", dpt => 9 , rrd_name => "Zaehler_Leistung", rrd => "g" }; my @countermodes = (5,15,60,1440); #Aufloesungen fuer COUNTER RRDs in Minuten (1440 = Tagesverbrauch) my $port = Device::SerialPort->new($device) || die $!; $port->databits(8) || die "failed setting databits"; $port->baudrate(9600) || die "failed setting baudrate"; $port->parity("none") || die "failed setting parity"; $port->stopbits(1); $port->handshake("none"); $port->dtr_active(0); $port->purge_all(); $port->read_char_time(0); # don't wait for each character $port->read_const_time(4000); # 1 second per unfulfilled "read" call $port->write_settings || die "cannot write settings"; # Loop zum Datenempfang my $error=0; while ($error != 1) { my ($x,$data) = 0 ; my $sml = 0; my $start = 0; my $value = 0; my $dec_value = 0; my $count = 0; my $saw = 0; if ($debug == 1) {print "Step 1 - Daten holen \n";} while ($start < 2) # wait for second 1B1B1B1B01010101 { ($count,$saw)=$port->read(512); # will read 512 chars if ($count == 512) # wurden 512 chars gelesen ? { $x = uc(unpack('H*',$saw)); # nach hex wandeln $data .= $x; if ($data =~ /1B1B1B1B01010101/) {$start ++}; } # if } # while if ($debug==1) {print "Step 2 - Reg Exp 1 Datensatz zusammensetzen \n";} $data =~ m/1B1B1B1B01010101(.*?)B1B1B1/; $sml = $1; print "Zaehler Haushalt: \n"; if ($debug==1) {print "Step 3 - Datensatz auswerten \n";} foreach my $obiscnt (@obis) { # Umwandeln OBIS in HEx my $hc =""; foreach my $c (split(/\./,$obiscnt->{obis})) { $hc .= sprintf("%02X", $c); } my $obissearch = $hc; # FF fuer Suche an Hex-Wert anhaegne $obissearch .="FF"; if ($debug==1) { print $obissearch." Obis\n";} $sml =~ m/$obiscnt->{obis}(.*?)0177/; my $sml_val = $1; if ($debug==1) { print $1." contains hex \n";} #extract value $sml_val =~ s/^.*52FF//; $sml_val = substr($sml_val,2); if ($debug == 1) { print $sml_val." hex \n";} $value = $sml_val; $dec_value = sprintf("%d", hex($value)); $dec_value /= $obiscnt->{fact}; print $dec_value."<<<<---- Wert\n"; # RRD-Graphen erstellen - bei Bedarf wieder aktiv setzen #if ($obis->{rrd} eq "c") # { # &rrd_counter ($obis->{rrd_name},$dec_value) # } #if ($obis->{rrd} eq "g") # { # &rrd_gauge ($obis->{rrd_name},$dec_value) # } &knx_write ($obiscnt->{ga},$dec_value,$obiscnt->{dpt}); if ($debug == 1) {print "GA:".$obiscnt->{ga}." Wert:".$dec_value." DPT:".$obiscnt->{dpt}."\n";} } # foreach sleep $repeat; } # while $port->close() || warn "Serial port did not close proper!\n"; undef $port; ### SUBS ### sub rrd_counter { if ($debug==1){print ("COUNTER","\n")}; foreach (@countermodes) { my $obisname = $_[0]; if ($debug==1){print $obisname." obisname \n";} my $value = $_[1]; if ($debug==1){print $value." value \n";} my $rrdname = $obisname."_".$_."\.rrd"; if ($debug==1){print ($rrdname,"\n")}; my $rrdfile = $rrdpath."\/".$rrdname; unless (-e $rrdfile) { RRDs::create ($rrdfile,"DS:value:COUNTER:".(($_*60)+600).":0:10000000000","RRA:AVERAGE:0.5:1:365","RRA:AVERAGE:0.5:7:300","-s ".($_*60)); } my $countervalue = int($value*$_*60); RRDs::update("$rrdfile", "N:$countervalue"); } } sub rrd_gauge { if ($debug==1){print ("GAUGE","\n")}; my $obisname = $_[0]; if ($debug==1){print $obisname." obisname \n";} my $value = $_[1]; if ($debug==1){print $value." value \n";} my $rrdname = $obisname."\.rrd"; if ($debug==1){print ($rrdname,"\n")}; my $rrdfile = $rrdpath."\/".$rrdname; unless (-e $rrdfile) { RRDs::create ($rrdfile,"DS:value:GAUGE:900:0:10000000000","RRA:AVERAGE:0.5:1:2160","RRA:AVERAGE:0.5:5:2016","RRA:AVERAGE:0.5:15:2880","RRA:AVERAGE:0.5:60:8760"); } RRDs::update("$rrdfile", "N:$value"); } sub knx_write { my ($dst,$value,$dpt,$response,$dbgmsg) = @_; my $bytes; my $apci = ($response) ? 0x40 : 0x80; # 0x40=response, 0x80=write # DPT 1 (1 bit) = EIS 1/7 (move=DPT 1.8, step=DPT 1.7) # DPT 2 (1 bit controlled) = EIS 8 # DPT 3 (3 bit controlled) = EIS 2 # DPT 4 (Character) = EIS 13 # DPT 5 (8 bit unsigned value) = EIS 6 (DPT 5.1) oder EIS 14.001 (DPT 5.10) # DPT 6 (8 bit signed value) = EIS 14.000 # DPT 7 (2 byte unsigned value) = EIS 10.000 # DPT 8 (2 byte signed value) = EIS 10.001 # DPT 9 (2 byte float value) = EIS 5 # DPT 10 (Time) = EIS 3 # DPT 11 (Date) = EIS 4 # DPT 12 (4 byte unsigned value) = EIS 11.000 # DPT 13 (4 byte signed value) = EIS 11.001 # DPT 14 (4 byte float value) = EIS 9 # DPT 15 (Entrance access) = EIS 12 # DPT 16 (Character string) = EIS 15 # $dpt = $eibgaconf{$dst}{'DPTSubId'} unless $dpt; # read dpt from eibgaconf if existing given ($dpt) { when (/^12/) { $bytes = pack ("CCL>", 0, $apci, $value); } #EIS11.000/DPT12 (4 byte unsigned) when (/^13/) { $bytes = pack ("CCl>", 0, $apci, $value); } when (/^14/) { $bytes = pack ("CCf>", 0, $apci, $value); } when (/^16/) { $bytes = pack ("CCa14", 0, $apci, $value); } when (/^17/) { $bytes = pack ("CCC", 0, $apci, $value & 0x3F); } when (/^20/) { $bytes = pack ("CCC", 0, $apci, $value); } when (/^\d\d/) { return; } # other DPT XX 15 are unhandled when (/^[1,2,3]/) { $bytes = pack ("CC", 0, $apci | ($value & 0x3f)); } #send 6bit small when (/^4/) { $bytes = pack ("CCc", 0, $apci, ord($value)); } when ([5,5.001]) { $bytes = pack ("CCC", 0, $apci, encode_dpt5($value)); } #EIS 6/DPT5.001 1byte when ([5.004,5.005,5.010]) { $bytes = pack ("CCC", 0, $apci, $value); } when (/^5/) { $bytes = pack ("CCC", 0, $apci, $value); } when (/^6/) { $bytes = pack ("CCc", 0, $apci, $value); } when (/^7/) { $bytes = pack ("CCS>", 0, $apci, $value); } when (/^8/) { $bytes = pack ("CCs>", 0, $apci, $value); } when (/^9/) { $bytes = pack ("CCCC", 0, $apci, encode_dpt9($value)); } #EIS5/DPT9 2byte float default { LOGGER('WARN',"None or unsupported DPT: $dpt sent to $dst value $value"); return; } } my $leibcon = EIBConnection->EIBSocketURL($eib_url) or return("Error opening con: $!"); if ($leibcon->EIBOpenT_Group(str2addr($dst),1) == -1) { return("Error opening group: $!"); } my $res=$leibcon->EIBSendAPDU($bytes); $leibcon->EIBClose(); return $res; # str2addr: Convert an EIB address string in the form "1/2/3" or "1.2.3" to an integer sub str2addr { my $str = $_[0]; if ($str =~ /(\d+)\/(\d+)\/(\d+)/) { # logical address return ($1 << 11) | ($2 << 8) | $3; } elsif ($str =~ /(\d+)\.(\d+)\.(\d+)/) { # physical address return ($1 << 12) | ($2 << 8) | $3; } else { #bad return; } } } 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; }
Code:Step 1 - Daten holen Step 2 - Reg Exp 1 Datensatz zusammensetzen Zaehler Haushalt: Step 3 - Datensatz auswerten 010800FF Obis FF63018201621E52FF5600050D8E9C contains hex 00050D8E9C hex 8477.4556<<<<---- Wert GA:14/7/51 Wert:8477.4556 DPT:14 0F0700FF Obis Use of uninitialized value $1 in concatenation (.) or string at /home/user/smlMarch.pl line 105. contains hex Use of uninitialized value $sml_val in substitution (s///) at /home/user/smlMarch.pl line 108. Use of uninitialized value $sml_val in substr at /home/user/smlMarch.pl line 109. substr outside of string at /home/user/smlMarch.pl line 109. Use of uninitialized value $sml_val in concatenation (.) or string at /home/user/smlMarch.pl line 110. hex Use of uninitialized value $value in hex at /home/user/smlMarch.pl line 113. 0<<<<---- Wert GA:14/7/50 Wert:0 DPT:9
Einen Kommentar schreiben:
-
danke Mirko,
jetzt sagt er, dass das schon woanders running ist. Cronjob steht
Einen Kommentar schreiben:
-
benötige hilfe:
Putty läuft, debug=1.
Was muss ich nun auf der Konsole eingeben?
Dnke und Grüße,
Lio
Einen Kommentar schreiben:
-
jetzt funktioniert putty auf ein mak nimmer... hab die WinSCP- portable. Muss das auf morgen verschieben-mir brummt der Schädel.
Dann geb ich den Pfad und den Namen des Plugins ein und bekomme den Output angezeigt?
Danke und Grüße,
Lio
Einen Kommentar schreiben:
-
Einfach $debug = 1 setzen und in der Konsole aufrufen.
Einen Kommentar schreiben:
-
das hat nicht bewirkt. Da stand aber auch vorher schon
push @obis,{obis=>"7.0", fact=>10,
kann ich den Wert as einem Log auslesen?
Momentan kann ich das Ergebnis nur in der Comet sehen.
Code:#!/usr/bin/perl use warnings; use strict; use Device::SerialPort; use feature "switch"; use EIBConnection; use RRDs; use Fcntl qw(:DEFAULT :flock); #0701000F0700FF = 7.0 FIXME !!! [0F]0700 #070100010801FF = 1.8.1 #070100010800FF = 1.8.1 # Lock setzen damit Skript nur einmal startet open *{0} or die "What!? $0:$!"; flock *{0}, LOCK_EX|LOCK_NB or die "$0 is already running somewhere!\n"; my $eib_url = "local:/tmp/eib"; #for local eibd "local:/tmp/eib" for eibd in LAN: "ip:192.168.2.220:6720" my $device = "/dev/usbserial-A601NKCL"; my $repeat = 20; # Wiederholung alle x Sekunden my $rrdpath = "/var/www/rrd"; my $debug = 0; my @obis; push @obis,{obis=>"1.8.0", fact=>10000, ga =>"14/7/51", dpt => 14, rrd_name => "Zaehler_Verbrauch", rrd => "c" }; #rrd: c=counter ; g=gauge push @obis,{obis=>"15.7.0", fact=>10, ga =>"14/7/50", dpt => 9 , rrd_name => "Zaehler_Leistung", rrd => "g" }; my @countermodes = (5,15,60,1440); #Aufloesungen fuer COUNTER RRDs in Minuten (1440 = Tagesverbrauch) my $port = Device::SerialPort->new($device) || die $!; $port->databits(8) || die "failed setting databits"; $port->baudrate(9600) || die "failed setting baudrate"; $port->parity("none") || die "failed setting parity"; $port->stopbits(1); $port->handshake("none"); $port->dtr_active(0); $port->purge_all(); $port->read_char_time(0); # don't wait for each character $port->read_const_time(4000); # 1 second per unfulfilled "read" call $port->write_settings || die "cannot write settings"; # Loop zum Datenempfang my $error=0; while ($error != 1) { my ($x,$data) = 0 ; my $sml = 0; my $start = 0; my $value = 0; my $dec_value = 0; my $count = 0; my $saw = 0; if ($debug == 1) {print "Step 1 - Daten holen \n";} while ($start < 2) # wait for second 1B1B1B1B01010101 { ($count,$saw)=$port->read(512); # will read 512 chars if ($count == 512) # wurden 512 chars gelesen ? { $x = uc(unpack('H*',$saw)); # nach hex wandeln $data .= $x; if ($data =~ /1B1B1B1B01010101/) {$start ++}; } # if } # while if ($debug==1) {print "Step 2 - Reg Exp 1 Datensatz zusammensetzen \n";} $data =~ m/1B1B1B1B01010101(.*?)B1B1B1/; $sml = $1; print "Zaehler Haushalt: \n"; if ($debug==1) {print "Step 3 - Datensatz auswerten \n";} foreach my $obiscnt (@obis) { # Umwandeln OBIS in HEx my $hc =""; foreach my $c (split(/\./,$obiscnt->{obis})) { $hc .= sprintf("%02X", $c); } my $obissearch = $hc; # FF fuer Suche an Hex-Wert anhaegne $obissearch .="FF"; if ($debug==1) { print $obissearch." Obis\n";} $sml =~ m/$obiscnt->{obis}(.*?)0177/; my $sml_val = $1; if ($debug==1) { print $1." contains hex \n";} #extract value $sml_val =~ s/^.*52FF//; $sml_val = substr($sml_val,2); if ($debug == 1) { print $sml_val." hex \n";} $value = $sml_val; $dec_value = sprintf("%d", hex($value)); $dec_value /= $obiscnt->{fact}; print $dec_value."<<<<---- Wert\n"; # RRD-Graphen erstellen - bei Bedarf wieder aktiv setzen #if ($obis->{rrd} eq "c") # { # &rrd_counter ($obis->{rrd_name},$dec_value) # } #if ($obis->{rrd} eq "g") # { # &rrd_gauge ($obis->{rrd_name},$dec_value) # } &knx_write ($obiscnt->{ga},$dec_value,$obiscnt->{dpt}); if ($debug == 1) {print "GA:".$obiscnt->{ga}." Wert:".$dec_value." DPT:".$obiscnt->{dpt}."\n";} } # foreach sleep $repeat; } # while $port->close() || warn "Serial port did not close proper!\n"; undef $port; ### SUBS ### sub rrd_counter { if ($debug==1){print ("COUNTER","\n")}; foreach (@countermodes) { my $obisname = $_[0]; if ($debug==1){print $obisname." obisname \n";} my $value = $_[1]; if ($debug==1){print $value." value \n";} my $rrdname = $obisname."_".$_."\.rrd"; if ($debug==1){print ($rrdname,"\n")}; my $rrdfile = $rrdpath."\/".$rrdname; unless (-e $rrdfile) { RRDs::create ($rrdfile,"DS:value:COUNTER:".(($_*60)+600).":0:10000000000","RRA:AVERAGE:0.5:1:365","RRA:AVERAGE:0.5:7:300","-s ".($_*60)); } my $countervalue = int($value*$_*60); RRDs::update("$rrdfile", "N:$countervalue"); } } sub rrd_gauge { if ($debug==1){print ("GAUGE","\n")}; my $obisname = $_[0]; if ($debug==1){print $obisname." obisname \n";} my $value = $_[1]; if ($debug==1){print $value." value \n";} my $rrdname = $obisname."\.rrd"; if ($debug==1){print ($rrdname,"\n")}; my $rrdfile = $rrdpath."\/".$rrdname; unless (-e $rrdfile) { RRDs::create ($rrdfile,"DS:value:GAUGE:900:0:10000000000","RRA:AVERAGE:0.5:1:2160","RRA:AVERAGE:0.5:5:2016","RRA:AVERAGE:0.5:15:2880","RRA:AVERAGE:0.5:60:8760"); } RRDs::update("$rrdfile", "N:$value"); } sub knx_write { my ($dst,$value,$dpt,$response,$dbgmsg) = @_; my $bytes; my $apci = ($response) ? 0x40 : 0x80; # 0x40=response, 0x80=write # DPT 1 (1 bit) = EIS 1/7 (move=DPT 1.8, step=DPT 1.7) # DPT 2 (1 bit controlled) = EIS 8 # DPT 3 (3 bit controlled) = EIS 2 # DPT 4 (Character) = EIS 13 # DPT 5 (8 bit unsigned value) = EIS 6 (DPT 5.1) oder EIS 14.001 (DPT 5.10) # DPT 6 (8 bit signed value) = EIS 14.000 # DPT 7 (2 byte unsigned value) = EIS 10.000 # DPT 8 (2 byte signed value) = EIS 10.001 # DPT 9 (2 byte float value) = EIS 5 # DPT 10 (Time) = EIS 3 # DPT 11 (Date) = EIS 4 # DPT 12 (4 byte unsigned value) = EIS 11.000 # DPT 13 (4 byte signed value) = EIS 11.001 # DPT 14 (4 byte float value) = EIS 9 # DPT 15 (Entrance access) = EIS 12 # DPT 16 (Character string) = EIS 15 # $dpt = $eibgaconf{$dst}{'DPTSubId'} unless $dpt; # read dpt from eibgaconf if existing given ($dpt) { when (/^12/) { $bytes = pack ("CCL>", 0, $apci, $value); } #EIS11.000/DPT12 (4 byte unsigned) when (/^13/) { $bytes = pack ("CCl>", 0, $apci, $value); } when (/^14/) { $bytes = pack ("CCf>", 0, $apci, $value); } when (/^16/) { $bytes = pack ("CCa14", 0, $apci, $value); } when (/^17/) { $bytes = pack ("CCC", 0, $apci, $value & 0x3F); } when (/^20/) { $bytes = pack ("CCC", 0, $apci, $value); } when (/^\d\d/) { return; } # other DPT XX 15 are unhandled when (/^[1,2,3]/) { $bytes = pack ("CC", 0, $apci | ($value & 0x3f)); } #send 6bit small when (/^4/) { $bytes = pack ("CCc", 0, $apci, ord($value)); } when ([5,5.001]) { $bytes = pack ("CCC", 0, $apci, encode_dpt5($value)); } #EIS 6/DPT5.001 1byte when ([5.004,5.005,5.010]) { $bytes = pack ("CCC", 0, $apci, $value); } when (/^5/) { $bytes = pack ("CCC", 0, $apci, $value); } when (/^6/) { $bytes = pack ("CCc", 0, $apci, $value); } when (/^7/) { $bytes = pack ("CCS>", 0, $apci, $value); } when (/^8/) { $bytes = pack ("CCs>", 0, $apci, $value); } when (/^9/) { $bytes = pack ("CCCC", 0, $apci, encode_dpt9($value)); } #EIS5/DPT9 2byte float default { LOGGER('WARN',"None or unsupported DPT: $dpt sent to $dst value $value"); return; } } my $leibcon = EIBConnection->EIBSocketURL($eib_url) or return("Error opening con: $!"); if ($leibcon->EIBOpenT_Group(str2addr($dst),1) == -1) { return("Error opening group: $!"); } my $res=$leibcon->EIBSendAPDU($bytes); $leibcon->EIBClose(); return $res; # str2addr: Convert an EIB address string in the form "1/2/3" or "1.2.3" to an integer sub str2addr { my $str = $_[0]; if ($str =~ /(\d+)\/(\d+)\/(\d+)/) { # logical address return ($1 << 11) | ($2 << 8) | $3; } elsif ($str =~ /(\d+)\.(\d+)\.(\d+)/) { # physical address return ($1 << 12) | ($2 << 8) | $3; } else { #bad return; } } } 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; }
Einen Kommentar schreiben:
-
Eben nochmal geändert, sollte eigentlich so jetzt richtig sein.
Du hättest in @obis noch die 0F.0.7 in 15.0.7 ändern müssen.
Grüße
Einen Kommentar schreiben:
-
Hallo,
für meine Werte zum Testen habe ich die Obis Zeilen von Mirko übernommen.
Hier wurden die Werte ja richtig angezeigt.
Die Subs habe ich ebenfalls rauskopiert, tty und GA angepasst.
Der Verbrauch wird richtig angezeigt, aber bei Leistung steht -0.1 ???
wüsste jetzt nicht woran das liegen könnte.
Grüße,
Lio
Einen Kommentar schreiben:
-
Damit sollte der Workaround für 15.0.7 nicht mehr nötig sein.
Schön dass es sich entwickelt!
Grüße
Code:#!/usr/bin/perl use warnings; use strict; use Device::SerialPort; use feature "switch"; use EIBConnection; use RRDs; use Fcntl qw(:DEFAULT :flock); #0701000F0700FF = 15.7.0 #070100010801FF = 1.8.1 #070100010800FF = 1.8.1 # Lock setzen damit Skript nur einmal startet open *{0} or die "What!? $0:$!"; flock *{0}, LOCK_EX|LOCK_NB or die "$0 is already running somewhere!\n"; my $eib_url = "ip:rk_nas"; #for local eibd "local:/tmp/eib" for eibd in LAN: "ip:192.168.2.220:6720" my $device = "/dev/ttyUSB0"; my $repeat = 20; # Wiederholung alle x Sekunden my $rrdpath = "/var/www/rrd"; my $debug = 0; my @obis; push @obis,{obis=>"1.8.2", fact=>10000, ga =>"5/5/5", dpt => 14, rrd_name => "Zaehlerstand", rrd => "c" }; #rrd: c=counter ; g=gauge push @obis,{obis=>"15.7.0", fact=>10, ga =>"5/5/6", dpt => 14 , rrd_name => "Zaehler_Leistung", rrd => "g" }; my @countermodes = (5,15,60,1440); #Aufloesungen fuer COUNTER RRDs in Minuten (1440 = Tagesverbrauch) my $port = Device::SerialPort->new($device) || die $!; $port->databits(8) || die "failed setting databits"; $port->baudrate(9600) || die "failed setting baudrate"; $port->parity("none") || die "failed setting parity"; $port->stopbits(1); $port->handshake("none"); $port->dtr_active(0); $port->purge_all(); $port->read_char_time(0); # don't wait for each character $port->read_const_time(4000); # 1 second per unfulfilled "read" call $port->write_settings || die "cannot write settings"; # Loop zum Datenempfang my $error=0; while ($error != 1) { my ($x,$data) = 0 ; my $sml = 0; my $start = 0; my $value = 0; my $dec_value = 0; my $count = 0; my $saw = 0; if ($debug == 1) {print "Step 1 - Daten holen \n";} while ($start < 2) # wait for second 1B1B1B1B01010101 { ($count,$saw)=$port->read(512); # will read 512 chars if ($count == 512) # wurden 512 chars gelesen ? { $x = uc(unpack('H*',$saw)); # nach hex wandeln $data .= $x; if ($data =~ /1B1B1B1B01010101/) {$start ++}; } # if } # while if ($debug==1) {print "Step 2 - Reg Exp 1 Datensatz zusammensetzen \n";} $data =~ m/1B1B1B1B01010101(.*?)B1B1B1/; $sml = $1; print "Zaehler Haushalt: \n"; if ($debug==1) {print "Step 3 - Datensatz auswerten \n";} foreach my $obiscnt (@obis) { # Umwandeln OBIS in HEx [COLOR="Red"]my $hc =""; foreach my $c (split(/\./,$obiscnt->{obis})) { $hc .= sprintf("%02X", $c); } my $obissearch = $hc;[/COLOR] # FF fuer Suche an Hex-Wert anhaegne $obissearch .="FF"; if ($debug==1) { print $obissearch." Obis\n";} $sml =~ m/$obiscnt->{obis}(.*?)0177/; my $sml_val = $1; if ($debug==1) { print $1." contains hex \n";} #extract value $sml_val =~ s/^.*52FF//; $sml_val = substr($sml_val,2); if ($debug == 1) { print $sml_val." hex \n";} $value = $sml_val; $dec_value = sprintf("%d", hex($value)); $dec_value /= $obiscnt->{fact}; print $dec_value."<<<<---- Wert\n"; # RRD-Graphen erstellen - bei Bedarf wieder aktiv setzen #if ($obis->{rrd} eq "c") # { # &rrd_counter ($obis->{rrd_name},$dec_value) # } #if ($obis->{rrd} eq "g") # { # &rrd_gauge ($obis->{rrd_name},$dec_value) # } &knx_write ($obiscnt->{ga},$dec_value,$obiscnt->{dpt}); if ($debug == 1) {print "GA:".$obiscnt->{ga}." Wert:".$dec_value." DPT:".$obiscnt->{dpt}."\n";} } # foreach sleep $repeat; } # while $port->close() || warn "Serial port did not close proper!\n"; undef $port; ### SUBS ### sub rrd_counter {} # wie gehabt sub rrd_gauge {} # wie gehabt sub knx_write {} # wie gehabt
Einen Kommentar schreiben:
-
Hi,
das angepasste Perl-Script hat quasi 24 Stunden überstanden. Hier der geänderte Code:
Code:#!/usr/bin/perl use warnings; use strict; use Device::SerialPort; use feature "switch"; use EIBConnection; use RRDs; use Fcntl qw(:DEFAULT :flock); #0701000F0700FF = 7.0 FIXME !!! [0F]0700 #070100010801FF = 1.8.1 #070100010800FF = 1.8.1 # Lock setzen damit Skript nur einmal startet open *{0} or die "What!? $0:$!"; flock *{0}, LOCK_EX|LOCK_NB or die "$0 is already running somewhere!\n"; my $eib_url = "ip:rk_nas"; #for local eibd "local:/tmp/eib" for eibd in LAN: "ip:192.168.2.220:6720" my $device = "/dev/ttyUSB0"; my $repeat = 20; # Wiederholung alle x Sekunden my $rrdpath = "/var/www/rrd"; my $debug = 0; my @obis; push @obis,{obis=>"1.8.2", fact=>10000, ga =>"5/5/5", dpt => 14, rrd_name => "Zaehlerstand", rrd => "c" }; #rrd: c=counter ; g=gauge # Workaround fuer 15.7.0 - aktuellen Verbrauch push @obis,{obis=>"F.7.0", fact=>10, ga =>"5/5/6", dpt => 14 , rrd_name => "Zaehler_Leistung", rrd => "g" }; my @countermodes = (5,15,60,1440); #Aufloesungen fuer COUNTER RRDs in Minuten (1440 = Tagesverbrauch) my $port = Device::SerialPort->new($device) || die $!; $port->databits(8) || die "failed setting databits"; $port->baudrate(9600) || die "failed setting baudrate"; $port->parity("none") || die "failed setting parity"; $port->stopbits(1); $port->handshake("none"); $port->dtr_active(0); $port->purge_all(); $port->read_char_time(0); # don't wait for each character $port->read_const_time(4000); # 1 second per unfulfilled "read" call $port->write_settings || die "cannot write settings"; # Loop zum Datenempfang my $error=0; while ($error != 1) { my ($x,$data) = 0 ; my $sml = 0; my $start = 0; my $value = 0; my $dec_value = 0; my $count = 0; my $saw = 0; if ($debug == 1) {print "Step 1 - Daten holen \n";} while ($start < 2) # wait for second 1B1B1B1B01010101 { ($count,$saw)=$port->read(512); # will read 512 chars if ($count == 512) # wurden 512 chars gelesen ? { $x = uc(unpack('H*',$saw)); # nach hex wandeln $data .= $x; if ($data =~ /1B1B1B1B01010101/) {$start ++}; } # if } # while if ($debug==1) {print "Step 2 - Reg Exp 1 Datensatz zusammensetzen \n";} $data =~ m/1B1B1B1B01010101(.*?)B1B1B1/; $sml = $1; print "Zaehler Haushalt: \n"; if ($debug==1) {print "Step 3 - Datensatz auswerten \n";} foreach my $obiscnt (@obis) { # Umwandeln OBIS in HEx-Wert my $obissearch = $obiscnt->{obis}; $obissearch =~ s/\./0/g; # FF fuer Suche an Hex-Wert anhaegne $obissearch .="FF"; if ($debug==1) { print $obissearch." Obis\n";} $sml =~ m/$obiscnt->{obis}(.*?)0177/; my $sml_val = $1; if ($debug==1) { print $1." contains hex \n";} #extract value $sml_val =~ s/^.*52FF//; $sml_val = substr($sml_val,2); if ($debug == 1) { print $sml_val." hex \n";} $value = $sml_val; $dec_value = sprintf("%d", hex($value)); $dec_value /= $obiscnt->{fact}; print $dec_value."<<<<---- Wert\n"; # RRD-Graphen erstellen - bei Bedarf wieder aktiv setzen #if ($obis->{rrd} eq "c") # { # &rrd_counter ($obis->{rrd_name},$dec_value) # } #if ($obis->{rrd} eq "g") # { # &rrd_gauge ($obis->{rrd_name},$dec_value) # } &knx_write ($obiscnt->{ga},$dec_value,$obiscnt->{dpt}); if ($debug == 1) {print "GA:".$obiscnt->{ga}." Wert:".$dec_value." DPT:".$obiscnt->{dpt}."\n";} } # foreach sleep $repeat; } # while $port->close() || warn "Serial port did not close proper!\n"; undef $port; ### SUBS ### sub rrd_counter {} # wie gehabt sub rrd_gauge {} # wie gehabt sub knx_write {} # wie gehabt
Einen Kommentar schreiben:
-
Hi Lio,
ja, ist immer noch das gleiche Thema. Ich möchte meinen ED300L auslesen, der spricht ja SML.
Das neue Script scheint das Problem zu lösen, hat die ganze Nacht anstandslos Daten geliefert. Ich mach das mal schick, dann stell ich es hier ein.
Grüße
Gunnar
Einen Kommentar schreiben:
Einen Kommentar schreiben: