######################################################################################################################## # $Id: 76_SMAPortalSPG.pm 19799 2019-07-08 16:33:29Z DS_Starter $ ######################################################################################################################### # 76_SMAPortalSPG.pm # # (c) 2019-2020 by Heiko Maaz e-mail: Heiko dot Maaz at t-online dot de # # 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 FHEM::SMAPortalSPG; ## no critic 'package' use strict; use warnings; use GPUtils qw(GP_Import GP_Export); # wird für den Import der FHEM Funktionen aus der fhem.pl benötigt use Time::HiRes qw(gettimeofday); eval "use FHEM::Meta;1" or my $modMetaAbsent = 1; ## no critic 'eval' # Run before module compilation BEGIN { # Import from main:: GP_Import( qw( AnalyzePerlCommand AttrVal AttrNum defs delFromDevAttrList delFromAttrList devspec2array deviceEvents Debug FmtDateTime FmtTime FW_makeImage fhemTimeGm getKeyValue gettimeofday genUUID init_done InternalTimer IsDisabled Log Log3 makeReadingName modules readingsSingleUpdate readingsBulkUpdate readingsBulkUpdateIfChanged readingsBeginUpdate readingsDelete readingsEndUpdate ReadingsNum ReadingsTimestamp ReadingsVal RemoveInternalTimer readingFnAttributes setKeyValue sortTopicNum TimeNow Value json2nameValue FW_directNotify ) ); # Export to main context with different name # my $pkg = caller(0); # my $main = $pkg; # $main =~ s/^(?:.+::)?([^:]+)$/main::$1\_/g; # foreach (@_) { # *{ $main . $_ } = *{ $pkg . '::' . $_ }; # } GP_Export( qw( Initialize pageAsHtml ) ); } # Versions History intern my %vNotesIntern = ( "1.6.0" => "19.04.2020 switch to pachages, some improvements according to PBP ", "1.5.0" => "07.07.2019 new attributes headerAlignment, headerDetail ", "1.4.0" => "26.06.2019 support for FTUI-Widget ", "1.3.0" => "24.06.2019 replace suggestIcon by consumerAdviceIcon ", "1.2.0" => "21.06.2019 GetFn -> get html ", "1.1.0" => "13.06.2019 commandRef revised, changed attribute W/kW to Wh/kWh ", "1.0.0" => "03.06.2019 initial Version " ); ################################################################ sub Initialize { my ($hash) = @_; my $fwd = join(",",devspec2array("TYPE=FHEMWEB:FILTER=STATE=Initialized")); $hash->{DefFn} = \&Define; $hash->{GetFn} = \&Get; $hash->{RenameFn} = \&Rename; $hash->{CopyFn} = \&Copy; $hash->{FW_summaryFn} = \&FwFn; $hash->{FW_detailFn} = \&FwFn; $hash->{AttrFn} = \&Attr; $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 ". "headerAlignment:center,left,right ". "headerDetail:all,co,pv,pvco,statusLink ". "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 ". "consumerAdviceIcon ". "layoutType:pv,co,pvco,diff ". "Wh/kWh:Wh,kWh ". "weatherColor:colorpicker,RGB ". $readingFnAttributes; $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; } ############################################################### # SMAPortalSPG Define ############################################################### sub 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 setVersionInfo($hash); readingsSingleUpdate($hash,"state", "initialized", 1); # Init für "state" return; } ############################################################### # SMAPortalSPG Get ############################################################### sub Get { my ($hash, @a) = @_; return "\"get X\" needs at least an argument" if ( @a < 2 ); my $name = shift @a; my $cmd = shift @a; my $getlist = "Unknown argument $cmd, choose one of ". "html:noArg ". "ftui:noArg "; if ($cmd eq "html") { return pageAsHtml($hash); } if ($cmd eq "ftui") { return pageAsHtml($hash,"ftui"); } return; } ################################################################ sub 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 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 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] = "consumerAdviceIcon"; } return; } ################################################################ sub 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 .= ""; $ret .= "
"; $ret .= "SMA Portal graphic device $d is disabled"; $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, \&pageRefresh, $hash, 0); Log3($d, 5, "$d - next start of autoRefresh: ".FmtDateTime(gettimeofday()+$al)); } return $ret; } ################################################################ sub pageRefresh { 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, \&pageRefresh, $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 setVersionInfo { my ($hash) = @_; my $name = $hash->{NAME}; my $v = (sortTopicNum("desc",keys %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: 76_SMAPortalSPG.pm 19799 2019-07-08 16:33:29Z 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: 76_SMAPortalSPG.pm 19799 2019-07-08 16:33:29Z 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; } ################################################################ # Grafik als HTML zurück liefern (z.B. für Widget) ################################################################ sub pageAsHtml { my ($hash,$ftui) = @_; my $name = $hash->{NAME}; my $link = $hash->{LINK}; my $height; if ($ftui && $ftui eq "ftui") { # Aufruf aus TabletUI -> FW_cmd ersetzen gemäß FTUI Syntax my $s = substr($link,0,length($link)-2); $link = $s.",'$ftui')}"; } $link = AnalyzePerlCommand(undef, $link) if($link =~ m/^{(.*)}$/s); my $alias = AttrVal($name, "alias", $name); # Linktext als Aliasname oder Devicename setzen my $dlink = "$alias"; my $ret = ""; if(IsDisabled($name)) { $height = AttrNum($name, 'beamHeight', 200); $ret .= ""; $ret .= ""; $ret .= ""; $ret .= ""; $ret .= "
"; $ret .= "SMA Portal graphic device $name is disabled"; $ret .= "
"; } else { $ret .= "$dlink
" if(AttrVal($name,"showLink",0)); $ret .= $link; } $ret .= ""; return $ret; } 1; =pod =item summary Definition of graphic devices by the SMAPortal module =item summary_DE Erstellung von Grafik-Devices durch das SMAPortal-Modul =begin html

SMAPortalSPG


The module SMAPortalSPG is a device module attuned to the module SMAPortal for definition of graphic devices.
Graphic data can also be integrated into FHEM Tablet UI with the "SMAPortalSPG Widget".
    Define

      A SMAPortal graphic device is defined by the command "set <name> createPortalGraphic <type>" in an SMAPortal device. Please see the description of SMAPortal "createPortalGraphic" command.

    Set
      N/A

    Get

      • get <name> html
      • The SMAPortal graphic is fetched as HTML-code and depicted.


    Attribute

      • alias
        In conjunction with "showLink" a user-defined label for the device.

      • autoRefresh
        If set, active browser pages of the FHEMWEB device which has called the SMAPortalSPG device, are new reloaded after the specified time (seconds). Browser pages of a particular FHEMWEB device to be refreshed can be specified by attribute "autoRefreshFW" instead.

      • autoRefreshFW
        If "autoRefresh" is activated, you can specify a particular FHEMWEB device whose active browser pages are refreshed periodically.

      • beamColor
        Color selection for the primary beams.

      • beamColor2
        Color selection for the secondary beams. The second color only make sense for devices of type "Generation_Consumption" (Type pvco) and "Differential" (Type diff).

      • beamHeight <value>
        Height of beams in px and therefore the determination of the whole graphic Height. In conjunction with "hourCount" it is possible to create quite tiny graphics. (default: 200)

      • beamWidth <value>
        Width of the beams in px. (default: 6 (auto))

      • consumerList <Verbraucher1>:<Icon>@<Farbe>,<Verbraucher2>:<Icon>@<Farbe>,...
        Comma separated list of consumers which are connected to the Sunny Home Manager.
        Once the activation of a listed consumer is planned, the consumer icon will be shown in the beams of the planned period. The name of a consumer must be identical to its name in Reading "L3_<consumer>_Planned".

        Example:
        attr <name> consumerList Trockner:scene_clothes_dryer@yellow,Waschmaschine:scene_washing_machine@lightgreen,Geschirrspueler:scene_dishwasher@orange

      • consumerLegend <none | icon_top | icon_bottom | text_top | text_bottom>
        Location respectively the method of the shown consumer legend.

      • disable
        Activate/deactivate the device.

      • forcePageRefresh
        The attribute is evaluated by the SMAPortal module.
        If set, a reload of all browser pages with active FHEMWEB connections will be enforced when the parent SMAPortal device was updated.

      • headerAlignment <center | left | right>
        Alignment of the header lines. (default: center)

      • headerDetail <all | co | pv | pvco | statusLink>
        Detail level of the header lines. (default: all)
          all display production (PV), consumption (CO), link to SMAPortal device + update timestamp (default)
          co display consumption (CO) only
          pv display production (PV) only
          pvco display production (PV) and consumption (CO)
          statusLink Link to SMAPortal device + update timestamp only

      • hourCount <4...24>
        Amount of beams/hours to show. (default: 24)

      • hourStyle
        Format of time specification.

          not set - only hours without minutes (default)
          :00 - hours and minutes two-digit, e.g. 10:00
          :0 - hours and minutes one-digit, e.g. 8:0

      • maxPV <0...val>
        Maximum yield per hour to calculate the beam height. (default: 0 -> dynamical)

      • htmlStart <HTML-String>
        A user-defined HTML-String issued before the graphic code.

      • htmlEnd <HTML-String>
        A user-defined HTML-String issued after the graphic code.

      • showDiff <no | top | bottom>
        Additional note of the difference "Generation - Consumption" as well as the device type Differential (diff) does. (default: no)

      • showHeader
        Shows the header line with forecast data, Rest of the current day generation and the forecast of the next day (default: 1)

      • showLink
        Show the detail link above the graphic device. (default: 1)

      • showNight
        Show the night hours (without forecast values) additionally. (default: 0)

      • showWeather
        Show weather icons. (default: 1)

      • spaceSize <value>
        Determines the space (px) above or below the beams (only when using the type "Differential" (diff)) to the shown values. If styles are using large fonts the default value may be too less. In that cases please increase the value. (default: 24)

      • consumerAdviceIcon
        Set the icon used in periods with suggestion to switch consumers on. You can use the standard "Select Icon" function (down left in FHEMWEB) to select the wanted icon.

      • layoutType <pv | co | pvco | diff>
        Layout type of Portal graphic. (default: pv)

          pv - Generation
          co - Consumption
          pvco - Generation and Consumption
          diff - Differenz between Generation and Consumption

      • Wh/kWh <Wh | kWh>
        Switch the unit to W or to kW rounded to one position after decimal point. (default: W)

      • weatherColor
        Color of weather icons.

=end html =begin html_DE

SMAPortalSPG


Das Modul SMAPortalSPG ist ein mit SMAPortal abgestimmtes Gerätemodul zur Definition von Grafik-Devices.
Die Portalgrafik kann ebenfalls in FHEM Tablet UI mit dem "SMAPortalSPG Widget" integriert werden.
    Define

      Ein SMAPortal Grafik-Device wird durch den SMAPortal Befehl "set <name> createPortalGraphic <Typ>" erstellt. Siehe auch die Beschreibung zum SMAPortal "createPortalGraphic" Befehl.

    Set
      N/A

    Get

      • get <name> html
      • Die SMAPortal-Grafik wird als HTML-Code abgerufen und wiedergegeben.


    Attribute

      • alias
        In Verbindung mit "showLink" ein 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 den Anzeigedevice-Typ "Generation_Consumption" (pvco) und "Differential" (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 <Verbraucher1>:<Icon>@<Farbe>,<Verbraucher2>:<Icon>@<Farbe>,...
        Komma getrennte Liste der am SMA Sunny Home Manager angeschlossenen Geräte.
        Sobald die Aktivierung 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:
        attr <name> consumerList 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 Verbraucherlegende.

      • disable
        Aktiviert/deaktiviert das Device.

      • forcePageRefresh
        Das Attribut wird durch das SMAPortal-Device ausgewertet.
        Wenn gesetzt, wird ein Reload aller Browserseiten mit aktiven FHEMWEB-Verbindungen nach dem Update des Eltern-SMAPortal-Devices erzwungen.

      • headerAlignment <center | left | right>
        Ausrichtung der Kopfzeilen. (default: center)

      • headerDetail <all | co | pv | pvco | statusLink>
        Detailiierungsgrad der Kopfzeilen. (default: all)
          all Anzeige Erzeugung (PV), Verbrauch (CO), Link zum SMAPortal-Device + Aktualisierungszeit (default)
          co nur Verbrauch (CO)
          pv nur Erzeugung (PV)
          pvco Erzeugung (PV) und Verbrauch (CO)
          statusLink nur Link zum SMAPortal-Device + Aktualisierungszeit

      • 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. (default: 0 -> dynamisch)

      • htmlStart <HTML-String>
        Angabe eines beliebigen HTML-Strings der vor dem Grafik-Code ausgeführt wird.

      • htmlEnd <HTML-String>
        Angabe eines beliebigen HTML-Strings der nach dem Grafik-Code ausgeführt wird.

      • showDiff <no | top | bottom>
        Zusätzliche Anzeige der Differenz "Ertrag - Verbrauch" wie beim Anzeigetyp Differential (diff). (default: no)

      • showHeader
        Anzeige der Kopfzeile mit Prognosedaten, Rest des aktuellen Tages und des nächsten Tages (default: 1)

      • showLink
        Anzeige des Detail-Links über dem Grafik-Device (default: 1)

      • showNight
        Die Nachtstunden (ohne Ertragsprognose) werden mit angezeigt. (default: 0)

      • showWeather
        Wettericons anzeigen. (default: 1)

      • spaceSize <value>
        Legt fest wieviel Platz in px über oder unter den Balken (bei Anzeigetyp Differential (diff)) zur Anzeige der Werte freigehalten wird. Bei Styles mit große Fonts kann der default-Wert zu klein sein bzw. rutscht ein Balken u.U. über die Grundlinie. In diesen Fällen bitte den Wert erhöhen. (default: 24)

      • consumerAdviceIcon
        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

      • Wh/kWh <Wh | kWh>
        Definiert die Anzeigeeinheit in Wh oder in kWh 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": "stable", "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