From fd26c977bf1ef5ac4d05a35dcf5cf3fc64e7f634 Mon Sep 17 00:00:00 2001
From: icinger <>
Date: Sun, 5 Jun 2016 07:52:54 +0000
Subject: [PATCH] 47_OBIS: Fix: SML_specialities - check, weather String is
valid Hex or plain Text New: attr "valueBracket" - use left, reight or both
values for readings
git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@11613 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
FHEM/47_OBIS.pm | 162 +++++++++++++++++++++++++++++-------------------
1 file changed, 98 insertions(+), 64 deletions(-)
diff --git a/FHEM/47_OBIS.pm b/FHEM/47_OBIS.pm
index 8f9d47859..8e51afef7 100644
--- a/FHEM/47_OBIS.pm
+++ b/FHEM/47_OBIS.pm
@@ -43,9 +43,9 @@ my %OBIS_codes = ( "Serial" => qr{^0-0:96.1.255(?:.\d+)?\((.*?)\).*},
"Powerdrops" => qr{^0.0.96.7.\d(?:.\d+)?\((.*?)\).*},
"Time_param" => qr{^0.0.96.2.1(?:.\d+)?\((.*?)\).*},
"Time_current" => qr{^0.0.1.0.0(?:.\d+)?\((.*?)\).*},
- "Channel_sum" => qr{^(?:1.0.)?(\d+).1.7(?:.\d+)?(?:\(.*?\))?\((<|>)?([-+]?\d+\.?\d*)\*?(.*)\).*},
- "Channels" => qr{^(?:\d.0.)?(\d+).7\.\d+(?:.\d+)?(?:\(.*?\))?\((<|>)?([-+]?\d+\.?\d*)\*?(.*)\).*},
- "Channels2" => qr{^(?:0.1.)?(\d+).2\.\d+(?:.\d+)?(?:\(.*?\))?\((<|>)?(-?\d+\.?\d*)\*?(.*)\).*},
+ "Channel_sum" => qr{^(?:1.0.)?(\d+).1.7(?:.0|.255)?(?:\(.*?\))?\((<|>)?([-+]?\d+\.?\d*)\*?(.*)\).*},
+ "Channels" => qr{^(?:\d.0.)?(\d+).7\.\d+(?:.0|.255)?(?:\(.*?\))?\((<|>)?([-+]?\d+\.?\d*)\*?(.*)\).*},
+ "Channels2" => qr{^(?:0.1.)?(\d+).2\.\d+(?:.0|.255)?(?:\(.*?\))?\((<|>)?(-?\d+\.?\d*)\*?(.*)\).*},
"Counter" => qr{^(?:1.\d.)?(\d).(8)\.(\d)(?:.\d+)?(?:\(.*?\))?\((<|>)?(-?\d+\.?\d*)\*?(.*)\).*},
"ManufID" => qr{^129-129:199\.130\.3(?:.\d+)?\((.*?)\).*},
"PublicKey" => qr{^129-129:199\.130\.5(?:.\d+)?\((.*?)\).*},
@@ -53,10 +53,14 @@ my %OBIS_codes = ( "Serial" => qr{^0-0:96.1.255(?:.\d+)?\((.*?)\).*},
my %SML_specialities = ("TIME" => [qr{0.0.96.2.1
|0.0.1.0.0 }x, sub{return strftime("%d-%m-%Y %H:%M:%S", localtime(unpack("i", pack("I", hex(@_)))))}],
- "HEX2" => [qr{1-0:0\.0\.[0-9] }x, sub{my $a=shift;$a=~s/(..)/$1-/g;$a=~s/-$//;return $a;}],
+ "HEX2" => [qr{1-0:0\.0\.[0-9] }x, sub{my $a=shift;
+ if ( $a =~ /^[0-9a-fA-F]+$/ ) {$a=~s/(..)/$1-/g;$a=~s/-$//};
+ return $a;}],
"HEX4" => [qr{1.0.96.5.5
|0.0.96.240.\d+
- |129.129.199.130.5}x, sub{my $a=shift;$a=~s/(....)/$1-/g;$a=~s/-$//;return $a;}],
+ |129.129.199.130.5}x, sub{my $a=shift;
+ if ( $a =~ /^[0-9a-fA-F]+$/ ) {$a=~s/(....)/$1-/g;$a=~s/-$//};
+ return $a;}],
"INFO" => [qr{1-0:0\.0\.[0-9]
|129.129.199.130.3}x, ""],
);
@@ -72,11 +76,11 @@ sub OBIS_Initialize($)
$hash->{ReadyFn} = "OBIS_Ready";
$hash->{DefFn} = "OBIS_Define";
$hash->{ParseFn} = "OBIS_Parse";
- #$hash->{SetFn} = "OBIS_Set";
+# $hash->{SetFn} = "OBIS_Set";
$hash->{UndefFn} = "OBIS_Undef";
$hash->{AttrFn} = "OBIS_Attr";
- $hash->{AttrList}= "do_not_notify:1,0 interval offset_feed offset_energy IODev channels directions alignTime pollingMode:on,off unitReadings:on,off ignoreUnknown:on,off ".
+ $hash->{AttrList}= "do_not_notify:1,0 interval offset_feed offset_energy IODev channels directions alignTime pollingMode:on,off unitReadings:on,off ignoreUnknown:on,off valueBracket:first,second,both ".
$readingFnAttributes;
}
@@ -315,8 +319,8 @@ sub OBIS_Parse($$)
}
}
$hash->{helper}{BUFFER} .= $buf;
- if (length($hash->{helper}{BUFFER}) >5000) { #longer than 3 messages, this is a traffic jam
- $hash->{helper}{BUFFER} =substr( $hash->{helper}{BUFFER} , -1500);
+ if (length($hash->{helper}{BUFFER}) >10000) { #longer than 3 messages, this is a traffic jam
+ $hash->{helper}{BUFFER} =substr( $hash->{helper}{BUFFER} , -10000);
}
my %dir=("<"=>"out",">"=>"in");
@@ -334,16 +338,16 @@ sub OBIS_Parse($$)
$rmsg = substr($buffer, 0, index($buffer,chr(13).chr(10)));
Log3 $hash,5,"OBIS ($name) - Msg-Parse: $rmsg";
my $channel=" ";
- if($rmsg=~/\/.*|^((?:\d{1,3}-\d{1,3}:)?\d{1,3}.\d{1,3}.\d{1,3})(?:\*\d{1,3})?(?:\(.*?\))?\(.*?\)|!/) { # old regex: \/.*|\d-\d{1,3}:\d{1,3}.\d{1,3}.\d{1,3}\*\d{1,3}\(.*?\)|!
+ if($rmsg=~/\/.*|^((?:\d{1,3}-\d{1,3}:)?(?:\d{1,3}|[CF]).\d{1,3}(?:.\d{1,3})?(?:\*\d{1,3})?)(?:\(.*?\))?\(.*?\)|!/) { # old regex: \/.*|\d-\d{1,3}:\d{1,3}.\d{1,3}.\d{1,3}\*\d{1,3}\(.*?\)|!
if (length $1) {
$channel=$1;
$channel=~s/:/\./;
$channel=~s/-/\./;
}
if ($hash->{MeterType} eq "Unknown") {$hash->{MeterType}="Standard"}
- if($rmsg=~/^([23456789]+)-.*/) {
- Log3 $hash,3,"OBIS ($name) - Unknown OBIS-Device, please report: $rmsg".chr(13).chr(10)."Please report to User icinger at forum.fhem.de";
- }
+# if($rmsg=~/^([23456789]+)-.*/) {
+# Log3 $hash,3,"OBIS ($name) - Unknown OBIS-Device, please report: $rmsg".chr(13).chr(10)."Please report to User icinger at forum.fhem.de";
+# }
# End of Message
if ($rmsg=~/!.*/) {
@@ -361,60 +365,84 @@ sub OBIS_Parse($$)
Log3 $hash,3,"OBIS ($name) - Unknown Message: $rmsg".chr(13).chr(10)."Please report to User icinger at forum.fhem.de"
} else {
my $found=0;
- for my $code (keys %OBIS_codes) {
- if ($rmsg =~ $OBIS_codes{$code}) {
- if ($code=~/Channel_sum.*/) {
- $rmsg =~ $OBIS_codes{$code};
- my $L= $hash->{helper}{Channels}{$channel} //$hash->{helper}{Channels}{$1} // "sum_$OBIS_channels{$1}" //$channel;
- readingsBulkUpdate($hash, $L,(looks_like_number($3) ? $3+0 : $3).(AttrVal($name,"unitReadings","off") eq "off"?"":" $4"));
- readingsBulkUpdate($hash, "dir_$L",$hash->{helper}{directions}{$2} // $dir{$2}) if (length $2);
- }
-
- elsif ($code=~/Channels.*/) {
- $rmsg =~ $OBIS_codes{$code};
- my $L=$hash->{helper}{Channels}{$channel} //$hash->{helper}{Channels}{$1} // $OBIS_channels{$1} //$channel;
- readingsBulkUpdate($hash, "$L",(looks_like_number($3) ? $3+0 : $3).(AttrVal($name,"unitReadings","off") eq "off"?"":" $4"));
- readingsBulkUpdate($hash, "dir_$L",$hash->{helper}{directions}{$2} // $dir{$2}) if (length $2);
+ if (!($hash->{helper}{Channels}{$channel} //$hash->{helper}{Channels}{$1})) {
+ for my $code (keys %OBIS_codes) {
+ if ($rmsg =~ $OBIS_codes{$code}) {
+ Log3 $hash,5,"Msg $rmsg is of type $code";
+ if ($code=~/Channel_sum.*/) {
+ $rmsg =~ $OBIS_codes{$code};
+ my $L= $hash->{helper}{Channels}{$channel} //$hash->{helper}{Channels}{$1} // "sum_$OBIS_channels{$1}" //$channel;
+ readingsBulkUpdate($hash, $L,(looks_like_number($3) ? $3+0 : $3).(AttrVal($name,"unitReadings","off") eq "off"?"":" $4"));
+ readingsBulkUpdate($hash, "dir_$L",$hash->{helper}{directions}{$2} // $dir{$2}) if (length $2);
+ }
+
+ elsif ($code=~/Channels.*/) {
+ $rmsg =~ $OBIS_codes{$code};
+ my $L=$hash->{helper}{Channels}{$channel} //$hash->{helper}{Channels}{$1} // $OBIS_channels{$1} //$channel;
+ readingsBulkUpdate($hash, "$L",(looks_like_number($3) ? $3+0 : $3).(AttrVal($name,"unitReadings","off") eq "off"?"":" $4"));
+ readingsBulkUpdate($hash, "dir_$L",$hash->{helper}{directions}{$2} // $dir{$2}) if (length $2);
+ }
+
+ elsif ($code=~/Counter.*/) {
+ $rmsg =~ $OBIS_codes{$code};
+ my $L=$hash->{helper}{Channels}{$channel} //$hash->{helper}{Channels}{$1.".".$2} // $OBIS_channels{$1.".".$2} // $channel;
+ my $chan=$3+0 > 0 ? "_Ch$3" : "";
+ if($1==1) {
+ readingsBulkUpdate($hash, $L.$chan ,(looks_like_number($3) ? $5+0 : $5) +AttrVal($name,"offset_energy",0).(AttrVal($name,"unitReadings","off") eq "off"?"":" $6"));
+ } elsif ($1==2) {
+ readingsBulkUpdate($hash, $L.$chan ,(looks_like_number($3) ? $5+0 : $5) +AttrVal($name,"offset_feed",0).(AttrVal($name,"unitReadings","off") eq "off"?"":" $6"));
+ }
+ readingsBulkUpdate($hash, "dir_$L",$hash->{helper}{directions}{$4} // $dir{$4}) if (length $4);
+
+ } else
+ {
+ $rmsg =~ $OBIS_codes{$code};
+ my $data=$1;
+ if($rmsg=~$SML_specialities{"HEX4"}[0]) {
+ $data=$SML_specialities{"HEX4"}[1]->($data)
+ } elsif($rmsg=~$SML_specialities{"HEX2"}[0]) {
+ $data=$SML_specialities{"HEX2"}[1]->($data)
+ } elsif($rmsg=~$SML_specialities{"TIME"}[0]) {
+ $data=~/(\d+)/;
+ $data=$SML_specialities{"TIME"}[1]->($1)
+ }
+ my $chan=$code//$OBIS_channels{$channel} //$channel;
+ $chan=$hash->{helper}{Channels}{$channel} //$hash->{helper}{Channels}{$1} // $OBIS_channels{$1} //$channel;
+
+ readingsBulkUpdate($hash, $chan ,$data);
+ }
+ $found=1;
+ last;
}
- elsif ($code=~/Counter.*/) {
- $rmsg =~ $OBIS_codes{$code};
- my $L=$hash->{helper}{Channels}{$channel} //$hash->{helper}{Channels}{$1.".".$2} // $OBIS_channels{$1.".".$2} // $channel;
- my $chan=$3+0 > 0 ? "_Ch$3" : "";
- if($1==1) {
- readingsBulkUpdate($hash, $L.$chan ,(looks_like_number($3) ? $5+0 : $5) +AttrVal($name,"offset_energy",0).(AttrVal($name,"unitReadings","off") eq "off"?"":" $6"));
- } elsif ($1==2) {
- readingsBulkUpdate($hash, $L.$chan ,(looks_like_number($3) ? $5+0 : $5) +AttrVal($name,"offset_feed",0).(AttrVal($name,"unitReadings","off") eq "off"?"":" $6"));
- }
- readingsBulkUpdate($hash, "dir_$L",$hash->{helper}{directions}{$4} // $dir{$4}) if (length $4);
-
- } else
- {
- $rmsg =~ $OBIS_codes{$code};
- my $data=$1;
- if($rmsg=~$SML_specialities{"HEX4"}[0]) {
- $data=$SML_specialities{"HEX4"}[1]->($data)
- } elsif($rmsg=~$SML_specialities{"HEX2"}[0]) {
- $data=$SML_specialities{"HEX2"}[1]->($data)
- } elsif($rmsg=~$SML_specialities{"TIME"}[0]) {
- $data=~/(\d+)/;
- $data=$SML_specialities{"TIME"}[1]->($1)
- }
- my $chan=$code//$OBIS_channels{$channel} //$channel;
- $chan=$hash->{helper}{Channels}{$channel} //$hash->{helper}{Channels}{$1} // $OBIS_channels{$1} //$channel;;
- readingsBulkUpdate($hash, $chan ,$data);
- }
- $found=1;
- last;
- }
-
- }
+ }
+ }
if ($found==0) {
- $rmsg=~/^((?:\d{1,3}-\d{1,3}:)?\d{1,3}.\d{1,3}.\d{1,3})(?:\*\d{1,3})?(?:\(.*?\))?\((.*?)(?:\*.*)?\)/;
- my $chan=$hash->{helper}{Channels}{$channel} //$hash->{helper}{Channels}{$1} // $OBIS_channels{$1} //$channel;;
- if (length $2) {
- if (AttrVal($name,"ignoreUnknown","off") eq "off" || $chan ne $channel) {readingsBulkUpdate($hash, $chan ,$2);}
- }
+ $rmsg=~/^((?:\d{1,3}-\d{1,3}:)?(?:\d{1,3}|[CF]).\d{1,3}(?:.\d{1,3})?(?:\*\d{1,3})?)(?:\((.*?)\))?\((.*?)\)/;
+ my $chan=$hash->{helper}{Channels}{$channel} //$hash->{helper}{Channels}{$1} // $OBIS_channels{$1} //$channel;
+ my $chan1=$chan;
+ my $chan2=$chan."_2";
+# Log 3,"Setting $chan";
+ my $v1=$3;
+ my $v2;
+ if (AttrVal($name,"valueBracket","second") eq "first") {
+ $v1=length $2 ? $2 : $3;
+ }
+ if (AttrVal($name,"valueBracket","second") eq "both") {
+ $v2=$2;
+ ($v1,$v2)=($v2,$v1);
+ if (!length $v1 and length $v2) {$v1=$v2;$v2=""}
+ $chan1.="_1" if length $2;
+ }
+ if (AttrVal($name,"unitReadings","off") eq "off") {
+ $v1=~s/(.*)\*.*/$1/;
+ $v2=~s/(.*)\*.*/$1/;
+ }
+ $v1+=0 if (looks_like_number($v1));
+ $v2+=0 if (looks_like_number($v2));
+ if (AttrVal($name,"ignoreUnknown","off") eq "off" || $chan ne $channel) {
+ readingsBulkUpdate($hash, $chan1 ,$v1) if length $v1;
+ readingsBulkUpdate($hash, $chan2 ,$v2) if length $v2;}
}
}
}
@@ -707,6 +735,9 @@ sub OBIS_decodeTL($){
Reduces CPU-load.
unitReadings
Adds the units to the readings like w, wH, A etc.
+ valueBracket
+ Sets, weather to use the value from the first or the second bracket, if applicable.
+ Standard is "second"
@@ -774,6 +805,9 @@ sub OBIS_decodeTL($){
kann das zu einer spürbaren Senkung der Prozessorleistung führen.
unitReadings
Hängt bei den Readings auch die Einheiten an, zB w, wH, A usw.
+ valueBracket
+ Legt fest, ob der Wert aus dem ersten oder zweiten Klammernpaar genommen wird.
+ Standard ist "second"