";
+ $ret .= "";
+ if(!$hash) {
+ $ret .= "Device \"$name\" doesn't exist !";
+ } elsif (!defined($defs{$wlname})) {
+ $ret .= "Graphic device \"$wlname\" doesn't exist !";
+ } elsif ($dl != 4) {
+ $ret .= "The attribute \"detailLevel\" of device \"$name\" has to be set to level \"4\" !";
+ } elsif (!defined $pv0) {
+ # Vorschlag : Das und level 4 data weiter unten stehen so verloren auf der Seite
+ # man könnte die beiden Meldungen noch in eine mini packen
+ # und mit dem Wert aus attr beamHeight in etwa auf die spätere Ausǵabe vorformatieren
+ $ret .= "Awaiting level 2 data ...";
+ } elsif (!defined $pv1) {
+ $ret .= "Awaiting level 4 data ...";
+ }
- @pgCDev = split(',',AttrVal($wlname,"consumers","")); # definierte Verbraucher ermitteln
- ($legend_style, $legend) = split('_',AttrVal($wlname,'legend_style','icon_top'));
+ $ret .= "";
+ $ret .= "";
+ $ret .= " ";
+ return $ret;
+ }
+
+ @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)));
@@ -1438,38 +1470,37 @@ sub PortalAsHtml ($$) {
$legend_txt .= $txt.' '.FW_makeImage($im).' ';
} else {
my (undef,$co) = split('\@',$im);
- $co = '#cccccc' if (!$co); # irgendeine Farbe per default
+ $co = '#cccccc' if (!$co); # Farbe per default
$legend_txt .= ''.$txt.' '; # hier auch Umbruch erlauben
}
}
}
# Parameter f. Anzeige extrahieren
- $maxhours = AttrNum($wlname, 'hours', 24);
- $hourstyle = AttrVal($wlname, 'hour_style', undef);
- $colorv = AttrVal($wlname, 'color', undef);
- $colorc = AttrVal($wlname, 'color2', '000000'); # schwarz wenn keine Userauswahl;
- $icon = AttrVal($wlname, 'icon', undef);
- $html_start = AttrVal($wlname, 'html_start', undef); # beliebige HTML Strings die vor dem Weblink ausgegeben werden
- $html_end = AttrVal($wlname, 'html_end', undef); # beliebige HTML Strings die nach dem Weblink ausgegeben werden
+ $maxhours = AttrNum($wlname, 'hourCount', 24);
+ $hourstyle = AttrVal($wlname, 'hourStyle', undef);
+ $colorv = AttrVal($wlname, 'beamColor', undef);
+ $colorc = AttrVal($wlname, 'beamColor2', '000000'); # schwarz wenn keine Userauswahl;
+ $icon = AttrVal($wlname, 'suggestIcon', undef);
+ $html_start = AttrVal($wlname, 'htmlStart', undef); # beliebige HTML Strings die vor der Grafik ausgegeben werden
+ $html_end = AttrVal($wlname, 'htmlEnd', undef); # beliebige HTML Strings die nach der Grafik ausgegeben werden
- $type = AttrVal($wlname, 'type', 'pv');
- $kw = AttrVal($wlname, 'W/kW', 'W');
+ $type = AttrVal($wlname, 'layoutType', 'pv');
+ $kw = AttrVal($wlname, 'W/kW', 'W');
- $height = AttrNum($wlname, 'height', 200);
- $width = AttrNum($wlname, 'width', 6); # zu klein ist nicht problematisch
- $w = $width*$maxhours; # gesammte Breite der Ausgabe , WetterIcon brauch ca.34px
- $fsize = AttrNum($wlname, 'font_size', 24);
- $maxVal = AttrNum($wlname, 'maxPV', 0); # dyn. Anpassung der Balkenhöhe oder statisch ?
+ $height = AttrNum($wlname, 'beamHeight', 200);
+ $width = AttrNum($wlname, 'beamWidth', 6); # zu klein ist nicht problematisch
+ $w = $width*$maxhours; # gesammte Breite der Ausgabe , WetterIcon braucht ca. 34px
+ $fsize = AttrNum($wlname, 'spaceSize', 24);
+ $maxVal = AttrNum($wlname, 'maxPV', 0); # dyn. Anpassung der Balkenhöhe oder statisch ?
- $show_night = AttrNum($wlname, 'show_night', 0); # alle Balken (Spalten) anzeigen ?
- $show_diff = AttrVal($wlname, 'show_diff', 'no'); # zusätzliche Anzeige $di{} in allen Typen
- $weather = AttrNum($wlname, 'show_weather', 1);
- $colorw = AttrVal($wlname, 'weather_color',undef);
+ $show_night = AttrNum($wlname, 'showNight', 0); # alle Balken (Spalten) anzeigen ?
+ $show_diff = AttrVal($wlname, 'showDiff', 'no'); # zusätzliche Anzeige $di{} in allen Typen
+ $weather = AttrNum($wlname, 'showWeather', 1);
+ $colorw = AttrVal($wlname, 'weatherColor', undef);
- $wlalias = AttrVal($wlname, 'alias', $wlname);
- $header = (AttrNum($wlname, 'show_header', 1)) ? 1 : undef;
- $wlname = (AttrNum($wlname, 'show_link', 1) == 1) ? $wlname : '';
+ $wlalias = AttrVal($wlname, 'alias', $wlname);
+ $header = (AttrNum($wlname, 'showHeader', 1)) ? 1 : undef;
# Icon Erstellung, mit @ ergänzen falls einfärben
# Beispiel mit Farbe: $icon = FW_makeImage('light_light_dim_100.svg@green');
@@ -1503,7 +1534,7 @@ sub PortalAsHtml ($$) {
# Headerzeile generieren
my $alias = AttrVal($name, "alias", "SMA Sunny Portal"); # Linktext als Aliasname oder "SMA Sunny Portal"
my $dlink = "$alias";
- $wllink = ($wlname) ? "$wlalias" : '';
+ my $lup = ReadingsTimestamp($name, "state", "0000-00-00 00:00:00"); # letzte Updatezeit
# Da der Header relativ viele Zeichen hat, müssen Stellen erlaubt werden an denen automatisch umgebrochen werden kann.
# Sonst sind schmale Ausgaben nicht von den Balken bzw. deren Anzahl abhängig, sondern allein durch die Breite des Headers bestimmt
@@ -1511,19 +1542,22 @@ sub PortalAsHtml ($$) {
if ($header) {
my ($h1,$h2);
if(AttrVal("global","language","EN") eq "DE") {
- $h1 = "Prognosedaten[pv] - nächsten 4 Stunden: $pv4h/h / Rest des Tages: $pvRe/h / Morgen: $pvTo/h";
- $h2 = "Prognosedaten[co] - nächsten 4 Stunden: $co4h/h / Rest des Tages: $coRe/h / Morgen: $coTo/h";
+ $h1 = "Prognose [pv] - nächste 4 Stunden: $pv4h/h / Rest des Tages: $pvRe/h / Morgen: $pvTo/h";
+ $h2 = "Prognose [co] - nächste 4 Stunden: $co4h/h / Rest des Tages: $coRe/h / Morgen: $coTo/h";
+ my ($year, $month, $day, $hour, $min, $sec) = $lup =~ /(\d+)-(\d\d)-(\d\d)\s+(.*)/;
+ $lup = "$3.$2.$1 $4";
} else {
- $h1 = "forecast data[pv] - next 4 hours: $pv4h/h / rest of day: $pvRe / tomorrow: $pvTo/h";
- $h2 = "forecast data[co] - next 4 hours: $co4h/h / rest of day: $coRe / tomorrow: $coTo/h";
+ $h1 = "forecast data [pv] - next 4 hours: $pv4h/h / rest of day: $pvRe / tomorrow: $pvTo/h";
+ $h2 = "forecast data [co] - next 4 hours: $co4h/h / rest of day: $coRe / tomorrow: $coTo/h";
}
+ $lup = " (last update: $lup)";
if ($type eq 'pv') {
- $header = $dlink.' '.$h1;
+ $header = $dlink.' '.$lup.' '.$h1;
} elsif ($type eq 'co') {
- $header = $dlink.' '.$h2;
+ $header = $dlink.' '.$lup.' '.$h2;
} else {
- $header = $dlink.' '.$h1.' '.$h2;
+ $header = $dlink.' '.$lup.' '.$h1.' '.$h2;
}
}
@@ -1539,7 +1573,7 @@ sub PortalAsHtml ($$) {
if(AttrVal("global","language","EN") eq "DE") {
(undef,undef,undef,$t{0}) = ReadingsVal($name,"L2_ThisHour_Time",'0') =~ m/(\d{2}).(\d{2}).(\d{4})\s(\d{2})/;
} else {
- (undef,undef,undef,$t{0}) = ReadingsVal($name,"L2_ThisHour_Time",'0') =~ m/(\d{4})-(\d{2})-(\d{2})\s(\d{2})/;
+ (undef,undef,undef,$t{0}) = ReadingsVal($name,"L2_ThisHour_Time",'0') =~ m/(\d{4})-(\d{2})-(\d{2})\s(\d{2})/;
}
$t{0} = int($t{0}); # zum Rechnen Integer ohne führende Null
@@ -1568,13 +1602,13 @@ sub PortalAsHtml ($$) {
$end = int($end);
#correct the hour for accurate display
- if ($start < $t{0}) { #consumption seems to be tomorrow
+ if ($start < $t{0}) { # consumption seems to be tomorrow
$start = 23-$t{0}+$start;
} else {
$start -= $t{0};
}
- if ($end < $t{0}) { #consumption seems to be tomorrow
+ if ($end < $t{0}) { # consumption seems to be tomorrow
$end = 23-$t{0}+$end;
} else {
$end -= $t{0};
@@ -1590,8 +1624,8 @@ sub PortalAsHtml ($$) {
$maxVal = (!$maxVal) ? $pv{0} : $maxVal; # Startwert wenn kein Wert bereits via attr vorgegeben ist
$maxCon = $co{0}; # für Typ co
- $maxDif = $di{0}; # für Typ dif
- $minDif = $di{0}; # für Typ dif
+ $maxDif = $di{0}; # für Typ diff
+ $minDif = $di{0}; # für Typ diff
foreach $i (1..$maxhours-1) {
$pv{$i} = ReadingsNum($name,"L4_NextHour".sprintf("%02d",$i)."_PvMeanPower",0); # Erzeugung
@@ -1617,8 +1651,6 @@ sub PortalAsHtml ($$) {
$t{$i} = int($t{$i}); # keine führende 0
}
- return "Awaiting level 4 data ... " if(!defined $pv{1});
-
######################################
# Tabellen Ausgabe erzeugen
@@ -1626,11 +1658,12 @@ sub PortalAsHtml ($$) {
# lässt sich durch einbetten in eine zusätzliche Table roomoverview eindämmen
# Die Tabelle ist recht schmal angelegt, aber nur so lassen sich Umbrüche erzwingen
- $ret = $html_start if (defined($html_start));
+ $ret = "";
+ $ret .= $html_start if (defined($html_start));
$ret .= "";
- $ret .= "$wllink | ";
+ $ret .= " ";
$ret .= "";
- $ret .= "\n"; # das \n erleichtert das lesen der debug Quelltextausgabe
+ $ret .= "\n"; # das \n erleichtert das Lesen der debug Quelltextausgabe
if ($header) { # Header ausgeben
$ret .= "";
@@ -1672,7 +1705,7 @@ sub PortalAsHtml ($$) {
foreach $i (0..$maxhours-1) {
$val = formatVal6($di{$i},$kw,$we{$i});
- $val = ($di{$i} < 0) ? ''.$val.'' : '+'.$val; # Geschmacksfrage, negativ Zahlen in Fettschrift
+ $val = ($di{$i} < 0) ? ''.$val.'' : '+'.$val; # negativ Zahlen in Fettschrift
$ret .= "$val | ";
}
$ret .= " | "; # freier Platz am Ende
@@ -1683,7 +1716,7 @@ sub PortalAsHtml ($$) {
foreach $i (0..$maxhours-1) {
# Achtung Falle, Division by Zero möglich,
# maxVal kann gerade bei kleineren maxhours Ausgaben in der Nacht leicht auf 0 fallen
- $height = 200 if (!$height); # Fallback, sollte eigentlich nicht vorkommen, ausser der User setzt das auf 0
+ $height = 200 if (!$height); # Fallback, sollte eigentlich nicht vorkommen, außer der User setzt es auf 0
$maxVal = 1 if (!$maxVal);
$maxCon = 1 if (!$maxCon);
@@ -1736,14 +1769,14 @@ sub PortalAsHtml ($$) {
$px_neg = $height - $px_pos; # Rundungsfehler vermeiden
} else { # Dynamische hoch/runter Verschiebung der Null-Linie
- if ($minDif >= 0 ) { # keine negativen Balken vorhanden, die positiven bekommen den gesammten Raum
+ if ($minDif >= 0 ) { # keine negativen Balken vorhanden, die Positiven bekommen den gesammten Raum
$px_neg = 0;
$px_pos = $height;
} else {
if ($maxDif > 0) {
$px_neg = int($height * abs($minDif) / ($maxDif + abs($minDif))); # Wieviel % entfallen auf unten ?
$px_pos = $height-$px_neg; # der Rest ist oben
- } else { # keine positiven Balken vorhanden, die negativen bekommen den gesammten Raum
+ } else { # keine positiven Balken vorhanden, die Negativen bekommen den gesammten Raum
$px_neg = $height;
$px_pos = 0;
}
@@ -1788,7 +1821,7 @@ sub PortalAsHtml ($$) {
if ($v || $show_night) {
# Balken nur einfärben wenn der User via Attr eine Farbe vorgibt, sonst bestimmt class odd von TR alleine die Farbe
my $style = "style=\"padding-bottom:0px; vertical-align:top; margin-left:auto; margin-right:auto;";
- $style .= (defined($colorv)) ? " background-color:#$colorv\"" : '"'; #" Syntaxhilight :)
+ $style .= (defined($colorv)) ? " background-color:#$colorv\"" : '"'; # Syntaxhilight
$ret .= "";
$ret .= "";
@@ -1927,6 +1960,7 @@ sub PortalAsHtml ($$) {
$ret .= " | ";
$ret .= $html_end if (defined($html_end));
+ $ret .= "";
return $ret;
}
@@ -2049,6 +2083,63 @@ return $weather_ids{$id} if(defined($weather_ids{$id}));
return 'unknown';
}
+######################################################################################################
+# Refresh eines Raumes aus $hash->{HELPER}{SPGROOM}
+# bzw. Longpoll von SSCam bzw. eines SMAPortalSPG Devices wenn $hash->{HELPER}{SPGDEV} gefüllt
+# $hash, $pload (1=Page reload), SMAPortalSPG-Event (1=Event)
+######################################################################################################
+sub SPGRefresh($$$) {
+ my ($hash,$pload,$lpollspg) = @_;
+ my $name;
+ if (ref $hash ne "HASH") {
+ ($name,$pload,$lpollspg) = split ",",$hash;
+ $hash = $defs{$name};
+ } else {
+ $name = $hash->{NAME};
+ }
+ my $fpr = 0;
+
+ # Kontext des SMAPortalSPG-Devices speichern für Refresh
+ my $sd = $hash->{HELPER}{SPGDEV}?$hash->{HELPER}{SPGDEV}:"\"n.a.\""; # Name des aufrufenden SMAPortalSPG-Devices
+ my $sr = $hash->{HELPER}{SPGROOM}?$hash->{HELPER}{SPGROOM}:"\"n.a.\""; # Raum aus dem das SMAPortalSPG-Device die Funktion aufrief
+ my $sl = $hash->{HELPER}{SPGDETAIL}?$hash->{HELPER}{SPGDETAIL}:"\"n.a.\""; # Name des SMAPortalSPG-Devices (wenn Detailansicht)
+ $fpr = AttrVal($hash->{HELPER}{SPGDEV},"forcePageRefresh",0) if($hash->{HELPER}{SPGDEV});
+ Log3($name, 4, "$name - Refresh - caller: $sd, callerroom: $sr, detail: $sl, pload: $pload, forcePageRefresh: $fpr, event_Spgdev: $lpollspg");
+
+ # Page-Reload
+ if($pload && ($hash->{HELPER}{SPGROOM} && !$hash->{HELPER}{SPGDETAIL} && !$fpr)) {
+ # trifft zu wenn in einer Raumansicht
+ my @rooms = split(",",$hash->{HELPER}{SPGROOM});
+ foreach (@rooms) {
+ my $room = $_;
+ { map { FW_directNotify("FILTER=room=$room", "#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") }
+ }
+ } elsif ($pload && (!$hash->{HELPER}{SPGROOM} || $hash->{HELPER}{SPGDETAIL})) {
+ # trifft zu bei Detailansicht oder im FLOORPLAN bzw. Dashboard oder wenn Seitenrefresh mit dem
+ # SMAPortalSPG-Attribut "forcePageRefresh" erzwungen wird
+ { map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") }
+ } else {
+ if($fpr) {
+ { map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } devspec2array("TYPE=FHEMWEB") }
+ }
+ }
+
+ # parentState des SMAPortalSPG-Device updaten
+ my @spgs = devspec2array("TYPE=SMAPortalSPG");
+ my $st = ReadingsVal($name, "state", "initialized");
+ foreach(@spgs) {
+ if($defs{$_}{PARENT} eq $name) {
+ next if(IsDisabled($defs{$_}{NAME}));
+ readingsBeginUpdate($defs{$_});
+ readingsBulkUpdate($defs{$_},"parentState", $st);
+ readingsBulkUpdate($defs{$_},"state", "updated");
+ readingsEndUpdate($defs{$_}, 1);
+ }
+ }
+
+return;
+}
+
1;
=pod
@@ -2076,7 +2167,7 @@ return 'unknown';
SMAPortal
- Mit diesem Modul können Daten aus dem SMA-Portal abgerufen werden.
+ Mit diesem Modul können Daten aus dem SMA Sunny Portal abgerufen werden.
Momentan sind es:
@@ -2143,8 +2234,8 @@ return 'unknown';
Erstellt Devices zur grafischen Anzeige der SMA Sunny Portal Prognosedaten in verschiedenen Layouts.
Das Attribut "detailLevel" muss auf den Level 4 gesetzt sein. Der Befehl setzt dieses Attribut automatisch auf
den benötigten Wert.
- Mit den Attributen im Abschnitt "Attribute der Grafikdevices" können Erscheinungsbild und
- Farbgebung der Prognosedaten in den erstellten Devices angepasst werden.
+ Mit den "Attributen des Grafikdevices" können Erscheinungsbild und
+ Farbgebung der Prognosedaten in den erstellten Grafik-Devices angepasst werden.
@@ -2253,156 +2344,7 @@ return 'unknown';
-
-
-
- Attribute der Grafikdevices
-
-
-
- - alias
- In Verbindung mit "show_link" beliebiger Abzeigename.
-
-
-
- - color
- Farbauswahl der Balken.
-
-
-
- - color2
- Farbauswahl der sekundären Balken. Die zweite Farbe ist nur sinnvoll für Anzeigedevice "Generation_Consumption"
- (Type pvco) und "Differential" (Type diff).
-
-
-
- - consumers
- Komma getrennte Liste der am Sunny Home Manager angeschlossenen Geräte in der Form <Verbrauchername>:<Icon>@<Farbe>.
- Der Name des Verbrauchers muss dabei dem Namen im Reading "L3_<Verbrauchername>_Planned" entsprechen.
-
- Beispiel:
- Trockner:scene_clothes_dryer@yellow,Waschmaschine:scene_washing_machine@lightgreen,Geschirrspueler:scene_dishwasher@orange
-
-
-
-
- - font_size <value>
- Legt fest wieviel Platz über den Balken (bei Anzeigetyp Differential (diff) auch unter diesen) zur Anzeige der Werte
- freigehalten wird. Bei Styles die große Fonts benutzen, kann der default-Wert zu klein sein, bzw. u.U. rutscht ein
- Balken über die Grundlinie. In diesen Fällen bitte den Wert erhöhen.. (default: 24)
-
-
-
- - height <value>
- Höhe der Balken in px und damit Bestimmung der gesammten Höhe.
- In Verbindung mit hour lassen sich damit auch recht kleine Grafikausgaben erzeugen. (default: 200)
-
-
-
- - hours <4...24>
- Anzahl der Balken/Stunden. (default: 24)
-
-
-
- - hour_style
- Format der Zeitangabe.
-
-
-
-
- nicht gesetzt | - nur Stundenangabe ohne Minuten (default) |
- :00 | - Stunden sowie Minuten zweistellig, z.B. 10:00 |
- :0 | - Stunden sowie Minuten einstellig, z.B. 8:0 |
-
-
-
-
-
- - html_start <HTML-String>
- Angabe eines beliebigen HTML-Strings der vor der generierten Portalgrafik ausgegeben wird.
-
-
-
- - html_end <HTML-String>
- Angabe eines beliebigen HTML-Strings der nach der generierten Portalgrafik ausgegeben wird.
-
-
-
- - icon
- Setzt das Icon zur Darstellung der Zeiten mit Verbraucherempfehlung.
- Dazu kann ein beliebiges Icon mit Hilfe der Standard "Select Icon"-Funktion (links unten im FHEMWEB) direkt ausgewählt
- werden.
-
-
-
- - legend_style <none | icon_top | icon_bottom | text_top | text_bottom>
- Lage bzw. Art und Weise der angezeigten Consumers Legende.
-
-
-
- - maxPV <0...val>
- Maximaler Ertrag in einer Stunde zur Berechnung der Balkenhöhe, 0 = dynamisch. (default: 0)
-
-
-
- - show_diff <no | top | bottom>
- Zusätzliche Anzeige der Differenz "Ertrag - Verbrauch" wie beim Anzeigetyp Differential (diff). (default: no)
-
-
-
- - show_header <1|0>
- Anzeige der Kopfzeile mit Prognosedaten, Rest des aktuellen Tages und des nächsten Tages (default: 1)
-
-
-
- - show_link <1|0>
- Anzeige des Device-Detaillinks über der grafischen Ausgabe (default: 1)
-
-
-
- - show_night <1|0>
- Ebenfalls die Nachtstunden ohne Ertragsprognose anzeigen (default: 0)
-
-
-
- - show_weather <1|0>
- Wettericons anzeigen. (default: 1)
-
-
-
- - type <pv | co | pvco | diff>
- Layout der Portalgrafik. (default: pv)
-
-
-
-
- pv | - Erzeugung |
- co | - Verbrauch |
- pvco | - Erzeugung und Verbrauch |
- diff | - Differenz von Erzeugung und Verbrauch |
-
-
-
-
-
- - W/kW <W | kW>
- Wertanzeige in W oder in kW auf eine Nachkommastelle gerundet. (default: W)
-
-
-
- - width <value>
- Breite der Balken in px. ( default: 6 (auto) )
-
-
-
- - weather_color
- Farbe der Wetter-Icons.
-
-
-
-
-
-
+
diff --git a/fhem/contrib/DS_Starter/76_SMAPortalSPG.pm b/fhem/contrib/DS_Starter/76_SMAPortalSPG.pm
new file mode 100644
index 000000000..2ae2965f4
--- /dev/null
+++ b/fhem/contrib/DS_Starter/76_SMAPortalSPG.pm
@@ -0,0 +1,572 @@
+########################################################################################################################
+# $Id: $
+#########################################################################################################################
+# 76_SMAPortalSPG.pm
+#
+# (c) 2019 by Heiko Maaz e-mail: Heiko dot Maaz at t-online dot de
+# forked from 98_weblink.pm by Rudolf König
+#
+# This Module is used by module 76_SMAPortal to create graphic devices.
+# It can't be used standalone without any SMAPortal-Device.
+#
+# This script is part of fhem.
+#
+# Fhem is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# Fhem is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with fhem. If not, see .
+#
+#########################################################################################################################
+
+package main;
+
+use strict;
+use warnings;
+use Time::HiRes qw(gettimeofday);
+eval "use FHEM::Meta;1" or my $modMetaAbsent = 1;
+
+# Versions History intern
+our %SMAPortalSPG_vNotesIntern = (
+ "1.0.0" => "03.06.2019 initial Version "
+);
+
+################################################################
+sub SMAPortalSPG_Initialize($) {
+ my ($hash) = @_;
+
+ my $fwd = join(",",devspec2array("TYPE=FHEMWEB:FILTER=STATE=Initialized"));
+
+ $hash->{DefFn} = "SMAPortalSPG_Define";
+ $hash->{AttrList} = "autoRefresh:selectnumbers,120,0.2,1800,0,log10 ".
+ "autoRefreshFW:$fwd ".
+ "beamColor:colorpicker,RGB ".
+ "beamColor2:colorpicker,RGB ".
+ "beamHeight ".
+ "beamWidth ".
+ "consumerList ".
+ "consumerLegend:none,icon_top,icon_bottom,text_top,text_bottom ".
+ "disable:1,0 ".
+ "forcePageRefresh:1,0 ".
+ "hourCount:slider,4,1,24 ".
+ "hourStyle ".
+ "maxPV ".
+ "htmlStart ".
+ "htmlEnd ".
+ "showDiff:no,top,bottom ".
+ "showHeader:1,0 ".
+ "showLink:1,0 ".
+ "showNight:1,0 ".
+ "showWeather:1,0 ".
+ "spaceSize ".
+ "suggestIcon ".
+ "layoutType:pv,co,pvco,diff ".
+ "W/kW:W,kW ".
+ "weatherColor:colorpicker,RGB ".
+ $readingFnAttributes;
+ $hash->{RenameFn} = "SMAPortalSPG_Rename";
+ $hash->{CopyFn} = "SMAPortalSPG_Copy";
+ $hash->{FW_summaryFn} = "SMAPortalSPG_FwFn";
+ $hash->{FW_detailFn} = "SMAPortalSPG_FwFn";
+ $hash->{AttrFn} = "SMAPortalSPG_Attr";
+ $hash->{FW_hideDisplayName} = 1; # Forum 88667
+
+ # $hash->{FW_addDetailToSummary} = 1;
+ # $hash->{FW_atPageEnd} = 1; # wenn 1 -> kein Longpoll ohne informid in HTML-Tag
+
+ eval { FHEM::Meta::InitMod( __FILE__, $hash ) }; # für Meta.pm (https://forum.fhem.de/index.php/topic,97589.0.html)
+
+return;
+}
+
+################################################################
+sub SMAPortalSPG_Define($$) {
+ my ($hash, $def) = @_;
+ my ($name, $type, $link) = split("[ \t]+", $def, 3);
+
+ if(!$link) {
+ return "Usage: define SMAPortalSPG ";
+ }
+
+ my $arg = (split("[()]",$link))[1];
+ $arg =~ s/'//g;
+ $hash->{PARENT} = (split(",",$arg))[0];
+ $hash->{HELPER}{MODMETAABSENT} = 1 if($modMetaAbsent); # Modul Meta.pm nicht vorhanden
+ $hash->{LINK} = $link;
+
+ # Versionsinformationen setzen
+ SMAPortalSPG_setVersionInfo($hash);
+
+ readingsSingleUpdate($hash,"state", "initialized", 1); # Init für "state"
+
+return undef;
+}
+
+################################################################
+sub SMAPortalSPG_Rename($$) {
+ my ($new_name,$old_name) = @_;
+ my $hash = $defs{$new_name};
+
+ $hash->{DEF} =~ s/$old_name/$new_name/g;
+ $hash->{LINK} =~ s/$old_name/$new_name/g;
+
+return;
+}
+
+################################################################
+sub SMAPortalSPG_Copy($$) {
+ my ($old_name,$new_name) = @_;
+ my $hash = $defs{$new_name};
+
+ $hash->{DEF} =~ s/$old_name/$new_name/g;
+ $hash->{LINK} =~ s/$old_name/$new_name/g;
+
+return;
+}
+
+################################################################
+sub SMAPortalSPG_Attr($$$$) {
+ my ($cmd,$name,$aName,$aVal) = @_;
+ my $hash = $defs{$name};
+ my ($do,$val);
+
+ # $cmd can be "del" or "set"
+ # $name is device name
+ # aName and aVal are Attribute name and value
+
+ if($aName eq "disable") {
+ if($cmd eq "set") {
+ $do = ($aVal) ? 1 : 0;
+ }
+ $do = 0 if($cmd eq "del");
+ $val = ($do == 1 ? "disabled" : "initialized");
+ readingsSingleUpdate($hash, "state", $val, 1);
+
+ if($do == 1) {
+ my @allrds = keys%{$defs{$name}{READINGS}};
+ foreach my $key(@allrds) {
+ delete($defs{$name}{READINGS}{$key}) if($key ne "state");
+ }
+ }
+ }
+
+ if($aName eq "icon") {
+ $_[2] = "suggestIcon";
+ }
+
+return undef;
+}
+
+################################################################
+sub SMAPortalSPG_FwFn($;$$$) {
+ my ($FW_wname, $d, $room, $pageHash) = @_; # pageHash is set for summaryFn.
+ my $hash = $defs{$d};
+ my $link = $hash->{LINK};
+ my $height;
+
+ RemoveInternalTimer($hash);
+ $hash->{HELPER}{FW} = $FW_wname;
+
+ $link = AnalyzePerlCommand(undef, $link) if($link =~ m/^{(.*)}$/s);
+
+ my $alias = AttrVal($d, "alias", $d); # Linktext als Aliasname oder Devicename setzen
+ my $dlink = "$alias";
+
+ my $ret = "";
+ if(IsDisabled($d)) {
+ $height = AttrNum($d, 'beamHeight', 200);
+ $ret .= "";
+ $ret .= "";
+ $ret .= "";
+ $ret .= "SMA Portal graphic device $d is disabled";
+ $ret .= " | ";
+ $ret .= " ";
+ $ret .= " ";
+ } else {
+ $ret .= "$dlink " if(AttrVal($d,"showLink",0));
+ $ret .= $link;
+ }
+
+ # Autorefresh nur des aufrufenden FHEMWEB-Devices
+ my $al = AttrVal($d, "autoRefresh", 0);
+ if($al) {
+ InternalTimer(gettimeofday()+$al, "SMAPortalSPG_refresh", $hash, 0);
+ Log3($d, 5, "$d - next start of autoRefresh: ".FmtDateTime(gettimeofday()+$al));
+ }
+
+return $ret;
+}
+
+################################################################
+sub SMAPortalSPG_refresh($) {
+ my ($hash) = @_;
+ my $d = $hash->{NAME};
+
+ # Seitenrefresh festgelegt durch SMAPortalSPG-Attribut "autoRefresh" und "autoRefreshFW"
+ my $rd = AttrVal($d, "autoRefreshFW", $hash->{HELPER}{FW});
+ { map { FW_directNotify("#FHEMWEB:$_", "location.reload('true')", "") } $rd }
+
+ my $al = AttrVal($d, "autoRefresh", 0);
+ if($al) {
+ InternalTimer(gettimeofday()+$al, "SMAPortalSPG_refresh", $hash, 0);
+ Log3($d, 5, "$d - next start of autoRefresh: ".FmtDateTime(gettimeofday()+$al));
+ } else {
+ RemoveInternalTimer($hash);
+ }
+
+return;
+}
+
+#############################################################################################
+# Versionierungen des Moduls setzen
+# Die Verwendung von Meta.pm und Packages wird berücksichtigt
+#############################################################################################
+sub SMAPortalSPG_setVersionInfo($) {
+ my ($hash) = @_;
+ my $name = $hash->{NAME};
+
+ my $v = (sortTopicNum("desc",keys %SMAPortalSPG_vNotesIntern))[0];
+ my $type = $hash->{TYPE};
+ $hash->{HELPER}{PACKAGE} = __PACKAGE__;
+ $hash->{HELPER}{VERSION} = $v;
+
+ if($modules{$type}{META}{x_prereqs_src} && !$hash->{HELPER}{MODMETAABSENT}) {
+ # META-Daten sind vorhanden
+ $modules{$type}{META}{version} = "v".$v; # Version aus META.json überschreiben, Anzeige mit {Dumper $modules{SMAPortal}{META}}
+ if($modules{$type}{META}{x_version}) { # {x_version} ( nur gesetzt wenn $Id: 49_SMAPortalSPG.pm 19051 2019-03-27 22:10:48Z DS_Starter $ im Kopf komplett! vorhanden )
+ $modules{$type}{META}{x_version} =~ s/1.1.1/$v/g;
+ } else {
+ $modules{$type}{META}{x_version} = $v;
+ }
+ return $@ unless (FHEM::Meta::SetInternals($hash)); # FVERSION wird gesetzt ( nur gesetzt wenn $Id: 49_SMAPortalSPG.pm 19051 2019-03-27 22:10:48Z DS_Starter $ im Kopf komplett! vorhanden )
+ if(__PACKAGE__ eq "FHEM::$type" || __PACKAGE__ eq $type) {
+ # es wird mit Packages gearbeitet -> Perl übliche Modulversion setzen
+ # mit {->VERSION()} im FHEMWEB kann Modulversion abgefragt werden
+ use version 0.77; our $VERSION = FHEM::Meta::Get( $hash, 'version' );
+ }
+ } else {
+ # herkömmliche Modulstruktur
+ $hash->{VERSION} = $v;
+ }
+
+return;
+}
+
+1;
+
+=pod
+=item summary Definition of grapic devices by the SMAPortal module
+=item summary_DE Erstellung von Grafik-Devices durch das SMAPortal-Modul
+=begin html
+
+
+SMAPortalSPG
+
+ Is coming soon.
+
+=end html
+=begin html_DE
+
+
+SMAPortalSPG
+
+
+Das Modul SMAPortalSPG ist ein mit SMAPortal abgestimmtes Gerätemodul zur Definition von Grafik-Devices.
+
+
+
+ Define
+
+
+
+ Ein SMAPortal Grafik Device wird durch den SMAPortal Befehl "set <name> createPortalGraphic <Typ>" erstellt.
+ Siehe auch die Beschreibung zum SMAPortal "createPortalGraphic" Befehl.
+
+
+
+
+ Set
+
+
+
+
+ Get
+
+
+
+
+
+ Attribute
+
+
+
+
+ - alias
+ In Verbindung mit "showLink" beliebiger Abzeigename.
+
+
+
+
+ - autoRefresh
+ Wenn gesetzt, werden aktive Browserseiten des FHEMWEB-Devices welches das SMAPortalSPG-Device aufgerufen hat, nach der
+ eingestellten Zeit (Sekunden) neu geladen. Sollen statt dessen Browserseiten eines bestimmten FHEMWEB-Devices neu
+ geladen werden, kann dieses Device mit dem Attribut "autoRefreshFW" festgelegt werden.
+
+
+
+
+ - autoRefreshFW
+ Ist "autoRefresh" aktiviert, kann mit diesem Attribut das FHEMWEB-Device bestimmt werden dessen aktive Browserseiten
+ regelmäßig neu geladen werden sollen.
+
+
+
+
+ - beamColor
+ Farbauswahl der primären Balken.
+
+
+
+
+ - beamColor2
+ Farbauswahl der sekundären Balken. Die zweite Farbe ist nur sinnvoll für Anzeigedevice "Generation_Consumption"
+ (Type pvco) und "Differential" (Type diff).
+
+
+
+
+ - beamHeight <value>
+ Höhe der Balken in px und damit Bestimmung der gesammten Höhe.
+ In Verbindung mit hourCount lassen sich damit auch recht kleine Grafikausgaben erzeugen. (default: 200)
+
+
+
+
+ - beamWidth <value>
+ Breite der Balken in px. ( default: 6 (auto) )
+
+
+
+
+ - consumerList
+ Komma getrennte Liste der am Sunny Home Manager angeschlossenen Geräte in der Form <Verbrauchername>:<Icon>@<Farbe>.
+ Sobald die Einschaltung einer der angegebenen Verbraucher geplant ist, wird der geplante Zeitraum in der Grafik
+ angezeigt.
+ Der Name des Verbrauchers muss dabei dem Namen im Reading "L3_<Verbrauchername>_Planned" entsprechen.
+
+ Beispiel:
+ Trockner:scene_clothes_dryer@yellow,Waschmaschine:scene_washing_machine@lightgreen,Geschirrspueler:scene_dishwasher@orange
+
+
+
+
+
+ - consumerLegend <none | icon_top | icon_bottom | text_top | text_bottom>
+ Lage bzw. Art und Weise der angezeigten Consumers Legende.
+
+
+
+
+ - disable
+ Aktiviert/deaktiviert das Device.
+
+
+
+
+ - forcePageRefresh
+ Das Attribut wird durch SMAPortal ausgewertet.
+ Wenn gesetzt, wird ein Reload aller Browserseiten mit aktiven FHEMWEB-Verbindungen nach dem Abschluß bestimmter
+ SMAPortal-Befehle erzwungen.
+
+
+
+
+ - hourCount <4...24>
+ Anzahl der Balken/Stunden. (default: 24)
+
+
+
+
+ - hourStyle
+ Format der Zeitangabe.
+
+
+
+
+ nicht gesetzt | - nur Stundenangabe ohne Minuten (default) |
+ :00 | - Stunden sowie Minuten zweistellig, z.B. 10:00 |
+ :0 | - Stunden sowie Minuten einstellig, z.B. 8:0 |
+
+
+
+
+
+
+ - maxPV <0...val>
+ Maximaler Ertrag in einer Stunde zur Berechnung der Balkenhöhe, 0 = dynamisch. (default: 0)
+
+
+
+
+ - htmlStart <HTML-String>
+ Angabe eines beliebigen HTML-Strings der vor der generierten Portalgrafik ausgegeben wird.
+
+
+
+
+ - htmlEnd <HTML-String>
+ Angabe eines beliebigen HTML-Strings der nach der generierten Portalgrafik ausgegeben wird.
+
+
+
+
+ - showDiff <no | top | bottom>
+ Zusätzliche Anzeige der Differenz "Ertrag - Verbrauch" wie beim Anzeigetyp Differential (diff). (default: no)
+
+
+
+
+ - showHeader <1|0>
+ Anzeige der Kopfzeile mit Prognosedaten, Rest des aktuellen Tages und des nächsten Tages (default: 1)
+
+
+
+
+ - showLink <1|0>
+ Anzeige des Device-Detaillinks über der grafischen Ausgabe (default: 1)
+
+
+
+
+ - showNight <1|0>
+ Ebenfalls die Nachtstunden ohne Ertragsprognose anzeigen (default: 0)
+
+
+
+
+ - showWeather <1|0>
+ Wettericons anzeigen. (default: 1)
+
+
+
+
+ - spaceSize <value>
+ Legt fest wieviel Platz in px über den Balken (bei Anzeigetyp Differential (diff) auch unter diesen) zur Anzeige der
+ Werte freigehalten wird. Bei Styles die große Fonts benutzen, kann der default-Wert zu klein sein, bzw. u.U. rutscht ein
+ Balken über die Grundlinie. In diesen Fällen bitte den Wert erhöhen. (default: 24)
+
+
+
+
+ - suggestIcon
+ Setzt das Icon zur Darstellung der Zeiten mit Verbraucherempfehlung.
+ Dazu kann ein beliebiges Icon mit Hilfe der Standard "Select Icon"-Funktion (links unten im FHEMWEB) direkt ausgewählt
+ werden.
+
+
+
+
+ - layoutType <pv | co | pvco | diff>
+ Layout der Portalgrafik. (default: pv)
+
+
+
+
+ pv | - Erzeugung |
+ co | - Verbrauch |
+ pvco | - Erzeugung und Verbrauch |
+ diff | - Differenz von Erzeugung und Verbrauch |
+
+
+
+
+
+
+ - W/kW <W | kW>
+ Wertanzeige in W oder in kW auf eine Nachkommastelle gerundet. (default: W)
+
+
+
+
+ - weatherColor
+ Farbe der Wetter-Icons.
+
+
+
+
+
+
+
+
+=end html_DE
+
+=for :application/json;q=META.json 76_SMAPortalSPG.pm
+{
+ "abstract": "Definition of grapic devices by the SMAPortal module",
+ "x_lang": {
+ "de": {
+ "abstract": "Erstellung von Grafik-Devices durch das SMAPortal-Modul"
+ }
+ },
+ "keywords": [
+ "sma",
+ "photovoltaik",
+ "electricity",
+ "portal",
+ "smaportal",
+ "graphics",
+ "longpoll",
+ "refresh"
+ ],
+ "version": "v1.1.1",
+ "release_status": "testing",
+ "author": [
+ "Heiko Maaz "
+ ],
+ "x_fhem_maintainer": [
+ "DS_Starter"
+ ],
+ "x_fhem_maintainer_github": [
+ "nasseeder1"
+ ],
+ "prereqs": {
+ "runtime": {
+ "requires": {
+ "FHEM": 5.00918799,
+ "perl": 5.014,
+ "Time::HiRes": 0
+ },
+ "recommends": {
+ "FHEM::Meta": 0
+ },
+ "suggests": {
+ }
+ }
+ },
+ "resources": {
+ "repository": {
+ "x_dev": {
+ "type": "svn",
+ "url": "https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter",
+ "web": "https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter/76_SMAPortalSPG.pm",
+ "x_branch": "dev",
+ "x_filepath": "fhem/contrib/",
+ "x_raw": "https://svn.fhem.de/fhem/trunk/fhem/contrib/DS_Starter/76_SMAPortalSPG.pm"
+ }
+ }
+ }
+}
+=end :application/json;q=META.json
+
+=cut
|
|