mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-21 20:06:18 +00:00
76_SMAPortal: some improvements, avoid login trouble in some cases
git-svn-id: https://svn.fhem.de/fhem/trunk@23096 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
caa9a2fa65
commit
a799e9e99f
@ -1,5 +1,6 @@
|
|||||||
# 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.
|
||||||
|
- change: 76_SMAPortal: some improvements, avoid login trouble in some cases
|
||||||
- bugfix: 89_FULLY: Fixed JSON decoding error and password handling
|
- bugfix: 89_FULLY: Fixed JSON decoding error and password handling
|
||||||
- bugfix: 98_backup.pm: log output include files (forum #115478)
|
- bugfix: 98_backup.pm: log output include files (forum #115478)
|
||||||
- bugfix: 93_Log2Syslog: avoid Logfile archive execution done in rare cases
|
- bugfix: 93_Log2Syslog: avoid Logfile archive execution done in rare cases
|
||||||
|
@ -137,6 +137,8 @@ BEGIN {
|
|||||||
|
|
||||||
# Versions History intern
|
# Versions History intern
|
||||||
my %vNotesIntern = (
|
my %vNotesIntern = (
|
||||||
|
"3.6.2" => "03.11.2020 new function _detailViewOn to Switch the detail view on SMA energy balance site, new default userAgent ",
|
||||||
|
"3.6.1" => "31.10.2020 adjust anchortime in getBalanceMonthData ",
|
||||||
"3.6.0" => "11.10.2020 new relative time arguments for attr balanceDay, balanceMonth, balanceYear, new attribute useRelativeNames ",
|
"3.6.0" => "11.10.2020 new relative time arguments for attr balanceDay, balanceMonth, balanceYear, new attribute useRelativeNames ",
|
||||||
"3.5.0" => "10.10.2020 _getLiveData: get data from Dashboard instead of homemanager site depending of attr noHomeManager, ".
|
"3.5.0" => "10.10.2020 _getLiveData: get data from Dashboard instead of homemanager site depending of attr noHomeManager, ".
|
||||||
"extract OperationHealth key, new attr cookieDelete ",
|
"extract OperationHealth key, new attr cookieDelete ",
|
||||||
@ -236,9 +238,9 @@ my %statkeys = ( # Statistikdaten auszulesende Schlüs
|
|||||||
);
|
);
|
||||||
|
|
||||||
my %hset = ( # Hash der Set-Funktion
|
my %hset = ( # Hash der Set-Funktion
|
||||||
credentials => { fn => "_setCredentials" },
|
credentials => { fn => \&_setCredentials },
|
||||||
getData => { fn => "_setGetData" },
|
getData => { fn => \&_setGetData },
|
||||||
createPortalGraphic => { fn => "_setCreatePortalGraphic" },
|
createPortalGraphic => { fn => \&_setCreatePortalGraphic },
|
||||||
);
|
);
|
||||||
|
|
||||||
my %mandatory; # Arbeitskopie von %stpl -> abzurufenden Datenprovider Stammdaten nach Login
|
my %mandatory; # Arbeitskopie von %stpl -> abzurufenden Datenprovider Stammdaten nach Login
|
||||||
@ -277,7 +279,7 @@ my @pd = qw( plantMasterData
|
|||||||
plantLogbook
|
plantLogbook
|
||||||
);
|
);
|
||||||
|
|
||||||
|
my $defuseragent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:77.0) Gecko/20100101 Firefox/77.0";
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
# SMAPortal Initialize
|
# SMAPortal Initialize
|
||||||
@ -313,7 +315,7 @@ sub Initialize {
|
|||||||
"showPassInLog:1,0 ".
|
"showPassInLog:1,0 ".
|
||||||
"userAgent ".
|
"userAgent ".
|
||||||
"useRelativeNames:1,0 ".
|
"useRelativeNames:1,0 ".
|
||||||
"verbose5Data:multiple-strict,none,loginData,".$v5d." ".
|
"verbose5Data:multiple-strict,none,loginData,detailViewSwitch,".$v5d." ".
|
||||||
$readingFnAttributes;
|
$readingFnAttributes;
|
||||||
|
|
||||||
eval { FHEM::Meta::InitMod( __FILE__, $hash ) }; ## no critic 'eval' # für Meta.pm (https://forum.fhem.de/index.php/topic,97589.0.html)
|
eval { FHEM::Meta::InitMod( __FILE__, $hash ) }; ## no critic 'eval' # für Meta.pm (https://forum.fhem.de/index.php/topic,97589.0.html)
|
||||||
@ -371,7 +373,7 @@ return;
|
|||||||
###############################################################
|
###############################################################
|
||||||
# SMAPortal Set
|
# SMAPortal Set
|
||||||
###############################################################
|
###############################################################
|
||||||
sub Set { ## no critic 'complexity'
|
sub Set {
|
||||||
my ($hash, @a) = @_;
|
my ($hash, @a) = @_;
|
||||||
return "\"set X\" needs at least an argument" if ( @a < 2 );
|
return "\"set X\" needs at least an argument" if ( @a < 2 );
|
||||||
my $name = $a[0];
|
my $name = $a[0];
|
||||||
@ -427,14 +429,12 @@ sub Set { ## no critic 'complexity'
|
|||||||
prop1 => $prop1,
|
prop1 => $prop1,
|
||||||
aref => \@a,
|
aref => \@a,
|
||||||
};
|
};
|
||||||
|
|
||||||
no strict "refs"; ## no critic 'NoStrict'
|
if($hset{$opt} && defined &{$hset{$opt}{fn}}) {
|
||||||
if($hset{$opt}) {
|
my $ret = q{};
|
||||||
my $ret = "";
|
$ret = &{$hset{$opt}{fn}} ($params);
|
||||||
$ret = &{$hset{$opt}{fn}} ($params) if(defined &{$hset{$opt}{fn}});
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
use strict "refs";
|
|
||||||
|
|
||||||
return "$setlist";
|
return "$setlist";
|
||||||
}
|
}
|
||||||
@ -890,7 +890,7 @@ sub GetSetData { ## no critic 'complexity'
|
|||||||
my ($string) = @_;
|
my ($string) = @_;
|
||||||
my ($name,$getp,$setp) = split("\\|",$string);
|
my ($name,$getp,$setp) = split("\\|",$string);
|
||||||
my $hash = $defs{$name};
|
my $hash = $defs{$name};
|
||||||
my $useragent = AttrVal($name, "userAgent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)");
|
my $useragent = AttrVal($name, "userAgent", $defuseragent);
|
||||||
my $cookieLocation = AttrVal($name, "cookieLocation", "./log/".$name."_cookie.txt");
|
my $cookieLocation = AttrVal($name, "cookieLocation", "./log/".$name."_cookie.txt");
|
||||||
my $v5d = AttrVal($name, "verbose5Data", "none");
|
my $v5d = AttrVal($name, "verbose5Data", "none");
|
||||||
my $verbose = AttrVal($name, "verbose", 3);
|
my $verbose = AttrVal($name, "verbose", 3);
|
||||||
@ -947,7 +947,7 @@ sub GetSetData { ## no critic 'complexity'
|
|||||||
if($errstate) {
|
if($errstate) {
|
||||||
$st = encode_base64 ( $state,"");
|
$st = encode_base64 ( $state,"");
|
||||||
return "$name|0|0|$errstate|$getp|$setp|$st";
|
return "$name|0|0|$errstate|$getp|$setp|$st";
|
||||||
}
|
}
|
||||||
|
|
||||||
### die Anlagen Asset Daten auslesen (Funktionen aus %mandatory mit doit=1)
|
### die Anlagen Asset Daten auslesen (Funktionen aus %mandatory mit doit=1)
|
||||||
### (Hash %mandatory ist leer wenn kein SMA Home Manager eingesetzt)
|
### (Hash %mandatory ist leer wenn kein SMA Home Manager eingesetzt)
|
||||||
@ -1004,13 +1004,22 @@ sub GetSetData { ## no critic 'complexity'
|
|||||||
#############################
|
#############################
|
||||||
if($getp ne "none") {
|
if($getp ne "none") {
|
||||||
|
|
||||||
|
_detailViewOn ({ name => $name,
|
||||||
|
ua => $ua,
|
||||||
|
state => $state,
|
||||||
|
daref => \@da
|
||||||
|
}); # Detailanzeige einschalten
|
||||||
|
|
||||||
for my $k (keys %{$subs{$name}}) {
|
for my $k (keys %{$subs{$name}}) {
|
||||||
next if(!$subs{$name}{$k}{doit});
|
next if(!$subs{$name}{$k}{doit});
|
||||||
|
|
||||||
no strict "refs"; ## no critic 'NoStrict'
|
no strict "refs"; ## no critic 'NoStrict'
|
||||||
|
|
||||||
if(!defined &{$subs{$name}{$k}{func}}) {
|
if(!defined &{$subs{$name}{$k}{func}}) {
|
||||||
Log3 ($name, 2, qq{$name - WARNING - data provider '$k' call function '$subs{$name}{$k}{func}' doesn't exist and is ignored });
|
Log3 ($name, 2, qq{$name - WARNING - data provider '$k' call function '$subs{$name}{$k}{func}' doesn't exist and is ignored });
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
($errstate,$state,$reread,$retry) = &{$subs{$name}{$k}{func}} ({ name => $name,
|
($errstate,$state,$reread,$retry) = &{$subs{$name}{$k}{func}} ({ name => $name,
|
||||||
ua => $ua,
|
ua => $ua,
|
||||||
state => $state,
|
state => $state,
|
||||||
@ -1525,6 +1534,8 @@ sub _getBalanceDayData { ## no critic "not used"
|
|||||||
my $state = $paref->{state};
|
my $state = $paref->{state};
|
||||||
my $daref = $paref->{daref}; # Referenz zum Datenarray
|
my $daref = $paref->{daref}; # Referenz zum Datenarray
|
||||||
|
|
||||||
|
# _detailViewOn ($paref); # Detailanzeige einschalten
|
||||||
|
|
||||||
my ($reread,$retry,$errstate) = (0,0,0);
|
my ($reread,$retry,$errstate) = (0,0,0);
|
||||||
|
|
||||||
my @bd = split /\s+/x ,AttrVal($name, "balanceDay", "current");
|
my @bd = split /\s+/x ,AttrVal($name, "balanceDay", "current");
|
||||||
@ -1607,6 +1618,8 @@ sub _getBalanceMonthData { ## no critic "not used"
|
|||||||
my $state = $paref->{state};
|
my $state = $paref->{state};
|
||||||
my $daref = $paref->{daref}; # Referenz zum Datenarray
|
my $daref = $paref->{daref}; # Referenz zum Datenarray
|
||||||
|
|
||||||
|
# _detailViewOn ($paref); # Detailanzeige einschalten
|
||||||
|
|
||||||
my ($reread,$retry,$errstate) = (0,0,0);
|
my ($reread,$retry,$errstate) = (0,0,0);
|
||||||
|
|
||||||
my @bd = split /\s+/x ,AttrVal($name, "balanceMonth", "current");
|
my @bd = split /\s+/x ,AttrVal($name, "balanceMonth", "current");
|
||||||
@ -1657,16 +1670,18 @@ sub _getBalanceMonthData { ## no critic "not used"
|
|||||||
};
|
};
|
||||||
$addon = createDateAddon ($params);
|
$addon = createDateAddon ($params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $dim = daysInMonth ($m+1, $y+1900); # errechnet wieviel Tage der gegebene Monat hat
|
||||||
|
|
||||||
eval { timelocal(0, 0, 0, 1, $m, $y) } or do { $state = (split(" at", $@))[0];
|
eval { timelocal(0, 0, 0, $dim, $m, $y) } or do { $state = (split(" at", $@))[0];
|
||||||
$errstate = 1;
|
$errstate = 1;
|
||||||
Log3($name, 2, "$name - ERROR - invalid date/time format in attribute 'balanceMonth' detected: $state");
|
Log3($name, 2, "$name - ERROR - invalid date/time format in attribute 'balanceMonth' detected: $state");
|
||||||
return ($errstate,$state,$reread,$retry);
|
return ($errstate,$state,$reread,$retry);
|
||||||
};
|
};
|
||||||
|
|
||||||
Log3 ($name, 4, "$name - retrieve $tag ".($y+1900)."-".sprintf "%02d", $m+1);
|
Log3 ($name, 4, "$name - retrieve $tag ".($y+1900)."-".sprintf "%02d", $m+1);
|
||||||
|
|
||||||
my $cts = fhemTimeLocal(0, 0, 0, 1, $m, $y);
|
my $cts = fhemTimeLocal(0, 0, 0, $dim, $m, $y);
|
||||||
my $offset = fhemTzOffset($cts);
|
my $offset = fhemTzOffset($cts);
|
||||||
my $anchort = int($cts + $offset); # anchorTime in UTC -> abzurufendes Datum
|
my $anchort = int($cts + $offset); # anchorTime in UTC -> abzurufendes Datum
|
||||||
|
|
||||||
@ -1701,6 +1716,8 @@ sub _getBalanceYearData { ## no critic "not used"
|
|||||||
my $state = $paref->{state};
|
my $state = $paref->{state};
|
||||||
my $daref = $paref->{daref}; # Referenz zum Datenarray
|
my $daref = $paref->{daref}; # Referenz zum Datenarray
|
||||||
|
|
||||||
|
# _detailViewOn ($paref); # Detailanzeige einschalten
|
||||||
|
|
||||||
my ($reread,$retry,$errstate) = (0,0,0);
|
my ($reread,$retry,$errstate) = (0,0,0);
|
||||||
|
|
||||||
my @bd = split /\s+/x ,AttrVal($name, "balanceYear", "current");
|
my @bd = split /\s+/x ,AttrVal($name, "balanceYear", "current");
|
||||||
@ -1848,6 +1865,38 @@ sub _getPlantLogbook { ## no critic "not used"
|
|||||||
return ($errstate,$state,$reread,$retry);
|
return ($errstate,$state,$reread,$retry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Detailanzeige einschalten
|
||||||
|
# vor dem eigentlichen Datenabruf
|
||||||
|
################################################################
|
||||||
|
sub _detailViewOn {
|
||||||
|
my $paref = shift;
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $ua = $paref->{ua}; # LWP Useragent
|
||||||
|
my $state = $paref->{state};
|
||||||
|
my $daref = $paref->{daref}; # Referenz zum Datenarray
|
||||||
|
|
||||||
|
my ($reread,$retry,$errstate) = (0,0,0);
|
||||||
|
|
||||||
|
my $tag = "detailViewSwitch";
|
||||||
|
my %fields = ("Content-Type" => "application/json; charset=utf-8");
|
||||||
|
my $cont = qq{{"showDetailMode":true}};
|
||||||
|
|
||||||
|
($errstate,$state) = __dispatchPost ({ name => $name,
|
||||||
|
ua => $ua,
|
||||||
|
call => 'https://www.sunnyportal.com/FixedPages/HoManEnergyRedesign.aspx/UpdateDisplayOption',
|
||||||
|
tag => $tag,
|
||||||
|
state => $state,
|
||||||
|
fnaref => [ qw( extractHelperData ) ],
|
||||||
|
fields => \%fields,
|
||||||
|
content => $cont,
|
||||||
|
addon => "",
|
||||||
|
daref => $daref
|
||||||
|
});
|
||||||
|
|
||||||
|
return ($errstate,$state,$reread,$retry);
|
||||||
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Dispatcher GET
|
# Dispatcher GET
|
||||||
################################################################
|
################################################################
|
||||||
@ -1915,10 +1964,11 @@ sub __dispatchPost {
|
|||||||
call => $call,
|
call => $call,
|
||||||
tag => $tag,
|
tag => $tag,
|
||||||
fields => $fields,
|
fields => $fields,
|
||||||
content => $cont,
|
content => $cont
|
||||||
});
|
});
|
||||||
|
|
||||||
($reread,$retry,$errstate,$state) = ___analyzeData ({ name => $name,
|
($reread,$retry,$errstate,$state) = ___analyzeData ({ name => $name,
|
||||||
|
ua => $ua,
|
||||||
errstate => $errstate,
|
errstate => $errstate,
|
||||||
state => $state,
|
state => $state,
|
||||||
data => $data
|
data => $data
|
||||||
@ -2025,28 +2075,35 @@ sub ___analyzeData { ## no critic 'complexity'
|
|||||||
my $name = $paref->{name};
|
my $name = $paref->{name};
|
||||||
my $errstate = $paref->{errstate};
|
my $errstate = $paref->{errstate};
|
||||||
my $state = $paref->{state};
|
my $state = $paref->{state};
|
||||||
|
my $ua = $paref->{ua};
|
||||||
my $ad = $paref->{data};
|
my $ad = $paref->{data};
|
||||||
my $hash = $defs{$name};
|
my $hash = $defs{$name};
|
||||||
my ($reread,$retry) = (0,0);
|
my ($reread,$retry) = (0,0);
|
||||||
my $data = "";
|
my $data = "";
|
||||||
|
|
||||||
my $v5d = AttrVal($name, "verbose5Data", "none");
|
my $v5d = AttrVal($name, "verbose5Data", "none");
|
||||||
my $ad_content = encode("utf8", $ad->decoded_content);
|
my $ad_content = encode("utf8", $ad->decoded_content);
|
||||||
my $act = $hash->{HELPER}{RETRIES}; # Index aktueller Wiederholungsversuch
|
my $act = $hash->{HELPER}{RETRIES}; # Index aktueller Wiederholungsversuch
|
||||||
my $attstr = "Attempts read data again in $sleepretry s ... ($act of $maxretries)"; # Log vorbereiten
|
my $attstr = "Attempts read data again in $sleepretry s ... ($act of $maxretries)"; # Log vorbereiten
|
||||||
|
|
||||||
my $wm1e = qq{Updating of the live data was interrupted};
|
my $wm1e = qq{Updating of the live data was interrupted};
|
||||||
my $wm1d = qq{Die Aktualisierung der Live-Daten wurde unterbrochen};
|
my $wm1d = qq{Die Aktualisierung der Live-Daten wurde unterbrochen};
|
||||||
my $wm2e = qq{The current consumption could not be determined. The current purchased electricity is unknown};
|
my $wm2e = qq{The current consumption could not be determined. The current purchased electricity is unknown};
|
||||||
my $wm2d = qq{Der aktuelle Verbrauch konnte nicht ermittelt werden. Der aktuelle Netzbezug ist unbekannt};
|
my $wm2d = qq{Der aktuelle Verbrauch konnte nicht ermittelt werden. Der aktuelle Netzbezug ist unbekannt};
|
||||||
my $em1e = qq{Communication with the Sunny Home Manager is currently not possible};
|
my $em1e = qq{Communication with the Sunny Home Manager is currently not possible};
|
||||||
my $em1d = qq{Die Kommunikation mit dem Sunny Home Manager ist zurzeit nicht m};
|
my $em1d = qq{Die Kommunikation mit dem Sunny Home Manager ist zurzeit nicht m};
|
||||||
my $em2e = qq{The current data cannot be retrieved from the PV system. Check the cabling and configuration};
|
my $em2e = qq{The current data cannot be retrieved from the PV system. Check the cabling and configuration};
|
||||||
my $em2d = qq{Die aktuellen Daten .*? nicht von der Anlage abgerufen werden.*? Sie die Verkabelung und Konfiguration};
|
my $em2d = qq{Die aktuellen Daten .*? nicht von der Anlage abgerufen werden.*? Sie die Verkabelung und Konfiguration};
|
||||||
|
|
||||||
|
___extractCookie ({ ua => $ua,
|
||||||
|
data => $ad,
|
||||||
|
name => $name,
|
||||||
|
});
|
||||||
|
|
||||||
$data = eval{decode_json($ad_content)} or do { $data = $ad_content };
|
$data = eval{decode_json($ad_content)} or do { $data = $ad_content };
|
||||||
|
|
||||||
my $jsonerror = $ad->header('Jsonerror') // ""; # Portal meldet keine Verarbeitung des Reaquests möglich (z.B. Jahr 0000 zur Auswertung angefordert)
|
my $jsonerror = $ad->header('Jsonerror') // ""; # Portal meldet keine Verarbeitung des Reaquests möglich (z.B. Jahr 0000 zur Auswertung angefordert)
|
||||||
|
|
||||||
if($jsonerror) {
|
if($jsonerror) {
|
||||||
$errstate = 1;
|
$errstate = 1;
|
||||||
$state = "SMA Portal failure: "."Message -> ".$data->{Message}.",\nStackTrace -> ".$data->{StackTrace}.",\nExceptionType -> ".$data->{ExceptionType};
|
$state = "SMA Portal failure: "."Message -> ".$data->{Message}.",\nStackTrace -> ".$data->{StackTrace}.",\nExceptionType -> ".$data->{ExceptionType};
|
||||||
@ -2117,10 +2174,26 @@ sub ___analyzeData { ## no critic 'complexity'
|
|||||||
return ($reread,$retry,$errstate,$state);
|
return ($reread,$retry,$errstate,$state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Cookie Daten analysieren & extrahieren
|
||||||
|
# Die extract_cookies()-Methode sucht im HTTP::Response-Objekt,
|
||||||
|
# das als Argument übergeben wird, nach Set-Cookie: und
|
||||||
|
# Set-Cookie2: Headern.
|
||||||
|
################################################################
|
||||||
|
sub ___extractCookie {
|
||||||
|
my $paref = shift;
|
||||||
|
my $ua = $paref->{ua};
|
||||||
|
my $data = $paref->{data}; # empfangene Rohdaten
|
||||||
|
|
||||||
|
eval { $ua->cookie_jar->extract_cookies($data) } or return;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
## Verarbeitung empfangene Daten, setzen Readings
|
## Verarbeitung empfangene Daten, setzen Readings
|
||||||
################################################################
|
################################################################
|
||||||
sub ParseData { ## no critic 'complexity'
|
sub ParseData {
|
||||||
my $string = shift;
|
my $string = shift;
|
||||||
my @a = split("\\|",$string);
|
my @a = split("\\|",$string);
|
||||||
my $hash = $defs{$a[0]};
|
my $hash = $defs{$a[0]};
|
||||||
@ -2770,6 +2843,7 @@ sub extractConsumerMasterdata {
|
|||||||
my $clivedata = shift;
|
my $clivedata = shift;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my %consumers;
|
my %consumers;
|
||||||
|
my %hcon;
|
||||||
my ($i,$res);
|
my ($i,$res);
|
||||||
|
|
||||||
Log3 ($name, 4, "$name - ##### extracting consumer master data #### ");
|
Log3 ($name, 4, "$name - ##### extracting consumer master data #### ");
|
||||||
@ -2789,22 +2863,22 @@ sub extractConsumerMasterdata {
|
|||||||
next if(!$cn);
|
next if(!$cn);
|
||||||
$cn = replaceJunkSigns($cn);
|
$cn = replaceJunkSigns($cn);
|
||||||
|
|
||||||
$hash->{HELPER}{CONSUMER}{$i}{DeviceName} = $cn;
|
$hcon{$i}{DeviceName} = $cn;
|
||||||
$hash->{HELPER}{CONSUMER}{$i}{ConsumerOid} = $consumers{"${i}_ConsumerOid"};
|
$hcon{$i}{ConsumerOid} = $consumers{"${i}_ConsumerOid"};
|
||||||
$hash->{HELPER}{CONSUMER}{$i}{SerialNumber} = $c->{'SerialNumber'};
|
$hcon{$i}{SerialNumber} = $c->{'SerialNumber'};
|
||||||
$hash->{HELPER}{CONSUMER}{$i}{SUSyID} = $c->{'SUSyID'};
|
$hcon{$i}{SUSyID} = $c->{'SUSyID'};
|
||||||
|
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($hash->{HELPER}{CONSUMER}) {
|
for my $key (keys %hcon) {
|
||||||
for my $key (keys %{$hash->{HELPER}{CONSUMER}}) {
|
for my $parname (keys %{$hcon{$key}}) {
|
||||||
for my $parname (keys %{$hash->{HELPER}{CONSUMER}{$key}}) {
|
my $val = $hcon{$key}{$parname};
|
||||||
my $val = $hash->{HELPER}{CONSUMER}{$key}{$parname};
|
|
||||||
next if(!defined $val);
|
next if(!$val);
|
||||||
Log3 ($name, 4, "$name - CONSUMER master data: $key -> $parname = $val");
|
|
||||||
BlockingInformParent("FHEM::SMAPortal::setFromBlocking", [$name, "NULL", "CONSUMER:$key:$parname:$val"], 1);
|
Log3 ($name, 4, "$name - CONSUMER master data: $key -> $parname = $val");
|
||||||
}
|
BlockingInformParent("FHEM::SMAPortal::setFromBlocking", [$name, "NULL", "CONSUMER:$key:$parname:$val"], 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2952,6 +3026,34 @@ sub extractConsumerHistData { #
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Auswertung Daten aus Hilfsroutinen
|
||||||
|
################################################################
|
||||||
|
sub extractHelperData {
|
||||||
|
my $hash = shift;
|
||||||
|
my $daref = shift; # Referenz zum Datenarray
|
||||||
|
my $jdata = shift; # empfangene JSON-Daten
|
||||||
|
my $addon = shift; # ein optionales AddOn
|
||||||
|
my $tag = shift; # Kennzeichen der abgerufenen Daten/ der Abrufroutine
|
||||||
|
|
||||||
|
my $name = $hash->{NAME};
|
||||||
|
my $sd;
|
||||||
|
|
||||||
|
Log3 ($name, 4, "$name - extracting Helper data ");
|
||||||
|
|
||||||
|
my $data = eval{decode_json($jdata)} or do { Log3 ($name, 2, "$name - ERROR - can't decode JSON Data");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if(ref $data eq "HASH") {
|
||||||
|
while (my ($k,$v) = each %$data) {
|
||||||
|
push @$daref, "$tag:$v";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# sortiert eine Liste von Versionsnummern x.x.x
|
# sortiert eine Liste von Versionsnummern x.x.x
|
||||||
# Schwartzian Transform and the GRT transform
|
# Schwartzian Transform and the GRT transform
|
||||||
@ -3174,6 +3276,21 @@ sub delReadingFromBlocking {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# errechnet wieviel Tage ein gegebener Monat eines
|
||||||
|
# bestimmten Jahres hat
|
||||||
|
# $m: realer Monat (1..12)
|
||||||
|
# $y: reales Jahr (2020)
|
||||||
|
################################################################
|
||||||
|
sub daysInMonth {
|
||||||
|
my $m = shift;
|
||||||
|
my $y = shift;
|
||||||
|
|
||||||
|
my $dim = $m-2?30+($m*3%7<4):28+!($y%4||$y%400*!($y%100));
|
||||||
|
|
||||||
|
return $dim;
|
||||||
|
}
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Timestamp korrigieren
|
# Timestamp korrigieren
|
||||||
################################################################
|
################################################################
|
||||||
|
Loading…
x
Reference in New Issue
Block a user