diff --git a/fhem/contrib/DS_Starter/76_SMAPortal.pm b/fhem/contrib/DS_Starter/76_SMAPortal.pm
index f21da34c3..0b24bee4f 100644
--- a/fhem/contrib/DS_Starter/76_SMAPortal.pm
+++ b/fhem/contrib/DS_Starter/76_SMAPortal.pm
@@ -153,8 +153,12 @@ BEGIN {
);
}
+# Standardvariablen und Forward-Deklaration
+use vars qw($FW_ME); # webname (default is fhem), used by 97_GROUP/weblink
+
# Versions History intern
our %vNotesIntern = (
+ "2.1.0" => "07.06.2019 add informations about consumer switch and power state",
"2.0.0" => "03.06.2019 designed for SMAPortalSPG graphics device",
"1.8.0" => "27.05.2019 redesign of SMAPortal graphics by Wzut/XGuide ",
"1.7.1" => "01.05.2019 PortalAsHtml: use of colored svg-icons possible ",
@@ -340,6 +344,12 @@ sub DbLog_split($$) {
my $devhash = $defs{$device};
my ($reading, $value, $unit);
+ if($event =~ m/L3_.*_Power/) {
+ $event =~ /^L1_(.*)_Power:\s(.*)\s(.*)/;
+ $reading = "L1_$1_Power";
+ $value = $2;
+ $unit = $3;
+ }
if($event =~ m/L2_PlantPeakPower/) {
$event =~ /^L2_PlantPeakPower:\s(.*)\s(.*)/;
$reading = "L2_PlantPeakPower";
@@ -592,7 +602,7 @@ sub GetData($) {
my $hash = $defs{$name};
my ($livedata_content);
my $login_state = 0;
- my ($forecast_content,$weatherdata_content) = ("","");
+ my ($forecast_content,$weatherdata_content,$consumerlivedata_content) = ("","","");
my $useragent = AttrVal($name, "userAgent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)");
my $cookieLocation = AttrVal($name, "cookieLocation", "./log/mycookies.txt");
@@ -638,7 +648,20 @@ sub GetData($) {
if ($forecast_page->content =~ m/ForecastChartDataPoint/i) {
$forecast_content = $forecast_page->content;
- Log3 $name, 5, "$name - Forecast Data received:\n".Dumper decode_json($forecast_content);
+ Log3 $name, 5, "$name - Forecast data received:\n".Dumper decode_json($forecast_content);
+ }
+ }
+
+ # JSON Consumer Livedaten
+ if($dl > 2) {
+ Log3 $name, 4, "$name - Getting consumer live data now";
+
+ my $consumerlivedata = $ua->get('https://www.sunnyportal.com/Homan/ConsumerBalance/GetLiveProxyValues');
+ Log3 $name, 5, "$name - Return Code: ".$consumerlivedata->code;
+
+ if ($consumerlivedata->content =~ m/HoManConsumerLiveData/i) {
+ $consumerlivedata_content = $consumerlivedata->content;
+ Log3 $name, 5, "$name - Consumer live data received:\n".Dumper decode_json($consumerlivedata_content);
}
}
@@ -680,11 +703,12 @@ sub GetData($) {
my ($reread,$retry) = analivedat($hash,$livedata_content);
# Daten müssen als Einzeiler zurückgegeben werden
- $livedata_content = encode_base64($livedata_content,"");
- $forecast_content = encode_base64($forecast_content,"") if($forecast_content);
- $weatherdata_content = encode_base64($weatherdata_content,"") if($weatherdata_content);
+ $livedata_content = encode_base64($livedata_content,"");
+ $forecast_content = encode_base64($forecast_content,"") if($forecast_content);
+ $weatherdata_content = encode_base64($weatherdata_content,"") if($weatherdata_content);
+ $consumerlivedata_content = encode_base64($consumerlivedata_content,"") if($consumerlivedata_content);
-return "$name|$livedata_content|$forecast_content|$weatherdata_content|$login_state|$reread|$retry";
+return "$name|$livedata_content|$forecast_content|$weatherdata_content|$consumerlivedata_content|$login_state|$reread|$retry";
}
################################################################
@@ -698,13 +722,15 @@ sub ParseData($) {
my $ld_response = decode_base64($a[1]);
my $fd_response = decode_base64($a[2]) if($a[2]);
my $wd_response = decode_base64($a[3]) if($a[3]);
- my $login_state = $a[4];
- my $reread = $a[5];
- my $retry = $a[6];
+ my $cd_response = decode_base64($a[4]) if($a[4]);
+ my $login_state = $a[5];
+ my $reread = $a[6];
+ my $retry = $a[7];
- my $livedata_content = decode_json($ld_response);
- my $forecast_content = decode_json($fd_response) if($fd_response);
- my $weatherdata_content = decode_json($wd_response) if($wd_response);
+ my $livedata_content = decode_json($ld_response);
+ my $forecast_content = decode_json($fd_response) if($fd_response);
+ my $weatherdata_content = decode_json($wd_response) if($wd_response);
+ my $consumerlivedata_content = decode_json($cd_response) if($cd_response);
my $state = "ok";
@@ -797,6 +823,11 @@ sub ParseData($) {
extractConsumerData($hash,$forecast_content);
}
+ if ($consumerlivedata_content && $consumerlivedata_content !~ m/undefined/i) {
+ # Auswertung Consumer Live Daten
+ extractConsumerLiveData($hash,$consumerlivedata_content);
+ }
+
if ($weatherdata_content && $weatherdata_content !~ m/undefined/i) {
# Auswertung Wetterdaten
extractWeatherData($hash,$weatherdata_content);
@@ -810,7 +841,7 @@ sub ParseData($) {
if(!$hash->{HELPER}{RETRIES} && !$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";
+ Log3 ($name, 2, "$name - $state");
}
readingsBeginUpdate($hash);
@@ -1204,6 +1235,73 @@ sub extractConsumerData($$) {
return;
}
+################################################################
+## Auswertung Consumer Livedata
+################################################################
+sub extractConsumerLiveData($$) {
+ my ($hash,$clivedata) = @_;
+ my $name = $hash->{NAME};
+ my %consumers;
+ my ($key,$val,$i,$res);
+
+ my $dl = AttrVal($name, "detailLevel", 1);
+ if($dl <= 2) {
+ return;
+ }
+
+ readingsBeginUpdate($hash);
+
+ # allen Consumer Objekte die ID zuordnen
+ $i = 0;
+ foreach my $c (@{$clivedata->{'MeasurementData'}}) {
+ $consumers{"${i}_ConsumerName"} = encode("utf8", $c->{'DeviceName'} );
+ $consumers{"${i}_ConsumerOid"} = $c->{'Consume'}{'ConsumerOid'};
+ $consumers{"${i}_ConsumerLfd"} = $i;
+ my $cpower = $c->{'Consume'}{'Measurement'}; # aktueller Energieverbrauch in W
+ my $cn = $consumers{"${i}_ConsumerName"}; # Verbrauchername
+ $cn = substUmlauts($cn);
+
+ readingsBulkUpdate($hash, "L3_${cn}_Power", $cpower." W");
+
+ $i++;
+ }
+
+ if(%consumers && $clivedata->{'ParameterData'}) {
+ # es sind Daten zu den Verbrauchern vorhanden
+ # Kind: "Utc" ?
+ $i = 0;
+ foreach my $c (@{$clivedata->{'ParameterData'}}) {
+ my $tkind = $c->{'Parameters'}[0]{'Timestamp'}{'Kind'}; # Zeitart: Unspecified, Utc
+ # Log3 ($name, 1, "$name - $tkind");
+ my $GriSwStt = $c->{'Parameters'}[0]{'Value'}; # on: 1, off: 0
+ my $GriSwAuto = $c->{'Parameters'}[1]{'Value'}; # automatic = 1
+ my $OperationAutoEna = $c->{'Parameters'}[2]{'Value'}; # Automatic Betrieb erlaubt ?
+ my $ltchange = TimeAdjust($hash,$c->{'Parameters'}[0]{'Timestamp'}{'DateTime'},$tkind); # letzter Schaltzeitpunkt der Bluetooth-Steckdose (Verbraucher)
+ my $cn = $consumers{"${i}_ConsumerName"}; # Verbrauchername
+ $cn = substUmlauts($cn); # evtl. Umlaute im Verbrauchernamen ersetzen
+
+ if(!$GriSwStt && $GriSwAuto) {
+ $res = "off (automatic)";
+ } elsif (!$GriSwStt && !$GriSwAuto) {
+ $res = "off";
+ } elsif ($GriSwStt) {
+ $res = "on";
+ } else {
+ $res = "undefined";
+ }
+
+ readingsBulkUpdate($hash, "L3_${cn}_Switch", $res);
+ readingsBulkUpdate($hash, "L3_${cn}_SwitchLastTime", $ltchange);
+
+ $i++;
+ }
+ }
+
+ readingsEndUpdate($hash, 1);
+
+return;
+}
+
################################################################
# sortiert eine Liste von Versionsnummern x.x.x
# Schwartzian Transform and the GRT transform
@@ -1455,16 +1553,26 @@ sub PortalAsHtml ($$) {
return $ret;
}
- @pgCDev = split(',',AttrVal($wlname,"consumerList","")); # definierte Verbraucher ermitteln
+ @pgCDev = split(',',AttrVal($wlname,"consumerList","")); # definierte Verbraucher ermitteln
($legend_style, $legend) = split('_',AttrVal($wlname,'consumerLegend','icon_top'));
$legend = '' if(($legend_style eq 'none') || (!int(@pgCDev)));
if ($legend) {
foreach (@pgCDev) {
- my($txt,$im) = split(':',$_);
+ my($txt,$im) = split(':',$_); # $txt ist der Verbrauchername
+ my $swstate = ReadingsVal($name,"L3_".$txt."_Switch", "undef");
+ my $swicon = "";
+ if($swstate eq "off") {
+ $swicon = "
";
+ } elsif ($swstate eq "on") {
+ $swicon = "
";
+ } elsif ($swstate =~ /off.*automatic.*/i) {
+ $swicon = "
";
+ }
+
if ($legend_style eq 'icon') { # mögliche Umbruchstellen mit normalen Blanks vorsehen !
- $legend_txt .= $txt.' '.FW_makeImage($im).' ';
+ $legend_txt .= $txt.' '.FW_makeImage($im).' '.$swicon.' ';
} else {
my (undef,$co) = split('\@',$im);
$co = '#cccccc' if (!$co); # Farbe per default
@@ -2174,7 +2282,7 @@ return;