mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 12:49:34 +00:00
76_SMAPortal: new attr balanceDay, balanceMonth, balanceYear for statistics dataprovider, new set getData command, update button in header of Portal Graphics, minor code changes according PBP
git-svn-id: https://svn.fhem.de/fhem/trunk@22573 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
aad2f6bf5b
commit
0e58c690b4
@ -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_SMAPortal: new attr balanceDay, balanceMonth, balanceYear for
|
||||||
|
statistics dataprovider, new set getData command,
|
||||||
|
update button in header of Portal Graphics, minor
|
||||||
|
code changes according PBP
|
||||||
- change: 10_WS980: change conversion ration of w/m2 to 0.0079
|
- change: 10_WS980: change conversion ration of w/m2 to 0.0079
|
||||||
.- bugfix: 98_DOIFtools: improve popup position (Forum #113404)
|
.- bugfix: 98_DOIFtools: improve popup position (Forum #113404)
|
||||||
- bugfix: 48_BlinkCamera: videoDelete on new API and first TFA pin verify
|
- bugfix: 48_BlinkCamera: videoDelete on new API and first TFA pin verify
|
||||||
|
@ -71,6 +71,7 @@ BEGIN {
|
|||||||
CommandDeleteAttr
|
CommandDeleteAttr
|
||||||
CommandDeleteReading
|
CommandDeleteReading
|
||||||
CommandSet
|
CommandSet
|
||||||
|
CommandGet
|
||||||
defs
|
defs
|
||||||
delFromDevAttrList
|
delFromDevAttrList
|
||||||
delFromAttrList
|
delFromAttrList
|
||||||
@ -136,6 +137,8 @@ BEGIN {
|
|||||||
|
|
||||||
# Versions History intern
|
# Versions History intern
|
||||||
my %vNotesIntern = (
|
my %vNotesIntern = (
|
||||||
|
"3.4.0" => "09.08.2020 attr balanceDay, balanceMonth, balanceYear for data provider balanceDayData, balanceMonthData, balanceYearData ".
|
||||||
|
"set getData command, update button in header of PortalAsHtml, minor code changes according PBP",
|
||||||
"3.3.4" => "12.07.2020 fix break in header if attribute hourCount was reduced ",
|
"3.3.4" => "12.07.2020 fix break in header if attribute hourCount was reduced ",
|
||||||
"3.3.3" => "07.07.2020 change extractLiveData, minor fixes ",
|
"3.3.3" => "07.07.2020 change extractLiveData, minor fixes ",
|
||||||
"3.3.2" => "05.07.2020 change timeout calc, new reading lastSuccessTime ",
|
"3.3.2" => "05.07.2020 change timeout calc, new reading lastSuccessTime ",
|
||||||
@ -228,6 +231,12 @@ my %statkeys = ( # Statistikdaten auszulesende Schlüs
|
|||||||
AutarkyRate => 1,
|
AutarkyRate => 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
my %hset = ( # Hash der Set-Funktion
|
||||||
|
credentials => { fn => "_setCredentials" },
|
||||||
|
getData => { fn => "_setGetData" },
|
||||||
|
createPortalGraphic => { fn => "_setCreatePortalGraphic" },
|
||||||
|
);
|
||||||
|
|
||||||
my %mandatory; # Arbeitskopie von %stpl -> abzurufenden Datenprovider Stammdaten nach Login
|
my %mandatory; # Arbeitskopie von %stpl -> abzurufenden Datenprovider Stammdaten nach Login
|
||||||
my %subs; # Arbeitskopie von %stpl -> Festlegung abzurufenden Datenprovider
|
my %subs; # Arbeitskopie von %stpl -> Festlegung abzurufenden Datenprovider
|
||||||
my %stpl = ( # Ausgangstemplate Subfunktionen der Datenprovider
|
my %stpl = ( # Ausgangstemplate Subfunktionen der Datenprovider
|
||||||
@ -241,12 +250,12 @@ my %stpl = (
|
|||||||
consumerMonthData => { doit => 0, nohm => 1, level => 'L07', func => '_getConsumerMonthData' },
|
consumerMonthData => { doit => 0, nohm => 1, level => 'L07', func => '_getConsumerMonthData' },
|
||||||
consumerYearData => { doit => 0, nohm => 1, level => 'L08', func => '_getConsumerYearData' },
|
consumerYearData => { doit => 0, nohm => 1, level => 'L08', func => '_getConsumerYearData' },
|
||||||
plantLogbook => { doit => 0, nohm => 0, level => 'L09', func => '_getPlantLogbook' },
|
plantLogbook => { doit => 0, nohm => 0, level => 'L09', func => '_getPlantLogbook' },
|
||||||
balanceCurrentData => { doit => 0, nohm => 0, level => 'L10', func => '_getBalanceCurrentData' },
|
|
||||||
balanceDayData => { doit => 0, nohm => 0, level => 'L11', func => '_getBalanceDayData' },
|
balanceDayData => { doit => 0, nohm => 0, level => 'L11', func => '_getBalanceDayData' },
|
||||||
balanceMonthData => { doit => 0, nohm => 0, level => 'L12', func => '_getBalanceMonthData' },
|
balanceMonthData => { doit => 0, nohm => 0, level => 'L12', func => '_getBalanceMonthData' },
|
||||||
balanceYearData => { doit => 0, nohm => 0, level => 'L13', func => '_getBalanceYearData' },
|
balanceYearData => { doit => 0, nohm => 0, level => 'L13', func => '_getBalanceYearData' },
|
||||||
balanceTotalData => { doit => 0, nohm => 0, level => 'L14', func => '_getBalanceTotalData' },
|
balanceTotalData => { doit => 0, nohm => 0, level => 'L14', func => '_getBalanceTotalData' },
|
||||||
);
|
);
|
||||||
|
|
||||||
# Tags der verfügbaren Datenquellen
|
# Tags der verfügbaren Datenquellen
|
||||||
my @pd = qw( plantMasterData
|
my @pd = qw( plantMasterData
|
||||||
consumerMasterdata
|
consumerMasterdata
|
||||||
@ -286,7 +295,10 @@ sub Initialize {
|
|||||||
$hash->{SetFn} = \&Set;
|
$hash->{SetFn} = \&Set;
|
||||||
$hash->{GetFn} = \&Get;
|
$hash->{GetFn} = \&Get;
|
||||||
$hash->{DbLog_splitFn} = \&DbLog_split;
|
$hash->{DbLog_splitFn} = \&DbLog_split;
|
||||||
$hash->{AttrList} = "cookieLocation ".
|
$hash->{AttrList} = "balanceDay ".
|
||||||
|
"balanceMonth ".
|
||||||
|
"balanceYear ".
|
||||||
|
"cookieLocation ".
|
||||||
"disable:0,1 ".
|
"disable:0,1 ".
|
||||||
"interval ".
|
"interval ".
|
||||||
"noHomeManager:1,0 ".
|
"noHomeManager:1,0 ".
|
||||||
@ -360,7 +372,7 @@ sub Set { ## no critic 'complexity'
|
|||||||
my $opt = $a[1];
|
my $opt = $a[1];
|
||||||
my $prop = $a[2];
|
my $prop = $a[2];
|
||||||
my $prop1 = $a[3];
|
my $prop1 = $a[3];
|
||||||
my ($setlist,$success);
|
my $setlist;
|
||||||
my $ad = "";
|
my $ad = "";
|
||||||
|
|
||||||
return if(IsDisabled($name));
|
return if(IsDisabled($name));
|
||||||
@ -374,7 +386,8 @@ sub Set { ## no critic 'complexity'
|
|||||||
# erweiterte Setlist wenn Credentials gesetzt
|
# erweiterte Setlist wenn Credentials gesetzt
|
||||||
$setlist = "Unknown argument $opt, choose one of ".
|
$setlist = "Unknown argument $opt, choose one of ".
|
||||||
"credentials ".
|
"credentials ".
|
||||||
"createPortalGraphic:Generation,Consumption,Generation_Consumption,Differential "
|
"createPortalGraphic:Generation,Consumption,Generation_Consumption,Differential ".
|
||||||
|
"getData:noArg "
|
||||||
;
|
;
|
||||||
if($hash->{HELPER}{PLANTOID} && $hash->{HELPER}{CONSUMER}) {
|
if($hash->{HELPER}{PLANTOID} && $hash->{HELPER}{CONSUMER}) {
|
||||||
my $lfd = 0;
|
my $lfd = 0;
|
||||||
@ -392,19 +405,86 @@ sub Set { ## no critic 'complexity'
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($opt eq "credentials") {
|
if ($opt && $ad && $opt =~ /$ad/x) {
|
||||||
return "Credentials are incomplete, use username password" if (!$prop || !$prop1);
|
# Verbraucher schalten
|
||||||
($success) = setcredentials($hash,$prop,$prop1);
|
$hash->{HELPER}{GETTER} = "none";
|
||||||
|
$hash->{HELPER}{SETTER} = "$opt:$prop";
|
||||||
|
CallInfo($hash);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
my $params = {
|
||||||
|
hash => $hash,
|
||||||
|
name => $name,
|
||||||
|
opt => $opt,
|
||||||
|
prop => $prop,
|
||||||
|
prop1 => $prop1,
|
||||||
|
aref => \@a,
|
||||||
|
};
|
||||||
|
|
||||||
|
no strict "refs"; ## no critic 'NoStrict'
|
||||||
|
if($hset{$opt}) {
|
||||||
|
my $ret = "";
|
||||||
|
$ret = &{$hset{$opt}{fn}} ($params) if(defined &{$hset{$opt}{fn}});
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
use strict "refs";
|
||||||
|
|
||||||
|
return "$setlist";
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Setter credentials
|
||||||
|
# credentials speichern
|
||||||
|
################################################################
|
||||||
|
sub _setCredentials { ## no critic "not used"
|
||||||
|
my $paref = shift;
|
||||||
|
my $hash = $paref->{hash};
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $prop = $paref->{prop};
|
||||||
|
my $prop1 = $paref->{prop1};
|
||||||
|
|
||||||
|
return qq{Credentials are incomplete, use "set $name credentials <username> <password>"} if (!$prop || !$prop1);
|
||||||
|
my ($success) = setcredentials($hash,$prop,$prop1);
|
||||||
|
|
||||||
if($success) {
|
if($success) {
|
||||||
delcookiefile ($hash);
|
delcookiefile ($hash);
|
||||||
CallInfo($hash);
|
CallInfo($hash);
|
||||||
return "Username and Password saved successfully";
|
return "Username and Password saved successfully";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return "Error while saving Username / Password - see logfile for details";
|
return "Error while saving Username / Password - see logfile for details";
|
||||||
}
|
}
|
||||||
|
|
||||||
} elsif ($opt eq "createPortalGraphic") {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Setter getData
|
||||||
|
# identisch zu "get gata", Workaround um mit webCmd
|
||||||
|
# arbeiten zu können
|
||||||
|
################################################################
|
||||||
|
sub _setGetData { ## no critic "not used"
|
||||||
|
my $paref = shift;
|
||||||
|
my $name = $paref->{name};
|
||||||
|
|
||||||
|
CommandGet(undef, "$name data");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################
|
||||||
|
# Setter createPortalGraphic
|
||||||
|
# create createPortalGraphic devices
|
||||||
|
################################################################
|
||||||
|
sub _setCreatePortalGraphic { ## no critic "not used"
|
||||||
|
my $paref = shift;
|
||||||
|
my $hash = $paref->{hash};
|
||||||
|
my $name = $paref->{name};
|
||||||
|
my $prop = $paref->{prop};
|
||||||
|
|
||||||
if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
|
if (!$hash->{CREDENTIALS}) {return "Credentials of $name are not set - make sure you've set it with \"set $name credentials username password\"";}
|
||||||
my ($htmldev,$ret,$c,$type,$color2);
|
my ($htmldev,$ret,$c,$type,$color2);
|
||||||
|
|
||||||
@ -438,7 +518,7 @@ sub Set { ## no critic 'complexity'
|
|||||||
CommandAttr($hash->{CL},"$htmldev alias $c"); # Alias setzen
|
CommandAttr($hash->{CL},"$htmldev alias $c"); # Alias setzen
|
||||||
|
|
||||||
$c = qq{This device provides a praphical output of SMA Sunny Portal values.\n}.
|
$c = qq{This device provides a praphical output of SMA Sunny Portal values.\n}.
|
||||||
qq{It is important that a SMA Home Manager is installed. Otherwise no forecast data are privided by SMA!\n}.
|
qq{It is important that a SMA Home Manager is installed. Otherwise no forecast data are provided by SMA!\n}.
|
||||||
qq{The device "$name" needs to contain "forecastData" in attribute "providerLevel".\n}.
|
qq{The device "$name" needs to contain "forecastData" in attribute "providerLevel".\n}.
|
||||||
qq{The attribute "providerLevel" must also contain "consumerCurrentdata" if you want switch your consumer connectet to the SMA Home Manager.};
|
qq{The attribute "providerLevel" must also contain "consumerCurrentdata" if you want switch your consumer connectet to the SMA Home Manager.};
|
||||||
|
|
||||||
@ -474,18 +554,6 @@ sub Set { ## no critic 'complexity'
|
|||||||
CommandAttr($hash->{CL},"$htmldev room $room");
|
CommandAttr($hash->{CL},"$htmldev room $room");
|
||||||
|
|
||||||
return "SMA Portal Graphics device \"$htmldev\" created and assigned to room \"$room\".";
|
return "SMA Portal Graphics device \"$htmldev\" created and assigned to room \"$room\".";
|
||||||
|
|
||||||
} elsif ($opt && $ad && $opt =~ /$ad/x) {
|
|
||||||
# Verbraucher schalten
|
|
||||||
$hash->{HELPER}{GETTER} = "none";
|
|
||||||
$hash->{HELPER}{SETTER} = "$opt:$prop";
|
|
||||||
CallInfo($hash);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return "$setlist";
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
@ -532,37 +600,10 @@ return;
|
|||||||
###############################################################
|
###############################################################
|
||||||
sub DbLog_split {
|
sub DbLog_split {
|
||||||
my ($event, $device) = @_;
|
my ($event, $device) = @_;
|
||||||
my $devhash = $defs{$device};
|
|
||||||
my ($reading, $value, $unit);
|
my ($reading, $value, $unit);
|
||||||
|
|
||||||
if($event =~ m/[_\-fd]Consumption|Quote/x) {
|
if($event =~ /\s(Wh|W|kWh|%|h)$/xms) {
|
||||||
$event =~ /^L(.*):\s(.*)\s(.*)/x;
|
($reading, $value, $unit) = $event =~ /(.*):\s(.*)\s(.*)/x;
|
||||||
if($1) {
|
|
||||||
$reading = "L".$1;
|
|
||||||
$value = $2;
|
|
||||||
$unit = $3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($event =~ m/Power|PV|FeedIn|SelfSupply|Temperature|Total|Energy|Hour:|Hour(\d\d):/x) {
|
|
||||||
$event =~ /^L(.*):\s(.*)\s(.*)/x;
|
|
||||||
if($1) {
|
|
||||||
$reading = "L".$1;
|
|
||||||
$value = $2;
|
|
||||||
$unit = $3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($event =~ m/Next04Hours-IsConsumption|RestOfDay-IsConsumption|Tomorrow-IsConsumption|Battery/x) {
|
|
||||||
$event =~ /^L(.*):\s(.*)\s(.*)/x;
|
|
||||||
if($1) {
|
|
||||||
$reading = "L".$1;
|
|
||||||
$value = $2;
|
|
||||||
$unit = $3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($event =~ m/summary/x && $event =~ /(.*):\s(.*)\s(.*)/x) {
|
|
||||||
$reading = $1;
|
|
||||||
$value = $2;
|
|
||||||
$unit = $3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ($reading, $value, $unit);
|
return ($reading, $value, $unit);
|
||||||
@ -584,8 +625,7 @@ sub setcredentials {
|
|||||||
$len = scalar @key;
|
$len = scalar @key;
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$credstr = join "",
|
$credstr = join "",
|
||||||
map { $i = ($i + 1) % $len;
|
map { $i = ($i + 1) % $len; chr((ord($_) + $key[$i]) % 256) } split //, $credstr; ## no critic 'Map blocks';
|
||||||
chr((ord($_) + $key[$i]) % 256) } split //, $credstr;
|
|
||||||
# End Scramble-Routine
|
# End Scramble-Routine
|
||||||
|
|
||||||
$index = $hash->{TYPE}."_".$hash->{NAME}."_credentials";
|
$index = $hash->{TYPE}."_".$hash->{NAME}."_credentials";
|
||||||
@ -635,9 +675,7 @@ sub getcredentials {
|
|||||||
$len = scalar @key;
|
$len = scalar @key;
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$credstr = join "",
|
$credstr = join "",
|
||||||
map { $i = ($i + 1) % $len;
|
map { $i = ($i + 1) % $len; chr((ord($_) - $key[$i] + 256) % 256) } split //, $credstr; ## no critic 'Map blocks';
|
||||||
chr((ord($_) - $key[$i] + 256) % 256) }
|
|
||||||
split //, $credstr;
|
|
||||||
# Ende Descramble-Routine
|
# Ende Descramble-Routine
|
||||||
|
|
||||||
($username, $passwd) = split(":",decode_base64($credstr));
|
($username, $passwd) = split(":",decode_base64($credstr));
|
||||||
@ -693,11 +731,9 @@ sub Attr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($cmd eq "set") {
|
if ($cmd eq "set") {
|
||||||
if ($aName =~ m/interval/x) {
|
if ($aName eq "interval") {
|
||||||
unless ($aVal =~ /^\d+$/x) {return " The Value for $aName is not valid. Use only figures 0-9 !";}
|
unless ($aVal =~ /^\d+$/x) {return "The value for $aName is not valid. Use only figures 0-9 !";}
|
||||||
}
|
return qq{The interval must be >= 120 seconds or 0 if you don't want use automatic updates} if($aVal > 0 && $aVal < 120);
|
||||||
if($aName =~ m/interval/x) {
|
|
||||||
return qq{The interval must be >= 120 seconds or 0 if you don't want use automatic updates} if($aVal > 0 && $aVal < 30);
|
|
||||||
InternalTimer(gettimeofday()+1.0, "FHEM::SMAPortal::CallInfo", $hash, 0);
|
InternalTimer(gettimeofday()+1.0, "FHEM::SMAPortal::CallInfo", $hash, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -713,7 +749,7 @@ return;
|
|||||||
# $nr = 1 wenn Retry Zähler nicht zurückgesetzt werden soll
|
# $nr = 1 wenn Retry Zähler nicht zurückgesetzt werden soll
|
||||||
#
|
#
|
||||||
################################################################
|
################################################################
|
||||||
sub CallInfo {
|
sub CallInfo { ## no critic 'complexity'
|
||||||
my ($hash,$nc,$nr) = @_;
|
my ($hash,$nc,$nr) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
my $new;
|
my $new;
|
||||||
@ -768,6 +804,7 @@ sub CallInfo {
|
|||||||
Log3 ($name, 3, "$name - ################################################################");
|
Log3 ($name, 3, "$name - ################################################################");
|
||||||
Log3 ($name, 3, "$name - ### start new set/get data from SMA Sunny Portal ###");
|
Log3 ($name, 3, "$name - ### start new set/get data from SMA Sunny Portal ###");
|
||||||
Log3 ($name, 3, "$name - ################################################################");
|
Log3 ($name, 3, "$name - ################################################################");
|
||||||
|
Log3 ($name, 5, "$name - SMAPortal version: $hash->{HELPER}{VERSION}");
|
||||||
Log3 ($name, 4, "$name - calculated maximum cycles: $maxcycles");
|
Log3 ($name, 4, "$name - calculated maximum cycles: $maxcycles");
|
||||||
Log3 ($name, 4, "$name - calculated timeout: $timeout");
|
Log3 ($name, 4, "$name - calculated timeout: $timeout");
|
||||||
}
|
}
|
||||||
@ -1434,43 +1471,6 @@ sub _getForecastData { ## no critic "not used"
|
|||||||
return ($errstate,$state,$reread,$retry);
|
return ($errstate,$state,$reread,$retry);
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################
|
|
||||||
# Abruf Statistik Daten Day
|
|
||||||
# (anchorTime beachten !)
|
|
||||||
################################################################
|
|
||||||
sub _getBalanceCurrentData { ## no critic "not used"
|
|
||||||
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 ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
|
||||||
my $cts = fhemTimeLocal(0, 0, 0, $mday, $mon, $year);
|
|
||||||
my $offset = fhemTzOffset($cts);
|
|
||||||
my $anchort = int($cts + $offset); # anchorTime in UTC -> abzurufendes Datum
|
|
||||||
|
|
||||||
my $tab = 0; # Tab 0 -> Current, Tab 1 -> Tag , 2->Monat, 3->Jahr, 4->Gesamt
|
|
||||||
my %fields = ("Content-Type" => "application/json; charset=utf-8");
|
|
||||||
my $cont = qq{{"tabNumber":$tab,"anchorTime":$anchort}};
|
|
||||||
|
|
||||||
($errstate,$state) = __dispatchPost ({ name => $name,
|
|
||||||
ua => $ua,
|
|
||||||
call => 'https://www.sunnyportal.com/FixedPages/HoManEnergyRedesign.aspx/GetLegendWithValues',
|
|
||||||
tag => "balanceCurrentData",
|
|
||||||
state => $state,
|
|
||||||
fnaref => [ qw( extractStatisticData ) ],
|
|
||||||
fields => \%fields,
|
|
||||||
content => $cont,
|
|
||||||
addon => "Current",
|
|
||||||
daref => $daref
|
|
||||||
});
|
|
||||||
|
|
||||||
return ($errstate,$state,$reread,$retry);
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Abruf Statistik Daten Day
|
# Abruf Statistik Daten Day
|
||||||
# (anchorTime beachten !)
|
# (anchorTime beachten !)
|
||||||
@ -1484,8 +1484,35 @@ sub _getBalanceDayData { ## no critic "not used"
|
|||||||
|
|
||||||
my ($reread,$retry,$errstate) = (0,0,0);
|
my ($reread,$retry,$errstate) = (0,0,0);
|
||||||
|
|
||||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
my @bd = split /\s+/x ,AttrVal($name, "balanceDay", "current");
|
||||||
my $cts = fhemTimeLocal(0, 0, 0, $mday, $mon, $year);
|
|
||||||
|
for my $bal (@bd) {
|
||||||
|
my ($y,$m,$d);
|
||||||
|
my $addon = "Day";
|
||||||
|
$addon .= "_".$bal;
|
||||||
|
|
||||||
|
if($bal ne "current") {
|
||||||
|
($y,$m,$d) = $bal =~ /(\d{4})-(\d{2})-(\d{2})/x;
|
||||||
|
|
||||||
|
if(!$y || !$m || !$d) {
|
||||||
|
Log3 ($name, 2, qq{$name - The attribute "balanceDay" value "$bal" is ignored. A valid date with form "YYYY-MM-DD" is needed});
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
$y -= 1900;
|
||||||
|
$m -= 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
(undef,undef,undef,$d,$m,$y) = localtime(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
eval { timelocal(0, 0, 0, $d, $m, $y) } or do { $state = (split(" at", $@))[0];
|
||||||
|
$errstate = 1;
|
||||||
|
Log3($name, 2, "$name - ERROR - invalid date/time format in attribute 'balanceDay' detected: $state");
|
||||||
|
return ($errstate,$state,$reread,$retry);
|
||||||
|
};
|
||||||
|
|
||||||
|
my $cts = fhemTimeLocal(0, 0, 0, $d, $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
|
||||||
|
|
||||||
@ -1501,10 +1528,12 @@ sub _getBalanceDayData { ## no critic "not used"
|
|||||||
fnaref => [ qw( extractStatisticData ) ],
|
fnaref => [ qw( extractStatisticData ) ],
|
||||||
fields => \%fields,
|
fields => \%fields,
|
||||||
content => $cont,
|
content => $cont,
|
||||||
addon => "Day",
|
addon => $addon,
|
||||||
daref => $daref
|
daref => $daref
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return ($errstate,$state,$reread,$retry);
|
return ($errstate,$state,$reread,$retry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1521,8 +1550,36 @@ sub _getBalanceMonthData { ## no critic "not used"
|
|||||||
|
|
||||||
my ($reread,$retry,$errstate) = (0,0,0);
|
my ($reread,$retry,$errstate) = (0,0,0);
|
||||||
|
|
||||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
my @bd = split /\s+/x ,AttrVal($name, "balanceMonth", "current");
|
||||||
my $cts = fhemTimeLocal(0, 0, 0, $mday, $mon, $year);
|
|
||||||
|
for my $bal (@bd) {
|
||||||
|
my ($y,$m);
|
||||||
|
my $addon = "Month";
|
||||||
|
$addon .= "_".$bal;
|
||||||
|
|
||||||
|
if($bal ne "current") {
|
||||||
|
($y,$m) = $bal =~ /^(\d{4})-(\d{2})$/x;
|
||||||
|
|
||||||
|
if(!$y || !$m) {
|
||||||
|
Log3 ($name, 2, qq{$name - The attribute "balanceMonth" value "$bal" is ignored. A valid date with form "YYYY-MM" is needed});
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
$y -= 1900;
|
||||||
|
$m -= 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$m = (localtime(time))[4];
|
||||||
|
$y = (localtime(time))[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
eval { timelocal(0, 0, 0, 1, $m, $y) } or do { $state = (split(" at", $@))[0];
|
||||||
|
$errstate = 1;
|
||||||
|
Log3($name, 2, "$name - ERROR - invalid date/time format in attribute 'balanceMonth' detected: $state");
|
||||||
|
return ($errstate,$state,$reread,$retry);
|
||||||
|
};
|
||||||
|
|
||||||
|
my $cts = fhemTimeLocal(0, 0, 0, 1, $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
|
||||||
|
|
||||||
@ -1538,10 +1595,12 @@ sub _getBalanceMonthData { ## no critic "not used"
|
|||||||
fnaref => [ qw( extractStatisticData ) ],
|
fnaref => [ qw( extractStatisticData ) ],
|
||||||
fields => \%fields,
|
fields => \%fields,
|
||||||
content => $cont,
|
content => $cont,
|
||||||
addon => "Month",
|
addon => $addon,
|
||||||
daref => $daref
|
daref => $daref
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return ($errstate,$state,$reread,$retry);
|
return ($errstate,$state,$reread,$retry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1558,8 +1617,33 @@ sub _getBalanceYearData { ## no critic "not used"
|
|||||||
|
|
||||||
my ($reread,$retry,$errstate) = (0,0,0);
|
my ($reread,$retry,$errstate) = (0,0,0);
|
||||||
|
|
||||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
|
my @bd = split /\s+/x ,AttrVal($name, "balanceYear", "current");
|
||||||
my $cts = fhemTimeLocal(0, 0, 0, $mday, $mon, $year);
|
|
||||||
|
for my $bal (@bd) {
|
||||||
|
my $y;
|
||||||
|
my $addon = "Year";
|
||||||
|
$addon .= "_".$bal;
|
||||||
|
|
||||||
|
if($bal ne "current") {
|
||||||
|
($y) = $bal =~ /^(\d{4})$/x;
|
||||||
|
|
||||||
|
if(!$y) {
|
||||||
|
Log3 ($name, 2, qq{$name - The attribute "balanceYear" value "$bal" is ignored. A valid date with form "YYYY" is needed});
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
$y -= 1900;
|
||||||
|
} else {
|
||||||
|
$y = (localtime(time))[5];
|
||||||
|
}
|
||||||
|
|
||||||
|
eval { timelocal(0, 0, 0, 1, 1, $y) } or do { $state = (split(" at", $@))[0];
|
||||||
|
$errstate = 1;
|
||||||
|
Log3($name, 2, "$name - ERROR - invalid date/time format in attribute 'balanceYear' detected: $state");
|
||||||
|
return ($errstate,$state,$reread,$retry);
|
||||||
|
};
|
||||||
|
|
||||||
|
my $cts = fhemTimeLocal(0, 0, 0, 1, 1, $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
|
||||||
|
|
||||||
@ -1575,9 +1659,10 @@ sub _getBalanceYearData { ## no critic "not used"
|
|||||||
fnaref => [ qw( extractStatisticData ) ],
|
fnaref => [ qw( extractStatisticData ) ],
|
||||||
fields => \%fields,
|
fields => \%fields,
|
||||||
content => $cont,
|
content => $cont,
|
||||||
addon => "Year",
|
addon => $addon,
|
||||||
daref => $daref
|
daref => $daref
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return ($errstate,$state,$reread,$retry);
|
return ($errstate,$state,$reread,$retry);
|
||||||
}
|
}
|
||||||
@ -1858,6 +1943,13 @@ sub ___analyzeData { ## no critic 'complexity'
|
|||||||
|
|
||||||
$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)
|
||||||
|
if($jsonerror) {
|
||||||
|
$errstate = 1;
|
||||||
|
$state = "SMA Portal failure: "."Message -> ".$data->{Message}.",\nStackTrace -> ".$data->{StackTrace}.",\nExceptionType -> ".$data->{ExceptionType};
|
||||||
|
return ($reread,$retry,$errstate,$state);
|
||||||
|
}
|
||||||
|
|
||||||
if(ref $data eq "HASH") {
|
if(ref $data eq "HASH") {
|
||||||
for my $k (keys %{$data}) {
|
for my $k (keys %{$data}) {
|
||||||
my $val = $data->{$k};
|
my $val = $data->{$k};
|
||||||
@ -1995,12 +2087,6 @@ sub ParseData { ## no critic
|
|||||||
my $gc = ReadingsNum($name, "${ldlv}_GridConsumption", 0);
|
my $gc = ReadingsNum($name, "${ldlv}_GridConsumption", 0);
|
||||||
my $sum = $fi-$gc;
|
my $sum = $fi-$gc;
|
||||||
|
|
||||||
# if(!$errstate && $lddo && !$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");
|
|
||||||
# }
|
|
||||||
|
|
||||||
my $ts = strftime('%Y-%m-%d %H:%M:%S', localtime);
|
my $ts = strftime('%Y-%m-%d %H:%M:%S', localtime);
|
||||||
if(AttrVal("global", "language", "EN") eq "DE") {
|
if(AttrVal("global", "language", "EN") eq "DE") {
|
||||||
$ts = strftime('%d.%m.%Y %H:%M:%S', localtime);
|
$ts = strftime('%d.%m.%Y %H:%M:%S', localtime);
|
||||||
@ -2345,7 +2431,10 @@ return;
|
|||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
# Auswertung Statistic Daten
|
# Auswertung Statistic Daten
|
||||||
# $period = Current | Day | Month | Year
|
# $period = Day[_<date>] |
|
||||||
|
# Month[_<date>] |
|
||||||
|
# Year[_<date>] |
|
||||||
|
# Total
|
||||||
################################################################
|
################################################################
|
||||||
sub extractStatisticData {
|
sub extractStatisticData {
|
||||||
my $hash = shift;
|
my $hash = shift;
|
||||||
@ -3146,11 +3235,34 @@ sub PortalAsHtml {
|
|||||||
|
|
||||||
$header = "<table align=\"$hdrAlign\">";
|
$header = "<table align=\"$hdrAlign\">";
|
||||||
|
|
||||||
# Header Link + Status
|
# Header Link + Status + Update Button
|
||||||
if($hdrDetail eq "all" || $hdrDetail eq "statusLink") {
|
if($hdrDetail eq "all" || $hdrDetail eq "statusLink") {
|
||||||
my ($year, $month, $day, $hour, $min, $sec) = $lup =~ /(\d+)-(\d\d)-(\d\d)\s+(.*)/x;
|
my ($year, $month, $day, $time) = $lup =~ /(\d{4})-(\d{2})-(\d{2})\s+(.*)/x;
|
||||||
$lup = "$3.$2.$1 $4";
|
|
||||||
$header .= "<tr><td colspan=\"3\" align=\"left\"><b>".$dlink."</b></td><td colspan=\"4\" align=\"right\">(".$lupt." ".$lup.")</td></tr>";
|
if(AttrVal("global","language","EN") eq "DE") {
|
||||||
|
$lup = "$day.$month.$year $time";
|
||||||
|
} else {
|
||||||
|
$lup = "$year-$month-$day $time";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $cmdupdate = "\"FW_cmd('$FW_ME$FW_subdir?XHR=1&cmd=set $name getData')\""; # Update Button generieren
|
||||||
|
|
||||||
|
if ($ftui && $ftui eq "ftui") {
|
||||||
|
$cmdupdate = "\"ftui.setFhemStatus('set $name getData')\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $upstate = ReadingsVal($name,"state", "undef");
|
||||||
|
my $upicon = "<img src=\"$FW_ME/www/images/default/1px-spacer.png\">";
|
||||||
|
|
||||||
|
if ($upstate =~ /ok/ix) {
|
||||||
|
$upicon = "<a onClick=$cmdupdate><img src=\"$FW_ME/www/images/default/10px-kreis-gruen.png\"></a>";
|
||||||
|
} elsif ($upstate =~ /running/ix) {
|
||||||
|
$upicon = "<img src=\"$FW_ME/www/images/default/10px-kreis-gelb.png\"></a>";
|
||||||
|
} else {
|
||||||
|
$upicon = "<a onClick=$cmdupdate><img src=\"$FW_ME/www/images/default/10px-kreis-rot.png\"></a>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$header .= "<tr><td colspan=\"3\" align=\"left\"><b>".$dlink."</b></td><td colspan=\"3\" align=\"right\">(".$lupt." ".$lup.") ".$upicon."</td></tr>";
|
||||||
}
|
}
|
||||||
|
|
||||||
# Header Information pv
|
# Header Information pv
|
||||||
@ -3746,15 +3858,15 @@ sub SPGRefresh {
|
|||||||
my @rooms = split(",",$hash->{HELPER}{SPGROOM});
|
my @rooms = split(",",$hash->{HELPER}{SPGROOM});
|
||||||
for (@rooms) {
|
for (@rooms) {
|
||||||
my $room = $_;
|
my $room = $_;
|
||||||
{ map { FW_directNotify("FILTER=room=$room", "#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") }
|
{ map { FW_directNotify("FILTER=room=$room", "#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") } ## no critic 'void context';
|
||||||
}
|
}
|
||||||
} elsif ($pload && (!$hash->{HELPER}{SPGROOM} || $hash->{HELPER}{SPGDETAIL})) {
|
} elsif ($pload && (!$hash->{HELPER}{SPGROOM} || $hash->{HELPER}{SPGDETAIL})) {
|
||||||
# trifft zu bei Detailansicht oder im FLOORPLAN bzw. Dashboard oder wenn Seitenrefresh mit dem
|
# trifft zu bei Detailansicht oder im FLOORPLAN bzw. Dashboard oder wenn Seitenrefresh mit dem
|
||||||
# SMAPortalSPG-Attribut "forcePageRefresh" erzwungen wird
|
# SMAPortalSPG-Attribut "forcePageRefresh" erzwungen wird
|
||||||
{ map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") }
|
{ map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") } ## no critic 'void context';
|
||||||
} else {
|
} else {
|
||||||
if($fpr) {
|
if($fpr) {
|
||||||
{ map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") }
|
{ map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") } ## no critic 'void context';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3865,7 +3977,7 @@ return;
|
|||||||
<br>
|
<br>
|
||||||
<ul>
|
<ul>
|
||||||
<a name="createPortalGraphic"></a>
|
<a name="createPortalGraphic"></a>
|
||||||
<li><b> set <name> createPortalGraphic <Generation | Consumption | Generation_Consumption | Differential> </b> <br>
|
<li><b> createPortalGraphic <Generation | Consumption | Generation_Consumption | Differential> </b> <br>
|
||||||
Creates graphical devices to show the SMA Sunny Portal forecast data in several layouts.
|
Creates graphical devices to show the SMA Sunny Portal forecast data in several layouts.
|
||||||
The attribute "providerLevel" must contain "forecastData". <br>
|
The attribute "providerLevel" must contain "forecastData". <br>
|
||||||
With the <a href="#SMAPortalSPGattr">"attributes of the graphic device"</a> the appearance and coloration of the forecast
|
With the <a href="#SMAPortalSPGattr">"attributes of the graphic device"</a> the appearance and coloration of the forecast
|
||||||
@ -3875,18 +3987,26 @@ return;
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><b> set <name> credentials <username> <password> </b> </li>
|
<li><b> credentials <username> <password> </b> </li>
|
||||||
Set Username / Password used for the login into the SMA Sunny Portal.
|
Set Username / Password used for the login into the SMA Sunny Portal.
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<a name="consumer"></a>
|
<a name="consumer"></a>
|
||||||
<li><b> set <name> <consumer name> <on | off | auto> </b> <br>
|
<li><b> <consumer name> <on | off | auto> </b> <br>
|
||||||
Once consumer data are available, the consumer are shown in the Set and can be switched to on, off or the automatic mode (auto)
|
Once consumer data are available, the consumer are shown in the Set and can be switched to on, off or the automatic mode (auto)
|
||||||
that means the consumer are controlled by the Sunny Home Manager.
|
that means the consumer are controlled by the Sunny Home Manager.
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<a name="getData"></a>
|
||||||
|
<li><b> getData </b> <br>
|
||||||
|
Identical to the "get data" command. Simplifies the use of the attribute "webCmd" in the FHEMWEB.
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<br><br>
|
<br><br>
|
||||||
@ -3898,7 +4018,7 @@ return;
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<a name="data"></a>
|
<a name="data"></a>
|
||||||
<li><b> get <name> data </b> <br>
|
<li><b> data </b> <br>
|
||||||
This command fetch the data from the SMA Sunny Portal manually.
|
This command fetch the data from the SMA Sunny Portal manually.
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@ -3906,7 +4026,7 @@ return;
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<a name="storedCredentials"></a>
|
<a name="storedCredentials"></a>
|
||||||
<li><b> get <name> storedCredentials </b> <br>
|
<li><b> storedCredentials </b> <br>
|
||||||
The saved credentials are displayed in a popup window.
|
The saved credentials are displayed in a popup window.
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@ -3918,6 +4038,43 @@ return;
|
|||||||
<ul>
|
<ul>
|
||||||
<br>
|
<br>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
|
<a name="balanceDay"></a>
|
||||||
|
<li><b>balanceDay <YYYY-MM-DD> [current <YYYY-MM-DD> <YYYY-MM-DD> ...] </b><br>
|
||||||
|
Defines the days from which the data provider "balanceDayData" delivers the data. The day specifications are separated by
|
||||||
|
spaces, current = current day. <br>
|
||||||
|
(default: current day) <br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<b>Example:</b><br>
|
||||||
|
attr <name> balanceDay current 2020-08-07 2020-08-06 2020-08-05 <br>
|
||||||
|
</ul>
|
||||||
|
</li><br>
|
||||||
|
|
||||||
|
<a name="balanceMonth"></a>
|
||||||
|
<li><b>balanceMonth <YYYY-MM> [current <YYYY-MM> <YYYY-MM> ...] </b><br>
|
||||||
|
Defines from which months the data provider "balanceMonthData" delivers the data. The month specifications are separated by
|
||||||
|
spaces, current = current month. <br>
|
||||||
|
(default: current month) <br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<b>Example:</b><br>
|
||||||
|
attr <name> balanceMonth current 2019-07 2019-06 2019-05 <br>
|
||||||
|
</ul>
|
||||||
|
</li><br>
|
||||||
|
|
||||||
|
<a name="balanceYear"></a>
|
||||||
|
<li><b>balanceYear <YYYY> [current <YYYY> <YYYY> <YYYY> ...] </b><br>
|
||||||
|
Defines the years from which the data provider "balanceYearData" delivers the data. The year specifications are separated by
|
||||||
|
spaces, current = current year. <br>
|
||||||
|
(default: current year) <br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<b>Example:</b><br>
|
||||||
|
attr <name> balanceYear current 2019 2018 2017 <br>
|
||||||
|
</ul>
|
||||||
|
</li><br>
|
||||||
|
|
||||||
<a name="cookieLocation"></a>
|
<a name="cookieLocation"></a>
|
||||||
<li><b>cookieLocation <Pfad/File> </b><br>
|
<li><b>cookieLocation <Pfad/File> </b><br>
|
||||||
The path and filename of received Cookies. <br>
|
The path and filename of received Cookies. <br>
|
||||||
@ -3990,9 +4147,9 @@ return;
|
|||||||
<tr><td> <b>consumerMonthData</b> </td><td>- consumer data month are generated </td></tr>
|
<tr><td> <b>consumerMonthData</b> </td><td>- consumer data month are generated </td></tr>
|
||||||
<tr><td> <b>consumerYearData</b> </td><td>- consumer data year are generated </td></tr>
|
<tr><td> <b>consumerYearData</b> </td><td>- consumer data year are generated </td></tr>
|
||||||
<tr><td> <b>plantLogbook</b> </td><td>- the maximum of 25 most recent entries of the plant logbook are retrieved </td></tr>
|
<tr><td> <b>plantLogbook</b> </td><td>- the maximum of 25 most recent entries of the plant logbook are retrieved </td></tr>
|
||||||
<tr><td> <b>balanceDayData</b> </td><td>- Statistics data of the day are retrieved </td></tr>
|
<tr><td> <b>balanceDayData</b> </td><td>- Statistics data of the day are retrieved (see attribute <a href="#balanceDay">balanceDay</a>) </td></tr>
|
||||||
<tr><td> <b>balanceMonthData</b> </td><td>- Statistics data of the month are retrieved </td></tr>
|
<tr><td> <b>balanceMonthData</b> </td><td>- Statistics data of the month are retrieved (see attribute <a href="#balanceMonth">balanceMonth</a>) </td></tr>
|
||||||
<tr><td> <b>balanceYearData</b> </td><td>- Statistical data of the year are retrieved </td></tr>
|
<tr><td> <b>balanceYearData</b> </td><td>- Statistical data of the year are retrieved (see attribute <a href="#balanceYear">balanceYear</a>) </td></tr>
|
||||||
<tr><td> <b>balanceTotalData</b> </td><td>- Total statistics data are retrieved </td></tr>
|
<tr><td> <b>balanceTotalData</b> </td><td>- Total statistics data are retrieved </td></tr>
|
||||||
</table>
|
</table>
|
||||||
</ul>
|
</ul>
|
||||||
@ -4113,7 +4270,7 @@ return;
|
|||||||
<br>
|
<br>
|
||||||
<ul>
|
<ul>
|
||||||
<a name="createPortalGraphic"></a>
|
<a name="createPortalGraphic"></a>
|
||||||
<li><b> set <name> createPortalGraphic <Generation | Consumption | Generation_Consumption | Differential> </b> <br>
|
<li><b> createPortalGraphic <Generation | Consumption | Generation_Consumption | Differential> </b> <br>
|
||||||
Erstellt Devices zur grafischen Anzeige der SMA Sunny Portal Prognosedaten in verschiedenen Layouts.
|
Erstellt Devices zur grafischen Anzeige der SMA Sunny Portal Prognosedaten in verschiedenen Layouts.
|
||||||
Das Attribut "providerLevel" muss auf den Level "forecastData" enthalten. <br>
|
Das Attribut "providerLevel" muss auf den Level "forecastData" enthalten. <br>
|
||||||
Mit den <a href="#SMAPortalSPGattr">"Attributen des Grafikdevices"</a> können Erscheinungsbild und
|
Mit den <a href="#SMAPortalSPGattr">"Attributen des Grafikdevices"</a> können Erscheinungsbild und
|
||||||
@ -4124,15 +4281,23 @@ return;
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<a name="credentials"></a>
|
<a name="credentials"></a>
|
||||||
<li><b> set <name> credentials <username> <password> </b> <br>
|
<li><b> credentials <username> <password> </b> <br>
|
||||||
Setzt Username / Passwort zum Login in das SMA Sunny Portal.
|
Setzt Username / Passwort zum Login in das SMA Sunny Portal.
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<a name="getData"></a>
|
||||||
|
<li><b> getData </b> <br>
|
||||||
|
Identisch zum "get data" Befehl. Vereinfacht die Benutzung des Attributs "webCmd" im FHEMWEB.
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<br>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<a name="Verbrauchername"></a>
|
<a name="Verbrauchername"></a>
|
||||||
<li><b> set <name> <Verbrauchername> <on | off | auto> </b> <br>
|
<li><b> <Verbrauchername> <on | off | auto> </b> <br>
|
||||||
Es werden die an den SMA Sunny Homemanager angeschlossene Verbraucher (Bluetooth Steckdosen) angeboten sobald sie vom
|
Es werden die an den SMA Sunny Homemanager angeschlossene Verbraucher (Bluetooth Steckdosen) angeboten sobald sie vom
|
||||||
Modul erkannt wurden.
|
Modul erkannt wurden.
|
||||||
Sobald diese Daten vorliegen, werden die vorhandenen Verbraucher im Set angezeigt und können eingeschaltet, ausgeschaltet
|
Sobald diese Daten vorliegen, werden die vorhandenen Verbraucher im Set angezeigt und können eingeschaltet, ausgeschaltet
|
||||||
@ -4150,7 +4315,7 @@ return;
|
|||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
<a name="data"></a>
|
<a name="data"></a>
|
||||||
<li><b> get <name> data </b> <br>
|
<li><b> data </b> <br>
|
||||||
Mit diesem Befehl werden die Daten aus dem SMA Sunny Portal manuell abgerufen.
|
Mit diesem Befehl werden die Daten aus dem SMA Sunny Portal manuell abgerufen.
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@ -4158,7 +4323,7 @@ return;
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<a name="storedCredentials"></a>
|
<a name="storedCredentials"></a>
|
||||||
<li><b> get <name> storedCredentials </b> <br>
|
<li><b> storedCredentials </b> <br>
|
||||||
Die gespeicherten Anmeldeinformationen (Credentials) werden in einem Popup als Klartext angezeigt.
|
Die gespeicherten Anmeldeinformationen (Credentials) werden in einem Popup als Klartext angezeigt.
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@ -4171,6 +4336,43 @@ return;
|
|||||||
<ul>
|
<ul>
|
||||||
<br>
|
<br>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
||||||
|
<a name="balanceDay"></a>
|
||||||
|
<li><b>balanceDay <YYYY-MM-DD> [current <YYYY-MM-DD> <YYYY-MM-DD> ...] </b><br>
|
||||||
|
Legt fest, von welchen Tagen der Datenprovider "balanceDayData" die Daten liefert. Die Tagesangaben werden durch Leerzeichen
|
||||||
|
getrennt, current = aktueller Tag. <br>
|
||||||
|
(default: aktueller Tag) <br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<b>Beispiel:</b><br>
|
||||||
|
attr <name> balanceDay current 2020-08-07 2020-08-06 2020-08-05 <br>
|
||||||
|
</ul>
|
||||||
|
</li><br>
|
||||||
|
|
||||||
|
<a name="balanceMonth"></a>
|
||||||
|
<li><b>balanceMonth <YYYY-MM> [current <YYYY-MM> <YYYY-MM> ...] </b><br>
|
||||||
|
Legt fest, von welchen Monaten der Datenprovider "balanceMonthData" die Daten liefert. Die Monatsangaben werden durch Leerzeichen
|
||||||
|
getrennt, current = aktueller Monat. <br>
|
||||||
|
(default: aktueller Monat) <br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<b>Beispiel:</b><br>
|
||||||
|
attr <name> balanceMonth current 2019-07 2019-06 2019-05 <br>
|
||||||
|
</ul>
|
||||||
|
</li><br>
|
||||||
|
|
||||||
|
<a name="balanceYear"></a>
|
||||||
|
<li><b>balanceYear <YYYY> [current <YYYY> <YYYY> <YYYY> ...] </b><br>
|
||||||
|
Legt fest, von welchen Jahren der Datenprovider "balanceYearData" die Daten liefert. Die Jahresangaben werden durch Leerzeichen
|
||||||
|
getrennt, current = aktuelles Jahr. <br>
|
||||||
|
(default: aktuelles Jahr) <br><br>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<b>Beispiel:</b><br>
|
||||||
|
attr <name> balanceYear current 2019 2018 2017 <br>
|
||||||
|
</ul>
|
||||||
|
</li><br>
|
||||||
|
|
||||||
<a name="cookieLocation"></a>
|
<a name="cookieLocation"></a>
|
||||||
<li><b>cookieLocation <Pfad/File> </b><br>
|
<li><b>cookieLocation <Pfad/File> </b><br>
|
||||||
Angabe von Pfad und Datei zur Abspeicherung des empfangenen Cookies. <br>
|
Angabe von Pfad und Datei zur Abspeicherung des empfangenen Cookies. <br>
|
||||||
@ -4244,9 +4446,9 @@ return;
|
|||||||
<tr><td> <b>consumerMonthData</b> </td><td>- Verbraucherdaten Monat werden erzeugt </td></tr>
|
<tr><td> <b>consumerMonthData</b> </td><td>- Verbraucherdaten Monat werden erzeugt </td></tr>
|
||||||
<tr><td> <b>consumerYearData</b> </td><td>- Verbraucherdaten Jahr werden erzeugt </td></tr>
|
<tr><td> <b>consumerYearData</b> </td><td>- Verbraucherdaten Jahr werden erzeugt </td></tr>
|
||||||
<tr><td> <b>plantLogbook</b> </td><td>- die maximal 25 aktuellsten Einträge des Anlagenlogbuchs werden abgerufen </td></tr>
|
<tr><td> <b>plantLogbook</b> </td><td>- die maximal 25 aktuellsten Einträge des Anlagenlogbuchs werden abgerufen </td></tr>
|
||||||
<tr><td> <b>balanceDayData</b> </td><td>- Statistikdaten des Tages werden abgerufen </td></tr>
|
<tr><td> <b>balanceDayData</b> </td><td>- Statistikdaten des Tages werden abgerufen (siehe Attribut <a href="#balanceDay">balanceDay</a>) </td></tr>
|
||||||
<tr><td> <b>balanceMonthData</b> </td><td>- Statistikdaten des Monats werden abgerufen </td></tr>
|
<tr><td> <b>balanceMonthData</b> </td><td>- Statistikdaten des Monats werden abgerufen (siehe Attribut <a href="#balanceMonth">balanceMonth</a>) </td></tr>
|
||||||
<tr><td> <b>balanceYearData</b> </td><td>- Statistikdaten des Jahres werden abgerufen </td></tr>
|
<tr><td> <b>balanceYearData</b> </td><td>- Statistikdaten des Jahres werden abgerufen (siehe Attribut <a href="#balanceYear">balanceYear</a>) </td></tr>
|
||||||
<tr><td> <b>balanceTotalData</b> </td><td>- Statistikdaten Gesamt werden abgerufen </td></tr>
|
<tr><td> <b>balanceTotalData</b> </td><td>- Statistikdaten Gesamt werden abgerufen </td></tr>
|
||||||
</table>
|
</table>
|
||||||
</ul>
|
</ul>
|
||||||
|
Loading…
Reference in New Issue
Block a user