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

    So ... da isses: https://knx-user-forum.de/352354-post88.html
    Umgezogen? Ja! ... Fertig? Nein!
    Baustelle 2.0 !

    Kommentar


      Zitat von JuMi2006 Beitrag anzeigen
      Versuchs mal hiermit....klingt nach SML-Protokoll, oder den Thread mal nach SML durchsuchen.

      Open Automation / Code / [r1702] /tools/sml-meter/sml_meter.pl
      Dieses Plugin funktioniert mit dem volkszaehler ir-lesekopf super! Wo in dem Code muss ich meinen aktuellen Zählerstand eintragen, damit der Counter diesen dann hoch zählt?

      Danke

      Kommentar


        Normalerweise bekommst du per SML Protokoll den aktuellen Zäherstand. Da muss nichts hochgezählt werden.

        Ich hänge mal meine aktuelle Version dran. Ich hatte seinerzeit das PlugIn erweitert, so dass weniger Konfiguration nötig ist.
        Ich muss mir doch mal meinen Account bei sourceforge freischalten lassen, damit der ganze Kram nicht verloren geht

        Außerdem benutze ich kein COUNTER RRD sonder DERIVE. Mit den COUNTER RRDs hatte ich Probleme mit Wertüberläufen.

        Ach ja, das Ganze läuft als Crontab, nicht als wiregate PlugIn.

        Gruß

        Code:
        #!/usr/bin/perl
        #
        # Autor: coolrunnings / www.knx-user-forum.de
        # Based on the PlugIn sml-meter by JuMi2006 / www.knx-user-forum.de
        # knx_write sub: makki / www.knx-user-forum.de
        # Version: 0.2
        # Datum: 03.11.2013
        
        use warnings;
        use strict;
        use Device::SerialPort;
        use feature "switch";
        use EIBConnection;
        use RRDs;
        use Scalar::Util qw(looks_like_number);
        
        #####################################################################
        # define everything here
        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",  ga =>"9/0/0", dpt =>  14, rrd_name => "zaehler_verbrauch"}; 
        push @obis,{obis=>"16.7.0", ga =>"9/0/1", dpt =>  9, rrd_name => "zaehler_leistung" };
        push @obis,{obis=>"36.7.0", ga =>"9/0/2", dpt =>  9, rrd_name => "zaehler_leistung_L1"};
        push @obis,{obis=>"56.7.0", ga =>"9/0/3", dpt =>  9, rrd_name => "zaehler_leistung_L2"};
        push @obis,{obis=>"76.7.0", ga =>"9/0/4", dpt =>  9, rrd_name => "zaehler_leistung_L3"};
        my @countermodes = (5,15,60,1440);    #Aufloesungen fuer COUNTER RRDs in Minuten (1440 = Tagesverbrauch)
        my @derivemodes = (5,15,60,1440);    #Aufloesungen fuer DERIVE RRDs in Minuten (1440 = Tagesverbrauch)
        
        my $debug   = "1";
        my $logging = "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
        
        #####################################################################
        # don't touch anything after this point
        
        my $filename = "/tmp/sml_meter.log";
        if ( $logging == "1" ) {open (LOG, ">>$filename") or $logging = "0";}
        
        if ( $logging == "1" ) {print LOG "===============================================\n";}
        if ( $logging == "1" ) {print LOG (localtime)." Start new run\n";}
        
        
        my ($x,$rawdata) = 0 ;
        my $count = 0;
        my $saw = 0;
        my $start = 0;
        
        if ($debug == 1) {print "Step 1 - Collect data \n";}
        if ($logging == 1) {print LOG "Step 1 - Collect data \n";}
        
        while ($start < 2) {	# wait for second 1B1B1B1B01010101
           
        	($count,$saw)=$port->read(512);  # will read 512 chars
        	if ($count == 512) {       		# 512 chars read?
        		$x = uc(unpack('H*',$saw)); # nach hex wandeln
        		$rawdata .= $x;
        		if ($rawdata =~ /1B1B1B1B01010101/)  {$start ++};
        	} # if
        }  # while
        
        if ($debug==1) {print "Step 2 - Reg Exp 1 build dataset \n";}
        if ($logging==1) {print LOG "Step 2 - Reg Exp 1 build dataset \n";}
        
        $rawdata =~ m/1B1B1B1B01010101(.*?)B1B1B1/;
        #print $rawdata ."\n";
        
        if ($debug==1) {print "Step 3 - Analyze data \n";}
        if ($logging==1) {print LOG "Step 3 - Analyze data \n";}
        
        # find OBIS values in raw data
        foreach my $obiscnt (@obis) {
        	if ( $debug == 1 ) {print "\n";}
        	if ( $logging == 1 ) {print LOG "-----------------------------------------------\n";}
        	my $obissearch = &obis2search($obiscnt->{obis});
        	
        	$rawdata =~ m/$obissearch(.*?)017707/;
        	my $obisdata = $1."01";
        	
        	print "found: ".$obisdata."\n";
        	
        	my $smlStatus  = "";
        	my $smlValTime = "";
        	my $smlUnit    = "";
        	my $smlScaler  = "";
        	my $smlValue   = "";
        	my $smlValueS  = "";
        	
        	## check status
        	if ( $debug == 1 ) {print "check sml status:          ";}
        	if ( $logging == 1 ) {print LOG "check sml status:          ";}
        	$smlStatus = &parseOBIS(\$obisdata);
        	
        	## check value time
        	if ( $debug == 1 ) {print "check sml value time:      ";}
        	if ( $logging == 1 ) {print LOG "check sml value time:      ";}
        	$smlValTime = &parseOBIS(\$obisdata);
        	
        	## check unit
        	if ( $debug == 1 ) {print "check sml unit:            ";}
        	if ( $logging == 1 ) {print LOG "check sml unit:            ";}
        	$smlUnit = &parseOBIS(\$obisdata);
        	
        	## check scaler
        	if ( $debug == 1 ) {print "check sml scaler:          ";}
        	if ( $logging == 1 ) {print LOG "check sml scaler:          ";}
        	$smlScaler = &parseOBIS(\$obisdata);
        	
        	## check value
        	if ( $debug == 1 ) {print "check sml value:           ";}
        	if ( $logging == 1 ) {print LOG "check sml value:           ";}
        	$smlValue = &parseOBIS(\$obisdata);
        	
        	## check value signature
        	if ( $debug == 1 ) {print "check sml value signature: ";}
        	if ( $logging == 1 ) {print LOG "check sml value signature: ";}
        	$smlValueS = &parseOBIS(\$obisdata);
        
        	#print "done: ".$obisdata."\n";
        	#print  $smlStatus;
        	
        	# Calculate value
        	if ( $smlValue ne "" ) {
        		my $calcvalue  = ($smlValue * (10**$smlScaler));
        		
        		# Modify value depening on unit
        		my $smlUnitCfg_ref = &getSMLUnitStr($smlUnit);
        		my @smlUnitCfg = @{$smlUnitCfg_ref};
        		
        		if ( (@smlUnitCfg) == 2 ) {
        			my $tUnitStr  = $smlUnitCfg[0];
        			my $tUnitRRD  = $smlUnitCfg[1];
        			
        			# Wh to kWh
        			if ( $smlUnit == 30  ) {
        				$calcvalue = $calcvalue * 0.001;
        				$tUnitStr  = "kWh";
        			}
        			
        			if ( $debug == 1 ) {print "Unit config: [".$tUnitStr."][".$tUnitRRD."]\n";}
        			if ( $logging == 1 ) {print LOG "Unit config: [".$tUnitStr."][".$tUnitRRD."]\n";}
        			
        			if ( $debug == 1 ) {print "Final value: [".$calcvalue." ".$tUnitStr."]\n";}
        			if ( $logging == 1 ) {print LOG "Final value: [".$calcvalue." ".$tUnitStr."]\n";}
        		
        			# write rrd
        			if ($tUnitRRD =~ m/c/) {
        				&rrd_counter ($obiscnt->{rrd_name},$calcvalue)
        			}
        			
        			if ($tUnitRRD =~ m/d/) {
        				&rrd_derive ($obiscnt->{rrd_name},$calcvalue)
        			}
        			
        			if ($tUnitRRD =~ m/g/) {
        				&rrd_gauge ($obiscnt->{rrd_name},$calcvalue)
        			}
        
        			# send value to bus
        			&knx_write ($obiscnt->{ga},$calcvalue,$obiscnt->{dpt});
        			if ($debug == 1) {print "GA:".$obiscnt->{ga}." value:".$calcvalue." DPT:".$obiscnt->{dpt}."\n";}
        			if ($logging == 1) {print LOG "GA:".$obiscnt->{ga}." value:".$calcvalue." DPT:".$obiscnt->{dpt}."\n";}
        				
        				
        		}
        		else {
        			if ( $debug == 1 ) {print "No unit found. No data will be written.\n";}
        			if ( $logging == 1 ) {print LOG "No unit found. No data will be written.\n";}
        		}
        	}	
        }
        
        $port->close() || warn "Serial port did not close proper!\n";
        undef $port;
        
        if ( $logging == "1" ) {close LOG;}
        
        ## subs ##
        
        #####################################################################
        # convert OBIS to search parameter
        sub obis2search {
        
        	my ($obisid) = @_;
        	my $res = "77070100";
        	
        	if ($debug==1) { print "OBIS ID:     ".$obisid."\n";}
        	if ($logging==1) { print LOG "OBIS ID:     ".$obisid."\n";}
        		
        	foreach my $c ( split(/\./,$obisid) ) {
        		$res .= sprintf("%02X",$c);
        	}
        	
        	$res .= "FF";
        	
        	if ($debug==1) { print "OBIS search: ".$res."\n";}
        	if ($logging==1) { print LOG "OBIS search: ".$res."\n";}
        	
        	return $res;
        }
        
        #####################################################################
        # parse OBIS data
        sub parseOBIS {
        	#my ($obisdata) = @_;
        	my $r_obisdata = shift;
        	my $res = "";
        	
        	if ( length($$r_obisdata) < 2 ) {
        		print "error --> data too short\n";
        		return $res;
        	}
        	
        	my $smlDataTypeID = substr($$r_obisdata,0,2); 
        	
        	if ( $smlDataTypeID == "01" ) {
        		## no data
        		if ( $debug == 1 ) {print "[empty]\n";}
        		if ( $logging == 1 ) {print LOG "[empty]\n";}
        		$$r_obisdata =~ s/^..//;	# remove first 2 characters
        		return $res;
        	}
        	else {
        		#if ( $debug == 1 ) {print "found something ";}
        		#if ( $logging == 1 ) {print LOG "found something ";}
        		
        		my $smlDataType    = substr($smlDataTypeID,0,1);
        		my $smlIntBitCode = substr($smlDataTypeID,1,1);
        		
        		# only signed and unsigned int possible
        		if ( $smlDataType != "5" && $smlDataType != "6") {
        			if ( $debug == 1 ) {print "Invalid datatype [".$smlDataType."]\n"; };
        			if ( $logging == 1 ) {print LOG "Invalid datatype [".$smlDataType."]\n"; };
        			return $res;
        		}
        		
        		$$r_obisdata =~ s/^..//;	# remove first 2 characters
        		
        		
        		my $smlIntBitCnt = 0;
        		
        		#switch ( $smlIntBitCode ) {
        		#	case 2	{ $smlIntBitCnt =  8 }
        		#	case 3	{ $smlIntBitCnt = 16 }
        		#	case 5	{ $smlIntBitCnt = 32 }
        		#	case 9	{ $smlIntBitCnt = 64 }
        		#	else  	{ if ( $debug == 1 ) {print "Invalid integer bit count [".$smlIntBitCode."]\n"; };
        		#			  return $res; 
        		#			}
        		#}
        		
        		if ( $smlIntBitCode == 2 ) {
        			$smlIntBitCnt =  8
        		}
        		elsif ( $smlIntBitCode == 3 ) {
        			$smlIntBitCnt =  16
        		}
        		elsif ( $smlIntBitCode == 5 ) {
        			$smlIntBitCnt =  32
        		}
        		elsif ( $smlIntBitCode == 9 ) {
        			$smlIntBitCnt =  64
        		}
        		else {
        			if ( $debug == 1 ) {print "Invalid integer bit count [".$smlIntBitCode."]\n"; };
        			if ( $logging == 1 ) {print LOG "Invalid integer bit count [".$smlIntBitCode."]\n"; };
        			return $res;
        		}
        		
        		my $smlIntCharCnt = ($smlIntBitCnt/4);
        		
        		# check that the rest of the string is long enought for the bit count
        		if ( (length($$r_obisdata)) < $smlIntCharCnt ) {
        			if ( $debug == 1 ) {print "String not long enough for for detected bit count [".$smlIntCharCnt."]\n"; };
        			if ( $logging == 1 ) {print LOG "String not long enough for for detected bit count [".$smlIntCharCnt."]\n"; };
        			return $res;
        		}
        		
        		# get the hex values
        		my $hexval = substr($$r_obisdata,0,$smlIntCharCnt);
        		$$r_obisdata = substr($$r_obisdata,$smlIntCharCnt);
        		
        		# if signed, get 2' complement
        		if ( $smlDataType == 5 ) {
        			my $hexbin = sprintf("%0${smlIntBitCnt}b",hex($hexval));
        		
        			if ( substr($hexbin,0,1) == 1 ) {
        				#if ( $debug == 1 ) { print "2's complement \n"; }
        				#if ( $logging == 1 ) { print LOG "2's complement \n"; }
        				my $hexinv = sprintf("%08x",~hex($hexval));
        				$res = (substr($hexinv,6,2)+1)*(-1);
        			
        			}
        			else {
        				$res = hex($hexval);
        			}
        		}
        		else {
        			$res = hex($hexval);
        		}
        		
        		if ( $debug == 1 ) { print "[".$res."]\n";}
        		if ( $logging == 1 ) { print LOG "[".$res."]\n";}
        		
        		return $res;
        	}
        	
        	return $res;
        }
        
        #####################################################################
        # get SML unit string depending on value
        # DLMS Units as specified in ISO EN 62056-62 and used by SML
        # original values from unit.h in vzlogger project
        # The volkszaehler.org project
        sub getSMLUnitStr {
        
        	my ($smlUnitCode) = @_;
        	
        	my %unitmap = (	
        	# code	  # unit		#rrd		# quantity						#name					#SI definition
        	
        	1 => 	[ "a",			"g" ],      # time                			year            		52*7*24*60*60 s
        	2 => 	[ "mo",			"g" ],      # time                			month            		31*24*60*60 s
        	3 => 	[ "wk",			"g" ],      # time                			week            		7*24*60*60 s
        	4 => 	[ "d",			"g" ],      # time                			day            			24*60*60 s
        	5 => 	[ "h",			"g" ],      # time                			hour            		60*60 s
        	6 => 	[ "min.",		"g" ],      # time                			min            			60 s
        	7 => 	[ "s",			"g" ],      # time (t)            			second            		s
        	8 => 	[ "°",			"g" ],      # (phase) angle        			degree            		rad*180/π
        	9 => 	[ "°C",			"g" ],      # temperature (T)       		degree celsius      	K-273.15
        	10 => 	[ "currency",	"g" ],    	# (local) currency
        	11 => 	[ "m",			"g" ],      # length (l)            		metre            		m
        	12 => 	[ "m/s",		"g" ],      # speed (v)            			metre per second    	m/s
        	13 => 	[ "m³",			"g" ],      # volume (V)            		cubic metre        		m³
        	14 => 	[ "m³",			"g" ],      # corrected volume      		cubic metre        		m³
        	15 => 	[ "m³/h",		"g" ],      # volume flux           		cubic metre per hour    m³/(60*60s)
        	16 => 	[ "m³/h",		"g" ],      # corrected volume flux 		cubic metre per hour    m³/(60*60s)
        	17 => 	[ "m³/d",		"g" ],      # volume flux                        					m³/(24*60*60s)
        	18 => 	[ "m³/d",		"g" ],      # corrected volume flux                					m³/(24*60*60s)
        	19 => 	[ "l",			"g" ],      # volume            			litre            		10-3 m³
        	20 => 	[ "kg",			"g" ],      # mass (m)            			kilogram
        	21 => 	[ "N",			"g" ],      # force (F)            			newton
        	22 => 	[ "Nm",			"g" ],      # energy            			newtonmeter        		J = Nm = Ws
        	23 => 	[ "Pa",			"g" ],      # pressure (p)          		pascal            		N/m²
        	24 => 	[ "bar",		"g" ],      # pressure (p)          		bar            			10⁵ N/m²
        	25 => 	[ "J",			"g" ],      # energy            			joule            		J = Nm = Ws
        	26 => 	[ "J/h",		"g" ],      # thermal power        			joule per hour        	J/(60*60s)
        	27 => 	[ "W",			"g" ],      # active power (P)      		watt            		W = J/s
        	28 => 	[ "VA",			"g" ],      # apparent power (S)    		volt-ampere
        	29 => 	[ "var",		"g" ],      # reactive power (Q)    		var
        	30 => 	[ "Wh",			"cdg" ],    # active energy        			watt-hour        		W*(60*60s)
        	31 => 	[ "VAh",		"g" ],      # apparent energy       		volt-ampere-hour    	VA*(60*60s)
        	32 => 	[ "varh",		"g" ],      # reactive energy       		var-hour        		var*(60*60s)
        	33 => 	[ "A",			"g" ],      # current (I)           		ampere            		A
        	34 => 	[ "C",			"g" ],      # electrical charge (Q) 		coulomb            		C = As
        	35 => 	[ "V",			"g" ],      # voltage (U)           		volt            		V
        	36 => 	[ "V/m",		"g" ],      # electr. field strength (E)    volt per metre
        	37 => 	[ "F",			"g" ],      # capacitance (C)       		farad            		C/V = As/V
        	38 => 	[ "Ω",			"g" ],      # resistance (R)        		ohm            			Ω = V/A
        	39 => 	[ "Ωm²/m",		"g" ],      # resistivity (ρ)       		Ωm
        	40 => 	[ "Wb",			"g" ],      # magnetic flux (Φ)     		weber            		Wb = Vs
        	41 => 	[ "T",			"g" ],      # magnetic flux density (B)    	tesla            		Wb/m2
        	42 => 	[ "A/m",		"g" ],      # magnetic field strength (H)   ampere per metre    	A/m
        	43 => 	[ "H",			"g" ],      # inductance (L)        		henry            		H = Wb/A
        	44 => 	[ "Hz",			"g" ],      # frequency (f => ω)        	hertz            		1/s
        	45 => 	[ "1/(Wh)",		"g" ],      # R_W                           (Active energy meter constant or pulse value)
        	46 => 	[ "1/(varh)",	"g" ],     	# R_B                           (reactive energy meter constant or pulse value)
        	47 => 	[ "1/(VAh)",	"g" ],    	# R_S                           (apparent energy meter constant or pulse value)
        	48 => 	[ "V²h",		"g" ],      # volt-squared hour        	´	volt-squaredhours    	V²(60*60s)
        	49 => 	[ "A²h",		"g" ],      # ampere-squared hour        	ampere-squaredhours    	A²(60*60s)
        	50 => 	[ "kg/s",		"g" ],      # mass flux            			kilogram per second    	kg/s
        	51 => 	[ "S => mho",	"g" ],     	# conductance siemens                    				1/Ω
        	52 => 	[ "K",			"g" ],     	# temperature (T)        		kelvin
        	53 => 	[ "1/(V²h)",	"g" ],    	# R_U²h                        (Volt-squared hour meter constant or pulse value)
        	54 => 	[ "1/(A²h)",	"g" ],    	# R_I²h                        (Ampere-squared hour meter constant or pulse value)
        	55 => 	[ "1/m³",		"g" ],      # R_V => meter constant or pulse value (volume)
        	56 => 	[ "%",			"g" ],      # percentage            		%
        	57 => 	[ "Ah",			"g" ],      # ampere-hours            		ampere-hour
        	60 => 	[ "Wh/m³",		"g" ],      # energy per volume                    					3,6*103 J/m³
        	61 => 	[ "J/m³",		"g" ],      # calorific value, wobbe
        	62 => 	[ "Mol %",		"g" ],      # molar fraction of        		mole percent    (Basic gas composition unit)
        										# gas composition  
        	63 => 	[ "g/m³",		"g" ],      # mass density, quantity of material            (Gas analysis => accompanying elements)
        	64 => 	[ "Pa s",		"g" ],      # dynamic viscosity pascal second       		(Characteristic of gas stream)
        	253 => 	[ "(reserved)",	"g"],		# reserved
        	254 => 	[ "(other)",	"g" ],    	# other unit
        	255 => 	[ "(unitless)",	"g"]   	# no unit, unitless, count
        	);
        	
        	#print "-------- unit ".$unitmap{$smlUnitCode}[0]."\n";
        	
        	#print "-------- unit ".$unitmap{$smlUnitCode}."\n";
        	
        	my $unitarray_ref = $unitmap{$smlUnitCode};
        	
        	return $unitarray_ref;
        	
        }
        
        #####################################################################
        
        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;
        }
        
        #####################################################################
        
        sub rrd_counter
        {
            if ($debug==1){print ("COUNTER","\n")};
        	if ($logging==1){print LOG ("-- COUNTER ---","\n")};
        	
        	my $obisname = $_[0];
        	if ($debug==1){print "obisname  ".$obisname."\n";}
        	if ($logging==1){print LOG "obisname  ".$obisname."\n";}
        	my $value = $_[1];
            if ($debug==1){print "value     ".$value."\n";}
        	if ($logging==1){print LOG "value     ".$value."\n";}
            
            foreach (@countermodes)
            {
                my $rrdname = $obisname."_".$_."_c\.rrd";
                if ($debug==1){print "rrdname   ".$rrdname."\n"};
        		if ($logging==1){print LOG "----------\n"};
        		if ($logging==1){print LOG "rrdname   ".$rrdname."\n"};
                my $rrdfile = $rrdpath."\/".$rrdname;
                unless (-e $rrdfile)
                {
                    RRDs::create ($rrdfile,"DS:value:COUNTER:".(($_*60)+600).":0:U",
        			"RRA:AVERAGE:0.5:1:366",	
        			"RRA:AVERAGE:0.5:7:1308",
        			"-s ".($_*60));				# step 
                }
                my $countervalue = int($value*$_*60);
        		if ($debug==1){print "[".$value."]*[".$_."]*[60] = ".$countervalue." countervalue \n";}
        		if ($logging==1){print LOG "[".$value."]*[".$_."]*[60] = ".$countervalue." countervalue \n";}
                RRDs::update("$rrdfile", "N:$countervalue");
            }
        }
        
        sub rrd_derive
        {
            if ($debug==1){print ("DERIVE","\n")};
        	if ($logging==1){print LOG ("-- DERIVE ---","\n")};
        	
        	my $obisname = $_[0];
        	if ($debug==1){print "obisname  ".$obisname."\n";}
        	if ($logging==1){print LOG "obisname  ".$obisname."\n";}
        	my $value = $_[1];
            if ($debug==1){print "value     ".$value."\n";}
        	if ($logging==1){print LOG "value     ".$value."\n";}
            
            foreach (@derivemodes)
            {
                my $rrdname = $obisname."_".$_."_d\.rrd";
                if ($debug==1){print "rrdname   ".$rrdname."\n"};
        		if ($logging==1){print LOG "----------\n"};
        		if ($logging==1){print LOG "rrdname   ".$rrdname."\n"};
                my $rrdfile = $rrdpath."\/".$rrdname;
                unless (-e $rrdfile)
                {
                    RRDs::create ($rrdfile,"DS:value:DERIVE:".(($_*60)+600).":0:U",
        			"RRA:AVERAGE:0.5:1:366",	
        			"RRA:AVERAGE:0.5:7:1308",
        			"-s ".($_*60));				# step 
                }
                my $derivevalue = int($value*$_*60);
        		if ($debug==1){print "[".$value."]*[".$_."]*[60] = ".$derivevalue." derivevalue \n";}
        		if ($logging==1){print LOG "[".$value."]*[".$_."]*[60] = ".$derivevalue." derivevalue \n";}
                RRDs::update("$rrdfile", "N:$derivevalue");
            }
        }
        
        #####################################################################
        
        sub rrd_gauge
        {
            if ($debug==1){print ("GAUGE","\n")};
        	if ($logging==1){print LOG ("-- GAUGE --","\n")};
            my $obisname = $_[0];
            if ($debug==1){print "obisname  ".$obisname."\n";}
        	if ($logging==1){print LOG "obisname  ".$obisname."\n";}
        	my $value = $_[1];
            if ($debug==1){print "value     ".$value."\n";}
        	if ($logging==1){print LOG "value     ".$value."\n";}
            my $rrdname = $obisname."_g\.rrd";
            if ($debug==1){print "rrdname   ".$rrdname."\n"};
        	if ($logging==1){print LOG "rrdname   ".$rrdname."\n"};
            my $rrdfile = $rrdpath."\/".$rrdname;
            unless (-e $rrdfile)
            {
                RRDs::create ($rrdfile,"DS:value:GAUGE:900:0:U",
        		"RRA:AVERAGE:0.5:1:2016",		# 5 minutes for 7 days
        		"RRA:AVERAGE:0.5:6:1488",		# 30 minutes for 31 days
        		"RRA:AVERAGE:0.5:12:4392",		# 1 hour for 5 month
        		"RRA:AVERAGE:0.5:72:7320",		# 6 hours for 5 years
        		"RRA:AVERAGE:0.5:2016:1308");	# 1 day for 25 years	
            }
            RRDs::update("$rrdfile", "N:$value");
        }

        Kommentar


          danke für den Code. Beim ausführen bekomme ich folgendes:

          Code:
          wiregate:/etc/wiregate/plugin/generic/backup# perl zahler2
          Step 1 - Collect data
          Step 2 - Reg Exp 1 build dataset
          Step 3 - Analyze data
          
          OBIS ID:     1.8.0
          OBIS search: 77070100010800FF
          found: 6400018201621E52FF56000156AE9301
          check sml status:          Invalid integer bit count [4]
          check sml value time:      Invalid datatype [0]
          check sml unit:            Invalid datatype [0]
          check sml scaler:          Invalid datatype [0]
          check sml value:           Invalid datatype [0]
          check sml value signature: Invalid datatype [0]
          
          OBIS ID:     16.7.0
          OBIS search: 77070100100700FF
          found: 0101621B52FF55000055A701
          check sml status:          [empty]
          check sml value time:      [empty]
          check sml unit:            [27]
          check sml scaler:          [-1]
          check sml value:           [21927]
          check sml value signature: [empty]
          Unit config: [W][g]
          Final value: [2192.7 W]
          GAUGE
          obisname  zaehler_leistung
          value     2192.7
          rrdname   zaehler_leistung_g.rrd
          GA:9/0/1 value:2192.7 DPT:9
          
          OBIS ID:     36.7.0
          OBIS search: 77070100240700FF
          Use of uninitialized value $1 in concatenation (.) or string at zahler2 line 91.
          found: 01
          check sml status:          [empty]
          check sml value time:      error --> data too short
          check sml unit:            error --> data too short
          check sml scaler:          error --> data too short
          check sml value:           error --> data too short
          check sml value signature: error --> data too short
          
          OBIS ID:     56.7.0
          OBIS search: 77070100380700FF
          Use of uninitialized value $1 in concatenation (.) or string at zahler2 line 91.
          found: 01
          check sml status:          [empty]
          check sml value time:      error --> data too short
          check sml unit:            error --> data too short
          check sml scaler:          error --> data too short
          check sml value:           error --> data too short
          check sml value signature: error --> data too short
          
          OBIS ID:     76.7.0
          OBIS search: 770701004C0700FF
          Use of uninitialized value $1 in concatenation (.) or string at zahler2 line 91.
          found: 01
          check sml status:          [empty]
          check sml value time:      error --> data too short
          check sml unit:            error --> data too short
          check sml scaler:          error --> data too short
          check sml value:           error --> data too short
          check sml value signature: error --> data too short
          wiregate:/etc/wiregate/plugin/generic/backup#
          Was läuft da falsch?

          Kommentar


            Du musst die OBIS IDs anpassen. Evtl. sendet dein Zähler andere Daten.
            Ändere mal folgende Zeile im Code ab und poste die Rohdaten:

            Code:
            $rawdata =~ m/1B1B1B1B01010101(.*?)B1B1B1/;
            print $rawdata ."\n";

            Kommentar


              Anbei:

              Code:
              wiregate:/etc/wiregate/plugin/generic/backup# perl zahler2
              Step 1 - Collect data
              Step 2 - Reg Exp 1 build dataset
              51ACECC61C1B26FAEAB8FF0101016351AC00760700090153E827620062007263020171016322D4000000001B1B1B1B1A03DD611B1B1B1B01010101760700090153E8296200620072630101760101070009006F4D630B0901454D480000424ECD010163237C00760700090153E82A620062007263070177010B0901454D480000424ECD070100620AFFFF72620165006FC55D7777078181C78203FF0101010104454D480177070100000009FF010101010B0901454D480000424ECD0177070100010800FF6400018201621E52FF560001583F4A0177070100010801FF0101621E52FF560001583F4A0177070100010802FF0101621E52FF5600000000000177070100100700FF0101621B52FF55000055C50177078181C78205FF0172620165006FC55D01018302000AA1993A626C62D3345F4C95977A5262309183F335956147F25996456B2152F3FE8490C451ACECC61C1B26FAEAB8FF010101632BCD00760700090153E82D6200620072630201710163AAC3000000001B1B1B1B1A0319961B1B1B1B01010101760700090153E82F6200620072630101760101070009006F4D650B0901454D480000424ECD010163134900760700090153E830620062007263070177010B0901454D480000424ECD070100620AFFFF72620165006FC55E7777078181C78203FF0101010104454D480177070100000009FF010101010B0901454D480000424ECD0177070100010800FF6400018201621E52FF560001583F530177070100010801FF0101621E52FF560001583F530177070100010802FF0101621E52FF5600000000000177070100100700FF0101621B52FF55000056B50177078181C78205FF0172620165006FC55F01018302000AA1993A626C62D3345F4C95977A5262309183F335956147F25996456B2152F3FE8490C451ACECC61C1B26FAEAB8FF0101016319EF00760700090153E833620062007263020171016332FB000000001B1B1B1B1A0392FF1B1B1B1B01010101760700090153E8356200620072630101760101070009006F4D670B0901454D480000424ECD01016377B700760700090153E836620062007263070177010B0901454D480000424ECD070100620AFFFF72620165006FC5607777078181C78203FF0101010104454D480177070100000009FF010101010B0901454D480000424ECD0177070100010800FF6400018201621E52FF560001583F5C0177070100010801FF0101621E52FF560001583F5C0177070100010802FF0101621E52FF5600000000000177070100100700FF0101621B52FF55000057280177078181C78205FF0172620165006FC56001018302000AA1993A626C62D3345F4C95977A5262309183F335956147F25996456B2152F3FE8490C451ACECC61C1B26FAEAB8FF0101016390CB00760700090153E8396200
              Step 3 - Analyze data
              
              OBIS ID:     1.8.0
              OBIS search: 77070100010800FF
              found: 6400018201621E52FF560001583F4A01
              check sml status:          Invalid integer bit count [4]
              check sml value time:      Invalid datatype [0]
              check sml unit:            Invalid datatype [0]
              check sml scaler:          Invalid datatype [0]
              check sml value:           Invalid datatype [0]
              check sml value signature: Invalid datatype [0]
              
              OBIS ID:     16.7.0
              OBIS search: 77070100100700FF
              found: 0101621B52FF55000055C501
              check sml status:          [empty]
              check sml value time:      [empty]
              check sml unit:            [27]
              check sml scaler:          [-1]
              check sml value:           [21957]
              check sml value signature: [empty]
              Unit config: [W][g]
              Final value: [2195.7 W]
              GAUGE
              obisname  zaehler_leistung
              value     2195.7
              rrdname   zaehler_leistung_g.rrd
              GA:9/0/1 value:2195.7 DPT:9
              
              OBIS ID:     36.7.0
              OBIS search: 77070100240700FF
              Use of uninitialized value $1 in concatenation (.) or string at zahler2 line 93.
              found: 01
              check sml status:          [empty]
              check sml value time:      error --> data too short
              check sml unit:            error --> data too short
              check sml scaler:          error --> data too short
              check sml value:           error --> data too short
              check sml value signature: error --> data too short
              
              OBIS ID:     56.7.0
              OBIS search: 77070100380700FF
              Use of uninitialized value $1 in concatenation (.) or string at zahler2 line 93.
              found: 01
              check sml status:          [empty]
              check sml value time:      error --> data too short
              check sml unit:            error --> data too short
              check sml scaler:          error --> data too short
              check sml value:           error --> data too short
              check sml value signature: error --> data too short
              
              OBIS ID:     76.7.0
              OBIS search: 770701004C0700FF
              Use of uninitialized value $1 in concatenation (.) or string at zahler2 line 93.
              found: 01
              check sml status:          [empty]
              check sml value time:      error --> data too short
              check sml unit:            error --> data too short
              check sml scaler:          error --> data too short
              check sml value:           error --> data too short
              check sml value signature: error --> data too short
              wiregate:/etc/wiregate/plugin/generic/backup#

              Kommentar


                Was hast du denn für einen Zähler?
                Ich habe mir mal die Daten angeschaut. Da kommen ganz komische Sachen rüber, z.B.:

                Code:
                	  
                77 
                  07 01 00 01 08 00 FF 
                    64 00 01
                    82 01
                    62 1E 52 FF 56 00 01
                    58 3F 53 01
                Das sollte eigentlich der aktuelle Zählerstand sein (1.8.0).
                Die 3. Zeile ist der Status. Die 6 am Anfang besagt, dass es sich um einen unsigned Wert handelt. Die bit Anzahl danach darf aber nur 2 (8 bit), 3 (16 bit), 5 (32 bit) oder 9 (64 bit) sein. So steht es zumindest in der Norm.

                Gruß

                Kommentar


                  Zitat von coolrunnings Beitrag anzeigen
                  Was hast du denn für einen Zähler?
                  Ich habe mir mal die Daten angeschaut. Da kommen ganz komische Sachen rüber, z.B.:

                  Code:
                        
                  77 
                    07 01 00 01 08 00 FF 
                      64 00 01
                      82 01
                      62 1E 52 FF 56 00 01
                      58 3F 53 01
                  Das sollte eigentlich der aktuelle Zählerstand sein (1.8.0).
                  Die 3. Zeile ist der Status. Die 6 am Anfang besagt, dass es sich um einen unsigned Wert handelt. Die bit Anzahl danach darf aber nur 2 (8 bit), 3 (16 bit), 5 (32 bit) oder 9 (64 bit) sein. So steht es zumindest in der Norm.

                  Gruß
                  Hi,

                  von dem Zähler hab ich ein Foto angehangen.

                  Danke für die Unterstützung
                  Angehängte Dateien

                  Kommentar


                    Also ich hab auch nen Zähler von der RWE, aber den ISKRA und nicht den EMH. Damit klappt es einwandfrei.

                    Ich hab den Code mal angepasst, so dass die 4 für 24 bit steht und 6 für 40 bit. Konnte darüber allerdings nichts in der Spezi finden. Dann sähen die OBIS Daten so aus:

                    Code:
                    	  
                    77 
                      07 01 00 01 08 00 FF   # ID 1-1.8.0
                        64 00 01 82              # Status 0x182 --> 386
                        01                          # keine Zeit 
                        62 1E                      # Unit 0x1E --> 30 --> Wh
                        52  FF                     # Scaler -1 --> value+10^-1
                        56 00 01 58 3F 53     # Value: 0x1583F53 --> 22560595 Wh --> 2256,0595 kWh
                        01                          # keine value Signatur
                    Du hast du OBIS IDs 1.8.0, 1.8.1, 1.8.2 und 16.7.0
                    Hier der Code:

                    Code:
                    #!/usr/bin/perl
                    #
                    # Autor: coolrunnings / www.knx-user-forum.de
                    # Based on the PlugIn sml-meter by JuMi2006 / www.knx-user-forum.de
                    # knx_write sub: makki / www.knx-user-forum.de
                    # Version: 0.2
                    # Datum: 03.11.2013
                    # Licenced under the GPLv3
                    
                    use warnings;
                    use strict;
                    use Device::SerialPort;
                    use feature "switch";
                    use EIBConnection;
                    use RRDs;
                    use Scalar::Util qw(looks_like_number);
                    
                    #####################################################################
                    # define everything here
                    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",  ga =>"9/0/0", dpt =>  14, rrd_name => "zaehler_verbrauch"}; 
                    push @obis,{obis=>"16.7.0", ga =>"9/0/1", dpt =>  9, rrd_name => "zaehler_leistung" };
                    push @obis,{obis=>"36.7.0", ga =>"9/0/2", dpt =>  9, rrd_name => "zaehler_leistung_L1"};
                    push @obis,{obis=>"56.7.0", ga =>"9/0/3", dpt =>  9, rrd_name => "zaehler_leistung_L2"};
                    push @obis,{obis=>"76.7.0", ga =>"9/0/4", dpt =>  9, rrd_name => "zaehler_leistung_L3"};
                    my @countermodes = (5,15,60,1440);    #Aufloesungen fuer COUNTER RRDs in Minuten (1440 = Tagesverbrauch)
                    my @derivemodes = (5,15,60,1440);    #Aufloesungen fuer DERIVE RRDs in Minuten (1440 = Tagesverbrauch)
                    
                    my $debug   = "1";
                    my $logging = "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
                    
                    #####################################################################
                    # don't touch anything starting here
                    
                    my $filename = "/tmp/sml_meter.log";
                    if ( $logging == "1" ) {open (LOG, ">>$filename") or $logging = "0";}
                    
                    if ( $logging == "1" ) {print LOG "===============================================\n";}
                    if ( $logging == "1" ) {print LOG (localtime)." Start new run\n";}
                    
                    
                    my ($x,$rawdata) = 0 ;
                    my $count = 0;
                    my $saw = 0;
                    my $start = 0;
                    
                    if ($debug == 1) {print "Step 1 - Collect data \n";}
                    if ($logging == 1) {print LOG "Step 1 - Collect data \n";}
                    
                    while ($start < 2) {	# wait for second 1B1B1B1B01010101
                       
                    	($count,$saw)=$port->read(512);  # will read 512 chars
                    	if ($count == 512) {       		# 512 chars read?
                    		$x = uc(unpack('H*',$saw)); # nach hex wandeln
                    		$rawdata .= $x;
                    		if ($rawdata =~ /1B1B1B1B01010101/)  {$start ++};
                    	} # if
                    }  # while
                    
                    if ($debug==1) {print "Step 2 - Reg Exp 1 build dataset \n";}
                    if ($logging==1) {print LOG "Step 2 - Reg Exp 1 build dataset \n";}
                    
                    $rawdata =~ m/1B1B1B1B01010101(.*?)B1B1B1/;
                    print $rawdata."\n";
                    
                    if ($debug==1) {print "Step 3 - Analyze data \n";}
                    if ($logging==1) {print LOG "Step 3 - Analyze data \n";}
                    
                    # find OBIS values in raw data
                    foreach my $obiscnt (@obis) {
                    	if ( $debug == 1 ) {print "\n";}
                    	if ( $logging == 1 ) {print LOG "-----------------------------------------------\n";}
                    	my $obissearch = &obis2search($obiscnt->{obis});
                    	
                    	$rawdata =~ m/$obissearch(.*?)017707/;
                    	my $obisdata = $1."01";
                    	
                    	if ( $debug == 1 ) {print "found: ".$obisdata."\n";}
                    	if ( $logging == 1 ) {print LOG "found: ".$obisdata."\n";}
                    	
                    	my $smlStatus  = "";
                    	my $smlValTime = "";
                    	my $smlUnit    = "";
                    	my $smlScaler  = "";
                    	my $smlValue   = "";
                    	my $smlValueS  = "";
                    	
                    	## check status
                    	if ( $debug == 1 ) {print "check sml status:          ";}
                    	if ( $logging == 1 ) {print LOG "check sml status:          ";}
                    	$smlStatus = &parseOBIS(\$obisdata);
                    	
                    	## check value time
                    	if ( $debug == 1 ) {print "check sml value time:      ";}
                    	if ( $logging == 1 ) {print LOG "check sml value time:      ";}
                    	$smlValTime = &parseOBIS(\$obisdata);
                    	
                    	## check unit
                    	if ( $debug == 1 ) {print "check sml unit:            ";}
                    	if ( $logging == 1 ) {print LOG "check sml unit:            ";}
                    	$smlUnit = &parseOBIS(\$obisdata);
                    	
                    	## check scaler
                    	if ( $debug == 1 ) {print "check sml scaler:          ";}
                    	if ( $logging == 1 ) {print LOG "check sml scaler:          ";}
                    	$smlScaler = &parseOBIS(\$obisdata);
                    	
                    	## check value
                    	if ( $debug == 1 ) {print "check sml value:           ";}
                    	if ( $logging == 1 ) {print LOG "check sml value:           ";}
                    	$smlValue = &parseOBIS(\$obisdata);
                    	
                    	## check value signature
                    	if ( $debug == 1 ) {print "check sml value signature: ";}
                    	if ( $logging == 1 ) {print LOG "check sml value signature: ";}
                    	$smlValueS = &parseOBIS(\$obisdata);
                    
                    	#print "done: ".$obisdata."\n";
                    	#print  $smlStatus;
                    	
                    	# Calculate value
                    	if ( $smlValue ne "" ) {
                    		my $calcvalue  = ($smlValue * (10**$smlScaler));
                    		
                    		# Modify value depening on unit
                    		my $smlUnitCfg_ref = &getSMLUnitStr($smlUnit);
                    		my @smlUnitCfg = @{$smlUnitCfg_ref};
                    		
                    		if ( (@smlUnitCfg) == 2 ) {
                    			my $tUnitStr  = $smlUnitCfg[0];
                    			my $tUnitRRD  = $smlUnitCfg[1];
                    			
                    			# Wh to kWh
                    			if ( $smlUnit == 30  ) {
                    				$calcvalue = $calcvalue * 0.001;
                    				$tUnitStr  = "kWh";
                    			}
                    			
                    			if ( $debug == 1 ) {print "Unit config: [".$tUnitStr."][".$tUnitRRD."]\n";}
                    			if ( $logging == 1 ) {print LOG "Unit config: [".$tUnitStr."][".$tUnitRRD."]\n";}
                    			
                    			if ( $debug == 1 ) {print "Final value: [".$calcvalue." ".$tUnitStr."]\n";}
                    			if ( $logging == 1 ) {print LOG "Final value: [".$calcvalue." ".$tUnitStr."]\n";}
                    		
                    			# write rrd
                    			if ($tUnitRRD =~ m/c/) {
                    				&rrd_counter ($obiscnt->{rrd_name},$calcvalue)
                    			}
                    			
                    			if ($tUnitRRD =~ m/d/) {
                    				&rrd_derive ($obiscnt->{rrd_name},$calcvalue)
                    			}
                    			
                    			if ($tUnitRRD =~ m/g/) {
                    				&rrd_gauge ($obiscnt->{rrd_name},$calcvalue)
                    			}
                    
                    			# send value to bus
                    			&knx_write ($obiscnt->{ga},$calcvalue,$obiscnt->{dpt});
                    			if ($debug == 1) {print "GA:".$obiscnt->{ga}." value:".$calcvalue." DPT:".$obiscnt->{dpt}."\n";}
                    			if ($logging == 1) {print LOG "GA:".$obiscnt->{ga}." value:".$calcvalue." DPT:".$obiscnt->{dpt}."\n";}
                    				
                    				
                    		}
                    		else {
                    			if ( $debug == 1 ) {print "No unit found. No data will be written.\n";}
                    			if ( $logging == 1 ) {print LOG "No unit found. No data will be written.\n";}
                    		}
                    	}	
                    }
                    
                    $port->close() || warn "Serial port did not close proper!\n";
                    undef $port;
                    
                    if ( $logging == "1" ) {close LOG;}
                    
                    ## subs ##
                    
                    #####################################################################
                    # convert OBIS to search parameter
                    sub obis2search {
                    
                    	my ($obisid) = @_;
                    	my $res = "77070100";
                    	
                    	if ($debug==1) { print "OBIS ID:     ".$obisid."\n";}
                    	if ($logging==1) { print LOG "OBIS ID:     ".$obisid."\n";}
                    		
                    	foreach my $c ( split(/\./,$obisid) ) {
                    		$res .= sprintf("%02X",$c);
                    	}
                    	
                    	$res .= "FF";
                    	
                    	if ($debug==1) { print "OBIS search: ".$res."\n";}
                    	if ($logging==1) { print LOG "OBIS search: ".$res."\n";}
                    	
                    	return $res;
                    }
                    
                    #####################################################################
                    # parse OBIS data
                    sub parseOBIS {
                    	#my ($obisdata) = @_;
                    	my $r_obisdata = shift;
                    	my $res = "";
                    	
                    	if ( length($$r_obisdata) < 2 ) {
                    		print "error --> data too short\n";
                    		return $res;
                    	}
                    	
                    	my $smlDataTypeID = substr($$r_obisdata,0,2); 
                    	
                    	if ( $smlDataTypeID == "01" ) {
                    		## no data
                    		if ( $debug == 1 ) {print "[empty]\n";}
                    		if ( $logging == 1 ) {print LOG "[empty]\n";}
                    		$$r_obisdata =~ s/^..//;	# remove first 2 characters
                    		return $res;
                    	}
                    	else {
                    		#if ( $debug == 1 ) {print "found something ";}
                    		#if ( $logging == 1 ) {print LOG "found something ";}
                    		
                    		my $smlDataType    = substr($smlDataTypeID,0,1);
                    		my $smlIntBitCode = substr($smlDataTypeID,1,1);
                    		
                    		# only signed and unsigned int possible
                    		if ( $smlDataType != "5" && $smlDataType != "6") {
                    			if ( $debug == 1 ) {print "Invalid datatype [".$smlDataType."]\n"; };
                    			if ( $logging == 1 ) {print LOG "Invalid datatype [".$smlDataType."]\n"; };
                    			return $res;
                    		}
                    		
                    		$$r_obisdata =~ s/^..//;	# remove first 2 characters
                    		
                    		
                    		my $smlIntBitCnt = 0;
                    		
                    		#switch ( $smlIntBitCode ) {
                    		#	case 2	{ $smlIntBitCnt =  8 }
                    		#	case 3	{ $smlIntBitCnt = 16 }
                    		#	case 5	{ $smlIntBitCnt = 32 }
                    		#	case 9	{ $smlIntBitCnt = 64 }
                    		#	else  	{ if ( $debug == 1 ) {print "Invalid integer bit count [".$smlIntBitCode."]\n"; };
                    		#			  return $res; 
                    		#			}
                    		#}
                    		
                    		if ( $smlIntBitCode == 2 ) {
                    			$smlIntBitCnt =  8
                    		}
                    		elsif ( $smlIntBitCode == 3 ) {
                    			$smlIntBitCnt =  16
                    		}
                    		elsif ( $smlIntBitCode == 4 ) { # not conform with the SML specification!
                    			$smlIntBitCnt =  24
                    		}
                    		elsif ( $smlIntBitCode == 5 ) {
                    			$smlIntBitCnt =  32
                    		}
                            elsif ( $smlIntBitCode == 6 ) { # not conform with the SML specification!
                    			$smlIntBitCnt =  40
                    		}
                    		elsif ( $smlIntBitCode == 9 ) {
                    			$smlIntBitCnt =  64
                    		}
                    		else {
                    			if ( $debug == 1 ) {print "Invalid integer bit count [".$smlIntBitCode."]\n"; };
                    			if ( $logging == 1 ) {print LOG "Invalid integer bit count [".$smlIntBitCode."]\n"; };
                    			return $res;
                    		}
                    		
                    		my $smlIntCharCnt = ($smlIntBitCnt/4);
                    		
                    		# check that the rest of the string is long enought for the bit count
                    		if ( (length($$r_obisdata)) < $smlIntCharCnt ) {
                    			if ( $debug == 1 ) {print "String not long enough for for detected bit count [".$smlIntCharCnt."]\n"; };
                    			if ( $logging == 1 ) {print LOG "String not long enough for for detected bit count [".$smlIntCharCnt."]\n"; };
                    			return $res;
                    		}
                    		
                    		# get the hex values
                    		my $hexval = substr($$r_obisdata,0,$smlIntCharCnt);
                    		$$r_obisdata = substr($$r_obisdata,$smlIntCharCnt);
                    		
                    		# if signed, get 2' complement
                    		if ( $smlDataType == 5 ) {
                    			my $hexbin = sprintf("%0${smlIntBitCnt}b",hex($hexval));
                    		
                    			if ( substr($hexbin,0,1) == 1 ) {
                    				#if ( $debug == 1 ) { print "2's complement \n"; }
                    				#if ( $logging == 1 ) { print LOG "2's complement \n"; }
                    				my $hexinv = sprintf("%08x",~hex($hexval));
                    				$res = (substr($hexinv,6,2)+1)*(-1);
                    			
                    			}
                    			else {
                    				$res = hex($hexval);
                    			}
                    		}
                    		else {
                    			$res = hex($hexval);
                    		}
                    		
                    		if ( $debug == 1 ) { print "[".$res."]\n";}
                    		if ( $logging == 1 ) { print LOG "[".$res."]\n";}
                    		
                    		return $res;
                    	}
                    	
                    	return $res;
                    }
                    
                    #####################################################################
                    # get SML unit string depending on value
                    # DLMS Units as specified in ISO EN 62056-62 and used by SML
                    # original values from unit.h in vzlogger project
                    # The volkszaehler.org project
                    sub getSMLUnitStr {
                    
                    	my ($smlUnitCode) = @_;
                    	
                    	my %unitmap = (	
                    	# code	  # unit		#rrd		# quantity						#name					#SI definition
                    	
                    	1 => 	[ "a",			"g" ],      # time                			year            		52*7*24*60*60 s
                    	2 => 	[ "mo",			"g" ],      # time                			month            		31*24*60*60 s
                    	3 => 	[ "wk",			"g" ],      # time                			week            		7*24*60*60 s
                    	4 => 	[ "d",			"g" ],      # time                			day            			24*60*60 s
                    	5 => 	[ "h",			"g" ],      # time                			hour            		60*60 s
                    	6 => 	[ "min.",		"g" ],      # time                			min            			60 s
                    	7 => 	[ "s",			"g" ],      # time (t)            			second            		s
                    	8 => 	[ "°",			"g" ],      # (phase) angle        			degree            		rad*180/π
                    	9 => 	[ "°C",			"g" ],      # temperature (T)       		degree celsius      	K-273.15
                    	10 => 	[ "currency",	"g" ],    	# (local) currency
                    	11 => 	[ "m",			"g" ],      # length (l)            		metre            		m
                    	12 => 	[ "m/s",		"g" ],      # speed (v)            			metre per second    	m/s
                    	13 => 	[ "m³",			"g" ],      # volume (V)            		cubic metre        		m³
                    	14 => 	[ "m³",			"g" ],      # corrected volume      		cubic metre        		m³
                    	15 => 	[ "m³/h",		"g" ],      # volume flux           		cubic metre per hour    m³/(60*60s)
                    	16 => 	[ "m³/h",		"g" ],      # corrected volume flux 		cubic metre per hour    m³/(60*60s)
                    	17 => 	[ "m³/d",		"g" ],      # volume flux                        					m³/(24*60*60s)
                    	18 => 	[ "m³/d",		"g" ],      # corrected volume flux                					m³/(24*60*60s)
                    	19 => 	[ "l",			"g" ],      # volume            			litre            		10-3 m³
                    	20 => 	[ "kg",			"g" ],      # mass (m)            			kilogram
                    	21 => 	[ "N",			"g" ],      # force (F)            			newton
                    	22 => 	[ "Nm",			"g" ],      # energy            			newtonmeter        		J = Nm = Ws
                    	23 => 	[ "Pa",			"g" ],      # pressure (p)          		pascal            		N/m²
                    	24 => 	[ "bar",		"g" ],      # pressure (p)          		bar            			10⁵ N/m²
                    	25 => 	[ "J",			"g" ],      # energy            			joule            		J = Nm = Ws
                    	26 => 	[ "J/h",		"g" ],      # thermal power        			joule per hour        	J/(60*60s)
                    	27 => 	[ "W",			"g" ],      # active power (P)      		watt            		W = J/s
                    	28 => 	[ "VA",			"g" ],      # apparent power (S)    		volt-ampere
                    	29 => 	[ "var",		"g" ],      # reactive power (Q)    		var
                    	30 => 	[ "Wh",			"cdg" ],    # active energy        			watt-hour        		W*(60*60s)
                    	31 => 	[ "VAh",		"g" ],      # apparent energy       		volt-ampere-hour    	VA*(60*60s)
                    	32 => 	[ "varh",		"g" ],      # reactive energy       		var-hour        		var*(60*60s)
                    	33 => 	[ "A",			"g" ],      # current (I)           		ampere            		A
                    	34 => 	[ "C",			"g" ],      # electrical charge (Q) 		coulomb            		C = As
                    	35 => 	[ "V",			"g" ],      # voltage (U)           		volt            		V
                    	36 => 	[ "V/m",		"g" ],      # electr. field strength (E)    volt per metre
                    	37 => 	[ "F",			"g" ],      # capacitance (C)       		farad            		C/V = As/V
                    	38 => 	[ "Ω",			"g" ],      # resistance (R)        		ohm            			Ω = V/A
                    	39 => 	[ "Ωm²/m",		"g" ],      # resistivity (ρ)       		Ωm
                    	40 => 	[ "Wb",			"g" ],      # magnetic flux (Φ)     		weber            		Wb = Vs
                    	41 => 	[ "T",			"g" ],      # magnetic flux density (B)    	tesla            		Wb/m2
                    	42 => 	[ "A/m",		"g" ],      # magnetic field strength (H)   ampere per metre    	A/m
                    	43 => 	[ "H",			"g" ],      # inductance (L)        		henry            		H = Wb/A
                    	44 => 	[ "Hz",			"g" ],      # frequency (f => ω)        	hertz            		1/s
                    	45 => 	[ "1/(Wh)",		"g" ],      # R_W                           (Active energy meter constant or pulse value)
                    	46 => 	[ "1/(varh)",	"g" ],     	# R_B                           (reactive energy meter constant or pulse value)
                    	47 => 	[ "1/(VAh)",	"g" ],    	# R_S                           (apparent energy meter constant or pulse value)
                    	48 => 	[ "V²h",		"g" ],      # volt-squared hour        	´	volt-squaredhours    	V²(60*60s)
                    	49 => 	[ "A²h",		"g" ],      # ampere-squared hour        	ampere-squaredhours    	A²(60*60s)
                    	50 => 	[ "kg/s",		"g" ],      # mass flux            			kilogram per second    	kg/s
                    	51 => 	[ "S => mho",	"g" ],     	# conductance siemens                    				1/Ω
                    	52 => 	[ "K",			"g" ],     	# temperature (T)        		kelvin
                    	53 => 	[ "1/(V²h)",	"g" ],    	# R_U²h                        (Volt-squared hour meter constant or pulse value)
                    	54 => 	[ "1/(A²h)",	"g" ],    	# R_I²h                        (Ampere-squared hour meter constant or pulse value)
                    	55 => 	[ "1/m³",		"g" ],      # R_V => meter constant or pulse value (volume)
                    	56 => 	[ "%",			"g" ],      # percentage            		%
                    	57 => 	[ "Ah",			"g" ],      # ampere-hours            		ampere-hour
                    	60 => 	[ "Wh/m³",		"g" ],      # energy per volume                    					3,6*103 J/m³
                    	61 => 	[ "J/m³",		"g" ],      # calorific value, wobbe
                    	62 => 	[ "Mol %",		"g" ],      # molar fraction of        		mole percent    (Basic gas composition unit)
                    										# gas composition  
                    	63 => 	[ "g/m³",		"g" ],      # mass density, quantity of material            (Gas analysis => accompanying elements)
                    	64 => 	[ "Pa s",		"g" ],      # dynamic viscosity pascal second       		(Characteristic of gas stream)
                    	253 => 	[ "(reserved)",	"g"],		# reserved
                    	254 => 	[ "(other)",	"g" ],    	# other unit
                    	255 => 	[ "(unitless)",	"g"]   	# no unit, unitless, count
                    	);
                    	
                    	#print "-------- unit ".$unitmap{$smlUnitCode}[0]."\n";
                    	
                    	#print "-------- unit ".$unitmap{$smlUnitCode}."\n";
                    	
                    	my $unitarray_ref = $unitmap{$smlUnitCode};
                    	
                    	return $unitarray_ref;
                    	
                    }
                    
                    #####################################################################
                    
                    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;
                    }
                    
                    #####################################################################
                    
                    sub rrd_counter
                    {
                        if ($debug==1){print ("COUNTER","\n")};
                    	if ($logging==1){print LOG ("-- COUNTER ---","\n")};
                    	
                    	my $obisname = $_[0];
                    	if ($debug==1){print "obisname  ".$obisname."\n";}
                    	if ($logging==1){print LOG "obisname  ".$obisname."\n";}
                    	my $value = $_[1];
                        if ($debug==1){print "value     ".$value."\n";}
                    	if ($logging==1){print LOG "value     ".$value."\n";}
                        
                        foreach (@countermodes)
                        {
                            my $rrdname = $obisname."_".$_."_c\.rrd";
                            if ($debug==1){print "rrdname   ".$rrdname."\n"};
                    		if ($logging==1){print LOG "----------\n"};
                    		if ($logging==1){print LOG "rrdname   ".$rrdname."\n"};
                            my $rrdfile = $rrdpath."\/".$rrdname;
                            unless (-e $rrdfile)
                            {
                                RRDs::create ($rrdfile,"DS:value:COUNTER:".(($_*60)+600).":0:U",
                    			"RRA:AVERAGE:0.5:1:366",	
                    			"RRA:AVERAGE:0.5:7:1308",
                    			"-s ".($_*60));				# step 
                            }
                            my $countervalue = int($value*$_*60);
                    		if ($debug==1){print "[".$value."]*[".$_."]*[60] = ".$countervalue." countervalue \n";}
                    		if ($logging==1){print LOG "[".$value."]*[".$_."]*[60] = ".$countervalue." countervalue \n";}
                            RRDs::update("$rrdfile", "N:$countervalue");
                        }
                    }
                    
                    sub rrd_derive
                    {
                        if ($debug==1){print ("DERIVE","\n")};
                    	if ($logging==1){print LOG ("-- DERIVE ---","\n")};
                    	
                    	my $obisname = $_[0];
                    	if ($debug==1){print "obisname  ".$obisname."\n";}
                    	if ($logging==1){print LOG "obisname  ".$obisname."\n";}
                    	my $value = $_[1];
                        if ($debug==1){print "value     ".$value."\n";}
                    	if ($logging==1){print LOG "value     ".$value."\n";}
                        
                        foreach (@derivemodes)
                        {
                            my $rrdname = $obisname."_".$_."_d\.rrd";
                            if ($debug==1){print "rrdname   ".$rrdname."\n"};
                    		if ($logging==1){print LOG "----------\n"};
                    		if ($logging==1){print LOG "rrdname   ".$rrdname."\n"};
                            my $rrdfile = $rrdpath."\/".$rrdname;
                            unless (-e $rrdfile)
                            {
                                RRDs::create ($rrdfile,"DS:value:DERIVE:".(($_*60)+600).":0:U",
                    			"RRA:AVERAGE:0.5:1:366",	
                    			"RRA:AVERAGE:0.5:7:1308",
                    			"-s ".($_*60));				# step 
                            }
                            my $derivevalue = int($value*$_*60);
                    		if ($debug==1){print "[".$value."]*[".$_."]*[60] = ".$derivevalue." derivevalue \n";}
                    		if ($logging==1){print LOG "[".$value."]*[".$_."]*[60] = ".$derivevalue." derivevalue \n";}
                            RRDs::update("$rrdfile", "N:$derivevalue");
                        }
                    }
                    
                    #####################################################################
                    
                    sub rrd_gauge
                    {
                        if ($debug==1){print ("GAUGE","\n")};
                    	if ($logging==1){print LOG ("-- GAUGE --","\n")};
                        my $obisname = $_[0];
                        if ($debug==1){print "obisname  ".$obisname."\n";}
                    	if ($logging==1){print LOG "obisname  ".$obisname."\n";}
                    	my $value = $_[1];
                        if ($debug==1){print "value     ".$value."\n";}
                    	if ($logging==1){print LOG "value     ".$value."\n";}
                        my $rrdname = $obisname."_g\.rrd";
                        if ($debug==1){print "rrdname   ".$rrdname."\n"};
                    	if ($logging==1){print LOG "rrdname   ".$rrdname."\n"};
                        my $rrdfile = $rrdpath."\/".$rrdname;
                        unless (-e $rrdfile)
                        {
                            RRDs::create ($rrdfile,"DS:value:GAUGE:900:0:U",
                    		"RRA:AVERAGE:0.5:1:2016",		# 5 minutes for 7 days
                    		"RRA:AVERAGE:0.5:6:1488",		# 30 minutes for 31 days
                    		"RRA:AVERAGE:0.5:12:4392",		# 1 hour for 5 month
                    		"RRA:AVERAGE:0.5:72:7320",		# 6 hours for 5 years
                    		"RRA:AVERAGE:0.5:2016:1308");	# 1 day for 25 years	
                        }
                        RRDs::update("$rrdfile", "N:$value");
                    }

                    Kommentar


                      Super, klasse! Vielen Dank!
                      Kannst du bitte noch sagen wie oft du den Script über crontab ausführen lässt?

                      Anbei nun der output:
                      Code:
                      wiregate:/etc/wiregate/plugin/generic/backup# perl zaehler3
                      Step 1 - Collect data
                      Step 2 - Reg Exp 1 build dataset
                      1B1B1B1B01010101760700090154886D6200620072630101760101070009007082CF0B0901454D480000424ECD0101630B8900760700090154886E620062007263070177010B0901454D480000424ECD070100620AFFFF7262016500700BE27777078181C78203FF0101010104454D480177070100000009FF010101010B0901454D480000424ECD0177070100010800FF6400018001621E52FF56000158AFEF0177070100010801FF0101621E52FF56000158AFEF0177070100010802FF0101621E52FF5600000000000177070100100700FF0101621B52FF55000000C40177078181C78205FF017262016500700BE201018302000AA1993A626C62D3345F4C95977A5262309183F335956147F25996456B2152F3FE8490C451ACECC61C1B26FAEAB8FF01010163A24C00760700090154886F62006200726302017101631EC1000000001B1B1B1B1A0377C21B1B1B1B0101010176070009015488736200620072630101760101070009007082D10B0901454D480000424ECD010163FB68007607000901548874620062007263070177010B0901454D480000424ECD070100620AFFFF7262016500700BE37777078181C78203FF0101010104454D480177070100000009FF010101010B0901454D480000424ECD0177070100010800FF6400018201621E52FF56000158AFF00177070100010801FF0101621E52FF56000158AF1B1B1B1B0101010176070009015488D36200620072630101760101070009007082F10B0901454D480000424ECD01016370330076070009015488D4620062007263070177010B0901454D480000424ECD070100620AFFFF7262016500700C297777078181C78203FF0101010104454D480177070100000009FF010101010B0901454D480000424ECD0177070100010800FF6400018001621E52FF56000158AFF30177070100010801FF0101621E52FF56000158AFF30177070100010802FF0101621E52FF5600000000000177070100100700FF0101621B52FF55000000C90177078181C78205FF017262016500700C2901018302000AA1993A626C62D3345F4C95977A5262309183F335956147F25996456B2152F3FE8490C451ACECC61C1B26FAEAB8FF0101016395930076070009015488D5620062007263020171016342D7000000001B1B1B1B1A0322521B1B1B1B0101010176070009015488D96200620072630101760101070009007082F30B0901454D480000424ECD01016343830076070009015488DA620062007263070177010B0901454D480000424ECD070100620AFFFF7262016500700C2B7777078181C78203FF0101010104454D480177070100000009FF010101010B0901454D480000424ECD0177070100010800FF6400018201621E52FF56000158AFF40177070100010801FF0101621E52FF56000158AF
                      Step 3 - Analyze data
                      
                      OBIS ID:     1.8.0
                      OBIS search: 77070100010800FF
                      found: 6400018001621E52FF56000158AFEF01
                      check sml status:          [384]
                      check sml value time:      [empty]
                      check sml unit:            [30]
                      check sml scaler:          [-1]
                      check sml value:           [22589423]
                      check sml value signature: [empty]
                      Unit config: [kWh][cdg]
                      Final value: [2258.9423 kWh]
                      COUNTER
                      obisname  zaehler_verbrauch
                      value     2258.9423
                      rrdname   zaehler_verbrauch_5_c.rrd
                      [2258.9423]*[5]*[60] = 677682 countervalue
                      rrdname   zaehler_verbrauch_15_c.rrd
                      [2258.9423]*[15]*[60] = 2033048 countervalue
                      rrdname   zaehler_verbrauch_60_c.rrd
                      [2258.9423]*[60]*[60] = 8132192 countervalue
                      rrdname   zaehler_verbrauch_1440_c.rrd
                      [2258.9423]*[1440]*[60] = 195172614 countervalue
                      DERIVE
                      obisname  zaehler_verbrauch
                      value     2258.9423
                      rrdname   zaehler_verbrauch_5_d.rrd
                      [2258.9423]*[5]*[60] = 677682 derivevalue
                      rrdname   zaehler_verbrauch_15_d.rrd
                      [2258.9423]*[15]*[60] = 2033048 derivevalue
                      rrdname   zaehler_verbrauch_60_d.rrd
                      [2258.9423]*[60]*[60] = 8132192 derivevalue
                      rrdname   zaehler_verbrauch_1440_d.rrd
                      [2258.9423]*[1440]*[60] = 195172614 derivevalue
                      GAUGE
                      obisname  zaehler_verbrauch
                      value     2258.9423
                      rrdname   zaehler_verbrauch_g.rrd
                      GA:9/0/0 value:2258.9423 DPT:14
                      
                      OBIS ID:     16.7.0
                      OBIS search: 77070100100700FF
                      found: 0101621B52FF55000000C401
                      check sml status:          [empty]
                      check sml value time:      [empty]
                      check sml unit:            [27]
                      check sml scaler:          [-1]
                      check sml value:           [196]
                      check sml value signature: [empty]
                      Unit config: [W][g]
                      Final value: [19.6 W]
                      GAUGE
                      obisname  zaehler_leistung
                      value     19.6
                      rrdname   zaehler_leistung_g.rrd
                      GA:9/0/1 value:19.6 DPT:9
                      
                      OBIS ID:     36.7.0
                      OBIS search: 77070100240700FF
                      Use of uninitialized value $1 in concatenation (.) or string at zaehler3 line 91.
                      found: 01
                      check sml status:          [empty]
                      check sml value time:      error --> data too short
                      check sml unit:            error --> data too short
                      check sml scaler:          error --> data too short
                      check sml value:           error --> data too short
                      check sml value signature: error --> data too short
                      
                      OBIS ID:     56.7.0
                      OBIS search: 77070100380700FF
                      Use of uninitialized value $1 in concatenation (.) or string at zaehler3 line 91.
                      found: 01
                      check sml status:          [empty]
                      check sml value time:      error --> data too short
                      check sml unit:            error --> data too short
                      check sml scaler:          error --> data too short
                      check sml value:           error --> data too short
                      check sml value signature: error --> data too short
                      
                      OBIS ID:     76.7.0
                      OBIS search: 770701004C0700FF
                      Use of uninitialized value $1 in concatenation (.) or string at zaehler3 line 91.
                      found: 01
                      check sml status:          [empty]
                      check sml value time:      error --> data too short
                      check sml unit:            error --> data too short
                      check sml scaler:          error --> data too short
                      check sml value:           error --> data too short
                      check sml value signature: error --> data too short

                      Kommentar


                        Zitat von mosjka1 Beitrag anzeigen
                        Super, klasse! Vielen Dank!
                        Kannst du bitte noch sagen wie oft du den Script über crontab ausführen lässt?
                        Alle 5 Minuten.

                        Zitat von mosjka1 Beitrag anzeigen
                        Code:
                        OBIS ID:     1.8.0
                        OBIS search: 77070100010800FF
                        found: 6400018001621E52FF56000158AFEF01
                        check sml status:          [384]
                        check sml value time:      [empty]
                        check sml unit:            [30]
                        check sml scaler:          [-1]
                        check sml value:           [22589423]
                        check sml value signature: [empty]
                        Unit config: [kWh][cdg]
                        Final value: [2258.9423 kWh]
                        Das sieht gut aus. Wie gesagt, du kannst die COUNTER RRDs noch deaktivieren. Einfach
                        Code:
                        @countermodes =();
                        Zitat von mosjka1 Beitrag anzeigen
                        Code:
                        OBIS ID:     16.7.0
                        OBIS search: 77070100100700FF
                        found: 0101621B52FF55000000C401
                        check sml status:          [empty]
                        check sml value time:      [empty]
                        check sml unit:            [27]
                        check sml scaler:          [-1]
                        check sml value:           [196]
                        check sml value signature: [empty]
                        Unit config: [W][g]
                        Final value: [19.6 W]
                        Sieht auch soweit schlüssig aus. Aber 19,6W momentaner Verbrauch ist schon sportlich. Hast du noch nichts dran hängen?

                        Zitat von mosjka1 Beitrag anzeigen
                        Code:
                        OBIS ID:     36.7.0
                        OBIS ID:     76.7.0
                        Die würde ich noch aus der Config entfernen.

                        Kommentar


                          Entschuldigt, dass ich mich hier dran hänge.
                          Ich habe zwei Leseköpfe von Udo an zwei EMH Zählern, die am Wiregate hängen. Ich habe extra ein 3.5.1-wiregate-1.41 Kernel installiert (installieren lassen), damit die cp210x usb-uart Wandler funktionieren.

                          Code:
                          Bus 001 Device 009: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x Composite Device
                          Bus 001 Device 008: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x Composite Device
                          Leider bekomme ich immer noch nur "Schrott" auf dem Device.
                          Code:
                          root@wiregate248:/home/user# socat - /dev/ttyUSBehzEMHHaupt,raw,echo=0,b9600,parenb=0,cs8,cstopb=1
                          ��oMbbrcv
                          MPNbbrcw;Wc"xv
                                     EMH�p;Wb
                          ��rbe���ww��ǂ�EMHw    �
                                                               EMH�p;Ww�d�bR�V��w�bR�V��w�bR�Vw�bR�U���
                          oder
                          Code:
                          root@wiregate248:/home/user# socat - /dev/ttyUSBehzEMHHaupt,raw,echo=0,b9600,parenb=0,cs8,cstopb=1
                          ��oMbbrcv
                          MPNbbrcw;Wc"xv
                                     EMH�p;Wb
                          ��rbe���ww��ǂ�EMHw    �
                                                               EMH�p;Ww�d�bR�V��w�bR�V��w�bR�Vw�bR�U���
                          Hat jemand eine Idee, was ich probieren kann?

                          Danke und Gruß Moritz

                          Kommentar


                            Zitat von coolrunnings Beitrag anzeigen
                            Alle 5 Minuten.



                            Das sieht gut aus. Wie gesagt, du kannst die COUNTER RRDs noch deaktivieren. Einfach
                            Code:
                            @countermodes =();
                            Sieht auch soweit schlüssig aus. Aber 19,6W momentaner Verbrauch ist schon sportlich. Hast du noch nichts dran hängen?



                            Die würde ich noch aus der Config entfernen.
                            flutsch jetzt bestens!!! Danke !!!

                            Ps.: der Lesekopf hängt an dem Zähler von der Luftwärmepumpe. Sie war gerade nicht im Betrieb. Wenn sie mal anläuft, sieht die Sache ganz anders aus, leider!

                            Wenn ich noch einen zweiten Lesekopf an den Haustromzähler dran machen möchte, erstelle ich dazu eine Kopie von diesem script und dort ändere ich die Schnittstelle ab, oder kann der zweite Zähler über den selben script laufen. Die Zähler sind identisch.

                            Kommentar


                              Zitat von mosjka1 Beitrag anzeigen
                              Ps.: der Lesekopf hängt an dem Zähler von der Luftwärmepumpe. Sie war gerade nicht im Betrieb.
                              Das beruhigt mich dann doch etwas

                              Zitat von mosjka1 Beitrag anzeigen
                              Wenn ich noch einen zweiten Lesekopf an den Haustromzähler dran machen möchte, erstelle ich dazu eine Kopie von diesem script und dort ändere ich die Schnittstelle ab, oder kann der zweite Zähler über den selben script laufen. Die Zähler sind identisch.
                              Genau so. Und die GAs musst du natürlich noch anpassen.

                              Kommentar


                                Zitat von kleinklausi Beitrag anzeigen
                                Entschuldigt, dass ich mich hier dran hänge.
                                Ich habe zwei Leseköpfe von Udo an zwei EMH Zählern, die am Wiregate hängen. Ich habe extra ein 3.5.1-wiregate-1.41 Kernel installiert (installieren lassen), damit die cp210x usb-uart Wandler funktionieren.

                                Code:
                                Bus 001 Device 009: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x Composite Device
                                Bus 001 Device 008: ID 10c4:ea60 Cygnal Integrated Products, Inc. CP210x Composite Device
                                Leider bekomme ich immer noch nur "Schrott" auf dem Device.
                                Code:
                                root@wiregate248:/home/user# socat - /dev/ttyUSBehzEMHHaupt,raw,echo=0,b9600,parenb=0,cs8,cstopb=1
                                ��oMbbrcv
                                MPNbbrcw;Wc"xv
                                           EMH�p;Wb
                                ��rbe���ww��ǂ�EMHw    �
                                                                     EMH�p;Ww�d�bR�V��w�bR�V��w�bR�Vw�bR�U���
                                oder
                                Code:
                                root@wiregate248:/home/user# socat - /dev/ttyUSBehzEMHHaupt,raw,echo=0,b9600,parenb=0,cs8,cstopb=1
                                ��oMbbrcv
                                MPNbbrcw;Wc"xv
                                           EMH�p;Wb
                                ��rbe���ww��ǂ�EMHw    �
                                                                     EMH�p;Ww�d�bR�V��w�bR�V��w�bR�Vw�bR�U���
                                Hat jemand eine Idee, was ich probieren kann?

                                Danke und Gruß Moritz
                                probiere mal

                                Code:
                                cat /dev/ttyUSB0 | od -tx1

                                Kommentar

                                Lädt...
                                X