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

    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

    Kommentar


      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

      Kommentar


        Hallo Frank,

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

        Kommentar


          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
          Umgezogen? Ja! ... Fertig? Nein!
          Baustelle 2.0 !

          Kommentar


            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

            Kommentar


              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;
              }
              Umgezogen? Ja! ... Fertig? Nein!
              Baustelle 2.0 !

              Kommentar


                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.

                Kommentar


                  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
                  Umgezogen? Ja! ... Fertig? Nein!
                  Baustelle 2.0 !

                  Kommentar


                    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

                    Kommentar


                      @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
                      Umgezogen? Ja! ... Fertig? Nein!
                      Baustelle 2.0 !

                      Kommentar


                        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

                        Kommentar


                          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 ?
                          Umgezogen? Ja! ... Fertig? Nein!
                          Baustelle 2.0 !

                          Kommentar


                            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

                            Kommentar


                              Halt, Stop, Langsam

                              Ist doch schon alles fertig. Nimm das Script hier:

                              HIER KLICKEN:
                              https://knx-user-forum.de/292600-post261.html

                              Und nur das !!!

                              Dort passt Du unter Channels DEINE Werte an die Du auslesen möchtest (Schema liegt ja vor). Und trägst noch die richtige Geschwindigkeit, Schnittstelle etc. ein.
                              Also fasse nur den Bereich bis ### ENDE KONFIGURATION ### an.

                              Fertig!

                              Was ist daran so schwierig?

                              Alles andere ist alter Tobak.
                              Umgezogen? Ja! ... Fertig? Nein!
                              Baustelle 2.0 !

                              Kommentar


                                AW: Zählerabfrage als Wiregate Plugin

                                na ja. mein Problem ist ja immer noch, dass mein Zähler alle 10 Sekunden selber sendet und das funzt mit der socat Abfrage nicht. die while Schleife im gepostet Script macht das aber perfekt. ohne die werde ich es wohl nicht zum laufen bekommen, denke ich.

                                Grüße
                                Mike

                                Gesendet von meinem GT-P1000 mit Tapatalk 2

                                Kommentar

                                Lädt...
                                X