2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-22 20:24:36 +00:00

76_SolarForecast.pm: contrib 0.68.2

git-svn-id: https://svn.fhem.de/fhem/trunk@26419 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2022-09-18 14:55:01 +00:00
parent 3c5327f4d0
commit 881607a2e8

View File

@ -126,7 +126,7 @@ BEGIN {
# Versions History intern # Versions History intern
my %vNotesIntern = ( my %vNotesIntern = (
"0.68.2 "=> "18.09.2022 fix function _setpvCorrectionFactorAuto ", "0.68.2 "=> "18.09.2022 fix function _setpvCorrectionFactorAuto, new attr optimizeSolCastAPIreqInterval, change createReadingsFromArray ",
"0.68.1 "=> "17.09.2022 new readings Today_MaxPVforecast, Today_MaxPVforecastTime ", "0.68.1 "=> "17.09.2022 new readings Today_MaxPVforecast, Today_MaxPVforecastTime ",
"0.68.0 "=> "15.09.2022 integrate SolCast API, change attribute Wh/kWh to Wh_kWh, rename Reading nextPolltime to ". "0.68.0 "=> "15.09.2022 integrate SolCast API, change attribute Wh/kWh to Wh_kWh, rename Reading nextPolltime to ".
"nextCycletime, rework plant config check, minor (bug)fixes ", "nextCycletime, rework plant config check, minor (bug)fixes ",
@ -699,6 +699,7 @@ sub Initialize {
"maxVariancePerDay ". "maxVariancePerDay ".
"maxValBeam ". "maxValBeam ".
"numHistDays:slider,1,1,30 ". "numHistDays:slider,1,1,30 ".
"optimizeSolCastAPIreqInterval:1,0 ".
"preferredChargeBattery:slider,0,1,100 ". "preferredChargeBattery:slider,0,1,100 ".
"rainFactorDamping:slider,0,1,100 ". "rainFactorDamping:slider,0,1,100 ".
"sameWeekdaysForConsfc:1,0 ". "sameWeekdaysForConsfc:1,0 ".
@ -1753,10 +1754,11 @@ sub _getRoofTopData {
} }
my $lrt = SolCastAPIVal ($hash, '?All', '?All', 'lastretrieval_timestamp', 0); my $lrt = SolCastAPIVal ($hash, '?All', '?All', 'lastretrieval_timestamp', 0);
my $apiitv = SolCastAPIVal ($hash, '?All', '?All', 'currentAPIinterval', $apirepetdef);
if ($lrt && $t < $lrt + $apirepetdef) { if ($lrt && $t < $lrt + $apiitv) {
my $rt = $lrt + $apirepetdef - $t; my $rt = $lrt + $apiitv - $t;
readingsSingleUpdate($hash, 'nextSolCastCall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($lrt + $apirepetdef))[0], 1); #readingsSingleUpdate($hash, 'nextSolCastCall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($lrt + $apiitv))[0], 1);
return qq{The waiting time to the next SolCast API call has not expired yet. The remaining waiting time is $rt seconds}; return qq{The waiting time to the next SolCast API call has not expired yet. The remaining waiting time is $rt seconds};
} }
} }
@ -1949,9 +1951,6 @@ sub __solCast_ApiResponse {
my $t = time; my $t = time;
___setLastAPIcallKeyData ($hash, $t); ___setLastAPIcallKeyData ($hash, $t);
my $lrt = SolCastAPIVal ($hash, '?All', '?All', 'lastretrieval_timestamp', $t);
readingsSingleUpdate($hash, 'nextSolCastCall', 'after '.(timestampToTimestring ($lrt + $apirepetdef))[0], 1);
my $param = { my $param = {
hash => $hash, hash => $hash,
name => $name, name => $name,
@ -2018,11 +2017,44 @@ sub ___setLastAPIcallKeyData {
$data{$type}{$name}{solcastapi}{'?All'}{'?All'}{lastretrieval_time} = (timestampToTimestring ($t))[3]; # letzte Abrufzeit $data{$type}{$name}{solcastapi}{'?All'}{'?All'}{lastretrieval_time} = (timestampToTimestring ($t))[3]; # letzte Abrufzeit
$data{$type}{$name}{solcastapi}{'?All'}{'?All'}{lastretrieval_timestamp} = $t; # letzter Abrufzeitstempel $data{$type}{$name}{solcastapi}{'?All'}{'?All'}{lastretrieval_timestamp} = $t; # letzter Abrufzeitstempel
$data{$type}{$name}{solcastapi}{'?All'}{'?All'}{todaySolCastAPIcalls} += 1; $data{$type}{$name}{solcastapi}{'?All'}{'?All'}{todayDoneAPIcalls} += 1;
## Berechnung des optimalen Request Intervalls
################################################
if (AttrVal($name, 'optimizeSolCastAPIreqInterval', 0)) {
my $asc = CurrentVal ($hash, 'allstringscount', 1); # Anzahl der Strings my $asc = CurrentVal ($hash, 'allstringscount', 1); # Anzahl der Strings
my $madr = $apimaxreqs / $asc; # max. tägliche Anzahl API Abrufe my $madr = $apimaxreqs / $asc; # kalkulieren max. tägliche Anzahl API Abrufe
my $darr = $apimaxreqs - SolCastAPIVal ($hash, '?All', '?All', 'todaySolCastAPIcalls', 0); # verbleibende SolCast API Calls am aktuellen Tag
my %seen;
my @as = map { $data{$type}{$name}{solcastapi}{'?IdPair'}{$_}{apikey}; } keys %{$data{$type}{$name}{solcastapi}{'?IdPair'}};
my @unique = grep { !$seen{$_}++ } @as;
my $upc = scalar @unique;
$madr *= $upc;
# $data{$type}{$name}{current}{solCastTodayMaxAPIcalls} = $madr;
my $darr = $madr - SolCastAPIVal ($hash, '?All', '?All', 'todayDoneAPIcalls', 0); # verbleibende SolCast API Calls am aktuellen Tag
$darr = 0 if($darr < 0);
$data{$type}{$name}{solcastapi}{'?All'}{'?All'}{todayRemaingAPIcalls} = $darr;
my $date = strftime "%Y-%m-%d", localtime($t);
my $sstime = timestringToTimestamp ($date.' '.ReadingsVal($name, "Today_SunSet", '00:00').':00');
my $dart = $sstime - $t; # verbleibende Sekunden bis Sonnenuntergang
$dart = 0 if($dart < 0);
#$data{$type}{$name}{current}{secondsUntilSunSet} = $dart;
$data{$type}{$name}{solcastapi}{'?All'}{'?All'}{currentAPIinterval} = $apirepetdef;
$data{$type}{$name}{solcastapi}{'?All'}{'?All'}{currentAPIinterval} = int ($dart / $darr) if($dart && $darr);
}
else {
$data{$type}{$name}{solcastapi}{'?All'}{'?All'}{currentAPIinterval} = $apirepetdef;
}
my $lang = AttrVal ('global', 'language', 'EN');
my $apiitv = SolCastAPIVal ($hash, '?All', '?All', 'currentAPIinterval', $apirepetdef);
readingsSingleUpdate($hash, 'nextSolCastCall', $hqtxt{after}{$lang}.' '.(timestampToTimestring ($t + $apiitv))[0], 1);
return; return;
} }
@ -2167,15 +2199,26 @@ sub Attr {
if ($cmd eq "set") { if ($cmd eq "set") {
if ($aName eq "interval") { if ($aName eq "interval") {
unless ($aVal =~ /^[0-9]+$/x) {return "The value for $aName is not valid. Use only figures 0-9 !";} unless ($aVal =~ /^[0-9]+$/x) {
return qq{The value for $aName is not valid. Use only figures 0-9 !};
}
InternalTimer(gettimeofday()+1.0, "FHEM::SolarForecast::centralTask", $hash, 0); InternalTimer(gettimeofday()+1.0, "FHEM::SolarForecast::centralTask", $hash, 0);
} }
if ($aName eq "maxVariancePerDay") { if ($aName eq "maxVariancePerDay") {
unless ($aVal =~ /^[0-9.]+$/x) {return "The value for $aName is not valid. Use only numbers with optional decimal places !";} unless ($aVal =~ /^[0-9.]+$/x) {
return qq{The value for $aName is not valid. Use only numbers with optional decimal places !};
} }
} }
if ($init_done == 1 && $aName eq "optimizeSolCastAPIreqInterval") {
if (!isSolCastUsed ($hash)) {
return qq{The attribute $aName is only valid for device model "SolCastAPI".};
}
}
}
my $params = { my $params = {
hash => $hash, hash => $hash,
name => $name, name => $name,
@ -2595,6 +2638,8 @@ sub centralTask {
deleteReadingspec ($hash, "nextPolltime"); deleteReadingspec ($hash, "nextPolltime");
delete $data{$type}{$name}{solcastapi}{'All'}; delete $data{$type}{$name}{solcastapi}{'All'};
delete $data{$type}{$name}{solcastapi}{'#All'}; delete $data{$type}{$name}{solcastapi}{'#All'};
delete $data{$type}{$name}{solcastapi}{'?All'}{'?All'}{todaySolCastAPIcalls};
delete $data{$type}{$name}{solcastapi}{'?All'}{'?All'}{currentAPIInterval};
############################################################### ###############################################################
@ -2654,6 +2699,8 @@ sub centralTask {
_specialActivities ($centpars); # zusätzliche Events generieren + Sonderaufgaben _specialActivities ($centpars); # zusätzliche Events generieren + Sonderaufgaben
_transferWeatherValues ($centpars); # Wetterwerte übertragen _transferWeatherValues ($centpars); # Wetterwerte übertragen
createReadingsFromArray ($hash, \@da, 1); # Readings erzeugen
if (isSolCastUsed ($hash)) { if (isSolCastUsed ($hash)) {
_getRoofTopData ($centpars); # SolCast API Strahlungswerte abrufen _getRoofTopData ($centpars); # SolCast API Strahlungswerte abrufen
_transferSolCastRadiationValues ($centpars); # SolCast API Strahlungswerte übertragen _transferSolCastRadiationValues ($centpars); # SolCast API Strahlungswerte übertragen
@ -2672,9 +2719,8 @@ sub centralTask {
_calcReadingsTomorrowPVFc ($centpars); # zusätzliche Readings Tomorrow_HourXX_PVforecast berechnen _calcReadingsTomorrowPVFc ($centpars); # zusätzliche Readings Tomorrow_HourXX_PVforecast berechnen
_createSummaries ($centpars); # Zusammenfassungen erstellen _createSummaries ($centpars); # Zusammenfassungen erstellen
if(@da) { createReadingsFromArray ($hash, \@da, 1); # Readings erzeugen
createReadingsFromArray ($hash, \@da, 1);
}
calcVariance ($centpars); # Autokorrektur berechnen calcVariance ($centpars); # Autokorrektur berechnen
saveEnergyConsumption ($centpars); # Energie Hausverbrauch speichern saveEnergyConsumption ($centpars); # Energie Hausverbrauch speichern
@ -2698,7 +2744,7 @@ sub createStringConfig { ## no critic "not used"
my $type = $hash->{TYPE}; my $type = $hash->{TYPE};
delete $data{$type}{$name}{strings}; # Stringhash zurücksetzen delete $data{$type}{$name}{strings}; # Stringhash zurücksetzen
my @istrings = split ",", ReadingsVal ($name, "inverterStrings", undef); # Stringbezeichner my @istrings = split ",", ReadingsVal ($name, "inverterStrings", ""); # Stringbezeichner
$data{$type}{$name}{current}{allstringscount} = scalar @istrings; # Anzahl der Anlagenstrings $data{$type}{$name}{current}{allstringscount} = scalar @istrings; # Anzahl der Anlagenstrings
if(!@istrings) { if(!@istrings) {
@ -2890,7 +2936,7 @@ sub _specialActivities {
delete $hash->{HELPER}{INITCONTOTAL}; delete $hash->{HELPER}{INITCONTOTAL};
delete $hash->{HELPER}{INITFEEDTOTAL}; delete $hash->{HELPER}{INITFEEDTOTAL};
delete $data{$type}{$name}{solcastapi}{'?All'}{'?All'}{todaySolCastAPIcalls}; delete $data{$type}{$name}{solcastapi}{'?All'}{'?All'}{todayDoneAPIcalls};
delete $data{$type}{$name}{current}{todayMaxEstValue}; delete $data{$type}{$name}{current}{todayMaxEstValue};
delete $data{$type}{$name}{current}{todayMaxEstTimestamp}; delete $data{$type}{$name}{current}{todayMaxEstTimestamp};
@ -8378,6 +8424,8 @@ sub createReadingsFromArray {
my $daref = shift; my $daref = shift;
my $doevt = shift // 0; my $doevt = shift // 0;
return if(!scalar @$daref);
readingsBeginUpdate($hash); readingsBeginUpdate($hash);
for my $elem (@$daref) { for my $elem (@$daref) {
@ -8387,6 +8435,8 @@ sub createReadingsFromArray {
readingsEndUpdate($hash, $doevt); readingsEndUpdate($hash, $doevt);
undef @$daref;
return; return;
} }
@ -9132,6 +9182,9 @@ return $def;
# Sonderabfragen # Sonderabfragen
# SolCastAPIVal ($hash, '?All', '?All', 'lastretrieval_time', $def) - letzte Abfrage Zeitstring # SolCastAPIVal ($hash, '?All', '?All', 'lastretrieval_time', $def) - letzte Abfrage Zeitstring
# SolCastAPIVal ($hash, '?All', '?All', 'lastretrieval_timestamp', $def) - letzte Abfrage Unix Timestamp # SolCastAPIVal ($hash, '?All', '?All', 'lastretrieval_timestamp', $def) - letzte Abfrage Unix Timestamp
# SolCastAPIVal ($hash, '?All', '?All', 'todayDoneAPIcalls', $def) - heute ausgeführte API Requests
# SolCastAPIVal ($hash, '?All', '?All', 'todayRemaingAPIcalls', $def) - heute noch mögliche API Requests
# SolCastAPIVal ($hash, '?All', '?All', 'currentAPIinterval', $def) - aktuelles API Request Intervall
# SolCastAPIVal ($hash, '?IdPair', '?<pk>', 'rtid', $def) - RoofTop-ID, <pk> = Paarschlüssel # SolCastAPIVal ($hash, '?IdPair', '?<pk>', 'rtid', $def) - RoofTop-ID, <pk> = Paarschlüssel
# SolCastAPIVal ($hash, '?IdPair', '?<pk>', 'apikey', $def) - API-Key, <pk> = Paarschlüssel # SolCastAPIVal ($hash, '?IdPair', '?<pk>', 'apikey', $def) - API-Key, <pk> = Paarschlüssel
# #
@ -9204,9 +9257,9 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
</ul> </ul>
<br> <br>
Nach der Definition des Devices sind zwingend Vorhersage-Devices des Typs DWD_OpenData zuzuordnen sowie weitere Nach der Definition des Devices sind in Abhängigkeit der verwendeten Prognosequellen zwingend weitere
anlagenspezifische Angaben mit den entsprechenden set-Kommandos zu hinterlegen. <br> anlagenspezifische Angaben mit den entsprechenden set-Kommandos zu hinterlegen. <br>
Mit nachfolgenden set-Kommandos werden die Quellen(devices) für maßgebliche Informationen Mit nachfolgenden set-Kommandos werden für die Funktion des Moduls maßgebliche Informationen
hinterlegt: <br><br> hinterlegt: <br><br>
<ul> <ul>
@ -9216,18 +9269,26 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
<tr><td> <b>currentRadiationDev </b> </td><td>DWD_OpenData Device welches Strahlungsdaten liefert bzw. SolCast-API </td></tr> <tr><td> <b>currentRadiationDev </b> </td><td>DWD_OpenData Device welches Strahlungsdaten liefert bzw. SolCast-API </td></tr>
<tr><td> <b>currentInverterDev</b> </td><td>Device welches PV Leistungsdaten liefert </td></tr> <tr><td> <b>currentInverterDev</b> </td><td>Device welches PV Leistungsdaten liefert </td></tr>
<tr><td> <b>currentMeterDev</b> </td><td>Device welches Netz I/O-Daten liefert </td></tr> <tr><td> <b>currentMeterDev</b> </td><td>Device welches Netz I/O-Daten liefert </td></tr>
<tr><td> <b>currentBatteryDev</b> </td><td>Device welches Batterie Leistungsdaten liefert </td></tr> <tr><td> <b>currentBatteryDev</b> </td><td>Device welches Batterie Leistungsdaten liefert (sofern vorhanden) </td></tr>
<tr><td> <b>inverterStrings</b> </td><td>Bezeichner der vohandenen Anlagenstrings </td></tr>
<tr><td> <b>moduleDirection</b> </td><td>Ausrichtung (Azimuth) der Anlagenstrings </td></tr>
<tr><td> <b>modulePeakString</b> </td><td>die DC-Peakleistung der Anlagenstrings </td></tr>
<tr><td> <b>roofIdentPair</b> </td><td>die Identifikationsdaten (bei Nutzung der SolCast API) </td></tr>
<tr><td> <b>moduleRoofTops</b> </td><td>die Rooftop Parameter (bei Nutzung der SolCast API) </td></tr>
<tr><td> <b>moduleTiltAngle</b> </td><td>die Neigungswinkel der der Anlagenmodule </td></tr>
</table> </table>
</ul> </ul>
<br> <br>
Um eine Anpassung an die persönliche Anlage zu ermöglichen, können Korrekturfaktoren manuell Um eine Anpassung an die persönliche Anlage zu ermöglichen, können Korrekturfaktoren manuell
(set &lt;name&gt; pvCorrectionFactor_XX) bzw. automatisiert (set &lt;name&gt; pvCorrectionFactor_Auto on) bestimmt (set &lt;name&gt; pvCorrectionFactor_XX) bzw. automatisiert (set &lt;name&gt; pvCorrectionFactor_Auto on) bestimmt
werden. <br><br> werden. Weiterhin kann mit den Attributen <a href="#SolarForecast-attr-cloudFactorDamping">cloudFactorDamping</a> und
<a href="#SolarForecast-attr-rainFactorDamping">rainFactorDamping</a> der Beeinflussungsgrad von Bewölkungs- und
Regenprognosen eingestellt werden. <br><br>
<b>Hinweis</b><br> <b>Hinweis</b><br>
Es wird empfohlen die automatische Vorhersagekorrektur unmittelbar einzuschalten, da das SolarForecast Device etliche Tage Bei Nutzung des DWD für die solare Vorhersage wird empfohlen die automatische Vorhersagekorrektur unmittelbar
benötigt um eine Optimierung der Korrekturfaktoren zu erreichen. einzuschalten, da das SolarForecast Device eine lange Zeit benötigt um die Optimierung der Korrekturfaktoren zu erreichen.
<br><br> <br><br>
</ul> </ul>
@ -9470,7 +9531,7 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
<a id="SolarForecast-set-modulePeakString"></a> <a id="SolarForecast-set-modulePeakString"></a>
<li><b>modulePeakString &lt;Stringname1&gt;=&lt;Peak&gt; [&lt;Stringname2&gt;=&lt;Peak&gt; &lt;Stringname3&gt;=&lt;Peak&gt; ...] </b> <br><br> <li><b>modulePeakString &lt;Stringname1&gt;=&lt;Peak&gt; [&lt;Stringname2&gt;=&lt;Peak&gt; &lt;Stringname3&gt;=&lt;Peak&gt; ...] </b> <br><br>
Die Peakleistung des Strings "StringnameX" in kWp. Der Stringname ist ein Schlüsselwert des Die DC Peakleistung des Strings "StringnameX" in kWp. Der Stringname ist ein Schlüsselwert des
Readings <b>inverterStrings</b>. <br><br> Readings <b>inverterStrings</b>. <br><br>
<ul> <ul>
@ -9681,8 +9742,8 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
<ul> <ul>
<b>Beispiele: </b> <br> <b>Beispiele: </b> <br>
set &lt;name&gt; roofIdentPair p1 rtid="92fc-6796-f574-ae5f" apikey="oNHDbkKuC_eGEvZe7ECLl6-T1jLyfOgC" <br> set &lt;name&gt; roofIdentPair p1 rtid=92fc-6796-f574-ae5f apikey=oNHDbkKuC_eGEvZe7ECLl6-T1jLyfOgC <br>
set &lt;name&gt; roofIdentPair p2 rtid=f574-ae5f-"92fc-6796" apikey="eGEvZe7ECLl6_T1jLyfOgC_oNHDbkKuC" <br> set &lt;name&gt; roofIdentPair p2 rtid=f574-ae5f-92fc-6796 apikey=eGEvZe7ECLl6_T1jLyfOgC_oNHDbkKuC <br>
</ul> </ul>
<br> <br>
@ -9864,7 +9925,9 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
<tr><td> <b>lastretrieval_time</b> </td><td>Zeit des letzten SolCast API Abrufs </td></tr> <tr><td> <b>lastretrieval_time</b> </td><td>Zeit des letzten SolCast API Abrufs </td></tr>
<tr><td> <b>lastretrieval_timestamp</b> </td><td>Unix Timestamp des letzten SolCast API Abrufs </td></tr> <tr><td> <b>lastretrieval_timestamp</b> </td><td>Unix Timestamp des letzten SolCast API Abrufs </td></tr>
<tr><td> <b>pv_estimate</b> </td><td>erwartete PV Erzeugung von SolCast API (Wh) </td></tr> <tr><td> <b>pv_estimate</b> </td><td>erwartete PV Erzeugung von SolCast API (Wh) </td></tr>
<tr><td> <b>todayDoneAPIcalls</b> </td><td>Anzahl der ausgeführten API Requests am aktuellen Tag </td></tr>
<tr><td> <b>todayRemaingAPIcalls</b> </td><td>Anzahl der noch möglichen API Requests am aktuellen Tag </td></tr>
<tr><td> <b>currentAPIinterval</b> </td><td>das aktuell verwendete API Abrufintervall </td></tr>
</table> </table>
</ul> </ul>
</li> </li>
@ -10376,6 +10439,16 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
</li> </li>
<br> <br>
<a id="SolarForecast-attr-optimizeSolCastAPIreqInterval"></a>
<li><b>optimizeSolCastAPIreqInterval </b><br>
(nur bei Verwendung der SolCast API) <br><br>
Das default Abrufintervall der SolCast API beträgt fest 1 Stunde. Ist dieses Attribut gesetzt erfolgt ein dynamische
Anpassung des Intervalls mit dem Ziel die maximal möglichen Abrufe innerhalb von Sonnenauf- und untergang
auszunutzen. <br>
(default: 0)
</li>
<br>
<a id="SolarForecast-attr-preferredChargeBattery"></a> <a id="SolarForecast-attr-preferredChargeBattery"></a>
<li><b>preferredChargeBattery </b><br> <li><b>preferredChargeBattery </b><br>
Es werden Verbraucher mit dem Mode <b>can</b> erst dann eingeschaltet, wenn die angegebene Batterieladung (%) Es werden Verbraucher mit dem Mode <b>can</b> erst dann eingeschaltet, wenn die angegebene Batterieladung (%)