mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 09:16:53 +00:00
76_SMAInverter: V2.13.0, attr target-serial/target-susyid are set automatically if not defined, new inverter types added, support of Meta/Installer, ETOTAL is calculated if inverter doesn't provide it
git-svn-id: https://svn.fhem.de/fhem/trunk@20036 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
615dd33b2f
commit
1ef7e158dc
@ -1,5 +1,9 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||||
# Do not insert empty lines here, update check depends on it.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
|
- feature: 76_SMAInverter: V2.13.0, attr target-serial/target-susyid are set
|
||||||
|
automatically if not defined, new inverter types
|
||||||
|
added, support of Meta/Installer, ETOTAL is
|
||||||
|
calculated if inverter doesn't provide it
|
||||||
- feature: 14_SD_UT: added new model OR28V & fixed RC_10
|
- feature: 14_SD_UT: added new model OR28V & fixed RC_10
|
||||||
- feature: 70_ZoneMinder: added cause and notes to alerts. Credits to Obi
|
- feature: 70_ZoneMinder: added cause and notes to alerts. Credits to Obi
|
||||||
- bugfix: 73_NUKIBridge: fix "Can't use stringas a HASH ref while strict
|
- bugfix: 73_NUKIBridge: fix "Can't use stringas a HASH ref while strict
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
# $Id$
|
# $Id$
|
||||||
#################################################################################################################
|
#################################################################################################################
|
||||||
#
|
#
|
||||||
#
|
|
||||||
# Copyright notice
|
# Copyright notice
|
||||||
#
|
#
|
||||||
# Published according Creative Commons : Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)
|
# Published according Creative Commons : Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)
|
||||||
@ -17,61 +16,10 @@
|
|||||||
#
|
#
|
||||||
# Description:
|
# Description:
|
||||||
# This is an FHEM-Module for SMA Inverters.
|
# This is an FHEM-Module for SMA Inverters.
|
||||||
# Tested on Sunny Tripower 6000TL-20 and Sunny Island 4.4
|
|
||||||
#
|
#
|
||||||
# Requirements:
|
|
||||||
# This module requires:
|
|
||||||
# - Perl Module: IO::Socket::INET
|
|
||||||
# - Perl Module: DateTime
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#################################################################################################################
|
#################################################################################################################
|
||||||
# Versions History by DS_Starter
|
|
||||||
#
|
|
||||||
# 2.10.1 28.04.2019 fix perl warnings, Forum:#56080.msg933276.html#msg933276
|
|
||||||
# 2.10.0 29.06.2018 Internal MODEL added
|
|
||||||
# 2.9.2 08.10.2017 adapted to use extended abortArg (Forum:77472)
|
|
||||||
# 2.9.1 24.04.2017 fix for issue #24 (Wrong INV_TYPE for STP10000TL-20) and fix for issue #25 (unpack out of range for SB1.5-1VL-40)
|
|
||||||
# 2.9.0 23.04.2017 fixed issue #22: wrong logon command for SunnyBoy systems
|
|
||||||
# 2.8.3 19.04.2017 enhanced inverter Type-Hash
|
|
||||||
# 2.8.2 23.03.2017 changed SMA_logon sub
|
|
||||||
# 2.8.1 06.12.2016 SMAInverter version as internal
|
|
||||||
# 2.8 05.12.2016 changed commandsections to make sure getting only data from inverters with preset
|
|
||||||
# $inv_susyid and $inv_serial
|
|
||||||
# 2.7.4 04.12.2016 change loading of IO::Socket::INET, DateTime
|
|
||||||
# 2.7.3 04.12.2016 commandref adapted
|
|
||||||
# 2.7.2 03.12.2016 use Time::HiRes qw(gettimeofday tv_interval)
|
|
||||||
# 2.7.1 02.12.2016 showproctime improved
|
|
||||||
# 2.7 02.12.2016 showproctime added
|
|
||||||
# 2.6.1 29.11.2016 getstatus_DoParse changed due to inititialized issues
|
|
||||||
# 2.6 28.11.2016 bugfix warnings ParseDone redefine at startup, uninitialized value $avg if FHEM was
|
|
||||||
# restarted in sleeptime, switched avg_energy to avg_power, commandref updated
|
|
||||||
# 2.5.2 27.11.2016 bugfix average calc, bugfix warnings at startup
|
|
||||||
# 2.5.1 26.11.2016 calc of averagebuf changed to 5, 10, 15 minutes
|
|
||||||
# 2.5 26.11.2016 averagebuf changed, Attr timeout added
|
|
||||||
# 2.4 26.11.2016 create ringbuffer for calculating average energy last 5, 10, 15 cycles
|
|
||||||
# 2.3 25.11.2016 bugfixing
|
|
||||||
# 2.2 24.11.2016 further optimize of non-blocking operation
|
|
||||||
# 2.1 24.11.2016 avg_energy_lastcycles added
|
|
||||||
# 2.0 24.11.2016 switched module to non-blocking operation
|
|
||||||
# 1.8.4 23.11.2016 prepare non-blocking operation
|
|
||||||
# 1.8.3 23.11.2016 readings opertime_start, opertime_stop
|
|
||||||
# 1.8.2 22.11.2016 eliminate global vars, prepare non-blocking operation
|
|
||||||
# 1.8.1 22.11.2016 eliminate global vars, create command array
|
|
||||||
# 1.8 21.11.2016 eliminate $r_OK, $r_FAIL, create command-array
|
|
||||||
# 1.7 21.11.2016 devtypes completed, minor bugfixes, commandref completed
|
|
||||||
# 1.6.1 19.11.2016 bugfix perl warning during fhem start
|
|
||||||
# 1.6 09.11.2016 added operation control by sunrise,sunset, Attr offset, suppressSleep added
|
|
||||||
# 1.5 08.11.2016 added device classes hash
|
|
||||||
# 1.4 07.11.2016 compatibility to SBFSpot improved, bilingual dependend on attr "language" of global-device,
|
|
||||||
# added hash of SMA device types
|
|
||||||
# 1.3 07.11.2016 Attr SBFSpotComp added to get compatibility mode with SBFSpot
|
|
||||||
# 1.2 06.11.2016 function get data added, log output level changed to 4 in sub SMAInverter_Attr,
|
|
||||||
# some code changes
|
|
||||||
# 1.1 06.11.2016 Attr mode manual, automatic added
|
|
||||||
# 1.0 06.11.2016 Attr disable added,
|
|
||||||
# $globalName replaced by $name in all expressions (due to module redesign to non-blocking later)
|
|
||||||
|
|
||||||
|
|
||||||
package main;
|
package main;
|
||||||
|
|
||||||
@ -82,8 +30,57 @@ eval "use DateTime;1" or my $MissModulDateTime = "DateTime";
|
|||||||
use Time::HiRes qw(gettimeofday tv_interval);
|
use Time::HiRes qw(gettimeofday tv_interval);
|
||||||
use Blocking;
|
use Blocking;
|
||||||
use Time::Local;
|
use Time::Local;
|
||||||
|
eval "use FHEM::Meta;1" or my $modMetaAbsent = 1;
|
||||||
|
|
||||||
my $SMAInverterVersion = "2.10.0";
|
# Versions History by DS_Starter
|
||||||
|
our %SMAInverter_vNotesIntern = (
|
||||||
|
"2.13.0" => "20.08.2019 support of Meta.pm ",
|
||||||
|
"2.12.0" => "20.08.2019 set warning to log if SPOT_ETODAY, SPOT_ETOTAL was not delivered or successfully ".
|
||||||
|
"calculated in SMAInverter_SMAcommand, Forum: https://forum.fhem.de/index.php/topic,56080.msg967823.html#msg967823 ",
|
||||||
|
"2.11.0" => "17.08.2019 attr target-serial, target-susyid are set automatically if not defined, commandref revised ",
|
||||||
|
"2.10.2" => "14.08.2019 new types to %SMAInverter_devtypes ",
|
||||||
|
"2.10.1" => "28.04.2019 fix perl warnings, Forum:#56080.msg933276.html#msg933276 ",
|
||||||
|
"2.10.0" => "29.06.2018 Internal MODEL added ",
|
||||||
|
"2.9.2" => "08.10.2017 adapted to use extended abortArg (Forum:77472) ",
|
||||||
|
"2.9.1" => "24.04.2017 fix for issue #24 (Wrong INV_TYPE for STP10000TL-20) and fix for issue #25 (unpack out of range for SB1.5-1VL-40) ",
|
||||||
|
"2.9.0" => "23.04.2017 fixed issue #22: wrong logon command for SunnyBoy systems ",
|
||||||
|
"2.8.3" => "19.04.2017 enhanced inverter Type-Hash ",
|
||||||
|
"2.8.2" => "23.03.2017 changed SMAInverter_SMAlogon sub ",
|
||||||
|
"2.8.1" => "06.12.2016 SMAInverter version as internal ",
|
||||||
|
"2.8.0" => "05.12.2016 changed commandsections to make sure getting only data from inverters with preset ".
|
||||||
|
"\$inv_susyid and \$inv_serial ",
|
||||||
|
"2.7.4" => "04.12.2016 change loading of IO::Socket::INET, DateTime ",
|
||||||
|
"2.7.3" => "04.12.2016 commandref adapted ",
|
||||||
|
"2.7.2" => "03.12.2016 use Time::HiRes qw(gettimeofday tv_interval ",
|
||||||
|
"2.7.1" => "02.12.2016 showproctime improved ",
|
||||||
|
"2.7.0" => "02.12.2016 showproctime added ",
|
||||||
|
"2.6.1" => "29.11.2016 SMAInverter_getstatusDoParse changed due to inititialized issues ",
|
||||||
|
"2.6.0" => "28.11.2016 bugfix warnings ParseDone redefine at startup, uninitialized value \$avg if FHEM was ".
|
||||||
|
"restarted in sleeptime, switched avg_energy to avg_power, commandref updated ",
|
||||||
|
"2.5.2" => "27.11.2016 bugfix average calc, bugfix warnings at startup ",
|
||||||
|
"2.5.1" => "26.11.2016 calc of averagebuf changed to 5, 10, 15 minutes ",
|
||||||
|
"2.5.0" => "26.11.2016 averagebuf changed, Attr timeout added ",
|
||||||
|
"2.4.0" => "26.11.2016 create ringbuffer for calculating average energy last 5, 10, 15 cycles ",
|
||||||
|
"2.3.0" => "25.11.2016 bugfixing ",
|
||||||
|
"2.2.0" => "24.11.2016 further optimize of non-blocking operation ",
|
||||||
|
"2.1.0" => "24.11.2016 avg_energy_lastcycles added ",
|
||||||
|
"2.0.0" => "24.11.2016 switched module to non-blocking operation ",
|
||||||
|
"1.8.4" => "23.11.2016 prepare non-blocking operation ",
|
||||||
|
"1.8.3" => "23.11.2016 readings opertime_start, opertime_stop ",
|
||||||
|
"1.8.2" => "22.11.2016 eliminate global vars, prepare non-blocking operation ",
|
||||||
|
"1.8.1" => "22.11.2016 eliminate global vars, create command array ",
|
||||||
|
"1.8.0" => "21.11.2016 eliminate \$r_OK, \$r_FAIL, create command-array ",
|
||||||
|
"1.7.0" => "21.11.2016 devtypes completed, minor bugfixes, commandref completed ",
|
||||||
|
"1.6.1" => "19.11.2016 bugfix perl warning during fhem start ",
|
||||||
|
"1.6.0" => "09.11.2016 added operation control by sunrise,sunset, Attr offset, suppressSleep added ",
|
||||||
|
"1.5.0" => "08.11.2016 added device classes hash ",
|
||||||
|
"1.4.0" => "07.11.2016 compatibility to SBFSpot improved, bilingual dependend on attr \"language\" of global-device ".
|
||||||
|
"added hash of SMA device types ",
|
||||||
|
"1.3.0" => "07.11.2016 Attr SBFSpotComp added to get compatibility mode with SBFSpot ",
|
||||||
|
"1.2.0" => "06.11.2016 function get data added, log output level changed to 4 in sub SMAInverter_Attr, some code changes ",
|
||||||
|
"1.1.0" => "06.11.2016 Attr mode manual, automatic added ",
|
||||||
|
"1.0.0" => "06.11.2016 Attr disable added, \$globalName replaced by \$name in all expressions (due to module redesign to non-blocking later) "
|
||||||
|
);
|
||||||
|
|
||||||
# Inverter Data fields and supported commands flags.
|
# Inverter Data fields and supported commands flags.
|
||||||
# $inv_SPOT_ETODAY # Today yield
|
# $inv_SPOT_ETODAY # Today yield
|
||||||
@ -229,6 +226,34 @@ my %SMAInverter_devtypes = (
|
|||||||
9305 => "SB6.0-1SP-US-40",
|
9305 => "SB6.0-1SP-US-40",
|
||||||
9306 => "SB8.0-1SP-US-40",
|
9306 => "SB8.0-1SP-US-40",
|
||||||
9307 => "Energy Meter",
|
9307 => "Energy Meter",
|
||||||
|
9313 => "SB50.0-3SP-40",
|
||||||
|
9319 => "SB3.0-1AV-40 (Sunny Boy 3.0 AV-40)",
|
||||||
|
9320 => "SB3.6-1AV-40 (Sunny Boy 3.6 AV-40)",
|
||||||
|
9321 => "SB4.0-1AV-40 (Sunny Boy 4.0 AV-40)",
|
||||||
|
9322 => "SB5.0-1AV-40 (Sunny Boy 5.0 AV-40)",
|
||||||
|
9324 => "SBS1.5-1VL-10 (Sunny Boy Storage 1.5)",
|
||||||
|
9325 => "SBS2.0-1VL-10 (Sunny Boy Storage 2.0)",
|
||||||
|
9326 => "SBS2.5-1VL-10 (Sunny Boy Storage 2.5)",
|
||||||
|
9327 => "SMA Energy Meter",
|
||||||
|
9331 => "SI 3.0M-12 (Sunny Island 3.0M)",
|
||||||
|
9332 => "SI 4.4M-12 (Sunny Island 4.4M)",
|
||||||
|
9333 => "SI 6.0H-12 (Sunny Island 6.0H)",
|
||||||
|
9334 => "SI 8.0H-12 (Sunny Island 8.0H)",
|
||||||
|
9335 => "SMA Com Gateway",
|
||||||
|
9336 => "STP 15000TL-30",
|
||||||
|
9337 => "STP 17000TL-30",
|
||||||
|
9344 => "STP4.0-3AV-40 (Sunny Tripower 4.0)",
|
||||||
|
9345 => "STP5.0-3AV-40 (Sunny Tripower 5.0)",
|
||||||
|
9346 => "STP6.0-3AV-40 (Sunny Tripower 6.0)",
|
||||||
|
9347 => "STP8.0-3AV-40 (Sunny Tripower 8.0)",
|
||||||
|
9356 => "SBS3.7-1VL-10 (Sunny Boy Storage 3.7)",
|
||||||
|
9358 => "SBS5.0-10 (Sunny Boy Storage 5.0)",
|
||||||
|
9366 => "STP3.0-3AV-40 (Sunny Tripower 3.0)",
|
||||||
|
9401 => "SB3.0-1AV-41 (Sunny Boy 3.0 AV-41)",
|
||||||
|
9402 => "SB3.6-1AV-41 (Sunny Boy 3.6 AV-41)",
|
||||||
|
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)",
|
||||||
);
|
);
|
||||||
|
|
||||||
# Wechselrichter Class-Hash DE
|
# Wechselrichter Class-Hash DE
|
||||||
@ -278,6 +303,9 @@ sub SMAInverter_Initialize($) {
|
|||||||
$readingFnAttributes;
|
$readingFnAttributes;
|
||||||
$hash->{AttrFn} = "SMAInverter_Attr";
|
$hash->{AttrFn} = "SMAInverter_Attr";
|
||||||
|
|
||||||
|
eval { FHEM::Meta::InitMod( __FILE__, $hash ) }; # für Meta.pm (https://forum.fhem.de/index.php/topic,97589.0.html)
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
@ -297,7 +325,6 @@ sub SMAInverter_Define($$) {
|
|||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
$hash->{LASTUPDATE} = 0;
|
$hash->{LASTUPDATE} = 0;
|
||||||
$hash->{INTERVAL} = $hash->{HELPER}{INTERVAL} = AttrVal($name, "interval", 60);
|
$hash->{INTERVAL} = $hash->{HELPER}{INTERVAL} = AttrVal($name, "interval", 60);
|
||||||
$hash->{VERSION} = $SMAInverterVersion;
|
|
||||||
$hash->{HELPER}{FAULTEDCYCLES} = 0;
|
$hash->{HELPER}{FAULTEDCYCLES} = 0;
|
||||||
delete($hash->{HELPER}{AVERAGEBUF}) if($hash->{HELPER}{AVERAGEBUF});
|
delete($hash->{HELPER}{AVERAGEBUF}) if($hash->{HELPER}{AVERAGEBUF});
|
||||||
|
|
||||||
@ -308,6 +335,10 @@ sub SMAInverter_Define($$) {
|
|||||||
$hash->{HELPER}{DEFAULT_TARGET_SERIAL} = 0xFFFFFFFF; # 0xFFFFFFFF is any serialnumber
|
$hash->{HELPER}{DEFAULT_TARGET_SERIAL} = 0xFFFFFFFF; # 0xFFFFFFFF is any serialnumber
|
||||||
$hash->{HELPER}{PKT_ID} = 0x8001; # Packet ID
|
$hash->{HELPER}{PKT_ID} = 0x8001; # Packet ID
|
||||||
$hash->{HELPER}{MAXBYTES} = 300; # constant MAXBYTES scalar 300
|
$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 ($IP,$Host,$Caps);
|
||||||
|
|
||||||
@ -466,7 +497,7 @@ sub SMAInverter_GetData($) {
|
|||||||
InternalTimer(gettimeofday()+$interval, "SMAInverter_GetData", $hash, 0);
|
InternalTimer(gettimeofday()+$interval, "SMAInverter_GetData", $hash, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("getstatus_DoParse", "$name", "getstatus_ParseDone", $timeout, "getstatus_ParseAborted", $hash);
|
$hash->{HELPER}{RUNNING_PID} = BlockingCall("SMAInverter_getstatusDoParse", "$name", "SMAInverter_getstatusParseDone", $timeout, "SMAInverter_getstatusParseAborted", $hash);
|
||||||
$hash->{HELPER}{RUNNING_PID}{loglevel} = 4;
|
$hash->{HELPER}{RUNNING_PID}{loglevel} = 4;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -475,7 +506,7 @@ return;
|
|||||||
###############################################################
|
###############################################################
|
||||||
# non-blocking Inverter Datenabruf
|
# non-blocking Inverter Datenabruf
|
||||||
###############################################################
|
###############################################################
|
||||||
sub getstatus_DoParse($) {
|
sub SMAInverter_getstatusDoParse($) {
|
||||||
my ($name) = @_;
|
my ($name) = @_;
|
||||||
my $hash = $defs{$name};
|
my $hash = $defs{$name};
|
||||||
my $interval = AttrVal($name, "interval", 60);
|
my $interval = AttrVal($name, "interval", 60);
|
||||||
@ -520,22 +551,34 @@ sub getstatus_DoParse($) {
|
|||||||
# Background-Startzeit
|
# Background-Startzeit
|
||||||
$bst = [gettimeofday];
|
$bst = [gettimeofday];
|
||||||
|
|
||||||
Log3 ($name, 4, "$name -> Start BlockingCall getstatus_DoParse");
|
Log3 ($name, 4, "$name -> Start BlockingCall SMAInverter_getstatusDoParse");
|
||||||
|
|
||||||
# set dependency from surise/sunset used for inverter operation time
|
# set dependency from surise/sunset used for inverter operation time
|
||||||
my $offset = AttrVal($name,"offset",0);
|
my $offset = AttrVal($name,"offset",0);
|
||||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
|
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
|
||||||
|
|
||||||
my ($sunrise_h,$sunrise_m,$sunrise_s) = split(":",sunrise_abs('-'.$offset));
|
my ($sunrise_h,$sunrise_m,$sunrise_s) = split(":",sunrise_abs('-'.$offset));
|
||||||
my ($sunset_h,$sunset_m,$sunset_s) = split(":",sunset_abs('+'.$offset));
|
my ($sunset_h,$sunset_m,$sunset_s) = split(":",sunset_abs('+'.$offset));
|
||||||
|
|
||||||
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_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_stop = DateTime->new(year=>$year+1900,month=>$mon+1,day=>$mday,hour=>$sunset_h,minute=>$sunset_m,second=>$sunset_s,time_zone=>'local');
|
||||||
my $dt_now = DateTime->now(time_zone=>'local');
|
my $dt_now = DateTime->now(time_zone=>'local');
|
||||||
|
|
||||||
Log3 $name, 4, "$name - current time: ".$dt_now->dmy('.')." ".$dt_now->hms;
|
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 begin: ".$oper_start->dmy('.')." ".$oper_start->hms;
|
||||||
Log3 $name, 4, "$name - operation time end: ".$oper_stop->dmy('.')." ".$oper_stop->hms;
|
Log3 $name, 4, "$name - operation time end: ".$oper_stop->dmy('.')." ".$oper_stop->hms;
|
||||||
|
|
||||||
my $opertime_start = $oper_start->dmy('.')." ".$oper_start->hms;
|
my $opertime_start = $oper_start->dmy('.')." ".$oper_start->hms;
|
||||||
my $opertime_stop = $oper_stop->dmy('.')." ".$oper_stop->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_stop) {
|
||||||
|
my $val;
|
||||||
|
$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 (($oper_start <= $dt_now && $dt_now <= $oper_stop) || AttrVal($name,"suppressSleep",0)) {
|
if (($oper_start <= $dt_now && $dt_now <= $oper_stop) || AttrVal($name,"suppressSleep",0)) {
|
||||||
# normal operation or suppressed sleepmode
|
# normal operation or suppressed sleepmode
|
||||||
|
|
||||||
@ -572,62 +615,62 @@ sub getstatus_DoParse($) {
|
|||||||
push(@commands, "sup_DeviceStatus"); # Check DeviceStatus
|
push(@commands, "sup_DeviceStatus"); # Check DeviceStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
if(SMA_logon($hash->{HOST}, $hash->{PASS}, $hash)) {
|
if(SMAInverter_SMAlogon($hash->{HOST}, $hash->{PASS}, $hash)) {
|
||||||
Log3 $name, 5, "$name - Logged in now";
|
Log3 $name, 5, "$name - Logged in now";
|
||||||
|
|
||||||
foreach my $i(@commands) {
|
foreach my $i(@commands) {
|
||||||
if ($i eq "sup_TypeLabel") {
|
if ($i eq "sup_TypeLabel") {
|
||||||
($sup_TypeLabel,$inv_TYPE,$inv_CLASS,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x58000200, 0x00821E00, 0x008220FF);
|
($sup_TypeLabel,$inv_TYPE,$inv_CLASS,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x58000200, 0x00821E00, 0x008220FF);
|
||||||
}
|
}
|
||||||
elsif ($i eq "sup_EnergyProduction") {
|
elsif ($i eq "sup_EnergyProduction") {
|
||||||
($sup_EnergyProduction,$inv_SPOT_ETODAY,$inv_SPOT_ETOTAL,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x54000200, 0x00260100, 0x002622FF);
|
($sup_EnergyProduction,$inv_SPOT_ETODAY,$inv_SPOT_ETOTAL,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x54000200, 0x00260100, 0x002622FF);
|
||||||
}
|
}
|
||||||
elsif ($i eq "sup_SpotDCPower") {
|
elsif ($i eq "sup_SpotDCPower") {
|
||||||
($sup_SpotDCPower,$inv_SPOT_PDC1,$inv_SPOT_PDC2,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x53800200, 0x00251E00, 0x00251EFF);
|
($sup_SpotDCPower,$inv_SPOT_PDC1,$inv_SPOT_PDC2,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x53800200, 0x00251E00, 0x00251EFF);
|
||||||
}
|
}
|
||||||
elsif ($i eq "sup_SpotACPower") {
|
elsif ($i eq "sup_SpotACPower") {
|
||||||
($sup_SpotACPower,$inv_SPOT_PAC1,$inv_SPOT_PAC2,$inv_SPOT_PAC3,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x51000200, 0x00464000, 0x004642FF);
|
($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") {
|
elsif ($i eq "sup_SpotACTotalPower") {
|
||||||
($sup_SpotACTotalPower,$inv_SPOT_PACTOT,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x51000200, 0x00263F00, 0x00263FFF);
|
($sup_SpotACTotalPower,$inv_SPOT_PACTOT,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00263F00, 0x00263FFF);
|
||||||
}
|
}
|
||||||
elsif ($i eq "sup_ChargeStatus") {
|
elsif ($i eq "sup_ChargeStatus") {
|
||||||
($sup_ChargeStatus,$inv_ChargeStatus,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x51000200, 0x00295A00, 0x00295AFF);
|
($sup_ChargeStatus,$inv_ChargeStatus,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00295A00, 0x00295AFF);
|
||||||
}
|
}
|
||||||
elsif ($i eq "sup_SpotDCVoltage") {
|
elsif ($i eq "sup_SpotDCVoltage") {
|
||||||
($sup_SpotDCVoltage,$inv_SPOT_UDC1,$inv_SPOT_UDC2,$inv_SPOT_IDC1,$inv_SPOT_IDC2,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x53800200, 0x00451F00, 0x004521FF);
|
($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);
|
||||||
}
|
}
|
||||||
elsif ($i eq "sup_SpotACVoltage") {
|
elsif ($i eq "sup_SpotACVoltage") {
|
||||||
($sup_SpotACVoltage,$inv_SPOT_UAC1,$inv_SPOT_UAC2,$inv_SPOT_UAC3,$inv_SPOT_IAC1,$inv_SPOT_IAC2,$inv_SPOT_IAC3,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x51000200, 0x00464800, 0x004655FF);
|
($sup_SpotACVoltage,$inv_SPOT_UAC1,$inv_SPOT_UAC2,$inv_SPOT_UAC3,$inv_SPOT_IAC1,$inv_SPOT_IAC2,$inv_SPOT_IAC3,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00464800, 0x004655FF);
|
||||||
}
|
}
|
||||||
elsif ($i eq "sup_BatteryInfo") {
|
elsif ($i eq "sup_BatteryInfo") {
|
||||||
($sup_BatteryInfo,$inv_BAT_CYCLES,$inv_BAT_TEMP,$inv_BAT_UDC,$inv_BAT_IDC,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x51000200, 0x00491E00, 0x00495DFF);
|
($sup_BatteryInfo,$inv_BAT_CYCLES,$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_SpotGridFrequency") {
|
elsif ($i eq "sup_SpotGridFrequency") {
|
||||||
($sup_SpotGridFrequency,$inv_SPOT_FREQ,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x51000200, 0x00465700, 0x004657FF);
|
($sup_SpotGridFrequency,$inv_SPOT_FREQ,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00465700, 0x004657FF);
|
||||||
}
|
}
|
||||||
elsif ($i eq "sup_OperationTime") {
|
elsif ($i eq "sup_OperationTime") {
|
||||||
($sup_OperationTime,$inv_SPOT_OPERTM,$inv_SPOT_FEEDTM,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x54000200, 0x00462E00, 0x00462FFF);
|
($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") {
|
elsif ($i eq "sup_InverterTemperature") {
|
||||||
($sup_InverterTemperature,$inv_TEMP,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x52000200, 0x00237700, 0x002377FF);
|
($sup_InverterTemperature,$inv_TEMP,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x52000200, 0x00237700, 0x002377FF);
|
||||||
}
|
}
|
||||||
elsif ($i eq "sup_MaxACPower") {
|
elsif ($i eq "sup_MaxACPower") {
|
||||||
($sup_MaxACPower,$inv_PACMAX1,$inv_PACMAX2,$inv_PACMAX3,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x51000200, 0x00411E00, 0x004120FF);
|
($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") {
|
elsif ($i eq "sup_MaxACPower2") {
|
||||||
($sup_MaxACPower2,$inv_PACMAX1_2,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x51000200, 0x00832A00, 0x00832AFF);
|
($sup_MaxACPower2,$inv_PACMAX1_2,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51000200, 0x00832A00, 0x00832AFF);
|
||||||
}
|
}
|
||||||
elsif ($i eq "sup_GridRelayStatus") {
|
elsif ($i eq "sup_GridRelayStatus") {
|
||||||
($sup_GridRelayStatus,$inv_GRIDRELAY,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x51800200, 0x00416400, 0x004164FF);
|
($sup_GridRelayStatus,$inv_GRIDRELAY,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51800200, 0x00416400, 0x004164FF);
|
||||||
}
|
}
|
||||||
elsif ($i eq "sup_DeviceStatus") {
|
elsif ($i eq "sup_DeviceStatus") {
|
||||||
($sup_DeviceStatus,$inv_STATUS,$inv_susyid,$inv_serial) = SMA_command($hash, $hash->{HOST}, 0x51800200, 0x00214800, 0x002148FF);
|
($sup_DeviceStatus,$inv_STATUS,$inv_susyid,$inv_serial) = SMAInverter_SMAcommand($hash, $hash->{HOST}, 0x51800200, 0x00214800, 0x002148FF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# nothing more to do, just log out
|
# nothing more to do, just log out
|
||||||
SMA_logout($hash,$hash->{HOST});
|
SMAInverter_SMAlogout($hash,$hash->{HOST});
|
||||||
|
|
||||||
# Inverter Laufzeit ermitteln
|
# Inverter Laufzeit ermitteln
|
||||||
$irt = tv_interval($ist);
|
$irt = tv_interval($ist);
|
||||||
@ -761,8 +804,8 @@ sub getstatus_DoParse($) {
|
|||||||
push(@row_array, "grid_freq. ".sprintf("%.2f",$inv_SPOT_FREQ)."\n");
|
push(@row_array, "grid_freq. ".sprintf("%.2f",$inv_SPOT_FREQ)."\n");
|
||||||
}
|
}
|
||||||
if($sup_TypeLabel) {
|
if($sup_TypeLabel) {
|
||||||
push(@row_array, "device_type ".devtype($inv_TYPE)."\n");
|
push(@row_array, "device_type ".SMAInverter_devtype($inv_TYPE)."\n");
|
||||||
push(@row_array, "device_class ".classtype($inv_CLASS)."\n");
|
push(@row_array, "device_class ".SMAInverter_classtype($inv_CLASS)."\n");
|
||||||
push(@row_array, "susyid ".$inv_susyid." - SN: ".$inv_serial."\n") if($inv_susyid && $inv_serial);
|
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, "device_name "."SN: ".$inv_serial."\n") if($inv_serial);
|
||||||
push(@row_array, "serial_number ".$inv_serial."\n") if($inv_serial);
|
push(@row_array, "serial_number ".$inv_serial."\n") if($inv_serial);
|
||||||
@ -783,10 +826,10 @@ sub getstatus_DoParse($) {
|
|||||||
push(@row_array, "operation_time ".$inv_SPOT_OPERTM."\n");
|
push(@row_array, "operation_time ".$inv_SPOT_OPERTM."\n");
|
||||||
}
|
}
|
||||||
if($sup_GridRelayStatus) {
|
if($sup_GridRelayStatus) {
|
||||||
push(@row_array, "gridrelay_status ".StatusText($inv_GRIDRELAY)."\n");
|
push(@row_array, "gridrelay_status ".SMAInverter_StatusText($inv_GRIDRELAY)."\n");
|
||||||
}
|
}
|
||||||
if($sup_DeviceStatus) {
|
if($sup_DeviceStatus) {
|
||||||
push(@row_array, "device_status ".StatusText($inv_STATUS)."\n");
|
push(@row_array, "device_status ".SMAInverter_StatusText($inv_STATUS)."\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { # kein SBFSpot Compatibility Mode
|
} else { # kein SBFSpot Compatibility Mode
|
||||||
@ -851,8 +894,8 @@ sub getstatus_DoParse($) {
|
|||||||
push(@row_array, "SPOT_FREQ ".$inv_SPOT_FREQ."\n");
|
push(@row_array, "SPOT_FREQ ".$inv_SPOT_FREQ."\n");
|
||||||
}
|
}
|
||||||
if($sup_TypeLabel) {
|
if($sup_TypeLabel) {
|
||||||
push(@row_array, "INV_TYPE ".devtype($inv_TYPE)."\n");
|
push(@row_array, "INV_TYPE ".SMAInverter_devtype($inv_TYPE)."\n");
|
||||||
push(@row_array, "INV_CLASS ".classtype($inv_CLASS)."\n");
|
push(@row_array, "INV_CLASS ".SMAInverter_classtype($inv_CLASS)."\n");
|
||||||
push(@row_array, "SUSyID ".$inv_susyid."\n") if($inv_susyid);
|
push(@row_array, "SUSyID ".$inv_susyid."\n") if($inv_susyid);
|
||||||
push(@row_array, "Serialnumber ".$inv_serial."\n") if($inv_serial);
|
push(@row_array, "Serialnumber ".$inv_serial."\n") if($inv_serial);
|
||||||
}
|
}
|
||||||
@ -872,10 +915,10 @@ sub getstatus_DoParse($) {
|
|||||||
push(@row_array, "SPOT_OPERTM ".$inv_SPOT_OPERTM."\n");
|
push(@row_array, "SPOT_OPERTM ".$inv_SPOT_OPERTM."\n");
|
||||||
}
|
}
|
||||||
if($sup_GridRelayStatus) {
|
if($sup_GridRelayStatus) {
|
||||||
push(@row_array, "INV_GRIDRELAY ".StatusText($inv_GRIDRELAY)."\n");
|
push(@row_array, "INV_GRIDRELAY ".SMAInverter_StatusText($inv_GRIDRELAY)."\n");
|
||||||
}
|
}
|
||||||
if($sup_DeviceStatus) {
|
if($sup_DeviceStatus) {
|
||||||
push(@row_array, "INV_STATUS ".StatusText($inv_STATUS)."\n");
|
push(@row_array, "INV_STATUS ".SMAInverter_StatusText($inv_STATUS)."\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -907,7 +950,7 @@ sub getstatus_DoParse($) {
|
|||||||
|
|
||||||
$rt = ($irt?$irt:'').",".$brt;
|
$rt = ($irt?$irt:'').",".$brt;
|
||||||
|
|
||||||
Log3 ($name, 4, "$name -> BlockingCall getstatus_DoParse finished");
|
Log3 ($name, 4, "$name -> BlockingCall SMAInverter_getstatusDoParse finished");
|
||||||
|
|
||||||
return "$name|$rowlist|$avg|$rt";
|
return "$name|$rowlist|$avg|$rt";
|
||||||
}
|
}
|
||||||
@ -915,7 +958,7 @@ return "$name|$rowlist|$avg|$rt";
|
|||||||
###############################################################
|
###############################################################
|
||||||
# Auswertung non-blocking Inverter Datenabruf
|
# Auswertung non-blocking Inverter Datenabruf
|
||||||
###############################################################
|
###############################################################
|
||||||
sub getstatus_ParseDone ($) {
|
sub SMAInverter_getstatusParseDone ($) {
|
||||||
my ($string) = @_;
|
my ($string) = @_;
|
||||||
my @a = split("\\|",$string);
|
my @a = split("\\|",$string);
|
||||||
my $name = $a[0];
|
my $name = $a[0];
|
||||||
@ -925,7 +968,7 @@ sub getstatus_ParseDone ($) {
|
|||||||
my $rt = $a[3];
|
my $rt = $a[3];
|
||||||
my ($irt,$brt) = split(",", $rt);
|
my ($irt,$brt) = split(",", $rt);
|
||||||
|
|
||||||
Log3 ($name, 4, "$name -> Start BlockingCall getstatus_ParseDone");
|
Log3 ($name, 4, "$name -> Start BlockingCall SMAInverter_getstatusParseDone");
|
||||||
|
|
||||||
# proctime Readings löschen
|
# proctime Readings löschen
|
||||||
if(!AttrVal($name, "showproctime", undef)) {
|
if(!AttrVal($name, "showproctime", undef)) {
|
||||||
@ -959,7 +1002,7 @@ sub getstatus_ParseDone ($) {
|
|||||||
readingsEndUpdate($hash, 1);
|
readingsEndUpdate($hash, 1);
|
||||||
|
|
||||||
delete($hash->{HELPER}{RUNNING_PID});
|
delete($hash->{HELPER}{RUNNING_PID});
|
||||||
Log3 ($name, 4, "$name -> BlockingCall getstatus_ParseDone finished");
|
Log3 ($name, 4, "$name -> BlockingCall SMAInverter_getstatusParseDone finished");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -967,7 +1010,7 @@ return;
|
|||||||
###############################################################
|
###############################################################
|
||||||
# Abbruchroutine Timeout Inverter Abfrage
|
# Abbruchroutine Timeout Inverter Abfrage
|
||||||
###############################################################
|
###############################################################
|
||||||
sub getstatus_ParseAborted(@) {
|
sub SMAInverter_getstatusParseAborted(@) {
|
||||||
my ($hash,$cause) = @_;
|
my ($hash,$cause) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $discycles = $hash->{HELPER}{FAULTEDCYCLES};
|
my $discycles = $hash->{HELPER}{FAULTEDCYCLES};
|
||||||
@ -988,7 +1031,7 @@ return;
|
|||||||
##########################################################################
|
##########################################################################
|
||||||
# SMA Command Execution
|
# SMA Command Execution
|
||||||
##########################################################################
|
##########################################################################
|
||||||
sub SMA_command($$$$$) {
|
sub SMAInverter_SMAcommand($$$$$) {
|
||||||
# Parameters: $hash - host - command - first - last
|
# Parameters: $hash - host - command - first - last
|
||||||
my ($hash,$host,$command,$first,$last) = @_;
|
my ($hash,$host,$command,$first,$last) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
@ -1024,14 +1067,14 @@ sub SMA_command($$$$$) {
|
|||||||
my $target_serial = AttrVal($name, "target-serial", $default_target_serial);
|
my $target_serial = AttrVal($name, "target-serial", $default_target_serial);
|
||||||
|
|
||||||
# Define own ID and target ID and packet ID
|
# Define own ID and target ID and packet ID
|
||||||
$myID = ByteOrderShort(substr(sprintf("%04X",$mysusyid),0,4)) . ByteOrderLong(sprintf("%08X",$myserialnumber));
|
$myID = SMAInverter_ByteOrderShort(substr(sprintf("%04X",$mysusyid),0,4)) . SMAInverter_ByteOrderLong(sprintf("%08X",$myserialnumber));
|
||||||
$target_ID = ByteOrderShort(substr(sprintf("%04X",$target_susyid),0,4)) . ByteOrderLong(sprintf("%08X",$target_serial));
|
$target_ID = SMAInverter_ByteOrderShort(substr(sprintf("%04X",$target_susyid),0,4)) . SMAInverter_ByteOrderLong(sprintf("%08X",$target_serial));
|
||||||
|
|
||||||
# Increasing Packet ID
|
# Increasing Packet ID
|
||||||
$hash->{HELPER}{PKT_ID} = $hash->{HELPER}{PKT_ID} + 1;
|
$hash->{HELPER}{PKT_ID} = $hash->{HELPER}{PKT_ID} + 1;
|
||||||
$spkt_ID = ByteOrderShort(sprintf("%04X",$hash->{HELPER}{PKT_ID}));
|
$spkt_ID = SMAInverter_ByteOrderShort(sprintf("%04X",$hash->{HELPER}{PKT_ID}));
|
||||||
|
|
||||||
$cmd_ID = ByteOrderLong(sprintf("%08X",$command)) . ByteOrderLong(sprintf("%08X",$first)) . ByteOrderLong(sprintf("%08X",$last));
|
$cmd_ID = SMAInverter_ByteOrderLong(sprintf("%08X",$command)) . SMAInverter_ByteOrderLong(sprintf("%08X",$first)) . SMAInverter_ByteOrderLong(sprintf("%08X",$last));
|
||||||
|
|
||||||
#build final command to send
|
#build final command to send
|
||||||
$cmd = $cmdheader . $pktlength . $esignature . $target_ID . "0000" . $myID . "0000" . "00000000" . $spkt_ID . $cmd_ID . "00000000";
|
$cmd = $cmdheader . $pktlength . $esignature . $target_ID . "0000" . $myID . "0000" . "00000000" . $spkt_ID . $cmd_ID . "00000000";
|
||||||
@ -1108,9 +1151,29 @@ sub SMA_command($$$$$) {
|
|||||||
Log3 $name, 5, "$name - Data identifier $data_ID";
|
Log3 $name, 5, "$name - Data identifier $data_ID";
|
||||||
|
|
||||||
if($data_ID eq 0x2601) {
|
if($data_ID eq 0x2601) {
|
||||||
|
if (length($data) >= 66) {
|
||||||
$inv_SPOT_ETOTAL = unpack("V*", substr($data, 62, 4));
|
$inv_SPOT_ETOTAL = unpack("V*", substr($data, 62, 4));
|
||||||
$inv_SPOT_ETODAY = unpack("V*", substr $data, 78, 4);
|
} else {
|
||||||
Log3 $name, 5, "$name - Found Data SPOT_ETOTAL=$inv_SPOT_ETOTAL and SPOT_ETODAY=$inv_SPOT_ETODAY";
|
Log3 $name, 3, "$name - WARNING - ETOTAL wasn't deliverd ... set it to \"0\" !";
|
||||||
|
$inv_SPOT_ETOTAL = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length($data) >= 82) {
|
||||||
|
$inv_SPOT_ETODAY = unpack("V*", substr ($data, 78, 4));
|
||||||
|
} else {
|
||||||
|
# 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", undef);
|
||||||
|
if(defined $etotold && $inv_SPOT_ETOTAL > $etotold) {
|
||||||
|
$inv_SPOT_ETODAY = $inv_SPOT_ETOTAL - $etotold;
|
||||||
|
Log3 $name, 3, "$name - ETODAY calculated successfully !";
|
||||||
|
} else {
|
||||||
|
Log3 $name, 3, "$name - WARNING - unable to calculate ETODAY ... set it to \"0\" !";
|
||||||
|
$inv_SPOT_ETODAY = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
return (1,$inv_SPOT_ETODAY,$inv_SPOT_ETOTAL,$inv_susyid,$inv_serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1275,7 +1338,7 @@ return 0;
|
|||||||
##########################################################################
|
##########################################################################
|
||||||
# Login
|
# Login
|
||||||
##########################################################################
|
##########################################################################
|
||||||
sub SMA_logon($$$) {
|
sub SMAInverter_SMAlogon($$$) {
|
||||||
# Parameters: host - passcode
|
# Parameters: host - passcode
|
||||||
my ($host,$pass,$hash) = @_;
|
my ($host,$pass,$hash) = @_;
|
||||||
my $cmdheader = "534D4100000402A00000000100";
|
my $cmdheader = "534D4100000402A00000000100";
|
||||||
@ -1306,13 +1369,13 @@ sub SMA_logon($$$) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Get current timestamp in epoch format (unix format)
|
# Get current timestamp in epoch format (unix format)
|
||||||
$timestmp = ByteOrderLong(sprintf("%08X",int(time())));
|
$timestmp = SMAInverter_ByteOrderLong(sprintf("%08X",int(time())));
|
||||||
|
|
||||||
# Define own ID and target ID and packet ID
|
# Define own ID and target ID and packet ID
|
||||||
$myID = ByteOrderShort(substr(sprintf("%04X",$mysusyid),0,4)) . ByteOrderLong(sprintf("%08X",$myserialnumber));
|
$myID = SMAInverter_ByteOrderShort(substr(sprintf("%04X",$mysusyid),0,4)) . SMAInverter_ByteOrderLong(sprintf("%08X",$myserialnumber));
|
||||||
$target_ID = ByteOrderShort(substr(sprintf("%04X",$target_susyid),0,4)) . ByteOrderLong(sprintf("%08X",$target_serial));
|
$target_ID = SMAInverter_ByteOrderShort(substr(sprintf("%04X",$target_susyid),0,4)) . SMAInverter_ByteOrderLong(sprintf("%08X",$target_serial));
|
||||||
$pkt_ID = 0x8001; # Reset to 0x8001
|
$pkt_ID = 0x8001; # Reset to 0x8001
|
||||||
$spkt_ID = ByteOrderShort(sprintf("%04X",$pkt_ID));
|
$spkt_ID = SMAInverter_ByteOrderShort(sprintf("%04X",$pkt_ID));
|
||||||
|
|
||||||
#Logon command
|
#Logon command
|
||||||
$cmd_ID = "0C04FDFF" . "07000000" . "84030000"; # Logon command + User group "User" + (maybe) Timeout
|
$cmd_ID = "0C04FDFF" . "07000000" . "84030000"; # Logon command + User group "User" + (maybe) Timeout
|
||||||
@ -1355,7 +1418,7 @@ sub SMA_logon($$$) {
|
|||||||
Log3 $name, 1, "$name - Nothing received...";
|
Log3 $name, 1, "$name - Nothing received...";
|
||||||
# send: cmd_logout
|
# send: cmd_logout
|
||||||
$socket->close();
|
$socket->close();
|
||||||
SMA_logout($hash,$host);
|
SMAInverter_SMAlogout($hash,$host);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
# We have received something!
|
# We have received something!
|
||||||
@ -1373,14 +1436,14 @@ sub SMA_logon($$$) {
|
|||||||
Log3 $name, 5, "$name - Request/Response: SusyID $mysusyid/$r_susyid, Serial $myserialnumber/$r_serial, Packet ID $hash->{HELPER}{PKT_ID}/$r_pkt_ID, Command 0xFFFD040D/$r_cmd_ID, Error $r_error";
|
Log3 $name, 5, "$name - Request/Response: SusyID $mysusyid/$r_susyid, Serial $myserialnumber/$r_serial, Packet ID $hash->{HELPER}{PKT_ID}/$r_pkt_ID, Command 0xFFFD040D/$r_cmd_ID, Error $r_error";
|
||||||
# send: cmd_logout
|
# send: cmd_logout
|
||||||
$socket->close();
|
$socket->close();
|
||||||
SMA_logout($hash,$host);
|
SMAInverter_SMAlogout($hash,$host);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log3 $name, 1, "$name - Format of inverter response does not fit.";
|
Log3 $name, 1, "$name - Format of inverter response does not fit.";
|
||||||
# send: cmd_logout
|
# send: cmd_logout
|
||||||
$socket->close();
|
$socket->close();
|
||||||
SMA_logout($hash,$host);
|
SMAInverter_SMAlogout($hash,$host);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1392,19 +1455,49 @@ sub SMA_logon($$$) {
|
|||||||
|
|
||||||
if (AttrVal($name, "target-serial", undef)) {
|
if (AttrVal($name, "target-serial", undef)) {
|
||||||
return 0 unless($inv_serial eq $target_serial);
|
return 0 unless($inv_serial eq $target_serial);
|
||||||
|
} else {
|
||||||
|
BlockingInformParent("SMAInverter_setAttrFromBlocking", [$name, "target-serial", $inv_serial], 0); # Serial automatisch setzen, Forum: https://forum.fhem.de/index.php/topic,56080.msg967448.html#msg967448
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AttrVal($name, "target-susyid", undef)) {
|
if (AttrVal($name, "target-susyid", undef)) {
|
||||||
return 0 unless($inv_susyid eq $target_susyid);
|
return 0 unless($inv_susyid eq $target_susyid);
|
||||||
|
} else {
|
||||||
|
BlockingInformParent("SMAInverter_setAttrFromBlocking", [$name, "target-susyid", $inv_susyid], 0); # SuSyId automatisch setzen, Forum: https://forum.fhem.de/index.php/topic,56080.msg967448.html#msg967448
|
||||||
}
|
}
|
||||||
|
|
||||||
Log3 $name, 4, "$name - logged in to inverter serial: $inv_serial, susyid: $inv_susyid";
|
Log3 $name, 4, "$name - logged in to inverter serial: $inv_serial, susyid: $inv_susyid";
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Attributwert aus BlockingCall setzen
|
||||||
|
################################################################
|
||||||
|
sub SMAInverter_setAttrFromBlocking($$$) {
|
||||||
|
my ($name,$attr,$val) = @_;
|
||||||
|
my $hash = $defs{$name};
|
||||||
|
|
||||||
|
CommandAttr(undef,"$name $attr $val");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Readingwert aus BlockingCall setzen
|
||||||
|
################################################################
|
||||||
|
sub SMAInverter_setReadingFromBlocking($$$) {
|
||||||
|
my ($name,$reading,$val) = @_;
|
||||||
|
my $hash = $defs{$name};
|
||||||
|
|
||||||
|
readingsSingleUpdate($hash, $reading, $val, 0);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# Logout
|
# Logout
|
||||||
##########################################################################
|
##########################################################################
|
||||||
sub SMA_logout($$) {
|
sub SMAInverter_SMAlogout($$) {
|
||||||
# Parameters: host
|
# Parameters: host
|
||||||
my ($hash,$host) = @_;
|
my ($hash,$host) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
@ -1424,11 +1517,11 @@ sub SMA_logout($$) {
|
|||||||
my $target_serial = AttrVal($name, "target-serial", $default_target_serial);
|
my $target_serial = AttrVal($name, "target-serial", $default_target_serial);
|
||||||
|
|
||||||
# Define own ID and target ID and packet ID
|
# Define own ID and target ID and packet ID
|
||||||
$myID = ByteOrderShort(substr(sprintf("%04X",$mysusyid),0,4)) . ByteOrderLong(sprintf("%08X",$myserialnumber));
|
$myID = SMAInverter_ByteOrderShort(substr(sprintf("%04X",$mysusyid),0,4)) . SMAInverter_ByteOrderLong(sprintf("%08X",$myserialnumber));
|
||||||
$target_ID = ByteOrderShort(substr(sprintf("%04X",$target_susyid),0,4)) . ByteOrderLong(sprintf("%08X",$target_serial));
|
$target_ID = SMAInverter_ByteOrderShort(substr(sprintf("%04X",$target_susyid),0,4)) . SMAInverter_ByteOrderLong(sprintf("%08X",$target_serial));
|
||||||
# Increasing Packet ID
|
# Increasing Packet ID
|
||||||
$hash->{HELPER}{PKT_ID} = $hash->{HELPER}{PKT_ID} + 1;
|
$hash->{HELPER}{PKT_ID} = $hash->{HELPER}{PKT_ID} + 1;
|
||||||
$spkt_ID = ByteOrderShort(sprintf("%04X",$hash->{HELPER}{PKT_ID}));
|
$spkt_ID = SMAInverter_ByteOrderShort(sprintf("%04X",$hash->{HELPER}{PKT_ID}));
|
||||||
|
|
||||||
# Logout command
|
# Logout command
|
||||||
$cmd_ID = "0E01FDFF" . "FFFFFFFF"; # Logout command
|
$cmd_ID = "0E01FDFF" . "FFFFFFFF"; # Logout command
|
||||||
@ -1459,33 +1552,73 @@ sub SMA_logout($$) {
|
|||||||
Log3 $name, 4, "$name - logged out now from inverter serial: $target_serial, susyid: $target_susyid";
|
Log3 $name, 4, "$name - logged out now from inverter serial: $target_serial, susyid: $target_susyid";
|
||||||
|
|
||||||
$socket->close();
|
$socket->close();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# Hilfsroutinen
|
# Versionierungen des Moduls setzen
|
||||||
|
# Die Verwendung von Meta.pm und Packages wird berücksichtigt
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
sub SMAInverter_setVersionInfo($) {
|
||||||
|
my ($hash) = @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
##########################
|
my $v = (sortTopicNum("desc",keys %SMAInverter_vNotesIntern))[0];
|
||||||
sub ByteOrderShort($) {
|
my $type = $hash->{TYPE};
|
||||||
|
$hash->{HELPER}{PACKAGE} = __PACKAGE__;
|
||||||
|
$hash->{HELPER}{VERSION} = $v;
|
||||||
|
|
||||||
|
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$ im Kopf komplett! vorhanden )
|
||||||
|
$modules{$type}{META}{x_version} =~ s/1.1.1/$v/g;
|
||||||
|
} else {
|
||||||
|
$modules{$type}{META}{x_version} = $v;
|
||||||
|
}
|
||||||
|
return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id$ im Kopf komplett! vorhanden )
|
||||||
|
if(__PACKAGE__ eq "FHEM::$type" || __PACKAGE__ eq $type) {
|
||||||
|
# es wird mit Packages gearbeitet -> Perl übliche Modulversion setzen
|
||||||
|
# mit {<Modul>->VERSION()} im FHEMWEB kann Modulversion abgefragt werden
|
||||||
|
use version 0.77; our $VERSION = FHEM::Meta::Get( $hash, 'version' );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
# herkömmliche Modulstruktur
|
||||||
|
$hash->{VERSION} = $v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# Sortierung
|
||||||
|
##########################################################################
|
||||||
|
sub SMAInverter_ByteOrderShort($) {
|
||||||
my $input = $_[0];
|
my $input = $_[0];
|
||||||
my $output = "";
|
my $output = "";
|
||||||
$output = substr($input, 2, 2) . substr($input, 0, 2);
|
$output = substr($input, 2, 2) . substr($input, 0, 2);
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
##########################
|
##########################################################################
|
||||||
sub ByteOrderLong($) {
|
# Sortierung
|
||||||
|
##########################################################################
|
||||||
|
sub SMAInverter_ByteOrderLong($) {
|
||||||
my $input = $_[0];
|
my $input = $_[0];
|
||||||
my $output = "";
|
my $output = "";
|
||||||
$output = substr($input, 6, 2) . substr($input, 4, 2) . substr($input, 2, 2) . substr($input, 0, 2);
|
$output = substr($input, 6, 2) . substr($input, 4, 2) . substr($input, 2, 2) . substr($input, 0, 2);
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
##########################
|
##########################################################################
|
||||||
sub StatusText($)
|
# Texte for State
|
||||||
{
|
# Parameter is the code, return value is the Text or if not known then
|
||||||
# Parameter is the code, return value is the Text or if not known then the code as string
|
# the code as string
|
||||||
|
##########################################################################
|
||||||
|
sub SMAInverter_StatusText($) {
|
||||||
my $code = $_[0];
|
my $code = $_[0];
|
||||||
|
|
||||||
if($code eq 51) { return (AttrVal("global", "language", "EN") eq "DE") ? "geschlossen" : "Closed"; }
|
if($code eq 51) { return (AttrVal("global", "language", "EN") eq "DE") ? "geschlossen" : "Closed"; }
|
||||||
@ -1500,21 +1633,22 @@ sub StatusText($)
|
|||||||
return sprintf("%d", $code);
|
return sprintf("%d", $code);
|
||||||
}
|
}
|
||||||
|
|
||||||
##########################
|
##########################################################################
|
||||||
# identify device type
|
# identify inverter type
|
||||||
|
##########################################################################
|
||||||
sub devtype ($) {
|
sub SMAInverter_devtype ($) {
|
||||||
my ($code) = @_;
|
my ($code) = @_;
|
||||||
|
|
||||||
unless (exists($SMAInverter_devtypes{$code})) { return $code;}
|
unless (exists($SMAInverter_devtypes{$code})) { return $code;}
|
||||||
my $dev = $SMAInverter_devtypes{$code};
|
my $dev = $SMAInverter_devtypes{$code};
|
||||||
|
|
||||||
return ($dev);
|
return ($dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
##########################
|
##########################################################################
|
||||||
# identify device class
|
# identify device class
|
||||||
|
##########################################################################
|
||||||
sub classtype ($) {
|
sub SMAInverter_classtype ($) {
|
||||||
my ($code) = @_;
|
my ($code) = @_;
|
||||||
my $class;
|
my $class;
|
||||||
|
|
||||||
@ -1599,31 +1733,113 @@ The retrieval of the inverter will be executed non-blocking. You can adjust the
|
|||||||
<b>Get</b>
|
<b>Get</b>
|
||||||
<br>
|
<br>
|
||||||
<ul>
|
<ul>
|
||||||
<code>get <name> data</code>
|
|
||||||
|
<li><b> get <name> data </b>
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
The request of the inverter will be executed. Those possibility is especifically created for the "manual" operation mode (see attribute "mode").
|
The request of the inverter will be executed. Those possibility is especifically created for the "manual" operation
|
||||||
|
mode (see attribute "mode").
|
||||||
|
<br>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<br>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<b>Attributes</b>
|
<b>Attributes</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>interval</b> : Queryintreval in seconds </li>
|
|
||||||
<li><b>detail-level</b> : "0" - Only Power and Energy / "1" - Including Voltage and Current / "2" - All values </li>
|
<a name="detail-level"></a>
|
||||||
<li><b>disable</b> : 1 = the module is disabled </li>
|
<li><b>detail-level [0|1|2] </b><br>
|
||||||
<li><b>mode</b> : automatic = the inverter will be polled by preset interval, manual = query only by command "get <name> data" </li>
|
Defines the complexity of the generated readings. <br><br>
|
||||||
<li><b>offset</b> : time in seconds to prefer the sunrise respectively defer the sunset virtualy (0 ... 7200). You will be able to extend the working
|
|
||||||
period of the module. </li>
|
<ul>
|
||||||
<li><b>SBFSpotComp</b> : 1 = the readings are created like SBFSpot-style </li>
|
<table>
|
||||||
<li><b>suppressSleep</b> : the sleep mode (after sunset, before sunrise) is deactivated and the inverter will be polled continuously. </li>
|
<colgroup> <col width=10%> <col width=90%> </colgroup>
|
||||||
<li><b>showproctime</b> : shows processing time in background and wasted time to retrieve inverter data </li>
|
<tr><td> 0 </td><td>- only Power and Energy </td></tr>
|
||||||
<li><b>target-susyid</b> : In case of a Multigate the target SUSyID can be defined. If more than one inverter is installed you have to
|
<tr><td> 1 </td><td>- as 0, additional voltage and current </td></tr>
|
||||||
set the inverter-SUSyID to assign the inverter to the device definition.
|
<tr><td> 2 </td><td>- all values </td></tr>
|
||||||
Default is 0xFFFF, means any SUSyID</li>
|
</table>
|
||||||
<li><b>target-serial</b> : In case of a Multigate the target Serialnumber can be defined. If more than one inverter is installed you have to
|
</ul>
|
||||||
set the inverter-Serialnumber to assign the inverter to the device definition.
|
|
||||||
Default is 0xFFFFFFFF, means any Serialnumber</li>
|
</li>
|
||||||
<li><b>timeout</b> : setup timeout of inverter data request (default 60s) </li>
|
<br>
|
||||||
|
|
||||||
|
<a name="disable"></a>
|
||||||
|
<li><b>disable [1|0]</b><br>
|
||||||
|
Deactivate/activate the module.
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="interval"></a>
|
||||||
|
<li><b>interval </b><br>
|
||||||
|
Request cycle in seconds. (default: 60)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="mode"></a>
|
||||||
|
<li><b>mode [automatic|manual] </b><br>
|
||||||
|
The request mode of the inverter. (default: automatic) <br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<table>
|
||||||
|
<colgroup> <col width=10%> <col width=90%> </colgroup>
|
||||||
|
<tr><td> automatic </td><td>- the inverter will be polled regularly as defined by attribute "interval" </td></tr>
|
||||||
|
<tr><td> manual </td><td>- query only by command "get <name> data" </td></tr>
|
||||||
|
</table>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="offset"></a>
|
||||||
|
<li><b>offset <0 - 7200> </b><br>
|
||||||
|
Time in seconds to forward the real sunrise respectively defer the real sunset.
|
||||||
|
You will be able to extend the working period of the module.
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="SBFSpotComp"></a>
|
||||||
|
<li><b>SBFSpotComp [1|0]</b><br>
|
||||||
|
The reading names are created like the SBFSpot-style. (default: 0)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="showproctime"></a>
|
||||||
|
<li><b>showproctime [1|0]</b><br>
|
||||||
|
Shows the processing time in background and the wasted time to retrieve inverter data. (default: 0)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="suppressSleep"></a>
|
||||||
|
<li><b>suppressSleep [1|0]</b><br>
|
||||||
|
The sleep mode (after sunset and before sunrise) is deactivated and the inverter will be polled continuously. (default: 0)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="target-serial"></a>
|
||||||
|
<li><b>target-serial </b><br>
|
||||||
|
In case of a Multigate the target serial number has to be defined. If more than one inverter is installed,
|
||||||
|
you have to set the inverter serial number to assign the inverter to the device definition.
|
||||||
|
If only one inverter available, the attribut is set automatically once the serial number of the inverter was detected.
|
||||||
|
(default: 0xFFFFFFFF = means any serial number)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="target-susyid"></a>
|
||||||
|
<li><b>target-susyid </b><br>
|
||||||
|
In case of a Multigate the target SUSyID has to be defined. If more than one inverter is installed,
|
||||||
|
you have to set the inverter-SUSyID to assign the inverter to the device definition.
|
||||||
|
If only one inverter available, the attribut is set automatically once the SUSyID of the inverter was detected.
|
||||||
|
(default: 0xFFFF = means any SUSyID)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="timeout"></a>
|
||||||
|
<li><b>timeout </b><br>
|
||||||
|
Setup timeout of inverter data request in seconds. (default 60)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<b>Readings</b>
|
<b>Readings</b>
|
||||||
@ -1748,31 +1964,115 @@ Die Abfrage des Wechselrichters wird non-blocking ausgeführt. Der Timeoutwert f
|
|||||||
<b>Get</b>
|
<b>Get</b>
|
||||||
<br>
|
<br>
|
||||||
<ul>
|
<ul>
|
||||||
<code>get <name> data</code>
|
|
||||||
|
<li><b> get <name> data </b>
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
Die Datenabfrage des Wechselrichters wird ausgeführt. Diese Möglichkeit ist speziell für den Betriebsmodus "manual" vorgesehen (siehe Attribut "mode").
|
Die Datenabfrage des Wechselrichters wird ausgeführt. Diese Möglichkeit ist speziell für den Betriebsmodus "manual"
|
||||||
|
vorgesehen (siehe Attribut "mode").
|
||||||
|
<br>
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<b>Attribute</b>
|
<b>Attribute</b>
|
||||||
|
<br<br>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>interval</b> : Abfrageinterval in Sekunden </li>
|
|
||||||
<li><b>detail-level</b> : "0" - Nur Leistung und Energie / "1" - zusätzlich Strom und Spannung / "2" - Alle Werte </li>
|
<a name="detail-level"></a>
|
||||||
<li><b>disable</b> : 1 = das Modul ist disabled </li>
|
<li><b>detail-level [0|1|2] </b><br>
|
||||||
<li><b>mode</b> : automatic = die Wechselrichterwerte werden im eingestellten Interval abgefragt, manual = Abfrage nur mit "get <name> data" </li>
|
Legt den Umfang der ausgegebenen Readings fest. <br><br>
|
||||||
<li><b>offset</b> : Zeit in Sekunden um die der Sonnenaufgang vorgezogen bzw. Sonnenuntergang verzögert wird (0 ... 7200). Dadurch wird die
|
|
||||||
effektive Aktivzeit des Moduls erweitert. </li>
|
<ul>
|
||||||
<li><b>suppressSleep</b> : der Schlafmodus (nach Sonnenuntergang, vor Sonnenaufgang) wird ausgeschaltet und der WR abgefragt. </li>
|
<table>
|
||||||
<li><b>showproctime</b> : zeigt die für den Hintergrundprozess und die Abfrage des Wechselrichter verbrauchte Zeit. </li>
|
<colgroup> <col width=10%> <col width=90%> </colgroup>
|
||||||
<li><b>SBFSpotComp</b> : 1 = die Readings werden kompatibel zu SBFSpot-Ausgaben erzeugt </li>
|
<tr><td> 0 </td><td>- nur Leistung und Energie </td></tr>
|
||||||
<li><b>target-susyid</b> : Im Falle eines Multigate kann die Ziel-SUSyID definiert werden. Ist mehr als ein Wechselrichter installiert,
|
<tr><td> 1 </td><td>- wie 0, zusätzlich Strom und Spannung </td></tr>
|
||||||
muß die Wechselreichter-SUSyID gesetzt werden um den Wechselrichter der Device-Definition eindeutig zuzuweisen.
|
<tr><td> 2 </td><td>- alle Werte </td></tr>
|
||||||
Default ist 0xFFFF (=keine Einschränkung)</li>
|
</table>
|
||||||
<li><b>target-serial</b> : Im Falle eines Multigate kann die Ziel-Seriennummer definiert werden. Ist mehr als ein Wechselrichter installiert,
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="disable"></a>
|
||||||
|
<li><b>disable [1|0]</b><br>
|
||||||
|
Deaktiviert/aktiviert das Modul.
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="interval"></a>
|
||||||
|
<li><b>interval </b><br>
|
||||||
|
Abfrageinterval in Sekunden. (default: 60)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="mode"></a>
|
||||||
|
<li><b>mode [automatic|manual] </b><br>
|
||||||
|
Abfragemodus des Wechselrichters. (default: automatic) <br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<table>
|
||||||
|
<colgroup> <col width=10%> <col width=90%> </colgroup>
|
||||||
|
<tr><td> automatic </td><td>- die Wechselrichterwerte werden im eingestellten Interval abgefragt (Attribut "interval") </td></tr>
|
||||||
|
<tr><td> manual </td><td>- Abfrage nur mit "get <name> data" </td></tr>
|
||||||
|
</table>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="offset"></a>
|
||||||
|
<li><b>offset <0 - 7200> </b><br>
|
||||||
|
Zeit in Sekunden, um die der reale Sonnenaufgang vorgezogen bzw. reale Sonnenuntergang verzögert wird.
|
||||||
|
Dadurch wird die effektive Aktivzeit des Moduls erweitert.
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="SBFSpotComp"></a>
|
||||||
|
<li><b>SBFSpotComp [1|0]</b><br>
|
||||||
|
Die Readingnamen werden kompatibel zu SBFSpot-Ausgaben erzeugt. (default: 0)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="showproctime"></a>
|
||||||
|
<li><b>showproctime [1|0]</b><br>
|
||||||
|
Zeigt die für den Hintergrundprozess und die Abfrage des Wechselrichter verbrauchte Zeit. (default: 0)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="suppressSleep"></a>
|
||||||
|
<li><b>suppressSleep [1|0]</b><br>
|
||||||
|
Der Schlafmodus (nach Sonnenuntergang und vor Sonnenaufgang) wird ausgeschaltet und der WR abgefragt. (default: 0)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="target-serial"></a>
|
||||||
|
<li><b>target-serial </b><br>
|
||||||
|
Im Falle eines Multigate muss die Ziel-Seriennummer definiert werden. Ist mehr als ein Wechselrichter installiert,
|
||||||
muß die Wechselreichter-Seriennummer gesetzt werden um den Wechselrichter der Device-Definition eindeutig zuzuweisen.
|
muß die Wechselreichter-Seriennummer gesetzt werden um den Wechselrichter der Device-Definition eindeutig zuzuweisen.
|
||||||
Default ist 0xFFFFFFFF (=keine Einschränkung)</li>
|
Ist nur ein Wechselrichter vorhanden und das Attribut nicht gesetzt, wird es automatisch definiert sobald die
|
||||||
<li><b>timeout</b> : Einstellung des timeout für die Wechselrichterabfrage (default 60s) </li>
|
Seriennummer des Wechselrichters erkannt wurde.
|
||||||
|
(default: 0xFFFFFFFF = keine Einschränkung)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="target-susyid"></a>
|
||||||
|
<li><b>target-susyid </b><br>
|
||||||
|
Im Falle eines Multigate muss die Ziel-SUSyID definiert werden. Ist mehr als ein Wechselrichter installiert,
|
||||||
|
muß die Wechselreichter-SUSyID gesetzt werden um den Wechselrichter der Device-Definition eindeutig zuzuweisen.
|
||||||
|
Ist nur ein Wechselrichter vorhanden und das Attribut nicht gesetzt, wird es automatisch definiert sobald die
|
||||||
|
SUSyID des Wechselrichters erkannt wurde.
|
||||||
|
(default: 0xFFFF = keine Einschränkung)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a name="timeout"></a>
|
||||||
|
<li><b>timeout </b><br>
|
||||||
|
Einstellung des timeout für die Wechselrichterabfrage in Sekunden. (default 60)
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<b>Readings</b>
|
<b>Readings</b>
|
||||||
@ -1832,4 +2132,51 @@ Die Datenabfrage des Wechselrichters wird ausgeführt. Diese Möglichkeit ist sp
|
|||||||
|
|
||||||
=end html_DE
|
=end html_DE
|
||||||
|
|
||||||
|
=for :application/json;q=META.json 76_SMAInverter.pm
|
||||||
|
{
|
||||||
|
"abstract": "Integration of SMA Inverters over it's Speedwire (=Ethernet) Interface",
|
||||||
|
"x_lang": {
|
||||||
|
"de": {
|
||||||
|
"abstract": "Integration von SMA Wechselrichtern ueber Speedwire (=Ethernet) Interface"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"SMA",
|
||||||
|
"photovoltaics",
|
||||||
|
"PV",
|
||||||
|
"inverter"
|
||||||
|
],
|
||||||
|
"version": "v1.1.1",
|
||||||
|
"release_status": "stable",
|
||||||
|
"author": [
|
||||||
|
"Thomas Schoedl (sct14675)",
|
||||||
|
"Heiko Maaz <heiko.maaz@t-online.de>",
|
||||||
|
null
|
||||||
|
],
|
||||||
|
"x_fhem_maintainer": [
|
||||||
|
"sct14675",
|
||||||
|
"DS_Starter",
|
||||||
|
null
|
||||||
|
],
|
||||||
|
"prereqs": {
|
||||||
|
"runtime": {
|
||||||
|
"requires": {
|
||||||
|
"FHEM": 5.00918799,
|
||||||
|
"perl": 5.014,
|
||||||
|
"IO::Socket::INET": 0,
|
||||||
|
"DateTime": 0,
|
||||||
|
"Time::HiRes": 0,
|
||||||
|
"Blocking": 0,
|
||||||
|
"Time::Local": 0
|
||||||
|
},
|
||||||
|
"recommends": {
|
||||||
|
"FHEM::Meta": 0
|
||||||
|
},
|
||||||
|
"suggests": {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
=end :application/json;q=META.json
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
Loading…
x
Reference in New Issue
Block a user