2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-10 03:06:37 +00:00

76_SolarForecast.pm: contrib 0.66.0

git-svn-id: https://svn.fhem.de/fhem/trunk@26256 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2022-07-24 14:45:28 +00:00
parent a2545a5a5a
commit 1afe19c07d

View File

@ -120,6 +120,10 @@ BEGIN {
# Versions History intern
my %vNotesIntern = (
"0.66.0 "=> "24.07.2022 insert function calcPeaklossByTemp to calculate peak power reduction by temperature ",
"0.65.8 "=> "23.07.2022 change calculation of cloud cover in calcRange function ",
"0.65.7 "=> "20.07.2022 change performance ratio in calcPVforecast to 0.85 ",
"0.65.6 "=> "20.07.2022 change __calcEnergyPieces for consumer types with \$hef{\$cotype}{f} == 1 ",
"0.65.5 "=> "13.07.2022 extend isInterruptable and isAddSwitchOffCond ",
"0.65.4 "=> "11.07.2022 new function isConsumerLogOn, minor fixes ",
"0.65.3 "=> "10.07.2022 consumer with mode=must are now interruptable, change hourscsme ",
@ -518,8 +522,6 @@ my %weather_ids = (
);
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
@ -535,10 +537,14 @@ my @dweattrmust = qw(TTT Neff R101 ww SunUp SunRise SunSet);
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 $prdef = 0.85; # default Performance Ratio (PR)
my $tempcoeffdef = -0.45; # default Temperaturkoeffizient Pmpp (%/°C) lt. Datenblatt Solarzelle
my $tempmodinc = 25; # default Temperaturerhöhung an Solarzellen gegenüber Umgebungstemperatur bei wolkenlosem Himmel
my $tempbasedef = 25; # Temperatur Module bei Nominalleistung
my $cldampdef = 35; # Gewichtung (%) 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 $rdampdef = 10; # Gewichtung (%) 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)
@ -572,7 +578,7 @@ my $cssdef = qq{.flowg.text { stroke: none; fill: gray; font-siz
my %hef = ( # Energiedaktoren für Verbrauchertypen
"heater" => { f => 1.00, m => 1.00, l => 1.00, mt => 240 },
"other" => { f => 1.00, m => 1.00, l => 1.00, mt => $defmintime }, # f = Faktor Energieverbrauch in erster Stunde
"other" => { f => 1.00, m => 1.00, l => 1.00, mt => $defmintime }, # f = Faktor Energieverbrauch in erster Stunde (wichtig auch für Kalkulation in __calcEnergyPieces !)
"charger" => { f => 1.00, m => 1.00, l => 1.00, mt => 120 }, # m = Faktor Energieverbrauch zwischen erster und letzter Stunde
"dishwasher" => { f => 0.45, m => 0.10, l => 0.45, mt => 180 }, # l = Faktor Energieverbrauch in letzter Stunde
"dryer" => { f => 0.40, m => 0.40, l => 0.20, mt => 90 }, # mt = default mintime (Minuten)
@ -2976,13 +2982,17 @@ sub __calcEnergyPieces {
my $cotype = ConsumerVal ($hash, $c, "type", $defctype );
my $mintime = ConsumerVal ($hash, $c, "mintime", $defmintime);
my $hours = ceil ($mintime / 60); # Laufzeit in h
my $hours = ceil ($mintime / 60); # Laufzeit in h
my $ctote = ConsumerVal ($hash, $c, "avgenergy", undef); # gemessener durchschnittlicher Energieverbrauch pro Stunde (Wh)
$ctote //= ConsumerVal ($hash, $c, "power", 0); # alternativer nominaler Energieverbrauch in W (bzw. Wh bezogen auf 1 h)
my $ctote = ConsumerVal ($hash, $c, "avgenergy", undef); # gemessener durchschnittlicher Energieverbrauch pro Stunde (Wh)
$ctote //= ConsumerVal ($hash, $c, "power", 0); # alternativer nominaler Energieverbrauch in W (bzw. Wh bezogen auf 1 h)
my $epiecef = $ctote * $hef{$cotype}{f}; # Gewichtung erste Laufstunde
my $epiecel = $ctote * $hef{$cotype}{l}; # Gewichtung letzte Laufstunde
if (int($hef{$cotype}{f}) == 1) { # bei linearen Verbrauchertypen die nominale Leistungsangabe verwenden statt Durchschnitt
$ctote = ConsumerVal ($hash, $c, "power", 0);
}
my $epiecef = $ctote * $hef{$cotype}{f}; # Gewichtung erste Laufstunde
my $epiecel = $ctote * $hef{$cotype}{l}; # Gewichtung letzte Laufstunde
my $epiecem = $ctote * $hef{$cotype}{m};
@ -6321,7 +6331,6 @@ sub calcPVforecast {
my $type = $hash->{TYPE};
my $stch = $data{$type}{$name}{strings}; # String Configuration Hash
my $pr = 1.0; # Performance Ratio (PR)
my $fh1 = $fh+1;
my $chour = strftime "%H", localtime($t+($num*3600)); # aktuelle Stunde
@ -6333,7 +6342,7 @@ sub calcPVforecast {
my $hq = "m";
my $clouddamp = AttrVal($name, "cloudFactorDamping", $cldampdef); # prozentuale Berücksichtigung des Bewölkungskorrekturfaktors
my $raindamp = AttrVal($name, "rainFactorDamping", $rdampdef); # prozentuale Berücksichtigung des Regenkorrekturfaktors
my $raindamp = AttrVal($name, "rainFactorDamping", $rdampdef); # prozentuale Berücksichtigung des Regenkorrekturfaktors
my @strings = sort keys %{$stch};
my $rainprob = NexthoursVal ($hash, "NextHour".sprintf("%02d",$num), "rainprob", 0); # Niederschlagswahrscheinlichkeit> 0,1 mm während der letzten Stunde
@ -6342,7 +6351,9 @@ sub calcPVforecast {
my $cloudcover = NexthoursVal ($hash, "NextHour".sprintf("%02d",$num), "cloudcover", 0); # effektive Wolkendecke nächste Stunde X
my $ccf = 1 - ((($cloudcover - $cloud_base)/100) * $clouddamp/100); # Cloud Correction Faktor mit Steilheit und Fußpunkt
my $range = calcRange ($cloudcover); # V 0.50.1 # Range errechnen
my $range = calcRange ($cloudcover); # Range errechnen
my $temp = NexthoursVal ($hash, "NextHour".sprintf("%02d",$num), "temp", $tempbasedef); # vorhergesagte Temperatur Stunde X
## Ermitteln des relevanten Autokorrekturfaktors
if ($uac eq "on") { # Autokorrektur soll genutzt werden
@ -6374,30 +6385,45 @@ sub calcPVforecast {
my ($lh,$sq);
for my $st (@strings) { # für jeden String der Config ..
my $peak = $stch->{"$st"}{peak}; # String Peak (kWp)
$peak *= 1000; # kWp in Wp umrechnen
my $ta = $stch->{"$st"}{tilt}; # Neigungswinkel Solarmodule
my $moddir = $stch->{"$st"}{dir}; # Ausrichtung der Solarmodule
my $peak = $stch->{"$st"}{peak}; # String Peak (kWp)
my $af = $hff{$ta}{$moddir} / 100; # Flächenfaktor: http://www.ing-büro-junge.de/html/photovoltaik.html
$paref->{peak} = $peak;
$paref->{cloudcover} = $cloudcover;
$paref->{temp} = $temp;
my $pv = sprintf "%.1f", ($rad * $af * $kJtokWh * $peak * $pr * $ccf * $rcf);
my ($peakloss, $modtemp) = calcPeaklossByTemp ($paref); # Reduktion Peakleistung durch Temperaturkoeffizienten der Module (vorzeichengehaftet)
$peak += $peakloss;
delete $paref->{peak};
delete $paref->{cloudcover};
delete $paref->{temp};
$peak *= 1000; # kWp in Wp umrechnen
my $ta = $stch->{"$st"}{tilt}; # Neigungswinkel Solarmodule
my $moddir = $stch->{"$st"}{dir}; # Ausrichtung der Solarmodule
my $af = $hff{$ta}{$moddir} / 100; # Flächenfaktor: http://www.ing-büro-junge.de/html/photovoltaik.html
my $pv = sprintf "%.1f", ($rad * $af * $kJtokWh * $peak * $prdef * $ccf * $rcf);
$lh = { # Log-Hash zur Ausgabe
"moduleDirection" => $moddir,
"modulePeakString" => $peak." W",
"moduleTiltAngle" => $ta,
"Area factor" => $af,
"Cloudcover" => $cloudcover,
"CloudRange" => $range,
"CloudFactorDamping" => $clouddamp." %",
"Cloudfactor" => $ccf,
"Rainprob" => $rainprob,
"Rainfactor" => $rcf,
"RainFactorDamping" => $raindamp." %",
"Radiation" => $rad,
"Factor kJ to kWh" => $kJtokWh,
"PV generation forecast (raw)" => $pv." Wh"
"moduleDirection" => $moddir,
"modulePeakString" => $peak." W",
"moduleTiltAngle" => $ta,
"Forecasted temperature" => $temp." °C",
"Module Temp (calculated)" => $modtemp." °C",
"Loss String Peak Power by Temp" => $peakloss." kWP",
"Area factor" => $af,
"Cloudcover" => $cloudcover,
"CloudRange" => $range,
"CloudFactorDamping" => $clouddamp." %",
"Cloudfactor" => $ccf,
"Rainprob" => $rainprob,
"Rainfactor" => $rcf,
"RainFactorDamping" => $raindamp." %",
"Radiation" => $rad,
"Factor kJ to kWh" => $kJtokWh,
"PV generation forecast (raw)" => $pv." Wh"
};
$sq = q{};
@ -6445,6 +6471,40 @@ sub calcPVforecast {
return $pvsum;
}
###################################################################
# Zellen Leistungskorrektur Einfluss durch Wärmekoeffizienten
# berechnen
#
# Die Nominalleistung der Module wird bei 25 Grad
# Umgebungstemperatur und bei 1.000 Watt Sonneneinstrahlung
# gemessen.
# Steigt die Temperatur um 1 Grad Celsius sinkt die Modulleistung
# typisch um 0,4 Prozent. Solartellen können im Sommer 70°C heiß
# werden.
#
# Das würde für eine 10 kWp Photovoltaikanlage folgenden
# Leistungsverlust bedeuten:
#
# Leistungsverlust = -0,4%/K * 45K * 10 kWp = 1,8 kWp
#
# https://www.enerix.de/photovoltaiklexikon/temperaturkoeffizient/
#
###################################################################
sub calcPeaklossByTemp {
my $paref = shift;
my $hash = $paref->{hash};
my $name = $paref->{name};
my $peak = $paref->{peak} // return (0,0);
my $cloudcover = $paref->{cloudcover} // return (0,0); # vorhergesagte Wolkendecke Stunde X
my $temp = $paref->{temp} // return (0,0); # vorhergesagte Temperatur Stunde X
my $modtemp = $temp + ($tempmodinc * (1 - ($cloudcover/100))); # kalkulierte Modultemperatur
my $peakloss = sprintf "%.2f", $tempcoeffdef * ($temp - $tempbasedef) * $peak / 100;
return ($peakloss, $modtemp);
}
################################################################
# 70% Regel kalkulieren
################################################################
@ -6678,7 +6738,8 @@ return;
sub calcRange {
my $range = shift;
$range = sprintf("%.0f", $range/10);
#$range = sprintf "%.0f", $range/10;
$range = sprintf "%.0f", $range;
return $range;
}
@ -7032,7 +7093,7 @@ sub listDataPool {
my $cret;
for my $ckey (sort keys %{$h->{$idx}}) {
if(ref $h->{$idx}{$ckey} eq "HASH") {
my $hk;
my $hk = qq{};
for my $f (sort {$a<=>$b} keys %{$h->{$idx}{$ckey}}) {
$hk .= " " if($hk);
$hk .= "$f=".$h->{$idx}{$ckey}{$f};
@ -7069,22 +7130,26 @@ sub listDataPool {
my $batin = CircularVal ($hash, $idx, "batin", "-");
my $batout = CircularVal ($hash, $idx, "batout", "-");
my $pvcf;
my $pvcf = qq{};
if(ref $pvcorrf eq "HASH") {
for my $f (sort {$a<=>$b} keys %{$h->{$idx}{pvcorrf}}) {
$pvcf .= " " if($pvcf);
$pvcf .= "$f=".$h->{$idx}{pvcorrf}{$f};
my $ct = ($pvcf =~ tr/=// // 0) / 10;
$pvcf .= "\n " if($ct =~ /^([1-9])?$/);
}
}
else {
$pvcf = $pvcorrf;
}
my $cfq;
my $cfq = qq{};
if(ref $quality eq "HASH") {
for my $q (sort {$a<=>$b} keys %{$h->{$idx}{quality}}) {
$cfq .= " " if($cfq);
$cfq .= "$q=".$h->{$idx}{quality}{$q};
$cfq .= " " if($cfq);
$cfq .= "$q=".$h->{$idx}{quality}{$q};
my $ct1 = ($cfq =~ tr/=// // 0) / 10;
$cfq .= "\n " if($ct1 =~ /^([1-9])?$/);
}
}
else {
@ -8648,8 +8713,9 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
<a id="SolarForecast-attr-cloudFactorDamping"></a>
<li><b>cloudFactorDamping </b><br>
Prozentuale Berücksichtigung (Dämpfung) des Bewölkungprognosefaktors bei der solaren Vorhersage. <br>
Größere Werte vermindern, kleinere Werte erhöhen tendenziell den prognostizierten PV Ertrag.<br>
Prozentuale Mehrgewichtung der Berücksichtigung des Bewölkungsfaktors bei der solaren Vorhersage. <br>
Größere Werte vermindern, kleinere Werte erhöhen tendenziell den prognostizierten PV Ertrag (Dämpfung der PV
Prognose durch den Bewölkungsfaktor).<br>
(default: 35)
</li>
<br>
@ -9046,8 +9112,9 @@ Ein/Ausschaltzeiten sowie deren Ausführung vom SolarForecast Modul übernehmen
<a id="SolarForecast-attr-rainFactorDamping"></a>
<li><b>rainFactorDamping </b><br>
Prozentuale Berücksichtigung (Dämpfung) des Regenprognosefaktors bei der solaren Vorhersage. <br>
Größere Werte vermindern, kleinere Werte erhöhen tendenziell den prognostizierten PV Ertrag.<br>
Prozentuale Mehrgewichtung der Berücksichtigung des Regenprognosefaktors bei der solaren Vorhersage. <br>
Größere Werte vermindern, kleinere Werte erhöhen tendenziell den prognostizierten PV Ertrag (Dämpfung der PV
Prognose durch den Regenfaktor).<br>
(default: 10)
</li>
<br>