diff --git a/fhem/contrib/MadMax/76_SMAInverter.pm b/fhem/contrib/MadMax/76_SMAInverter.pm index 8f3e7ab7a..69ff37373 100644 --- a/fhem/contrib/MadMax/76_SMAInverter.pm +++ b/fhem/contrib/MadMax/76_SMAInverter.pm @@ -1,5 +1,5 @@ ################################################################################################################# -# $Id: 76_SMAInverter.pm 23909 2021-03-07 20:06:59Z DS_Starter $ +# $Id: 76_SMAInverter.pm 29075 2024-08-17 10:10:54Z MadMax $ ################################################################################################################# # # Copyright notice @@ -32,6 +32,45 @@ eval "use FHEM::Meta;1" or my $modMetaAbsent = 1; # Versions History by DS_Starter our %SMAInverter_vNotesIntern = ( + "2.25.3" => "16.08.2024 fix IDC2 bug 3MPP", + "2.25.2" => "16.08.2024 fix IDC3 bug", + "2.25.1" => "21.04.2024 read Bat_Status", + "2.25.0" => "23.03.2024 PW Lengs set so max 18", + "2.24.1" => "10.03.2024 GridConection (SI only)", + "2.24.0" => "08.03.2024 add GridConection (SI/Hybrid-Inverter)", + "2.23.8" => "21.01.2024 Voltage L1-L2-L3 bug", + "2.23.7" => "25.12.2023 add DC-Power PV-Inverter", + "2.23.6" => "24.09.2023 add BAT_P_Charge/Discarge", + "2.23.5" => "25.06.2023 buxfix line 1267", + "2.23.4" => "20.06.2023 buxfix DC-Power 2.0", + "2.23.3" => "19.06.2023 buxfix DC-Power", + "2.23.2" => "20.05.2023 add new SMAInverter_StatusText", + "2.23.1" => "19.05.2023 add String 3 (only STP X Inverter)", + "2.23.0" => "14.05.2023 read firmware version", + "2.22.2" => "01.05.2023 fix name STPxxSE". + "add new Readings (GeneralOperatingStatus, OperatingStatus, BACKRELAYRELAY)", + "2.22.1" => "23.04.2023 add STP X", + "2.22.0" => "03.04.2023 add SI x.xM-13", + "2.21.6" => "12.02.2023 read PV-Power (DC) from Hybridinverter, set state to PV-Power (Hybridinverter)", + "2.21.5" => "08.02.2023 bugfix reset TODAY Counter", + "2.21.4" => "28.01.2023 bugfix save INVCLASS && INVTYPE", + "2.21.3" => "26.01.2023 bugfix SBFSpotComp reset DAYCOUNTER", + "2.21.2" => "18.01.2023 fix reset TODAY Counter Batterry/PV only Hybrid/Batterie-Inverter", + "2.21.1" => "16.01.2023 fix reset TODAY Counter", + "2.21.0" => "15.01.2023 read EM-Data, disable suppressSleep (Batterie/Hybrid-Inverter)". + "add more Meterdata, add Backup Curre & Power (only Hybrid-Inverter)". + "set ETODAY, EPVTODAY, LOADTODAY, UNLOADTODAY at 0 out of opertime (https://forum.fhem.de/index.php/topic,56080.msg1257950.html#msg1257950)", + "2.20.3" => "15.01.2023 fix show FVERSION ", + "2.20.2" => "12.01.2023 new read SPOT_EPVTOTAL / SPOT_EPVTODAY (Hybrid Inverter)", + "2.20.1" => "09.01.2023 fix BAT_UNLOADTODAY calculate", + "2.20.0" => "08.01.2023 crypt Password", + "2.19.1" => "07.01.2023 new read BAT_UNLOADTODAY / BAT_UNLOADTOTAL, included by 300P,", + "2.19.0" => "04.01.2023 new read BAT_CAPACITY, included by 300P,", + "2.18.3" => "11.10.2022 fix new ETOTAL/LOADTOTAL bug 2.0 ;)", + "2.18.2" => "09.10.2022 fix new ETOTAL/LOADTOTAL bug", + "2.18.1" => "03.10.2022 new SE Inverters fix BAT-Data, fix ETODAY bug", + "2.18.0" => "30.09.2022 new SE Inverters", + "2.17.1" => "12.07.2021 fix ETOTAL/LOADTOTAL bug", "2.17.0" => "01.07.2021 fix ETOTAL/LOADTOTAL bug", "2.16.1" => "21.06.2021 hide unavailable data", "2.16.0" => "21.06.2021 AC Voltage and AC Curren read fixed, read CosPhi included ", @@ -133,6 +172,9 @@ our %SMAInverter_vNotesIntern = ( # $inv_STATUS # Inverter Status # $inv_BAT_LOADTODAY # Today Batteryload # $inv_BAT_LOADTOTAL # Total Batteryload +# $inv_BAT_CAPACITY # Battery Capacity (Percent) #TTT +# $inv_BAT_UNLOADTODAY # Today Batteryunload +# $inv_BAT_UNLOADTOTAL # Total Batteryunload # Aufbau Wechselrichter Type-Hash # https://github.com/SBFspot/SBFspot/blob/master/SBFspot/TagListDE-DE.txt @@ -272,6 +314,18 @@ my %SMAInverter_devtypes = ( 9403 => "SB4.0-1AV-41 (Sunny Boy 4.0 AV-41)", 9404 => "SB5.0-1AV-41 (Sunny Boy 5.0 AV-41)", 9405 => "SB6.0-1AV-41 (Sunny Boy 6.0 AV-41)", +9473 => "SI 3.0M-13 (Sunny Island 3.0M)", +9474 => "SI 4.4M-13 (Sunny Island 4.4M)", +9475 => "SI 6.0H-13 (Sunny Island 6.0H)", +9476 => "SI 8.0H-13 (Sunny Island 8.0H)", +19048 => "STP5.0SE (SUNNY TRIPOWER 5.0 SE)", +19049 => "STP6.0SE (SUNNY TRIPOWER 6.0 SE)", +19050 => "STP8.0SE (SUNNY TRIPOWER 8.0 SE)", +19051 => "STP10.0SE (SUNNY TRIPOWER 10.0 SE)", +9490 => "STP X 50-12 (SUNNY TRIPOWER X 50-12)", +9491 => "STP X 50-15 (SUNNY TRIPOWER X 50-15)", +9492 => "STP X 50-20 (SUNNY TRIPOWER X 50-20)", +9488 => "STP X 50-25 (SUNNY TRIPOWER X 50-25)", ); # Wechselrichter Class-Hash DE @@ -280,6 +334,7 @@ my %SMAInverter_classesDE = ( 8001 => "Solar-Wechselrichter", 8002 => "Wind-Wechselrichter", 8007 => "Batterie-Wechselrichter", +8009 => "Hybrid-Wechselrichter", 8033 => "Verbraucher", 8064 => "Sensorik allgemein", 8065 => "Stromzähler", @@ -292,6 +347,7 @@ my %SMAInverter_classesEN = ( 8001 => "Solar Inverters", 8002 => "Wind Turbine Inverter", 8007 => "Batterie Inverters", +8009 => "Hybrid Inverters", 8033 => "Consumer", 8064 => "Sensor System in General", 8065 => "Electricity meter", @@ -309,6 +365,7 @@ sub SMAInverter_Initialize($) { $hash->{GetFn} = "SMAInverter_Get"; $hash->{AttrList} = "interval " . "detail-level:0,1,2 " . + "readEnergyMeter-data:0,1 " . "disable:1,0 " . "mode:manual,automatic ". "offset ". @@ -341,6 +398,12 @@ sub SMAInverter_Define($$) { return "Wrong syntax: use define SMAInverter " if ((int(@a) < 4) and (int(@a) > 5)); + my $Pass = $a[2]; + my $password = SMAInverter_SMAencrypt($Pass); + $Pass = SMAInverter_SMAdecrypt( $password ); + + return "passwort longer then 18 char" if(length $Pass > 18); #check 1-18 Chars + my $name = $hash->{NAME}; $hash->{LASTUPDATE} = 0; $hash->{INTERVAL} = $hash->{HELPER}{INTERVAL} = AttrVal($name, "interval", 60); @@ -355,14 +418,14 @@ sub SMAInverter_Define($$) { $hash->{HELPER}{PKT_ID} = 0x8001; # Packet ID $hash->{HELPER}{MAXBYTES} = 300; # constant MAXBYTES scalar 300 $hash->{HELPER}{MODMETAABSENT} = 1 if($modMetaAbsent); # Modul Meta.pm nicht vorhanden - + # Versionsinformationen setzen SMAInverter_setVersionInfo($hash); my ($IP,$Host,$Caps); - my $Pass = $a[2]; # to do: check 1-12 Chars + # extract IP or Hostname from $a[3] if (!defined $Host) { if ( $a[3] =~ /^([A-Za-z0-9_.])/ ) { @@ -374,7 +437,8 @@ sub SMAInverter_Define($$) { return "Argument:{$a[3]} not accepted as Host or IP. Read device specific help file."; } - $hash->{PASS} = $Pass; + $hash->{DEF} = "$password $Host"; + $hash->{PASS} = $password; $hash->{HOST} = $Host; InternalTimer(gettimeofday()+5, "SMAInverter_GetData", $hash, 0); # Start Hauptroutine @@ -481,6 +545,50 @@ sub SMAInverter_Attr(@) { return; } +########################################################################## +# Encrypt Passwort/Username übernommen aus 76_SMAEVCharger.pm author: Jürgen Allmich +########################################################################## + +sub SMAInverter_SMAencrypt($) +{ + my ($decoded) = @_; + my $key = getUniqueId(); + my $encoded; + + return $decoded if( $decoded =~ /crypt:/ ); + + for my $char (split //, $decoded) { + my $encode = chop($key); + $encoded .= sprintf("%.2x",ord($char)^ord($encode)); + $key = $encode.$key; + } + + return 'crypt:'.$encoded; +} + +########################################################################## +# Decrypt Passwort/Username übernommen aus 76_SMAEVCharger.pm author: Jürgen Allmich +########################################################################## + +sub SMAInverter_SMAdecrypt($) +{ + my ($encoded) = @_; + my $key = getUniqueId(); + my $decoded; + + return $encoded if( $encoded !~ /crypt:/ ); + + $encoded = $1 if( $encoded =~ /crypt:(.*)/ ); + + for my $char (map { pack('C', hex($_)) } ($encoded =~ /(..)/g)) { + my $decode = chop($key); + $decoded .= chr(ord($char)^ord($decode)); + $key = $decode.$key; + } + + return $decoded; +} + ############################################################### # Hauptschleife Datenabruf ############################################################### @@ -489,7 +597,7 @@ sub SMAInverter_GetData($) { my $name = $hash->{NAME}; my $interval = AttrVal($name, "interval", 60); my $timeout = AttrVal($name, "timeout", 60); - + RemoveInternalTimer($hash, "SMAInverter_GetData"); if ($init_done != 1) { @@ -507,14 +615,67 @@ sub SMAInverter_GetData($) { Log3 ($name, 4, "$name - ###############################################################"); Log3 ($name, 4, "$name - ########## Begin of new SMAInverter get data cycle ##########"); Log3 ($name, 4, "$name - ###############################################################"); - Log3 ($name, 4, "$name - timeout cycles since module start: $hash->{HELPER}{FAULTEDCYCLES}"); + Log3 ($name, 4, "$name - timeout cycles since module start: $hash->{HELPER}{FAULTEDCYCLES}, Interval: $interval"); # decide of operation if(AttrVal($name,"mode","automatic") eq "automatic") { # automatic operation mode InternalTimer(gettimeofday()+$interval, "SMAInverter_GetData", $hash, 0); } + + ################################################################## + #neuer Tag + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(); + my $firtRunDay = 0; + + if(ReadingsNum($name, ".yesterday", 0) ne $mday) + { + Log3 $name, 4, "$name -> new Day"; + $firtRunDay = 1; + + readingsSingleUpdate($hash,".yesterday",$mday, 1); + #BlockingInformParent("SMAInverter_setReadingFromBlocking", [$name, ".yesterday", $mday], 0); + } + + # ETOTAL speichern für ETODAY-Berechnung wenn WR ETODAY nicht liefert # Abnullen der TODAY werte + if ($firtRunDay == 1) { + my $INVCLASS = InternalVal($name, "INVCLASS", 0); + my $INVTYPE = InternalVal($name, "INVTYPE", 0); + + my $val = 0; + $val = ReadingsNum($name, "etotal", 0)*1000 if (exists $defs{$name}{READINGS}{etotal}); + $val = ReadingsNum($name, "SPOT_ETOTAL", 0) if (exists $defs{$name}{READINGS}{SPOT_ETOTAL}); + + readingsSingleUpdate($hash,".etotal_yesterday",$val, 1); + # EPVTOTAL speichern für EPVTODAY-Berechnung wenn WR EPVTODAY nicht liefert # Abnullen der TODAY werte + if ($INVCLASS eq "8009") { + $val = ReadingsNum($name, "epvtotal", 0)*1000 if (exists $defs{$name}{READINGS}{epvtotal}); + $val = ReadingsNum($name, "SPOT_EPVTOTAL", 0) if (exists $defs{$name}{READINGS}{SPOT_EPVTOTAL}); + + readingsSingleUpdate($hash,".epvtotal_yesterday",$val, 1); + } + + # BATTERYLOAD_TOTAL speichern für BAT_LOADTODAY-Berechnung wenn WR BAT_LOADTODAY nicht liefert # Abnullen der TODAY werte + if ($INVCLASS eq "8009" || $INVCLASS eq "8007") { + $val = ReadingsNum($name, "bat_loadtotal", 0)*1000 if (exists $defs{$name}{READINGS}{bat_loadtotal}); + $val = ReadingsNum($name, "BAT_LOADTOTAL", 0) if (exists $defs{$name}{READINGS}{BAT_LOADTOTAL}); + + readingsSingleUpdate($hash,".bat_loadtotal_yesterday",$val, 1); + } + + # BATTERYUNLOAD_TOTAL speichern für BAT_UNLOADTODAY-Berechnung wenn WR BAT_UNLOADTODAY nicht liefert # Abnullen der TODAY werte + if ($INVCLASS eq "8009" || $INVCLASS eq "8007") { # V2.14.1, Forum: https://forum.fhem.de/index.php/topic,56080.msg1134664.html#msg1134664 + $val = ReadingsNum($name, "bat_unloadtotal", 0)*1000 if (exists $defs{$name}{READINGS}{bat_unloadtotal}); + $val = ReadingsNum($name, "BAT_UNLOADTOTAL", 0) if (exists $defs{$name}{READINGS}{BAT_UNLOADTOTAL}); + + readingsSingleUpdate($hash,".bat_unloadtotal_yesterday",$val, 1); + } + } + +$hash->{HELPER}{firtRunDay} = $firtRunDay; + +Log3 ($name, 4, "$name - start BlockingCall"); $hash->{HELPER}{RUNNING_PID} = BlockingCall("SMAInverter_getstatusDoParse", "$name", "SMAInverter_getstatusParseDone", $timeout, "SMAInverter_getstatusParseAborted", $hash); $hash->{HELPER}{RUNNING_PID}{loglevel} = 4; @@ -526,63 +687,115 @@ return; ############################################################### sub SMAInverter_getstatusDoParse($) { my ($name) = @_; + Log3 ($name, 4, "$name - running BlockingCall SMAInverter_getstatusDoParse"); + my $hash = $defs{$name}; my $interval = AttrVal($name, "interval", 60); my $sc = AttrVal($name, "SBFSpotComp", 0); my ($sup_EnergyProduction, + $sup_PVEnergyProduction, + $sup_Firmware, $sup_SpotDCPower, + $sup_SpotDCPower_2, + $sup_SpotDCPower_3, $sup_SpotACPower, $sup_MaxACPower, $sup_MaxACPower2, $sup_SpotACTotalPower, $sup_ChargeStatus, $sup_SpotDCVoltage, + $sup_SpotDCVoltage_2, $sup_SpotACVoltage, $sup_SpotACCurrent, + $sup_SpotACCurrent_Backup, $sup_BatteryInfo, $sup_BatteryInfo_2, #SBS(1.5|2.0|2.5) + $sup_BatteryInfo_3, + $sup_BatteryInfo_4, + $sup_BatteryInfo_5, $sup_BatteryInfo_TEMP, $sup_BatteryInfo_UDC, $sup_BatteryInfo_IDC, + $sup_BatteryInfo_Capacity, $sup_BatteryInfo_Capac, + $sup_BatteryInfo_Charge, $sup_SpotGridFrequency, $sup_TypeLabel, $sup_OperationTime, $sup_InverterTemperature, $sup_GridRelayStatus, + $sup_BackupRelayStatus, + $sup_GridConection, + $sup_OperatingStatus, + $sup_GeneralOperatingStatus, + $sup_WaitingTimeUntilFeedIn, $sup_SpotBatteryLoad, - $sup_DeviceStatus); + $sup_SpotBatteryUnload, + $sup_DeviceStatus, + $sup_BatStatus, + $sup_Insulation_1, + $sup_Insulation_2, + $sup_EM_1, + $sup_EM_2, + $sup_EM_3, + $sup_EM_4); my ($inv_TYPE, $inv_CLASS, $inv_SPOT_ETODAY, $inv_SPOT_ETOTAL, + $inv_SPOT_EPVTODAY, $inv_SPOT_EPVTOTAL, $inv_susyid, $inv_serial, - $inv_SPOT_PDC1, $inv_SPOT_PDC2, + $inv_Firmware, + $inv_SPOT_PDC,$inv_SPOT_PDC1, $inv_SPOT_PDC2, $inv_SPOT_PDC3, $inv_SPOT_PAC1, $inv_SPOT_PAC2, $inv_SPOT_PAC3, $inv_SPOT_PACTOT, $inv_PACMAX1, $inv_PACMAX2, $inv_PACMAX3, $inv_PACMAX1_2, $inv_ChargeStatus, - $inv_SPOT_UDC1, $inv_SPOT_UDC2, - $inv_SPOT_IDC1, $inv_SPOT_IDC2, + $inv_SPOT_UDC1, $inv_SPOT_UDC2, $inv_SPOT_UDC3, + $inv_SPOT_IDC1, $inv_SPOT_IDC2, $inv_SPOT_IDC3, $inv_SPOT_UAC1, $inv_SPOT_UAC2, $inv_SPOT_UAC3, $inv_SPOT_UAC1_2, $inv_SPOT_UAC2_3, $inv_SPOT_UAC3_1, $inv_SPOT_IAC1, $inv_SPOT_IAC2, $inv_SPOT_IAC3, + $inv_SPOT_IAC1_Backup,$inv_SPOT_IAC2_Backup,$inv_SPOT_IAC3_Backup, + $sup_SpotACCurrentBackup, $inv_BAT_rated_capacity, $inv_BAT_Typ, $inv_BAT_STATUS, $inv_SPOT_CosPhi, $inv_BAT_UDC, $inv_BAT_UDC_A, $inv_BAT_UDC_B, $inv_BAT_UDC_C, $inv_BAT_IDC, $inv_BAT_IDC_A, $inv_BAT_IDC_B, $inv_BAT_IDC_C, + $inv_BAT_P_Charge, $inv_BAT_P_Discharge, $inv_BAT_CYCLES, $inv_BAT_CYCLES_A, $inv_BAT_CYCLES_B, $inv_BAT_CYCLES_C, $inv_BAT_TEMP, $inv_BAT_TEMP_A, $inv_BAT_TEMP_B, $inv_BAT_TEMP_C, - $inv_BAT_LOADTODAY, $inv_BAT_LOADTOTAL, - $inv_SPOT_FREQ, $inv_SPOT_OPERTM, $inv_SPOT_FEEDTM, $inv_TEMP, $inv_GRIDRELAY, $inv_STATUS,); + $inv_BAT_LOADTODAY, $inv_BAT_LOADTOTAL, $inv_BAT_CAPACITY,$inv_BAT_UNLOADTODAY,$inv_BAT_UNLOADTOTAL, + $inv_BAT_Manufacturer, + $inv_SPOT_FREQ, $inv_SPOT_OPERTM, $inv_SPOT_FEEDTM, $inv_TEMP, $inv_GRIDRELAY, $inv_STATUS, + $inv_BACKUPRELAY, $inv_OperatingStatus, $inv_GeneralOperatingStatus, $inv_WaitingTimeUntilFeedIn, $inv_GridConection, + $Meter_Grid_FeedIn, $Meter_Grid_Consumation,$Meter_Total_Yield,$Meter_Total_Consumation, + $Meter_Power_Grid_FeedIn,$Meter_Power_Grid_Consumation, + $Meter_Grid_FeedIn_PAC1, $Meter_Grid_FeedIn_PAC2, $Meter_Grid_FeedIn_PAC3, $Meter_Grid_Consumation_PAC1, $Meter_Grid_Consumation_PAC2, $Meter_Grid_Consumation_PAC3, + $inv_DC_insulation, $inv_DC_Residual_Current); my @row_array; my @array; my $avg = 0; my ($ist,$bst,$irt,$brt,$rt); - + my $INVCLASS = InternalVal($name, "INVCLASS", 0); + my $INVTYPE = InternalVal($name, "INVTYPE", 0); + my $INVTYPE_NAME = ReadingsVal($name,"INV_TYPE",ReadingsVal($name,"device_type","")); + my $firtRunDay = $hash->{HELPER}{firtRunDay}; + my $readParameter = 0; + my $INVFWMAIN = InternalVal($name, "INVFWMAIN", 0); + + Log3 ($name, 4, "$name -> INVCLASS $INVCLASS"); + Log3 ($name, 4, "$name -> INVTYPE $INVTYPE"); + + if((InternalVal($name, "eventCount", 0) % 50) == 0) + { + Log3 $name, 4, "$name -> read Parameter"; + $readParameter = 1; + } + # Background-Startzeit $bst = [gettimeofday]; - - Log3 ($name, 4, "$name -> Start BlockingCall SMAInverter_getstatusDoParse"); + + Log3 ($name, 4, "$name -> start BlockingCall SMAInverter_getstatusDoParse"); # set dependency from surise/sunset used for inverter operation time my $offset = AttrVal($name,"offset",0); @@ -593,9 +806,17 @@ sub SMAInverter_getstatusDoParse($) { my $oper_start = DateTime->new(year=>$year+1900,month=>$mon+1,day=>$mday,hour=>$sunrise_h,minute=>$sunrise_m,second=>$sunrise_s,time_zone=>'local'); my $oper_stop = DateTime->new(year=>$year+1900,month=>$mon+1,day=>$mday,hour=>$sunset_h,minute=>$sunset_m,second=>$sunset_s,time_zone=>'local'); - my $oper_start_d = DateTime->new(year=>$year+1900,month=>$mon+1,day=>$mday,hour=>00,minute=>10,second=>00,time_zone=>'local'); + #my $oper_start_d = DateTime->new(year=>$year+1900,month=>$mon+1,day=>$mday,hour=>00,minute=>10,second=>00,time_zone=>'local'); my $dt_now = DateTime->now(time_zone=>'local'); + # if(ReadingsNum($name, ".yesterday", 0) ne $mday) + # { + # Log3 $name, 4, "$name -> new Day"; + # $firtRunDay = 1; + + # BlockingInformParent("SMAInverter_setReadingFromBlocking", [$name, ".yesterday", $mday], 0); + # } + Log3 $name, 4, "$name - current time: ".$dt_now->dmy('.')." ".$dt_now->hms; Log3 $name, 4, "$name - operation time begin: ".$oper_start->dmy('.')." ".$oper_start->hms; Log3 $name, 4, "$name - operation time end: ".$oper_stop->dmy('.')." ".$oper_stop->hms; @@ -603,22 +824,76 @@ sub SMAInverter_getstatusDoParse($) { my $opertime_start = $oper_start->dmy('.')." ".$oper_start->hms; my $opertime_stop = $oper_stop->dmy('.')." ".$oper_stop->hms; - # ETOTAL speichern für ETODAY-Berechnung wenn WR ETODAY nicht liefert - if ($dt_now <= $oper_start_d) { # V2.14.1, Forum: https://forum.fhem.de/index.php/topic,56080.msg1134664.html#msg1134664 - my $val = 0; - $val = ReadingsNum($name, "etotal", 0)*1000 if (exists $defs{$name}{READINGS}{etotal}); - $val = ReadingsNum($name, "SPOT_ETOTAL", 0) if (exists $defs{$name}{READINGS}{SPOT_ETOTAL}); - BlockingInformParent("SMAInverter_setReadingFromBlocking", [$name, ".etotal_yesterday", $val], 0); + # ETOTAL speichern für ETODAY-Berechnung wenn WR ETODAY nicht liefert # Abnullen der TODAY werte + if ($firtRunDay == 1) { # V2.14.1, Forum: https://forum.fhem.de/index.php/topic,56080.msg1134664.html#msg1134664 + # my $val = 0; + # $val = ReadingsNum($name, "etotal", 0)*1000 if (exists $defs{$name}{READINGS}{etotal}); + # $val = ReadingsNum($name, "SPOT_ETOTAL", 0) if (exists $defs{$name}{READINGS}{SPOT_ETOTAL}); + # BlockingInformParent("SMAInverter_setReadingFromBlocking", [$name, ".etotal_yesterday", $val], 0); + if ($sc) { + push(@row_array, "etoday 0\n"); + } + else { + push(@row_array, "SPOT_ETODAY 0\n"); + } +} + + # EPVTOTAL speichern für EPVTODAY-Berechnung wenn WR EPVTODAY nicht liefert # Abnullen der TODAY werte + if ($firtRunDay == 1 && $INVCLASS eq "8009") { + # my $val = 0; + # $val = ReadingsNum($name, "epvtotal", 0)*1000 if (exists $defs{$name}{READINGS}{epvtotal}); + # $val = ReadingsNum($name, "SPOT_EPVTOTAL", 0) if (exists $defs{$name}{READINGS}{SPOT_EPVTOTAL}); + # BlockingInformParent("SMAInverter_setReadingFromBlocking", [$name, ".epvtotal_yesterday", $val], 0); + if ($sc) { + push(@row_array, "epvtoday 0\n"); + } + else { + push(@row_array, "SPOT_EPVTODAY 0\n"); + } } - # BATTERYLOAD_TOTAL speichern für BAT_LOADTODAY-Berechnung wenn WR BAT_LOADTODAY nicht liefert - if ($dt_now <= $oper_start_d) { # V2.14.1, Forum: https://forum.fhem.de/index.php/topic,56080.msg1134664.html#msg1134664 - my $val = 0; - $val = ReadingsNum($name, "bat_loadtotal", 0)*1000 if (exists $defs{$name}{READINGS}{bat_loadtotal}); - $val = ReadingsNum($name, "BAT_LOADTOTAL", 0) if (exists $defs{$name}{READINGS}{BAT_LOADTOTAL}); - BlockingInformParent("SMAInverter_setReadingFromBlocking", [$name, ".bat_loadtotal_yesterday", $val], 0); + # BATTERYLOAD_TOTAL speichern für BAT_LOADTODAY-Berechnung wenn WR BAT_LOADTODAY nicht liefert # Abnullen der TODAY werte + if ($firtRunDay == 1 && ($INVCLASS eq "8009" || $INVCLASS eq "8007")) { + # my $val = 0; + # $val = ReadingsNum($name, "bat_loadtotal", 0)*1000 if (exists $defs{$name}{READINGS}{bat_loadtotal}); + # $val = ReadingsNum($name, "BAT_LOADTOTAL", 0) if (exists $defs{$name}{READINGS}{BAT_LOADTOTAL}); + # BlockingInformParent("SMAInverter_setReadingFromBlocking", [$name, ".bat_loadtotal_yesterday", $val], 0); + if ($sc) { + push(@row_array, "bat_loadtoday 0\n"); + } + else { + push(@row_array, "BAT_LOADTODAY 0\n"); + } } + # BATTERYUNLOAD_TOTAL speichern für BAT_UNLOADTODAY-Berechnung wenn WR BAT_UNLOADTODAY nicht liefert # Abnullen der TODAY werte + if ($firtRunDay == 1 && ($INVCLASS eq "8009" || $INVCLASS eq "8007")) { # V2.14.1, Forum: https://forum.fhem.de/index.php/topic,56080.msg1134664.html#msg1134664 + # my $val = 0; + # $val = ReadingsNum($name, "bat_unloadtotal", 0)*1000 if (exists $defs{$name}{READINGS}{bat_unloadtotal}); + # $val = ReadingsNum($name, "BAT_UNLOADTOTAL", 0) if (exists $defs{$name}{READINGS}{BAT_UNLOADTOTAL}); + # BlockingInformParent("SMAInverter_setReadingFromBlocking", [$name, ".bat_unloadtotal_yesterday", $val], 0); + if ($sc) { + push(@row_array, "bat_unloadtoday 0\n"); + } + else { + push(@row_array, "BAT_UNLOADTODAY 0\n"); + } + } + + my $suppressSleep = AttrVal($name,"suppressSleep",-1); + + if($suppressSleep < 0) + { + if($INVCLASS eq "8009" || $INVCLASS eq "8007") + { + $suppressSleep = 1; + } + else + { + $suppressSleep = 0; + } + } + if (($oper_start <= $dt_now && $dt_now <= $oper_stop) || AttrVal($name,"suppressSleep",0)) { # normal operation or suppressed sleepmode @@ -627,54 +902,99 @@ sub SMAInverter_getstatusDoParse($) { # Get the current attributes my $detail_level = AttrVal($name, "detail-level", 0); - + my $readEnergyMeter_data = AttrVal($name, "readEnergyMeter-data", 0); + # Aufbau Command-Array my @commands = ("sup_TypeLabel", # Check TypeLabel "sup_EnergyProduction", # Check EnergyProduction "sup_SpotDCPower", # Check SpotDCPower "sup_SpotACPower", # Check SpotACPower - "sup_SpotACTotalPower", # Check SpotACTotalPower - "sup_ChargeStatus" # Check BatteryChargeStatus + "sup_SpotACTotalPower" # Check SpotACTotalPower ); - + + if($INVCLASS eq "8009" || $INVCLASS eq "8007") + { + push(@commands, "sup_ChargeStatus"); # Check BatteryChargeStatus + push(@commands, "sup_SpotBatteryLoad"); # Check Batteryload + push(@commands, "sup_SpotBatteryUnload"); # Check BatteryUnload + } + + push(@commands, "sup_PVEnergyProduction") if($INVCLASS eq "8009"); # Check PV-EnergyProduction (Hybrid Inverter) + push(@commands, "sup_SpotDCPower_3") if($INVCLASS eq "8009" || $INVCLASS eq "8001"); # SpotDCPower summary + + #push(@commands, "sup_SpotDCPower_2") if($INVTYPE >= 9488 && $INVTYPE <= 9493); # SpotDCPower String 3 and more + if($detail_level > 0) { # Detail Level 1 or 2 >> get voltage and current levels push(@commands, "sup_SpotDCVoltage"); # Check SpotDCVoltage + #push(@commands, "sup_SpotDCVoltage_2") if($INVTYPE >= 9488 && $INVTYPE <= 9493); # SpotDCVoltage String 3 and more push(@commands, "sup_SpotACVoltage"); # Check SpotACVoltage push(@commands, "sup_SpotACCurrent"); # Check SpotACCurrent - if (ReadingsVal($name,"INV_TYPE","") =~ /SBS(6\.0|5\.0|3\.7)/xs || ReadingsVal($name,"device_type","") =~ /SBS(6\.0|5\.0|3\.7)/xs) + if($INVCLASS eq "8009") + { + push(@commands, "sup_SpotACCurrentBackup"); # Check BatteryInfo + } + + if ($INVTYPE_NAME =~ /SBS(6\.0|5\.0|3\.7)/xs) { push(@commands, "sup_BatteryInfo_UDC"); # Check BatteryInfo Voltage push(@commands, "sup_BatteryInfo_IDC"); # Check BatteryInfo current } - elsif (ReadingsVal($name,"INV_TYPE","") =~ /SBS(1\.5|2\.0|2\.5)/xs || ReadingsVal($name,"device_type","") =~ /SBS(1\.5|2\.0|2\.5)/xs) + elsif ($INVTYPE_NAME =~ /SBS(1\.5|2\.0|2\.5)/xs || $INVCLASS eq "8009") { push(@commands, "sup_BatteryInfo_2"); # Check BatteryInfo Voltage + push(@commands, "sup_BatteryInfo_Charge"); } - else{ + elsif($INVCLASS eq "8009" || $INVCLASS eq "8007") + { push(@commands, "sup_BatteryInfo"); # Check BatteryInfo } - - push(@commands, "sup_SpotBatteryLoad"); # Check Batteryload } if($detail_level > 1) { # Detail Level 2 >> get all data push(@commands, "sup_SpotGridFrequency"); # Check SpotGridFrequency push(@commands, "sup_OperationTime"); # Check OperationTime - push(@commands, "sup_InverterTemperature"); # Check InverterTemperature + push(@commands, "sup_InverterTemperature"); # Check InverterTemperature ? push(@commands, "sup_MaxACPower"); # Check MaxACPower - push(@commands, "sup_MaxACPower2"); # Check MaxACPower2 + push(@commands, "sup_MaxACPower2"); # Check MaxACPower2 ? push(@commands, "sup_GridRelayStatus"); # Check GridRelayStatus push(@commands, "sup_DeviceStatus"); # Check DeviceStatus + + push(@commands, "sup_Firmware") if($readParameter == 1); #Read WR Firmwareversion - if (ReadingsVal($name,"INV_TYPE","") =~ /SBS(6\.0|5\.0|3\.7)/xs || ReadingsVal($name,"device_type","") =~ /SBS(6\.0|5\.0|3\.7)/xs) + if ($INVTYPE_NAME =~ /SBS(6\.0|5\.0|3\.7)/xs) { push(@commands, "sup_BatteryInfo_TEMP"); # Check BatteryInfo Temperatur - push(@commands, "sup_BatteryInfo_Capac"); # Check BatteryInfo + push(@commands, "sup_BatteryInfo_Capac") if($readParameter == 1); # Check BatteryInfo capacity } + + if ($INVCLASS eq "8007" || $INVCLASS eq "8009") + { + push(@commands, "sup_BatStatus"); # Check DeviceStatus + push(@commands, "sup_BatteryInfo_Capacity") if($readParameter == 1); # Check BatteryInfo capacity + #push(@commands, "sup_BatteryInfo_3"); + push(@commands, "sup_BatteryInfo_4") if($readParameter == 1); # Check BatteryInfo rated apacity + #push(@commands, "sup_BatteryInfo_5"); + } + + #push(@commands, "sup_Insulation_1"); # Isolationsüberwachung + #push(@commands, "sup_Insulation_2"); # Isolationsüberwachung + + push(@commands, "sup_GeneralOperatingStatus"); + push(@commands, "sup_OperatingStatus") if($INVCLASS eq "8009" || $INVTYPE_NAME =~ /SI/xs); + push(@commands, "sup_BackupRelayStatus") if($INVCLASS eq "8009"); + push(@commands, "sup_GridConection") if($INVTYPE_NAME =~ /SI/xs); #nur SI Wechselrichter (Hybrids haben diesen Wert auch aber diese ändert sich weder im WR noch im Reading also unnötig) + #push(@commands, "sup_WaitingTimeUntilFeedIn") if($INVCLASS eq "8009"); } + + if($readEnergyMeter_data > 0) { + push(@commands, "sup_EM_1"); # EM Data 1 + push(@commands, "sup_EM_2"); # EM Data 2 + push(@commands, "sup_EM_3"); # EM Data 3 + push(@commands, "sup_EM_4"); # EM Data 4 + } Log3 $name, 5, "$name - ".ReadingsVal($name,"INV_TYPE","")."".ReadingsVal($name,"device_type",""); @@ -684,32 +1004,52 @@ sub SMAInverter_getstatusDoParse($) { for my $i(@commands) { if ($i eq "sup_TypeLabel") { + Log3 $name, 5, "$name -> sup_TypeLabel"; ($sup_TypeLabel,$inv_TYPE,$inv_CLASS,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x58000200, 0x00821E00, 0x008220FF); } elsif ($i eq "sup_EnergyProduction") { + Log3 $name, 5, "$name -> sup_EnergyProduction"; ($sup_EnergyProduction,$inv_SPOT_ETODAY,$inv_SPOT_ETOTAL,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x54000200, 0x00260100, 0x002622FF); + } + elsif ($i eq "sup_PVEnergyProduction") { + Log3 $name, 5, "$name -> sup_PVEnergyProduction"; + ($sup_PVEnergyProduction,$inv_SPOT_EPVTODAY,$inv_SPOT_EPVTOTAL,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x54000200, 0x0046c300, 0x0046c3FF); } elsif ($i eq "sup_SpotDCPower") { - ($sup_SpotDCPower,$inv_SPOT_PDC1,$inv_SPOT_PDC2,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x53800200, 0x00251E00, 0x00251EFF); + Log3 $name, 5, "$name -> sup_SpotDCPower"; + ($sup_SpotDCPower,$inv_SPOT_PDC1,$inv_SPOT_PDC2,$inv_SPOT_PDC3,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x53800200, 0x00251E00, 0x00251EFF); + } + elsif ($i eq "sup_SpotDCPower_3") { + Log3 $name, 5, "$name -> sup_SpotDCPower_3"; + ($sup_SpotDCPower_3,$inv_SPOT_PDC,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x0046c200, 0x0046c2FF); } elsif ($i eq "sup_SpotACPower") { + Log3 $name, 5, "$name -> sup_SpotACPower"; ($sup_SpotACPower,$inv_SPOT_PAC1,$inv_SPOT_PAC2,$inv_SPOT_PAC3,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00464000, 0x004642FF); } elsif ($i eq "sup_SpotACTotalPower") { + Log3 $name, 5, "$name -> sup_SpotACTotalPower"; ($sup_SpotACTotalPower,$inv_SPOT_PACTOT,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00263F00, 0x00263FFF); } elsif ($i eq "sup_ChargeStatus") { + Log3 $name, 5, "$name -> sup_ChargeStatus"; ($sup_ChargeStatus,$inv_ChargeStatus,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00295A00, 0x00295AFF); } elsif ($i eq "sup_SpotDCVoltage") { - ($sup_SpotDCVoltage,$inv_SPOT_UDC1,$inv_SPOT_UDC2,$inv_SPOT_IDC1,$inv_SPOT_IDC2,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x53800200, 0x00451F00, 0x004521FF); + Log3 $name, 5, "$name -> sup_SpotDCVoltage"; + ($sup_SpotDCVoltage,$inv_SPOT_UDC1,$inv_SPOT_UDC2,$inv_SPOT_UDC3,$inv_SPOT_IDC1,$inv_SPOT_IDC2,$inv_SPOT_IDC3,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x53800200, 0x00451F00, 0x004521FF); } elsif ($i eq "sup_SpotACVoltage") { + Log3 $name, 5, "$name -> sup_SpotACVoltage"; ($sup_SpotACVoltage,$inv_SPOT_UAC1,$inv_SPOT_UAC2,$inv_SPOT_UAC3,$inv_SPOT_UAC1_2,$inv_SPOT_UAC2_3,$inv_SPOT_UAC3_1,$inv_SPOT_CosPhi,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00464800, 0x004656FF); } elsif ($i eq "sup_SpotACCurrent") { Log3 $name, 5, "$name -> sup_SpotACCurrent"; ($sup_SpotACCurrent,$inv_SPOT_IAC1,$inv_SPOT_IAC2,$inv_SPOT_IAC3,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00465300, 0x004655FF); + } + elsif ($i eq "sup_SpotACCurrentBackup") { + Log3 $name, 5, "$name -> sup_SpotACCurrentBackup"; + ($sup_SpotACCurrent_Backup,$inv_SPOT_IAC1_Backup,$inv_SPOT_IAC2_Backup,$inv_SPOT_IAC3_Backup,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x40574600, 0x405748FF); } elsif ($i eq "sup_BatteryInfo_TEMP") { Log3 $name, 5, "$name -> sup_BatteryInfo_TEMP"; @@ -722,7 +1062,15 @@ sub SMAInverter_getstatusDoParse($) { elsif ($i eq "sup_BatteryInfo_IDC") { Log3 $name, 5, "$name -> sup_BatteryInfo_IDC"; ($sup_BatteryInfo_IDC,$inv_BAT_IDC,$inv_BAT_IDC_A,$inv_BAT_IDC_B,$inv_BAT_IDC_C,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00495D00, 0x00495D10); - } + } + elsif ($i eq "sup_BatteryInfo_Charge") { + Log3 $name, 5, "$name -> sup_BatteryInfo_Charge"; + ($sup_BatteryInfo_Charge,$inv_BAT_P_Charge,$inv_BAT_P_Discharge,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00496900, 0x00496AFF); + } + elsif ($i eq "sup_BatteryInfo_Capacity") { + Log3 $name, 5, "$name -> sup_BatteryInfo_Capacity"; + ($sup_BatteryInfo_Capacity,$inv_BAT_CAPACITY,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00696E00, 0x00696E10); + } elsif ($i eq "sup_BatteryInfo_Capac") { Log3 $name, 5, "$name -> sup_BatteryInfo_Capac"; #($sup_BatteryInfo_IDC,$inv_BAT_IDC,$inv_BAT_IDC_A,$inv_BAT_IDC_B,$inv_BAT_IDC_C,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00496800, 0x004968FF); @@ -734,32 +1082,111 @@ sub SMAInverter_getstatusDoParse($) { elsif ($i eq "sup_BatteryInfo_2") { Log3 $name, 5, "$name -> sup_BatteryInfo_2"; ($sup_BatteryInfo_2,$inv_BAT_TEMP,$inv_BAT_UDC,$inv_BAT_IDC,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00491E00, 0x00495DFF); - } + } + elsif ($i eq "sup_BatteryInfo_3") { + Log3 $name, 5, "$name -> sup_BatteryInfo_3"; + ($sup_BatteryInfo_3,$inv_BAT_Manufacturer,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x58020200, 0x08822C00, 0x08822CFF); + } + elsif ($i eq "sup_BatteryInfo_4") { + Log3 $name, 5, "$name -> sup_BatteryInfo_4"; + ($sup_BatteryInfo_4,$inv_BAT_rated_capacity,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x58000200, 0x00893700, 0x008937FF); + } + elsif ($i eq "sup_BatteryInfo_5") { + Log3 $name, 5, "$name -> sup_BatteryInfo_5"; + ($sup_BatteryInfo_5,$inv_BAT_Typ,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x58020200, 0x00B18900, 0x00B189FF); + } elsif ($i eq "sup_SpotGridFrequency") { + Log3 $name, 5, "$name -> sup_SpotGridFrequency"; ($sup_SpotGridFrequency,$inv_SPOT_FREQ,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00465700, 0x004657FF); } elsif ($i eq "sup_OperationTime") { + Log3 $name, 5, "$name -> sup_OperationTime"; ($sup_OperationTime,$inv_SPOT_OPERTM,$inv_SPOT_FEEDTM,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x54000200, 0x00462E00, 0x00462FFF); } elsif ($i eq "sup_InverterTemperature") { + Log3 $name, 5, "$name -> sup_InverterTemperature"; ($sup_InverterTemperature,$inv_TEMP,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x52000200, 0x00237700, 0x002377FF); } elsif ($i eq "sup_MaxACPower") { + Log3 $name, 5, "$name -> sup_MaxACPower"; ($sup_MaxACPower,$inv_PACMAX1,$inv_PACMAX2,$inv_PACMAX3,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00411E00, 0x004120FF); } elsif ($i eq "sup_MaxACPower2") { + Log3 $name, 5, "$name -> sup_MaxACPower2"; ($sup_MaxACPower2,$inv_PACMAX1_2,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00832A00, 0x00832AFF); } elsif ($i eq "sup_GridRelayStatus") { + Log3 $name, 5, "$name -> sup_GridRelayStatus"; ($sup_GridRelayStatus,$inv_GRIDRELAY,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51800200, 0x00416400, 0x004164FF); + } + elsif ($i eq "sup_BackupRelayStatus") { + Log3 $name, 5, "$name -> sup_BackupRelayStatus"; + ($sup_BackupRelayStatus,$inv_BACKUPRELAY,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51800200, 0x08412500, 0x084125FF); + } + elsif ($i eq "sup_GridConection") { + Log3 $name, 5, "$name -> sup_GridConection"; + ($sup_GridConection,$inv_GridConection,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51800200, 0x0846A600, 0x0846A6FF); + } + elsif ($i eq "sup_OperatingStatus") { + Log3 $name, 5, "$name -> sup_OperatingStatus"; + ($sup_OperatingStatus,$inv_OperatingStatus,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51800200, 0x08412B00, 0x08412BFF); + } + elsif ($i eq "sup_GeneralOperatingStatus") { + Log3 $name, 5, "$name -> sup_GeneralOperatingStatus"; + ($sup_GeneralOperatingStatus,$inv_GeneralOperatingStatus,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51800200, 0x08412800, 0x084128FF); + } + elsif ($i eq "sup_WaitingTimeUntilFeedIn") { + Log3 $name, 5, "$name -> sup_WaitingTimeUntilFeedIn"; + ($sup_WaitingTimeUntilFeedIn,$inv_WaitingTimeUntilFeedIn,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00416600, 0x004166FF); } elsif ($i eq "sup_DeviceStatus") { + Log3 $name, 5, "$name -> sup_DeviceStatus"; ($sup_DeviceStatus,$inv_STATUS,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51800200, 0x00214800, 0x002148FF); + } + elsif ($i eq "sup_BatStatus") { + Log3 $name, 5, "$name -> sup_BatStatus"; + ($sup_BatStatus,$inv_BAT_STATUS,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51800200, 0x08214800, 0x082148FF); } elsif ($i eq "sup_SpotBatteryLoad") { + Log3 $name, 5, "$name -> sup_SpotBatteryLoad"; ($sup_SpotBatteryLoad,$inv_BAT_LOADTODAY,$inv_BAT_LOADTOTAL,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x54000200, 0x00496700, 0x004967FF); } + elsif ($i eq "sup_SpotBatteryUnload") { + Log3 $name, 5, "$name -> sup_SpotBatteryUnload"; + ($sup_SpotBatteryUnload,$inv_BAT_UNLOADTODAY,$inv_BAT_UNLOADTOTAL,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x54000200, 0x00496800, 0x004968FF); + } + elsif ($i eq "sup_EM_1") { + Log3 ($name, 4, "$name -> EM 1"); + ($sup_EM_1,$Meter_Total_Yield,$Meter_Total_Consumation,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x54000200, 0x00462400, 0x004628FF); + } + elsif ($i eq "sup_EM_2") { + Log3 ($name, 4, "$name -> EM 2"); + ($sup_EM_2,$Meter_Grid_FeedIn,$Meter_Grid_Consumation,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x54000200, 0x40469100, 0x404692FF); + } + elsif ($i eq "sup_EM_3") { + Log3 ($name, 4, "$name -> EM 3"); + ($sup_EM_3,$Meter_Power_Grid_FeedIn,$Meter_Power_Grid_Consumation,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x40463600, 0x404637FF); + } + elsif ($i eq "sup_EM_4") { + Log3 ($name, 4, "$name -> EM 4"); + ($sup_EM_4,$Meter_Grid_FeedIn_PAC1, $Meter_Grid_FeedIn_PAC2, $Meter_Grid_FeedIn_PAC3, $Meter_Grid_Consumation_PAC1, $Meter_Grid_Consumation_PAC2, $Meter_Grid_Consumation_PAC3,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x0046E800, 0x0046EDFF); + } + elsif ($i eq "sup_Insulation_1") { + Log3 ($name, 4, "$name -> sup_Insulation_1"); + ($sup_Insulation_1,$inv_DC_Residual_Current,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51020200, 0x40254E00, 0x40254FFF); + } + elsif ($i eq "sup_Insulation_2") { + Log3 ($name, 4, "$name -> sup_Insulation_2"); + ($sup_Insulation_2,$inv_DC_insulation,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51020200, 0x00254F00, 0x00254FFF); + } + elsif ($i eq "sup_Firmware") { + Log3 ($name, 4, "$name -> sup_Firmware"); + ($sup_Firmware,$inv_Firmware,$INVFWMAIN,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x58000200, 0x00823400, 0x008234FF); + } } + + $INVCLASS = $inv_CLASS if(defined $inv_CLASS); + $INVTYPE = $inv_TYPE if(defined $inv_TYPE); # nothing more to do, just log out SMAInverter_SMAlogout($hash,$hash->{HOST}); @@ -780,21 +1207,24 @@ sub SMAInverter_getstatusDoParse($) { my $cnt15 = int(900/$interval); # Anzahl der Zyklen innerhalb 15 Minuten = Summe aller Messzyklen my $cntsum = $cnt15+1; # Sicherheitszuschlag Summe Anzahl aller Zyklen my @averagebuf; - if ($sup_TypeLabel && $sup_EnergyProduction && $inv_CLASS =~ /8001|8002|8007/xs) { + if ($sup_TypeLabel && $sup_SpotACTotalPower && $inv_CLASS =~ /8001|8002|8007|8009/xs) { + my $power = $inv_SPOT_PACTOT; + $power = $inv_SPOT_PDC if($inv_CLASS =~ /8009/xs); #DC Leistung bei Hybrid verwenden + # only for this block because of warnings if values not set at restart no warnings 'uninitialized'; if (!$hash->{HELPER}{AVERAGEBUF}) { for my $count (0..$cntsum) { # fill with new values - $inv_SPOT_PACTOT = $inv_SPOT_PACTOT // 0; - push(@averagebuf, $inv_SPOT_PACTOT); + $power = $power // 0; + push(@averagebuf, $power); } } else { @averagebuf = split(/,/, $hash->{HELPER}{AVERAGEBUF}) } pop(@averagebuf); # rechtes Element aus average buffer löschen - unshift(@averagebuf, $inv_SPOT_PACTOT); # und links mit neuem Wert füllen + unshift(@averagebuf, $power); # und links mit neuem Wert füllen $avg = join(',', @averagebuf); # calculate average energy and write to array for generate readings @@ -827,18 +1257,53 @@ sub SMAInverter_getstatusDoParse($) { push(@row_array, "avg_power_lastminutes_05 ".$AvP05."\n"); # Average Energy (last) 5 minutes push(@row_array, "avg_power_lastminutes_10 ".$AvP10."\n"); # Average Energy (last) 10 minutes push(@row_array, "avg_power_lastminutes_15 ".$AvP15."\n"); # Average Energy (last) 15 minutes - + use warnings; } - - if ($sc) { # SBFSpot Kompatibilitätsmodus + + if ($sc) { # SBFSpot Kompatibilitätsmodus + + if($sup_EM_1) { + push(@row_array, "Meter_TOTAL_FeedIn ".($Meter_Total_Yield/1000)."\n") if ($Meter_Total_Yield ne "-"); + push(@row_array, "Meter_TOTAL_Consumation ".($Meter_Total_Consumation/1000)."\n") if ($Meter_Total_Consumation ne "-"); + } + + if($sup_EM_2) { + push(@row_array, "Meter_TOTAL_Grid_FeedIn ".($Meter_Grid_FeedIn/1000)."\n") if ($Meter_Grid_FeedIn ne "-"); + push(@row_array, "Meter_TOTAL_Grid_Consumation ".($Meter_Grid_Consumation/1000)."\n") if ($Meter_Grid_Consumation ne "-"); + } + + if($sup_EM_3) { + push(@row_array, "Meter_Power_Grid_FeedIn ".($Meter_Power_Grid_FeedIn/1000)."\n") if ($Meter_Power_Grid_FeedIn ne "-"); + push(@row_array, "Meter_Power_Grid_Consumation ".($Meter_Power_Grid_Consumation/1000)."\n") if ($Meter_Power_Grid_Consumation ne "-"); + } + + if($sup_EM_4) { + push(@row_array, "Meter_Grid_FeedIn_phase_1_pac ".($Meter_Grid_FeedIn_PAC1/1000)."\n") if ($Meter_Grid_FeedIn_PAC1 ne "-"); + push(@row_array, "Meter_Grid_FeedIn_phase_2_pac ".($Meter_Grid_FeedIn_PAC2/1000)."\n") if ($Meter_Grid_FeedIn_PAC2 ne "-"); + push(@row_array, "Meter_Grid_FeedIn_phase_3_pac ".($Meter_Grid_FeedIn_PAC3/1000)."\n") if ($Meter_Grid_FeedIn_PAC3 ne "-"); + + push(@row_array, "Meter_Grid_Consumation_phase_1_pac ".($Meter_Grid_Consumation_PAC1/1000)."\n") if ($Meter_Grid_Consumation_PAC1 ne "-"); + push(@row_array, "Meter_Grid_Consumation_phase_2_pac ".($Meter_Grid_Consumation_PAC2/1000)."\n") if ($Meter_Grid_Consumation_PAC2 ne "-"); + push(@row_array, "Meter_Grid_Consumation_phase_3_pac ".($Meter_Grid_Consumation_PAC3/1000)."\n") if ($Meter_Grid_Consumation_PAC3 ne "-"); + } + if($sup_EnergyProduction) { push(@row_array, "etotal ".($inv_SPOT_ETOTAL/1000)."\n") if ($inv_SPOT_ETOTAL ne "-"); push(@row_array, "etoday ".($inv_SPOT_ETODAY/1000)."\n") if ($inv_SPOT_ETODAY ne "-"); + } + if($sup_PVEnergyProduction) { + push(@row_array, "epvtotal ".($inv_SPOT_EPVTOTAL/1000)."\n") if ($inv_SPOT_EPVTOTAL ne "-"); + push(@row_array, "epvtoday ".($inv_SPOT_EPVTODAY/1000)."\n") if ($inv_SPOT_EPVTODAY ne "-"); } if($sup_SpotDCPower) { - push(@row_array, "string_1_pdc ".sprintf("%.3f",$inv_SPOT_PDC1/1000)."\n"); - push(@row_array, "string_2_pdc ".sprintf("%.3f",$inv_SPOT_PDC2/1000)."\n"); + push(@row_array, "string_1_pdc ".sprintf("%.3f",$inv_SPOT_PDC1/1000)."\n") if ($inv_SPOT_PDC1 ne "-"); + push(@row_array, "string_2_pdc ".sprintf("%.3f",$inv_SPOT_PDC2/1000)."\n") if ($inv_SPOT_PDC2 ne "-"); + push(@row_array, "string_3_pdc ".sprintf("%.3f",$inv_SPOT_PDC3/1000)."\n") if ($inv_SPOT_PDC3 ne "-"); + } + if($sup_SpotDCPower_3) { + push(@row_array, "strings_pdc ".sprintf("%.3f",$inv_SPOT_PDC/1000)."\n"); + push(@row_array, "state ".sprintf("%.3f",$inv_SPOT_PDC/1000)."\n") if ($INVCLASS eq "8009"); } if($sup_SpotACPower) { push(@row_array, "phase_1_pac ".sprintf("%.3f",$inv_SPOT_PAC1/1000)."\n") if ($inv_SPOT_PAC1 ne "-"); @@ -847,10 +1312,10 @@ sub SMAInverter_getstatusDoParse($) { } if($sup_SpotACTotalPower) { push(@row_array, "total_pac ".sprintf("%.3f",$inv_SPOT_PACTOT/1000)."\n"); - push(@row_array, "state ".sprintf("%.3f",$inv_SPOT_PACTOT/1000)."\n"); + push(@row_array, "state ".sprintf("%.3f",$inv_SPOT_PACTOT/1000)."\n") if ($INVCLASS ne "8009"); } if($sup_ChargeStatus) { - push(@row_array, "chargestatus ".$inv_ChargeStatus."\n"); + push(@row_array, "chargestatus ".$inv_ChargeStatus."\n"); #TTT } if($inv_CLASS && $inv_CLASS eq 8007 && defined($inv_SPOT_PACTOT)) { # V2.10.1 28.04.2019 @@ -863,14 +1328,25 @@ sub SMAInverter_getstatusDoParse($) { push(@row_array, "power_in "."0"."\n"); } } + + if($sup_SpotBatteryLoad) { + push(@row_array, "bat_loadtotal ".($inv_BAT_LOADTOTAL/1000)."\n") if ($inv_BAT_LOADTOTAL ne "-"); + push(@row_array, "bat_loadtoday ".($inv_BAT_LOADTODAY/1000)."\n") if ($inv_BAT_LOADTODAY ne "-"); + } + if($sup_SpotBatteryUnload) { + push(@row_array, "bat_unloadtotal ".($inv_BAT_UNLOADTOTAL/1000)."\n") if ($inv_BAT_UNLOADTOTAL ne "-"); + push(@row_array, "bat_unloadtoday ".($inv_BAT_UNLOADTODAY/1000)."\n") if ($inv_BAT_UNLOADTODAY ne "-"); + } if($detail_level > 0) { # For Detail Level 1 if($sup_SpotDCVoltage) { push(@row_array, "string_1_udc ".sprintf("%.2f",$inv_SPOT_UDC1)."\n"); - push(@row_array, "string_2_udc ".sprintf("%.2f",$inv_SPOT_UDC2)."\n"); + push(@row_array, "string_2_udc ".sprintf("%.2f",$inv_SPOT_UDC2)."\n") if($inv_SPOT_UDC2 ne "-"); + push(@row_array, "string_3_udc ".sprintf("%.2f",$inv_SPOT_UDC3)."\n") if($inv_SPOT_UDC3 ne "-"); push(@row_array, "string_1_idc ".sprintf("%.3f",$inv_SPOT_IDC1)."\n"); - push(@row_array, "string_2_idc ".sprintf("%.3f",$inv_SPOT_IDC2)."\n"); + push(@row_array, "string_2_idc ".sprintf("%.3f",$inv_SPOT_IDC2)."\n") if($inv_SPOT_IDC2 ne "-"); + push(@row_array, "string_3_idc ".sprintf("%.3f",$inv_SPOT_IDC3)."\n") if($inv_SPOT_IDC3 ne "-"); } if($sup_SpotACVoltage) { push(@row_array, "phase_1_uac ".sprintf("%.2f",$inv_SPOT_UAC1)."\n") if ($inv_SPOT_UAC1 ne "-"); @@ -885,10 +1361,23 @@ sub SMAInverter_getstatusDoParse($) { push(@row_array, "phase_1_iac ".sprintf("%.2f",$inv_SPOT_IAC1)."\n") if ($inv_SPOT_IAC1 ne "-"); push(@row_array, "phase_2_iac ".sprintf("%.2f",$inv_SPOT_IAC2)."\n") if ($inv_SPOT_IAC2 ne "-"); push(@row_array, "phase_3_iac ".sprintf("%.2f",$inv_SPOT_IAC3)."\n") if ($inv_SPOT_IAC3 ne "-"); + } + if($sup_SpotACCurrent_Backup) { + push(@row_array, "phase_backup_1_iac ".sprintf("%.2f",$inv_SPOT_IAC1_Backup)."\n") if ($inv_SPOT_IAC1_Backup ne "-"); + push(@row_array, "phase_backup_2_iac ".sprintf("%.2f",$inv_SPOT_IAC2_Backup)."\n") if ($inv_SPOT_IAC2_Backup ne "-"); + push(@row_array, "phase_backup_3_iac ".sprintf("%.2f",$inv_SPOT_IAC3_Backup)."\n") if ($inv_SPOT_IAC3_Backup ne "-"); + + push(@row_array, "phase_backup_1_pac ".sprintf("%.0f",$inv_SPOT_IAC1_Backup * ReadingsVal($name,"phase_1_uac",""))."\n") if ($inv_SPOT_IAC1_Backup ne "-"); + push(@row_array, "phase_backup_2_pac ".sprintf("%.0f",$inv_SPOT_IAC2_Backup * ReadingsVal($name,"phase_2_uac",""))."\n") if ($inv_SPOT_IAC2_Backup ne "-"); + push(@row_array, "phase_backup_3_pac ".sprintf("%.0f",$inv_SPOT_IAC3_Backup * ReadingsVal($name,"phase_3_uac",""))."\n") if ($inv_SPOT_IAC3_Backup ne "-"); } if($sup_BatteryInfo || $sup_BatteryInfo_2) { push(@row_array, "bat_udc ".$inv_BAT_UDC."\n"); push(@row_array, "bat_idc ".$inv_BAT_IDC."\n"); + if($INVTYPE_NAME =~ /STP(5\.0|6\.0|8\.0|10\.0)SE/xs) + { + push(@row_array, "bat_pdc ".sprintf("%.0f",($inv_BAT_UDC * $inv_BAT_IDC))."\n"); + } } if($sup_BatteryInfo_UDC) { push(@row_array, "bat_udc ".$inv_BAT_UDC."\n"); @@ -902,10 +1391,13 @@ sub SMAInverter_getstatusDoParse($) { push(@row_array, "bat_idc_b ".$inv_BAT_IDC_B."\n") if ($inv_BAT_IDC_B ne "-"); push(@row_array, "bat_idc_c ".$inv_BAT_IDC_C."\n") if ($inv_BAT_IDC_C ne "-"); } - if($sup_SpotBatteryLoad) { - push(@row_array, "bat_loadtotal ".($inv_BAT_LOADTOTAL/1000)."\n") if ($inv_BAT_LOADTOTAL ne "-"); - push(@row_array, "bat_loadtoday ".($inv_BAT_LOADTODAY/1000)."\n") if ($inv_BAT_LOADTODAY ne "-"); - } + if($sup_BatteryInfo_Capacity) { + push(@row_array, "bat_capacity ".$inv_BAT_CAPACITY."\n"); #TTT + } + if($sup_BatteryInfo_Charge) { + push(@row_array, "bat_p_charge ".($inv_BAT_P_Charge/1000)."\n"); #TTT + push(@row_array, "bat_p_discharge ".($inv_BAT_P_Discharge/1000)."\n"); #TTT + } } if($detail_level > 1) { @@ -916,11 +1408,18 @@ sub SMAInverter_getstatusDoParse($) { if($sup_BatteryInfo) { push(@row_array, "bat_cycles ".$inv_BAT_CYCLES."\n"); } + if($sup_BatteryInfo_4) { + push(@row_array, "bat_rated_capacity ".($inv_BAT_rated_capacity / 1000)."\n"); + } + if($sup_BatteryInfo_TEMP) { push(@row_array, "bat_temp ".$inv_BAT_TEMP."\n"); push(@row_array, "bat_temp_a ".$inv_BAT_TEMP_A."\n") if ($inv_BAT_TEMP_A ne "-"); push(@row_array, "bat_temp_b ".$inv_BAT_TEMP_B."\n") if ($inv_BAT_TEMP_B ne "-"); push(@row_array, "bat_temp_c ".$inv_BAT_TEMP_C."\n") if ($inv_BAT_TEMP_C ne "-"); + } + if($sup_BatStatus) { + push(@row_array, "bat_status ".SMAInverter_StatusText($inv_BAT_STATUS)."\n"); } if($sup_SpotGridFrequency) { push(@row_array, "grid_freq ".sprintf("%.2f",$inv_SPOT_FREQ)."\n"); @@ -931,6 +1430,9 @@ sub SMAInverter_getstatusDoParse($) { push(@row_array, "susyid ".$inv_susyid." - SN: ".$inv_serial."\n") if($inv_susyid && $inv_serial); push(@row_array, "device_name "."SN: ".$inv_serial."\n") if($inv_serial); push(@row_array, "serial_number ".$inv_serial."\n") if($inv_serial); + } + if($sup_Firmware) { + push(@row_array, "device_firmware ".$inv_Firmware."\n"); } if($sup_MaxACPower) { push(@row_array, "pac_max_phase_1 ".$inv_PACMAX1."\n"); @@ -952,18 +1454,77 @@ sub SMAInverter_getstatusDoParse($) { } if($sup_DeviceStatus) { push(@row_array, "device_status ".SMAInverter_StatusText($inv_STATUS)."\n"); + } + + if($sup_BackupRelayStatus) { + push(@row_array, "backuprelay_status ".SMAInverter_StatusText($inv_BACKUPRELAY)."\n"); + } + if($sup_GridConection) { + push(@row_array, "GridConection ".SMAInverter_StatusText($inv_GridConection)."\n"); + } + + if($sup_OperatingStatus) { + push(@row_array, "operating_status ".SMAInverter_StatusText($inv_OperatingStatus)."\n"); + } + if($sup_GeneralOperatingStatus) { + push(@row_array, "general_operating_status ".SMAInverter_StatusText($inv_GeneralOperatingStatus)."\n"); + } + if($sup_WaitingTimeUntilFeedIn) { + push(@row_array, "waiting_time_until_feed_in ".$inv_WaitingTimeUntilFeedIn."\n"); } } - + if($detail_level > 2) { + if($sup_Insulation_1) { + push(@row_array, "device_dc_insulation ".$inv_DC_insulation."\n"); + } + if($sup_Insulation_2) { + push(@row_array, "device_dc_residual_current ".$inv_DC_Residual_Current."\n"); + } + } } else { # kein SBFSpot Compatibility Mode - if($sup_EnergyProduction) { + + if($sup_EM_1) { + push(@row_array, "Meter_TOTAL_FeedIn ".$Meter_Total_Yield."\n") if ($Meter_Total_Yield ne "-"); + push(@row_array, "Meter_TOTAL_Consumation ".$Meter_Total_Consumation."\n") if ($Meter_Total_Consumation ne "-"); + } + + if($sup_EM_2) { + push(@row_array, "Meter_TOTAL_Grid_FeedIn ".$Meter_Grid_FeedIn."\n") if ($Meter_Grid_FeedIn ne "-"); + push(@row_array, "Meter_TOTAL_Grid_Consumation ".$Meter_Grid_Consumation."\n") if ($Meter_Grid_Consumation ne "-"); + } + + if($sup_EM_3) { + push(@row_array, "Meter_Power_Grid_FeedIn ".($Meter_Power_Grid_FeedIn)."\n") if ($Meter_Power_Grid_FeedIn ne "-"); + push(@row_array, "Meter_Power_Grid_Consumation ".($Meter_Power_Grid_Consumation)."\n") if ($Meter_Power_Grid_Consumation ne "-"); + } + + if($sup_EM_4) { + push(@row_array, "Meter_Grid_FeedIn_PAC1 ".($Meter_Grid_FeedIn_PAC1)."\n") if ($Meter_Grid_FeedIn_PAC1 ne "-"); + push(@row_array, "Meter_Grid_FeedIn_PAC2 ".($Meter_Grid_FeedIn_PAC2)."\n") if ($Meter_Grid_FeedIn_PAC2 ne "-"); + push(@row_array, "Meter_Grid_FeedIn_PAC3 ".($Meter_Grid_FeedIn_PAC3)."\n") if ($Meter_Grid_FeedIn_PAC3 ne "-"); + + push(@row_array, "Meter_Grid_Consumation_PAC1 ".($Meter_Grid_Consumation_PAC1)."\n") if ($Meter_Grid_Consumation_PAC1 ne "-"); + push(@row_array, "Meter_Grid_Consumation_PAC2 ".($Meter_Grid_Consumation_PAC2)."\n") if ($Meter_Grid_Consumation_PAC2 ne "-"); + push(@row_array, "Meter_Grid_Consumation_PAC3 ".($Meter_Grid_Consumation_PAC3)."\n") if ($Meter_Grid_Consumation_PAC3 ne "-"); + } + + if($sup_EnergyProduction) { push(@row_array, "SPOT_ETOTAL ".$inv_SPOT_ETOTAL."\n") if ($inv_SPOT_ETOTAL ne "-"); push(@row_array, "SPOT_ETODAY ".$inv_SPOT_ETODAY."\n") if ($inv_SPOT_ETODAY ne "-"); + } + if($sup_PVEnergyProduction) { + push(@row_array, "SPOT_EPVTOTAL ".$inv_SPOT_EPVTOTAL."\n") if ($inv_SPOT_EPVTOTAL ne "-"); + push(@row_array, "SPOT_EPVTODAY ".$inv_SPOT_EPVTODAY."\n") if ($inv_SPOT_EPVTODAY ne "-"); } if($sup_SpotDCPower) { - push(@row_array, "SPOT_PDC1 ".$inv_SPOT_PDC1."\n"); - push(@row_array, "SPOT_PDC2 ".$inv_SPOT_PDC2."\n"); + push(@row_array, "SPOT_PDC1 ".$inv_SPOT_PDC1."\n") if ($inv_SPOT_PDC1 ne "-"); + push(@row_array, "SPOT_PDC2 ".$inv_SPOT_PDC2."\n") if ($inv_SPOT_PDC2 ne "-"); + push(@row_array, "SPOT_PDC3 ".$inv_SPOT_PDC3."\n") if ($inv_SPOT_PDC3 ne "-"); + } + if($sup_SpotDCPower_3) { + push(@row_array, "SPOT_PDC ".($inv_SPOT_PDC)."\n"); + push(@row_array, "state ".$inv_SPOT_PDC."\n") if ($INVCLASS eq "8009"); } if($sup_SpotACPower) { push(@row_array, "SPOT_PAC1 ".$inv_SPOT_PAC1."\n") if ($inv_SPOT_PAC1 ne "-"); @@ -972,7 +1533,7 @@ sub SMAInverter_getstatusDoParse($) { } if($sup_SpotACTotalPower) { push(@row_array, "SPOT_PACTOT ".$inv_SPOT_PACTOT."\n"); - push(@row_array, "state ".$inv_SPOT_PACTOT."\n"); + push(@row_array, "state ".$inv_SPOT_PACTOT."\n") if ($INVCLASS ne "8009"); } if($sup_ChargeStatus) { push(@row_array, "ChargeStatus ".$inv_ChargeStatus."\n"); @@ -987,13 +1548,26 @@ sub SMAInverter_getstatusDoParse($) { push(@row_array, "POWER_IN "."0"."\n"); } } + + if($sup_SpotBatteryLoad) { + push(@row_array, "BAT_LOADTOTAL ".$inv_BAT_LOADTOTAL."\n") if ($inv_BAT_LOADTOTAL ne "-"); + push(@row_array, "BAT_LOADTODAY ".$inv_BAT_LOADTODAY."\n") if ($inv_BAT_LOADTODAY ne "-"); + } + + if($sup_SpotBatteryUnload) { + push(@row_array, "BAT_UNLOADTOTAL ".$inv_BAT_UNLOADTOTAL."\n") if ($inv_BAT_UNLOADTOTAL ne "-"); + push(@row_array, "BAT_UNLOADTODAY ".$inv_BAT_UNLOADTODAY."\n") if ($inv_BAT_UNLOADTODAY ne "-"); + } + if($detail_level > 0) { # For Detail Level 1 if($sup_SpotDCVoltage) { push(@row_array, "SPOT_UDC1 ".$inv_SPOT_UDC1."\n"); - push(@row_array, "SPOT_UDC2 ".$inv_SPOT_UDC2."\n"); + push(@row_array, "SPOT_UDC2 ".$inv_SPOT_UDC2."\n") if($inv_SPOT_UDC2 ne "-"); + push(@row_array, "SPOT_UDC3 ".$inv_SPOT_UDC3."\n") if($inv_SPOT_UDC3 ne "-"); push(@row_array, "SPOT_IDC1 ".$inv_SPOT_IDC1."\n"); - push(@row_array, "SPOT_IDC2 ".$inv_SPOT_IDC2."\n"); + push(@row_array, "SPOT_IDC2 ".$inv_SPOT_IDC2."\n") if($inv_SPOT_IDC2 ne "-"); + push(@row_array, "SPOT_IDC3 ".$inv_SPOT_IDC3."\n") if($inv_SPOT_IDC3 ne "-"); } if($sup_SpotACVoltage) { push(@row_array, "SPOT_UAC1 ".$inv_SPOT_UAC1."\n") if ($inv_SPOT_UAC1 ne "-"); @@ -1008,10 +1582,23 @@ sub SMAInverter_getstatusDoParse($) { push(@row_array, "SPOT_IAC1 ".sprintf("%.2f",$inv_SPOT_IAC1)."\n") if ($inv_SPOT_IAC1 ne "-"); push(@row_array, "SPOT_IAC2 ".sprintf("%.2f",$inv_SPOT_IAC2)."\n") if ($inv_SPOT_IAC2 ne "-"); push(@row_array, "SPOT_IAC3 ".sprintf("%.2f",$inv_SPOT_IAC3)."\n") if ($inv_SPOT_IAC3 ne "-"); + } + if($sup_SpotACCurrent_Backup) { + push(@row_array, "SPOT_Backup_IAC1 ".sprintf("%.2f",$inv_SPOT_IAC1_Backup)."\n") if ($inv_SPOT_IAC1_Backup ne "-"); + push(@row_array, "SPOT_Backup_IAC2 ".sprintf("%.2f",$inv_SPOT_IAC2_Backup)."\n") if ($inv_SPOT_IAC2_Backup ne "-"); + push(@row_array, "SPOT_Backup_IAC3 ".sprintf("%.2f",$inv_SPOT_IAC3_Backup)."\n") if ($inv_SPOT_IAC3_Backup ne "-"); + + push(@row_array, "SPOT_Backup_PAC1 ".sprintf("%.0f",$inv_SPOT_IAC1_Backup * ReadingsVal($name,"SPOT_UAC1",""))."\n") if ($inv_SPOT_IAC1_Backup ne "-"); + push(@row_array, "SPOT_Backup_PAC2 ".sprintf("%.0f",$inv_SPOT_IAC2_Backup * ReadingsVal($name,"SPOT_UAC2",""))."\n") if ($inv_SPOT_IAC2_Backup ne "-"); + push(@row_array, "SPOT_Backup_PAC3 ".sprintf("%.0f",$inv_SPOT_IAC3_Backup * ReadingsVal($name,"SPOT_UAC3",""))."\n") if ($inv_SPOT_IAC3_Backup ne "-"); } if($sup_BatteryInfo || $sup_BatteryInfo_2) { push(@row_array, "BAT_UDC ". $inv_BAT_UDC."\n"); - push(@row_array, "BAT_IDC ". $inv_BAT_IDC."\n"); + push(@row_array, "BAT_IDC ". $inv_BAT_IDC."\n"); + if($INVTYPE_NAME =~ /STP(5\.0|6\.0|8\.0|10\.0)SE/xs) + { + push(@row_array, "BAT_PDC ".sprintf("%.0f",($inv_BAT_UDC * $inv_BAT_IDC))."\n"); + } } if($sup_BatteryInfo_UDC) { push(@row_array, "BAT_UDC ". $inv_BAT_UDC."\n"); @@ -1025,10 +1612,15 @@ sub SMAInverter_getstatusDoParse($) { push(@row_array, "BAT_IDC_B ".$inv_BAT_IDC_B."\n") if ($inv_BAT_IDC_B ne "-"); push(@row_array, "BAT_IDC_C ".$inv_BAT_IDC_C."\n") if ($inv_BAT_IDC_C ne "-"); } - if($sup_SpotBatteryLoad) { - push(@row_array, "BAT_LOADTOTAL ".$inv_BAT_LOADTOTAL."\n") if ($inv_BAT_LOADTOTAL ne "-"); - push(@row_array, "BAT_LOADTODAY ".$inv_BAT_LOADTODAY."\n") if ($inv_BAT_LOADTODAY ne "-"); - } + + if($sup_BatteryInfo_Capacity) { + push(@row_array, "BAT_CAPACITY ".$inv_BAT_CAPACITY."\n") if ($inv_BAT_CAPACITY ne "-"); #TTT + } + + if($sup_BatteryInfo_Charge) { + push(@row_array, "BAT_P_CHARGE ".$inv_BAT_P_Charge."\n"); #TTT + push(@row_array, "BAT_P_DISCHARGE ".$inv_BAT_P_Discharge."\n"); #TTT + } } if($detail_level > 1) { @@ -1038,12 +1630,18 @@ sub SMAInverter_getstatusDoParse($) { } if($sup_BatteryInfo) { push(@row_array, "BAT_CYCLES ".$inv_BAT_CYCLES."\n"); + } + if($sup_BatteryInfo_4) { + push(@row_array, "BAT_RATED_CAPACITY ".$inv_BAT_rated_capacity."\n"); } if($sup_BatteryInfo_TEMP) { push(@row_array, "BAT_TEMP ". $inv_BAT_TEMP."\n"); push(@row_array, "BAT_TEMP_A ".$inv_BAT_TEMP_A."\n") if ($inv_BAT_TEMP_A ne "-"); push(@row_array, "BAT_TEMP_B ".$inv_BAT_TEMP_B."\n") if ($inv_BAT_TEMP_B ne "-"); push(@row_array, "BAT_TEMP_C ".$inv_BAT_TEMP_C."\n") if ($inv_BAT_TEMP_C ne "-"); + } + if($sup_BatStatus) { + push(@row_array, "BAT_STATUS ".SMAInverter_StatusText($inv_BAT_STATUS)."\n"); } if($sup_SpotGridFrequency) { push(@row_array, "SPOT_FREQ ".$inv_SPOT_FREQ."\n"); @@ -1053,6 +1651,9 @@ sub SMAInverter_getstatusDoParse($) { push(@row_array, "INV_CLASS ". SMAInverter_classtype($inv_CLASS)."\n"); push(@row_array, "SUSyID ". $inv_susyid."\n") if($inv_susyid); push(@row_array, "Serialnumber ".$inv_serial."\n") if($inv_serial); + } + if($sup_Firmware) { + push(@row_array, "INV_FIRMWARE ".$inv_Firmware."\n"); } if($sup_MaxACPower) { push(@row_array, "INV_PACMAX1 ".$inv_PACMAX1."\n"); @@ -1074,8 +1675,34 @@ sub SMAInverter_getstatusDoParse($) { } if($sup_DeviceStatus) { push(@row_array, "INV_STATUS ".SMAInverter_StatusText($inv_STATUS)."\n"); + } + + if($sup_BackupRelayStatus) { + push(@row_array, "INV_BACKRELAYRELAY ".SMAInverter_StatusText($inv_BACKUPRELAY)."\n"); + } + if($sup_GridConection) { + push(@row_array, "INV_GridConection ".SMAInverter_StatusText($inv_GridConection)."\n"); + } + + if($sup_OperatingStatus) { + push(@row_array, "INV_OperatingStatus ".SMAInverter_StatusText($inv_OperatingStatus)."\n"); + } + if($sup_GeneralOperatingStatus) { + push(@row_array, "INV_GeneralOperatingStatus ".SMAInverter_StatusText($inv_GeneralOperatingStatus)."\n"); + } + if($sup_WaitingTimeUntilFeedIn) { + push(@row_array, "INV_WaitingTimeUntilFeedIn ".$inv_WaitingTimeUntilFeedIn."\n"); } } + + if($detail_level > 2) { + if($sup_Insulation_1) { + push(@row_array, "INV_DC_Insulation ".$inv_DC_insulation."\n"); + } + if($sup_Insulation_2) { + push(@row_array, "INV_DC_Residual_Current ".$inv_DC_Residual_Current."\n"); + } + } } } else { @@ -1109,7 +1736,7 @@ sub SMAInverter_getstatusDoParse($) { Log3 ($name, 4, "$name -> BlockingCall SMAInverter_getstatusDoParse finished"); -return "$name|$rowlist|$avg|$rt"; +return "$name|$rowlist|$avg|$rt|$INVCLASS|$INVTYPE|$INVFWMAIN"; } ############################################################### @@ -1124,6 +1751,10 @@ sub SMAInverter_getstatusParseDone ($) { $hash->{HELPER}{AVERAGEBUF} = $a[2] if($a[2]); my $rt = $a[3]; my ($irt,$brt) = split(",", $rt); + + $hash->{INVCLASS} = $a[4]; + $hash->{INVTYPE} = $a[5]; + $hash->{INVFWMAIN} = $a[6]; Log3 ($name, 4, "$name -> Start BlockingCall SMAInverter_getstatusParseDone"); @@ -1197,30 +1828,41 @@ sub SMAInverter_SMAcommand($$$$$) { my $esignature = "0010606509A0"; my ($inv_TYPE, $inv_CLASS, $inv_SPOT_ETODAY, $inv_SPOT_ETOTAL, + $inv_SPOT_EPVTODAY, $inv_SPOT_EPVTOTAL, $inv_susyid, $inv_serial, - $inv_SPOT_PDC1, $inv_SPOT_PDC2, + $inv_Firmware, + $inv_SPOT_PDC, $inv_SPOT_PDC1, $inv_SPOT_PDC2, $inv_SPOT_PDC3, $inv_SPOT_PAC1, $inv_SPOT_PAC2, $inv_SPOT_PAC3, $inv_SPOT_PACTOT, $inv_PACMAX1, $inv_PACMAX2, $inv_PACMAX3, $inv_PACMAX1_2, $inv_ChargeStatus, - $inv_SPOT_UDC1, $inv_SPOT_UDC2, - $inv_SPOT_IDC1, $inv_SPOT_IDC2, + $inv_SPOT_UDC1, $inv_SPOT_UDC2, $inv_SPOT_UDC3, + $inv_SPOT_IDC1, $inv_SPOT_IDC2, $inv_SPOT_IDC3, $inv_SPOT_UAC1, $inv_SPOT_UAC2, $inv_SPOT_UAC3, $inv_SPOT_UAC1_2, $inv_SPOT_UAC2_3, $inv_SPOT_UAC3_1, $inv_SPOT_IAC1, $inv_SPOT_IAC2, $inv_SPOT_IAC3, + $inv_SPOT_IAC1_Backup, $inv_SPOT_IAC2_Backup, $inv_SPOT_IAC3_Backup, $inv_SPOT_CosPhi, $inv_BAT_UDC, $inv_BAT_UDC_A, $inv_BAT_UDC_B, $inv_BAT_UDC_C, $inv_BAT_IDC, $inv_BAT_IDC_A, $inv_BAT_IDC_B, $inv_BAT_IDC_C, + $inv_BAT_P_Charge, $inv_BAT_P_Discharge, $inv_BAT_CYCLES, $inv_BAT_CYCLES_A, $inv_BAT_CYCLES_B, $inv_BAT_CYCLES_C, $inv_BAT_TEMP, $inv_BAT_TEMP_A, $inv_BAT_TEMP_B, $inv_BAT_TEMP_C, - $inv_BAT_LOADTODAY, $inv_BAT_LOADTOTAL, - $inv_SPOT_FREQ, $inv_SPOT_OPERTM, $inv_SPOT_FEEDTM, $inv_TEMP, $inv_GRIDRELAY, $inv_STATUS); + $inv_BAT_LOADTODAY, $inv_BAT_LOADTOTAL, $inv_BAT_CAPACITY,$inv_BAT_UNLOADTODAY,$inv_BAT_UNLOADTOTAL, + $inv_BAT_rated_capacity, $inv_BAT_STATUS, + $inv_SPOT_FREQ, $inv_SPOT_OPERTM, $inv_SPOT_FEEDTM, $inv_TEMP, $inv_GRIDRELAY, $inv_STATUS, + $inv_BACKUPRELAY, $inv_OperatingStatus, $inv_GeneralOperatingStatus, $inv_WaitingTimeUntilFeedIn, $inv_GridConection, + $Meter_Grid_FeedIn, $Meter_Grid_Consumation, $Meter_Total_FeedIn, $Meter_Total_Consumation, + $Meter_Power_Grid_FeedIn, $Meter_Power_Grid_Consumation, + $Meter_Grid_FeedIn_PAC1, $Meter_Grid_FeedIn_PAC2, $Meter_Grid_FeedIn_PAC3, $Meter_Grid_Consumation_PAC1, $Meter_Grid_Consumation_PAC2, $Meter_Grid_Consumation_PAC3); my $mysusyid = $hash->{HELPER}{MYSUSYID}; my $myserialnumber = $hash->{HELPER}{MYSERIALNUMBER}; my ($cmd, $myID, $target_ID, $spkt_ID, $cmd_ID); my ($socket,$data,$size,$data_ID); my ($i, $temp, $count); # Variables for loops and calculation + my $INVTYPE_NAME = ReadingsVal($name,"INV_TYPE",ReadingsVal($name,"device_type","")); + # Seriennummer und SuSyID des Ziel-WR setzen my $default_target_susyid = $hash->{HELPER}{DEFAULT_TARGET_SUSYID}; my $default_target_serial = $hash->{HELPER}{DEFAULT_TARGET_SERIAL}; @@ -1315,19 +1957,144 @@ sub SMAInverter_SMAcommand($$$$$) { $data_ID = unpack("v*", substr $data, 55, 2); Log3 ($name, 5, "$name - Data identifier $data_ID"); +#Meter + + if($data_ID eq 0x4624) { + if (length($data) >= 66) { + $Meter_Grid_FeedIn = unpack("V*", substr($data, 62, 4)); + + if(($Meter_Grid_FeedIn eq -2147483648) || ($Meter_Grid_FeedIn eq 0xFFFFFFFF) || $Meter_Grid_FeedIn <= 0) {$Meter_Grid_FeedIn = "-"; } + } + else { + Log3 ($name, 3, "$name - WARNING - Meter_Grid_FeedIn wasn't deliverd ... set it to \"0\" !"); + $Meter_Grid_FeedIn = "-"; + } + + if (length($data) >= 82) { + $Meter_Grid_Consumation = unpack("V*", substr($data, 78, 4)); + + if(($Meter_Grid_Consumation eq -2147483648) || ($Meter_Grid_Consumation eq 0xFFFFFFFF) || $Meter_Grid_Consumation <= 0) {$Meter_Grid_Consumation = "-"; } + } + else { + Log3 ($name, 3, "$name - WARNING - Meter_Grid_Consumation wasn't deliverd ... set it to \"0\" !"); + $Meter_Grid_Consumation = "-"; + } + + Log3 $name, 5, "$name - Data Meter_Grid_FeedIn=$Meter_Grid_FeedIn and Meter_Grid_Consumation=$Meter_Grid_Consumation"; + return (1,$Meter_Grid_FeedIn,$Meter_Grid_Consumation,$inv_susyid,$inv_serial); + } + + if($data_ID eq 0x4691) { + if (length($data) >= 66) { + $Meter_Grid_FeedIn = unpack("V*", substr($data, 62, 4)); + + if(($Meter_Grid_FeedIn eq -2147483648) || ($Meter_Grid_FeedIn eq 0xFFFFFFFF) || $Meter_Grid_FeedIn <= 0) {$Meter_Grid_FeedIn = "-"; } + } + else { + Log3 ($name, 3, "$name - WARNING - Meter_Grid_FeedIn wasn't deliverd ... set it to \"0\" !"); + $Meter_Grid_FeedIn = "-"; + } + + if (length($data) >= 82) { + $Meter_Grid_Consumation = unpack("V*", substr($data, 78, 4)); + + if(($Meter_Grid_Consumation eq -2147483648) || ($Meter_Grid_Consumation eq 0xFFFFFFFF) || $Meter_Grid_Consumation <= 0) {$Meter_Grid_Consumation = "-"; } + } + else { + Log3 ($name, 3, "$name - WARNING - Meter_Grid_Consumation wasn't deliverd ... set it to \"0\" !"); + $Meter_Grid_Consumation = "-"; + } + + Log3 $name, 5, "$name - Data Meter_Grid_FeedIn=$Meter_Grid_FeedIn and Meter_Grid_Consumation=$Meter_Grid_Consumation"; + return (1,$Meter_Grid_FeedIn,$Meter_Grid_Consumation,$inv_susyid,$inv_serial); + } + + if($data_ID eq 0x4636) { + if (length($data) >= 66) { + $Meter_Power_Grid_FeedIn = unpack("V*", substr($data, 62, 4)); + + if(($Meter_Power_Grid_FeedIn eq -2147483648) || ($Meter_Power_Grid_FeedIn eq 0xFFFFFFFF) || $Meter_Power_Grid_FeedIn < 0) {$Meter_Grid_FeedIn = "-"; } + } + else { + Log3 ($name, 3, "$name - WARNING - Meter_Power_Grid_FeedIn wasn't deliverd ... set it to \"0\" !"); + $Meter_Grid_FeedIn = "-"; + } + + if (length($data) >= 94) { + $Meter_Power_Grid_Consumation = unpack("V*", substr($data, 90, 4)); + + if(($Meter_Power_Grid_Consumation eq -2147483648) || ($Meter_Power_Grid_Consumation eq 0xFFFFFFFF) || $Meter_Power_Grid_Consumation < 0) {$Meter_Power_Grid_Consumation = "-"; } + } + else { + Log3 ($name, 3, "$name - WARNING - Meter_Power_Grid_Consumation wasn't deliverd ... set it to \"0\" !"); + $Meter_Grid_Consumation = "-"; + } + + Log3 $name, 5, "$name - Data Meter_Power_Grid_FeedIn=$Meter_Power_Grid_FeedIn and Meter_Power_Grid_Consumation=$Meter_Power_Grid_Consumation"; + return (1,$Meter_Power_Grid_FeedIn,$Meter_Power_Grid_Consumation,$inv_susyid,$inv_serial); + } + + if($data_ID eq 0x46e8) { + $Meter_Grid_FeedIn_PAC1 = unpack("l*", substr $data, 62, 4); + if($Meter_Grid_FeedIn_PAC1 eq -2147483648) {$Meter_Grid_FeedIn_PAC1 = "-"; } # Catch 0x80000000 as 0 value + $Meter_Grid_FeedIn_PAC2 = unpack("l*", substr $data, 90, 4); + if($Meter_Grid_FeedIn_PAC2 eq -2147483648) {$Meter_Grid_FeedIn_PAC2 = "-"; } # Catch 0x80000000 as 0 value + $Meter_Grid_FeedIn_PAC3 = unpack("l*", substr $data, 118, 4); + if($Meter_Grid_FeedIn_PAC3 eq -2147483648) {$Meter_Grid_FeedIn_PAC3 = "-"; } # Catch 0x80000000 as 0 value + Log3 $name, 5, "$name - Found Data Meter_Grid_FeedIn_PAC1=$Meter_Grid_FeedIn_PAC1 and Meter_Grid_FeedIn_PAC2=$Meter_Grid_FeedIn_PAC2 and Meter_Grid_FeedIn_PAC3=$Meter_Grid_FeedIn_PAC3"; + + $Meter_Grid_Consumation_PAC1 = unpack("l*", substr $data, 146, 4); + if($Meter_Grid_Consumation_PAC1 eq -2147483648) {$Meter_Grid_Consumation_PAC1 = "-"; } # Catch 0x80000000 as 0 value + $Meter_Grid_Consumation_PAC2 = unpack("l*", substr $data, 174, 4); + if($Meter_Grid_Consumation_PAC2 eq -2147483648) {$Meter_Grid_Consumation_PAC2 = "-"; } # Catch 0x80000000 as 0 value + $Meter_Grid_Consumation_PAC3 = unpack("l*", substr $data, 202, 4); + if($Meter_Grid_Consumation_PAC3 eq -2147483648) {$Meter_Grid_Consumation_PAC3 = "-"; } # Catch 0x80000000 as 0 value + Log3 $name, 5, "$name - Found Data Meter_Grid_Consumation_PAC1=$Meter_Grid_Consumation_PAC1 and Meter_Grid_Consumation_PAC2=$Meter_Grid_Consumation_PAC2 and Meter_Grid_Consumation_PAC3=$Meter_Grid_Consumation_PAC3"; + + return (1,$Meter_Grid_FeedIn_PAC1,$Meter_Grid_FeedIn_PAC2,$Meter_Grid_FeedIn_PAC3,$Meter_Grid_Consumation_PAC1,$Meter_Grid_Consumation_PAC2,$Meter_Grid_Consumation_PAC3,$inv_susyid,$inv_serial); + } +#Meter end + + if($data_ID eq 0x8234) { + $inv_Firmware = hex(unpack("H*", substr $data, 81, 1)); + my $INVFWMAIN = $inv_Firmware; + $inv_Firmware = $inv_Firmware .".". hex(unpack("H*", substr $data, 80, 1)); + $inv_Firmware = $inv_Firmware .".". hex(unpack("H*", substr $data, 79, 1)); + + my $inv_Firmware_X = hex(unpack("H*", substr $data, 78, 1)); + + if($inv_Firmware_X == 4) + { + $inv_Firmware = $inv_Firmware ." R"; + } + else + { + $inv_Firmware = $inv_Firmware ." ?".$inv_Firmware_X; + } + + Log3 $name, 5, "$name - Found Data Firmware=$inv_Firmware data=$data"; + return (1,$inv_Firmware,$INVFWMAIN,$inv_susyid,$inv_serial); + } + if($data_ID eq 0x2601) { if (length($data) >= 66) { $inv_SPOT_ETOTAL = unpack("V*", substr($data, 62, 4)); + + if(($inv_SPOT_ETOTAL eq -2147483648) || ($inv_SPOT_ETOTAL eq 0xFFFFFFFF) || $inv_SPOT_ETOTAL <= 0) {$inv_SPOT_ETOTAL = "-"; } } else { Log3 ($name, 3, "$name - WARNING - ETOTAL wasn't deliverd ... set it to \"0\" !"); $inv_SPOT_ETOTAL = "-"; } + $inv_SPOT_ETODAY = "-"; if (length($data) >= 82) { $inv_SPOT_ETODAY = unpack("V*", substr ($data, 78, 4)); - } - elsif($inv_SPOT_ETOTAL ne "-") { + + if(($inv_SPOT_ETODAY eq -2147483648) || ($inv_SPOT_ETODAY eq 0xFFFFFFFF) || $inv_SPOT_ETODAY <= 0) {$inv_SPOT_ETODAY = "-"; } + } + + if($inv_SPOT_ETODAY eq "-" && $inv_SPOT_ETOTAL ne "-") { # ETODAY wurde vom WR nicht geliefert, es wird versucht ihn zu berechnen Log3 ($name, 3, "$name - ETODAY wasn't delivered from inverter, try to calculate it ..."); my $etotold = ReadingsNum($name, ".etotal_yesterday", 0); @@ -1341,28 +2108,67 @@ sub SMAInverter_SMAcommand($$$$$) { $inv_SPOT_ETODAY = "-"; } } - else - { - $inv_SPOT_ETODAY = "-"; - } Log3 $name, 5, "$name - Data SPOT_ETOTAL=$inv_SPOT_ETOTAL and SPOT_ETODAY=$inv_SPOT_ETODAY"; return (1,$inv_SPOT_ETODAY,$inv_SPOT_ETOTAL,$inv_susyid,$inv_serial); } + #PV Ertrag + if($data_ID eq 0x46C3) { + if (length($data) >= 66) { + $inv_SPOT_EPVTOTAL = unpack("V*", substr($data, 62, 4)); + + if(($inv_SPOT_EPVTOTAL eq -2147483648) || ($inv_SPOT_EPVTOTAL eq 0xFFFFFFFF) || $inv_SPOT_EPVTOTAL <= 0) {$inv_SPOT_EPVTOTAL = "-"; } + } + else { + Log3 ($name, 3, "$name - WARNING - EPVTOTAL wasn't deliverd ... set it to \"0\" !"); + $inv_SPOT_EPVTOTAL = "-"; + } + + $inv_SPOT_EPVTODAY = "-"; + if (length($data) >= 82) { + $inv_SPOT_EPVTODAY = unpack("V*", substr ($data, 78, 4)); + + if(($inv_SPOT_EPVTODAY eq -2147483648) || ($inv_SPOT_EPVTODAY eq 0xFFFFFFFF) || $inv_SPOT_EPVTODAY <= 0) {$inv_SPOT_EPVTODAY = "-"; } + } + + if($inv_SPOT_EPVTODAY eq "-" && $inv_SPOT_EPVTOTAL ne "-") { + # EPVTODAY wurde vom WR nicht geliefert, es wird versucht ihn zu berechnen + Log3 ($name, 3, "$name - EPVTODAY wasn't delivered from inverter, try to calculate it ..."); + my $etotold = ReadingsNum($name, ".epvtotal_yesterday", 0); + + if($etotold && $inv_SPOT_EPVTOTAL > $etotold) { + $inv_SPOT_EPVTODAY = $inv_SPOT_EPVTOTAL - $etotold; + Log3 ($name, 3, "$name - EPVTODAY calculated successfully !"); + } + else { + Log3 ($name, 3, "$name - WARNING - unable to calculate EPVTODAY ... set it to \"0\" !"); + $inv_SPOT_EPVTODAY = "-"; + } + } + + Log3 $name, 5, "$name - Data SPOT_EPVTOTAL=$inv_SPOT_EPVTOTAL and SPOT_EPVTODAY=$inv_SPOT_EPVTODAY"; + return (1,$inv_SPOT_EPVTODAY,$inv_SPOT_EPVTOTAL,$inv_susyid,$inv_serial); + } if($data_ID eq 0x4967) { if (length($data) >= 66) { $inv_BAT_LOADTOTAL = unpack("V*", substr($data, 62, 4)); + + if(($inv_BAT_LOADTOTAL eq -2147483648) || ($inv_BAT_LOADTOTAL eq 0xFFFFFFFF) || $inv_BAT_LOADTOTAL <= 0) {$inv_BAT_LOADTOTAL = "-"; } } else { Log3 $name, 3, "$name - WARNING - BATTERYLOAD_TOTAL wasn't deliverd ... set it to \"0\" !"; $inv_BAT_LOADTOTAL = "-"; } + $inv_BAT_LOADTODAY = "-"; if (length($data) >= 82) { $inv_BAT_LOADTODAY = unpack("V*", substr ($data, 78, 4)); + + if(($inv_BAT_LOADTODAY eq -2147483648) || ($inv_BAT_LOADTODAY eq 0xFFFFFFFF) || $inv_BAT_LOADTODAY <= 0) {$inv_BAT_LOADTODAY = "-"; } } - elsif($inv_BAT_LOADTOTAL ne "-") { + + if($inv_BAT_LOADTODAY eq "-" && $inv_BAT_LOADTOTAL ne "-") { # BATTERYLOAD_TODAY wurde vom WR nicht geliefert, es wird versucht ihn zu berechnen Log3 $name, 3, "$name - BATTERYLOAD_TODAY wasn't delivered from inverter, try to calculate it ..."; my $bltotold = ReadingsNum($name, ".bat_loadtotal_yesterday", 0); @@ -1376,24 +2182,77 @@ sub SMAInverter_SMAcommand($$$$$) { $inv_BAT_LOADTODAY = "-"; } } - else - { - $inv_BAT_LOADTODAY = "-"; - } Log3 $name, 5, "$name - Data BAT_LOADTOTAL=$inv_BAT_LOADTOTAL and BAT_LOADTODAY=$inv_BAT_LOADTODAY"; return (1,$inv_BAT_LOADTODAY,$inv_BAT_LOADTOTAL,$inv_susyid,$inv_serial); } + + if($data_ID eq 0x4968) { + if (length($data) >= 66) { + $inv_BAT_UNLOADTOTAL = unpack("V*", substr($data, 62, 4)); + + if(($inv_BAT_UNLOADTOTAL eq -2147483648) || ($inv_BAT_UNLOADTOTAL eq 0xFFFFFFFF) || $inv_BAT_UNLOADTOTAL <= 0) {$inv_BAT_UNLOADTOTAL = "-"; } + } + else { + Log3 $name, 3, "$name - WARNING - BATTERYUNLOAD_TOTAL wasn't deliverd ... set it to \"0\" !"; + $inv_BAT_UNLOADTOTAL = "-"; + } - if($data_ID eq 0x251E) { - $inv_SPOT_PDC1 = unpack("V*", substr $data, 62, 4); - if($size < 90) {$inv_SPOT_PDC2 = 0; } else {$inv_SPOT_PDC2 = unpack("V*", substr $data, 90, 4); } # catch short response, in case PDC2 not supported - $inv_SPOT_PDC1 = ($inv_SPOT_PDC1 == 2147483648) ? 0 : $inv_SPOT_PDC1; - $inv_SPOT_PDC2 = ($inv_SPOT_PDC2 == 2147483648) ? 0 : $inv_SPOT_PDC2; - Log3 $name, 5, "$name - Found Data SPOT_PDC1=$inv_SPOT_PDC1 and SPOT_PDC2=$inv_SPOT_PDC2"; - return (1,$inv_SPOT_PDC1,$inv_SPOT_PDC2,$inv_susyid,$inv_serial); + $inv_BAT_UNLOADTODAY = "-"; + if (length($data) >= 82) { + $inv_BAT_UNLOADTODAY = unpack("V*", substr ($data, 78, 4)); + + if(($inv_BAT_UNLOADTODAY eq -2147483648) || ($inv_BAT_UNLOADTODAY eq 0xFFFFFFFF) || $inv_BAT_UNLOADTODAY <= 0) {$inv_BAT_UNLOADTODAY = "-"; } + } + + if($inv_BAT_UNLOADTODAY eq "-" && $inv_BAT_UNLOADTOTAL ne "-") { + # BATTERYUNLOAD_TODAY wurde vom WR nicht geliefert, es wird versucht ihn zu berechnen + Log3 $name, 3, "$name - BATTERYUNLOAD_TODAY wasn't delivered from inverter, try to calculate it ..."; + my $bultotold = ReadingsNum($name, ".bat_unloadtotal_yesterday", 0); + + if($bultotold && $inv_BAT_UNLOADTOTAL > $bultotold) { + $inv_BAT_UNLOADTODAY = $inv_BAT_UNLOADTOTAL - $bultotold; + Log3 $name, 3, "$name - BATTERYUNLOAD_TODAY calculated successfully !"; + } + else { + Log3 $name, 3, "$name - WARNING - unable to calculate BATTERYUNLOAD_TODAY ... set it to \"0\" !"; + $inv_BAT_UNLOADTODAY = "-"; + } + } + + Log3 $name, 3, "$name - Data BAT_UNLOADTOTAL=$inv_BAT_UNLOADTOTAL and BAT_UNLOADTODAY=$inv_BAT_UNLOADTODAY"; + return (1,$inv_BAT_UNLOADTODAY,$inv_BAT_UNLOADTOTAL,$inv_susyid,$inv_serial); } + if($data_ID eq 0x251E) { + $inv_SPOT_PDC1 = unpack("l*", substr $data, 62, 4); + #$inv_SPOT_PDC1 = (abs($inv_SPOT_PDC1) eq 2147483648) ? 0 : $inv_SPOT_PDC1; + if(($inv_SPOT_PDC1 eq -2147483648) || ($inv_SPOT_PDC1 eq 0xFFFFFFFF)) {$inv_SPOT_PDC1 = "-"; } + + if($size < 90) {$inv_SPOT_PDC2 = "-"; } else { + $inv_SPOT_PDC2 = unpack("l*", substr $data, 90, 4); + #$inv_SPOT_PDC2 = (abs($inv_SPOT_PDC2) eq 2147483648) ? 0 : $inv_SPOT_PDC2; + if(($inv_SPOT_PDC2 eq -2147483648) || ($inv_SPOT_PDC2 eq 0xFFFFFFFF)) {$inv_SPOT_PDC2 = "-"; } + } # catch short response, in case PDC2 not supported + if($size < 118) {$inv_SPOT_PDC3 = "-"; } else { + $inv_SPOT_PDC3 = unpack("l*", substr $data, 118, 4); + #$inv_SPOT_PDC3 = (abs($inv_SPOT_PDC3) eq 2147483648) ? 0 : $inv_SPOT_PDC3; + if(($inv_SPOT_PDC3 eq -2147483648) || ($inv_SPOT_PDC3 eq 0xFFFFFFFF)) {$inv_SPOT_PDC3 = "-"; } + } # catch short response, in case PDC3 not supported + + Log3 $name, 5, "$name - Found Data SPOT_PDC1=$inv_SPOT_PDC1, SPOT_PDC2=$inv_SPOT_PDC2 and SPOT_PDC3=$inv_SPOT_PDC3"; + return (1,$inv_SPOT_PDC1,$inv_SPOT_PDC2,$inv_SPOT_PDC3,$inv_susyid,$inv_serial); + } + + if($data_ID eq 0x46C2) { + #$inv_SPOT_PDC = unpack("V*", substr $data, 62, 4); + #$inv_SPOT_PDC = ($inv_SPOT_PDC == 2147483648) ? 0 : $inv_SPOT_PDC; + $inv_SPOT_PDC = unpack("l*", substr $data, 62, 4); + if(($inv_SPOT_PDC eq -2147483648) || ($inv_SPOT_PDC eq 0xFFFFFFFF)) {$inv_SPOT_PDC = "-"; } + Log3 $name, 5, "$name - Found Data SPOT_PDC=$inv_SPOT_PDC"; + return (1,$inv_SPOT_PDC,$inv_susyid,$inv_serial); + } + if($data_ID eq 0x4640) { $inv_SPOT_PAC1 = unpack("l*", substr $data, 62, 4); if($inv_SPOT_PAC1 eq -2147483648) {$inv_SPOT_PAC1 = "-"; } # Catch 0x80000000 as 0 value @@ -1433,34 +2292,59 @@ sub SMAInverter_SMAcommand($$$$$) { return (1,$inv_ChargeStatus,$inv_susyid,$inv_serial); } + if($data_ID eq 0x696E) { + $inv_BAT_CAPACITY = unpack("V*", substr $data, 62, 4); + Log3 $name, 5, "$name - Found Data Battery Capacity =$inv_BAT_CAPACITY"; #TTT + return (1,$inv_BAT_CAPACITY,$inv_susyid,$inv_serial); + } if($data_ID eq 0x451F) { $inv_SPOT_UDC1 = unpack("l*", substr $data, 62, 4); # catch shorter responses in case not second string supported if($size < 146) { - $inv_SPOT_UDC2 = 0; + $inv_SPOT_UDC2 = "-"; + $inv_SPOT_UDC3 = "-"; $inv_SPOT_IDC1 = unpack("l*", substr $data, 90, 4); - $inv_SPOT_IDC2 = 0; - } else { + $inv_SPOT_IDC2 = "-"; + $inv_SPOT_IDC3 = "-"; + } elsif($size < 194) { $inv_SPOT_UDC2 = unpack("l*", substr $data, 90, 4); + $inv_SPOT_UDC3 = "-"; $inv_SPOT_IDC1 = unpack("l*", substr $data, 118, 4); $inv_SPOT_IDC2 = unpack("l*", substr $data, 146, 4); + $inv_SPOT_IDC3 = "-"; + } else { + $inv_SPOT_UDC2 = unpack("l*", substr $data, 90, 4); + $inv_SPOT_UDC3 = unpack("l*", substr $data, 118, 4); + $inv_SPOT_IDC1 = unpack("l*", substr $data, 146, 4); + $inv_SPOT_IDC2 = unpack("l*", substr $data, 174, 4); + $inv_SPOT_IDC3 = unpack("l*", substr $data, 202, 4); } - if(($inv_SPOT_UDC1 eq -2147483648) || ($inv_SPOT_UDC1 eq 0xFFFFFFFF)) {$inv_SPOT_UDC1 = 0; } else {$inv_SPOT_UDC1 = $inv_SPOT_UDC1 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value - if(($inv_SPOT_UDC2 eq -2147483648) || ($inv_SPOT_UDC2 eq 0xFFFFFFFF)) {$inv_SPOT_UDC2 = 0; } else {$inv_SPOT_UDC2 = $inv_SPOT_UDC2 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value - if(($inv_SPOT_IDC1 eq -2147483648) || ($inv_SPOT_IDC1 eq 0xFFFFFFFF)) {$inv_SPOT_IDC1 = 0; } else {$inv_SPOT_IDC1 = $inv_SPOT_IDC1 / 1000; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value - if(($inv_SPOT_IDC2 eq -2147483648) || ($inv_SPOT_IDC2 eq 0xFFFFFFFF)) {$inv_SPOT_IDC2 = 0; } else {$inv_SPOT_IDC2 = $inv_SPOT_IDC2 / 1000; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value - - Log3 $name, 5, "$name - Found Data SPOT_UDC1=$inv_SPOT_UDC1 and SPOT_UDC2=$inv_SPOT_UDC2 and SPOT_IDC1=$inv_SPOT_IDC1 and SPOT_IDC2=$inv_SPOT_IDC2"; - return (1,$inv_SPOT_UDC1,$inv_SPOT_UDC2,$inv_SPOT_IDC1,$inv_SPOT_IDC2,$inv_susyid,$inv_serial); + if(($inv_SPOT_UDC1 eq -2147483648) || ($inv_SPOT_UDC1 eq 0xFFFFFFFF)) {$inv_SPOT_UDC1 = 0; } elsif($inv_SPOT_UDC1 ne "-") {$inv_SPOT_UDC1 = $inv_SPOT_UDC1 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + if(($inv_SPOT_UDC2 eq -2147483648) || ($inv_SPOT_UDC2 eq 0xFFFFFFFF)) {$inv_SPOT_UDC2 = 0; } elsif($inv_SPOT_UDC2 ne "-") {$inv_SPOT_UDC2 = $inv_SPOT_UDC2 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + if(($inv_SPOT_UDC3 eq -2147483648) || ($inv_SPOT_UDC3 eq 0xFFFFFFFF)) {$inv_SPOT_UDC3 = 0; } elsif($inv_SPOT_UDC3 ne "-") {$inv_SPOT_UDC3 = $inv_SPOT_UDC3 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + if(($inv_SPOT_IDC1 eq -2147483648) || ($inv_SPOT_IDC1 eq 0xFFFFFFFF)) {$inv_SPOT_IDC1 = 0; } elsif($inv_SPOT_IDC1 ne "-") {$inv_SPOT_IDC1 = $inv_SPOT_IDC1 / 1000; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + if(($inv_SPOT_IDC2 eq -2147483648) || ($inv_SPOT_IDC2 eq 0xFFFFFFFF)) {$inv_SPOT_IDC2 = 0; } elsif($inv_SPOT_IDC2 ne "-") {$inv_SPOT_IDC2 = $inv_SPOT_IDC2 / 1000; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + if(($inv_SPOT_IDC3 eq -2147483648) || ($inv_SPOT_IDC3 eq 0xFFFFFFFF)) {$inv_SPOT_IDC3 = 0; } elsif($inv_SPOT_IDC3 ne "-") {$inv_SPOT_IDC3 = $inv_SPOT_IDC3 / 1000; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + + Log3 $name, 5, "$name - Found Data SPOT_UDC1=$inv_SPOT_UDC1, SPOT_UDC2=$inv_SPOT_UDC2, SPOT_UDC3=$inv_SPOT_UDC3, SPOT_IDC1=$inv_SPOT_IDC1, SPOT_IDC2=$inv_SPOT_IDC2 and SPOT_IDC3=$inv_SPOT_IDC3"; + return (1,$inv_SPOT_UDC1,$inv_SPOT_UDC2,$inv_SPOT_UDC3,$inv_SPOT_IDC1,$inv_SPOT_IDC2,$inv_SPOT_IDC3,$inv_susyid,$inv_serial); } if($data_ID eq 0x4648) { $inv_SPOT_UAC1 = unpack("l*", substr $data, 62, 4); $inv_SPOT_UAC2 = unpack("l*", substr $data, 90, 4); $inv_SPOT_UAC3 = unpack("l*", substr $data, 118, 4); - $inv_SPOT_UAC1_2 = unpack("l*", substr $data, 146, 4); - $inv_SPOT_UAC2_3 = unpack("l*", substr $data, 174, 4); - $inv_SPOT_UAC3_1 = unpack("l*", substr $data, 202, 4); + if($size >= 230) { + $inv_SPOT_UAC1_2 = unpack("l*", substr $data, 146, 4); + $inv_SPOT_UAC2_3 = unpack("l*", substr $data, 174, 4); + $inv_SPOT_UAC3_1 = unpack("l*", substr $data, 202, 4); + } + else + { + $inv_SPOT_UAC1_2 = "-"; + $inv_SPOT_UAC2_3 = "-"; + $inv_SPOT_UAC3_1 = "-"; + } if($size >= 230) { $inv_SPOT_CosPhi = unpack("l*", substr $data, 230, 4); @@ -1474,10 +2358,11 @@ sub SMAInverter_SMAcommand($$$$$) { if(($inv_SPOT_UAC1 eq -2147483648) || ($inv_SPOT_UAC1 eq 0xFFFFFFFF) || $inv_SPOT_UAC1 < 0) {$inv_SPOT_UAC1 = "-"; } else {$inv_SPOT_UAC1 = $inv_SPOT_UAC1 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value if(($inv_SPOT_UAC2 eq -2147483648) || ($inv_SPOT_UAC2 eq 0xFFFFFFFF) || $inv_SPOT_UAC2 < 0) {$inv_SPOT_UAC2 = "-"; } else {$inv_SPOT_UAC2 = $inv_SPOT_UAC2 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value if(($inv_SPOT_UAC3 eq -2147483648) || ($inv_SPOT_UAC3 eq 0xFFFFFFFF) || $inv_SPOT_UAC3 < 0) {$inv_SPOT_UAC3 = "-"; } else {$inv_SPOT_UAC3 = $inv_SPOT_UAC3 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value - if(($inv_SPOT_UAC1_2 eq -2147483648) || ($inv_SPOT_UAC1_2 eq 0xFFFFFFFF) || $inv_SPOT_UAC1_2 < 0) {$inv_SPOT_UAC1_2 = "-"; } else {$inv_SPOT_UAC1_2 = $inv_SPOT_UAC1_2 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value - if(($inv_SPOT_UAC2_3 eq -2147483648) || ($inv_SPOT_UAC2_3 eq 0xFFFFFFFF) || $inv_SPOT_UAC2_3 < 0) {$inv_SPOT_UAC2_3 = "-"; } else {$inv_SPOT_UAC2_3 = $inv_SPOT_UAC2_3 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value - if(($inv_SPOT_UAC3_1 eq -2147483648) || ($inv_SPOT_UAC3_1 eq 0xFFFFFFFF) || $inv_SPOT_UAC3_1 < 0) {$inv_SPOT_UAC3_1 = "-"; } else {$inv_SPOT_UAC3_1 = $inv_SPOT_UAC3_1 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value - + if($size >= 230) { + if(($inv_SPOT_UAC1_2 eq -2147483648) || ($inv_SPOT_UAC1_2 eq 0xFFFFFFFF) || $inv_SPOT_UAC1_2 < 0) {$inv_SPOT_UAC1_2 = "-"; } else {$inv_SPOT_UAC1_2 = $inv_SPOT_UAC1_2 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + if(($inv_SPOT_UAC2_3 eq -2147483648) || ($inv_SPOT_UAC2_3 eq 0xFFFFFFFF) || $inv_SPOT_UAC2_3 < 0) {$inv_SPOT_UAC2_3 = "-"; } else {$inv_SPOT_UAC2_3 = $inv_SPOT_UAC2_3 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + if(($inv_SPOT_UAC3_1 eq -2147483648) || ($inv_SPOT_UAC3_1 eq 0xFFFFFFFF) || $inv_SPOT_UAC3_1 < 0) {$inv_SPOT_UAC3_1 = "-"; } else {$inv_SPOT_UAC3_1 = $inv_SPOT_UAC3_1 / 100; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + } Log3 $name, 5, "$name - Found Data SPOT_UAC1=$inv_SPOT_UAC1 and SPOT_UAC2=$inv_SPOT_UAC2 and SPOT_UAC3=$inv_SPOT_UAC3 and inv_SPOT_UAC1_2=$inv_SPOT_UAC1_2 and inv_SPOT_UAC2_3=$inv_SPOT_UAC2_3 and inv_SPOT_UAC3_1=$inv_SPOT_UAC3_1 and inv_SPOT_CosPhi=$inv_SPOT_CosPhi"; return (1,$inv_SPOT_UAC1,$inv_SPOT_UAC2,$inv_SPOT_UAC3,$inv_SPOT_UAC1_2,$inv_SPOT_UAC2_3,$inv_SPOT_UAC3_1,$inv_SPOT_CosPhi,$inv_susyid,$inv_serial); } @@ -1495,9 +2380,38 @@ sub SMAInverter_SMAcommand($$$$$) { return (1,$inv_SPOT_IAC1,$inv_SPOT_IAC2,$inv_SPOT_IAC3,$inv_susyid,$inv_serial); } - if ($data_ID eq 0x495B && (ReadingsVal($name,"INV_TYPE","") =~ /SBS(1\.5|2\.0|2\.5)/xs || - ReadingsVal($name,"device_type","") =~ /SBS(1\.5|2\.0|2\.5)/xs)) { + if($data_ID eq 0x5746) { + $inv_SPOT_IAC1_Backup = unpack("l*", substr $data, 62, 4); + $inv_SPOT_IAC2_Backup = unpack("l*", substr $data, 90, 4); + $inv_SPOT_IAC3_Backup = unpack("l*", substr $data, 118, 4); + + if(($inv_SPOT_IAC1_Backup eq -2147483648) || ($inv_SPOT_IAC1_Backup eq 0xFFFFFFFF) || $inv_SPOT_IAC1_Backup < 0) {$inv_SPOT_IAC1_Backup = "-"; } else {$inv_SPOT_IAC1_Backup = $inv_SPOT_IAC1_Backup / 1000; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + if(($inv_SPOT_IAC2_Backup eq -2147483648) || ($inv_SPOT_IAC2_Backup eq 0xFFFFFFFF) || $inv_SPOT_IAC2_Backup < 0) {$inv_SPOT_IAC2_Backup = "-"; } else {$inv_SPOT_IAC2_Backup = $inv_SPOT_IAC2_Backup / 1000; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + if(($inv_SPOT_IAC3_Backup eq -2147483648) || ($inv_SPOT_IAC3_Backup eq 0xFFFFFFFF) || $inv_SPOT_IAC3_Backup < 0) {$inv_SPOT_IAC3_Backup = "-"; } else {$inv_SPOT_IAC3_Backup = $inv_SPOT_IAC3_Backup / 1000; } # Catch 0x80000000 and 0xFFFFFFFF as 0 value + + Log3 $name, 5, "$name - Found Data inv_SPOT_IAC1_Backup=$inv_SPOT_IAC1_Backup and inv_SPOT_IAC2_Backup=$inv_SPOT_IAC2_Backup and inv_SPOT_IAC3_Backup=$inv_SPOT_IAC3_Backup"; + return (1,$inv_SPOT_IAC1_Backup,$inv_SPOT_IAC2_Backup,$inv_SPOT_IAC3_Backup,$inv_susyid,$inv_serial); + } + + if ($data_ID eq 0x8937) { + + $inv_BAT_rated_capacity = unpack("V*", substr $data, 78, 4); + Log3 $name, 5, "$name - Found Data and inv_BAT_rated_capacity=$inv_BAT_rated_capacity"; + return (1,$inv_BAT_rated_capacity,$inv_susyid,$inv_serial); + } + + if ($data_ID eq 0x4969) { + + $inv_BAT_P_Charge = unpack("V*", substr $data, 62, 4); + $inv_BAT_P_Discharge = unpack("V*", substr $data, 90, 4); + + Log3 $name, 5, "$name - Found Data inv_BAT_P_Charge=$inv_BAT_P_Charge and inv_BAT_P_Discharge=$inv_BAT_P_Discharge"; + return (1,$inv_BAT_P_Charge,$inv_BAT_P_Discharge,$inv_susyid,$inv_serial); + } + + if ($data_ID eq 0x495B && $INVTYPE_NAME =~ /STP(5\.0|6\.0|8\.0|10\.0)SE/xs) { + $inv_BAT_TEMP = unpack("V*", substr $data, 62, 4) / 10; $inv_BAT_UDC = unpack("V*", substr $data, 90, 4) / 100; $inv_BAT_IDC = unpack("l*", substr $data, 118, 4); @@ -1509,7 +2423,23 @@ sub SMAInverter_SMAcommand($$$$$) { $inv_BAT_IDC = $inv_BAT_IDC / 1000; } - Log3 $name, 5, "$name - Found Data and BAT_TEMP=$inv_BAT_TEMP and BAT_UDC=$inv_BAT_UDC and BAT_IDC=$inv_BAT_IDC"; + Log3 $name, 5, "$name - Found Data and BAT_TEMP=$inv_BAT_TEMP and BAT_UDC=$inv_BAT_UDC and BAT_IDC=$inv_BAT_IDC (STPxxSE)"; + return (1,$inv_BAT_TEMP,$inv_BAT_UDC,$inv_BAT_IDC,$inv_susyid,$inv_serial); + } + elsif ($data_ID eq 0x495B && $INVTYPE_NAME =~ /SBS(1\.5|2\.0|2\.5)/xs) { + + $inv_BAT_TEMP = unpack("V*", substr $data, 62, 4) / 10; + $inv_BAT_UDC = unpack("V*", substr $data, 90, 4) / 100; + $inv_BAT_IDC = unpack("l*", substr $data, 118, 4); + + if($inv_BAT_IDC eq -2147483648) { # Catch 0x80000000 as 0 value + $inv_BAT_IDC = "-"; + } + else { + $inv_BAT_IDC = $inv_BAT_IDC / 1000; + } + + Log3 $name, 5, "$name - Found Data and BAT_TEMP=$inv_BAT_TEMP and BAT_UDC=$inv_BAT_UDC and BAT_IDC=$inv_BAT_IDC (SBS1.5-2.5)"; return (1,$inv_BAT_TEMP,$inv_BAT_UDC,$inv_BAT_IDC,$inv_susyid,$inv_serial); } elsif($data_ID eq 0x495B) { @@ -1611,9 +2541,17 @@ sub SMAInverter_SMAcommand($$$$$) { if($data_ID eq 0x462E) { $inv_SPOT_OPERTM = int(unpack("V*", substr $data, 62, 4) / 36) / 100; - $inv_SPOT_FEEDTM = int(unpack("V*", substr $data, 78, 4) / 36) / 100; - Log3 $name, 5, "$name - Found Data SPOT_OPERTM=$inv_SPOT_OPERTM and SPOT_FEEDTM=$inv_SPOT_FEEDTM"; - return (1,$inv_SPOT_OPERTM,$inv_SPOT_FEEDTM,$inv_susyid,$inv_serial); + if($size > 78) { + $inv_SPOT_FEEDTM = int(unpack("V*", substr $data, 78, 4) / 36) / 100; + + Log3 $name, 5, "$name - Found Data SPOT_OPERTM=$inv_SPOT_OPERTM and SPOT_FEEDTM=$inv_SPOT_FEEDTM"; + return (1,$inv_SPOT_OPERTM,$inv_SPOT_FEEDTM,$inv_susyid,$inv_serial); + } + else + { + Log3 $name, 5, "$name - Found Data SPOT_OPERTM=$inv_SPOT_OPERTM and SPOT_FEEDTM=--"; + return (1,$inv_SPOT_OPERTM,0,$inv_susyid,$inv_serial); + } } if($data_ID eq 0x4657) { @@ -1648,7 +2586,7 @@ sub SMAInverter_SMAcommand($$$$$) { } while ((unpack("V*", substr $data, 62 + $i*4, 4) ne 0x00FFFFFE) && ($i < 5)); # 0x00FFFFFE is the end marker for attributes Log3 $name, 5, "$name - Found Data INV_GRIDRELAY=$inv_GRIDRELAY"; return (1,$inv_GRIDRELAY,$inv_susyid,$inv_serial); - } + } if($data_ID eq 0x2148) { $i = 0; @@ -1661,7 +2599,80 @@ sub SMAInverter_SMAcommand($$$$$) { } while ((unpack("V*", substr $data, 62 + $i*4, 4) ne 0x00FFFFFE) && ($i < 5)); # 0x00FFFFFE is the end marker for attributes Log3 $name, 5, "$name - Found Data inv_STATUS=$inv_STATUS"; return (1,$inv_STATUS,$inv_susyid,$inv_serial); - } + } + + if($data_ID eq 0x414D) { + $i = 0; + $temp = 0; + $inv_BAT_STATUS = 0x00FFFFFD; # Code for No Information; + do { + $temp = unpack("V*", substr $data, 62 + $i*4, 4); + if(($temp & 0xFF000000) ne 0) { $inv_BAT_STATUS = $temp & 0x00FFFFFF; } + $i = $i + 1; + } while ((unpack("V*", substr $data, 62 + $i*4, 4) ne 0x00FFFFFE) && ($i < 5)); # 0x00FFFFFE is the end marker for attributes + Log3 $name, 5, "$name - Found Data inv_BAT_STATUS=$inv_BAT_STATUS"; + return (1,$inv_BAT_STATUS,$inv_susyid,$inv_serial); + } + + if($data_ID eq 0x4125) { + $i = 0; + $temp = 0; + $inv_BACKUPRELAY = 0x00FFFFFD; # Code for No Information; + do { + $temp = unpack("V*", substr $data, 62 + $i*4, 4); + if(($temp & 0xFF000000) ne 0) { $inv_BACKUPRELAY = $temp & 0x00FFFFFF; } + $i = $i + 1; + } while ((unpack("V*", substr $data, 62 + $i*4, 4) ne 0x00FFFFFE) && ($i < 5)); # 0x00FFFFFE is the end marker for attributes + Log3 $name, 5, "$name - Found Data inv_BACKUPRELAY=$inv_BACKUPRELAY"; + return (1,$inv_BACKUPRELAY,$inv_susyid,$inv_serial); + } + + if($data_ID eq 0x46A6) { + $i = 0; + $temp = 0; + $inv_GridConection = 0x00FFFFFD; # Code for No Information; + do { + $temp = unpack("V*", substr $data, 62 + $i*4, 4); + if(($temp & 0xFF000000) ne 0) { $inv_GridConection = $temp & 0x00FFFFFF; } + $i = $i + 1; + } while ((unpack("V*", substr $data, 62 + $i*4, 4) ne 0x00FFFFFE) && ($i < 5)); # 0x00FFFFFE is the end marker for attributes + Log3 $name, 5, "$name - Found Data inv_GridConection=$inv_GridConection"; + return (1,$inv_GridConection,$inv_susyid,$inv_serial); + } + + if($data_ID eq 0x412b) { + $i = 0; + $temp = 0; + $inv_OperatingStatus = 0x00FFFFFD; # Code for No Information; + do { + $temp = unpack("V*", substr $data, 62 + $i*4, 4); + if(($temp & 0xFF000000) ne 0) { $inv_OperatingStatus = $temp & 0x00FFFFFF; } + $i = $i + 1; + } while ((unpack("V*", substr $data, 62 + $i*4, 4) ne 0x00FFFFFE) && ($i < 5)); # 0x00FFFFFE is the end marker for attributes + Log3 $name, 5, "$name - Found Data inv_OperatingStatus=$inv_OperatingStatus"; + return (1,$inv_OperatingStatus,$inv_susyid,$inv_serial); + } + + if($data_ID eq 0x4128) { + $i = 0; + $temp = 0; + $inv_GeneralOperatingStatus = 0x00FFFFFD; # Code for No Information; + do { + $temp = unpack("V*", substr $data, 62 + $i*4, 4); + if(($temp & 0xFF000000) ne 0) { $inv_GeneralOperatingStatus = $temp & 0x00FFFFFF; } + $i = $i + 1; + } while ((unpack("V*", substr $data, 62 + $i*4, 4) ne 0x00FFFFFE) && ($i < 5)); # 0x00FFFFFE is the end marker for attributes + Log3 $name, 5, "$name - Found Data inv_GeneralOperatingStatus=$inv_GeneralOperatingStatus"; + return (1,$inv_GeneralOperatingStatus,$inv_susyid,$inv_serial); + } + + if($data_ID eq 0x4166) { + + $inv_WaitingTimeUntilFeedIn = unpack("l*", substr $data, 62, 4); + Log3 $name, 5, "$name - Found Data inv_WaitingTimeUntilFeedIn=$inv_WaitingTimeUntilFeedIn"; + return (1,$inv_WaitingTimeUntilFeedIn,$inv_susyid,$inv_serial); + } + return 0; } @@ -1673,7 +2684,7 @@ sub SMAInverter_SMAlogon($$$) { # Parameters: host - passcode my ($host,$pass,$hash) = @_; my $cmdheader = "534D4100000402A00000000100"; - my $pktlength = "3A"; # length = 58 for logon command + my $pktlength = "42"; # length = 66 for logon command (old 3A = 58) my $esignature = "001060650EA0"; my $name = $hash->{NAME}; my $mysusyid = $hash->{HELPER}{MYSUSYID}; @@ -1689,10 +2700,11 @@ sub SMAInverter_SMAlogon($$$) { my $target_serial = AttrVal($name, "target-serial", $default_target_serial); #Encode the password - my $encpasswd = "888888888888888888888888"; # template for password + $pass = SMAInverter_SMAdecrypt( $pass ); + my $encpasswd = "8888888888888888888888888888888888888888"; # template for password for my $index (0..length $pass ) # encode password { - if ( (hex(substr($encpasswd,($index*2),2)) + ord(substr($pass,$index,1))) < 256 ) { + if ( (hex(substr($encpasswd,($index*2),2)) + ord(substr($pass,$index,1))) < 256 ) { substr($encpasswd,($index*2),2) = substr(sprintf ("%lX", (hex(substr($encpasswd,($index*2),2)) + ord(substr($pass,$index,1)))),0,2); } else { substr($encpasswd,($index*2),2) = substr(sprintf ("%lX", (hex(substr($encpasswd,($index*2),2)) + ord(substr($pass,$index,1)))),1,2); @@ -1903,12 +2915,12 @@ sub SMAInverter_setVersionInfo($) { if($modules{$type}{META}{x_prereqs_src} && !$hash->{HELPER}{MODMETAABSENT}) { # META-Daten sind vorhanden $modules{$type}{META}{version} = "v".$v; # Version aus META.json überschreiben, Anzeige mit {Dumper $modules{SMAPortal}{META}} - if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 76_SMAInverter.pm 23909 2021-03-07 20:06:59Z DS_Starter $ im Kopf komplett! vorhanden ) - $modules{$type}{META}{x_version} =~ s/1.1.1/$v/g; + if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 76_SMAInverter.pm 29075 2024-08-17 10:10:54Z MadMax $ im Kopf komplett! vorhanden ) + $modules{$type}{META}{x_version} =~ s/1\.1\.1/$v/xsg; } else { $modules{$type}{META}{x_version} = $v; } - return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 76_SMAInverter.pm 23909 2021-03-07 20:06:59Z DS_Starter $ im Kopf komplett! vorhanden ) + return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 76_SMAInverter.pm 29075 2024-08-17 10:10:54Z MadMax $ im Kopf komplett! vorhanden ) if(__PACKAGE__ eq "FHEM::$type" || __PACKAGE__ eq $type) { # es wird mit Packages gearbeitet -> Perl übliche Modulversion setzen # mit {->VERSION()} im FHEMWEB kann Modulversion abgefragt werden @@ -1955,7 +2967,18 @@ sub SMAInverter_StatusText($) { if($code eq 51) { return (AttrVal("global", "language", "EN") eq "DE") ? "geschlossen" : "Closed"; } if($code eq 311) { return (AttrVal("global", "language", "EN") eq "DE") ? "offen" : "Open"; } if($code eq 16777213) { return (AttrVal("global", "language", "EN") eq "DE") ? "Information liegt nicht vor" : "No Information"; } - + + if($code eq 235) { return (AttrVal("global", "language", "EN") eq "DE") ? "Netzparallelbetrieb" : "parallel grid operation"; } + if($code eq 1463) { return (AttrVal("global", "language", "EN") eq "DE") ? "Ersatzstrombetrieb" : "backup"; } + if($code eq 2119) { return (AttrVal("global", "language", "EN") eq "DE") ? "Abregelung" : "derating"; } + if($code eq 569) { return (AttrVal("global", "language", "EN") eq "DE") ? "Eingeschaltet" : "activated"; } + if($code eq 1295) { return (AttrVal("global", "language", "EN") eq "DE") ? "Standby" : "standby"; } + if($code eq 295) { return (AttrVal("global", "language", "EN") eq "DE") ? "MPP" : "MPP"; } + if($code eq 1795) { return (AttrVal("global", "language", "EN") eq "DE") ? "Verriegelt" : "locked"; } + if($code eq 1779) { return (AttrVal("global", "language", "EN") eq "DE") ? "Getrennt" : "disconnected"; } + + if($code eq 1780) { return (AttrVal("global", "language", "EN") eq "DE") ? "Öffentliches Stromnetz" : "public grid"; } + if($code eq 35) { return (AttrVal("global", "language", "EN") eq "DE") ? "Fehler" : "Fault"; } if($code eq 303) { return "Off"; } if($code eq 307) { return "Ok"; } @@ -2089,13 +3112,20 @@ The retrieval of the inverter will be executed non-blocking. You can adjust the 0 - only Power and Energy 1 - as 0, additional voltage and current - 2 - all values + 2 - as 1, additional voltage and current
- + + +
  • readEnergyMeter-data [1|0]
    + Deactivates/activates the reading of the energy meter/smart meter data via the inverter.
    + The Readings Meter_xxx are then created and filled with data. +
  • +
    +
  • disable [1|0]
    Deactivate/activate the module. @@ -2180,10 +3210,16 @@ The retrieval of the inverter will be executed non-blocking. You can adjust the
  • BAT_IDC [A,B,C] / bat_idc [A,B,C] : Battery Current [A,B,C]
  • BAT_TEMP [A,B,C] / bat_temp [A,B,C] : Battery temperature [A,B,C]
  • BAT_UDC [A,B,C] / bat_udc [A,B,C] : Battery Voltage [A,B,C]
  • +
  • BAT_PDC / bat_pdc : Battery power (only Hybrid-Inverter), calculated from I and U
  • +
  • BAT_P_CHARGE / bat_p_charge : Battery chargepower (only Hybrid-Inverter)
  • +
  • BAT_P_DISCHARGE / bat_p_discharge : Battery dischargepower (only Hybrid-Inverter)
  • ChargeStatus / chargestatus : Battery Charge status
  • +
  • BAT_CAPACITY / bat_capacity : Battery (remaining) Capacity (SOH)
  • +
  • BAT_RATED_CAPACITY / bat_rated_capacity : Battery reted Capacity Wh/kWh
  • BAT_LOADTODAY : Battery Load Today
  • BAT_LOADTOTAL : Battery Load Total
  • -
  • ChargeStatus / chargestatus : Battery Charge status
  • +
  • BAT_UNLOADTODAY : Battery Unload Today
  • +
  • BAT_UNLOADTOTAL : Battery Unload Total
  • CLASS / device_class : Inverter Class
  • PACMAX1 / pac_max_phase_1 : Nominal power in Ok Mode
  • PACMAX1_2 / pac_max_phase_1_2 : Maximum active power device (Some inverters like SB3300/SB1200)
  • @@ -2192,6 +3228,8 @@ The retrieval of the inverter will be executed non-blocking. You can adjust the
  • Serialnumber / serial_number : Inverter Serialnumber
  • SPOT_ETODAY / etoday : Today yield
  • SPOT_ETOTAL / etotal : Total yield
  • +
  • SPOT_EPVTODAY / epvtoday : Today PV yield
  • +
  • SPOT_EPVTOTAL / epvtotal : Total PV yield
  • SPOT_FEEDTM / feed-in_time : Feed-in time
  • SPOT_FREQ / grid_freq : Grid Frequency
  • SPOT_CosPhi / coshhi : displacement factor
  • @@ -2200,6 +3238,7 @@ The retrieval of the inverter will be executed non-blocking. You can adjust the
  • SPOT_IAC3 / phase_3_iac : Grid current phase L3
  • SPOT_IDC1 / string_1_idc : DC current input
  • SPOT_IDC2 / string_2_idc : DC current input
  • +
  • SPOT_IDC3 / string_3_idc : DC current input
  • SPOT_OPERTM / operation_time : Operation Time
  • SPOT_PAC1 / phase_1_pac : Power L1
  • SPOT_PAC2 / phase_2_pac : Power L2
  • @@ -2207,6 +3246,8 @@ The retrieval of the inverter will be executed non-blocking. You can adjust the
  • SPOT_PACTOT / total_pac : Total Power
  • SPOT_PDC1 / string_1_pdc : DC power input 1
  • SPOT_PDC2 / string_2_pdc : DC power input 2
  • +
  • SPOT_PDC3 / string_3_pdc : DC power input 3
  • +
  • SPOT_PDC / strings_pds : DC power summary (only Hybrid-Inverter)
  • SPOT_UAC1 / phase_1_uac : Grid voltage phase L1
  • SPOT_UAC2 / phase_2_uac : Grid voltage phase L2
  • SPOT_UAC3 / phase_3_uac : Grid voltage phase L3
  • @@ -2215,13 +3256,26 @@ The retrieval of the inverter will be executed non-blocking. You can adjust the
  • SPOT_UAC3_1 / phase_3_1_uac : Grid voltage phase L3-L1
  • SPOT_UDC1 / string_1_udc : DC voltage input
  • SPOT_UDC2 / string_2_udc : DC voltage input
  • +
  • SPOT_UDC3 / string_3_udc : DC voltage input
  • SUSyID / susyid : Inverter SUSyID
  • INV_TEMP / device_temperature : Inverter temperature
  • INV_TYPE / device_type : Inverter Type
  • POWER_IN / power_in : Battery Charging power
  • POWER_OUT / power_out : Battery Discharging power
  • -
  • INV_GRIDRELAY / gridrelay_status : Grid Relay/Contactor Status
  • +
  • INV_GRIDRELAY / gridrelay_status : Grid Relay/Contactor Status
  • +
  • INV_BACKUPRELAY / backuprelay_status : Backup Relay/Contactor Status (only Hybrid-Inverter)
  • +
  • INV_GridConection / grid_conection : state of Gridconection (public grid/disconnected) (only SI-Inverter)
  • +
  • INV_GeneralOperatingStatus / general_operating_status
  • +
  • : General Status from the Inverter (MPP/Activated/Derating)
  • +
  • INV_OperatingStatus / operating_status : operating status from the Inverter (Parallel grid operation/Backup) (only Hybrid-Inverter)
  • INV_STATUS / device_status : Inverter Status
  • +
  • INV_FIRMWARE / device_firmware : Inverter firmware version
  • +
  • SPOT_BACKUP_IAC1 / phase_backup_1_iac : Backup current phase L1
  • +
  • SPOT_BACKUP_IAC2 / phase_backup_2_iac : Backup current phase L2
  • +
  • SPOT_BACKUP_IAC3 / phase_backup_3_iac : Backup current phase L3
  • +
  • SPOT_BACKUP_PAC1 / phase_backup_1_pac : Backup power phase L1
  • +
  • SPOT_BACKUP_PAC2 / phase_backup_2_pac : Backup power phase L2
  • +
  • SPOT_BACKUP_PAC3 / phase_backup_3_pac : Backup power phase L3
  • opertime_start : Begin of iverter operating time corresponding the calculated time of sunrise with consideration of the attribute "offset" (if set)
  • opertime_stop : End of iverter operating time corresponding the calculated time of sunrise with consideration of the @@ -2232,6 +3286,15 @@ The retrieval of the inverter will be executed non-blocking. You can adjust the
  • avg_power_lastminutes_15 : average power of the last 15 minutes.
  • inverter_processing_time : wasted time to retrieve the inverter data
  • background_processing_time : total wasted time by background process (BlockingCall)
  • + +
  • Meter_Grid_FeedIn_PACx / Meter_Grid_FeedIn_phase_x_pac : Power Grid_FeedIn phase Lx
  • +
  • Meter_Grid_Consumation_PACx / Meter_Grid_Consumation_phase_x_pac : Power Grid_Consumation phase Lx
  • +
  • Meter_Power_Grid_FeedIn / Meter_Power_Grid_FeedIn : total Power Grid_FeedIn
  • +
  • Meter_Power_Grid_Consumation / Meter_Power_Grid_Consumation : total Power Grid_Consumation
  • +
  • Meter_TOTAL_FeedIn / Meter_TOTAL_FeedIn : total Energie Grid_FeedIn
  • +
  • Meter_TOTAL_Consumation / Meter_TOTAL_Consumation : total Energie Grid_Consumation
  • +
  • Meter_TOTAL_Grid_FeedIn / Meter_TOTAL_Grid_FeedIn : total Energie Grid_FeedIn
  • +
  • Meter_TOTAL_Grid_Consumation / Meter_TOTAL_Grid_Consumation : total Energie Grid_Consumation


  • @@ -2331,6 +3394,13 @@ Die Abfrage des Wechselrichters wird non-blocking ausgeführt. Der Timeoutwert f
    + + +
  • readEnergyMeter-data [1|0]
    + Deaktiviert/aktiviert das lesen der Energymeter/Smartmeter Daten über den Wechselrichter.
    + Die Readings Meter_xxx werden dann angelegt und mit Daten befüllt. +
  • +
  • disable [1|0]
    @@ -2418,9 +3488,16 @@ Die Abfrage des Wechselrichters wird non-blocking ausgeführt. Der Timeoutwert f
  • BAT_IDC [A,B,C] / bat_idc [A,B,C] : Akku Strom [A,B,C]
  • BAT_TEMP [A,B,C] / bat_temp [A,B,C] : Akku Temperatur [A,B,C]
  • BAT_UDC [A,B,C] / bat_udc [A,B,C] : Akku Spannung [A,B,C]
  • +
  • BAT_PDC / bat_pdc : Akku Leistung (bei Hybridwechselrichtern), berechneter Wert aus Strom und Spannung
  • +
  • BAT_P_CHARGE / bat_p_charge : Akku Ladeleistung (bei Hybridwechselrichtern)
  • +
  • BAT_P_DISCHARGE / bat_p_discharge : Akku Entladeleistung (bei Hybridwechselrichtern)
  • ChargeStatus / chargestatus : Akku Ladestand
  • +
  • BAT_CAPACITY / bat_capacity : Battery (verbleibende) Kapazität (SOH)
  • +
  • BAT_RATED_CAPACITY / bat_rated_capacity : Battery Nennkapazität Wh/kWh
  • BAT_LOADTODAY : Battery Load Today
  • BAT_LOADTOTAL : Battery Load Total
  • +
  • BAT_UNLOADTODAY : Battery Unload Today
  • +
  • BAT_UNLOADTOTAL : Battery Unload Total
  • CLASS / device_class : Wechselrichter Klasse
  • PACMAX1 / pac_max_phase_1 : Nominelle Leistung in Ok Mode
  • PACMAX1_2 / pac_max_phase_1_2 : Maximale Leistung (für einige Wechselrichtertypen)
  • @@ -2428,6 +3505,8 @@ Die Abfrage des Wechselrichters wird non-blocking ausgeführt. Der Timeoutwert f
  • PACMAX3 / pac_max_phase_3 : Nominelle Leistung in Fault Mode
  • Serialnumber / serial_number : Wechselrichter Seriennummer
  • SPOT_ETODAY / etoday : Energie heute
  • +
  • SPOT_EPVTOTAL / epvtotal : PV Energie Insgesamt
  • +
  • SPOT_EPVTODAY / epvtoday : PV Energie heute
  • SPOT_ETOTAL / etotal : Energie Insgesamt
  • SPOT_FEEDTM / feed-in_time : Einspeise-Stunden
  • SPOT_FREQ / grid_freq : Netz Frequenz
  • @@ -2437,6 +3516,7 @@ Die Abfrage des Wechselrichters wird non-blocking ausgeführt. Der Timeoutwert f
  • SPOT_IAC3 / phase_3_iac : Netz Strom phase L3
  • SPOT_IDC1 / string_1_idc : DC Strom Eingang 1
  • SPOT_IDC2 / string_2_idc : DC Strom Eingang 2
  • +
  • SPOT_IDC3 / string_3_idc : DC Strom Eingang 3
  • SPOT_OPERTM / operation_time : Betriebsstunden
  • SPOT_PAC1 / phase_1_pac : Leistung L1
  • SPOT_PAC2 / phase_2_pac : Leistung L2
  • @@ -2444,6 +3524,8 @@ Die Abfrage des Wechselrichters wird non-blocking ausgeführt. Der Timeoutwert f
  • SPOT_PACTOT / total_pac : Gesamtleistung
  • SPOT_PDC1 / string_1_pdc : DC Leistung Eingang 1
  • SPOT_PDC2 / string_2_pdc : DC Leistung Eingang 2
  • +
  • SPOT_PDC3 / string_3_pdc : DC Leistung Eingang 3
  • +
  • SPOT_PDC / strings_pds : DC Leistung gesamt (bei Hybridwechselrichtern)
  • SPOT_UAC1 / phase_1_uac : Netz Spannung phase L1
  • SPOT_UAC2 / phase_2_uac : Netz Spannung phase L2
  • SPOT_UAC3 / phase_3_uac : Netz Spannung phase L3
  • @@ -2452,13 +3534,26 @@ Die Abfrage des Wechselrichters wird non-blocking ausgeführt. Der Timeoutwert f
  • SPOT_UAC3_1 / phase_3_1_uac : Netz Spannung phase L3-L1
  • SPOT_UDC1 / string_1_udc : DC Spannung Eingang 1
  • SPOT_UDC2 / string_2_udc : DC Spannung Eingang 2
  • +
  • SPOT_UDC3 / string_3_udc : DC Spannung Eingang 3
  • SUSyID / susyid : Wechselrichter SUSyID
  • INV_TEMP / device_temperature : Wechselrichter Temperatur
  • INV_TYPE / device_type : Wechselrichter Typ
  • POWER_IN / power_in : Akku Ladeleistung
  • POWER_OUT / power_out : Akku Entladeleistung
  • INV_GRIDRELAY / gridrelay_status : Netz Relais Status
  • +
  • INV_BACKUPRELAY / backuprelay_status : Backup Relais Status (bei Hybridwechselrichtern)
  • +
  • INV_GridConection / grid_conection : Status des Netzanschlusses (Öffentliches Stromnetz/Getrennt) (nur SI-Inverter)
  • +
  • INV_GeneralOperatingStatus / general_operating_status
  • +
  • : Allgemeiner Betriebszustand des Wechselrichters (MPP/Eingeschaltet/Abregelung)
  • +
  • INV_OperatingStatus / operating_status : Betriebsstatus des Wechselrichters (Netzparallelbetrieb/Backup) (bei Hybridwechselrichtern)
  • INV_STATUS / device_status : Wechselrichter Status
  • +
  • INV_FIRMWARE / device_firmware : Wechselrichter Firmwareversion
  • +
  • SPOT_BACKUP_IAC1 / phase_backup_1_iac : Backup Strom phase L1
  • +
  • SPOT_BACKUP_IAC2 / phase_backup_2_iac : Backup Strom phase L2
  • +
  • SPOT_BACKUP_IAC3 / phase_backup_3_iac : Backup Strom phase L3
  • +
  • SPOT_BACKUP_PAC1 / phase_backup_1_pac : Backup Leistung phase L1
  • +
  • SPOT_BACKUP_PAC2 / phase_backup_2_pac : Backup Leistung phase L2
  • +
  • SPOT_BACKUP_PAC3 / phase_backup_3_pac : Backup Leistung phase L3
  • opertime_start : Beginn Aktivzeit des Wechselrichters entsprechend des ermittelten Sonnenaufgangs mit Berücksichtigung des Attributs "offset" (wenn gesetzt)
  • opertime_stop : Ende Aktivzeit des Wechselrichters entsprechend des ermittelten Sonnenuntergangs mit Berücksichtigung des @@ -2470,6 +3565,14 @@ Die Abfrage des Wechselrichters wird non-blocking ausgeführt. Der Timeoutwert f
  • inverter_processing_time : verbrauchte Zeit um den Wechelrichter abzufragen.
  • background_processing_time : gesamte durch den Hintergrundprozess (BlockingCall) verbrauchte Zeit.
  • +
  • Meter_Grid_FeedIn_PACx / Meter_Grid_FeedIn_phase_x_pac : Leistung Netzeinspeisung phase Lx
  • +
  • Meter_Grid_Consumation_PACx / Meter_Grid_Consumation_phase_x_pac : Leistung Netzbezug phase Lx
  • +
  • Meter_Power_Grid_FeedIn / Meter_Power_Grid_FeedIn : Summe Leistung Netzeinspeisung
  • +
  • Meter_Power_Grid_Consumation / Meter_Power_Grid_Consumation : Summe Leistung Netzbezug
  • +
  • Meter_TOTAL_FeedIn / Meter_TOTAL_FeedIn : Summe Energie Netzeinspeisung
  • +
  • Meter_TOTAL_Consumation / Meter_TOTAL_Consumation : Summe Energie Netzbezug
  • +
  • Meter_TOTAL_Grid_FeedIn / Meter_TOTAL_Grid_FeedIn : Summe Energie Netzeinspeisung
  • +
  • Meter_TOTAL_Grid_Consumation / Meter_TOTAL_Grid_Consumation : Summe Energie Netzbezug


  • @@ -2489,7 +3592,7 @@ Die Abfrage des Wechselrichters wird non-blocking ausgeführt. Der Timeoutwert f "PV", "inverter" ], - "version": "v2.16.1", + "version": "v2.25.3", "release_status": "stable", "author": [ "Maximilian Paries",