Ankündigung

Einklappen
Keine Ankündigung bisher.

Zählerabfrage als Wiregate Plugin

Einklappen
Dieses Thema ist geschlossen.
X
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • coolrunnings
    antwortet
    Zitat von JuMi2006 Beitrag anzeigen
    Die Logs sagen da aber was anderes
    Hier mal ein aktuelles Log

    Code:
    760500E2AB36620062007263010176010105004B8E660B090149534B0003C32949010163E1DE00760500E2AB37620062007263070177010B090149534B0003C32949070100620AFFFF726201650098C9147A77078181C78203FF010101010449534B0177070100000009FF010101010B090149534B0003C329490177070100010800FF650000018201621E52FF5900000000006EB7D60177070100010801FF0101621E52FF5900000000006EB7D60177070100010802FF0101621E52FF5900000000000000000177070100100700FF0101621B520055000000EE0177070100240700FF0101621B520055000000300177070100380700FF0101621B5200550000007A01770701004C0700FF0101621B520055000000430177078181C78205FF010101018302C2FBC74DB331F865613D6E2B45318F426AF70C57F06F6FEA07E2857CE89D3702E396D8EB1FEFDA6F553517AEBE729C99010101632F3D00760500E2AB3862006200726302017101630524001
    Wenn ich das grob aufteile, so wie es auch das Skript macht (suche zwischen OBIS ID und 0177, dann sind die Strings dazwischen unterschiedlich lang.

    Code:
    010801FF 0101621E52FF 5900000000006EB7D6 0177070100
    010802FF 0101621E52FF 590000000000000000 0177070100 
    100700FF 0101621B5200 55000000EE 0177070100
    240700FF 0101621B5200 5500000030 0177070100
    380700FF 0101621B5200 550000007A 0177070100
    4C0700FF 0101621B5200 5500000043 0177078181C78205FF

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Die Logs sagen da aber was anderes, verstehe ich nicht. Lässt sich auch schlecht aus der Ferne debuggen. Wenn dann macht es auch nur Sinn wenn man gemeinsam an einem Code arbeitet so dass später alle was davon haben statt individueller Krücken.

    Scaler ist der Faktor
    SML-Protokoll:
    http://www.vde.com/de/fnn/arbeitsgeb...n_SML_1-03.pdf

    Einen Kommentar schreiben:


  • coolrunnings
    antwortet
    Zitat von JuMi2006 Beitrag anzeigen

    EDIT: substr mit 22 sollte klappen, hab das im Code oben mal geändert, vielleicht will es noch jemand testen ?
    Mit 22 funktioniert es zumindest bei mir nicht, weil der ganze String weniger als 22 Zeichen hat.

    Einen Kommentar schreiben:


  • coolrunnings
    antwortet
    Zitat von JuMi2006 Beitrag anzeigen
    Der Faktor steckt in dem Matching

    Factoring fand ich vorhin bei google ...
    Kannst du mir das was genauer erklären, oder einen Link posten wo ich das nachlesen kann.

    Zitat von JuMi2006 Beitrag anzeigen
    Dein subtr aber eher ungünstig weil Du von hinten wegschneidest. Sowas sollte man immer allgemeingültig halten.
    Hab das mit dem substr inzwischen auch ganz rausgenommen.

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Der Faktor steckt in dem Matching, m.M.n. ist Dein subtr aber eher ungünstig weil Du von hinten wegschneidest. Sowas sollte man immer allgemeingültig halten.

    Factoring fand ich vorhin bei google ...


    EDIT: substr mit 22 sollte klappen, hab das im Code oben mal geändert, vielleicht will es noch jemand testen ?

    Einen Kommentar schreiben:


  • coolrunnings
    antwortet
    Erstmal VIELEN DANK für die Hilfe.
    Ich bin zwar selber Softwareentwickler, aber Perl hab ich bisher erfolgreich ignorieren können
    Mit deinem Vorschlag
    Code:
    $sml_val = substr($sml_val,14);
    hat es leider auch nicht funktioniert, weil dann der Wert für den Gesamtverbrauch zu groß war:
    Code:
    010800FF     Obis
    650000018201621E52FF5900000000006EAB9F contains hex
    1 Obis ID
    1E52FF5900000000006EAB9F hex
    52FF5900000000006EAB9F hex
    Integer overflow in hexadecimal number at sml_test line 105.
    Hexadecimal number > 0xffffffff non-portable at sml_test line 105.
    Wenn man es folgendermaßen anpasst, klappt es:

    Code:
    $sml_val = substr($sml_val,-10);
    Ich habe aber in der Zwischenzeit folgende Lösung implementiert:
    Code:
    my $obisid0 = (split(/\./,$obiscnt->{obis}))[0];
    if ($debug==1) { print $obisid0." Obis ID \n"; }
    if  ($obisid0==16)
    {
        $sml_val =~ s/^.*5200//;
    }
    else
    {
        $sml_val =~ s/^.*52FF//;
    }
    Was nun eleganter ist, kann jeder für sich entscheiden.

    Jetzt muss ich nur noch den richtigen Faktor bestimmen, weil 20,9W scheint mir doch etwas wenig.

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Probiere mal das:

    Code:
    #!/usr/bin/perl
    # Autor: JuMi2006 / www.knx-user-forum.de
    # knx_write sub: makki / www.knx-user-forum.de
    # Version: 0.1
    # Datum: 19.02.2013
    
    use warnings;
    use strict;
    use Device::SerialPort;
    use feature "switch";
    use EIBConnection;
    use RRDs;
    
    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/ttyUSB-0";
    my $rrdpath = "/var/www/rrd";
    
    my @obis;
    push @obis,{obis=>"1.8.0",  fact=>10000, ga =>"9/0/0", dpt => 14, rrd_name => "Zaehler_Verbrauch", rrd => "c"   }; #rrd: c=counter ; g=gauge
    push @obis,{obis=>"16.7.0",    fact=>10,    ga =>"9/0/1", dpt => 9 , rrd_name => "Zaehler_Leistung",  rrd => "g" };
    my @countermodes = (5,15,60,1440);    #Aufloesungen fuer COUNTER RRDs in Minuten (1440 = Tagesverbrauch)
    
    
    my $debug = "";
    my $port = Device::SerialPort->new($device) || die $!;
    $port->databits(8);
    $port->baudrate(9600);
    $port->parity("none");
    $port->stopbits(1);
    $port->handshake("none");
    $port->write_settings;
    $port->dtr_active(1);
    $port->purge_all();
    $port->read_char_time(0);     # don't wait for each character
    $port->read_const_time(2000); # 1 second per unfulfilled "read" call
    
    
    my ($x,$data);
    my $start = 0;
    while ($start < 2) { # wait for second 1B1B1B1B01010101
           my ($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 ++};
           }
    }
    
    $data =~ m/1B1B1B1B01010101(.*?)B1B1B1/;
    my $sml = $1;
    if ($debug==1){print $1." Rohdaten";}
    
    foreach my $obis (@obis)
    {
    $obis->{obis} =~ s/\./0/g;
    $obis->{obis} .= "FF";
    if ($debug==1){print $obis->{obis}." Obis\n";}
        $hc ="";
        foreach my $c (split(/\./,$obis->{obis})) {
            $hc .= sprintf("%02X", $c);
        }
        my $obissearch = $hc;
    $sml =~ m/$obissearch(.*?)0177/;
    if ($debug==1){print $1." contains hex \n";}
    my $sml_val = $1;
    #extract value
    $sml_val = substr($sml_val,22);
    print $sml_val." hex \n";
    my $value = $sml_val;
    my $dec_value = sprintf("%d", hex($value));
    $dec_value /= $obis->{fact};
    print $dec_value."<<<<---- Wert\n";
    
    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 ($obis->{ga},$dec_value,$obis->{dpt});
    print "GA:".$obis->{ga}." Wert:".$dec_value." DPT:".$obis->{dpt}."\n";
    }
    
    
    ### 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:


  • JuMi2006
    antwortet
    Ja ich sehe das Problem, lediglich für die Lösung belese ich mich gerade noch.

    Einen Kommentar schreiben:


  • coolrunnings
    antwortet
    Ich habe mir jetzt aus den 2 gefundenen Skripten eins zusammengebaut, dass sowohl mit der 16.7.0 statt 10.7.0 funktioniert und auch kein uninitialized mehr wirft.

    Code:
    #!/usr/bin/perl
    
    use warnings;
    use strict;
    use Device::SerialPort;
    use feature "switch";
    use EIBConnection;
    use RRDs;
    
    
    #0701000F0700FF = 7.0       FIXME !!! [0F]0700
    #070100010801FF = 1.8.1
    #070100010800FF = 1.8.1
    
    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/ttyUSB0";
    my $rrdpath = "/var/www/rrd";
    
    my @obis;
    push @obis,{obis=>"1.8.0",  fact=>10000, ga =>"9/0/0", dpt => 14, rrd_name => "Zaehler_Verbrauch", rrd => "c"   }; #rrd: c=counter ; g=gauge
    push @obis,{obis=>"16.7.0",    fact=>10,    ga =>"9/0/1", dpt => 9 , rrd_name => "Zaehler_Leistung",  rrd => "g" };
    my @countermodes = (5,15,60,1440);    #Aufloesungen fuer COUNTER RRDs in Minuten (1440 = Tagesverbrauch)
    
    my $debug = "1";
    my $port = Device::SerialPort->new($device) || die $!;
    $port->databits(8);
    $port->baudrate(9600);
    $port->parity("none");
    $port->stopbits(1);
    $port->handshake("none");
    $port->write_settings;
    $port->dtr_active(1);
    $port->purge_all();
    $port->read_char_time(0);     # don't wait for each character
    $port->read_const_time(2000); # 1 second per unfulfilled "read" call
    
    
    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/;
    	 $sml =~ m/$obissearch(.*?)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";
    
    if ($obiscnt->{rrd} eq "c")
                {
                    &rrd_counter ($obiscnt->{rrd_name},$dec_value)
                }
    if ($obiscnt->{rrd} eq "g")
                {
                    &rrd_gauge ($obiscnt->{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
    
    
    $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;
    }
    Dafür bekomme ich wieder den integer overflow:

    Code:
    100700FF     Obis
    0101621B52005500000106 contains hex
    01621B52005500000106 hex
    Integer overflow in hexadecimal number at sml_test line 91.
    Hexadecimal number > 0xffffffff non-portable at sml_test line 91.
    -0.1<<<<---- Wert
    GAUGE
    Zaehler_Leistung obisname
    -0.1 value
    Zaehler_Leistung.rrd
    GA:9/0/1 Wert:-0.1 DPT:14
    Er kürzt beim hex Wert für die Leistung auch nicht soviel am Anfang weg wie beim Zählerstand.

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Ja genau das war es ... wurde wohl nie eingechecked

    Einen Kommentar schreiben:


  • coolrunnings
    antwortet
    Evtl. hier: https://knx-user-forum.de/300003-post335.html

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Schein ein Bug zu sein, ich dachte ich hätte das irgendwo schonmal gefixed - vielleicht nicht im SVN.
    Probiere mal statt 16.7.0 die 10.7.0 aus.

    Einen Kommentar schreiben:


  • coolrunnings
    antwortet
    Ich hab die OBIS Nr. auf 16.7.0 angepasst, bekomm aber immer noch eine Fehlermeldung:

    Code:
    160700FF Obis
    Use of uninitialized value $1 in concatenation (.) or string at SML_Meter line 62.
     contains hex
    Use of uninitialized value $sml_val in substitution (s///) at SML_Meter line 65.
    Use of uninitialized value $sml_val in substr at SML_Meter line 66.
    substr outside of string at SML_Meter line 66.
    Use of uninitialized value $sml_val in concatenation (.) or string at SML_Meter line 67.
     hex
    Use of uninitialized value $value in hex at SML_Meter line 69.
    0<<<<---- Wert
    GAUGE
    Zaehler_Leistung obisname
    0 value
    Zaehler_Leistung.rrd
    GA:9/0/1 Wert:0 DPT:9
    Kann es evtl. sein, dass im SVN nicht die aktuelle Version liegt? Ich habe ein paar Post vorher was von obissearch gelesen, kann aber davon im SVN nichts finden.

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Das sind Deine Zählerwerte:

    Code:
    070100[B]000009[/B]FF010101010B090149534B0003C32949 [B]hex2dec: 0.0.9[/B]
    070100[B]010800[/B]FF650000018201621E52FF5900000000006E7A9E [B]hex2dec: 1.8.0[/B]
    070100[B]010801[/B]FF0101621E52FF5900000000006E7A9E [B]hex2dec: 1.8.1[/B]
    070100[B]010802[/B]FF0101621E52FF590000000000000000 [B]hex2dec: 1.8.2[/B]
    070100[B]100700[/B]FF0101621B5200550000012A [B]hex2dec: 16.7.0 --> aktuelle Leistung[/B]
    070100[B]240700[/B]FF0101621B52005500000087 [B]hex2dec: 36.7.0 --> L1[/B]
    070100[B]380700[/B]FF0101621B52005500000058 [B]hex2dec: 56.7.0 --> L2[/B]
    070100[B]4C0700[/B]FF0101621B52005500000049 [B]hex2dec: 76.7.0 --> L3[/B]
    Einheiten/Factor müsste man evtl. korrigieren.

    EDIT:
    Hier mal eine gute Seite auf der man eine gute Übersicht über die OBIS-Codes hat: http://www.promotic.eu/en/pmdoc/Subs...62056_OBIS.htm

    Einen Kommentar schreiben:


  • coolrunnings
    antwortet
    Mit "Durchklicken" ist da leider nichts (Zumal ich eh gerade den Zähler nicht vor mir habe).

    Aber den Output kann ich posten:

    Code:
    root@wiregate1043:/etc/wiregate/plugin/generic# perl SML_Meter
    760500E23726620062007263010176010105004B67B60B090149534B0003C329490101630B9000760500E23727620062007263070177010B090149534B0003C32949070100620AFFFF726201650098962B7A77078181C78203FF010101010449534B0177070100000009FF010101010B090149534B0003C329490177070100010800FF650000018201621E52FF5900000000006E7A9E0177070100010801FF0101621E52FF5900000000006E7A9E0177070100010802FF0101621E52FF5900000000000000000177070100100700FF0101621B5200550000012A0177070100240700FF0101621B520055000000870177070100380700FF0101621B5200550000005801770701004C0700FF0101621B520055000000490177078181C78205FF010101018302C2FBC74DB331F865613D6E2B45318F426AF70C57F06F6FEA07E2857CE89D3702E396D8EB1FEFDA6F553517AEBE729C9901010163A49F00760500E237286200620072630201710163C2E1001
    10800FF Obis
    650000018201621E52FF5900000000006E7A9E contains hex
    00000000006E7A9E hex
    724.035<<<<---- Wert
    COUNTER
    Zaehler_Verbrauch obisname
    724.035 value
    Zaehler_Verbrauch_5.rrd
    Zaehler_Verbrauch obisname
    724.035 value
    Zaehler_Verbrauch_15.rrd
    Zaehler_Verbrauch obisname
    724.035 value
    Zaehler_Verbrauch_60.rrd
    Zaehler_Verbrauch obisname
    724.035 value
    Zaehler_Verbrauch_1440.rrd
    GA:9/0/0 Wert:724.035 DPT:14
    00700FF Obis
    0101621B5200550000012A contains hex
    01621B5200550000012A hex
    Integer overflow in hexadecimal number at SML_Meter line 69.
    Hexadecimal number > 0xffffffff non-portable at SML_Meter line 69.
    -0.1<<<<---- Wert
    GAUGE
    Zaehler_Leistung obisname
    -0.1 value
    Zaehler_Leistung.rrd
    GA:9/0/1 Wert:-0.1 DPT:9
    root@wiregate1043:/etc/wiregate/plugin/generic#

    Einen Kommentar schreiben:

Lädt...
X