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

  • mikeeyy
    antwortet
    Hallo JuMi

    ich habe jetzt mal Dein Script aus deinem letzten Post (Link) genommen und angepasst

    Code:
    #!/usr/bin/perl
    
    # Zaehlerabfrage fuer Zaehler 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.
    # Ein Wechsel der Geschwindigkeit ist möglich, in diesem Script aber noch nicht umgesetzt.
    
    # !!! Wiederholung nur alle 3 Minuten da der Zaehler 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
    # In dieser Version keine Anbindung an den KNX-Bus
    # Erweiterung um RRD,KNX-Anbindung und gezielte Wertsuche auf Wiregate: 
    # JuMi2006 / www.knx-user-forum.de
    # Version: 0.1.3
    # Datum: 23.04.2012
    
    use warnings;
    use strict;
    use Device::SerialPort;
    use RRDs;
    
    ### KONFIGURATION ###
    my $device = "/dev/ttyS0";    #Port
    my $conf4800 = "/tmp/conf4800";        #temporäre Konfigurationsdatei für Baudwechsel
    my $endsign = "!";            #Letztes Zeichen im Protokoll vom Zaehler
    my $rrdpath = "/var/www/rrd";        #Pfad für RRDs
    my $counterid = "Zaehler_HZ";        #Grundname für RRDs
    my %obis=(    "16.7"=>6,        #Obis-Zahl => Anzahl der Stellen z.B.: 6 = 123.45
            "32.7"=>3,
            "52.7"=>3,
            "31.7"=>6,
            "51.7"=>6,
            "71.7"=>6,
            "72.7"=>3,
            "1-0:1.8.1*255"=>10);        #!!!COUNTER!!!
    
    my %countermode=("1-0:1.8.1*255"=>24);        #Obiscode für Zaehlerstaende
                        #RRD gibt Verbrauch pro Tag aus (beta)
    
    
    ### ENDE KONFIGURATION ###
    
    ### Seriellen Port initialisieren
    
    ####4800baud
    my $port = new Device::SerialPort($device) || die "can't open $device: $!";
    $port->baudrate(9600)      || 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->rts_active(1);
    $port->dtr_active(1);
    $port->read_char_time(1000);     # 0.5 seconds for each character
    $port->read_const_time(5000);   # 1 second per unfulfilled "read" call
    $port->write_settings     || die 'fail write settings';
    
    
    $port->save($conf4800)     || warn "Can't save $conf4800: $!\n";
    
    ####START 300baud
    $port->baudrate()      || 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->dtr_active(1);
    $port->rts_active(1);
    $port->read_char_time(500);     # 0.5 seconds for each character
    $port->read_const_time(1000);   # 1 second per unfulfilled "read" call
    $port->write_settings     || die 'fail write settings';
    
    
    ### Anforderungstelegramm senden
    my $data="2f3f210d0a";                #Anfrage als HEX "/?!<CR><LF>"
    my $request = pack('H*',$data);
                            
    my $num_out = $port->write($request);
    print $request;
    die "write failed\n" unless ($num_out);
    die "write inclomplete\n" unless ($num_out == length($request));
    print "$num_out Bytes written\n";
    
    ### Warte auf Zaehlerkennung
    
    select(undef, undef, undef, 1.5); # 1.5 Sekunden warten
    
    ### Telegramm mit ACK und neuer Geschwindigkeit senden
    my $data2="063030300d0a";                #ACK und neue Geschwindigkeit in HEX "<ACK>040<CR><LF>"
    my $baudwechsel = pack('H*',$data2);    # 000 = 300baud, 040 = 4800baud
    
    my $num_out2 = $port->write($baudwechsel);
    print $baudwechsel;
    die "write failed\n" unless ($num_out2);
    die "write inclomplete\n" unless ($num_out2 == length($baudwechsel));
    print "$num_out2 Bytes written\n";
    
    ### Port mit neuer Geschwindigkeit intialisieren
    
    $port->restart($conf4800)  || warn "Can't restart $conf4800: $!\n"; ;
    
    #$port->baudrate(300); 
    #$port->write_settings;
    
    ### 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(25);     # Liest 25 Zeichen je Durchlauf aus
            if ($count > 0) {
                    $chars+=$count;
                    $buffer.=$saw;
            #print ($buffer,"\n");        # Ausgabe der eingelesenen Daten
    
    
    ### FILTER FOR END
    if ($buffer =~ /\Q$endsign\E/)            # \Q \E entwertet alle Sonderzeichen dazwischen
    {    
    $port->close || die "can't close $device: $!";    # Port schlieen
    last;                        # Schleife verlassen
    }
    ### ENDE FILTER FOR END
            
    }
            else {
                    $timeout--;
            }
    }
    
    if ($timeout<=0) {
    $port->close || die "can't close $device: $!";        
    print "Waited $STALL_DEFAULT seconds and never saw what I wanted\n";
            }
    print $buffer;        #Nur zur Kontrolle
    
    ### FILTER FOR DATA
    while (my($key, $value) = each %obis)
    {
    my $obiskey = $key."(";
    if ($buffer =~ /\Q$obiskey\E/)            # \Q \E entwertet alle Sonderzeichen dazwischen
    {    
    my $pos=index($buffer,$obiskey);        # Anfangsposition des OBIS-Key finden
    print ("Obiskey: $obiskey","\n");        # Kontrolldruck
    print ("Position: $pos","\n");            # Kontrolldruck
    print (length($obiskey),"\n");            # Kontrolldruck
    my $obisvalue=substr($buffer,($pos+length($key)+1),$obis{$key});     # Wert extrahieren
    print ($key,": ",$obisvalue,"\n");                    # Kontrolldruck
    
    ### RRD-Erstellen
    my $obisname = "$key";
    $obisname =~ tr/./-/;
    my $rrdname = $counterid."_".$obisname."\.rrd";
    print ($rrdname,"\n");
    my $rrdfile = $rrdpath."\/".$rrdname;
    
    
    ### RRD check COUNTER/GAUGE
    if (exists $countermode{$key})
    {
    print ("COUNTER","\n");
    ### COUNTER schreiben
    unless (-e $rrdfile) 
    {
    RRDs::create ($rrdfile,"DS:value:COUNTER:86500:0:10000000000","RRA:AVERAGE:0.5:1:365","RRA:AVERAGE:0.5:7:300","-s 86400");
    }
    ### RRD-Füllen
    RRDs::update("$rrdfile", "N:$obisvalue*=86400");
    }
    else
    {
    print ("GAUGE","\n");
    ###GAUGE schreiben
    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");
    }
    ### RRD-Füllen
    RRDs::update("$rrdfile", "N:$obisvalue");
    }
    }
    }
    ### ENDE FILTER FOR DATA
    
    
    
    ### Log der Zaehlerausgabe
    #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;
    Ergebnis:

    Obiskey: 1-0:1.8.1*255(
    Position: 83
    14
    1-0:1.8.1*255: 000617.072
    Zaehler_HZ_1-0:1-8-1*255.rrd
    COUNTER


    Sieht doch nicht so schlecht aus. Eine Einbindung von GAs zum Senden der Werte hat das ganze ja noch nicht. Ich würde jetzt versuchen die channel Einträge aus dem aktuellen Script

    z.B.

    Code:
    my @channels;                #Obis-Zahl => Gruppenadresse
    push @channels, {name => "16.7", ga =>"6/3/1", dpt => 9 };    #akt. Leistung
    push @channels, {name => "32.7", ga =>"6/3/11", dpt => 9 };    #Spannung L1
    push @channels, {name => "52.7", ga =>"6/3/21", dpt => 9 };    #Spannung L2
    push @channels, {name => "72.7", ga =>"6/3/31", dpt => 9 };    #Spannung L3
    push @channels, {name => "31.7", ga =>"6/3/10", dpt => 9 };    #Stromstaerke L1
    push @channels, {name => "51.7", ga =>"6/3/20", dpt => 9 };    #Stromstaerke L2
    push @channels, {name => "71.7", ga =>"6/3/30", dpt => 9 };    #Stromstarke L3
    push @channels, {name => "1-0:1.8.1", ga =>"6/3/0", dpt => 9 };    #Zaehlerstand gesamt
    hier mit einfließen zu lassen. Habe zwar noch keine Ahnung wie, aber ich probiere mal etwas rum :-)

    Grüße,
    Mike

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    https://knx-user-forum.de/225383-post148.html

    Das sollte die meisten Fragen beantworten. Das init.pl dient nur raus zu finden was der Zähler alles ausspuckt und was man auswerten möchte. Je nach Zähler können das von 1-100 Datensätze sein.

    Also vergiss jetzt mal das init-script und nimm das was ich zuletzt gepostet habe. Dort änderst Du die Einstellungen wie es im oben verlinkten Post beschrieben ist. Lediglich der richtige DPT ist noch mit einzutragen.

    Welche Rückmeldung vom Zähler erwartest Du ?

    Einen Kommentar schreiben:


  • mikeeyy
    antwortet
    Hi JuMi,

    kannst Du hier bitte mal posten wie bei Dir die Rohdaten aussehen die der Zähler ausspuckt.

    bei mir kommt hier folgendes raus:

    0-0:96.1.0*255(0505514284426675)
    1-0:1.8.0*255(003253.186*kWh)
    1-0:1.8.1*255(000615.455*kWh)
    1-0:1.8.2*255(002637.732*kWh)
    1-0:2.8.0*255(000000.226*kWh)
    1-0:2.8.1*255(000000.226*kWh)
    1-0:2.8.2*255(000000.000*kWh)
    0-0:96.14.0*255(02)
    1-0:15.7.0*255(001360*W)
    0-0:17.0.0*255(0085*A)
    0-0:96.3.10*255(1)
    0-1:96.1.0*255(0505514284426548)
    1-1:1.8.0*255(001216.858*kWh)(13-02-13 09:00:53)
    1-1:1.8.1*255(001216.859*kWh)(13-02-13 09:00:53)
    1-1:1.8.2*255(000000.000*kWh)(13-02-13 09:00:53)
    1-1:1.8.3*255(000000.000*kWh)(13-02-13 09:00:53)
    1-1:1.8.4*255(000000.000*kWh)(13-02-13 09:00:53)
    1-1:2.8.0*255(000000.000*kWh)(13-02-13 09:00:53)
    1-1:2.8.1*255(000000.000*kWh)(13-02-13 09:00:53)
    1-1:2.8.2*255(000000.000*kWh)(13-02-13 09:00:53)
    1-1:2.8.3*255(000000.000*kWh)(13-02-13 09:00:53)
    1-1:2.8.4*255(000000.000*kWh)(13-02-13 09:00:53)
    0-1:96.14.0*255(01)(13-02-13 09:00:53)
    1-1:15.7.0*255(000000*W)(13-02-13 09:00:53)
    0-1:17.0.0*255(0000*A)
    0-1:96.3.10*255(1)


    Ich müßte ja noch die channels entsprechend anpassen, um das korrekt verwerten zu können, richtig? bislang bekomme ich nur den ausdruck im terminal, wenn ich die print zeilen auskommentiere. RRDs erstellt er mir bislang keine..

    zweite frage.... gibt es eine möglichkeit dem script zu sagen das es auf eine rückmeldung/daten vom zähler warten soll? das init.pl script macht das ja.

    Grüße
    Mike

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    @mikey:
    d0 != SML

    d0 == IEC IEC 62056-21

    Das von mir hier gepostete Script macht genau das was Du willst wenn Du oben die Einstellungen veränderst. Eigentlich sind die gut kommentiert und selbsterklärend. Das script musst Du lediglich in die crontab eintragen (auch das geht per Webmin) damit es z.B. alle 3 Minuten aufgerufen wird.


    Grüße

    Einen Kommentar schreiben:


  • mikeeyy
    antwortet
    Hallo zusammen,

    mich beschäftigt das Thema ja auch auch wie vor. Bislang leider ohne durchschlagenden Erfolg. Ich hatte versucht das init.pl script mit dem hier funktionierenden IEC 62056-21 script zu kombinieren. über das init.pl script bekomme ich sauber meine daten ausgelesen, aber eben nich weiterverarbeitet. Ich hatte gehofft das es nicht so schwer sein kann, die möglichkeiten aus dem init.pl script zu verwenden, um die daten entsprechend weiterverarbeiten zu können. Bin leider nicht der Perl Spezi, daher habe ich das nicht auf die Reihe bekommen und wieder eingestellt. Der andere Ansatz war das volkszähler script. Das scheint ja SML zu unterstützen (Parameter "d0"). Hier bin ich aber leider auch noch nicht erfolgreich gewesen. Verbindung zum Zähler scheint grundsätzlich zu klappen. Aber mehr auch nicht. Die Einbindung in die CV ist mir bislang in diesem Zusammenhang aber auch noch gänzlich ein Rätsel. Viele Ideen und Ansätze aber bislang nichts greifbares oder verwertbares. Vom Verständnis her sollte aber der Ansatz mit dem init.pl Script aber auch machbar sein.

    Grüße,
    Mike

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Hallo Lio,

    es gibt eigentlich nur 2 Typen:
    1. IEC 62056-21
    2. SML


    Du hast SML ... das Script geht nur für den IEC 62056-21 Standard. Für Dich ist leider immer noch nichts dabei bis sich mal jemand an die SML Geschichte wagt ... das kann so schwer ja nicht sein.


    Grüße

    Einen Kommentar schreiben:


  • lio123
    antwortet
    Hallo,

    habe ein paar Datenblätter Eurer Zähler verglichen.
    Der Zähler von Mike scheint ähnlich mit meinem EMH EHZ H Zähler zu sein.
    Auch dieser sendet von alleine über die Frontschnittstelle.
    Kannst Du mir Dein Plugin mal senden?
    Evtl hilft das weiter:
    volkszaehler.org - wiki - EMH eHZ-H

    Mich wundert, dass es so viele Unterschiede gibt.

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Also der weg zurück zur ersten war dass es stabiler läuft wenn der Zähler langsamer ausgelesen wird (war bei einem meiner Zähler der Fall). Ansonsten glaube ich da noch eine Unverträglichkeit zw. WireGate und meinem Auslesekopf zu haben.

    Der Zählersprung entsteht im KNX.
    In der Konsole wird bei mir auf 0.001 kWh gemessen, auf dem Bus sind das nur 2.5 kWh-Schritte. DPT9 hat 2 Byte für die Wertdarstellung und DPT14 hat 14 Bytes zur Verfügung -> ergo viel genauer.

    Hier mal mein Script:

    Code:
    #!/usr/bin/perl
    # Zaehlerabfrage fuer Zaehler 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.
    # Ein Wechsel der Geschwindigkeit ist umgesetzt.
    # Basis des Scripts von volkszaehler.org / Autor: Andreas Schulze & Bugfix: Eric Schanze
    # DPT9 sub: makki / www.knx-user-forum.de
    # Baudwechsel: panzaeron / www.knx-user-forum.de
    # Erweiterung um RRD,KNX-Anbindung und gezielte Wertsuche auf Wiregate: 
    # JuMi2006 / www.knx-user-forum.de
    # Version: 0.1.6_beta
    # Datum: 30.01.2013
    
    use warnings;
    use strict;
    use RRDs;
    
    ### KONFIGURATION ###
    my $device = "/dev/usbserial-A600eZF1";		#Port usbserial-2-3.4.1.3
    my $rrdpath = "/tmp";		#Pfad fuer RRDs
    my $counterid = "HZ";			#Grundname fuer RRDs
    my $baudrate = "300";			#Baudrate fuer Zaehlerauslesung
    my @channels;				#Obis-Zahl => Gruppenadresse
    push @channels, {name => "16.7", ga =>"6/3/1", dpt => 9 };	#akt. Leistung
    push @channels, {name => "32.7", ga =>"6/3/11", dpt => 9 };	#Spannung L1
    push @channels, {name => "52.7", ga =>"6/3/21", dpt => 9 };	#Spannung L2
    push @channels, {name => "72.7", ga =>"6/3/31", dpt => 9 };	#Spannung L3
    push @channels, {name => "31.7", ga =>"6/3/10", dpt => 9 };	#Stromstaerke L1
    push @channels, {name => "51.7", ga =>"6/3/20", dpt => 9 };	#Stromstaerke L2
    push @channels, {name => "71.7", ga =>"6/3/30", dpt => 9 };	#Stromstarke L3
    push @channels, {name => "1.8.1", ga =>"6/3/0", dpt => 14 };	#Zaehlerstand gesamt
    
    my @countermodes = (5,15,60,1440);	#Aufloesungen fuer COUNTER RRDs in Minuten (1440 = Tagesverbrauch)
    
    ### ENDE KONFIGURATION ###
    
    my %speedrate = (			#Je nach Geschwindigkeit andere Befehel an Zaehler senden
    		"300"=>"'\x06\x30\x30\x30\x0d\x0a'",
    		"600"=>"'\x06\x30\x31\x30\x0d\x0a'",
    		"1200"=>"'\x06\x30\x32\x30\x0d\x0a'",
    		"2400"=>"'\x06\x30\x33\x30\x0d\x0a'",
    		"4800"=>"'\x06\x30\x34\x30\x0d\x0a'",
    		"9600"=>"'\x06\x30\x35\x30\x0d\x0a'"
    		);
    		
    my $ack = $speedrate{$baudrate};
    #print ($baudrate,"->",$ack);
    
    ### DATEN EMPFANGEN ###
    my @buffer = qx(echo '\x2f\x3f\x21\x0d\x0a' | socat -T 1 - $device,raw,echo=0,b300,parenb=1,parodd=0,cs7,cstopb=0; sleep 1; echo $ack | socat -T 1 - $device,raw,echo=0,b300,parenb=1,parodd=0,cs7,cstopb=0; socat -T 1 - $device,raw,echo=0,b$baudrate,parenb=1,parodd=0,cs7,cstopb=0);
    #print @buffer;
    
    foreach (@buffer)
    {
    	foreach my $obis (@channels)
    	{	
    	my $obiskey = $obis->{name}."\(";
    	if ($_ =~ /\Q$obiskey\E/)
    	{
    	$_  =~ m/[^(]+\(([^*]+)\*([^)]+)/;
    	my $value = $1;
    	my $unit = $2;
    	my $ga = $obis->{ga};
    	print ($obis->{name},"\n");
    	print ($value,"\n");
    	print ($unit,"\n");
    	print ($ga,"\n");
    	if ($unit =~ /\Qh\E/)
    	{
    	&rrd_counter ($obis->{name},$value)
    	}
    	else
    	{
    	&rrd_gauge ($obis->{name},$value)
    	}
    	&knx_write ($ga,$value,$obis->{dpt});
    	}
    	}
    }
    
    ### SUBS ###
    
    sub rrd_counter
    {
    print ("COUNTER","\n");
    foreach (@countermodes)
    {
    my $obisname = $_[0];
    my $value = $_[1];
    $obisname =~ tr/./-/;
    my $rrdname = $counterid."_".$obisname."_".$_."\.rrd";
    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
    {
    print ("GAUGE","\n");
    my $obisname = $_[0];
    my $value = $_[1];
    $obisname =~ tr/./-/;
    my $rrdname = $counterid."_".$obisname."\.rrd";
    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 {
        use feature "switch";
        use EIBConnection;
        my $eib_url = "local:/tmp/eib";
        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:


  • Frank0207
    antwortet
    Sowas dachte...

    ...ich mir schon. Leider sind meine momentanen PERL Kenntnisse und überhaupt die Plugin's noch Neuland. Ich war schon froh das ich das zum Laufen gebracht habe.

    Du hast also den Code von makki eingebunden und konntest somit den Zählerstand angemessen darstellen?
    Dann versuch ich mal auch den Teil anzupassen.
    Was hat jetzt das Auslesen mit der DPT14 Konvertierung zu tun?
    Weshalb der Rücksprung zur ersten Abfrage?

    @lio123: Ich nutze momentan die Version aus'm SVN bzw. hier aus'm Forum mit der Version 0.1.6

    Hier das Ergebnis was der Zähler ausspuckt:

    Code:
    /ELS5\@V9.30
    1-1:F.F(00000000)
    1-1:0.0.0(00350358)
    1-1:0.9.1(190449)
    1-1:0.9.2(130212)
    1-1:0.1.0(15)
    1-1:1.7.0(0.413*kW)
    1-1:1.8.1(0005332.0*kWh)
    1-1:1.8.1*01(0005218.0*kWh)
    1-1:1.8.1*12(0004946.6*kWh)
    1-1:1.8.1*11(0004572.0*kWh)
    1-1:1.8.1*10(0004237.9*kWh)
    1-1:1.8.1*09(0003887.9*kWh)
    1-1:1.8.1*08(0003584.7*kWh)
    1-1:1.8.1*07(0003317.9*kWh)
    1-1:1.8.1*06(0003030.5*kWh)
    1-1:1.8.1*05(0002728.1*kWh)
    1-1:1.8.1*04(0002422.9*kWh)
    1-1:1.8.1*03(0002075.2*kWh)
    1-1:1.8.1*02(0001813.1*kWh)
    1-1:1.8.2(0000000.0*kWh)
    1-1:1.8.2*01(0000000.0*kWh)
    1-1:1.8.2*12(0000000.0*kWh)
    1-1:1.8.2*11(0000000.0*kWh)
    1-1:1.8.2*10(0000000.0*kWh)
    1-1:1.8.2*09(0000000.0*kWh)
    1-1:1.8.2*08(0000000.0*kWh)
    1-1:1.8.2*07(0000000.0*kWh)
    1-1:1.8.2*06(0000000.0*kWh)
    1-1:1.8.2*05(0000000.0*kWh)
    1-1:1.8.2*04(0000000.0*kWh)
    1-1:1.8.2*03(0000000.0*kWh)
    1-1:1.8.2*02(0000000.0*kWh)
    1-1:1.8.3(0000000.0*kWh)
    1-1:1.8.3*01(0000000.0*kWh)
    1-1:1.8.3*12(0000000.0*kWh)
    1-1:1.8.3*11(0000000.0*kWh)
    1-1:1.8.3*10(0000000.0*kWh)
    1-1:1.8.3*09(0000000.0*kWh)
    1-1:1.8.3*08(0000000.0*kWh)
    1-1:1.8.3*07(0000000.0*kWh)
    1-1:1.8.3*06(0000000.0*kWh)
    1-1:1.8.3*05(0000000.0*kWh)
    1-1:1.8.3*04(0000000.0*kWh)
    1-1:1.8.3*03(0000000.0*kWh)
    1-1:1.8.3*02(0000000.0*kWh)
    1-1:1.8.4(0000000.0*kWh)
    1-1:1.8.4*01(0000000.0*kWh)
    1-1:1.8.4*12(0000000.0*kWh)
    1-1:1.8.4*11(0000000.0*kWh)
    1-1:1.8.4*10(0000000.0*kWh)
    1-1:1.8.4*09(0000000.0*kWh)
    1-1:1.8.4*08(0000000.0*kWh)
    1-1:1.8.4*07(0000000.0*kWh)
    1-1:1.8.4*06(0000000.0*kWh)
    1-1:1.8.4*05(0000000.0*kWh)
    1-1:1.8.4*04(0000000.0*kWh)
    1-1:1.8.4*03(0000000.0*kWh)
    1-1:1.8.4*02(0000000.0*kWh)
    1-1:1.9.0(0000114.0*kWh)
    1-1:1.9.0*01(0000271.3*kWh)
    1-1:1.9.0*12(0000374.5*kWh)
    1-1:1.9.0*11(0000334.1*kWh)
    1-1:1.9.0*10(0000350.0*kWh)
    1-1:1.9.0*09(0000303.2*kWh)
    1-1:1.9.0*08(0000266.7*kWh)
    1-1:1.9.0*07(0000287.4*kWh)
    1-1:1.9.0*06(0000302.3*kWh)
    1-1:1.9.0*05(0000305.1*kWh)
    1-1:1.9.0*04(0000347.7*kWh)
    1-1:1.9.0*03(0000262.0*kWh)
    1-1:1.9.0*02(0001813.1*kWh)
    1-1:1.9.1(0000114.0*kWh)
    1-1:1.9.1*01(0000271.3*kWh)
    1-1:1.9.1*12(0000374.5*kWh)
    1-1:1.9.1*11(0000334.1*kWh)
    1-1:1.9.1*10(0000350.0*kWh)
    1-1:1.9.1*09(0000303.2*kWh)
    1-1:1.9.1*08(0000266.7*kWh)
    1-1:1.9.1*07(0000287.4*kWh)
    1-1:1.9.1*06(0000302.3*kWh)
    1-1:1.9.1*05(0000305.1*kWh)
    1-1:1.9.1*04(0000347.7*kWh)
    1-1:1.9.1*03(0000262.0*kWh)
    1-1:1.9.1*02(0001813.1*kWh)
    1-1:1.9.2(0000000.0*kWh)
    1-1:1.9.2*01(0000000.0*kWh)
    1-1:1.9.2*12(0000000.0*kWh)
    1-1:1.9.2*11(0000000.0*kWh)
    1-1:1.9.2*10(0000000.0*kWh)
    1-1:1.9.2*09(0000000.0*kWh)
    1-1:1.9.2*08(0000000.0*kWh)
    1-1:1.9.2*07(0000000.0*kWh)
    1-1:1.9.2*06(0000000.0*kWh)
    1-1:1.9.2*05(0000000.0*kWh)
    1-1:1.9.2*04(0000000.0*kWh)
    1-1:1.9.2*03(0000000.0*kWh)
    1-1:1.9.2*02(0000000.0*kWh)
    1-1:1.9.3(0000000.0*kWh)
    1-1:1.9.3*01(0000000.0*kWh)
    1-1:1.9.3*12(0000000.0*kWh)
    1-1:1.9.3*11(0000000.0*kWh)
    1-1:1.9.3*10(0000000.0*kWh)
    1-1:1.9.3*09(0000000.0*kWh)
    1-1:1.9.3*08(0000000.0*kWh)
    1-1:1.9.3*07(0000000.0*kWh)
    1-1:1.9.3*06(0000000.0*kWh)
    1-1:1.9.3*05(0000000.0*kWh)
    1-1:1.9.3*04(0000000.0*kWh)
    1-1:1.9*3000000.k:930(00.*W1..(00*W)111.9*(000.kh
    :1.00kh
    -1941000.*)
    -:.4*100*k)
    11.490000*h
    -9402(00.*Wh9*4000.*111.*0000*kWh)
    root@wiregate907:/home/kWh/old#
    Grüsse Frank

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Zitat von Frank0207 Beitrag anzeigen
    Beim Beobachten habe ich festgestellt, dass der Wert richtig in der Konsole angezeigt wird, jedoch beim Schreiben auf die GA bleibt der alte Wert vorhanden. Das erste Beschreiben der der GA funktioniert, danach wird die GA erst bei einer Abweichung von 5kW im Gesamtzählerstand neu beschrieben.

    Kennt einer so ein Verhalten bzw. an was kann das liegen?

    Grüße

    Frank
    Hallo Frank,

    ja das liegt am DPT9 ... der ist für sowas zu ungenau. Die RRDs werden glücklicherweise direkt im Plugin erstellt.
    Ich hab mein Script auf DPT14 umgestellt, ist allerdings noch nicht im SVN ... die Subroutinen hab ich mir dazu bei makkis wiregated "geborgt".

    Falls ich es schaffe mach ich die Tage mal ein SVN Update. Aufgrund noch unerforschter Probleme bin ich wieder bei der ersten Revision des Auslesescriptes. Diese ist zwar langsamer aber zuverlässiger (zumindest auf dem WireGate). Deshalb ist es auch noch nicht im SVN ...

    Grüße

    EDIT: Hier hab ich das mal verfolgt https://knx-user-forum.de/wiregate/2...schreiben.html

    Einen Kommentar schreiben:


  • lio123
    antwortet
    Hallo Frank,

    könntest mal Dein Plugin und einen Datensatz Deines Zählers zur Verfügung stellen?
    Danke und Gruß,
    Lio

    Einen Kommentar schreiben:


  • Frank0207
    antwortet
    Hallo an alle,

    habe die Zählerabfrage an einem Elster AS1440 am Laufen.
    Bekomme Daten von Zählerstand, Momentane Leistung und Monatlicher Verbrauch. Zudem kann man noch die Historie der Verbräuche vom letzten Jahr abrufen.

    Alles funktioniert, außer das Update des Gesamtzählerstandes. Am Anfang dachte ich es handelt sich um die von JuMi2006 angesprochene Abweichung.

    Zitat von JuMi2006 Beitrag anzeigen
    So...mein erstes Plugin ;-)
    ...
    2. Der Wert aus dem Log/Konsole (1774,9) stimmt nicht 100% mit dem Bus überein 1774,08) !?
    ...
    }[/CODE]
    Beim Beobachten habe ich festgestellt, dass der Wert richtig in der Konsole angezeigt wird, jedoch beim Schreiben auf die GA bleibt der alte Wert vorhanden. Das erste Beschreiben der der GA funktioniert, danach wird die GA erst bei einer Abweichung von 5kW im Gesamtzählerstand neu beschrieben.

    Kennt einer so ein Verhalten bzw. an was kann das liegen?

    Grüße

    Frank

    Einen Kommentar schreiben:


  • hgestel
    antwortet
    Perl script Jumi2006 used for Iskra MT171

    With succes I used the per script from Jumi after 2 weeks of strugling.
    used Raspberry pi, 2 ir heads from Udo.

    Perl script:
    # JuMi2006 / www.knx-user-forum.de
    # Version: 0.1.3
    # Datum: 23.04.2012

    I had to adjust the timing used in the script.

    ####START 300baud
    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->dtr_active(0);
    $port->rts_active(0);
    $port->read_char_time(006); # 0.006 seconds for each character
    #$port->read_const_time(400); # 1 second per unfulfilled "read" call
    $port->write_settings || die 'fail write settings';


    Maybe this helps others with the same problem.
    thanks to Jumi

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Naja so schwer ist es ja nicht ... momentan hab ich bloss einfach keine Zeit da tiefer einzusteigen ... die Charts/RRDs fallen da eher mit ab bzw. kann man sich dann ja auch aus der GA erzeugen lassen.

    Wie gesagt guck mal ob du mit socket_subscribe was machen kannst...da finden sich viele Beispielplugins hier!

    Gruß

    Einen Kommentar schreiben:


  • mikeeyy
    antwortet
    Hallo Mirko,

    danke dennoch für die bisherige Unterstützung. Ich werde mich mal weiter an dem Script probieren. Meine Anforderungen sind eigentlich gering. Der Zählerstand vom WP Zähler reicht und dann auch nur als Zahl. Chart brauche ich gar nicht.So ich Fortschritte machen sollte, stelle ich diese hier ein.

    Grüße,
    Mike

    Einen Kommentar schreiben:

Lädt...
X