2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-02-25 09:55:38 +00:00

76_SolarForecast: new attr ctrlGenPVdeviation

git-svn-id: https://svn.fhem.de/fhem/trunk@28074 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2023-10-20 20:57:32 +00:00
parent 104dff0f47
commit 7ed994d557
2 changed files with 92 additions and 49 deletions

View File

@ -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.
- feature: 76_SolarForecast: new attr ctrlGenPVdeviation
- feature: 70_ESCVP21net: add reading stateP for on/off - feature: 70_ESCVP21net: add reading stateP for on/off
- feature: 76_SolarForecast: allow key 'noshow' more values, KI improves - feature: 76_SolarForecast: allow key 'noshow' more values, KI improves
- change: 22_HOMEMODE: change url for IP check - change: 22_HOMEMODE: change url for IP check

View File

@ -144,6 +144,7 @@ BEGIN {
# Versions History intern # Versions History intern
my %vNotesIntern = ( my %vNotesIntern = (
"1.0.6" => "19.10.2023 new attr ctrlGenPVdeviation ",
"1.0.5" => "11.10.2023 new sub _aiGetSpread for estimate AI results stepwise, allow key 'noshow' values 0,1,2,3 ". "1.0.5" => "11.10.2023 new sub _aiGetSpread for estimate AI results stepwise, allow key 'noshow' values 0,1,2,3 ".
"calculate conForecastTillNextSunrise accurate to the minute ", "calculate conForecastTillNextSunrise accurate to the minute ",
"1.0.4" => "10.10.2023 fix: print always Log in _calcCaQ* subroutines even if calaculated factors are equal ". "1.0.4" => "10.10.2023 fix: print always Log in _calcCaQ* subroutines even if calaculated factors are equal ".
@ -683,6 +684,8 @@ my %hqtxt = (
DE => qq{Verbrauch} }, DE => qq{Verbrauch} },
tday => { EN => qq{today}, tday => { EN => qq{today},
DE => qq{heute} }, DE => qq{heute} },
ctnsly => { EN => qq{continuously},
DE => qq{fortlaufend} },
yday => { EN => qq{yesterday}, yday => { EN => qq{yesterday},
DE => qq{gestern} }, DE => qq{gestern} },
after => { EN => qq{after}, after => { EN => qq{after},
@ -1012,6 +1015,7 @@ sub Initialize {
"ctrlAutoRefreshFW:$fwd ". "ctrlAutoRefreshFW:$fwd ".
"ctrlConsRecommendReadings:multiple-strict,$allcs ". "ctrlConsRecommendReadings:multiple-strict,$allcs ".
"ctrlDebug:multiple-strict,$dm ". "ctrlDebug:multiple-strict,$dm ".
"ctrlGenPVdeviation:daily,continuously ".
"ctrlInterval ". "ctrlInterval ".
"ctrlLanguage:DE,EN ". "ctrlLanguage:DE,EN ".
"ctrlNextDayForecastReadings:multiple-strict,$hod ". "ctrlNextDayForecastReadings:multiple-strict,$hod ".
@ -3999,6 +4003,7 @@ sub Attr {
my $name = shift; my $name = shift;
my $aName = shift; my $aName = shift;
my $aVal = shift; my $aVal = shift;
my $hash = $defs{$name}; my $hash = $defs{$name};
my ($do,$val); my ($do,$val);
@ -4021,11 +4026,17 @@ sub Attr {
delete $hash->{AUTOREFRESH}; delete $hash->{AUTOREFRESH};
} }
if($aName eq "ctrlNextDayForecastReadings") { if($aName eq 'ctrlNextDayForecastReadings') {
deleteReadingspec ($hash, "Tomorrow_Hour.*"); deleteReadingspec ($hash, "Tomorrow_Hour.*");
} }
if ($cmd eq "set") { if($aName eq 'ctrlGenPVdeviation' && $aVal eq 'daily') {
my $type = $hash->{TYPE};
deleteReadingspec ($hash, 'Today_PVdeviation');
delete $data{$type}{$name}{circular}{99}{tdayDvtn};
}
if ($cmd eq 'set') {
if ($aName eq 'ctrlInterval') { if ($aName eq 'ctrlInterval') {
unless ($aVal =~ /^[0-9]+$/x) { unless ($aVal =~ /^[0-9]+$/x) {
return qq{The value for $aName is not valid. Use only figures 0-9 !}; return qq{The value for $aName is not valid. Use only figures 0-9 !};
@ -4074,7 +4085,7 @@ sub Attr {
aVal => $aVal aVal => $aVal
}; };
$aName = "consumer" if($aName =~ /consumer?(\d+)$/xs); $aName = 'consumer' if($aName =~ /consumer?(\d+)$/xs);
if($hattr{$aName} && defined &{$hattr{$aName}{fn}}) { if($hattr{$aName} && defined &{$hattr{$aName}{fn}}) {
my $ret = q{}; my $ret = q{};
@ -5720,7 +5731,6 @@ sub _transferInverterValues {
debugLog ($paref, "collectData", "pv: $pv W, etotal: $etotal Wh"); debugLog ($paref, "collectData", "pv: $pv W, etotal: $etotal Wh");
my $nhour = $chour + 1; my $nhour = $chour + 1;
my $histetot = HistoryVal ($hash, $day, sprintf("%02d",$nhour), "etotal", 0); # etotal zu Beginn einer Stunde my $histetot = HistoryVal ($hash, $day, sprintf("%02d",$nhour), "etotal", 0); # etotal zu Beginn einer Stunde
my $ethishour; my $ethishour;
@ -6165,6 +6175,8 @@ sub _createSummaries {
$todaySumRe->{PV} += ReadingsNum ($name, "Today_Hour".sprintf("%02d",$th)."_PVreal", 0); $todaySumRe->{PV} += ReadingsNum ($name, "Today_Hour".sprintf("%02d",$th)."_PVreal", 0);
} }
my $pvre = int $todaySumRe->{PV};
push @{$data{$type}{$name}{current}{h4fcslidereg}}, int $next4HoursSum->{PV}; # Schieberegister 4h Summe Forecast push @{$data{$type}{$name}{current}{h4fcslidereg}}, int $next4HoursSum->{PV}; # Schieberegister 4h Summe Forecast
limitArray ($data{$type}{$name}{current}{h4fcslidereg}, $defslidenum); limitArray ($data{$type}{$name}{current}{h4fcslidereg}, $defslidenum);
@ -6200,6 +6212,7 @@ sub _createSummaries {
push @$daref, "Current_SelfConsumptionRate<>". $selfconsumptionrate. " %"; push @$daref, "Current_SelfConsumptionRate<>". $selfconsumptionrate. " %";
push @$daref, "Current_Surplus<>". $surplus. " W"; push @$daref, "Current_Surplus<>". $surplus. " W";
push @$daref, "Current_AutarkyRate<>". $autarkyrate. " %"; push @$daref, "Current_AutarkyRate<>". $autarkyrate. " %";
push @$daref, "Today_PVreal<>". $pvre. " Wh" if($pvre > ReadingsNum ($name, 'Today_PVreal', 0));
push @$daref, "NextHours_Sum01_PVforecast<>". (int $next1HoursSum->{PV})." Wh"; push @$daref, "NextHours_Sum01_PVforecast<>". (int $next1HoursSum->{PV})." Wh";
push @$daref, "NextHours_Sum02_PVforecast<>". (int $next2HoursSum->{PV})." Wh"; push @$daref, "NextHours_Sum02_PVforecast<>". (int $next2HoursSum->{PV})." Wh";
@ -6208,7 +6221,6 @@ sub _createSummaries {
push @$daref, "RestOfDayPVforecast<>". (int $restOfDaySum->{PV}). " Wh"; push @$daref, "RestOfDayPVforecast<>". (int $restOfDaySum->{PV}). " Wh";
push @$daref, "Tomorrow_PVforecast<>". (int $tomorrowSum->{PV}). " Wh"; push @$daref, "Tomorrow_PVforecast<>". (int $tomorrowSum->{PV}). " Wh";
push @$daref, "Today_PVforecast<>". (int $todaySumFc->{PV}). " Wh"; push @$daref, "Today_PVforecast<>". (int $todaySumFc->{PV}). " Wh";
push @$daref, "Today_PVreal<>". (int $todaySumRe->{PV}). " Wh" if(int $todaySumRe->{PV} > ReadingsNum($name, 'Today_PVreal', 0));
push @$daref, "Tomorrow_ConsumptionForecast<>". $tconsum. " Wh" if(defined $tconsum); push @$daref, "Tomorrow_ConsumptionForecast<>". $tconsum. " Wh" if(defined $tconsum);
push @$daref, "NextHours_Sum04_ConsumptionForecast<>". (int $next4HoursSum->{Consumption})." Wh"; push @$daref, "NextHours_Sum04_ConsumptionForecast<>". (int $next4HoursSum->{Consumption})." Wh";
@ -7730,7 +7742,7 @@ return;
} }
################################################################ ################################################################
# Kerrektur von Today_PVreal + # Korrektur von Today_PVreal +
# berechnet die prozentuale Abweichung von Today_PVforecast # berechnet die prozentuale Abweichung von Today_PVforecast
# und Today_PVreal # und Today_PVreal
################################################################ ################################################################
@ -7744,30 +7756,29 @@ sub _calcTodayPVdeviation {
my $day = $paref->{day}; my $day = $paref->{day};
my $daref = $paref->{daref}; my $daref = $paref->{daref};
my $sstime = timestringToTimestamp ($date.' '.ReadingsVal($name, "Today_SunSet", '22:00').':00');
return if($t < $sstime);
my $pvfc = ReadingsNum ($name, 'Today_PVforecast', 0); my $pvfc = ReadingsNum ($name, 'Today_PVforecast', 0);
my $pvre = ReadingsNum ($name, 'Today_PVreal', 0); my $pvre = ReadingsNum ($name, 'Today_PVreal', 0);
my $hsr = (split ":", ReadingsVal ($name, 'Today_SunRise', '03:00'))[0]; # die Stunde des Sonnenaufgangs return if(!$pvre);
my $ehsr = HistoryVal ($hash, $day, $hsr, 'etotal', 0); # gespeichertes etotal vor Sonnenaufgang
if ($ehsr) { my $dp;
my $esset = CurrentVal ($hash, 'etotal', 0); # Erzeugung total (Wh) nach Sonnenuntergang
$pvre = $esset - $ehsr; if (AttrVal($name, 'ctrlGenPVdeviation', 'daily') eq 'daily') {
} my $sstime = timestringToTimestamp ($date.' '.ReadingsVal ($name, "Today_SunSet", '22:00').':00');
return if($t < $sstime);
my $diff = $pvfc - $pvre; my $diff = $pvfc - $pvre;
$dp = sprintf "%.2f" , (100 * $diff / $pvre);
}
else {
my $rodfc = ReadingsNum ($name, 'RestOfDayPVforecast', 0);
my $dayfc = $pvre + $rodfc; # laufende Tagesprognose aus PVreal + Prognose Resttag
$dp = sprintf "%.2f", (100 * ($pvfc - $dayfc) / $dayfc);
}
if ($pvre) {
my $dp = sprintf "%.2f" , (100 * $diff / $pvre);
$data{$type}{$name}{circular}{99}{tdayDvtn} = $dp; $data{$type}{$name}{circular}{99}{tdayDvtn} = $dp;
push @$daref, "Today_PVdeviation<>". $dp. " %"; push @$daref, "Today_PVdeviation<>". $dp.' %';
push @$daref, "Today_PVreal<>". (sprintf "%.0f", $pvre)." Wh";
}
return; return;
} }
@ -8340,6 +8351,7 @@ sub entryGraphic {
flowgconsTime => AttrVal ($name, 'flowGraphicShowConsumerRemainTime', 1), # Verbraucher Restlaufeit in der Energieflußgrafik anzeigen flowgconsTime => AttrVal ($name, 'flowGraphicShowConsumerRemainTime', 1), # Verbraucher Restlaufeit in der Energieflußgrafik anzeigen
flowgconsDist => AttrVal ($name, 'flowGraphicConsumerDistance', $fgCDdef), # Abstand Verbrauchericons zueinander flowgconsDist => AttrVal ($name, 'flowGraphicConsumerDistance', $fgCDdef), # Abstand Verbrauchericons zueinander
css => AttrVal ($name, 'flowGraphicCss', $cssdef), # flowGraphicCss Styles css => AttrVal ($name, 'flowGraphicCss', $cssdef), # flowGraphicCss Styles
genpvdva => AttrVal ($name, 'ctrlGenPVdeviation', 'daily'), # Methode der Abweichungsberechnung
lang => AttrVal ($name, 'ctrlLanguage', AttrVal ('global', 'language', $deflang)), lang => AttrVal ($name, 'ctrlLanguage', AttrVal ('global', 'language', $deflang)),
debug => getDebug ($hash), # Debug Module debug => getDebug ($hash), # Debug Module
}; };
@ -8821,8 +8833,10 @@ sub _graphicHeader {
$ydayDvtn =~ s/\./,/; $ydayDvtn =~ s/\./,/;
$ydayDvtn =~ s/,0//; $ydayDvtn =~ s/,0//;
my $genpvdva = $paref->{genpvdva};
my $dvtntxt = $hqtxt{dvtn}{$lang}.'&nbsp;'; my $dvtntxt = $hqtxt{dvtn}{$lang}.'&nbsp;';
my $tdaytxt = $hqtxt{tday}{$lang}.':&nbsp;'."<b>".$tdayDvtn."</b>"; my $tdaytxt = ($genpvdva eq 'daily' ? $hqtxt{tday}{$lang} : $hqtxt{ctnsly}{$lang}).':&nbsp;'."<b>".$tdayDvtn."</b>";
my $ydaytxt = $hqtxt{yday}{$lang}.':&nbsp;'."<b>".$ydayDvtn."</b>"; my $ydaytxt = $hqtxt{yday}{$lang}.':&nbsp;'."<b>".$ydayDvtn."</b>";
my $text_tdayDvtn = $tdayDvtn =~ /^-[1-9]/? $hqtxt{pmtp}{$lang} : my $text_tdayDvtn = $tdayDvtn =~ /^-[1-9]/? $hqtxt{pmtp}{$lang} :
@ -9085,10 +9099,10 @@ sub __createOwnSpec {
$ownv .= "<tr>"; $ownv .= "<tr>";
$ownv .= "<td $dstyle></td>"; $ownv .= "<td $dstyle></td>";
$ownv .= "<td $dstyle><b>".$h->{0}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{0}{rdg},'')."</td>" if(exists $h->{0}{label}); $ownv .= "<td $dstyle><b>".$h->{0}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{0}{rdg},'')."</td>" if($h->{0}{label});
$ownv .= "<td $dstyle><b>".$h->{1}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{1}{rdg},'')."</td>" if(exists $h->{1}{label}); $ownv .= "<td $dstyle><b>".$h->{1}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{1}{rdg},'')."</td>" if($h->{1}{label});
$ownv .= "<td $dstyle><b>".$h->{2}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{2}{rdg},'')."</td>" if(exists $h->{2}{label}); $ownv .= "<td $dstyle><b>".$h->{2}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{2}{rdg},'')."</td>" if($h->{2}{label});
$ownv .= "<td $dstyle><b>".$h->{3}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{3}{rdg},'')."</td>" if(exists $h->{3}{label}); $ownv .= "<td $dstyle><b>".$h->{3}{label}.":</b></td> <td align=right $dstyle>".ReadingsVal ($name,$h->{3}{rdg},'')."</td>" if($h->{3}{label});
$ownv .= "</tr>"; $ownv .= "</tr>";
} }
@ -15551,7 +15565,7 @@ to ensure that the system configuration is correct.
<ul> <ul>
<table> <table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup> <colgroup> <col width="23%"> <col width="77%"> </colgroup>
<tr><td> <b>aiProcess</b> </td><td>Process flow of AI support </td></tr> <tr><td> <b>aiProcess</b> </td><td>Process flow of AI support </td></tr>
<tr><td> <b>aiData</b> </td><td>AI data </td></tr> <tr><td> <b>aiData</b> </td><td>AI data </td></tr>
<tr><td> <b>apiCall</b> </td><td>Retrieval API interface without data output </td></tr> <tr><td> <b>apiCall</b> </td><td>Retrieval API interface without data output </td></tr>
@ -15571,6 +15585,20 @@ to ensure that the system configuration is correct.
</li> </li>
<br> <br>
<a id="SolarForecast-attr-ctrlGenPVdeviation"></a>
<li><b>ctrlGenPVdeviation </b><br>
Specifies the method for calculating the deviation between predicted and real PV generation.
The Reading <b>Today_PVdeviation</b> is created depending on this setting. <br><br>
<ul>
<table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
<tr><td> <b>daily</b> </td><td>Calculation and creation of Today_PVdeviation is done after sunset (default) </td></tr>
<tr><td> <b>continuously</b> </td><td>Calculation and creation of Today_PVdeviation is done continuously </td></tr>
</table>
</ul>
</li><br>
<a id="SolarForecast-attr-ctrlInterval"></a> <a id="SolarForecast-attr-ctrlInterval"></a>
<li><b>ctrlInterval &lt;Sekunden&gt; </b><br> <li><b>ctrlInterval &lt;Sekunden&gt; </b><br>
Time interval of data collection. <br> Time interval of data collection. <br>
@ -15638,7 +15666,7 @@ to ensure that the system configuration is correct.
<ul> <ul>
<table> <table>
<colgroup> <col width="20%"> <col width="80%"> </colgroup> <colgroup> <col width="25%"> <col width="75%"> </colgroup>
<tr><td> <b>allStringsFullfilled</b> </td><td>Fulfillment status of error-free generation of all strings </td></tr> <tr><td> <b>allStringsFullfilled</b> </td><td>Fulfillment status of error-free generation of all strings </td></tr>
<tr><td> <b>conForecastTillNextSunrise</b> </td><td>Consumption forecast from current hour to the coming sunrise </td></tr> <tr><td> <b>conForecastTillNextSunrise</b> </td><td>Consumption forecast from current hour to the coming sunrise </td></tr>
<tr><td> <b>currentAPIinterval</b> </td><td>the current call interval of the SolCast API (only model SolCastAPI) in seconds </td></tr> <tr><td> <b>currentAPIinterval</b> </td><td>the current call interval of the SolCast API (only model SolCastAPI) in seconds </td></tr>
@ -17363,7 +17391,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<ul> <ul>
<table> <table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup> <colgroup> <col width="23%"> <col width="77%"> </colgroup>
<tr><td> <b>aiProcess</b> </td><td>Prozessablauf der KI Unterstützung </td></tr> <tr><td> <b>aiProcess</b> </td><td>Prozessablauf der KI Unterstützung </td></tr>
<tr><td> <b>aiData</b> </td><td>KI Daten </td></tr> <tr><td> <b>aiData</b> </td><td>KI Daten </td></tr>
<tr><td> <b>apiCall</b> </td><td>Abruf API Schnittstelle ohne Datenausgabe </td></tr> <tr><td> <b>apiCall</b> </td><td>Abruf API Schnittstelle ohne Datenausgabe </td></tr>
@ -17383,6 +17411,20 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
</li> </li>
<br> <br>
<a id="SolarForecast-attr-ctrlGenPVdeviation"></a>
<li><b>ctrlGenPVdeviation </b><br>
Legt die Methode zur Berechnung der Abweichung von prognostizierter und realer PV Erzeugung fest.
Das Reading <b>Today_PVdeviation</b> wird in Abhängigkeit dieser Einstellung erstellt. <br><br>
<ul>
<table>
<colgroup> <col width="15%"> <col width="85%"> </colgroup>
<tr><td> <b>daily</b> </td><td>Berechnung und Erstellung von Today_PVdeviation erfolgt nach Sonnenuntergang (default) </td></tr>
<tr><td> <b>continuously</b> </td><td>Berechnung und Erstellung von Today_PVdeviation erfolgt fortlaufend </td></tr>
</table>
</ul>
</li><br>
<a id="SolarForecast-attr-ctrlInterval"></a> <a id="SolarForecast-attr-ctrlInterval"></a>
<li><b>ctrlInterval &lt;Sekunden&gt; </b><br> <li><b>ctrlInterval &lt;Sekunden&gt; </b><br>
Zeitintervall der Datensammlung. <br> Zeitintervall der Datensammlung. <br>
@ -17450,7 +17492,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
<ul> <ul>
<table> <table>
<colgroup> <col width="20%"> <col width="80%"> </colgroup> <colgroup> <col width="25%"> <col width="75%"> </colgroup>
<tr><td> <b>allStringsFullfilled</b> </td><td>Erfüllungsstatus der fehlerfreien Generierung aller Strings </td></tr> <tr><td> <b>allStringsFullfilled</b> </td><td>Erfüllungsstatus der fehlerfreien Generierung aller Strings </td></tr>
<tr><td> <b>conForecastTillNextSunrise</b> </td><td>Verbrauchsprognose von aktueller Stunde bis zum kommenden Sonnenaufgang </td></tr> <tr><td> <b>conForecastTillNextSunrise</b> </td><td>Verbrauchsprognose von aktueller Stunde bis zum kommenden Sonnenaufgang </td></tr>
<tr><td> <b>currentAPIinterval</b> </td><td>das aktuelle Abrufintervall der SolCast API (nur Model SolCastAPI) in Sekunden </td></tr> <tr><td> <b>currentAPIinterval</b> </td><td>das aktuelle Abrufintervall der SolCast API (nur Model SolCastAPI) in Sekunden </td></tr>