diff --git a/fhem/CHANGED b/fhem/CHANGED index b3fa831a6..eb98f3202 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,7 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - feature: 77_SMAEM: use OBIS metrics (Thx to RiG), change Readings Lx_THD + to Lx_Strom, new attribute "noCoprocess", some fixes - feature: 49_SSCam: new attributes snapChatTxt and recChatTxt to activate send snaps and recordings with SSChatBot (Synology Chat) - feature: 14_SD_WS_Maverick: added support for device TFA 14.1504 diff --git a/fhem/FHEM/77_SMAEM.pm b/fhem/FHEM/77_SMAEM.pm index 1dc45e944..4e40f7eb5 100644 --- a/fhem/FHEM/77_SMAEM.pm +++ b/fhem/FHEM/77_SMAEM.pm @@ -3,7 +3,7 @@ # # Copyright notice # -# (c) 2016 Copyright: Volker Kettenbach +# (c) 2016-2019 Copyright: Volker Kettenbach # e-mail: volker at kettenbach minus it dot de # # Credits: @@ -34,8 +34,10 @@ use IO::Socket::Multicast; use Blocking; eval "use FHEM::Meta;1" or my $modMetaAbsent = 1; -# Versions History done by DS_Starter +# Versions History by DS_Starter our %SMAEM_vNotesIntern = ( + "4.0.0" => "16.12.2019 change module to OBIS metric resolution, change Readings Lx_THD to Lx_Strom, FirmwareVersion to SoftwareVersion ". + "new attribute \"noCoprocess\", many internal code changes ", "3.5.0" => "14.12.2019 support of SMA Homemanager 2.0 >= 2.03.4.R, attribute \"serialNumber\", ". "delete hash keys by set reset, initial OBIS items resolution ", "3.4.0" => "22.05.2019 support of Installer.pm/Meta.pm added, new version maintenance, commandref revised ", @@ -63,62 +65,66 @@ our %SMAEM_vNotesIntern = ( # Beschreibung OBIS Kennzahlen our %SMAEM_obisitem = ( - "1:1.4.0" => "SUM Wirkleistung +", - "1:1.8.0" => "SUM Wirkleistung + Zaehler", - "1:2.4.0" => "SUM Wirkleistung −", - "1:2.8.0" => "SUM Wirkleistung − Zaehler", - "1:3.4.0" => "SUM Blindleistung +", - "1:3.8.0" => "SUM Blindleistung + Zaehler", - "1:4.4.0" => "SUM Blindleistung −", - "1:4.8.0" => "SUM Blindleistung − Zaehler", - "1:9.4.0" => "SUM Scheinleistung +", - "1:9.8.0" => "SUM Scheinleistung + Zaehler", - "1:10.4.0" => "SUM Scheinleistung −", - "1:10.8.0" => "SUM Scheinleistung − Zaehler", + "1:1.4.0" => "SUM Wirkleistung Bezug", + "1:1.8.0" => "SUM Wirkleistung Bezug Zaehler", + "1:2.4.0" => "SUM Wirkleistung Einspeisung", + "1:2.8.0" => "SUM Wirkleistung Einspeisung Zaehler", + "1:3.4.0" => "SUM Blindleistung Bezug", + "1:3.8.0" => "SUM Blindleistung Bezug Zaehler", + "1:4.4.0" => "SUM Blindleistung Einspeisung", + "1:4.8.0" => "SUM Blindleistung Einspeisung Zaehler", + "1:9.4.0" => "SUM Scheinleistung Bezug", + "1:9.8.0" => "SUM Scheinleistung Bezug Zaehler", + "1:10.4.0" => "SUM Scheinleistung Einspeisung", + "1:10.8.0" => "SUM Scheinleistung Einspeisung Zaehler", "1:13.4.0" => "SUM Leistungsfaktor", - "1:21.4.0" => "L1 Wirkleistung +", - "1:21.8.0" => "L1 Wirkleistung + Zaehler", - "1:22.4.0" => "L1 Wirkleistung −", - "1:22.8.0" => "L1 Wirkleistung − Zaehler", - "1:23.4.0" => "L1 Blindleistung +", - "1:23.8.0" => "L1 Blindleistung + Zaehler", - "1:24.4.0" => "L1 Blindleistung −", - "1:24.8.0" => "L1 Blindleistung − Zaehler", - "1:29.4.0" => "L1 Scheinleistung +", - "1:29.8.0" => "L1 Scheinleistung + Zaehler", - "1:30.4.0" => "L1 Scheinleistung −", - "1:30.8.0" => "L1 Scheinleistung − Zaehler", + "1:14.4.0" => "Netzfrequenz", + "1:21.4.0" => "L1 Wirkleistung Bezug", + "1:21.8.0" => "L1 Wirkleistung Bezug Zaehler", + "1:22.4.0" => "L1 Wirkleistung Einspeisung", + "1:22.8.0" => "L1 Wirkleistung Einspeisung Zaehler", + "1:23.4.0" => "L1 Blindleistung Bezug", + "1:23.8.0" => "L1 Blindleistung Bezug Zaehler", + "1:24.4.0" => "L1 Blindleistung Einspeisung", + "1:24.8.0" => "L1 Blindleistung Einspeisung Zaehler", + "1:29.4.0" => "L1 Scheinleistung Bezug", + "1:29.8.0" => "L1 Scheinleistung Bezug Zaehler", + "1:30.4.0" => "L1 Scheinleistung Einspeisung", + "1:30.8.0" => "L1 Scheinleistung Einspeisung Zaehler", "1:31.4.0" => "L1 Strom", "1:32.4.0" => "L1 Spannung", - "1:41.4.0" => "L2 Wirkleistung +", - "1:41.8.0" => "L2 Wirkleistung + Zaehler", - "1:42.4.0" => "L2 Wirkleistung −", - "1:42.8.0" => "L2 Wirkleistung − Zaehler", - "1:43.4.0" => "L2 Blindleistung +", - "1:43.8.0" => "L2 Blindleistung + Zaehler", - "1:44.4.0" => "L2 Blindleistung −", - "1:44.8.0" => "L2 Blindleistung − Zaehler", - "1:49.4.0" => "L2 Scheinleistung +", - "1:49.8.0" => "L2 Scheinleistung + Zaehler", - "1:50.4.0" => "L2 Scheinleistung −", - "1:50.8.0" => "L2 Scheinleistung − Zaehler", + "1:33.4.0" => "L1 Leistungsfaktor", + "1:41.4.0" => "L2 Wirkleistung Bezug", + "1:41.8.0" => "L2 Wirkleistung Bezug Zaehler", + "1:42.4.0" => "L2 Wirkleistung Einspeisung", + "1:42.8.0" => "L2 Wirkleistung Einspeisung Zaehler", + "1:43.4.0" => "L2 Blindleistung Bezug", + "1:43.8.0" => "L2 Blindleistung Bezug Zaehler", + "1:44.4.0" => "L2 Blindleistung Einspeisung", + "1:44.8.0" => "L2 Blindleistung Einspeisung Zaehler", + "1:49.4.0" => "L2 Scheinleistung Bezug", + "1:49.8.0" => "L2 Scheinleistung Bezug Zaehler", + "1:50.4.0" => "L2 Scheinleistung Einspeisung", + "1:50.8.0" => "L2 Scheinleistung Einspeisung Zaehler", "1:51.4.0" => "L2 Strom", "1:52.4.0" => "L2 Spannung", - "1:61.4.0" => "L3 Wirkleistung +", - "1:61.8.0" => "L3 Wirkleistung + Zaehler", - "1:62.4.0" => "L3 Wirkleistung −", - "1:62.8.0" => "L3 Wirkleistung − Zaehler", - "1:63.4.0" => "L3 Blindleistung +", - "1:63.8.0" => "L3 Blindleistung + Zaehler", - "1:64.4.0" => "L3 Blindleistung −", - "1:64.8.0" => "L3 Blindleistung − Zaehler", - "1:69.4.0" => "L3 Scheinleistung +", - "1:69.8.0" => "L3 Scheinleistung + Zaehler", - "1:70.4.0" => "L3 Scheinleistung −", - "1:70.8.0" => "L3 Scheinleistung − Zaehler", + "1:53.4.0" => "L2 Leistungsfaktor", + "1:61.4.0" => "L3 Wirkleistung Bezug", + "1:61.8.0" => "L3 Wirkleistung Bezug Zaehler", + "1:62.4.0" => "L3 Wirkleistung Einspeisung", + "1:62.8.0" => "L3 Wirkleistung Einspeisung Zaehler", + "1:63.4.0" => "L3 Blindleistung Bezug", + "1:63.8.0" => "L3 Blindleistung Bezug Zaehler", + "1:64.4.0" => "L3 Blindleistung Einspeisung", + "1:64.8.0" => "L3 Blindleistung Einspeisung Zaehler", + "1:69.4.0" => "L3 Scheinleistung Bezug", + "1:69.8.0" => "L3 Scheinleistung Bezug Zaehler", + "1:70.4.0" => "L3 Scheinleistung Einspeisung", + "1:70.8.0" => "L3 Scheinleistung Einspeisung Zaehler", "1:71.4.0" => "L3 Strom", "1:72.4.0" => "L3 Spannung", - "144:0.0.0" => "Softwareversion", + "1:73.4.0" => "L3 Leistungsfaktor", + "144:0.0.0" => "Software Version", ); ############################################################### @@ -132,7 +138,7 @@ sub SMAEM_Initialize ($) { $hash->{DefFn} = "SMAEM_Define"; $hash->{UndefFn} = "SMAEM_Undef"; $hash->{DeleteFn} = "SMAEM_Delete"; - $hash->{DbLog_splitFn} = "SMAEM_DbLog_splitFn"; + $hash->{DbLog_splitFn} = "SMAEM_DbLogSplit"; $hash->{DelayedShutdownFn} = "SMAEM_DelayedShutdown"; $hash->{AttrFn} = "SMAEM_Attr"; $hash->{AttrList} = "interval ". @@ -140,6 +146,7 @@ sub SMAEM_Initialize ($) { "diffAccept ". "disableSernoInReading:1,0 ". "feedinPrice ". + "noCoprocess:1,0 ". "powerCost ". "serialNumber ". "timeout ". @@ -352,15 +359,15 @@ sub SMAEM_Read ($) { return if(IsDisabled($name)); - $socket->recv($data, 608); + $socket->recv($data, 656); my $dl = length($data); if($dl == 600) { # Each SMAEM packet is 600 bytes of packed payload $model = "EM / HM 2.0 < 2.03.4.R"; } elsif($dl == 608) { # Each packet of HM with FW >= 2.03.4.R is 608 bytes of packed payload $model = "HM 2.0 >= 2.03.4.R"; } else { - Log3 ($name, 1, "SMAEM $name - Buffer length ".$dl." is invalid. Don't parse it."); - return; + $model = "unknown"; + Log3 ($name, 3, "SMAEM $name - Buffer length ".$dl." is not usual. May be your meter has been updated with a new firmware."); } return if (time() <= $hash->{HELPER}{STARTTIME}+30); @@ -403,13 +410,18 @@ sub SMAEM_Read ($) { my $dataenc = encode_base64($data,""); - $hash->{HELPER}{RUNNING_PID} = BlockingCall("SMAEM_DoParse", "$name|$dataenc|$smaserial|$dl", "SMAEM_ParseDone", $timeout, "SMAEM_ParseAborted", $hash); - Log3 ($name, 4, "SMAEM $name - Blocking process with PID: $hash->{HELPER}{RUNNING_PID}{pid} started"); + if(AttrVal($name, "noCoprocess", 0)) { + SMAEM_DoParse ("$name|$dataenc|$smaserial|$dl"); + } else { + $hash->{HELPER}{RUNNING_PID} = BlockingCall("SMAEM_DoParse", "$name|$dataenc|$smaserial|$dl", "SMAEM_ParseDone", $timeout, "SMAEM_ParseAborted", $hash); + $hash->{HELPER}{RUNNING_PID}{loglevel} = 5 if($hash->{HELPER}{RUNNING_PID}); # Forum #77057 + Log3 ($name, 4, "SMAEM $name - Blocking process with PID: $hash->{HELPER}{RUNNING_PID}{pid} started"); + } } else { - - Log3 $hash, 5, "SMAEM $name: - received ".$dl." bytes but interval $hash->{INTERVAL}s isn't expired."; + Log3 $hash, 5, "SMAEM $name - received ".$dl." bytes but interval $hash->{INTERVAL}s isn't expired."; } + return undef; } @@ -443,6 +455,7 @@ sub SMAEM_DoParse ($) { # Format of the udp packets of the SMAEM: # http://www.sma.de/fileadmin/content/global/Partner/Documents/SMA_Labs/EMETER-Protokoll-TI-de-10.pdf # http://www.eb-systeme.de/?page_id=1240 + # http://www.eb-systeme.de/?page_id=3005 # Conversion like in this python code: # http://www.unifox.at/sma_energy_meter/ @@ -453,40 +466,34 @@ sub SMAEM_DoParse ($) { # OBIS Kennzahlen Zerlegung my $obis = {}; - my $i = 56; # Start nach Header (28 Bytes) + my $i = 56; # Start nach Header (28 Bytes) my $length; - my ($b,$c,$d,$e); # OBIS Klassen - while (substr($hex,$i,8) ne "00000000" && $i<=($dl*4)) { - $b = hex(substr($hex,$i,2)); - $c = hex(substr($hex,$i+2,2)); - $d = hex(substr($hex,$i+4,2)); - $e = hex(substr($hex,$i+6,2)); - $length = $d*2; - if ($b == 144) { - # Firmware Version - $obis->{$b.":0.0.0"} = hex(substr($hex,$i+8,2)).".".sprintf("%02d", hex(substr($hex,$i+10,2))).".".sprintf("%02d", hex(substr($hex,$i+12,2))).".".chr(hex(substr($hex,$i+14,2))); - $i = $i + 16; - next; - } - $obis->{"1:".$c.".".$d.".".$e} = hex(substr($hex,$i+8,$length)); - $i = $i + 8 + $length; - } - - Log3 ($name, 5, "SMAEM $name - OBIS metrics identified:"); - foreach my $k (sort keys %{$obis}) { - my $item = $SMAEM_obisitem{$k}?$SMAEM_obisitem{$k}:"no item found"; - Log3 ($name, 5, "SMAEM $name - $k -> ".$item." -> ".$obis->{$k}); - } + my ($b,$c,$d,$e); # OBIS Klassen - # Entscheidung ob EM/HM2.0 mit Firmware >= 2.03.4.R - my $offset = 0; - my $grid_freq; - $hex =~ /.*000d0400.{8}(000e0400)(.*)(00150400).*/; - if($1 && $1 eq "000e0400") { - $grid_freq = hex($2)/1000; - $offset = 16; - } - Log3 ($name, 4, "SMAEM $name - Offset: $offset"); + while (substr($hex,$i,8) ne "00000000" && $i<=($dl*2)) { + $b = hex(substr($hex,$i,2)); + $c = hex(substr($hex,$i+2,2)); + $d = hex(substr($hex,$i+4,2)); + $e = hex(substr($hex,$i+6,2)); + $length = $d*2; + if ($b == 144) { + # Firmware Version + $obis->{$b.":0.0.0"} = hex(substr($hex,$i+8,2)).".".sprintf("%02d", hex(substr($hex,$i+10,2))).".".sprintf("%02d", hex(substr($hex,$i+12,2))).".".chr(hex(substr($hex,$i+14,2))); + $i = $i + 16; + next; + } + $obis->{"1:".$c.".".$d.".".$e} = hex(substr($hex,$i+8,$length)); + $i = $i + 8 + $length; + } + + Log3 ($name, 5, "SMAEM $name - OBIS metrics identified:"); + my @ui; # Array für "unknown items" + foreach my $k (sort keys %{$obis}) { + my $uit = "unknown item"; + my $item = $SMAEM_obisitem{$k}?$SMAEM_obisitem{$k}:$uit; + push(@ui, $k) if($item eq $uit); + Log3 ($name, 5, "SMAEM $name - $k -> ".$item." -> ".$obis->{$k}); + } ################ Aufbau Ergebnis-Array #################### # Extract datasets from hex: @@ -498,12 +505,12 @@ sub SMAEM_DoParse ($) { # Prestring with SMAEM and SERIALNO or not my $ps = (!AttrVal($name, "disableSernoInReading", undef)) ? "SMAEM".$smaserial."_" : ""; - # Counter Divisor: [Hex-Value]=Ws => Ws/1000*3600=kWh => divide by 3600000 - # Sum L1-3 - my $bezug_wirk = hex(substr($hex,64,8))/10; - my $bezug_wirk_count = hex(substr($hex,80,16))/3600000; - my $einspeisung_wirk = hex(substr($hex,104,8))/10; - my $einspeisung_wirk_count = hex(substr($hex,120,16))/3600000; + # Counter Divisor: [Hex-Value] = Ws => Ws/1000*3600=kWh => divide by 3600000 + # Sum L1-L3 + my $bezug_wirk = $obis->{"1:1.4.0"}/10; + my $bezug_wirk_count = $obis->{"1:1.8.0"}/3600000; + my $einspeisung_wirk = $obis->{"1:2.4.0"}/10; + my $einspeisung_wirk_count = $obis->{"1:2.8.0"}/3600000; # calculation of GRID-hashes and persist to file Log3 ($name, 4, "SMAEM $name - old GRIDIN_SUM_$smaserial got from RAM: $gridinsum"); @@ -577,9 +584,13 @@ sub SMAEM_DoParse ($) { # error while writing values to file if ($retcode) { - $error = encode_base64($retcode,""); - $discycles++; - return "$name|''|''|''|$error|$discycles|''"; + $error = encode_base64($retcode,""); + $discycles++; + if(AttrVal($name, "noCoprocess", 0)) { + return SMAEM_ParseDone("$name|''|''|''|$error|$discycles|''"); + } else { + return "$name|''|''|''|$error|$discycles|''"; + } } push(@row_array, "state ".sprintf("%.1f", $einspeisung_wirk-$bezug_wirk)."\n"); @@ -590,37 +601,44 @@ sub SMAEM_DoParse ($) { push(@row_array, $ps."Einspeisung_Wirkleistung ".sprintf("%.1f",$einspeisung_wirk)."\n"); push(@row_array, $ps."Einspeisung_Wirkleistung_Zaehler ".sprintf("%.4f",$einspeisung_wirk_count)."\n"); - my $bezug_blind = hex(substr($hex,144,8))/10; - my $bezug_blind_count = hex(substr($hex,160,16))/3600000; - my $einspeisung_blind = hex(substr($hex,184,8))/10; - my $einspeisung_blind_count = hex(substr($hex,200,16))/3600000; + my $bezug_blind = $obis->{"1:3.4.0"}/10; + my $bezug_blind_count = $obis->{"1:3.8.0"}/3600000; + my $einspeisung_blind = $obis->{"1:4.4.0"}/10; + my $einspeisung_blind_count = $obis->{"1:4.8.0"}/3600000; push(@row_array, $ps."Bezug_Blindleistung ".sprintf("%.1f",$bezug_blind)."\n"); push(@row_array, $ps."Bezug_Blindleistung_Zaehler ".sprintf("%.1f",$bezug_blind_count)."\n"); push(@row_array, $ps."Einspeisung_Blindleistung ".sprintf("%.1f",$einspeisung_blind)."\n"); push(@row_array, $ps."Einspeisung_Blindleistung_Zaehler ".sprintf("%.1f",$einspeisung_blind_count)."\n"); - my $bezug_schein = hex(substr($hex,224,8))/10; - my $bezug_schein_count = hex(substr($hex,240,16))/3600000; - my $einspeisung_schein = hex(substr($hex,264,8))/10; - my $einspeisung_schein_count = hex(substr($hex,280,16))/3600000; + my $bezug_schein = $obis->{"1:9.4.0"}/10; + my $bezug_schein_count = $obis->{"1:9.8.0"}/3600000; + my $einspeisung_schein = $obis->{"1:10.4.0"}/10; + my $einspeisung_schein_count = $obis->{"1:10.8.0"}/3600000; push(@row_array, $ps."Bezug_Scheinleistung ".sprintf("%.1f",$bezug_schein)."\n"); push(@row_array, $ps."Bezug_Scheinleistung_Zaehler ".sprintf("%.1f",$bezug_schein_count)."\n"); push(@row_array, $ps."Einspeisung_Scheinleistung ".sprintf("%.1f",$einspeisung_schein)."\n"); push(@row_array, $ps."Einspeisung_Scheinleistung_Zaehler ".sprintf("%.1f",$einspeisung_schein_count)."\n"); - my $cosphi = hex(substr($hex,304,8))/1000; + my $cosphi = $obis->{"1:13.4.0"}/1000; push(@row_array, $ps."CosPhi ".sprintf("%.3f",$cosphi)."\n"); - push(@row_array, $ps."GridFreq ".$grid_freq."\n") if($grid_freq); - push(@row_array, $ps."FirmwareVersion ".$obis->{"144:0.0.0"}."\n"); - push(@row_array, "SerialNumber ".$smaserial."\n") if(!$ps); + my $grid_freq = $obis->{"1:14.4.0"}/1000; + push(@row_array, $ps."GridFreq ".$grid_freq."\n") if($grid_freq); + + push(@row_array, $ps."SoftwareVersion ".$obis->{"144:0.0.0"}."\n"); + push(@row_array, "SerialNumber ".$smaserial."\n") if(!$ps); push(@row_array, $ps."SUSyID ".$susyid."\n"); + + if(!@ui) { + push(@ui, "none"); # Wenn kein unbekanntes OBIS Item identifiziert wurde + } + push(@row_array, "OBISnewItems ".join(",",@ui)."\n"); # L1 - my $l1_bezug_wirk = hex(substr($hex,320+$offset,8))/10; - my $l1_bezug_wirk_count = hex(substr($hex,336+$offset,16))/3600000; - my $l1_einspeisung_wirk = hex(substr($hex,360+$offset,8))/10; - my $l1_einspeisung_wirk_count = hex(substr($hex,376+$offset,16))/3600000; + my $l1_bezug_wirk = $obis->{"1:21.4.0"}/10; + my $l1_bezug_wirk_count = $obis->{"1:21.8.0"}/3600000; + my $l1_einspeisung_wirk = $obis->{"1:22.4.0"}/10; + my $l1_einspeisung_wirk_count = $obis->{"1:22.8.0"}/3600000; push(@row_array, $ps."L1_Saldo_Wirkleistung ".sprintf("%.1f",$l1_einspeisung_wirk-$l1_bezug_wirk)."\n"); push(@row_array, $ps."L1_Saldo_Wirkleistung_Zaehler ".sprintf("%.1f",$l1_einspeisung_wirk_count-$l1_bezug_wirk_count)."\n"); push(@row_array, $ps."L1_Bezug_Wirkleistung ".sprintf("%.1f",$l1_bezug_wirk)."\n"); @@ -628,36 +646,36 @@ sub SMAEM_DoParse ($) { push(@row_array, $ps."L1_Einspeisung_Wirkleistung ".sprintf("%.1f",$l1_einspeisung_wirk)."\n"); push(@row_array, $ps."L1_Einspeisung_Wirkleistung_Zaehler ".sprintf("%.1f",$l1_einspeisung_wirk_count)."\n"); - my $l1_bezug_blind = hex(substr($hex,400+$offset,8))/10; - my $l1_bezug_blind_count = hex(substr($hex,416+$offset,16))/3600000; - my $l1_einspeisung_blind = hex(substr($hex,440+$offset,8))/10; - my $l1_einspeisung_blind_count = hex(substr($hex,456+$offset,16))/3600000; + my $l1_bezug_blind = $obis->{"1:23.4.0"}/10; + my $l1_bezug_blind_count = $obis->{"1:23.8.0"}/3600000; + my $l1_einspeisung_blind = $obis->{"1:24.4.0"}/10; + my $l1_einspeisung_blind_count = $obis->{"1:24.8.0"}/3600000; push(@row_array, $ps."L1_Bezug_Blindleistung ".sprintf("%.1f",$l1_bezug_blind)."\n"); push(@row_array, $ps."L1_Bezug_Blindleistung_Zaehler ".sprintf("%.1f",$l1_bezug_blind_count)."\n"); push(@row_array, $ps."L1_Einspeisung_Blindleistung ".sprintf("%.1f",$l1_einspeisung_blind)."\n"); push(@row_array, $ps."L1_Einspeisung_Blindleistung_Zaehler ".sprintf("%.1f",$l1_einspeisung_blind_count)."\n"); - my $l1_bezug_schein = hex(substr($hex,480+$offset,8))/10; - my $l1_bezug_schein_count = hex(substr($hex,496+$offset,16))/3600000; - my $l1_einspeisung_schein = hex(substr($hex,520+$offset,8))/10; - my $l1_einspeisung_schein_count = hex(substr($hex,536+$offset,16))/3600000; + my $l1_bezug_schein = $obis->{"1:29.4.0"}/10; + my $l1_bezug_schein_count = $obis->{"1:29.8.0"}/3600000; + my $l1_einspeisung_schein = $obis->{"1:30.4.0"}/10; + my $l1_einspeisung_schein_count = $obis->{"1:30.8.0"}/3600000; push(@row_array, $ps."L1_Bezug_Scheinleistung ".sprintf("%.1f",$l1_bezug_schein)."\n"); push(@row_array, $ps."L1_Bezug_Scheinleistung_Zaehler ".sprintf("%.1f",$l1_bezug_schein_count)."\n"); push(@row_array, $ps."L1_Einspeisung_Scheinleistung ".sprintf("%.1f",$l1_einspeisung_schein)."\n"); push(@row_array, $ps."L1_Einspeisung_Scheinleistung_Zaehler ".sprintf("%.1f",$l1_einspeisung_schein_count)."\n"); - my $l1_thd = hex(substr($hex,560+$offset,8))/1000; - my $l1_v = hex(substr($hex,576+$offset,8))/1000; - my $l1_cosphi = hex(substr($hex,592+$offset,8))/1000; - push(@row_array, $ps."L1_THD ".sprintf("%.2f",$l1_thd)."\n"); + my $l1_i = $obis->{"1:31.4.0"}/1000; + my $l1_v = $obis->{"1:32.4.0"}/1000; + my $l1_cosphi = $obis->{"1:33.4.0"}/1000; + push(@row_array, $ps."L1_Strom ".sprintf("%.2f",$l1_i)."\n"); push(@row_array, $ps."L1_Spannung ".sprintf("%.1f",$l1_v)."\n"); push(@row_array, $ps."L1_CosPhi ".sprintf("%.3f",$l1_cosphi)."\n"); # L2 - my $l2_bezug_wirk = hex(substr($hex,608+$offset,8))/10; - my $l2_bezug_wirk_count = hex(substr($hex,624+$offset,16))/3600000; - my $l2_einspeisung_wirk = hex(substr($hex,648+$offset,8))/10; - my $l2_einspeisung_wirk_count = hex(substr($hex,664+$offset,16))/3600000; + my $l2_bezug_wirk = $obis->{"1:41.4.0"}/10; + my $l2_bezug_wirk_count = $obis->{"1:41.8.0"}/3600000; + my $l2_einspeisung_wirk = $obis->{"1:42.4.0"}/10; + my $l2_einspeisung_wirk_count = $obis->{"1:42.8.0"}/3600000; push(@row_array, $ps."L2_Saldo_Wirkleistung ".sprintf("%.1f",$l2_einspeisung_wirk-$l2_bezug_wirk)."\n"); push(@row_array, $ps."L2_Saldo_Wirkleistung_Zaehler ".sprintf("%.1f",$l2_einspeisung_wirk_count-$l2_bezug_wirk_count)."\n"); push(@row_array, $ps."L2_Bezug_Wirkleistung ".sprintf("%.1f",$l2_bezug_wirk)."\n"); @@ -665,36 +683,36 @@ sub SMAEM_DoParse ($) { push(@row_array, $ps."L2_Einspeisung_Wirkleistung ".sprintf("%.1f",$l2_einspeisung_wirk)."\n"); push(@row_array, $ps."L2_Einspeisung_Wirkleistung_Zaehler ".sprintf("%.1f",$l2_einspeisung_wirk_count)."\n"); - my $l2_bezug_blind = hex(substr($hex,688+$offset,8))/10; - my $l2_bezug_blind_count = hex(substr($hex,704+$offset,16))/3600000; - my $l2_einspeisung_blind = hex(substr($hex,728+$offset,8))/10; - my $l2_einspeisung_blind_count = hex(substr($hex,744+$offset,16))/3600000; + my $l2_bezug_blind = $obis->{"1:43.4.0"}/10; + my $l2_bezug_blind_count = $obis->{"1:43.8.0"}/3600000; + my $l2_einspeisung_blind = $obis->{"1:44.4.0"}/10; + my $l2_einspeisung_blind_count = $obis->{"1:44.8.0"}/3600000; push(@row_array, $ps."L2_Bezug_Blindleistung ".sprintf("%.1f",$l2_bezug_blind)."\n"); push(@row_array, $ps."L2_Bezug_Blindleistung_Zaehler ".sprintf("%.1f",$l2_bezug_blind_count)."\n"); push(@row_array, $ps."L2_Einspeisung_Blindleistung ".sprintf("%.1f",$l2_einspeisung_blind)."\n"); push(@row_array, $ps."L2_Einspeisung_Blindleistung_Zaehler ".sprintf("%.1f",$l2_einspeisung_blind_count)."\n"); - my $l2_bezug_schein = hex(substr($hex,768+$offset,8))/10; - my $l2_bezug_schein_count = hex(substr($hex,784+$offset,16))/3600000; - my $l2_einspeisung_schein = hex(substr($hex,808+$offset,8))/10; - my $l2_einspeisung_schein_count = hex(substr($hex,824+$offset,16))/3600000; + my $l2_bezug_schein = $obis->{"1:49.4.0"}/10; + my $l2_bezug_schein_count = $obis->{"1:49.8.0"}/3600000; + my $l2_einspeisung_schein = $obis->{"1:50.4.0"}/10; + my $l2_einspeisung_schein_count = $obis->{"1:50.8.0"}/3600000; push(@row_array, $ps."L2_Bezug_Scheinleistung ".sprintf("%.1f",$l2_bezug_schein)."\n"); push(@row_array, $ps."L2_Bezug_Scheinleistung_Zaehler ".sprintf("%.1f",$l2_bezug_schein_count)."\n"); push(@row_array, $ps."L2_Einspeisung_Scheinleistung ".sprintf("%.1f",$l2_einspeisung_schein)."\n"); push(@row_array, $ps."L2_Einspeisung_Scheinleistung_Zaehler ".sprintf("%.1f",$l2_einspeisung_schein_count)."\n"); - my $l2_thd = hex(substr($hex,848+$offset,8))/1000; - my $l2_v = hex(substr($hex,864+$offset,8))/1000; - my $l2_cosphi = hex(substr($hex,880+$offset,8))/1000; - push(@row_array, $ps."L2_THD ".sprintf("%.2f",$l2_thd)."\n"); + my $l2_i = $obis->{"1:51.4.0"}/1000; + my $l2_v = $obis->{"1:52.4.0"}/1000; + my $l2_cosphi = $obis->{"1:53.4.0"}/1000; + push(@row_array, $ps."L2_Strom ".sprintf("%.2f",$l2_i)."\n"); push(@row_array, $ps."L2_Spannung ".sprintf("%.1f",$l2_v)."\n"); push(@row_array, $ps."L2_CosPhi ".sprintf("%.3f",$l2_cosphi)."\n"); # L3 - my $l3_bezug_wirk = hex(substr($hex,896+$offset,8))/10; - my $l3_bezug_wirk_count = hex(substr($hex,912+$offset,16))/3600000; - my $l3_einspeisung_wirk = hex(substr($hex,936+$offset,8))/10; - my $l3_einspeisung_wirk_count = hex(substr($hex,952+$offset,16))/3600000; + my $l3_bezug_wirk = $obis->{"1:61.4.0"}/10; + my $l3_bezug_wirk_count = $obis->{"1:61.8.0"}/3600000; + my $l3_einspeisung_wirk = $obis->{"1:62.4.0"}/10; + my $l3_einspeisung_wirk_count = $obis->{"1:62.8.0"}/3600000; push(@row_array, $ps."L3_Saldo_Wirkleistung ".sprintf("%.1f",$l3_einspeisung_wirk-$l3_bezug_wirk)."\n"); push(@row_array, $ps."L3_Saldo_Wirkleistung_Zaehler ".sprintf("%.1f",$l3_einspeisung_wirk_count-$l3_bezug_wirk_count)."\n"); push(@row_array, $ps."L3_Bezug_Wirkleistung ".sprintf("%.1f",$l3_bezug_wirk)."\n"); @@ -702,28 +720,28 @@ sub SMAEM_DoParse ($) { push(@row_array, $ps."L3_Einspeisung_Wirkleistung ".sprintf("%.1f",$l3_einspeisung_wirk)."\n"); push(@row_array, $ps."L3_Einspeisung_Wirkleistung_Zaehler ".sprintf("%.1f",$l3_einspeisung_wirk_count)."\n"); - my $l3_bezug_blind = hex(substr($hex,976+$offset,8))/10; - my $l3_bezug_blind_count = hex(substr($hex,992+$offset,16))/3600000; - my $l3_einspeisung_blind = hex(substr($hex,1016+$offset,8))/10; - my $l3_einspeisung_blind_count = hex(substr($hex,1032+$offset,16))/3600000; + my $l3_bezug_blind = $obis->{"1:63.4.0"}/10; + my $l3_bezug_blind_count = $obis->{"1:63.8.0"}/3600000; + my $l3_einspeisung_blind = $obis->{"1:64.4.0"}/10; + my $l3_einspeisung_blind_count = $obis->{"1:64.8.0"}/3600000; push(@row_array, $ps."L3_Bezug_Blindleistung ".sprintf("%.1f",$l3_bezug_blind)."\n"); push(@row_array, $ps."L3_Bezug_Blindleistung_Zaehler ".sprintf("%.1f",$l3_bezug_blind_count)."\n"); push(@row_array, $ps."L3_Einspeisung_Blindleistung ".sprintf("%.1f",$l3_einspeisung_blind)."\n"); push(@row_array, $ps."L3_Einspeisung_Blindleistung_Zaehler ".sprintf("%.1f",$l3_einspeisung_blind_count)."\n"); - my $l3_bezug_schein = hex(substr($hex,1056+$offset,8))/10; - my $l3_bezug_schein_count = hex(substr($hex,1072+$offset,16))/3600000; - my $l3_einspeisung_schein = hex(substr($hex,1096+$offset,8))/10; - my $l3_einspeisung_schein_count = hex(substr($hex,1112+$offset,16))/3600000; + my $l3_bezug_schein = $obis->{"1:69.4.0"}/10; + my $l3_bezug_schein_count = $obis->{"1:69.8.0"}/3600000; + my $l3_einspeisung_schein = $obis->{"1:70.4.0"}/10; + my $l3_einspeisung_schein_count = $obis->{"1:70.8.0"}/3600000; push(@row_array, $ps."L3_Bezug_Scheinleistung ".sprintf("%.1f",$l3_bezug_schein)."\n"); push(@row_array, $ps."L3_Bezug_Scheinleistung_Zaehler ".sprintf("%.1f",$l3_bezug_schein_count)."\n"); push(@row_array, $ps."L3_Einspeisung_Scheinleistung ".sprintf("%.1f",$l3_einspeisung_schein)."\n"); push(@row_array, $ps."L3_Einspeisung_Scheinleistung_Zaehler ".sprintf("%.1f",$l3_einspeisung_schein_count)."\n"); - my $l3_thd = hex(substr($hex,1136+$offset,8))/1000; - my $l3_v = hex(substr($hex,1152+$offset,8))/1000; - my $l3_cosphi = hex(substr($hex,1168+$offset,8))/1000; - push(@row_array, $ps."L3_THD ".sprintf("%.2f",$l3_thd)."\n"); + my $l3_i = $obis->{"1:71.4.0"}/1000; + my $l3_v = $obis->{"1:72.4.0"}/1000; + my $l3_cosphi = $obis->{"1:73.4.0"}/1000; + push(@row_array, $ps."L3_Strom ".sprintf("%.2f",$l3_i)."\n"); push(@row_array, $ps."L3_Spannung ".sprintf("%.1f",$l3_v)."\n"); push(@row_array, $ps."L3_CosPhi ".sprintf("%.3f",$l3_cosphi)."\n"); @@ -731,7 +749,11 @@ sub SMAEM_DoParse ($) { my $rowlist = join('_ESC_', @row_array); $rowlist = encode_base64($rowlist,""); -return "$name|$rowlist|$gridinsum|$gridoutsum|''|$discycles|$smaserial"; + if(AttrVal($name, "noCoprocess", 0)) { + return SMAEM_ParseDone ("$name|$rowlist|$gridinsum|$gridoutsum|''|$discycles|$smaserial"); + } else { + return "$name|$rowlist|$gridinsum|$gridoutsum|''|$discycles|$smaserial"; + } } ############################################################### @@ -759,13 +781,13 @@ sub SMAEM_ParseDone ($) { delete($hash->{HELPER}{RUNNING_PID}); return; } - + $hash->{'GRIDIN_SUM_'.$smaserial} = $gridinsum; $hash->{'GRIDOUT_SUM_'.$smaserial} = $gridoutsum; Log3($name, 4, "SMAEM $name - wrote new energy values to INTERNALS - GRIDIN_SUM_$smaserial: $gridinsum, GRIDOUT_SUM_$smaserial: $gridoutsum"); my @row_array = split("_ESC_", $rowlist); - + readingsBeginUpdate($hash); foreach my $row (@row_array) { chomp $row; @@ -773,7 +795,7 @@ sub SMAEM_ParseDone ($) { readingsBulkUpdate($hash, $a[0], $a[1]); } readingsEndUpdate($hash, 1); - + delete($hash->{HELPER}{RUNNING_PID}); CancelDelayedShutdown($name); @@ -802,7 +824,7 @@ return; ############################################################### # DbLog_splitFn ############################################################### -sub SMAEM_DbLog_splitFn ($) { +sub SMAEM_DbLogSplit ($) { my ($event,$device) = @_; my ($reading, $value, $unit) = ""; @@ -815,10 +837,10 @@ sub SMAEM_DbLog_splitFn ($) { $unit = 'W'; } elsif($reading =~ m/.*Spannung/) { $unit = 'V'; + } elsif($reading =~ m/.*Strom/) { + $unit = 'A'; } elsif($reading =~ m/.*leistung_Zaehler$/) { $unit = 'kWh'; - } elsif($reading =~ m/.*THD$/) { - $unit = '%'; } else { if(!defined($parts[1])) { $reading = "state"; @@ -830,8 +852,7 @@ sub SMAEM_DbLog_splitFn ($) { } } - Log3 ($device, 5, "SMAEM $device - splitFn returns Reading: ".$reading.", Value: ". - defined($value)?$value:''.", Unit: ".defined($unit)?$unit:''); + Log3 ($device, 5, "SMAEM $device - Split for DbLog done -> Reading: ".$reading.", Value: ".(defined($value)?$value:'').", Unit: ".(defined($unit)?$unit:'')); return ($reading, $value, $unit); } @@ -1100,7 +1121,7 @@ return;