mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
76_SolarForecast: consumption fc calc switch from average to median
git-svn-id: https://svn.fhem.de/fhem/trunk@29520 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
7b9a7f1863
commit
87524638d3
@ -1,5 +1,6 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||||
# Do not insert empty lines here, update check depends on it
|
# Do not insert empty lines here, update check depends on it
|
||||||
|
- change: 76_SolarForecast: consumption fc calc switch from average to median
|
||||||
- change: 76_SolarForecast: Attr graphicBeam1MaxVal, ctrlAreaFactorUsage are
|
- change: 76_SolarForecast: Attr graphicBeam1MaxVal, ctrlAreaFactorUsage are
|
||||||
obsolete
|
obsolete
|
||||||
- bugfix: 76_SolarForecast: fix interruptable key and some minor fixes
|
- bugfix: 76_SolarForecast: fix interruptable key and some minor fixes
|
||||||
|
@ -157,6 +157,7 @@ BEGIN {
|
|||||||
|
|
||||||
# Versions History intern
|
# Versions History intern
|
||||||
my %vNotesIntern = (
|
my %vNotesIntern = (
|
||||||
|
"1.43.3" => "13.01.2025 add Wiki icon in graphic header, _calcConsumptionForecast: switch calc from average to median, edit comref ",
|
||||||
"1.43.2" => "12.01.2025 _batChargeRecmd: bugfix calc socwh, Attr graphicBeam1MaxVal, (experimental) ctrlAreaFactorUsage are obsolete ".
|
"1.43.2" => "12.01.2025 _batChargeRecmd: bugfix calc socwh, Attr graphicBeam1MaxVal, (experimental) ctrlAreaFactorUsage are obsolete ".
|
||||||
"trackFlex now default in DWD Model, replace title Charging recommendation by Charging release ".
|
"trackFlex now default in DWD Model, replace title Charging recommendation by Charging release ".
|
||||||
"_saveEnergyConsumption: add dowrite flag, edit comref ",
|
"_saveEnergyConsumption: add dowrite flag, edit comref ",
|
||||||
@ -254,7 +255,7 @@ my %vNotesIntern = (
|
|||||||
"1.33.0" => "26.09.2024 substitute area factor hash by ___areaFactorFix function ",
|
"1.33.0" => "26.09.2024 substitute area factor hash by ___areaFactorFix function ",
|
||||||
"1.32.0" => "02.09.2024 new attr setupOtherProducerXX, report calculation and storage of negative consumption values ".
|
"1.32.0" => "02.09.2024 new attr setupOtherProducerXX, report calculation and storage of negative consumption values ".
|
||||||
"Forum: https://forum.fhem.de/index.php?msg=1319083 ".
|
"Forum: https://forum.fhem.de/index.php?msg=1319083 ".
|
||||||
"bugfix in _estConsumptionForecast, new ctrlDebug consumption_long ",
|
"bugfix in _calcConsumptionForecast, new ctrlDebug consumption_long ",
|
||||||
"1.31.0" => "20.08.2024 rename attributes ctrlWeatherDevX to setupWeatherDevX ",
|
"1.31.0" => "20.08.2024 rename attributes ctrlWeatherDevX to setupWeatherDevX ",
|
||||||
"1.30.0" => "18.08.2024 new attribute flowGraphicShift, Forum:https://forum.fhem.de/index.php?msg=1318597 ",
|
"1.30.0" => "18.08.2024 new attribute flowGraphicShift, Forum:https://forum.fhem.de/index.php?msg=1318597 ",
|
||||||
"1.29.4" => "03.08.2024 delete writeCacheToFile from _getRoofTopData, _specialActivities: avoid loop caused by \@widgetreadings ",
|
"1.29.4" => "03.08.2024 delete writeCacheToFile from _getRoofTopData, _specialActivities: avoid loop caused by \@widgetreadings ",
|
||||||
@ -487,15 +488,15 @@ my $cfile = 'controls_solarforecast.txt';
|
|||||||
|
|
||||||
|
|
||||||
# initiale Hashes für Stunden Consumption Forecast inkl. und exkl. Verbraucher
|
# initiale Hashes für Stunden Consumption Forecast inkl. und exkl. Verbraucher
|
||||||
my $conhfc = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
#my $conhfc = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
||||||
"09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
# "09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
||||||
"17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
# "17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
||||||
};
|
# };
|
||||||
|
|
||||||
my $conhfcex = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
#my $conhfcex = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
||||||
"09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
# "09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
||||||
"17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
# "17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
||||||
};
|
# };
|
||||||
# mögliche Debug-Module
|
# mögliche Debug-Module
|
||||||
my @dd = qw( aiProcess
|
my @dd = qw( aiProcess
|
||||||
aiData
|
aiData
|
||||||
@ -942,6 +943,8 @@ my %htitles = (
|
|||||||
DE => qq{Konfigurationsprüfung der Anlage} },
|
DE => qq{Konfigurationsprüfung der Anlage} },
|
||||||
jtsfft => { EN => qq{Open the SolarForecast Forum},
|
jtsfft => { EN => qq{Open the SolarForecast Forum},
|
||||||
DE => qq{Öffne das SolarForecast Forum} },
|
DE => qq{Öffne das SolarForecast Forum} },
|
||||||
|
opwiki => { EN => qq{Open the Wiki (German language)},
|
||||||
|
DE => qq{Öffne das Wiki} },
|
||||||
scaresps => { EN => qq{API request successful},
|
scaresps => { EN => qq{API request successful},
|
||||||
DE => qq{API Abfrage erfolgreich} },
|
DE => qq{API Abfrage erfolgreich} },
|
||||||
dwfcrsu => { EN => qq{Weather data are up to date according to used DWD model},
|
dwfcrsu => { EN => qq{Weather data are up to date according to used DWD model},
|
||||||
@ -7555,7 +7558,7 @@ sub centralTask {
|
|||||||
_batSocTarget ($centpars); # Batterie Optimum Ziel SOC berechnen
|
_batSocTarget ($centpars); # Batterie Optimum Ziel SOC berechnen
|
||||||
_batChargeRecmd ($centpars); # Batterie Ladefreigabe berechnen und erstellen
|
_batChargeRecmd ($centpars); # Batterie Ladefreigabe berechnen und erstellen
|
||||||
_manageConsumerData ($centpars); # Consumer Daten sammeln und Zeiten planen
|
_manageConsumerData ($centpars); # Consumer Daten sammeln und Zeiten planen
|
||||||
_estConsumptionForecast ($centpars); # Verbrauchsprognose erstellen
|
_calcConsumptionForecast ($centpars); # Verbrauchsprognose erstellen
|
||||||
_evaluateThresholds ($centpars); # Schwellenwerte bewerten und signalisieren
|
_evaluateThresholds ($centpars); # Schwellenwerte bewerten und signalisieren
|
||||||
_calcReadingsTomorrowPVFc ($centpars); # zusätzliche Readings Tomorrow_HourXX_PVforecast berechnen
|
_calcReadingsTomorrowPVFc ($centpars); # zusätzliche Readings Tomorrow_HourXX_PVforecast berechnen
|
||||||
_calcTodayPVdeviation ($centpars); # Vorhersageabweichung erstellen (nach Sonnenuntergang)
|
_calcTodayPVdeviation ($centpars); # Vorhersageabweichung erstellen (nach Sonnenuntergang)
|
||||||
@ -11812,7 +11815,7 @@ return ($simpCstat, $starttime, $stoptime, $supplmnt);
|
|||||||
################################################################
|
################################################################
|
||||||
# Energieverbrauch Vorhersage kalkulieren
|
# Energieverbrauch Vorhersage kalkulieren
|
||||||
################################################################
|
################################################################
|
||||||
sub _estConsumptionForecast {
|
sub _calcConsumptionForecast {
|
||||||
my $paref = shift;
|
my $paref = shift;
|
||||||
my $name = $paref->{name};
|
my $name = $paref->{name};
|
||||||
my $type = $paref->{type};
|
my $type = $paref->{type};
|
||||||
@ -11840,10 +11843,7 @@ sub _estConsumptionForecast {
|
|||||||
## Verbrauchsvorhersage für den kommenden Tag
|
## Verbrauchsvorhersage für den kommenden Tag
|
||||||
##############################################
|
##############################################
|
||||||
my $tomorrow = strftime "%a", localtime($t+86400); # Wochentagsname kommender Tag
|
my $tomorrow = strftime "%a", localtime($t+86400); # Wochentagsname kommender Tag
|
||||||
my $totcon = 0;
|
my (@cona, $exconfc, $csme);
|
||||||
my $dnum = 0;
|
|
||||||
|
|
||||||
my ($exconfc, $csme);
|
|
||||||
|
|
||||||
debugLog ($paref, 'consumption|consumption_long', "################### Consumption forecast for the next day ###################");
|
debugLog ($paref, 'consumption|consumption_long', "################### Consumption forecast for the next day ###################");
|
||||||
debugLog ($paref, 'consumption|consumption_long', "Date(s) to take note: ".join ',', @dtn) if(@dtn);
|
debugLog ($paref, 'consumption|consumption_long', "Date(s) to take note: ".join ',', @dtn) if(@dtn);
|
||||||
@ -11882,15 +11882,16 @@ sub _estConsumptionForecast {
|
|||||||
|
|
||||||
debugLog ($paref, 'consumption|consumption_long', "History Consumption day >$n< considering possible exclusions: $dcon");
|
debugLog ($paref, 'consumption|consumption_long', "History Consumption day >$n< considering possible exclusions: $dcon");
|
||||||
|
|
||||||
$totcon += $dcon;
|
push @cona, $dcon;
|
||||||
$dnum++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $dnum = scalar @cona;
|
||||||
|
|
||||||
if ($dnum) {
|
if ($dnum) {
|
||||||
my $tomavg = int ($totcon / $dnum);
|
my $tomcon = sprintf "%.0f", medianArray (\@cona);
|
||||||
$data{$name}{current}{tomorrowconsumption} = $tomavg; # prognostizierter Durchschnittsverbrauch aller (gleicher) Wochentage
|
$data{$name}{current}{tomorrowconsumption} = $tomcon; # prognostizierter Verbrauch (Median) aller (gleicher) Wochentage
|
||||||
|
|
||||||
debugLog ($paref, 'consumption|consumption_long', "estimated Consumption for tomorrow: $tomavg, days for avg: $dnum");
|
debugLog ($paref, 'consumption|consumption_long', "estimated Consumption for tomorrow: $tomcon, days for avg: $dnum");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
my $lang = $paref->{lang};
|
my $lang = $paref->{lang};
|
||||||
@ -11906,22 +11907,14 @@ sub _estConsumptionForecast {
|
|||||||
my $nhtime = NexthoursVal ($hash, $k, "starttime", undef); # Startzeit
|
my $nhtime = NexthoursVal ($hash, $k, "starttime", undef); # Startzeit
|
||||||
next if(!$nhtime);
|
next if(!$nhtime);
|
||||||
|
|
||||||
$conhfc = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
|
||||||
"09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
|
||||||
"17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
$conhfcex = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
|
||||||
"09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
|
||||||
"17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
$dnum = 0;
|
$dnum = 0;
|
||||||
my $consumerco = 0;
|
my $consumerco = 0;
|
||||||
my $utime = timestringToTimestamp ($nhtime);
|
my $utime = timestringToTimestamp ($nhtime);
|
||||||
my $nhday = strftime "%a", localtime($utime); # Wochentagsname des NextHours Key
|
my $nhday = strftime "%a", localtime($utime); # Wochentagsname des NextHours Key
|
||||||
my $nhhr = sprintf("%02d", (int (strftime "%H", localtime($utime))) + 1); # Stunde des Tages vom NextHours Key (01,02,...24)
|
my $nhhr = sprintf("%02d", (int (strftime "%H", localtime($utime))) + 1); # Stunde des Tages vom NextHours Key (01,02,...24)
|
||||||
|
|
||||||
|
my ($conhfc, $conhfcex);
|
||||||
|
|
||||||
for my $m (sort{$a<=>$b} keys %{$data{$name}{pvhist}}) {
|
for my $m (sort{$a<=>$b} keys %{$data{$name}{pvhist}}) {
|
||||||
next if($m eq $day); # next wenn gleicher Tag (Datum) wie heute
|
next if($m eq $day); # next wenn gleicher Tag (Datum) wie heute
|
||||||
|
|
||||||
@ -11966,18 +11959,19 @@ sub _estConsumptionForecast {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$conhfcex->{$nhhr} += ($hcon - $consumerco) if($hcon >= $consumerco); # prognostizierter Verbrauch Ex registrierter Verbraucher
|
push @{$conhfcex->{"$nhhr"}}, ($hcon - $consumerco) if($hcon >= $consumerco); # prognostizierter Verbrauch (Median) Ex registrierter Verbraucher
|
||||||
$conhfc->{$nhhr} += $hcon;
|
push @{$conhfc->{"$nhhr"}}, $hcon;
|
||||||
|
|
||||||
$dnum++;
|
$dnum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($dnum) {
|
if ($dnum) {
|
||||||
my $conavgex = int ($conhfcex->{$nhhr} / $dnum);
|
my $conavgex = sprintf "%.0f", medianArray (\@{$conhfcex->{$nhhr}}) if(scalar @{$conhfcex->{$nhhr}});
|
||||||
$data{$name}{nexthours}{$k}{confcEx} = $conavgex;
|
$data{$name}{nexthours}{$k}{confcEx} = $conavgex;
|
||||||
my $conavg = int ($conhfc->{$nhhr} / $dnum);
|
my $conavg = sprintf "%.0f", medianArray (\@{$conhfc->{$nhhr}}) if(scalar @{$conhfc->{$nhhr}});
|
||||||
$data{$name}{nexthours}{$k}{confc} = $conavg; # Durchschnittsverbrauch aller gleicher Wochentage pro Stunde
|
$data{$name}{nexthours}{$k}{confc} = $conavg; # prognostizierter Verbrauch (Median) auf Grundlage aller gleicher Wochentage pro Stunde
|
||||||
|
|
||||||
if (NexthoursVal ($hash, $k, 'today', 0)) { # nur Werte des aktuellen Tag speichern
|
if (NexthoursVal ($hash, $k, 'today', 0)) { # nur Werte des aktuellen Tag speichern
|
||||||
$data{$name}{circular}{sprintf("%02d",$nhhr)}{confc} = $conavg;
|
$data{$name}{circular}{sprintf("%02d",$nhhr)}{confc} = $conavg;
|
||||||
writeToHistory ( { paref => $paref, key => 'confc', val => $conavg, hour => $nhhr } );
|
writeToHistory ( { paref => $paref, key => 'confc', val => $conavg, hour => $nhhr } );
|
||||||
}
|
}
|
||||||
@ -13283,6 +13277,12 @@ sub _graphicHeader {
|
|||||||
$img = FW_makeImage('time_note@grey');
|
$img = FW_makeImage('time_note@grey');
|
||||||
my $fthicon = "<a href='https://forum.fhem.de/index.php?topic=137058.0' target='_blank'>$img</a>";
|
my $fthicon = "<a href='https://forum.fhem.de/index.php?topic=137058.0' target='_blank'>$img</a>";
|
||||||
my $fthtitle = $htitles{jtsfft}{$lang};
|
my $fthtitle = $htitles{jtsfft}{$lang};
|
||||||
|
|
||||||
|
## Wiki-Icon
|
||||||
|
##############
|
||||||
|
$img = FW_makeImage ('edit_copy@grey');
|
||||||
|
my $wikicon = "<a href='https://wiki.fhem.de/wiki/SolarForecast_-_Solare_Prognose_(PV_Erzeugung)_und_Verbrauchersteuerung' target='_blank'>$img</a>";
|
||||||
|
my $wiktitle = $htitles{opwiki}{$lang};
|
||||||
|
|
||||||
## Update-Icon
|
## Update-Icon
|
||||||
################
|
################
|
||||||
@ -13494,13 +13494,14 @@ sub _graphicHeader {
|
|||||||
#######################
|
#######################
|
||||||
my $alias = AttrVal ($name, "alias", $name ); # Linktext als Aliasname
|
my $alias = AttrVal ($name, "alias", $name ); # Linktext als Aliasname
|
||||||
my $dlink = qq{<a href="$::FW_ME$::FW_subdir?detail=$name">$alias</a>};
|
my $dlink = qq{<a href="$::FW_ME$::FW_subdir?detail=$name">$alias</a>};
|
||||||
|
my $space = ' ';
|
||||||
|
my $disti = qq{<span title="$chktitle"> $chkicon </span> $space <span title="$fthtitle"> $fthicon </span> $space <span title="$wiktitle"> $wikicon </span>};
|
||||||
|
|
||||||
$header .= qq{<tr>};
|
$header .= qq{<tr>};
|
||||||
$header .= qq{<td colspan="1" align="left" $dstyle> <b>$dlink</b> </td>};
|
$header .= qq{<td colspan="1" align="left" $dstyle> <b>$dlink</b> </td>};
|
||||||
$header .= qq{<td colspan="1" align="right" title="$chktitle" $dstyle> $chkicon </td>};
|
$header .= qq{<td colspan="2" align="center" $dstyle> $disti </td>};
|
||||||
$header .= qq{<td colspan="1" align="left" title="$fthtitle" $dstyle> $fthicon </td>};
|
$header .= qq{<td colspan="3" align="left" $dstyle> $lupt $lup $upicon </td>};
|
||||||
$header .= qq{<td colspan="3" align="left" $dstyle> $lupt $lup $upicon </td>};
|
$header .= qq{<td colspan="3" align="right" $dstyle> $api </td>};
|
||||||
$header .= qq{<td colspan="3" align="right" $dstyle> $api </td>};
|
|
||||||
$header .= qq{</tr>};
|
$header .= qq{</tr>};
|
||||||
$header .= qq{<tr>};
|
$header .= qq{<tr>};
|
||||||
$header .= qq{<td colspan="3" align="left" $dstyle> $sriseimg $srisetxt $ssetimg $ssettxt $waicon </td>};
|
$header .= qq{<td colspan="3" align="left" $dstyle> $sriseimg $srisetxt $ssetimg $ssettxt $waicon </td>};
|
||||||
@ -22418,14 +22419,15 @@ to ensure that the system configuration is correct.
|
|||||||
<ul>
|
<ul>
|
||||||
<table>
|
<table>
|
||||||
<colgroup> <col width="20%"> <col width="80%"> </colgroup>
|
<colgroup> <col width="20%"> <col width="80%"> </colgroup>
|
||||||
<tr><td> <b>lowSoc</b> </td><td>lower minimum SoC, the battery is not discharged lower than this value (> 0) </td></tr>
|
<tr><td> <b>lowSoc</b> </td><td>lower minimum SoC - The battery is not discharged lower than this value (> 0) </td></tr>
|
||||||
<tr><td> <b>upSoC</b> </td><td>upper minimum SoC, the usual value of the optimum SoC is between 'lowSoC' </td></tr>
|
<tr><td> <b>upSoC</b> </td><td>upper minimum SoC - The usual value of the optimum SoC tends to be </td></tr>
|
||||||
<tr><td> </td><td>and this value. </td></tr>
|
<tr><td> </td><td>between 'lowSoC' and 'upSoC' in periods with a high PV surplus </td></tr>
|
||||||
<tr><td> <b>maxSoC</b> </td><td>Maximum minimum SoC, SoC value that must be reached at least every 'careCycle' days </td></tr>
|
<tr><td> </td><td>and between 'upSoC' and 'maxSoC' in periods with a low PV surplus </td></tr>
|
||||||
<tr><td> </td><td>in order to balance the charge in the storage network. </td></tr>
|
<tr><td> <b>maxSoC</b> </td><td>Maximum minimum SoC - SoC value that must be reached at least every 'careCycle' days </td></tr>
|
||||||
<tr><td> </td><td>The specification is optional (<= 100, default: 95) </td></tr>
|
<tr><td> </td><td>in order to balance the charge in the storage network. </td></tr>
|
||||||
<tr><td> <b>careCycle</b> </td><td>Maximum interval in days that may occur between two states of charge </td></tr>
|
<tr><td> </td><td>The specification is optional (<= 100, default: 95) </td></tr>
|
||||||
<tr><td> </td><td>of at least 'maxSoC'. The specification is optional (default: 20) </td></tr>
|
<tr><td> <b>careCycle</b> </td><td>Maximum interval in days that may occur between two states of charge </td></tr>
|
||||||
|
<tr><td> </td><td>of at least 'maxSoC'. The specification is optional (default: 20) </td></tr>
|
||||||
</table>
|
</table>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
@ -24886,14 +24888,15 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
|||||||
<ul>
|
<ul>
|
||||||
<table>
|
<table>
|
||||||
<colgroup> <col width="20%"> <col width="80%"> </colgroup>
|
<colgroup> <col width="20%"> <col width="80%"> </colgroup>
|
||||||
<tr><td> <b>lowSoc</b> </td><td>unterer Mindest-SoC, die Batterie wird nicht tiefer als dieser Wert entladen (> 0) </td></tr>
|
<tr><td> <b>lowSoc</b> </td><td>unterer Mindest-SoC - Die Batterie wird nicht tiefer als dieser Wert entladen (> 0) </td></tr>
|
||||||
<tr><td> <b>upSoC</b> </td><td>oberer Mindest-SoC, der übliche Wert des optimalen SoC bewegt sich zwischen 'lowSoC' </td></tr>
|
<tr><td> <b>upSoC</b> </td><td>oberer Mindest-SoC - Der übliche Wert des optimalen SoC bewegt sich in Perioden mit hohen </td></tr>
|
||||||
<tr><td> </td><td>und diesem Wert. </td></tr>
|
<tr><td> </td><td>PV-Überschuß tendenziell zwischen 'lowSoC' und 'upSoC', in Perioden mit geringem PV-Überschuß </td></tr>
|
||||||
<tr><td> <b>maxSoC</b> </td><td>maximaler Mindest-SoC, SoC Wert der mindestens im Abstand von 'careCycle' Tagen erreicht </td></tr>
|
<tr><td> </td><td>tendenziell zwischen 'upSoC' und 'maxSoC' </td></tr>
|
||||||
<tr><td> </td><td>werden muß um den Ladungsausgleich im Speicherverbund auszuführen. </td></tr>
|
<tr><td> <b>maxSoC</b> </td><td>maximaler Mindest-SoC - SoC Wert der mindestens im Abstand von 'careCycle' Tagen erreicht </td></tr>
|
||||||
<tr><td> </td><td>Die Angabe ist optional (<= 100, default: 95) </td></tr>
|
<tr><td> </td><td>werden muß um den Ladungsausgleich im Speicherverbund auszuführen. </td></tr>
|
||||||
<tr><td> <b>careCycle</b> </td><td>maximaler Abstand in Tagen, der zwischen zwei Ladungszuständen von mindestens 'maxSoC' </td></tr>
|
<tr><td> </td><td>Die Angabe ist optional (<= 100, default: 95) </td></tr>
|
||||||
<tr><td> </td><td>auftreten darf. Die Angabe ist optional (default: 20) </td></tr>
|
<tr><td> <b>careCycle</b> </td><td>maximaler Abstand in Tagen, der zwischen zwei Ladungszuständen von mindestens 'maxSoC' </td></tr>
|
||||||
|
<tr><td> </td><td>auftreten darf. Die Angabe ist optional (default: 20) </td></tr>
|
||||||
</table>
|
</table>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
@ -157,6 +157,7 @@ BEGIN {
|
|||||||
|
|
||||||
# Versions History intern
|
# Versions History intern
|
||||||
my %vNotesIntern = (
|
my %vNotesIntern = (
|
||||||
|
"1.43.3" => "13.01.2025 add Wiki icon in graphic header, _calcConsumptionForecast: switch calc from average to median, edit comref ",
|
||||||
"1.43.2" => "12.01.2025 _batChargeRecmd: bugfix calc socwh, Attr graphicBeam1MaxVal, (experimental) ctrlAreaFactorUsage are obsolete ".
|
"1.43.2" => "12.01.2025 _batChargeRecmd: bugfix calc socwh, Attr graphicBeam1MaxVal, (experimental) ctrlAreaFactorUsage are obsolete ".
|
||||||
"trackFlex now default in DWD Model, replace title Charging recommendation by Charging release ".
|
"trackFlex now default in DWD Model, replace title Charging recommendation by Charging release ".
|
||||||
"_saveEnergyConsumption: add dowrite flag, edit comref ",
|
"_saveEnergyConsumption: add dowrite flag, edit comref ",
|
||||||
@ -254,7 +255,7 @@ my %vNotesIntern = (
|
|||||||
"1.33.0" => "26.09.2024 substitute area factor hash by ___areaFactorFix function ",
|
"1.33.0" => "26.09.2024 substitute area factor hash by ___areaFactorFix function ",
|
||||||
"1.32.0" => "02.09.2024 new attr setupOtherProducerXX, report calculation and storage of negative consumption values ".
|
"1.32.0" => "02.09.2024 new attr setupOtherProducerXX, report calculation and storage of negative consumption values ".
|
||||||
"Forum: https://forum.fhem.de/index.php?msg=1319083 ".
|
"Forum: https://forum.fhem.de/index.php?msg=1319083 ".
|
||||||
"bugfix in _estConsumptionForecast, new ctrlDebug consumption_long ",
|
"bugfix in _calcConsumptionForecast, new ctrlDebug consumption_long ",
|
||||||
"1.31.0" => "20.08.2024 rename attributes ctrlWeatherDevX to setupWeatherDevX ",
|
"1.31.0" => "20.08.2024 rename attributes ctrlWeatherDevX to setupWeatherDevX ",
|
||||||
"1.30.0" => "18.08.2024 new attribute flowGraphicShift, Forum:https://forum.fhem.de/index.php?msg=1318597 ",
|
"1.30.0" => "18.08.2024 new attribute flowGraphicShift, Forum:https://forum.fhem.de/index.php?msg=1318597 ",
|
||||||
"1.29.4" => "03.08.2024 delete writeCacheToFile from _getRoofTopData, _specialActivities: avoid loop caused by \@widgetreadings ",
|
"1.29.4" => "03.08.2024 delete writeCacheToFile from _getRoofTopData, _specialActivities: avoid loop caused by \@widgetreadings ",
|
||||||
@ -487,15 +488,15 @@ my $cfile = 'controls_solarforecast.txt';
|
|||||||
|
|
||||||
|
|
||||||
# initiale Hashes für Stunden Consumption Forecast inkl. und exkl. Verbraucher
|
# initiale Hashes für Stunden Consumption Forecast inkl. und exkl. Verbraucher
|
||||||
my $conhfc = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
#my $conhfc = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
||||||
"09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
# "09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
||||||
"17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
# "17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
||||||
};
|
# };
|
||||||
|
|
||||||
my $conhfcex = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
#my $conhfcex = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
||||||
"09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
# "09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
||||||
"17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
# "17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
||||||
};
|
# };
|
||||||
# mögliche Debug-Module
|
# mögliche Debug-Module
|
||||||
my @dd = qw( aiProcess
|
my @dd = qw( aiProcess
|
||||||
aiData
|
aiData
|
||||||
@ -942,6 +943,8 @@ my %htitles = (
|
|||||||
DE => qq{Konfigurationsprüfung der Anlage} },
|
DE => qq{Konfigurationsprüfung der Anlage} },
|
||||||
jtsfft => { EN => qq{Open the SolarForecast Forum},
|
jtsfft => { EN => qq{Open the SolarForecast Forum},
|
||||||
DE => qq{Öffne das SolarForecast Forum} },
|
DE => qq{Öffne das SolarForecast Forum} },
|
||||||
|
opwiki => { EN => qq{Open the Wiki (German language)},
|
||||||
|
DE => qq{Öffne das Wiki} },
|
||||||
scaresps => { EN => qq{API request successful},
|
scaresps => { EN => qq{API request successful},
|
||||||
DE => qq{API Abfrage erfolgreich} },
|
DE => qq{API Abfrage erfolgreich} },
|
||||||
dwfcrsu => { EN => qq{Weather data are up to date according to used DWD model},
|
dwfcrsu => { EN => qq{Weather data are up to date according to used DWD model},
|
||||||
@ -7555,7 +7558,7 @@ sub centralTask {
|
|||||||
_batSocTarget ($centpars); # Batterie Optimum Ziel SOC berechnen
|
_batSocTarget ($centpars); # Batterie Optimum Ziel SOC berechnen
|
||||||
_batChargeRecmd ($centpars); # Batterie Ladefreigabe berechnen und erstellen
|
_batChargeRecmd ($centpars); # Batterie Ladefreigabe berechnen und erstellen
|
||||||
_manageConsumerData ($centpars); # Consumer Daten sammeln und Zeiten planen
|
_manageConsumerData ($centpars); # Consumer Daten sammeln und Zeiten planen
|
||||||
_estConsumptionForecast ($centpars); # Verbrauchsprognose erstellen
|
_calcConsumptionForecast ($centpars); # Verbrauchsprognose erstellen
|
||||||
_evaluateThresholds ($centpars); # Schwellenwerte bewerten und signalisieren
|
_evaluateThresholds ($centpars); # Schwellenwerte bewerten und signalisieren
|
||||||
_calcReadingsTomorrowPVFc ($centpars); # zusätzliche Readings Tomorrow_HourXX_PVforecast berechnen
|
_calcReadingsTomorrowPVFc ($centpars); # zusätzliche Readings Tomorrow_HourXX_PVforecast berechnen
|
||||||
_calcTodayPVdeviation ($centpars); # Vorhersageabweichung erstellen (nach Sonnenuntergang)
|
_calcTodayPVdeviation ($centpars); # Vorhersageabweichung erstellen (nach Sonnenuntergang)
|
||||||
@ -11812,7 +11815,7 @@ return ($simpCstat, $starttime, $stoptime, $supplmnt);
|
|||||||
################################################################
|
################################################################
|
||||||
# Energieverbrauch Vorhersage kalkulieren
|
# Energieverbrauch Vorhersage kalkulieren
|
||||||
################################################################
|
################################################################
|
||||||
sub _estConsumptionForecast {
|
sub _calcConsumptionForecast {
|
||||||
my $paref = shift;
|
my $paref = shift;
|
||||||
my $name = $paref->{name};
|
my $name = $paref->{name};
|
||||||
my $type = $paref->{type};
|
my $type = $paref->{type};
|
||||||
@ -11840,10 +11843,7 @@ sub _estConsumptionForecast {
|
|||||||
## Verbrauchsvorhersage für den kommenden Tag
|
## Verbrauchsvorhersage für den kommenden Tag
|
||||||
##############################################
|
##############################################
|
||||||
my $tomorrow = strftime "%a", localtime($t+86400); # Wochentagsname kommender Tag
|
my $tomorrow = strftime "%a", localtime($t+86400); # Wochentagsname kommender Tag
|
||||||
my $totcon = 0;
|
my (@cona, $exconfc, $csme);
|
||||||
my $dnum = 0;
|
|
||||||
|
|
||||||
my ($exconfc, $csme);
|
|
||||||
|
|
||||||
debugLog ($paref, 'consumption|consumption_long', "################### Consumption forecast for the next day ###################");
|
debugLog ($paref, 'consumption|consumption_long', "################### Consumption forecast for the next day ###################");
|
||||||
debugLog ($paref, 'consumption|consumption_long', "Date(s) to take note: ".join ',', @dtn) if(@dtn);
|
debugLog ($paref, 'consumption|consumption_long', "Date(s) to take note: ".join ',', @dtn) if(@dtn);
|
||||||
@ -11882,15 +11882,16 @@ sub _estConsumptionForecast {
|
|||||||
|
|
||||||
debugLog ($paref, 'consumption|consumption_long', "History Consumption day >$n< considering possible exclusions: $dcon");
|
debugLog ($paref, 'consumption|consumption_long', "History Consumption day >$n< considering possible exclusions: $dcon");
|
||||||
|
|
||||||
$totcon += $dcon;
|
push @cona, $dcon;
|
||||||
$dnum++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $dnum = scalar @cona;
|
||||||
|
|
||||||
if ($dnum) {
|
if ($dnum) {
|
||||||
my $tomavg = int ($totcon / $dnum);
|
my $tomcon = sprintf "%.0f", medianArray (\@cona);
|
||||||
$data{$name}{current}{tomorrowconsumption} = $tomavg; # prognostizierter Durchschnittsverbrauch aller (gleicher) Wochentage
|
$data{$name}{current}{tomorrowconsumption} = $tomcon; # prognostizierter Verbrauch (Median) aller (gleicher) Wochentage
|
||||||
|
|
||||||
debugLog ($paref, 'consumption|consumption_long', "estimated Consumption for tomorrow: $tomavg, days for avg: $dnum");
|
debugLog ($paref, 'consumption|consumption_long', "estimated Consumption for tomorrow: $tomcon, days for avg: $dnum");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
my $lang = $paref->{lang};
|
my $lang = $paref->{lang};
|
||||||
@ -11906,22 +11907,14 @@ sub _estConsumptionForecast {
|
|||||||
my $nhtime = NexthoursVal ($hash, $k, "starttime", undef); # Startzeit
|
my $nhtime = NexthoursVal ($hash, $k, "starttime", undef); # Startzeit
|
||||||
next if(!$nhtime);
|
next if(!$nhtime);
|
||||||
|
|
||||||
$conhfc = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
|
||||||
"09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
|
||||||
"17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
$conhfcex = { "01" => 0, "02" => 0, "03" => 0, "04" => 0, "05" => 0, "06" => 0, "07" => 0, "08" => 0,
|
|
||||||
"09" => 0, "10" => 0, "11" => 0, "12" => 0, "13" => 0, "14" => 0, "15" => 0, "16" => 0,
|
|
||||||
"17" => 0, "18" => 0, "19" => 0, "20" => 0, "21" => 0, "22" => 0, "23" => 0, "24" => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
$dnum = 0;
|
$dnum = 0;
|
||||||
my $consumerco = 0;
|
my $consumerco = 0;
|
||||||
my $utime = timestringToTimestamp ($nhtime);
|
my $utime = timestringToTimestamp ($nhtime);
|
||||||
my $nhday = strftime "%a", localtime($utime); # Wochentagsname des NextHours Key
|
my $nhday = strftime "%a", localtime($utime); # Wochentagsname des NextHours Key
|
||||||
my $nhhr = sprintf("%02d", (int (strftime "%H", localtime($utime))) + 1); # Stunde des Tages vom NextHours Key (01,02,...24)
|
my $nhhr = sprintf("%02d", (int (strftime "%H", localtime($utime))) + 1); # Stunde des Tages vom NextHours Key (01,02,...24)
|
||||||
|
|
||||||
|
my ($conhfc, $conhfcex);
|
||||||
|
|
||||||
for my $m (sort{$a<=>$b} keys %{$data{$name}{pvhist}}) {
|
for my $m (sort{$a<=>$b} keys %{$data{$name}{pvhist}}) {
|
||||||
next if($m eq $day); # next wenn gleicher Tag (Datum) wie heute
|
next if($m eq $day); # next wenn gleicher Tag (Datum) wie heute
|
||||||
|
|
||||||
@ -11966,18 +11959,19 @@ sub _estConsumptionForecast {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$conhfcex->{$nhhr} += ($hcon - $consumerco) if($hcon >= $consumerco); # prognostizierter Verbrauch Ex registrierter Verbraucher
|
push @{$conhfcex->{"$nhhr"}}, ($hcon - $consumerco) if($hcon >= $consumerco); # prognostizierter Verbrauch (Median) Ex registrierter Verbraucher
|
||||||
$conhfc->{$nhhr} += $hcon;
|
push @{$conhfc->{"$nhhr"}}, $hcon;
|
||||||
|
|
||||||
$dnum++;
|
$dnum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($dnum) {
|
if ($dnum) {
|
||||||
my $conavgex = int ($conhfcex->{$nhhr} / $dnum);
|
my $conavgex = sprintf "%.0f", medianArray (\@{$conhfcex->{$nhhr}}) if(scalar @{$conhfcex->{$nhhr}});
|
||||||
$data{$name}{nexthours}{$k}{confcEx} = $conavgex;
|
$data{$name}{nexthours}{$k}{confcEx} = $conavgex;
|
||||||
my $conavg = int ($conhfc->{$nhhr} / $dnum);
|
my $conavg = sprintf "%.0f", medianArray (\@{$conhfc->{$nhhr}}) if(scalar @{$conhfc->{$nhhr}});
|
||||||
$data{$name}{nexthours}{$k}{confc} = $conavg; # Durchschnittsverbrauch aller gleicher Wochentage pro Stunde
|
$data{$name}{nexthours}{$k}{confc} = $conavg; # prognostizierter Verbrauch (Median) auf Grundlage aller gleicher Wochentage pro Stunde
|
||||||
|
|
||||||
if (NexthoursVal ($hash, $k, 'today', 0)) { # nur Werte des aktuellen Tag speichern
|
if (NexthoursVal ($hash, $k, 'today', 0)) { # nur Werte des aktuellen Tag speichern
|
||||||
$data{$name}{circular}{sprintf("%02d",$nhhr)}{confc} = $conavg;
|
$data{$name}{circular}{sprintf("%02d",$nhhr)}{confc} = $conavg;
|
||||||
writeToHistory ( { paref => $paref, key => 'confc', val => $conavg, hour => $nhhr } );
|
writeToHistory ( { paref => $paref, key => 'confc', val => $conavg, hour => $nhhr } );
|
||||||
}
|
}
|
||||||
@ -13283,6 +13277,12 @@ sub _graphicHeader {
|
|||||||
$img = FW_makeImage('time_note@grey');
|
$img = FW_makeImage('time_note@grey');
|
||||||
my $fthicon = "<a href='https://forum.fhem.de/index.php?topic=137058.0' target='_blank'>$img</a>";
|
my $fthicon = "<a href='https://forum.fhem.de/index.php?topic=137058.0' target='_blank'>$img</a>";
|
||||||
my $fthtitle = $htitles{jtsfft}{$lang};
|
my $fthtitle = $htitles{jtsfft}{$lang};
|
||||||
|
|
||||||
|
## Wiki-Icon
|
||||||
|
##############
|
||||||
|
$img = FW_makeImage ('edit_copy@grey');
|
||||||
|
my $wikicon = "<a href='https://wiki.fhem.de/wiki/SolarForecast_-_Solare_Prognose_(PV_Erzeugung)_und_Verbrauchersteuerung' target='_blank'>$img</a>";
|
||||||
|
my $wiktitle = $htitles{opwiki}{$lang};
|
||||||
|
|
||||||
## Update-Icon
|
## Update-Icon
|
||||||
################
|
################
|
||||||
@ -13494,13 +13494,14 @@ sub _graphicHeader {
|
|||||||
#######################
|
#######################
|
||||||
my $alias = AttrVal ($name, "alias", $name ); # Linktext als Aliasname
|
my $alias = AttrVal ($name, "alias", $name ); # Linktext als Aliasname
|
||||||
my $dlink = qq{<a href="$::FW_ME$::FW_subdir?detail=$name">$alias</a>};
|
my $dlink = qq{<a href="$::FW_ME$::FW_subdir?detail=$name">$alias</a>};
|
||||||
|
my $space = ' ';
|
||||||
|
my $disti = qq{<span title="$chktitle"> $chkicon </span> $space <span title="$fthtitle"> $fthicon </span> $space <span title="$wiktitle"> $wikicon </span>};
|
||||||
|
|
||||||
$header .= qq{<tr>};
|
$header .= qq{<tr>};
|
||||||
$header .= qq{<td colspan="1" align="left" $dstyle> <b>$dlink</b> </td>};
|
$header .= qq{<td colspan="1" align="left" $dstyle> <b>$dlink</b> </td>};
|
||||||
$header .= qq{<td colspan="1" align="right" title="$chktitle" $dstyle> $chkicon </td>};
|
$header .= qq{<td colspan="2" align="center" $dstyle> $disti </td>};
|
||||||
$header .= qq{<td colspan="1" align="left" title="$fthtitle" $dstyle> $fthicon </td>};
|
$header .= qq{<td colspan="3" align="left" $dstyle> $lupt $lup $upicon </td>};
|
||||||
$header .= qq{<td colspan="3" align="left" $dstyle> $lupt $lup $upicon </td>};
|
$header .= qq{<td colspan="3" align="right" $dstyle> $api </td>};
|
||||||
$header .= qq{<td colspan="3" align="right" $dstyle> $api </td>};
|
|
||||||
$header .= qq{</tr>};
|
$header .= qq{</tr>};
|
||||||
$header .= qq{<tr>};
|
$header .= qq{<tr>};
|
||||||
$header .= qq{<td colspan="3" align="left" $dstyle> $sriseimg $srisetxt $ssetimg $ssettxt $waicon </td>};
|
$header .= qq{<td colspan="3" align="left" $dstyle> $sriseimg $srisetxt $ssetimg $ssettxt $waicon </td>};
|
||||||
@ -15459,7 +15460,7 @@ END0
|
|||||||
|
|
||||||
$cc_dummy -= $currentPower;
|
$cc_dummy -= $currentPower;
|
||||||
$cicon = FW_makeImage ($cicon, '');
|
$cicon = FW_makeImage ($cicon, '');
|
||||||
($scale, $cicon) = __normIconScale ($cicon, $name);
|
($scale, $cicon) = __normIconScale ($name, $cicon);
|
||||||
|
|
||||||
$ret .= qq{<g id="consumer_${c}_$stna" transform="translate($cons_left,$y_pos),scale($scale)">};
|
$ret .= qq{<g id="consumer_${c}_$stna" transform="translate($cons_left,$y_pos),scale($scale)">};
|
||||||
$ret .= "<title>$calias</title>".$cicon;
|
$ret .= "<title>$calias</title>".$cicon;
|
||||||
@ -15488,7 +15489,7 @@ END1
|
|||||||
## Home Icon
|
## Home Icon
|
||||||
##############
|
##############
|
||||||
my $hicon = FW_makeImage ($homeicondef, '');
|
my $hicon = FW_makeImage ($homeicondef, '');
|
||||||
($scale, $hicon) = __normIconScale ($hicon, $name);
|
($scale, $hicon) = __normIconScale ($name, $hicon);
|
||||||
|
|
||||||
$ret .= qq{<g id="home_$stna" transform="translate(368,360),scale($scale)">}; # translate(X-Koordinate,Y-Koordinate), scale(<Größe>)-> Koordinaten ändern sich bei Größenänderung
|
$ret .= qq{<g id="home_$stna" transform="translate(368,360),scale($scale)">}; # translate(X-Koordinate,Y-Koordinate), scale(<Größe>)-> Koordinaten ändern sich bei Größenänderung
|
||||||
$ret .= "<title>Home</title>".$hicon;
|
$ret .= "<title>Home</title>".$hicon;
|
||||||
@ -15500,7 +15501,7 @@ END1
|
|||||||
my $dumtxt = $htitles{dumtxt}{$lang};
|
my $dumtxt = $htitles{dumtxt}{$lang};
|
||||||
my $dumcol = $cc_dummy <= 0 ? '@grey' : q{}; # Einfärbung Consumer Dummy
|
my $dumcol = $cc_dummy <= 0 ? '@grey' : q{}; # Einfärbung Consumer Dummy
|
||||||
my $dicon = FW_makeImage ($cicondef.$dumcol, '');
|
my $dicon = FW_makeImage ($cicondef.$dumcol, '');
|
||||||
($scale, $dicon) = __normIconScale ($dicon, $name);
|
($scale, $dicon) = __normIconScale ($name, $dicon);
|
||||||
|
|
||||||
$ret .= qq{<g id="dummy_$stna" transform="translate(660,360),scale($scale)">};
|
$ret .= qq{<g id="dummy_$stna" transform="translate(660,360),scale($scale)">};
|
||||||
$ret .= "<title>$dumtxt</title>".$dicon;
|
$ret .= "<title>$dumtxt</title>".$dicon;
|
||||||
@ -15810,7 +15811,7 @@ sub __addProducerIcon {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$picon = FW_makeImage ($picon, '');
|
$picon = FW_makeImage ($picon, '');
|
||||||
($scale, $picon) = __normIconScale ($picon, $name);
|
($scale, $picon) = __normIconScale ($name, $picon);
|
||||||
|
|
||||||
$ret .= qq{<g id="producer_${pn}_$stna" fill="grey" transform="translate($left,$y_coord),scale($scale)">};
|
$ret .= qq{<g id="producer_${pn}_$stna" fill="grey" transform="translate($left,$y_coord),scale($scale)">};
|
||||||
$ret .= "<title>$ptxt</title>".$picon;
|
$ret .= "<title>$ptxt</title>".$picon;
|
||||||
@ -15847,7 +15848,7 @@ sub __addNodeIcon {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$nicon = FW_makeImage ($nicon, '');
|
$nicon = FW_makeImage ($nicon, '');
|
||||||
($scale, $nicon) = __normIconScale ($nicon, $name);
|
($scale, $nicon) = __normIconScale ($name, $nicon);
|
||||||
|
|
||||||
my $ret = qq{<g id="node_$stna" transform="translate($x_coord,$y_coord),scale($scale)">}; # translate(X-Koordinate,Y-Koordinate), scale(<Größe>)-> Koordinaten ändern sich bei Größenänderung
|
my $ret = qq{<g id="node_$stna" transform="translate($x_coord,$y_coord),scale($scale)">}; # translate(X-Koordinate,Y-Koordinate), scale(<Größe>)-> Koordinaten ändern sich bei Größenänderung
|
||||||
$ret .= "<title>$ntxt</title>".$nicon;
|
$ret .= "<title>$ntxt</title>".$nicon;
|
||||||
@ -16034,8 +16035,9 @@ return $p;
|
|||||||
# scale: 0.10 Normativ $fgscaledef
|
# scale: 0.10 Normativ $fgscaledef
|
||||||
################################################################
|
################################################################
|
||||||
sub __normIconScale {
|
sub __normIconScale {
|
||||||
my $icon = shift;
|
|
||||||
my $name = shift;
|
my $name = shift;
|
||||||
|
my $icon = shift;
|
||||||
|
my $dim = shift // 470; # Dimension
|
||||||
|
|
||||||
my $hscale = $fgscaledef; # Scale Normativ
|
my $hscale = $fgscaledef; # Scale Normativ
|
||||||
my $wscale = $fgscaledef;
|
my $wscale = $fgscaledef;
|
||||||
@ -16044,27 +16046,27 @@ sub __normIconScale {
|
|||||||
|
|
||||||
return ($hscale, $icon) if(!$width || !$height);
|
return ($hscale, $icon) if(!$width || !$height);
|
||||||
|
|
||||||
$wscale = $hunit eq 'pt' ? 470 * $wscale / $width :
|
$wscale = $hunit eq 'pt' ? $dim * $wscale / $width :
|
||||||
$hunit eq 'px' ? 470 * $wscale / $width * 0.96 :
|
$hunit eq 'px' ? $dim * $wscale / $width * 0.96 :
|
||||||
$hunit eq 'in' ? 470 * $wscale / $width * 0.0138889 :
|
$hunit eq 'in' ? $dim * $wscale / $width * 0.0138889 :
|
||||||
$hunit eq 'mm' ? 470 * $wscale / $width * 0.352778 :
|
$hunit eq 'mm' ? $dim * $wscale / $width * 0.352778 :
|
||||||
$hunit eq 'cm' ? 470 * $wscale / $width * 0.0352778 :
|
$hunit eq 'cm' ? $dim * $wscale / $width * 0.0352778 :
|
||||||
$hunit eq 'pc' ? 470 * $wscale / $width * 0.0833333 :
|
$hunit eq 'pc' ? $dim * $wscale / $width * 0.0833333 :
|
||||||
$wscale;
|
$wscale;
|
||||||
|
|
||||||
$hscale = $hunit eq 'pt' ? 470 * $hscale / $height :
|
$hscale = $hunit eq 'pt' ? $dim * $hscale / $height :
|
||||||
$hunit eq 'px' ? 470 * $hscale / $height * 0.96 :
|
$hunit eq 'px' ? $dim * $hscale / $height * 0.96 :
|
||||||
$hunit eq 'in' ? 470 * $hscale / $height * 0.0138889 :
|
$hunit eq 'in' ? $dim * $hscale / $height * 0.0138889 :
|
||||||
$hunit eq 'mm' ? 470 * $hscale / $height * 0.352778 :
|
$hunit eq 'mm' ? $dim * $hscale / $height * 0.352778 :
|
||||||
$hunit eq 'cm' ? 470 * $hscale / $height * 0.0352778 :
|
$hunit eq 'cm' ? $dim * $hscale / $height * 0.0352778 :
|
||||||
$hunit eq 'pc' ? 470 * $hscale / $height * 0.0833333 :
|
$hunit eq 'pc' ? $dim * $hscale / $height * 0.0833333 :
|
||||||
$hscale;
|
$hscale;
|
||||||
|
|
||||||
$wscale = sprintf "%.2f", $wscale;
|
$wscale = sprintf "%.2f", $wscale;
|
||||||
$hscale = sprintf "%.2f", $hscale;
|
$hscale = sprintf "%.2f", $hscale;
|
||||||
|
|
||||||
my $widthnormpt = (sprintf "%.0f", (470 * (1 + $wscale))).'pt'; # Breite auf Normativ in pt skaliert
|
my $widthnormpt = (sprintf "%.0f", ($dim * (1 + $wscale))).'pt'; # Breite auf Normativ in pt skaliert
|
||||||
my $heightnormpt = (sprintf "%.0f", (470 * (1 + $hscale))).'pt'; # Höhe auf Normativ in pt skaliert
|
my $heightnormpt = (sprintf "%.0f", ($dim * (1 + $hscale))).'pt'; # Höhe auf Normativ in pt skaliert
|
||||||
|
|
||||||
$icon =~ s/width="(.*?)"/width="$widthnormpt"/;
|
$icon =~ s/width="(.*?)"/width="$widthnormpt"/;
|
||||||
$icon =~ s/height="(.*?)"/height="$heightnormpt"/;
|
$icon =~ s/height="(.*?)"/height="$heightnormpt"/;
|
||||||
@ -22417,14 +22419,15 @@ to ensure that the system configuration is correct.
|
|||||||
<ul>
|
<ul>
|
||||||
<table>
|
<table>
|
||||||
<colgroup> <col width="20%"> <col width="80%"> </colgroup>
|
<colgroup> <col width="20%"> <col width="80%"> </colgroup>
|
||||||
<tr><td> <b>lowSoc</b> </td><td>lower minimum SoC, the battery is not discharged lower than this value (> 0) </td></tr>
|
<tr><td> <b>lowSoc</b> </td><td>lower minimum SoC - The battery is not discharged lower than this value (> 0) </td></tr>
|
||||||
<tr><td> <b>upSoC</b> </td><td>upper minimum SoC, the usual value of the optimum SoC is between 'lowSoC' </td></tr>
|
<tr><td> <b>upSoC</b> </td><td>upper minimum SoC - The usual value of the optimum SoC tends to be </td></tr>
|
||||||
<tr><td> </td><td>and this value. </td></tr>
|
<tr><td> </td><td>between 'lowSoC' and 'upSoC' in periods with a high PV surplus </td></tr>
|
||||||
<tr><td> <b>maxSoC</b> </td><td>Maximum minimum SoC, SoC value that must be reached at least every 'careCycle' days </td></tr>
|
<tr><td> </td><td>and between 'upSoC' and 'maxSoC' in periods with a low PV surplus </td></tr>
|
||||||
<tr><td> </td><td>in order to balance the charge in the storage network. </td></tr>
|
<tr><td> <b>maxSoC</b> </td><td>Maximum minimum SoC - SoC value that must be reached at least every 'careCycle' days </td></tr>
|
||||||
<tr><td> </td><td>The specification is optional (<= 100, default: 95) </td></tr>
|
<tr><td> </td><td>in order to balance the charge in the storage network. </td></tr>
|
||||||
<tr><td> <b>careCycle</b> </td><td>Maximum interval in days that may occur between two states of charge </td></tr>
|
<tr><td> </td><td>The specification is optional (<= 100, default: 95) </td></tr>
|
||||||
<tr><td> </td><td>of at least 'maxSoC'. The specification is optional (default: 20) </td></tr>
|
<tr><td> <b>careCycle</b> </td><td>Maximum interval in days that may occur between two states of charge </td></tr>
|
||||||
|
<tr><td> </td><td>of at least 'maxSoC'. The specification is optional (default: 20) </td></tr>
|
||||||
</table>
|
</table>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
@ -24885,14 +24888,15 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
|
|||||||
<ul>
|
<ul>
|
||||||
<table>
|
<table>
|
||||||
<colgroup> <col width="20%"> <col width="80%"> </colgroup>
|
<colgroup> <col width="20%"> <col width="80%"> </colgroup>
|
||||||
<tr><td> <b>lowSoc</b> </td><td>unterer Mindest-SoC, die Batterie wird nicht tiefer als dieser Wert entladen (> 0) </td></tr>
|
<tr><td> <b>lowSoc</b> </td><td>unterer Mindest-SoC - Die Batterie wird nicht tiefer als dieser Wert entladen (> 0) </td></tr>
|
||||||
<tr><td> <b>upSoC</b> </td><td>oberer Mindest-SoC, der übliche Wert des optimalen SoC bewegt sich zwischen 'lowSoC' </td></tr>
|
<tr><td> <b>upSoC</b> </td><td>oberer Mindest-SoC - Der übliche Wert des optimalen SoC bewegt sich in Perioden mit hohen </td></tr>
|
||||||
<tr><td> </td><td>und diesem Wert. </td></tr>
|
<tr><td> </td><td>PV-Überschuß tendenziell zwischen 'lowSoC' und 'upSoC', in Perioden mit geringem PV-Überschuß </td></tr>
|
||||||
<tr><td> <b>maxSoC</b> </td><td>maximaler Mindest-SoC, SoC Wert der mindestens im Abstand von 'careCycle' Tagen erreicht </td></tr>
|
<tr><td> </td><td>tendenziell zwischen 'upSoC' und 'maxSoC' </td></tr>
|
||||||
<tr><td> </td><td>werden muß um den Ladungsausgleich im Speicherverbund auszuführen. </td></tr>
|
<tr><td> <b>maxSoC</b> </td><td>maximaler Mindest-SoC - SoC Wert der mindestens im Abstand von 'careCycle' Tagen erreicht </td></tr>
|
||||||
<tr><td> </td><td>Die Angabe ist optional (<= 100, default: 95) </td></tr>
|
<tr><td> </td><td>werden muß um den Ladungsausgleich im Speicherverbund auszuführen. </td></tr>
|
||||||
<tr><td> <b>careCycle</b> </td><td>maximaler Abstand in Tagen, der zwischen zwei Ladungszuständen von mindestens 'maxSoC' </td></tr>
|
<tr><td> </td><td>Die Angabe ist optional (<= 100, default: 95) </td></tr>
|
||||||
<tr><td> </td><td>auftreten darf. Die Angabe ist optional (default: 20) </td></tr>
|
<tr><td> <b>careCycle</b> </td><td>maximaler Abstand in Tagen, der zwischen zwei Ladungszuständen von mindestens 'maxSoC' </td></tr>
|
||||||
|
<tr><td> </td><td>auftreten darf. Die Angabe ist optional (default: 20) </td></tr>
|
||||||
</table>
|
</table>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
Loading…
Reference in New Issue
Block a user