mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +00:00
76_SMAPortal: contrib 2.8.0
git-svn-id: https://svn.fhem.de/fhem/trunk@22076 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
1753f10b00
commit
aa6601781c
@ -134,6 +134,8 @@ BEGIN {
|
||||
|
||||
# Versions History intern
|
||||
my %vNotesIntern = (
|
||||
"2.8.0" => "30.05.2020 refactoring process logic, attribute cookielifetime & getDataRetries deleted, command delCookieFile deleted ".
|
||||
"new attribute maxCallCycle ",
|
||||
"2.7.2" => "28.05.2020 delete cookie file if threshold of read retries reached ",
|
||||
"2.7.1" => "28.05.2020 change cookie default location to ./log/<name>_cookie.txt ",
|
||||
"2.7.0" => "27.05.2020 improve stability of data retrieval, new command delCookieFile, new readings dailyCallCounter and dailyIssueCookieCounter ".
|
||||
@ -178,10 +180,13 @@ my %vNotesIntern = (
|
||||
"1.2.2" => "11.03.2019 new Errormessage analyze added, make ready for Meta.pm ",
|
||||
"1.2.1" => "10.03.2019 behavior of state changed, commandref revised ",
|
||||
"1.2.0" => "09.03.2019 integrate weather data, minor fixes ",
|
||||
"1.1.0" => "09.03.2019 make get data more stable, new attribute \"getDataRetries\" ",
|
||||
"1.1.0" => "09.03.2019 make get data more stable, new attribute 'getDataRetries' ",
|
||||
"1.0.0" => "03.03.2019 initial "
|
||||
);
|
||||
|
||||
# Voreinstellungen
|
||||
my $maxretries = 4; # max. Anzahl Wiederholunegn in einem Abtuf-Cycle
|
||||
|
||||
###############################################################
|
||||
# SMAPortal Initialize
|
||||
###############################################################
|
||||
@ -196,10 +201,9 @@ sub Initialize {
|
||||
$hash->{GetFn} = \&Get;
|
||||
$hash->{DbLog_splitFn} = \&DbLog_split;
|
||||
$hash->{AttrList} = "cookieLocation ".
|
||||
"cookielifetime ".
|
||||
"detailLevel:1,2,3,4 ".
|
||||
"disable:0,1 ".
|
||||
"getDataRetries:4,5,6,7,8,9,10,11,12,13,14,15 ".
|
||||
"maxCallCycle:5,6,7,8,9,10,11,12,13,14,15 ".
|
||||
"interval ".
|
||||
"showPassInLog:1,0 ".
|
||||
"timeout ".
|
||||
@ -229,7 +233,6 @@ sub Define {
|
||||
setVersionInfo($hash); # Versionsinformationen setzen
|
||||
getcredentials($hash,1); # Credentials lesen und in RAM laden ($boot=1)
|
||||
CallInfo ($hash); # Start Daten Abrufschleife
|
||||
delcookiefile ($hash); # Start Schleife regelmäßiges Löschen Cookiefile
|
||||
|
||||
return;
|
||||
}
|
||||
@ -284,8 +287,7 @@ sub Set { ## no critic
|
||||
# erweiterte Setlist wenn Credentials gesetzt
|
||||
$setlist = "Unknown argument $opt, choose one of ".
|
||||
"credentials ".
|
||||
"createPortalGraphic:Generation,Consumption,Generation_Consumption,Differential ".
|
||||
"delCookieFile:noArg "
|
||||
"createPortalGraphic:Generation,Consumption,Generation_Consumption,Differential "
|
||||
;
|
||||
if($hash->{HELPER}{PLANTOID} && $hash->{HELPER}{CONSUMER}) {
|
||||
my $lfd = 0;
|
||||
@ -389,13 +391,6 @@ sub Set { ## no critic
|
||||
$hash->{HELPER}{SETTER} = "$opt:$prop";
|
||||
CallInfo($hash);
|
||||
|
||||
} elsif ($opt eq "delCookieFile") {
|
||||
my $cf = AttrVal($name, "cookieLocation", "./log/".$name."_cookie.txt");
|
||||
my $err = delcookiefile ($hash, 1);
|
||||
my $ret = $err ? qq{WARNING - Cookie file "$cf" not deleted: $err} : qq{Cookie file "$cf" deleted};
|
||||
Log3 ($name, 3, qq{$name - $ret}) if($err);
|
||||
return $ret;
|
||||
|
||||
} else {
|
||||
return "$setlist";
|
||||
}
|
||||
@ -593,10 +588,8 @@ sub Attr {
|
||||
delread($hash);
|
||||
delete $hash->{MODE};
|
||||
RemoveInternalTimer($hash);
|
||||
delcookiefile($hash,1);
|
||||
} else {
|
||||
InternalTimer(gettimeofday()+1.0, "FHEM::SMAPortal::CallInfo", $hash, 0);
|
||||
InternalTimer(gettimeofday()+5.0, "FHEM::SMAPortal::delcookiefile", $hash, 0);
|
||||
}
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
@ -620,12 +613,13 @@ return;
|
||||
}
|
||||
|
||||
################################################################
|
||||
## Hauptschleife BlockingCall
|
||||
## $hash->{HELPER}{GETTER} -> Flag für get Informationen
|
||||
## $hash->{HELPER}{SETTER} -> Parameter für set-Befehl
|
||||
# Hauptschleife BlockingCall
|
||||
# $hash->{HELPER}{GETTER} -> Flag für get Informationen
|
||||
# $hash->{HELPER}{SETTER} -> Parameter für set-Befehl
|
||||
# $nc = 1 wenn ein neuer Abrufcyclus gestartet werden soll
|
||||
################################################################
|
||||
sub CallInfo {
|
||||
my ($hash) = @_;
|
||||
my ($hash,$nc) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $timeout = AttrVal($name, "timeout", 30);
|
||||
my $interval = AttrVal($name, "interval", 300);
|
||||
@ -644,7 +638,7 @@ sub CallInfo {
|
||||
$hash->{MODE} = "Manual";
|
||||
} else {
|
||||
$new = gettimeofday()+$interval;
|
||||
InternalTimer($new, "FHEM::SMAPortal::CallInfo", $hash, 0);
|
||||
InternalTimer($new, "FHEM::SMAPortal::CallInfo", $hash, 0); # Wiederholungsintervall
|
||||
$hash->{MODE} = "Automatic - next polltime: ".FmtTime($new);
|
||||
}
|
||||
|
||||
@ -662,7 +656,15 @@ sub CallInfo {
|
||||
Log3 ($name, 4, "$name - ### start of set/get data from SMA Sunny Portal ###");
|
||||
Log3 ($name, 4, "$name - ################################################################");
|
||||
|
||||
$hash->{HELPER}{RETRIES} = AttrVal($name, "getDataRetries", 3)-1;
|
||||
$hash->{HELPER}{ACTCYCLE} = 0 if(!$nc);
|
||||
my $ac = $hash->{HELPER}{ACTCYCLE};
|
||||
my $maxac = AttrVal($name, "maxCallCycle", 5);
|
||||
|
||||
Log3 ($name, 3, "$name - Running data cycle: $ac of maximum $maxac");
|
||||
|
||||
readingsSingleUpdate($hash, "state", "running - call cycle $ac", 1);
|
||||
|
||||
$hash->{HELPER}{RETRIES} = $maxretries;
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("FHEM::SMAPortal::GetSetData", "$name|$getp|$setp", "FHEM::SMAPortal::ParseData", $timeout, "FHEM::SMAPortal::ParseAborted", $hash);
|
||||
$hash->{HELPER}{RUNNING_PID}{loglevel} = 5 if($hash->{HELPER}{RUNNING_PID}); # Forum #77057
|
||||
|
||||
@ -733,13 +735,78 @@ sub GetSetData { ## no cri
|
||||
|
||||
if(($livedata->content =~ m/FeedIn/ix) && ($livedata->content !~ m/expired/ix)) {
|
||||
Log3 $name, 4, "$name - Login to SMA-Portal successful";
|
||||
|
||||
# JSON Live Daten
|
||||
$livedata_content = $livedata->content;
|
||||
$login_state = 1;
|
||||
Log3 ($name, 4, "$name - Getting live data");
|
||||
Log3 ($name, 5, "$name - Data received:\n".Dumper decode_json($livedata_content)) if($v5d eq "liveData");
|
||||
|
||||
### einen Verbraucher schalten mit POST
|
||||
} else {
|
||||
my $usernameField = "ctl00\$ContentPlaceHolder1\$Logincontrol1\$txtUserName";
|
||||
my $passwordField = "ctl00\$ContentPlaceHolder1\$Logincontrol1\$txtPassword";
|
||||
my $loginField = "__EVENTTARGET";
|
||||
my $loginButton = "ctl00\$ContentPlaceHolder1\$Logincontrol1\$LoginBtn";
|
||||
|
||||
Log3 ($name, 4, "$name - User not logged in. Try login with credentials ...");
|
||||
|
||||
# Credentials abrufen
|
||||
my ($success, $username, $password) = getcredentials($hash,0);
|
||||
|
||||
if(!$success) {
|
||||
Log3($name, 1, "$name - Credentials couldn't be retrieved successfully - make sure you've set it with \"set $name credentials <username> <password>\"");
|
||||
$login_state = 0;
|
||||
|
||||
} else {
|
||||
|
||||
my $loginp = $ua->post('https://www.sunnyportal.com/Templates/Start.aspx',[$usernameField => $username, $passwordField => $password, "__EVENTTARGET" => $loginButton]);
|
||||
|
||||
Log3 ($name, 4, "$name - ".$loginp->code);
|
||||
Log3 ($name, 5, "$name - Login-Page return: ".$loginp->content);
|
||||
|
||||
if($loginp->content =~ /Logincontrol1_ErrorLabel/ix) {
|
||||
Log3 ($name, 1, "$name - Error: login to SMA-Portal failed");
|
||||
$livedata_content = "{\"Login-Status\":\"failed\"}";
|
||||
} else {
|
||||
Log3 ($name, 3, "$name - Login into SMA-Portal successfully done");
|
||||
handleCounter ($name, "dailyIssueCookieCounter"); # Cookie Ausstellungszähler setzen
|
||||
|
||||
$livedata_content = '{"Login-Status":"successful", "InfoMessages":["login to SMA-Portal successful."]}';
|
||||
BlockingInformParent("FHEM::SMAPortal::setFromBlocking", [$name, "NULL", "NULL", (gettimeofday())[0], "NULL"], 0);
|
||||
}
|
||||
|
||||
my $shmp = $ua->get('https://www.sunnyportal.com/FixedPages/HoManLive.aspx');
|
||||
Log3 ($name, 5, "$name - ".$shmp->code);
|
||||
}
|
||||
}
|
||||
|
||||
($reread,$retry) = analyzeData($hash,$livedata_content);
|
||||
|
||||
goto &GetSetData if($reread);
|
||||
|
||||
# Wiederholung Datenabruf innerhalb eines Cycle
|
||||
my $ac = $hash->{HELPER}{ACTCYCLE};
|
||||
my $maxcc = AttrVal($name, "maxCallCycle", 5);
|
||||
my $retc = $hash->{HELPER}{RETRIES};
|
||||
|
||||
if($getp ne "none" && $retry && $retc >= 0 && $ac <= $maxcc) { # Livedaten konnten nicht gelesen werden, neuer Versuch zeitverzögert
|
||||
my $act = $maxretries - $retc; # Index aktueller Wiederholungsversuch
|
||||
|
||||
$hash->{HELPER}{RETRIES} -= 1;
|
||||
|
||||
if($maxretries - $act == 0) { # Schwellenwert erreicht ($max-1 Leseversuche) -> Cookie File löschen
|
||||
Log3 ($name, 3, qq{$name - Maximum retries reached, delete cookie and start new cycle ...});
|
||||
sleep 3; # Verzögerung next cycle
|
||||
return "$name|1|$login_state|$getp|$setp"; # threshold exceed
|
||||
}
|
||||
|
||||
# sleep 3; # Perl Sleep -> nur im BlockingCall !
|
||||
goto &GetSetData;
|
||||
}
|
||||
|
||||
|
||||
### Verbraucher schalten
|
||||
#######################################
|
||||
if($setp ne "none") {
|
||||
my ($serial,$id);
|
||||
foreach my $key (keys %{$hash->{HELPER}{CONSUMER}}) {
|
||||
@ -768,7 +835,8 @@ sub GetSetData { ## no cri
|
||||
}
|
||||
}
|
||||
|
||||
### Daten abrufen mit GET
|
||||
### Daten abrufen
|
||||
#########################
|
||||
if($getp ne "none") {
|
||||
|
||||
# JSON Wetterdaten
|
||||
@ -866,48 +934,6 @@ sub GetSetData { ## no cri
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
my $usernameField = "ctl00\$ContentPlaceHolder1\$Logincontrol1\$txtUserName";
|
||||
my $passwordField = "ctl00\$ContentPlaceHolder1\$Logincontrol1\$txtPassword";
|
||||
my $loginField = "__EVENTTARGET";
|
||||
my $loginButton = "ctl00\$ContentPlaceHolder1\$Logincontrol1\$LoginBtn";
|
||||
|
||||
Log3 ($name, 3, "$name - User not logged in. Try login with credentials ...");
|
||||
|
||||
# Credentials abrufen
|
||||
my ($success, $username, $password) = getcredentials($hash,0);
|
||||
|
||||
unless ($success) {
|
||||
Log3($name, 1, "$name - Credentials couldn't be retrieved successfully - make sure you've set it with \"set $name credentials <username> <password>\"");
|
||||
$login_state = 0;
|
||||
|
||||
} else {
|
||||
my $loginp = $ua->post('https://www.sunnyportal.com/Templates/Start.aspx',[$usernameField => $username, $passwordField => $password, "__EVENTTARGET" => $loginButton]);
|
||||
|
||||
Log3 ($name, 4, "$name - ".$loginp->code);
|
||||
Log3 ($name, 5, "$name - Login-Page return: ".$loginp->content);
|
||||
|
||||
if($loginp->content =~ /Logincontrol1_ErrorLabel/ix) {
|
||||
Log3 ($name, 1, "$name - Error: login to SMA-Portal failed");
|
||||
$livedata_content = "{\"Login-Status\":\"failed\"}";
|
||||
} else {
|
||||
Log3 ($name, 3, "$name - Login into SMA-Portal successfully done");
|
||||
handleCounter ($name, "dailyIssueCookieCounter"); # Cookie Ausstellungszähler setzen
|
||||
|
||||
$livedata_content = '{"Login-Status":"successful", "InfoMessages":["login to SMA-Portal successful but get data with next data cycle."]}';
|
||||
BlockingInformParent("FHEM::SMAPortal::setFromBlocking", [$name, "NULL", "NULL", (gettimeofday())[0], "NULL"], 0);
|
||||
|
||||
$login_state = 1;
|
||||
$reread = 1;
|
||||
}
|
||||
|
||||
my $shmp = $ua->get('https://www.sunnyportal.com/FixedPages/HoManLive.aspx');
|
||||
Log3 ($name, 5, "$name - ".$shmp->code);
|
||||
}
|
||||
}
|
||||
|
||||
($reread,$retry) = analyzeLivedata($hash,$livedata_content) if($getp ne "none");
|
||||
|
||||
# Daten müssen als Einzeiler zurückgegeben werden
|
||||
my ($st,$lc,$fc,$wc,$cl,$cd,$cm,$cy) = ("","","","","","","","");
|
||||
$st = encode_base64($state,"");
|
||||
@ -919,7 +945,7 @@ sub GetSetData { ## no cri
|
||||
$cm = encode_base64($ccmonthdata_content,"") if($ccmonthdata_content);
|
||||
$cy = encode_base64($ccyeardata_content,"") if($ccyeardata_content);
|
||||
|
||||
return "$name|$login_state|$reread|$retry|$getp|$setp|$st|$lc|$fc|$wc|$cl|$cd|$cm|$cy";
|
||||
return "$name|0|$login_state|$getp|$setp|$st|$lc|$fc|$wc|$cl|$cd|$cm|$cy";
|
||||
}
|
||||
|
||||
################################################################
|
||||
@ -930,22 +956,36 @@ sub ParseData { ## no critic
|
||||
my @a = split("\\|",$string);
|
||||
my $hash = $defs{$a[0]};
|
||||
my $name = $hash->{NAME};
|
||||
my $timeout = AttrVal($name, "timeout", 30);
|
||||
|
||||
my ($login_state,$reread,$retry,$getp,$setp,$fc,$wc,$cl,$cd,$cm,$cy,$lc,$state);
|
||||
my ($login_state,$retry,$getp,$setp,$fc,$wc,$cl,$cd,$cm,$cy,$lc,$state,$exceed);
|
||||
|
||||
$login_state = $a[1];
|
||||
$reread = $a[2];
|
||||
$retry = $a[3];
|
||||
$getp = $a[4];
|
||||
$setp = $a[5];
|
||||
$state = decode_base64($a[6]);
|
||||
$lc = decode_base64($a[7]);
|
||||
$fc = decode_base64($a[8]) if($a[8]);
|
||||
$wc = decode_base64($a[9]) if($a[9]);
|
||||
$cl = decode_base64($a[10]) if($a[10]);
|
||||
$cd = decode_base64($a[11]) if($a[11]);
|
||||
$cm = decode_base64($a[12]) if($a[12]);
|
||||
$cy = decode_base64($a[13]) if($a[13]);
|
||||
$exceed = $a[1];
|
||||
$login_state = $a[2];
|
||||
$getp = $a[3];
|
||||
$setp = $a[4];
|
||||
|
||||
my $ac = $hash->{HELPER}{ACTCYCLE};
|
||||
my $maxac = AttrVal($name, "maxCallCycle", 5);
|
||||
|
||||
if($exceed && $ac <= $maxac) {
|
||||
delete($hash->{HELPER}{RUNNING_PID});
|
||||
delcookiefile ($hash);
|
||||
$hash->{HELPER}{GETTER} = $getp;
|
||||
$hash->{HELPER}{SETTER} = $setp;
|
||||
$hash->{HELPER}{ACTCYCLE}++;
|
||||
CallInfo($hash,1); # neuer Abrufcycle
|
||||
return;
|
||||
}
|
||||
|
||||
$state = decode_base64($a[5]);
|
||||
$lc = decode_base64($a[6]);
|
||||
$fc = decode_base64($a[7]) if($a[7]);
|
||||
$wc = decode_base64($a[8]) if($a[8]);
|
||||
$cl = decode_base64($a[9]) if($a[9]);
|
||||
$cd = decode_base64($a[10]) if($a[10]);
|
||||
$cm = decode_base64($a[11]) if($a[11]);
|
||||
$cy = decode_base64($a[12]) if($a[12]);
|
||||
|
||||
my ($livedata_content,$forecast_content,$weatherdata_content,$consumerlivedata_content);
|
||||
my ($ccdaydata_content,$ccmonthdata_content,$ccyeardata_content);
|
||||
@ -957,28 +997,6 @@ sub ParseData { ## no critic
|
||||
$ccmonthdata_content = decode_json($cm) if($cm);
|
||||
$ccyeardata_content = decode_json($cy) if($cy);
|
||||
|
||||
my $timeout = AttrVal($name, "timeout", 30);
|
||||
if($reread) { # login war erfolgreich, aber set/get muss jetzt noch ausgeführt werden
|
||||
delete($hash->{HELPER}{RUNNING_PID});
|
||||
readingsSingleUpdate($hash, "L1_Login-Status", "successful", 1);
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("FHEM::SMAPortal::GetSetData", "$name|$getp|$setp", "FHEM::SMAPortal::ParseData", $timeout, "FHEM::SMAPortal::ParseAborted", $hash);
|
||||
$hash->{HELPER}{RUNNING_PID}{loglevel} = 5 if($hash->{HELPER}{RUNNING_PID}); # Forum #77057
|
||||
return;
|
||||
}
|
||||
|
||||
if($retry && $hash->{HELPER}{RETRIES}) { # Livedaten konnten nicht gelesen werden, neuer Versuch zeitverzögert
|
||||
delete($hash->{HELPER}{RUNNING_PID});
|
||||
my $max = AttrVal($name, "getDataRetries", 1);
|
||||
my $act = $max - $hash->{HELPER}{RETRIES}; # Index aktueller Wiederholungsversuch
|
||||
|
||||
$hash->{HELPER}{RETRIES} -= 1;
|
||||
|
||||
delcookiefile ($hash, 1) if($max - $act <= 1); # Schwellenwert erreicht ($max-1 Leseversuche) -> Cookie File löschen
|
||||
|
||||
InternalTimer(gettimeofday()+3, "FHEM::SMAPortal::retrygetdata", $hash, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
my $dl = AttrVal($name, "detailLevel", 1);
|
||||
delread($hash, $dl+1);
|
||||
|
||||
@ -1112,12 +1130,12 @@ sub ParseData { ## no critic
|
||||
extractWeatherData($hash,$weatherdata_content);
|
||||
}
|
||||
|
||||
my $pv = ReadingsNum($name, "L1_PV", 0);
|
||||
my $fi = ReadingsNum($name, "L1_FeedIn", 0);
|
||||
my $pv = ReadingsNum($name, "L1_PV" , 0);
|
||||
my $fi = ReadingsNum($name, "L1_FeedIn" , 0);
|
||||
my $gc = ReadingsNum($name, "L1_GridConsumption", 0);
|
||||
my $sum = $fi-$gc;
|
||||
|
||||
if(!$hash->{HELPER}{RETRIES} && !$pv && !$fi && !$gc) {
|
||||
if(!$pv && !$fi && !$gc) {
|
||||
# keine Anlagendaten vorhanden
|
||||
$state = "Data can't be retrieved from SMA-Portal. Reread at next scheduled cycle.";
|
||||
Log3 ($name, 2, "$name - $state");
|
||||
@ -1137,6 +1155,7 @@ sub ParseData { ## no critic
|
||||
}
|
||||
readingsEndUpdate($hash, 1);
|
||||
|
||||
delcookiefile ($hash);
|
||||
delete($hash->{HELPER}{RUNNING_PID});
|
||||
$hash->{HELPER}{GETTER} = "all";
|
||||
$hash->{HELPER}{SETTER} = "none";
|
||||
@ -1159,44 +1178,26 @@ sub ParseAborted {
|
||||
$hash->{HELPER}{GETTER} = "all";
|
||||
$hash->{HELPER}{SETTER} = "none";
|
||||
|
||||
delcookiefile ($hash);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# regelmäßig Cookie-Datei löschen
|
||||
# $must = 1 -> Cookie Zwangslöschung
|
||||
# Cookie-Datei löschen
|
||||
################################################################
|
||||
sub delcookiefile {
|
||||
my ($hash,$must) = @_;
|
||||
my ($hash,$source) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my ($validperiod, $cookieLocation, $oldlogintime, $delfile);
|
||||
my $err = "";
|
||||
|
||||
RemoveInternalTimer($hash,"FHEM::SMAPortal::delcookiefile");
|
||||
|
||||
# Gültigkeitsdauer Cookie in Sekunden
|
||||
$validperiod = AttrVal($name, "cookielifetime", 3600);
|
||||
$cookieLocation = AttrVal($name, "cookieLocation", "./log/".$name."_cookie.txt");
|
||||
|
||||
if($must) {
|
||||
# Cookie Zwangslöschung
|
||||
$delfile = unlink($cookieLocation) or $err = $!;
|
||||
}
|
||||
|
||||
$oldlogintime = $hash->{HELPER}{oldlogintime} // 0;
|
||||
|
||||
if($init_done == 1 && gettimeofday() > $oldlogintime+$validperiod) { # löschen wenn gettimeofday()+$validperiod abgelaufen
|
||||
$delfile = unlink($cookieLocation) or $err = $!;
|
||||
}
|
||||
my $cookieLocation = AttrVal($name, "cookieLocation", "./log/".$name."_cookie.txt");
|
||||
my $delfile = unlink ($cookieLocation) or $err = $!;
|
||||
|
||||
if($delfile) {
|
||||
Log3 $name, 3, "$name - Cookie file deleted: $cookieLocation";
|
||||
}
|
||||
|
||||
return if(IsDisabled($name));
|
||||
|
||||
InternalTimer(gettimeofday()+30, "FHEM::SMAPortal::delcookiefile", $hash, 0);
|
||||
|
||||
return ($err);
|
||||
}
|
||||
|
||||
@ -1771,7 +1772,7 @@ sub handleCounter {
|
||||
}
|
||||
$count++;
|
||||
$cstring = "$rd:$day:$count";
|
||||
BlockingInformParent("FHEM::SMAPortal::setFromBlocking", [$name, "NULL", "NULL", "NULL", $cstring], 0);
|
||||
BlockingInformParent("FHEM::SMAPortal::setFromBlocking", [$name, "NULL", "NULL", "NULL", $cstring], 1);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1790,27 +1791,30 @@ sub setFromBlocking {
|
||||
|
||||
$hash->{HELPER}{GETTER} = $getp if($getp ne "NULL");
|
||||
$hash->{HELPER}{SETTER} = $setp if($setp ne "NULL");
|
||||
$hash->{HELPER}{oldlogintime} = $logintime if($logintime ne "NULL");
|
||||
|
||||
if($logintime ne "NULL") {
|
||||
$hash->{HELPER}{oldlogintime} = $logintime;
|
||||
readingsSingleUpdate($hash, "L1_Login-Status", "successful", 1);
|
||||
}
|
||||
|
||||
if($counter ne "NULL") {
|
||||
my @cparts = split ":", $counter, 2;
|
||||
readingsSingleUpdate($hash, $cparts[0], $cparts[1], 1);
|
||||
}
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# analysiere Livedaten
|
||||
# analysiere abgerufene Daten
|
||||
################################################################
|
||||
sub analyzeLivedata { ## no critic 'complexity'
|
||||
sub analyzeData { ## no critic 'complexity'
|
||||
my ($hash,$lc) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my ($reread,$retry) = (0,0);
|
||||
|
||||
my $max = AttrVal($name, "getDataRetries", 3);
|
||||
my $act = $max - $hash->{HELPER}{RETRIES}; # Index aktueller Wiederholungsversuch
|
||||
my $attstr = "Attempts read data again ... ($act of $max)";
|
||||
my $act = $maxretries - $hash->{HELPER}{RETRIES}; # Index aktueller Wiederholungsversuch
|
||||
my $attstr = "Attempts read data again ... ($act of $maxretries)";
|
||||
|
||||
my $livedata_content = decode_json($lc);
|
||||
for my $k (keys %$livedata_content) {
|
||||
@ -1833,28 +1837,28 @@ sub analyzeLivedata { #
|
||||
}
|
||||
|
||||
if ($new_val && $k !~ /__type/ix) {
|
||||
if($k =~ m/InfoMessages/x && $new_val =~ /.*login to SMA-Portal successful.*/) { ## no critic 'regular expression' # Regular expression without "/x" flag nicht anwenden !!!
|
||||
if($k =~ m/InfoMessages/x && $new_val =~ /login to SMA-Portal successful/) { ## no critic 'regular expression' # Regular expression without "/x" flag nicht anwenden !!!
|
||||
# Login war erfolgreich, Daten neu lesen
|
||||
Log3 $name, 3, "$name - Read portal data ...";
|
||||
$reread = 1;
|
||||
}
|
||||
if($k =~ m/WarningMessages/x && $new_val =~ /.*Updating of the live data was interrupted.*/) { ## no critic 'regular expression' # Regular expression without "/x" flag nicht anwenden !!!
|
||||
if($k =~ m/WarningMessages/x && $new_val =~ /Updating of the live data was interrupted/) { ## no critic 'regular expression' # Regular expression without "/x" flag nicht anwenden !!!
|
||||
Log3 $name, 3, "$name - Updating of the live data was interrupted. $attstr";
|
||||
$retry = 1;
|
||||
return ($reread,$retry);
|
||||
}
|
||||
if($k =~ m/WarningMessages/x && $new_val =~ /.*The current consumption could not be determined. The current purchased electricity is unknown.*/) { ## no critic 'regular expression' # Regular expression without "/x" flag nicht anwenden !!!
|
||||
if($k =~ m/WarningMessages/x && $new_val =~ /The current consumption could not be determined. The current purchased electricity is unknown/) { ## no critic 'regular expression' # Regular expression without "/x" flag nicht anwenden !!!
|
||||
Log3 $name, 3, "$name - The current consumption could not be determined. The current purchased electricity is unknown. $attstr";
|
||||
$retry = 1;
|
||||
return ($reread,$retry);
|
||||
}
|
||||
if($k =~ m/ErrorMessages/x && $new_val =~ /.*Communication with the Sunny Home Manager is currently not possible.*/) { ## no critic 'regular expression' # Regular expression without "/x" flag nicht anwenden !!!
|
||||
if($k =~ m/ErrorMessages/x && $new_val =~ /Communication with the Sunny Home Manager is currently not possible/) { ## no critic 'regular expression' # Regular expression without "/x" flag nicht anwenden !!!
|
||||
# Energiedaten konnten nicht ermittelt werden, Daten neu lesen mit Zeitverzögerung
|
||||
Log3 $name, 3, "$name - Communication with the Sunny Home Manager currently impossible. $attstr";
|
||||
$retry = 1;
|
||||
return ($reread,$retry);
|
||||
}
|
||||
if($k =~ m/ErrorMessages/x && $new_val =~ /.*The current data cannot be retrieved from the PV system. Check the cabling and configuration of the following energy meters.*/) { ## no critic 'regular expression' # Regular expression without "/x" flag nicht anwenden !!!
|
||||
if($k =~ m/ErrorMessages/x && $new_val =~ /The current data cannot be retrieved from the PV system. Check the cabling and configuration of the following energy meters/) { ## no critic 'regular expression' # Regular expression without "/x" flag nicht anwenden !!!
|
||||
# Energiedaten konnten nicht ermittelt werden, Daten neu lesen mit Zeitverzögerung
|
||||
Log3 $name, 3, "$name - Live data can't be retrieved. $attstr";
|
||||
$retry = 1;
|
||||
@ -1867,23 +1871,6 @@ sub analyzeLivedata { #
|
||||
return ($reread,$retry);
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Restart get Data
|
||||
################################################################
|
||||
sub retrygetdata {
|
||||
my ($hash) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $timeout = AttrVal($name, "timeout", 30);
|
||||
|
||||
my $getp = $hash->{HELPER}{GETTER};
|
||||
my $setp = $hash->{HELPER}{SETTER};
|
||||
|
||||
$hash->{HELPER}{RUNNING_PID} = BlockingCall("FHEM::SMAPortal::GetSetData", "$name|$getp|$setp", "FHEM::SMAPortal::ParseData", $timeout, "FHEM::SMAPortal::ParseAborted", $hash);
|
||||
$hash->{HELPER}{RUNNING_PID}{loglevel} = 5 if($hash->{HELPER}{RUNNING_PID}); # Forum #77057
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Timestamp korrigieren
|
||||
################################################################
|
||||
@ -2832,12 +2819,6 @@ return;
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<li><b> set <name> delCookieFile </b> </li>
|
||||
The active cookie will be deleted.
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<li><b> set <name> <consumer name> <on | off | auto> </b> </li>
|
||||
If the attribute "detailLevel" is set to 3 or higher, consumer data are fetched from the SMA Sunny Portal.
|
||||
@ -2870,12 +2851,6 @@ return;
|
||||
<ul>
|
||||
<br>
|
||||
<ul>
|
||||
<a name="cookielifetime"></a>
|
||||
<li><b>cookielifetime <Sekunden> </b><br>
|
||||
Validity period of a received Cookie. <br>
|
||||
(default: 3600)
|
||||
</li><br>
|
||||
|
||||
<a name="cookieLocation"></a>
|
||||
<li><b>cookieLocation <Pfad/File> </b><br>
|
||||
The path and filename of received Cookies. <br>
|
||||
@ -2909,12 +2884,6 @@ return;
|
||||
<li><b>disable</b><br>
|
||||
Deactivate/activate the device. </li><br>
|
||||
|
||||
<a name="getDataRetries"></a>
|
||||
<li><b>getDataRetries <Anzahl> </b><br>
|
||||
Maximal number of repetitions (get data) in case of no live data are fetched from the SMA Sunny Portal. <br>
|
||||
(default: 3)
|
||||
</li><br>
|
||||
|
||||
<a name="interval"></a>
|
||||
<li><b>interval <seconds> </b><br>
|
||||
Time interval for continuous data retrieval from the aus dem SMA Sunny Portal (default: 300 seconds). <br>
|
||||
@ -2926,6 +2895,13 @@ return;
|
||||
120 seconds although the SMA terms and conditions don't permit an automatic data fetch by computer programs.
|
||||
</li><br>
|
||||
|
||||
<a name="maxCallCycle"></a>
|
||||
<li><b>maxCallCycle <Anzahl> </b><br>
|
||||
Maximum number of retrieval cycles per data retrieval from the SMA Sunny Portal. Each retrieval cycle contains an
|
||||
internally defined number repeat requests. <br>
|
||||
(default: 5)
|
||||
</li><br>
|
||||
|
||||
<a name="showPassInLog"></a>
|
||||
<li><b>showPassInLog</b><br>
|
||||
If set, the used password will be displayed in Logfile output.
|
||||
@ -3049,12 +3025,6 @@ return;
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<li><b> set <name> delCookieFile </b> </li>
|
||||
Das aktive Cookie wird gelöscht.
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<ul>
|
||||
<li><b> set <name> <Verbrauchername> <on | off | auto> </b> </li>
|
||||
Ist das Atttribut detailLevel auf 3 oder höher gesetzt, werden Verbraucherdaten aus dem SMA Sunny Portal abgerufen.
|
||||
@ -3087,12 +3057,6 @@ return;
|
||||
<ul>
|
||||
<br>
|
||||
<ul>
|
||||
<a name="cookielifetime"></a>
|
||||
<li><b>cookielifetime <Sekunden> </b><br>
|
||||
Gültigkeitszeitraum für einen empfangenen Cookie. <br>
|
||||
(default: 3600)
|
||||
</li><br>
|
||||
|
||||
<a name="cookieLocation"></a>
|
||||
<li><b>cookieLocation <Pfad/File> </b><br>
|
||||
Angabe von Pfad und Datei zur Abspeicherung des empfangenen Cookies. <br>
|
||||
@ -3126,13 +3090,6 @@ return;
|
||||
<li><b>disable</b><br>
|
||||
Deaktiviert das Device. </li><br>
|
||||
|
||||
<a name="getDataRetries"></a>
|
||||
<li><b>getDataRetries <Anzahl> </b><br>
|
||||
Maximale Anzahl von Wiederholungen (get data) für den Fall, dass keine Live-Daten aus dem SMA Sunny Portal geholt
|
||||
werden konnten. <br>
|
||||
(default: 3)
|
||||
</li><br>
|
||||
|
||||
<a name="interval"></a>
|
||||
<li><b>interval <Sekunden> </b><br>
|
||||
Zeitintervall zum kontinuierlichen Datenabruf aus dem SMA Sunny Portal (Default: 300 Sekunden). <br>
|
||||
@ -3144,6 +3101,13 @@ return;
|
||||
Intervall von 120 Sekunden obwohl lt. SMA AGB der automatische Datenabruf untersagt ist.
|
||||
</li><br>
|
||||
|
||||
<a name="maxCallCycle"></a>
|
||||
<li><b>maxCallCycle <Anzahl> </b><br>
|
||||
Maximale Anzahl Abrufzyklen pro Datenabruf aus dem SMA Sunny Portal. Jeder Abrufzyklus enthält eine intern festgelegte Zahl
|
||||
Abrufwiederholungen. <br>
|
||||
(default: 5)
|
||||
</li><br>
|
||||
|
||||
<a name="showPassInLog"></a>
|
||||
<li><b>showPassInLog</b><br>
|
||||
Wenn gesetzt, wird das verwendete Passwort im Logfile angezeigt.
|
||||
|
Loading…
x
Reference in New Issue
Block a user