mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-01 01:09:47 +00:00
76_SolarForecast.pm: contrib 0.47.0
git-svn-id: https://svn.fhem.de/fhem/trunk@24522 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
e644768a59
commit
4539268113
@ -116,7 +116,7 @@ BEGIN {
|
||||
|
||||
# Versions History intern
|
||||
my %vNotesIntern = (
|
||||
"0.47.0" => "26.05.2021 add flowGraphic, attr flowGraphicSize ",
|
||||
"0.47.0" => "26.05.2021 add flowGraphic, attr flowGraphicSize, graphicSelect ",
|
||||
"0.46.1" => "21.05.2021 set <> reset pvHistory <day> <hour> ",
|
||||
"0.46.0" => "16.05.2021 integrate intotal, outtotal to currentBatteryDev, set maxconsumer to 9 ",
|
||||
"0.45.1" => "13.05.2021 change the calc of etotal at the beginning of every hour in _transferInverterValues ".
|
||||
@ -387,33 +387,35 @@ my %weather_ids = (
|
||||
'100' => { s => '0', icon => 'weather_night', txtd => 'sternenklarer Himmel', txte => 'starry sky' },
|
||||
);
|
||||
|
||||
my @chours = (5..21); # Stunden des Tages mit möglichen Korrekturwerten
|
||||
my $defpvme = 16.52; # default Wirkungsgrad Solarmodule
|
||||
my $definve = 98.3; # default Wirkungsgrad Wechselrichter
|
||||
my $kJtokWh = 0.00027778; # Umrechnungsfaktor kJ in kWh
|
||||
my $defmaxvar = 0.5; # max. Varianz pro Tagesberechnung Autokorrekturfaktor
|
||||
my $definterval = 70; # Standard Abfrageintervall
|
||||
my $defslidenum = 3; # max. Anzahl der Arrayelemente in Schieberegistern
|
||||
my @chours = (5..21); # Stunden des Tages mit möglichen Korrekturwerten
|
||||
my $defpvme = 16.52; # default Wirkungsgrad Solarmodule
|
||||
my $definve = 98.3; # default Wirkungsgrad Wechselrichter
|
||||
my $kJtokWh = 0.00027778; # Umrechnungsfaktor kJ in kWh
|
||||
my $defmaxvar = 0.5; # max. Varianz pro Tagesberechnung Autokorrekturfaktor
|
||||
my $definterval = 70; # Standard Abfrageintervall
|
||||
my $defslidenum = 3; # max. Anzahl der Arrayelemente in Schieberegistern
|
||||
|
||||
my $pvhcache = $attr{global}{modpath}."/FHEM/FhemUtils/PVH_SolarForecast_"; # Filename-Fragment für PV History (wird mit Devicename ergänzt)
|
||||
my $pvccache = $attr{global}{modpath}."/FHEM/FhemUtils/PVC_SolarForecast_"; # Filename-Fragment für PV Circular (wird mit Devicename ergänzt)
|
||||
my $pvhcache = $attr{global}{modpath}."/FHEM/FhemUtils/PVH_SolarForecast_"; # Filename-Fragment für PV History (wird mit Devicename ergänzt)
|
||||
my $pvccache = $attr{global}{modpath}."/FHEM/FhemUtils/PVC_SolarForecast_"; # Filename-Fragment für PV Circular (wird mit Devicename ergänzt)
|
||||
|
||||
my $calcmaxd = 30; # Anzahl Tage die zur Berechnung Vorhersagekorrektur verwendet werden
|
||||
my @dweattrmust = qw(TTT Neff R101 ww SunUp SunRise SunSet); # Werte die im Attr forecastProperties des Weather-DWD_Opendata Devices mindestens gesetzt sein müssen
|
||||
my @draattrmust = qw(Rad1h); # Werte die im Attr forecastProperties des Radiation-DWD_Opendata Devices mindestens gesetzt sein müssen
|
||||
my $whistrepeat = 900; # Wiederholungsintervall Schreiben historische Daten
|
||||
my $calcmaxd = 30; # Anzahl Tage die zur Berechnung Vorhersagekorrektur verwendet werden
|
||||
my @dweattrmust = qw(TTT Neff R101 ww SunUp SunRise SunSet); # Werte die im Attr forecastProperties des Weather-DWD_Opendata Devices mindestens gesetzt sein müssen
|
||||
my @draattrmust = qw(Rad1h); # Werte die im Attr forecastProperties des Radiation-DWD_Opendata Devices mindestens gesetzt sein müssen
|
||||
my $whistrepeat = 900; # Wiederholungsintervall Schreiben historische Daten
|
||||
|
||||
my $cldampdef = 35; # Dämpfung (%) des Korrekturfaktors bzgl. effektiver Bewölkung, siehe: https://www.energie-experten.org/erneuerbare-energien/photovoltaik/planung/sonnenstunden
|
||||
my $cloud_base = 0; # Fußpunktverschiebung bzgl. effektiver Bewölkung
|
||||
my $cldampdef = 35; # Dämpfung (%) des Korrekturfaktors bzgl. effektiver Bewölkung, siehe: https://www.energie-experten.org/erneuerbare-energien/photovoltaik/planung/sonnenstunden
|
||||
my $cloud_base = 0; # Fußpunktverschiebung bzgl. effektiver Bewölkung
|
||||
|
||||
my $rdampdef = 10; # Dämpfung (%) des Korrekturfaktors bzgl. Niederschlag (R101)
|
||||
my $rain_base = 0; # Fußpunktverschiebung bzgl. effektiver Bewölkung
|
||||
my $rdampdef = 10; # Dämpfung (%) des Korrekturfaktors bzgl. Niederschlag (R101)
|
||||
my $rain_base = 0; # Fußpunktverschiebung bzgl. effektiver Bewölkung
|
||||
|
||||
my $maxconsumer = 9; # maximale Anzahl der möglichen Consumer (Attribut)
|
||||
my @ctypes = qw(dishwasher dryer washingmachine heater other); # erlaubte Consumer Typen
|
||||
my $defmintime = 60; # default min. Einschalt- bzw. Zykluszeit in Minuten
|
||||
my $defctype = "other"; # default Verbrauchertyp
|
||||
my $defcmode = "can"; # default Planungsmode der Verbraucher
|
||||
my $maxconsumer = 9; # maximale Anzahl der möglichen Consumer (Attribut)
|
||||
my @ctypes = qw(dishwasher dryer washingmachine heater other); # erlaubte Consumer Typen
|
||||
my $defmintime = 60; # default min. Einschalt- bzw. Zykluszeit in Minuten
|
||||
my $defctype = "other"; # default Verbrauchertyp
|
||||
my $defcmode = "can"; # default Planungsmode der Verbraucher
|
||||
|
||||
my $defflowGSize = 300; # default flowGraphicSize
|
||||
|
||||
|
||||
my %hef = ( # Energiedaktoren für Verbrauchertypen
|
||||
@ -472,9 +474,10 @@ sub Initialize {
|
||||
# "consumerAdviceIcon ".
|
||||
"cloudFactorDamping:slider,0,1,100 ".
|
||||
"disable:1,0 ".
|
||||
"flowGraphicSize:slider,100,50,500 ".
|
||||
"flowGraphicSize: ".
|
||||
"follow70percentRule:1,dynamic,0 ".
|
||||
"forcePageRefresh:1,0 ".
|
||||
"graphicSelect:both,flow,forecast ".
|
||||
"headerAlignment:center,left,right ".
|
||||
"headerDetail:all,co,pv,pvco,statusLink ".
|
||||
"historyHour:slider,-23,-1,0 ".
|
||||
@ -2611,7 +2614,8 @@ sub _transferBatteryValues {
|
||||
my ($pou,$pounit) = split ":", $h->{pout}; # Readingname/Unit für aktuelle Batterieentladung
|
||||
my ($bin,$binunit) = split ":", $h->{intotal}; # Readingname/Unit der total in die Batterie eingespeisten Energie (Zähler)
|
||||
my ($bout,$boutunit) = split ":", $h->{outtotal}; # Readingname/Unit der total aus der Batterie entnommenen Energie (Zähler)
|
||||
|
||||
my $batchr = $h->{charge} // ""; # Readingname Ladezustand Batterie
|
||||
|
||||
return if(!$pin || !$pou);
|
||||
|
||||
$pounit //= $piunit;
|
||||
@ -2626,10 +2630,11 @@ sub _transferBatteryValues {
|
||||
my $binuf = $binunit =~ /^kWh$/xi ? 1000 : 1;
|
||||
my $boutuf = $boutunit =~ /^kWh$/xi ? 1000 : 1;
|
||||
|
||||
my $pbo = ReadingsNum ($badev, $pou, 0) * $pouf; # aktuelle Batterieentladung (W)
|
||||
my $pbi = ReadingsNum ($badev, $pin, 0) * $piuf; # aktueller Batterieladung (W)
|
||||
my $btotout = ReadingsNum ($badev, $bout, 0) * $boutuf; # totale Batterieentladung (Wh)
|
||||
my $btotin = ReadingsNum ($badev, $bin, 0) * $binuf; # totale Batterieladung (Wh)
|
||||
my $pbo = ReadingsNum ($badev, $pou, 0) * $pouf; # aktuelle Batterieentladung (W)
|
||||
my $pbi = ReadingsNum ($badev, $pin, 0) * $piuf; # aktueller Batterieladung (W)
|
||||
my $btotout = ReadingsNum ($badev, $bout, 0) * $boutuf; # totale Batterieentladung (Wh)
|
||||
my $btotin = ReadingsNum ($badev, $bin, 0) * $binuf; # totale Batterieladung (Wh)
|
||||
my $batcharge = ReadingsNum ($badev, $batchr, 50);
|
||||
|
||||
my $params;
|
||||
|
||||
@ -2678,7 +2683,7 @@ sub _transferBatteryValues {
|
||||
$batinthishour = 0;
|
||||
}
|
||||
|
||||
$data{$type}{$name}{circular}{sprintf("%02d",$nhour)}{batin} = $batinthishour; # Ringspeicher Battery In Forum: https://forum.fhem.de/index.php/topic,117864.msg1133350.html#msg1133350
|
||||
$data{$type}{$name}{circular}{sprintf("%02d",$nhour)}{batin} = $batinthishour; # Ringspeicher Battery In Forum: https://forum.fhem.de/index.php/topic,117864.msg1133350.html#msg1133350
|
||||
|
||||
$paref->{batinthishour} = $batinthishour;
|
||||
$paref->{nhour} = sprintf("%02d",$nhour);
|
||||
@ -2698,7 +2703,7 @@ sub _transferBatteryValues {
|
||||
setPVhistory ($paref);
|
||||
delete $paref->{histname};
|
||||
|
||||
my $botot = CurrentVal ($hash, "batouttotal", $btotout);
|
||||
my $botot = CurrentVal ($hash, "batouttotal", $btotout);
|
||||
$batoutthishour = int ($btotout - $botot);
|
||||
}
|
||||
else {
|
||||
@ -2723,11 +2728,13 @@ sub _transferBatteryValues {
|
||||
push @$daref, "Today_Hour".sprintf("%02d",$nhour)."_BatOut<>".$batoutthishour." Wh";
|
||||
push @$daref, "Current_PowerBatIn<>". (int $pbi)." W";
|
||||
push @$daref, "Current_PowerBatOut<>".(int $pbo)." W";
|
||||
push @$daref, "Current_BatCharge<>". $batcharge." %";
|
||||
|
||||
$data{$type}{$name}{current}{powerbatin} = int $pbi; # Hilfshash Wert aktuelle Batterieladung
|
||||
$data{$type}{$name}{current}{powerbatout} = int $pbo; # Hilfshash Wert aktuelle Batterieentladung
|
||||
$data{$type}{$name}{current}{batintotal} = int $btotin; # totale Batterieladung
|
||||
$data{$type}{$name}{current}{batouttotal} = int $btotout; # totale Batterieentladung
|
||||
$data{$type}{$name}{current}{batcharge} = $batcharge; # aktuelle Batterieladung
|
||||
|
||||
return;
|
||||
}
|
||||
@ -3204,39 +3211,13 @@ return;
|
||||
# FHEMWEB Fn
|
||||
################################################################
|
||||
sub FwFn {
|
||||
my ($FW_wname, $name, $room, $pageHash) = @_; # pageHash is set for summaryFn.
|
||||
my ($FW_wname, $name, $room, $pageHash) = @_; # pageHash is set for summaryFn.
|
||||
my $hash = $defs{$name};
|
||||
my $height;
|
||||
|
||||
RemoveInternalTimer($hash, \&pageRefresh);
|
||||
$hash->{HELPER}{FW} = $FW_wname;
|
||||
|
||||
my $foreg = forecastGraphic ($name);
|
||||
|
||||
my $flowgh = AttrVal ($name, "flowGraphicSize", 300);
|
||||
my $flowg = flowGraphic ($name, $flowgh);
|
||||
|
||||
my $alias = AttrVal($name, "alias", $name); # Linktext als Aliasname oder Devicename setzen
|
||||
my $dlink = qq{<a href="$FW_ME$FW_subdir?detail=$name">$alias</a>};
|
||||
|
||||
my $ret = q{};
|
||||
|
||||
if(IsDisabled($name)) {
|
||||
$height = AttrNum($name, 'beamHeight', 200);
|
||||
$ret .= "<table class='roomoverview'>";
|
||||
$ret .= "<tr style='height:".$height."px'>";
|
||||
$ret .= "<td>";
|
||||
$ret .= qq{Solar forecast graphic device <a href="$FW_ME$FW_subdir?detail=$name">$name</a> is disabled};
|
||||
$ret .= "</td>";
|
||||
$ret .= "</tr>";
|
||||
$ret .= "</table>";
|
||||
}
|
||||
else {
|
||||
$ret .= "<span>$dlink </span><br>" if(AttrVal($name,"showLink",0));
|
||||
$ret .= $foreg;
|
||||
$ret .= "\n";
|
||||
$ret .= $flowg;
|
||||
}
|
||||
my $ret = entryGraphic ($name);
|
||||
|
||||
# Autorefresh nur des aufrufenden FHEMWEB-Devices
|
||||
my $al = AttrVal($name, "autoRefresh", 0);
|
||||
@ -3277,40 +3258,170 @@ sub pageAsHtml {
|
||||
my $hash = shift;
|
||||
my $ftui = shift;
|
||||
my $name = $hash->{NAME};
|
||||
my $height;
|
||||
|
||||
my $link = forecastGraphic ($name, $ftui);
|
||||
|
||||
my $alias = AttrVal($name, "alias", $name); # Linktext als Aliasname oder Devicename setzen
|
||||
my $dlink = "<a href=\"$FW_ME$FW_subdir?detail=$name\">$alias</a>";
|
||||
|
||||
my $ret = "<html>";
|
||||
if(IsDisabled($name)) {
|
||||
$height = AttrNum($name, 'beamHeight', 200);
|
||||
$ret .= "<table class='roomoverview'>";
|
||||
$ret .= "<tr style='height:".$height."px'>";
|
||||
$ret .= "<td>";
|
||||
$ret .= qq{Solar Forecast Device <a href="$FW_ME$FW_subdir?detail=$name">$name</a> is disabled};
|
||||
$ret .= "</td>";
|
||||
$ret .= "</tr>";
|
||||
$ret .= "</table>";
|
||||
$ret .= entryGraphic ($name);
|
||||
$ret .= "</html>";
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Einstieg Grafikanzeige
|
||||
################################################################
|
||||
sub entryGraphic {
|
||||
my $name = shift;
|
||||
my $ftui = shift // "";
|
||||
|
||||
my $hash = $defs{$name};
|
||||
|
||||
# Setup Vollständigkeit prüfen
|
||||
###############################
|
||||
my $incomplete = _checkSetupComplete ($hash);
|
||||
return $incomplete if($incomplete);
|
||||
|
||||
# Parameter f. Anzeige extrahieren
|
||||
###################################
|
||||
my $width = AttrNum ($name, 'beamWidth', 6); # zu klein ist nicht problematisch
|
||||
my $maxhours = AttrNum ($name, 'hourCount', 24);
|
||||
my $colorw = AttrVal ($name, 'weatherColor', 'FFFFFF'); # Wetter Icon Farbe
|
||||
|
||||
my $alias = AttrVal ($name, "alias", $name); # Linktext als Aliasname oder Devicename setzen
|
||||
my $gsel = AttrVal ($name, 'graphicSelect', 'both'); # Auswahl der anzuzeigenden Grafiken
|
||||
my $dlink = qq{<a href="$FW_ME$FW_subdir?detail=$name">$alias</a>};
|
||||
|
||||
my $ret = q{};
|
||||
|
||||
return $ret if ($gsel eq "none");
|
||||
|
||||
my $params = {
|
||||
hash => $hash,
|
||||
name => $name,
|
||||
ftui => $ftui,
|
||||
maxhours => $maxhours,
|
||||
offset => AttrNum ($name, 'historyHour', 0),
|
||||
hourstyle => AttrVal ($name, 'hourStyle', ''),
|
||||
colorfc => AttrVal ($name, 'beam1Color', '000000'),
|
||||
colorc => AttrVal ($name, 'beam2Color', 'C4C4A7'),
|
||||
fcolor1 => AttrVal ($name, 'beam1FontColor', 'C4C4A7'),
|
||||
fcolor2 => AttrVal ($name, 'beam2FontColor', '000000'),
|
||||
beam1cont => AttrVal ($name, 'beam1Content', 'pvForecast'),
|
||||
beam2cont => AttrVal ($name, 'beam2Content', 'pvForecast'),
|
||||
icon => AttrVal ($name, 'consumerAdviceIcon', undef),
|
||||
html_start => AttrVal ($name, 'htmlStart', undef), # beliebige HTML Strings die vor der Grafik ausgegeben werden
|
||||
html_end => AttrVal ($name, 'htmlEnd', undef), # beliebige HTML Strings die nach der Grafik ausgegeben werden
|
||||
lotype => AttrVal ($name, 'layoutType', 'single'),
|
||||
kw => AttrVal ($name, 'Wh/kWh', 'Wh'),
|
||||
height => AttrNum ($name, 'beamHeight', 200),
|
||||
width => $width,
|
||||
w => $width * $maxhours, # gesammte Breite der Ausgabe , WetterIcon braucht ca. 34px
|
||||
fsize => AttrNum ($name, 'spaceSize', 24),
|
||||
maxVal => AttrNum ($name, 'maxValBeam', 0), # dyn. Anpassung der Balkenhöhe oder statisch ?
|
||||
show_night => AttrNum ($name, 'showNight', 0), # alle Balken (Spalten) anzeigen ?
|
||||
show_diff => AttrVal ($name, 'showDiff', 'no'), # zusätzliche Anzeige $di{} in allen Typen
|
||||
weather => AttrNum ($name, 'showWeather', 1),
|
||||
colorw => $colorw,
|
||||
colorwn => AttrVal ($name, 'weatherColorNight', $colorw), # Wetter Icon Farbe Nacht
|
||||
wlalias => AttrVal ($name, 'alias', $name),
|
||||
header => AttrNum ($name, 'showHeader', 1),
|
||||
hdrAlign => AttrVal ($name, 'headerAlignment', 'center'), # ermöglicht per attr die Ausrichtung der Tabelle zu setzen
|
||||
hdrDetail => AttrVal ($name, 'headerDetail', 'all'), # ermöglicht den Inhalt zu begrenzen, um bspw. passgenau in ftui einzubetten
|
||||
lang => AttrVal ("global", 'language', 'EN'),
|
||||
flowgh => AttrVal ($name, 'flowGraphicSize', $defflowGSize), # Größe Energieflußgrafik
|
||||
};
|
||||
|
||||
if(IsDisabled($name)) {
|
||||
$ret .= "<table class='roomoverview'>";
|
||||
$ret .= "<tr style='height:".$params->{height}."px'>";
|
||||
$ret .= "<td>";
|
||||
$ret .= qq{SolarForecast device <a href="$FW_ME$FW_subdir?detail=$name">$name</a> is disabled};
|
||||
$ret .= "</td>";
|
||||
$ret .= "</tr>";
|
||||
$ret .= "</table>";
|
||||
}
|
||||
else {
|
||||
$ret .= "<span>$dlink </span><br>" if(AttrVal($name,"showLink",0));
|
||||
$ret .= $link;
|
||||
}
|
||||
$ret .= "</html>";
|
||||
|
||||
$ret .= forecastGraphic ($params) if($gsel eq "both" || $gsel eq "forecast");
|
||||
$ret .= "\n";
|
||||
$ret .= flowGraphic ($params) if($gsel eq "both" || $gsel eq "flow");
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Vollständigkeit Setup prüfen
|
||||
################################################################
|
||||
sub _checkSetupComplete {
|
||||
my $hash = shift;
|
||||
my $ret = q{};
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $is = ReadingsVal ($name, "inverterStrings", undef); # String Konfig
|
||||
my $fcdev = ReadingsVal ($name, "currentForecastDev", undef); # Forecast Device (Wetter)
|
||||
my $radev = ReadingsVal ($name, "currentRadiationDev", undef); # Forecast Device (Wetter)
|
||||
my $indev = ReadingsVal ($name, "currentInverterDev", undef); # Inverter Device
|
||||
my $medev = ReadingsVal ($name, "currentMeterDev", undef); # Meter Device
|
||||
my $peak = ReadingsVal ($name, "modulePeakString", undef); # String Peak
|
||||
my $pv0 = NexthoursVal ($hash, "NextHour00", "pvforecast", undef);
|
||||
my $dir = ReadingsVal ($name, "moduleDirection", undef); # Modulausrichtung Konfig
|
||||
my $ta = ReadingsVal ($name, "moduleTiltAngle", undef); # Modul Neigungswinkel Konfig
|
||||
|
||||
if(!$is || !$fcdev || !$radev || !$indev || !$medev || !$peak || !defined $pv0 || !$dir || !$ta) {
|
||||
my $link = qq{<a href="$FW_ME$FW_subdir?detail=$name">$name</a>};
|
||||
my $height = AttrNum ($name, 'beamHeight', 200);
|
||||
my $lang = AttrVal ("global", "language", "EN");
|
||||
|
||||
$ret .= "<table class='roomoverview'>";
|
||||
$ret .= "<tr style='height:".$height."px'>";
|
||||
$ret .= "<td>";
|
||||
|
||||
if(!$fcdev) { ## no critic 'Cascading'
|
||||
$ret .= $hqtxt{cfd}{$lang};
|
||||
}
|
||||
elsif(!$radev) {
|
||||
$ret .= $hqtxt{crd}{$lang};
|
||||
}
|
||||
elsif(!$indev) {
|
||||
$ret .= $hqtxt{cid}{$lang};
|
||||
}
|
||||
elsif(!$medev) {
|
||||
$ret .= $hqtxt{mid}{$lang};
|
||||
}
|
||||
elsif(!$is) {
|
||||
$ret .= $hqtxt{ist}{$lang};
|
||||
}
|
||||
elsif(!$peak) {
|
||||
$ret .= $hqtxt{mps}{$lang};
|
||||
}
|
||||
elsif(!$dir) {
|
||||
$ret .= $hqtxt{mdr}{$lang};
|
||||
}
|
||||
elsif(!$ta) {
|
||||
$ret .= $hqtxt{mta}{$lang};
|
||||
}
|
||||
elsif(!defined $pv0) {
|
||||
$ret .= $hqtxt{awd}{$lang};
|
||||
}
|
||||
|
||||
$ret .= "</td>";
|
||||
$ret .= "</tr>";
|
||||
$ret .= "</table>";
|
||||
$ret =~ s/LINK/$link/gxs;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Vorhersagegrafik
|
||||
###############################################################################
|
||||
sub forecastGraphic { ## no critic 'complexity'
|
||||
my $name = shift;
|
||||
my $ftui = shift // "";
|
||||
my $hash = $defs{$name};
|
||||
my $paref = shift;
|
||||
my $hash = $paref->{hash};
|
||||
my $name = $paref->{name};
|
||||
my $ftui = $paref->{ftui};
|
||||
|
||||
my $ret = "";
|
||||
|
||||
@ -3324,12 +3435,6 @@ sub forecastGraphic {
|
||||
$hash->{HELPER}{SPGROOM} = $FW_room ? $FW_room : ""; # Raum aus dem das SMAPortalSPG-Device die Funktion aufrief
|
||||
$hash->{HELPER}{SPGDETAIL} = $FW_detail ? $FW_detail : ""; # Name des SMAPortalSPG-Devices (wenn Detailansicht)
|
||||
|
||||
# Setup Vollständigkeit prüfen
|
||||
###############################
|
||||
my $incomplete = _checkSetupComplete ($hash);
|
||||
return $incomplete if($incomplete);
|
||||
|
||||
|
||||
# Verbraucherlegende und Steuerung
|
||||
###################################
|
||||
my $legend_txt;
|
||||
@ -3377,35 +3482,35 @@ sub forecastGraphic {
|
||||
|
||||
# Parameter f. Anzeige extrahieren
|
||||
###################################
|
||||
my $maxhours = AttrNum ($name, 'hourCount', 24);
|
||||
my $offset = AttrNum ($name, 'historyHour', 0);
|
||||
my $hourstyle = AttrVal ($name, 'hourStyle', '');
|
||||
my $colorfc = AttrVal ($name, 'beam1Color', '000000');
|
||||
my $colorc = AttrVal ($name, 'beam2Color', 'C4C4A7');
|
||||
my $fcolor1 = AttrVal ($name, 'beam1FontColor', 'C4C4A7');
|
||||
my $fcolor2 = AttrVal ($name, 'beam2FontColor', '000000');
|
||||
my $beam1cont = AttrVal ($name, 'beam1Content', 'pvForecast');
|
||||
my $beam2cont = AttrVal ($name, 'beam2Content', 'pvForecast');
|
||||
my $icon = AttrVal ($name, 'consumerAdviceIcon', undef);
|
||||
my $html_start = AttrVal ($name, 'htmlStart', undef); # beliebige HTML Strings die vor der Grafik ausgegeben werden
|
||||
my $html_end = AttrVal ($name, 'htmlEnd', undef); # beliebige HTML Strings die nach der Grafik ausgegeben werden
|
||||
my $lotype = AttrVal ($name, 'layoutType', 'single');
|
||||
my $kw = AttrVal ($name, 'Wh/kWh', 'Wh');
|
||||
my $height = AttrNum ($name, 'beamHeight', 200);
|
||||
my $width = AttrNum ($name, 'beamWidth', 6); # zu klein ist nicht problematisch
|
||||
my $w = $width*$maxhours; # gesammte Breite der Ausgabe , WetterIcon braucht ca. 34px
|
||||
my $fsize = AttrNum ($name, 'spaceSize', 24);
|
||||
my $maxVal = AttrNum ($name, 'maxValBeam', 0); # dyn. Anpassung der Balkenhöhe oder statisch ?
|
||||
my $show_night = AttrNum ($name, 'showNight', 0); # alle Balken (Spalten) anzeigen ?
|
||||
my $show_diff = AttrVal ($name, 'showDiff', 'no'); # zusätzliche Anzeige $di{} in allen Typen
|
||||
my $weather = AttrNum ($name, 'showWeather', 1);
|
||||
my $colorw = AttrVal ($name, 'weatherColor', 'FFFFFF'); # Wetter Icon Farbe
|
||||
my $colorwn = AttrVal ($name, 'weatherColorNight', $colorw); # Wetter Icon Farbe Nacht
|
||||
my $wlalias = AttrVal ($name, 'alias', $name);
|
||||
my $header = AttrNum ($name, 'showHeader', 1);
|
||||
my $hdrAlign = AttrVal ($name, 'headerAlignment', 'center'); # ermöglicht per attr die Ausrichtung der Tabelle zu setzen
|
||||
my $hdrDetail = AttrVal ($name, 'headerDetail', 'all'); # ermöglicht den Inhalt zu begrenzen, um bspw. passgenau in ftui einzubetten
|
||||
my $lang = AttrVal ("global", 'language', 'EN');
|
||||
my $maxhours = $paref->{maxhours};
|
||||
my $offset = $paref->{offset};
|
||||
my $hourstyle = $paref->{hourstyle};
|
||||
my $colorfc = $paref->{colorfc};
|
||||
my $colorc = $paref->{colorc};
|
||||
my $fcolor1 = $paref->{fcolor1};
|
||||
my $fcolor2 = $paref->{fcolor2};
|
||||
my $beam1cont = $paref->{beam1cont};
|
||||
my $beam2cont = $paref->{beam2cont};
|
||||
my $icon = $paref->{icon};
|
||||
my $html_start = $paref->{html_start}; # beliebige HTML Strings die vor der Grafik ausgegeben werden
|
||||
my $html_end = $paref->{html_end}; # beliebige HTML Strings die nach der Grafik ausgegeben werden
|
||||
my $lotype = $paref->{lotype};
|
||||
my $kw = $paref->{kw};
|
||||
my $height = $paref->{height};
|
||||
my $width = $paref->{width}; # zu klein ist nicht problematisch
|
||||
my $w = $paref->{w}; # gesammte Breite der Ausgabe , WetterIcon braucht ca. 34px
|
||||
my $fsize = $paref->{fsize};
|
||||
my $maxVal = $paref->{maxVal}; # dyn. Anpassung der Balkenhöhe oder statisch ?
|
||||
my $show_night = $paref->{show_night}; # alle Balken (Spalten) anzeigen ?
|
||||
my $show_diff = $paref->{show_diff}; # zusätzliche Anzeige $di{} in allen Typen
|
||||
my $weather = $paref->{weather};
|
||||
my $colorw = $paref->{colorw}; # Wetter Icon Farbe
|
||||
my $colorwn = $paref->{colorwn}; # Wetter Icon Farbe Nacht
|
||||
my $wlalias = $paref->{wlalias};
|
||||
my $header = $paref->{header};
|
||||
my $hdrAlign = $paref->{hdrAlign}; # ermöglicht per attr die Ausrichtung der Tabelle zu setzen
|
||||
my $hdrDetail = $paref->{hdrDetail}; # ermöglicht den Inhalt zu begrenzen, um bspw. passgenau in ftui einzubetten
|
||||
my $lang = $paref->{lang};
|
||||
|
||||
# Icon Erstellung, mit @<Farbe> ergänzen falls einfärben
|
||||
# Beispiel mit Farbe: $icon = FW_makeImage('light_light_dim_100.svg@green');
|
||||
@ -4079,202 +4184,141 @@ sub forecastGraphic {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Vollständigkeit Setup prüfen
|
||||
################################################################
|
||||
sub _checkSetupComplete {
|
||||
my $hash = shift;
|
||||
my $ret = q{};
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $is = ReadingsVal ($name, "inverterStrings", undef); # String Konfig
|
||||
my $fcdev = ReadingsVal ($name, "currentForecastDev", undef); # Forecast Device (Wetter)
|
||||
my $radev = ReadingsVal ($name, "currentRadiationDev", undef); # Forecast Device (Wetter)
|
||||
my $indev = ReadingsVal ($name, "currentInverterDev", undef); # Inverter Device
|
||||
my $medev = ReadingsVal ($name, "currentMeterDev", undef); # Meter Device
|
||||
my $peak = ReadingsVal ($name, "modulePeakString", undef); # String Peak
|
||||
my $pv0 = NexthoursVal ($hash, "NextHour00", "pvforecast", undef);
|
||||
my $dir = ReadingsVal ($name, "moduleDirection", undef); # Modulausrichtung Konfig
|
||||
my $ta = ReadingsVal ($name, "moduleTiltAngle", undef); # Modul Neigungswinkel Konfig
|
||||
|
||||
if(!$is || !$fcdev || !$radev || !$indev || !$medev || !$peak || !defined $pv0 || !$dir || !$ta) {
|
||||
my $link = qq{<a href="$FW_ME$FW_subdir?detail=$name">$name</a>};
|
||||
my $height = AttrNum ($name, 'beamHeight', 200);
|
||||
my $lang = AttrVal ("global", "language", "EN");
|
||||
|
||||
$ret .= "<table class='roomoverview'>";
|
||||
$ret .= "<tr style='height:".$height."px'>";
|
||||
$ret .= "<td>";
|
||||
|
||||
if(!$fcdev) { ## no critic 'Cascading'
|
||||
$ret .= $hqtxt{cfd}{$lang};
|
||||
}
|
||||
elsif(!$radev) {
|
||||
$ret .= $hqtxt{crd}{$lang};
|
||||
}
|
||||
elsif(!$indev) {
|
||||
$ret .= $hqtxt{cid}{$lang};
|
||||
}
|
||||
elsif(!$medev) {
|
||||
$ret .= $hqtxt{mid}{$lang};
|
||||
}
|
||||
elsif(!$is) {
|
||||
$ret .= $hqtxt{ist}{$lang};
|
||||
}
|
||||
elsif(!$peak) {
|
||||
$ret .= $hqtxt{mps}{$lang};
|
||||
}
|
||||
elsif(!$dir) {
|
||||
$ret .= $hqtxt{mdr}{$lang};
|
||||
}
|
||||
elsif(!$ta) {
|
||||
$ret .= $hqtxt{mta}{$lang};
|
||||
}
|
||||
elsif(!defined $pv0) {
|
||||
$ret .= $hqtxt{awd}{$lang};
|
||||
}
|
||||
|
||||
$ret .= "</td>";
|
||||
$ret .= "</tr>";
|
||||
$ret .= "</table>";
|
||||
$ret =~ s/LINK/$link/gxs;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Energieflußgrafik
|
||||
################################################################
|
||||
sub flowGraphic {
|
||||
my $name = shift;
|
||||
my $h = shift;
|
||||
my $paref = shift;
|
||||
my $name = $paref->{name};
|
||||
my $flowgh = $paref->{flowgh};
|
||||
|
||||
my $fs = ($h < 300) ? '48px' : '32px';
|
||||
my $style = 'width:'.$h.'px; height:'.$h.'px;';
|
||||
my $style = 'width:'.$flowgh.'px; height:'.$flowgh.'px;';
|
||||
my $fs = ($flowgh < 300) ? '48px' : '32px';
|
||||
|
||||
my $inactive = 'stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2;';
|
||||
my $active = 'stroke-dashoffset: 20; stroke-dasharray: 10; animation: dash 0.5s linear; animation-iteration-count: infinite; opacity: 0.8;' ;
|
||||
my $inactive = 'stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2;';
|
||||
my $active = 'stroke-dashoffset: 20; stroke-dasharray: 10; animation: dash 0.5s linear; animation-iteration-count: infinite; opacity: 0.8;' ;
|
||||
|
||||
my $cpv = ReadingsNum($name, 'Current_PV', 0);
|
||||
my $sun_color = ($cpv) ? 'orange' : 'gray';
|
||||
my $cpv = ReadingsNum($name, 'Current_PV', 0);
|
||||
my $sun_color = ($cpv) ? 'orange' : 'gray';
|
||||
|
||||
my $cgc = ReadingsNum($name, 'Current_GridConsumption', 0);
|
||||
my $cgc_style = ($cgc) ? $active : $inactive;
|
||||
my $cgc_color = ($cgc) ? 'red' : 'gray';
|
||||
my $cgc = ReadingsNum($name, 'Current_GridConsumption', 0);
|
||||
my $cgc_style = ($cgc) ? $active : $inactive;
|
||||
my $cgc_color = ($cgc) ? 'red' : 'gray';
|
||||
|
||||
my $cgfi = ReadingsNum($name, 'Current_GridFeedIn', 0);
|
||||
my $cgfi_style = ($cgfi) ? $active : $inactive;
|
||||
my $cgfi_color = ($cgfi) ? 'yellow' : 'gray';
|
||||
my $cgfi = ReadingsNum($name, 'Current_GridFeedIn', 0);
|
||||
my $cgfi_style = ($cgfi) ? $active : $inactive;
|
||||
my $cgfi_color = ($cgfi) ? 'yellow' : 'gray';
|
||||
|
||||
my $csc = ReadingsNum($name, 'Current_SelfConsumption', 0);
|
||||
my $csc_style = ($csc) ? $active : $inactive;
|
||||
my $csc_color = ($csc) ? 'yellow' : 'gray';
|
||||
my $csc = ReadingsNum($name, 'Current_SelfConsumption', 0);
|
||||
my $csc_style = ($csc) ? $active : $inactive;
|
||||
my $csc_color = ($csc) ? 'yellow' : 'gray';
|
||||
|
||||
my $batin = ReadingsNum($name, 'Current_PowerBatIn', 0);
|
||||
my $batin_style = ($batin) ? $active : $inactive;
|
||||
my $batin_color = ($batin) ? 'yellow' : 'gray';
|
||||
my $batin = ReadingsNum($name, 'Current_PowerBatIn', undef);
|
||||
my $batout = ReadingsNum($name, 'Current_PowerBatOut', undef);
|
||||
my $soc = ReadingsNum($name, 'Current_BatCharge', 100);
|
||||
my $batcolor = ($soc > 10) ? 'green' : 'red';
|
||||
my $hasbat = 1;
|
||||
|
||||
my $batout = ReadingsNum($name, 'Current_PowerBatOut' , 0);
|
||||
my $batout_style = ($batout) ? $active : $inactive;
|
||||
my $batout_color = ($batout) ? 'yellow' : 'gray';
|
||||
if (!defined($batin) && !defined($batout)) {
|
||||
$hasbat = 0;
|
||||
$batin = 0;
|
||||
$batout = 0;
|
||||
$soc = 0;
|
||||
}
|
||||
|
||||
my $grid_color = ($cgfi) ? 'green' : 'red';
|
||||
$grid_color = 'gray' if (!$cgfi && !$cgc && $batout); # dritte Farbe
|
||||
my $batin_style = ($batin) ? $active : $inactive;
|
||||
my $batin_color = ($batin) ? 'yellow' : 'gray';
|
||||
my $batout_style = ($batout) ? $active : $inactive;
|
||||
my $batout_color = ($batout) ? 'yellow' : 'gray';
|
||||
|
||||
my $ret = qq{
|
||||
<table class="roomoverview">
|
||||
<tr><td><table class="block fbcalllist"><tr align="center"><td>
|
||||
my $grid_color = ($cgfi) ? 'green' : 'red';
|
||||
$grid_color = 'gray' if (!$cgfi && !$cgc && $batout); # dritte Farbe
|
||||
|
||||
my $ret = qq{
|
||||
<table class="roomoverview">
|
||||
<tr><td><table class="block"><tr align="center"><td>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" style="$style">
|
||||
<g transform="translate(200,50)">
|
||||
<g>
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(45)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(90)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(135)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(180)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(225)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(270)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(315)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<circle cx="0" cy="0" fill="$sun_color" r="16" stroke="orange" stroke-width="2"/>
|
||||
</g>
|
||||
|
||||
<g id="home" fill="grey" transform="translate(0,150),scale(4)">
|
||||
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
|
||||
</g>
|
||||
|
||||
<g id="grid" fill="$grid_color" transform="translate(150,310),scale(3.5)">
|
||||
<path d="M15.3,2H8.7L2,6.46V10H4V8H8v2.79l-4,9V22H6V20.59l6-3.27,6,3.27V22h2V19.79l-4-9V8h4v2h2V6.46ZM14,4V6H10V4ZM6.3,6,8,4.87V6Zm8,6L15,13.42,12,15,9,13.42,9.65,12ZM7.11,17.71,8.2,15.25l1.71.93Zm8.68-2.46,1.09,2.46-2.8-1.53ZM14,10H10V8h4Zm2-5.13L17.7,6H16Z"/>
|
||||
</g>
|
||||
};
|
||||
|
||||
|
||||
if ($hasbat) {
|
||||
$ret .= qq{
|
||||
<g fill="$batcolor" stroke="$batcolor" transform="translate(270,135),scale(.33)">
|
||||
<path d="m 134.65625,89.15625 c -6.01649,0 -11,4.983509 -11,11 l 0,180 c 0,6.01649 4.98351,11 11,11 l 95.5,0 c 6.01631,0 11,-4.9825 11,-11 l 0,-180 c 0,-6.016491 -4.98351,-11 -11,-11 l -95.5,0 z m 0,10 95.5,0 c 0.60951,0 1,0.390491 1,1 l 0,180 c 0,0.6085 -0.39231,1 -1,1 l -95.5,0 c -0.60951,0 -1,-0.39049 -1,-1 l 0,-180 c 0,-0.609509 0.39049,-1 1,-1 z"/>
|
||||
<path d="m 169.625,69.65625 c -6.01649,0 -11,4.983509 -11,11 l 0,14 10,0 0,-14 c 0,-0.609509 0.39049,-1 1,-1 l 25.5,0 c 0.60951,0 1,0.390491 1,1 l 0,14 10,0 0,-14 c 0,-6.016491 -4.98351,-11 -11,-11 l -25.5,0 z"/>
|
||||
};
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" style="$style">
|
||||
|
||||
<g fill="$sun_color" transform="translate(150,90) scale(0.03,-0.03)" stroke="none">
|
||||
<path d="M715 2608 c-28 -15 -45 -38 -45 -62 0 -12 63 -83 167 -188 179 -180 199 -192 243 -148 43 43 31 63 -142 236 -90 89 -172 165 -183 168 -11 3 -29 0 -40 -6z"/>
|
||||
<path d="M1207 2609 c-38 -22 -39 -55 -5 -136 35 -86 57 -113 91 -113 31 0 67 35 67 65 0 36 -49 147 -77 173 -26 24 -48 27 -76 11z"/>
|
||||
<path d="M1373 2236 c-103 -33 -194 -114 -241 -214 l-27 -57 0 -295 0 -295 33 -67 c39 -81 121 -158 202 -190 51 -21 73 -23 328 -26 229 -3 282 -1 330 13 125 36 226 134 263 255 19 63 20 88 17 337 l-3 269 -32 65 c-39 80 -111 150 -191 187 l-57 27 -290 2 c-220 2 -300 -1 -332 -11z m633 -143 c57 -30 111 -97 129 -157 21 -71 21 -461 0 -532 -19 -63 -72 -126 -133 -156 -46 -22 -54 -23 -312 -23 -258 0 -266 1 -312 23 -27 13 -64 42 -83 65 -60 70 -67 114 -63 385 3 261 5 270 72 340 71 76 98 81 406 79 242 -2 257 -3 296 -24z"/>
|
||||
<path d="M585 2130 c-23 -25 -22 -67 1 -90 31 -30 264 -119 288 -111 33 12 52 54 41 87 -9 24 -29 36 -135 81 -135 58 -168 63 -195 33z"/>
|
||||
<path d="M20 1720 c-27 -27 -25 -66 5 -96 l25 -25 416 3 c398 3 416 4 430 22 20 28 17 73 -6 96 -19 19 -33 20 -435 20 -402 0 -416 -1 -435 -20z"/>
|
||||
<path d="M2400 1380 c-25 -25 -26 -64 -2 -88 18 -18 159 -82 180 -82 24 0 62 43 62 71 0 37 -21 54 -105 90 -79 34 -108 36 -135 9z"/>
|
||||
<path d="M725 1325 c-128 -54 -155 -72 -155 -106 0 -27 39 -69 65 -69 37 0 248 91 273 118 35 37 18 91 -33 106 -12 3 -70 -15 -150 -49z"/>
|
||||
<path d="M733 817 c-260 -260 -293 -296 -293 -324 0 -35 38 -73 73 -73 14 0 119 97 314 292 262 262 293 296 293 325 0 35 -38 73 -74 73 -14 0 -116 -95 -313 -293z"/>
|
||||
<path d="M2225 1085 c-14 -13 -25 -34 -25 -46 0 -16 51 -74 167 -191 145 -146 171 -168 199 -168 37 0 67 29 67 66 0 22 -35 61 -170 195 -118 118 -176 169 -192 169 -12 0 -33 -11 -46 -25z"/>
|
||||
<path d="M1970 932 c-28 -9 -50 -35 -50 -59 0 -32 88 -243 114 -271 27 -31 72 -26 99 10 l20 27 -49 122 c-63 156 -86 186 -134 171z"/>
|
||||
<path d="M1288 913 c-16 -17 -118 -254 -118 -271 0 -5 9 -21 21 -36 25 -32 70 -35 97 -6 22 23 113 246 112 276 0 48 -80 73 -112 37z"/>
|
||||
<path d="M1620 902 l-25 -20 0 -415 c0 -394 1 -416 19 -436 24 -26 77 -28 99 -3 15 17 17 61 17 433 0 317 -3 419 -12 432 -21 27 -70 32 -98 9z"/>
|
||||
</g>
|
||||
|
||||
<g transform="translate(200,50)">
|
||||
<g>
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(45)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(90)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(135)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(180)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(225)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(270)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<g transform="rotate(315)">
|
||||
<line fill="none" stroke="$sun_color" stroke-linecap="round" stroke-width="5" transform="translate(0,9)" x1="0" x2="0" y1="16" y2="24" />
|
||||
</g>
|
||||
<circle cx="0" cy="0" fill="$sun_color" r="16" stroke="orange" stroke-width="2"/>
|
||||
</g>
|
||||
|
||||
<g id="home" fill="grey" transform="translate(0,150),scale(4)">
|
||||
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/>
|
||||
</g>
|
||||
|
||||
<g id="grid" fill="$grid_color" transform="translate(150,310),scale(3.5)">
|
||||
<path d="M15.3,2H8.7L2,6.46V10H4V8H8v2.79l-4,9V22H6V20.59l6-3.27,6,3.27V22h2V19.79l-4-9V8h4v2h2V6.46ZM14,4V6H10V4ZM6.3,6,8,4.87V6Zm8,6L15,13.42,12,15,9,13.42,9.65,12ZM7.11,17.71,8.2,15.25l1.71.93Zm8.68-2.46,1.09,2.46-2.8-1.53ZM14,10H10V8h4Zm2-5.13L17.7,6H16Z"/>
|
||||
</g>
|
||||
|
||||
<g id="battery" fill="#090" stroke="#090" transform="translate(300,170),scale(.2)">
|
||||
<line x1="75" y1="30" x2="75" y2="280" style="stroke-width: 12px;"></line>
|
||||
<line x1="225" y1="30" x2="225" y2="280" style="stroke-width: 12px;"></line>
|
||||
<line x1="69" y1="30" x2="231" y2="30" style="stroke-width: 12px;"></line>
|
||||
<line x1="69" y1="284" x2="231" y2="285" style="stroke-width: 12px;"></line>
|
||||
<line x1="105" y1="20" x2="195" y2="20" style="stroke-width: 25px;"></line>
|
||||
|
||||
<rect id="bat25" x="92" y="221" width="116" height="48" style="stroke-width:0px;"></rect>
|
||||
<rect id="bat50" x="92" y="163" width="116" height="48" style="stroke-width:0px;"></rect>
|
||||
<rect id="bat75" x="92" y="105" width="116" height="48" style="stroke-width:0px;"></rect>
|
||||
<rect id="bat100" x="92" y="47" width="116" height="48" style="stroke-width:0px;"></rect>
|
||||
</g>
|
||||
|
||||
<g transform="translate(50,50),scale(0.5)" stroke-width="27" fill="none">
|
||||
$ret .= '<path d="m 221.141,266.334 c 0,3.313 -2.688,6 -6,6 h -65.5 c -3.313,0 -6,-2.688 -6,-6 v -6 c 0,-3.314 2.687,-6 6,-6 l 65.5,-20 c 3.313,0 6,2.686 6,6 v 26 z"/>' if ($soc > 24);
|
||||
$ret .= '<path d="m 221.141,213.667 c 0,3.313 -2.688,6 -6,6 l -65.5,20 c -3.313,0 -6,-2.687 -6,-6 v -20 c 0,-3.313 2.687,-6 6,-6 l 65.5,-20 c 3.313,0 6,2.687 6,6 v 20 z"/>' if ($soc > 49);
|
||||
$ret .= '<path d="m 221.141,166.667 c 0,3.313 -2.688,6 -6,6 l -65.5,20 c -3.313,0 -6,-2.687 -6,-6 v -20 c 0,-3.313 2.687,-6 6,-6 l 65.5,-20 c 3.313,0 6,2.687 6,6 v 20 z"/>' if ($soc > 74);
|
||||
$ret .= '<path d="m 221.141,120 c 0,3.313 -2.688,6 -6,6 l -65.5,20 c -3.313,0 -6,-2.687 -6,-6 v -26 c 0,-3.313 2.687,-6 6,-6 h 65.5 c 3.313,0 6,2.687 6,6 v 6 z"/>' if ($soc > 90);
|
||||
$ret .= '</g>';
|
||||
}
|
||||
|
||||
$ret .= qq{
|
||||
<g transform="translate(50,50),scale(0.5)" stroke-width="27" fill="none">
|
||||
<path id="pv-home" style="$csc_style" d="M270,100 L270,180 C270,270,270,270,180,270 L100,270" stroke="$csc_color" />
|
||||
<text id="pv-home-txt" x="210" y="240" style="fill: #ccc; font-size: $fs; text-anchor: end;">$csc</text>
|
||||
|
||||
<path id="pv-grid" style="$cgfi_style" d="M300,100 L300,500" stroke="$cgfi_color" />
|
||||
<text id="pv-grid-txt" x="330" y="490" style="fill: #ccc; font-size: $fs; text-anchor: start;">$cgfi</text>
|
||||
<text id="pv-grid-txt" x="330" y="490" style="fill: #ccc; font-size: $fs; text-anchor: '
|
||||
};
|
||||
#"
|
||||
|
||||
$ret .= (!$hasbat) ? 'middle;" transform="translate(-120,620) rotate(-90)"' : 'start;"';
|
||||
|
||||
$ret .= qq{
|
||||
>$cgfi</text>
|
||||
<path id="grid-home" style="$cgc_style" d="M270,500 L270,420 C270,330,270,330,180,330 L100,330" stroke="$cgc_color" />
|
||||
<text id="grid-home-txt" x="210" y="390" style="fill: #ccc; font-size: $fs; text-anchor: end;">$cgc</text>
|
||||
};
|
||||
|
||||
|
||||
$ret .= qq{
|
||||
<path id="bat-home" style="$batout_style" d="M500,300 L100,300" stroke="$batout_color" />
|
||||
<text id="bat-home-txt" x="390" y="351" style="fill: #ccc; font-size: $fs; text-anchor: start;">$batout</text>
|
||||
|
||||
<path id="pv-bat" style="$batin_style" d="M330,100 L330,180 C330,270,330,270,420,270 L500,270" stroke="$batin_color" />
|
||||
<text id="pv-bat-txt" x="390" y="245" style="fill: #ccc; font-size: $fs; text-anchor: start;">$batin</text>
|
||||
</g>
|
||||
|
||||
</svg></td></tr></table></td></tr></table>
|
||||
};
|
||||
|
||||
<text x="0" y="500" style="fill: #ccc; font-size: $fs; text-anchor: middle;" transform="translate(150,300) rotate(-90)">$soc %</text>
|
||||
} if ($hasbat);
|
||||
|
||||
$ret .= qq{</g></svg></td></tr></table></td></tr></table>};
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
@ -5750,7 +5794,7 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
|
||||
|
||||
<ul>
|
||||
<a id="SolarForecast-set-currentBatteryDev"></a>
|
||||
<li><b>currentBatteryDev <Meter Device Name> pin=<Readingname>:<Einheit> pout=<Readingname>:<Einheit> [intotal=<Readingname>:<Einheit> outtotal=<Readingname>:<Einheit>] </b> <br><br>
|
||||
<li><b>currentBatteryDev <Meter Device Name> pin=<Readingname>:<Einheit> pout=<Readingname>:<Einheit> [intotal=<Readingname>:<Einheit> outtotal=<Readingname>:<Einheit> charge=<Readingname>] </b> <br><br>
|
||||
|
||||
Legt ein beliebiges Device und seine Readings zur Lieferung der Batterie Leistungsdaten fest.
|
||||
Das Modul geht davon aus dass der numerische Wert der Readings immer positiv ist.
|
||||
@ -5764,6 +5808,7 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
|
||||
<tr><td> <b>pout</b> </td><td>Reading welches die aktuelle Batterieentladung liefert </td></tr>
|
||||
<tr><td> <b>intotal</b> </td><td>Reading welches die totale Batterieladung liefert (fortlaufender Zähler) </td></tr>
|
||||
<tr><td> <b>outtotal</b> </td><td>Reading welches die totale Batterieentladung liefert (fortlaufender Zähler) </td></tr>
|
||||
<tr><td> <b>charge</b> </td><td>Reading welches den aktuellen Ladezustand (in Prozent) liefert </td></tr>
|
||||
<tr><td> <b>Einheit</b> </td><td>die jeweilige Einheit (W,Wh,kW,kWh) </td></tr>
|
||||
</table>
|
||||
</ul>
|
||||
@ -6376,6 +6421,13 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
|
||||
</li>
|
||||
<br>
|
||||
|
||||
<a id="SolarForecast-attr-flowGraphicSize"></a>
|
||||
<li><b>flowGraphicSize <Pixel> </b><br>
|
||||
Größe der Energieflußgrafik sofern angezeigt. Siehe auch Attribut <a href="#SolarForecast-attr-graphicSelect">graphicSelect</a>. <br>
|
||||
(default: 300)
|
||||
</li>
|
||||
<br>
|
||||
|
||||
<a id="SolarForecast-attr-follow70percentRule"></a>
|
||||
<li><b>follow70percentRule</b><br>
|
||||
Wenn gesetzt, wird die prognostizierte Leistung entsprechend der 70% Regel begrenzt. <br><br>
|
||||
@ -6400,6 +6452,21 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
|
||||
</li>
|
||||
<br>
|
||||
|
||||
<a id="SolarForecast-attr-graphicSelect"></a>
|
||||
<li><b>graphicSelect </b><br>
|
||||
Wählt die anzuzeigende interne Grafik des Moduls aus. <br><br>
|
||||
|
||||
<ul>
|
||||
<table>
|
||||
<colgroup> <col width=15%> <col width=85%> </colgroup>
|
||||
<tr><td> <b>flow</b> </td><td>zeigt die Energieflußgrafik an </td></tr>
|
||||
<tr><td> <b>forecast</b> </td><td>zeigt die Verhersagegrafik an </td></tr>
|
||||
<tr><td> <b>both</b> </td><td>zeigt Energiefluß- und Vorhersagegrafik an (default) </td></tr>
|
||||
</table>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
|
||||
<a id="SolarForecast-attr-headerAlignment"></a>
|
||||
<li><b>headerAlignment <center | left | right> </b><br>
|
||||
Ausrichtung der Kopfzeilen. <br>
|
||||
|
Loading…
Reference in New Issue
Block a user