diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm
index 3abb1baf4..93a5e8523 100644
--- a/fhem/contrib/DS_Starter/76_SolarForecast.pm
+++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm
@@ -1,5 +1,5 @@
########################################################################################################################
-# $Id: 76_SolarForecast.pm 21735 2023-05-28 23:53:24Z DS_Starter $
+# $Id: 76_SolarForecast.pm 21735 2023-06-01 23:53:24Z DS_Starter $
#########################################################################################################################
# 76_SolarForecast.pm
#
@@ -136,6 +136,7 @@ BEGIN {
# Versions History intern
my %vNotesIntern = (
+ "0.80.1" => "31.05.2023 adapt _calcCAQfromAPIPercentil to calculate corrfactor like _calcCAQfromDWDcloudcover ",
"0.80.0" => "28.05.2023 Support for Forecast.Solar-API (https://doc.forecast.solar/api), rename Getter solCastData to solApiData ".
"rename ctrlDebug keys: solcastProcess -> apiProcess, solcastAPIcall -> apiCall ".
"calculate cloudiness correction factors proactively and store it in circular hash ".
@@ -502,7 +503,7 @@ my %hget = ( # Ha
pvCircular => { fn => \&_getlistPVCircular, needcred => 0 },
forecastQualities => { fn => \&_getForecastQualities, needcred => 0 },
nextHours => { fn => \&_getlistNextHours, needcred => 0 },
- roofTopData => { fn => \&_getRoofTopData, needcred => 0 },
+ rooftopData => { fn => \&_getRoofTopData, needcred => 0 },
solApiData => { fn => \&_getlistSolCastData, needcred => 0 },
);
@@ -1255,15 +1256,15 @@ sub _setcurrentRadiationDev { ## no critic "not used"
my $dir = ReadingsVal ($name, 'moduleDirection', ''); # Modul Ausrichtung für jeden Stringbezeichner
return qq{Please complete command "set $name moduleDirection".} if(!$dir);
- }
-
- my $type = $hash->{TYPE};
- $data{$type}{$name}{current}{allStringsFullfilled} = 0; # Stringkonfiguration neu prüfen lassen
+ }
readingsSingleUpdate ($hash, "currentRadiationDev", $prop, 1);
createAssociatedWith ($hash);
writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben
setModel ($hash); # Model setzen
+
+ my $type = $hash->{TYPE};
+ $data{$type}{$name}{current}{allStringsFullfilled} = 0; # Stringkonfiguration neu prüfen lassen
return;
}
@@ -2062,7 +2063,7 @@ sub Get {
"nextHours:noArg ".
"pvCircular:noArg ".
"pvHistory:noArg ".
- "roofTopData:noArg ".
+ "rooftopData:noArg ".
"solApiData:noArg ".
"valCurrent:noArg "
;
@@ -2084,7 +2085,7 @@ sub Get {
return qq{Credentials of $name are not set."};
}
- $params->{force} = 1 if($opt eq 'roofTopData'); # forcierter (manueller) Abruf SolCast API
+ $params->{force} = 1 if($opt eq 'rooftopData'); # forcierter (manueller) Abruf SolCast API
$ret = &{$hget{$opt}{fn}} ($params);
return $ret;
@@ -2609,20 +2610,6 @@ sub __getForecastSolarData {
}
}
- my $msg;
- if($ctzAbsent) {
- $msg = qq{The library FHEM::Utility::CTZ is missing. Please update FHEM completely.};
- Log3 ($name, 2, "$name - ERROR - $msg");
- return $msg;
- }
-
- my $rmf = reqModFail();
- if($rmf) {
- $msg = "You have to install the required perl module: ".$rmf;
- Log3 ($name, 2, "$name - ERROR - $msg");
- return $msg;
- }
-
$paref->{allstrings} = ReadingsVal($name, 'inverterStrings', '');
$paref->{lang} = $lang;
@@ -4064,9 +4051,7 @@ sub _transferDWDRadiationValues {
my $err = checkdwdattr ($name,$raname,\@draattrmust);
$paref->{state} = $err if($err);
- if($debug =~ /radiationProcess/x) {
- Log3 ($name, 1, qq{$name DEBUG> collect Radiation data - device: $raname =>});
- }
+ debugLog ($paref, "radiationProcess", "collect Radiation data - device: $raname =>");
for my $num (0..47) {
my ($fd,$fh) = _calcDayHourMove ($chour, $num);
@@ -4086,9 +4071,7 @@ sub _transferDWDRadiationValues {
my ($hod) = $wantdt =~ /\s(\d{2}):/xs;
$hod = sprintf "%02d", int ($hod)+1; # Stunde des Tages
- if($debug =~ /radiationProcess/x) {
- Log3 ($name, 1, qq{$name DEBUG> got from device - starttime: $wantdt, reading: fc${fd}_${fh2}_Rad1h, value: $rad});
- }
+ debugLog ($paref, "radiationProcess", "got from device - starttime: $wantdt, reading: fc${fd}_${fh2}_Rad1h, value: $rad");
my $params = {
hash => $hash,
@@ -4112,9 +4095,7 @@ sub _transferDWDRadiationValues {
$data{$type}{$name}{nexthours}{$time_str}{today} = $fd == 0 ? 1 : 0;
$data{$type}{$name}{nexthours}{$time_str}{Rad1h} = $rad; # nur Info: original Vorhersage Strahlungsdaten
- if($debug =~ /radiationProcess/x) {
- Log3 ($name, 1, qq{$name DEBUG> wrote to nextHours Hash - pvfc: $est, hod: $hod, Rad1h: $rad});
- }
+ debugLog ($paref, "radiationProcess", "wrote to nextHours Hash - pvfc: $est, hod: $hod, Rad1h: $rad");
if($num < 23 && $fh < 24) { # Ringspeicher PV forecast Forum: https://forum.fhem.de/index.php/topic,117864.msg1133350.html#msg1133350
$data{$type}{$name}{circular}{sprintf("%02d",$fh1)}{pvfc} = $est;
@@ -4200,7 +4181,6 @@ sub __calcDWDEstimates {
my $temp = NexthoursVal ($hash, "NextHour".sprintf("%02d",$num), "temp", $tempbasedef); # vorhergesagte Temperatur Stunde X
- my $debug = $paref->{debug};
my $range = calcRange ($cloudcover); # Range errechnen
$paref->{range} = $range;
my ($hcfound, $hc, $hq) = ___readCorrfAndQuality ($paref); # liest den anzuwendenden Korrekturfaktor
@@ -4248,9 +4228,7 @@ sub __calcDWDEstimates {
$sq .= $idx." => ".$lh->{$idx}."\n";
}
- if($debug =~ /radiationProcess/x) {
- Log3 ($name, 1, "$name DEBUG> PV forecast calc (raw) for $reld Hour ".sprintf("%02d",$hod)." string $st ->\n$sq");
- }
+ debugLog ($paref, "radiationProcess", "PV forecast calc (raw) for $reld Hour ".sprintf("%02d",$hod)." string $st ->\n$sq");
}
$pvsum += $pv;
@@ -4266,10 +4244,8 @@ sub __calcDWDEstimates {
if ($invcapacity && $pvsum > $invcapacity) {
$pvsum = $invcapacity; # PV Vorhersage auf WR Kapazität begrenzen
-
- if($debug =~ /radiationProcess/x) {
- Log3 ($name, 1, "$name DEBUG> PV forecast limited to $pvsum Watt due to inverter capacity");
- }
+
+ debugLog ($paref, "radiationProcess", "PV forecast limited to $pvsum Watt due to inverter capacity");
}
my $logao = qq{};
@@ -4300,9 +4276,7 @@ sub __calcDWDEstimates {
$sq .= $idx." => ".$lh->{$idx}."\n";
}
- if($debug =~ /radiationProcess/x) {
- Log3 ($name, 1, "$name DEBUG> PV forecast calc for $reld Hour ".sprintf("%02d",$hod)." summary: \n$sq");
- }
+ debugLog ($paref, "radiationProcess", "PV forecast calc for $reld Hour ".sprintf("%02d",$hod)." summary: \n$sq");
}
return $pvsum;
@@ -4460,7 +4434,6 @@ sub __calcAPIEstimates {
my $ccf = 1 - ((($cloudcover - $cloud_base)/100) * $clouddamp/100); # Cloud Correction Faktor mit Steilheit und Fußpunkt
my $temp = NexthoursVal ($hash, "NextHour".sprintf("%02d",$num), "temp", $tempbasedef); # vorhergesagte Temperatur Stunde X
- my $debug = $paref->{debug};
my ($hcfound, $perc, $hq) = ___readPercAndQuality ($paref); # liest den anzuwendenden Korrekturfaktor
@@ -4488,10 +4461,7 @@ sub __calcAPIEstimates {
$sq .= $idx." => ".$lh->{$idx}."\n";
}
- if($debug =~ /radiationProcess/x) {
- Log3 ($name, 1, "$name DEBUG> PV estimate for $reld Hour ".sprintf ("%02d", $hod)." string $string ->\n$sq");
- }
-
+ debugLog ($paref, "radiationProcess", "PV estimate for $reld Hour ".sprintf ("%02d", $hod)." string $string ->\n$sq");
}
$pvsum += $pv;
@@ -4507,9 +4477,7 @@ sub __calcAPIEstimates {
if ($invcapacity && $pvsum > $invcapacity) {
$pvsum = $invcapacity; # PV Vorhersage auf WR Kapazität begrenzen
- if($debug =~ /radiationProcess/x) {
- Log3 ($name, 1, "$name DEBUG> PV forecast limited to $pvsum Watt due to inverter capacity");
- }
+ debugLog ($paref, "radiationProcess", "PV forecast limited to $pvsum Watt due to inverter capacity");
}
my $logao = qq{};
@@ -4538,9 +4506,7 @@ sub __calcAPIEstimates {
$sq .= $idx." => ".$lh->{$idx}."\n";
}
- if($debug =~ /radiationProcess/x) {
- Log3 ($name, 1, "$name DEBUG> PV estimate for $reld Hour ".sprintf ("%02d", $hod)." summary: \n$sq");
- }
+ debugLog ($paref, "radiationProcess", "PV estimate for $reld Hour ".sprintf ("%02d", $hod)." summary: \n$sq");
}
return $pvsum;
@@ -4718,11 +4684,8 @@ sub _transferInverterValues {
my $etuf = $etunit =~ /^kWh$/xi ? 1000 : 1;
my $etotal = ReadingsNum ($indev, $edread, 0) * $etuf; # Erzeugung total (Wh)
- my $debug = $paref->{debug};
- if($debug =~ /collectData/x) {
- Log3 ($name, 1, "$name DEBUG> collect Inverter data - device: $indev =>");
- Log3 ($name, 1, "$name DEBUG> pv: $pv W, etotal: $etotal Wh");
- }
+ debugLog ($paref, "collectData", "collect Inverter data - device: $indev =>");
+ debugLog ($paref, "collectData", "pv: $pv W, etotal: $etotal Wh");
my $nhour = $chour+1;
@@ -4780,11 +4743,8 @@ sub _transferWeatherValues {
$paref->{state} = $err if($err);
my $type = $paref->{type};
- my $debug = $paref->{debug};
- if($debug =~ /collectData/x) {
- Log3 ($name, 1, "$name DEBUG> collect Weather data - device: $fcname =>");
- }
+ debugLog ($paref, "collectData", "collect Weather data - device: $fcname =>");
my ($time_str);
@@ -4799,9 +4759,7 @@ sub _transferWeatherValues {
$data{$type}{$name}{current}{sunsetToday} = $date.' '.$fc0_SunSet.':00';
$data{$type}{$name}{current}{sunsetTodayTs} = timestringToTimestamp ($date.' '.$fc0_SunSet.':00');
- if($debug =~ /collectData/x) {
- Log3 ($name, 1, "$name DEBUG> sunrise/sunset today: $fc0_SunRise / $fc0_SunSet, sunrise/sunset tomorrow: $fc1_SunRise / $fc1_SunSet");
- }
+ debugLog ($paref, "collectData", "sunrise/sunset today: $fc0_SunRise / $fc0_SunSet, sunrise/sunset tomorrow: $fc1_SunRise / $fc1_SunSet");
push @$daref, "Today_SunRise<>". $fc0_SunRise;
push @$daref, "Today_SunSet<>". $fc0_SunSet;
@@ -4835,9 +4793,7 @@ sub _transferWeatherValues {
my $txt = ReadingsVal($fcname, "fc${fd}_${fh2}_wwd", '');
- if($debug =~ /collectData/x) {
- Log3 ($name, 1, "$name DEBUG> wid: fc${fd}_${fh1}_ww, val: $wid, txt: $txt, cc: $neff, rp: $r101, temp: $temp");
- }
+ debugLog ($paref, "collectData", "wid: fc${fd}_${fh1}_ww, val: $wid, txt: $txt, cc: $neff, rp: $r101, temp: $temp");
$time_str = "NextHour".sprintf "%02d", $num;
$data{$type}{$name}{nexthours}{$time_str}{weatherid} = $wid;
@@ -4955,11 +4911,8 @@ sub _transferMeterValues {
$data{$type}{$name}{circular}{99}{gridcontotal} = $gctotal; # Total Netzbezug speichern
$data{$type}{$name}{circular}{99}{feedintotal} = $fitotal; # Total Feedin speichern
- my $debug = $paref->{debug};
- if($debug =~ /collectData/x) {
- Log3 ($name, 1, "$name DEBUG> collect Meter data - device: $medev =>");
- Log3 ($name, 1, "$name DEBUG> gcon: $gco W, gfeedin: $gfin W, contotal: $gctotal Wh, feedtotal: $fitotal Wh");
- }
+ debugLog ($paref, "collectData", "collect Meter data - device: $medev =>");
+ debugLog ($paref, "collectData", "gcon: $gco W, gfeedin: $gfin W, contotal: $gctotal Wh, feedtotal: $fitotal Wh");
my $gcdaypast = 0;
my $gfdaypast = 0;
@@ -5430,10 +5383,8 @@ sub __planSwitchTimes {
return;
}
- if($debug =~ /consumerPlanning/x) {
- Log3 ($name, 1, qq{$name DEBUG> Planning consumer "$c" - name: }.ConsumerVal ($hash, $c, 'name', '').
- qq{ alias: }.ConsumerVal ($hash, $c, 'alias', ''));
- }
+ debugLog ($paref, "consumerPlanning", qq{Planning consumer "$c" - name: }.ConsumerVal ($hash, $c, 'name', '').
+ qq{ alias: }.ConsumerVal ($hash, $c, 'alias', ''));
my $type = $paref->{type};
my $lang = $paref->{lang};
@@ -5441,9 +5392,7 @@ sub __planSwitchTimes {
my $maxkey = (scalar keys %{$data{$type}{$name}{nexthours}}) - 1;
my $cicfip = AttrVal ($name, 'affectConsForecastInPlanning', 0); # soll Consumption Vorhersage in die Überschußermittlung eingehen ?
- if($debug =~ /consumerPlanning/x) {
- Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - Consider consumption forecast in consumer planning: }.($cicfip ? 'yes' : 'no'));
- }
+ debugLog ($paref, "consumerPlanning", qq{consumer "$c" - Consider consumption forecast in consumer planning: }.($cicfip ? 'yes' : 'no'));
my %max;
my %mtimes;
@@ -5490,17 +5439,13 @@ sub __planSwitchTimes {
return;
}
- if($debug =~ /consumerPlanning/x) {
- Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - epiece1: $epiece1});
- }
+ debugLog ($paref, "consumerPlanning", qq{consumer "$c" - epiece1: $epiece1});
my $mode = ConsumerVal ($hash, $c, "mode", "can");
my $calias = ConsumerVal ($hash, $c, "alias", "");
my $mintime = ConsumerVal ($hash, $c, "mintime", $defmintime); # Einplanungsdauer
- if($debug =~ /consumerPlanning/x) {
- Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - mode: $mode, mintime: $mintime, relevant method: surplus});
- }
+ debugLog ($paref, "consumerPlanning", qq{$name DEBUG> consumer "$c" - mode: $mode, mintime: $mintime, relevant method: surplus});
if (isSunPath ($hash, $c)) { # SunPath ist in mintime gesetzt
my ($riseshift, $setshift) = sunShift ($hash, $c);
@@ -5761,7 +5706,6 @@ sub ___switchonTimelimits {
my $hash = $paref->{hash};
my $name = $paref->{name};
my $c = $paref->{consumer};
- my $debug = $paref->{debug};
my $date = $paref->{date};
my $starttime = $paref->{starttime};
my $lang = $paref->{lang};
@@ -5771,9 +5715,7 @@ sub ___switchonTimelimits {
my $startts = CurrentVal ($hash, 'sunriseTodayTs', 0) + $riseshift;
$starttime = (timestampToTimestring ($startts, $lang))[3];
- if($debug =~ /consumerPlanning/x) {
- Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - starttime is set to >$starttime< due to >SunPath< is used});
- }
+ debugLog ($paref, "consumerPlanning", qq{consumer "$c" - starttime is set to >$starttime< due to >SunPath< is used});
}
my $origtime = $starttime;
@@ -5955,9 +5897,7 @@ sub ___switchConsumerOn {
my $mode = ConsumerVal ($hash, $c, "mode", $defcmode); # Consumer Planungsmode
my $enable = ___enableSwitchByBatPrioCharge ($paref); # Vorrangladung Batterie ?
- if($debug =~ /consumerSwitching/x) {
- Log3 ($name, 1, qq{$name DEBUG> Consumer switch enabled by battery: $enable});
- }
+ debugLog ($paref, "consumerSwitching", qq{$name DEBUG> Consumer switch enabled by battery: $enable});
if ($mode eq "can" && !$enable) { # Batterieladung - keine Verbraucher "Einschalten" Freigabe
$paref->{ps} = "priority charging battery";
@@ -6018,7 +5958,6 @@ sub ___switchConsumerOff {
my $c = $paref->{consumer};
my $t = $paref->{t}; # aktueller Unixtimestamp
my $state = $paref->{state};
- my $debug = $paref->{debug};
my $pstate = ConsumerVal ($hash, $c, "planstate", "");
my $stopts = ConsumerVal ($hash, $c, "planswitchoff", undef); # geplante Unix Stopzeit
@@ -6033,12 +5972,9 @@ sub ___switchConsumerOff {
my $caution;
Log3 ($name, 1, "$name - $err") if($err);
-
- if($debug =~ /consumerSwitching/x) { # nur für Debugging
- Log3 ($name, 1, qq{$name DEBUG> consumer "$c" - current Context is switching "off" => }.
- qq{swoffcond: $swoffcond, off-command: $offcom }
- );
- }
+
+ debugLog ($paref, "consumerSwitching", qq{consumer "$c" - current Context is switching "off" => }.
+ qq{swoffcond: $swoffcond, off-command: $offcom});
if(($swoffcond || ($stopts && $t >= $stopts)) &&
($auto && $offcom && simplifyCstate($pstate) =~ /started|starting|stopping|interrupt|continu/xs)) {
@@ -6419,7 +6355,6 @@ sub _estConsumptionForecast {
return if(!$medev || !$defs{$medev});
my $type = $paref->{type};
- my $debug = $paref->{debug};
my $acref = $data{$type}{$name}{consumers};
## Verbrauchsvorhersage für den nächsten Tag
@@ -6461,9 +6396,7 @@ sub _estConsumptionForecast {
my $tomavg = int ($totcon / $dnum);
$data{$type}{$name}{current}{tomorrowconsumption} = $tomavg; # prognostizierter Durchschnittsverbrauch aller (gleicher) Wochentage
- if($debug =~ /consumption/x) {
- Log3 ($name, 1, "$name DEBUG> estimated Consumption for tomorrow: $tomavg, days for avg: $dnum, hist. consumption registered consumers: ".sprintf "%.2f", $consumerco);
- }
+ debugLog ($paref, "consumption", "estimated Consumption for tomorrow: $tomavg, days for avg: $dnum, hist. consumption registered consumers: ".sprintf "%.2f", $consumerco);
}
else {
my $lang = $paref->{lang};
@@ -6542,9 +6475,7 @@ sub _estConsumptionForecast {
delete $paref->{histname};
}
- if($debug =~ /consumption/x) {
- Log3 ($name, 1, "$name DEBUG> estimated Consumption for $nhday -> starttime: $nhtime, con: $conavg, days for avg: $dnum, hist. consumption registered consumers: ".sprintf "%.2f", $consumerco);
- }
+ debugLog ($paref, "consumption", "estimated Consumption for $nhday -> starttime: $nhtime, con: $conavg, days for avg: $dnum, hist. consumption registered consumers: ".sprintf "%.2f", $consumerco);
}
}
@@ -8593,8 +8524,7 @@ sub __weatherOnBeam {
return $ret if(!$weather);
- my $m = $paref->{modulo} % 2;
- my $debug = $paref->{debug};
+ my $m = $paref->{modulo} % 2;
$ret .= "
| "; # freier Platz am Anfang
@@ -8623,9 +8553,7 @@ sub __weatherOnBeam {
$title .= ': '.$wcc;
if($icon_name eq 'unknown') {
- if($debug =~ /graphic/x) {
- Log3 ($name, 1, "$name DEBUG> unknown weather id: ".$hfcg->{$i}{weather}.", please inform the maintainer");
- }
+ debugLog ($paref, "graphic", "unknown weather id: ".$hfcg->{$i}{weather}.", please inform the maintainer");
}
$icon_name .= $hfcg->{$i}{weather} < 100 ? '@'.$colorw : '@'.$colorwn;
@@ -8634,9 +8562,7 @@ sub __weatherOnBeam {
if ($val eq $icon_name) { # passendes Icon beim User nicht vorhanden ! ( attr web iconPath falsch/prüfen/update ? )
$val = '???';
- if($debug =~ /graphic/x) { # nur für Debugging
- Log3 ($name, 1, qq{$name DEBUG> - the icon "$weather_ids{$hfcg->{$i}{weather}}{icon}" not found. Please check attribute "iconPath" of your FHEMWEB instance and/or update your FHEM software});
- }
+ debugLog ($paref, "graphic", qq{the icon "$weather_ids{$hfcg->{$i}{weather}}{icon}" not found. Please check attribute "iconPath" of your FHEMWEB instance and/or update your FHEM software});
}
$ret .= "$val | ";
@@ -9236,7 +9162,7 @@ sub _calcCAQfromDWDcloudcover {
my $daref = $paref->{daref};
my $debug = $paref->{debug};
- my $maxvar = AttrVal($name, 'affectMaxDayVariance', $defmaxvar); # max. Korrekturvarianz
+ my $maxvar = AttrVal ($name, 'affectMaxDayVariance', $defmaxvar); # max. Korrekturvarianz
for my $h (1..23) {
next if(!$chour || $h > $chour);
@@ -9244,10 +9170,9 @@ sub _calcCAQfromDWDcloudcover {
my $cccalc = ReadingsVal ($name, ".pvCorrectionFactor_".sprintf("%02d",$h)."_cloudcover", "");
if ($cccalc eq "done") {
- if($debug =~ /pvCorrection/x && isDWDUsed ($hash)) {
- Log3 ($name, 1, "$name DEBUG> cloudcover correction factor Hour: ".sprintf("%02d",$h)." already calculated");
- }
-
+ #if($debug =~ /pvCorrection/x && isDWDUsed ($hash)) {
+ # Log3 ($name, 1, "$name DEBUG> Cloudcover Corrf -> factor Hour: ".sprintf("%02d",$h)." already calculated");
+ #}
next;
}
@@ -9258,7 +9183,7 @@ sub _calcCAQfromDWDcloudcover {
next if(!$pvval);
$paref->{hour} = $h;
- my ($pvhis,$fchis,$dnum,$range) = __avgCloudcoverCorrFromHistory ($paref); # historische PV / Forecast Vergleichswerte ermitteln
+ my ($pvhis,$fchis,$dnum,$range) = __Pv_Fc_Ccover_Dnum_Hist ($paref); # historische PV / Forecast Vergleichswerte ermitteln
my ($oldfac, $oldq) = CircularAutokorrVal ($hash, sprintf("%02d",$h), $range, 0); # bisher definierter Korrekturfaktor/KF-Qualität der Stunde des Tages der entsprechenden Bewölkungsrange
$oldfac = 1 if(1 * $oldfac == 0);
@@ -9281,10 +9206,6 @@ sub _calcCAQfromDWDcloudcover {
$factor = sprintf "%.2f", ($pvval / $fcval);
$dnum = 1;
}
-
- if ($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> variance -> range: $range, hour: $h, days: $dnum, real: $pvval, forecast: $fcval, factor: $factor");
- }
if (abs($factor - $oldfac) > $maxvar) {
$factor = sprintf "%.2f", ($factor > $oldfac ? $oldfac + $maxvar : $oldfac - $maxvar);
@@ -9293,15 +9214,15 @@ sub _calcCAQfromDWDcloudcover {
else {
Log3 ($name, 3, "$name - new correction factor calculated: $factor (old: $oldfac) for hour: $h calculated") if($factor != $oldfac);
}
+
+ debugLog ($paref, "pvCorrection", "Cloudcover Corrf -> variance range: $range, hour: $h, days: $dnum, real: $pvval, forecast: $fcval, factor: $factor");
if (defined $range) {
my $type = $paref->{type};
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> write correction factor into circular Hash: Factor $factor, Hour $h, Range $range");
- }
+ debugLog ($paref, "pvCorrection", "Cloudcover Corrf -> write correction factor into circular Hash: Factor $factor, Hour $h, Range $range");
- $data{$type}{$name}{circular}{sprintf("%02d",$h)}{pvcorrf}{$range} = $factor; # Korrekturfaktor für Bewölkung Range 0..10 für die jeweilige Stunde als Datenquelle eintragen
+ $data{$type}{$name}{circular}{sprintf("%02d",$h)}{pvcorrf}{$range} = $factor; # Korrekturfaktor für Bewölkung der jeweiligen Stunde als Datenquelle eintragen
$data{$type}{$name}{circular}{sprintf("%02d",$h)}{quality}{$range} = $dnum; # Korrekturfaktor Qualität
push @$daref, ".pvCorrectionFactor_".sprintf("%02d",$h)."_cloudcover<>done";
@@ -9322,115 +9243,96 @@ return;
}
################################################################
-# Berechne Durchschnitte PV Vorhersage / PV Ertrag
-# aus Werten der PV History
+# ermittle PV Vorhersage / PV Ertrag aus PV History
+# unter Berücksichtigung der maximal zu nutzenden Tage
+# und der relevanten Bewölkung
################################################################
-sub __avgCloudcoverCorrFromHistory {
+sub __Pv_Fc_Ccover_Dnum_Hist {
my $paref = shift;
my $hash = $paref->{hash};
my $name = $paref->{name};
my $type = $paref->{type};
- my $hour = $paref->{hour}; # Stunde des Tages für die der Durchschnitt bestimmt werden soll
- my $day = $paref->{day}; # aktueller Tag
+ my $hour = $paref->{hour}; # Stunde des Tages für die der Durchschnitt bestimmt werden soll
+ my $day = $paref->{day}; # aktueller Tag
$hour = sprintf("%02d",$hour);
- my $debug = $paref->{debug};
my $pvhh = $data{$type}{$name}{pvhist};
- my ($usenhd, $calcd) = __useNumHistDays ($name); # ist Attr affectNumHistDays gesetzt ? und welcher Wert
+ my ($usenhd, $calcd) = __useNumHistDays ($name); # ist Attr affectNumHistDays gesetzt ? und welcher Wert
my @k = sort {$a<=>$b} keys %{$pvhh};
- my $ile = $#k; # Index letztes Arrayelement
- my ($idx) = grep {$k[$_] eq "$day"} (0..@k-1); # Index des aktuellen Tages
+ my $ile = $#k; # Index letztes Arrayelement
+ my ($idx) = grep {$k[$_] eq "$day"} (0..@k-1); # Index des aktuellen Tages
- if(defined $idx) {
- my $ei = $idx-1;
- $ei = $ei < 0 ? $ile : $ei;
- my @efa;
+ return if(!defined $idx);
- for my $e (0..$calcmaxd) {
- last if($e == $calcmaxd || $k[$ei] == $day);
- unshift @efa, $k[$ei];
- $ei--;
- }
+ my $ei = $idx-1;
+ $ei = $ei < 0 ? $ile : $ei;
+ my @efa;
- my $chwcc = HistoryVal ($hash, $day, $hour, "wcc", undef); # Wolkenbedeckung Heute & abgefragte Stunde
-
- if(!defined $chwcc) {
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> Day $day has no cloudiness value set for hour $hour, no past averages can be calculated");
- }
- return;
- }
-
- my $range = calcRange ($chwcc); # V 0.50.1
-
- if(scalar(@efa)) {
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> Raw Days ($calcmaxd) for average check: ".join " ",@efa);
- }
- }
- else { # vermeide Fehler: Illegal division by zero
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> Day $day has index $idx. Use only current day for average calc");
- }
- return (undef,undef,undef,$range);
- }
-
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> cloudiness range of day/hour $day/$hour is: $range");
- }
-
- my $dnum = 0;
- my ($pvrl,$pvfc) = (0,0);
-
- for my $dayfa (@efa) {
- my $histwcc = HistoryVal ($hash, $dayfa, $hour, "wcc", undef); # historische Wolkenbedeckung
-
- if(!defined $histwcc) {
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> Day $dayfa has no cloudiness value set for hour $hour, this history dataset is ignored.");
- }
- next;
- }
-
- $histwcc = calcRange ($histwcc); # V 0.50.1
-
- if($range == $histwcc) {
- $pvrl += HistoryVal ($hash, $dayfa, $hour, "pvrl", 0);
- $pvfc += HistoryVal ($hash, $dayfa, $hour, "pvfc", 0);
- $dnum++;
-
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> historical Day/hour $dayfa/$hour included - cloudiness range: $range");
- }
-
- last if( $dnum == $calcd);
- }
- else {
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> cloudiness range different: $range/$histwcc (current/historical) -> stored $dayfa/$hour (Day/hour) ignored.");
- }
- }
- }
-
- if(!$dnum) {
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> all cloudiness ranges were different/not set -> no historical averages calculated");
- }
- return (undef,undef,undef,$range);
- }
-
- my $pvhis = sprintf "%.2f", $pvrl;
- my $fchis = sprintf "%.2f", $pvfc;
-
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> Summary - cloudiness range: $range, days: $dnum, pvHist:$pvhis, fcHist:$fchis");
- }
- return ($pvhis,$fchis,$dnum,$range);
+ for my $e (0..$calcd) {
+ last if($e == $calcd || $k[$ei] == $day);
+ unshift @efa, $k[$ei];
+ $ei--;
}
-return;
+ my $chwcc = HistoryVal ($hash, $day, $hour, "wcc", undef); # Wolkenbedeckung Heute & abgefragte Stunde
+
+ if(!defined $chwcc) {
+ debugLog ($paref, 'pvCorrection', "Cloudcover Corrf -> Day $day has no cloudiness value set for hour $hour, no past averages can be calculated");
+ return;
+ }
+
+ my $range = calcRange ($chwcc); # V 0.50.1
+
+ if(scalar(@efa)) {
+ debugLog ($paref, 'pvCorrection', "Cloudcover Corrf -> Raw Days ($calcd) for average check: ".join " ",@efa);
+ }
+ else {
+ debugLog ($paref, 'pvCorrection', "Cloudcover Corrf -> Day $day has index $idx. Use only current day for average calc");
+ return (undef,undef,undef,$range);
+ }
+
+ debugLog ($paref, 'pvCorrection', "Cloudcover Corrf -> cloudiness range of day/hour $day/$hour is: $range");
+
+ my $dnum = 0;
+ my ($pvrl,$pvfc) = (0,0);
+
+ for my $dayfa (@efa) {
+ my $histwcc = HistoryVal ($hash, $dayfa, $hour, "wcc", undef); # historische Wolkenbedeckung
+
+ if(!defined $histwcc) {
+ debugLog ($paref, 'pvCorrection', "Cloudcover Corrf -> Day $dayfa has no cloudiness value set for hour $hour, this history dataset is ignored.");
+ next;
+ }
+
+ $histwcc = calcRange ($histwcc); # V 0.50.1
+
+ if($range == $histwcc) {
+ $pvrl += HistoryVal ($hash, $dayfa, $hour, "pvrl", 0);
+ $pvfc += HistoryVal ($hash, $dayfa, $hour, "pvfc", 0);
+ $dnum++;
+
+ debugLog ($paref, 'pvCorrection', "Cloudcover Corrf -> historical Day/hour $dayfa/$hour included - cloudiness range: $range");
+
+ last if( $dnum == $calcd);
+ }
+ else {
+ debugLog ($paref, 'pvCorrection', "Cloudcover Corrf -> cloudiness range different: $range/$histwcc (current/historical) -> ignore stored $dayfa/$hour (Day/hour)");
+ }
+ }
+
+ if(!$dnum) {
+ debugLog ($paref, 'pvCorrection', "Cloudcover Corrf -> all cloudiness ranges were different/not set -> no historical averages calculated");
+ return (undef,undef,undef,$range);
+ }
+
+ my $pvhis = sprintf "%.2f", $pvrl;
+ my $fchis = sprintf "%.2f", $pvfc;
+
+ debugLog ($paref, 'pvCorrection', "Cloudcover Corrf -> Summary - cloudiness range: $range, days: $dnum, pvHist:$pvhis, fcHist:$fchis");
+
+return ($pvhis,$fchis,$dnum,$range);
}
################################################################
@@ -9465,31 +9367,32 @@ sub _calcCAQfromAPIPercentil {
my $chour = $paref->{chour}; # aktuelle Stunde
my $date = $paref->{date};
my $daref = $paref->{daref};
- my $debug = $paref->{debug};
return if(isDWDUsed ($hash)); # wird DWD benutzt können Daten im solcastapi-Hash veraltet sein !
+ my $maxvar = AttrVal($name, 'affectMaxDayVariance', $defmaxvar); # max. Korrekturvarianz
+
for my $h (1..23) {
next if(!$chour || $h > $chour);
my $cdone = ReadingsVal ($name, ".pvCorrectionFactor_".sprintf("%02d",$h)."_apipercentil", "");
if($cdone eq "done") {
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV correction factor Hour: ".sprintf("%02d",$h)." already calculated");
- }
-
+ # debugLog ($paref, "pvCorrection", "Simple Corrf factor Hour: ".sprintf("%02d",$h)." already calculated");
next;
}
+
+ my $fcval = ReadingsNum ($name, "Today_Hour".sprintf("%02d",$h)."_PVforecast", 0);
+ next if(!$fcval);
my $pvval = ReadingsNum ($name, "Today_Hour".sprintf("%02d",$h)."_PVreal", 0);
next if(!$pvval);
- $paref->{hour} = $h;
- my ($dnum,$avgperc) = __avgAPIPercFromHistory ($paref); # historischen Percentilfaktor / Qualität ermitteln
+ $paref->{hour} = $h;
+ my ($pvhis,$fchis,$dnum) = __Pv_Fc_Dnum_Hist ($paref); # historischen Percentilfaktor / Qualität ermitteln
- my ($oldperc, $oldq) = CircularAutokorrVal ($hash, sprintf("%02d",$h), 'percentile', 1.0); # bisher definiertes Percentil/Qualität der Stunde des Tages der entsprechenden Bewölkungsrange
- $oldperc = 1.0 if(1 * $oldperc == 0 || $oldperc >= 10);
+ my ($oldfac, $oldq) = CircularAutokorrVal ($hash, sprintf("%02d",$h), 'percentile', 1.0); # bisher definiertes Percentil/Qualität der Stunde des Tages der entsprechenden Bewölkungsrange
+ $oldfac = 1.0 if(1 * $oldfac == 0 || $oldfac >= 10);
my @sts = split ",", ReadingsVal($name, 'inverterStrings', '');
my $tmstr = $date.' '.sprintf("%02d",$h-1).':00:00';
@@ -9501,15 +9404,13 @@ sub _calcCAQfromAPIPercentil {
}
if(!$est50) { # kein Standardpercentile vorhanden
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, qq{$name DEBUG> percentile -> hour: $h, the correction factor can't be calculated because of the default percentile has no value yet});
- }
+ debugLog ($paref, "pvCorrection", "Simple Corrf -> hour: $h, the correction factor can't be calculated because of the default percentile has no value yet");
next;
}
my $perc = sprintf "%.2f", ($pvval / $est50); # berechneter Faktor der Stunde -> speichern in pvHistory
- $paref->{pvcorrf} = $perc.'/1'; # Percentilfaktor in History speichern
+ $paref->{pvcorrf} = $perc.'/1'; # Korrekturfaktor / Qualität in History speichern
$paref->{nhour} = sprintf("%02d",$h);
$paref->{histname} = "pvcorrfactor";
@@ -9519,52 +9420,49 @@ sub _calcCAQfromAPIPercentil {
delete $paref->{nhour};
delete $paref->{pvcorrf};
- if ($debug =~ /pvCorrection/x) { # nur für Debugging
- Log3 ($name, 1, qq{$name DEBUG> PV estimates for hour of day "$h": $est50});
- Log3 ($name, 1, qq{$name DEBUG> correction factor -> number checked days: $dnum, pvreal: $pvval, correction factor: $perc});
- }
+ debugLog ($paref, 'pvCorrection', "Simple Corrf -> PV estimate for hour of day >$h<: $est50");
+ debugLog ($paref, 'pvCorrection', "Simple Corrf -> number checked days: $dnum, pvreal: $pvval, correction factor: $perc");
- my ($usenhd) = __useNumHistDays ($name); # ist Attr affectNumHistDays gesetzt ?
+ my $factor;
+ my ($usenhd) = __useNumHistDays ($name); # ist Attr affectNumHistDays gesetzt ?
- if ($dnum) { # Werte in History vorhanden -> haben Prio !
- $avgperc = $avgperc * $dnum;
+ if ($dnum) { # Werte in History vorhanden -> haben Prio !
$dnum++;
- $perc = sprintf "%.2f", (($avgperc + $perc) / $dnum);
-
- if ($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, qq{$name DEBUG> percentile -> old avg correction: }.($avgperc/($dnum-1)).qq{, new avg correction: }.$perc);
- }
+ $pvval = ($pvval + $pvhis) / $dnum; # Ertrag aktuelle Stunde berücksichtigen
+ $fcval = ($fcval + $fchis) / $dnum; # Vorhersage aktuelle Stunde berücksichtigen
+ $factor = sprintf "%.2f", ($pvval / $fcval); # Faktorberechnung: reale PV / Prognose
}
- elsif ($oldperc && !$usenhd) { # keine Werte in History vorhanden, aber in CircularVal && keine Beschränkung durch Attr affectNumHistDays
- $oldperc = $oldperc * $oldq;
- $dnum = $oldq + 1;
- $perc = sprintf "%.0f", (($oldperc + $perc) / $dnum);
-
- if ($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, qq{$name DEBUG> percentile -> old circular correction: }.($oldperc/$oldq).qq{, new correction: }.$perc);
- }
+ elsif ($oldfac && !$usenhd) { # keine Werte in History vorhanden, aber in CircularVal && keine Beschränkung durch Attr affectNumHistDays
+ $dnum = $oldq + 1;
+ $factor = sprintf "%.2f", ($pvval / $fcval);
+ $factor = sprintf "%.2f", ($factor + $oldfac) / 2;
}
- else { # ganz neuer Wert
- $dnum = 1;
-
- if ($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, qq{$name DEBUG> percentile -> new correction factor: }.$perc);
- }
+ else { # ganz neuer Wert
+ $dnum = 1;
+ $factor = sprintf "%.2f", ($pvval / $fcval);
+ $oldfac = '-';
}
-
- if($debug =~ /saveData2Cache/x) {
- Log3 ($name, 1, "$name DEBUG> write correction factor into circular Hash: $perc, Hour $h");
+
+ if (abs($factor - $oldfac) > $maxvar) {
+ $factor = sprintf "%.2f", ($factor > $oldfac ? $oldfac + $maxvar : $oldfac - $maxvar);
+ Log3 ($name, 3, "$name - new correction factor calculated (limited by affectMaxDayVariance): $factor (old: $oldfac) for hour: $h");
}
+ else {
+ Log3 ($name, 3, "$name - new correction factor calculated: $factor (old: $oldfac) for hour: $h calculated") if($factor != $oldfac);
+ }
+
+ debugLog ($paref, 'pvCorrection', "Simple Corrf -> old circular correction: $oldfac, new correction: $factor");
+ debugLog ($paref, 'saveData2Cache', "Simple Corrf -> write correction factor into circular Hash: $factor, Hour $h");
my $type = $paref->{type};
- $data{$type}{$name}{circular}{sprintf("%02d",$h)}{pvcorrf}{percentile} = $perc; # bestes Percentil für die jeweilige Stunde speichern
- $data{$type}{$name}{circular}{sprintf("%02d",$h)}{quality}{percentile} = $dnum; # Percentil Qualität
+ $data{$type}{$name}{circular}{sprintf("%02d",$h)}{pvcorrf}{percentile} = $factor; # Korrekturfaktor der jeweiligen Stunde als Datenquelle eintragen
+ $data{$type}{$name}{circular}{sprintf("%02d",$h)}{quality}{percentile} = $dnum; # Korrekturfaktor Qualität
push @$daref, ".pvCorrectionFactor_".sprintf("%02d",$h)."_apipercentil<>done";
if (useAutoCorrection ($name)) {
- push @$daref, "pvCorrectionFactor_".sprintf("%02d",$h). "<>".$perc." (automatic - old factor: $oldperc, average days: $dnum)";
+ push @$daref, "pvCorrectionFactor_".sprintf("%02d",$h). "<>".$factor." (automatic - old factor: $oldfac, average days: $dnum)";
push @$daref, "pvCorrectionFactor_".sprintf("%02d",$h). "_autocalc<>done";
}
}
@@ -9573,10 +9471,11 @@ return;
}
################################################################
-# Berechne den durchschnittlichen Korrekturfaktor
-# bei API Verwendung aus Werten der PV History
+# ermittle PV Vorhersage / PV Ertrag aus PV History
+# unter Berücksichtigung der maximal zu nutzenden Tage
+# OHNE Bewölkung
################################################################
-sub __avgAPIPercFromHistory {
+sub __Pv_Fc_Dnum_Hist {
my $paref = shift;
my $hash = $paref->{hash};
my $name = $paref->{name};
@@ -9585,7 +9484,6 @@ sub __avgAPIPercFromHistory {
my $day = $paref->{day}; # aktueller Tag
$hour = sprintf("%02d",$hour);
- my $debug = $paref->{debug};
my $pvhh = $data{$type}{$name}{pvhist};
my ($usenhd, $calcd) = __useNumHistDays ($name); # ist Attr affectNumHistDays gesetzt ? und welcher Wert
@@ -9594,66 +9492,49 @@ sub __avgAPIPercFromHistory {
my $ile = $#k; # Index letztes Arrayelement
my ($idx) = grep {$k[$_] eq "$day"} (0..@k-1); # Index des aktuellen Tages
- return 0 if(!defined $idx);
+ return if(!defined $idx);
my $ei = $idx-1;
$ei = $ei < 0 ? $ile : $ei;
+
my @efa;
- for my $e (0..$calcmaxd) {
- last if($e == $calcmaxd || $k[$ei] == $day);
+ for my $e (0..$calcd) { # old: $calcmaxd
+ last if($e == $calcd || $k[$ei] == $day); # old: $calcmaxd
unshift @efa, $k[$ei];
$ei--;
}
if(scalar(@efa)) {
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> Raw Days ($calcmaxd) for average check: ".join " ",@efa);
- }
+ debugLog ($paref, "pvCorrection", "Simple Corrf -> Raw Days ($calcd) for average check: ".join " ",@efa);
}
- else { # vermeide Fehler: Illegal division by zero
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> Day $day has index $idx. Use only current day for average calc");
- }
+ else {
+ debugLog ($paref, "pvCorrection", "Simple Corrf -> Day $day has index $idx. Use only current day for average calc");
return 0;
}
- my ($dnum, $percsum) = (0,0);
- my ($perc, $qual) = (1,0);
+ my $dnum = 0;
+ my ($pvrl,$pvfc) = (0,0);
for my $dayfa (@efa) {
- my $histval = HistoryVal ($hash, $dayfa, $hour, 'pvcorrf', undef); # historischen Percentilfaktor/Qualität
-
- next if(!defined $histval);
-
- ($perc, $qual) = split "/", $histval; # Percentilfaktor und Qualität splitten
-
- next if(!$perc || $qual eq 'm'); # manuell eingestellte Percentile überspringen
-
- $perc = 1 if(!$perc || $perc >= 10);
-
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> historical Day/hour $dayfa/$hour included - percentile factor: $perc");
- }
+ $pvrl += HistoryVal ($hash, $dayfa, $hour, "pvrl", 0);
+ $pvfc += HistoryVal ($hash, $dayfa, $hour, "pvfc", 0);
$dnum++;
- $percsum += $perc ;
+ debugLog ($paref, "pvCorrection", "Simple Corrf -> historical Day/hour $dayfa/$hour included -> PVreal: $pvrl (summary), PVforecast: $pvfc (summary)");
last if($dnum == $calcd);
}
if(!$dnum) {
- Log3 ($name, 5, "$name - PV History -> no historical percentile factor selected");
+ Log3 ($name, 5, "$name - PV History -> no historical PV data forecast and real found");
return 0;
}
- $perc = sprintf "%.2f", ($percsum/$dnum);
-
- if($debug =~ /pvCorrection/x) {
- Log3 ($name, 1, "$name DEBUG> PV History -> Summary - days: $dnum, average percentile factor: $perc");
- }
-
-return ($dnum,$perc);
+ my $pvhis = sprintf "%.2f", $pvrl;
+ my $fchis = sprintf "%.2f", $pvfc;
+
+return ($pvhis,$fchis,$dnum);
}
################################################################
@@ -9888,10 +9769,7 @@ sub setPVhistory {
$data{$type}{$name}{pvhist}{$day}{99}{temp} = q{};
}
- my $debug = $paref->{debug};
- if($debug =~ /saveData2Cache/x) {
- Log3 ($name, 1, "$name DEBUG> save PV History Day: $day, Hour: $nhour, Key: $histname, Value: $val");
- }
+ debugLog ($paref, 'saveData2Cache', "setPVhistory -> save PV History Day: $day, Hour: $nhour, Key: $histname, Value: $val");
return;
}
@@ -10767,6 +10645,24 @@ sub singleUpdateState {
return;
}
+################################################################
+# erstellt einen Debug-Eintrag im Log
+################################################################
+sub debugLog {
+ my $paref = shift;
+ my $dreg = shift; # Regex zum Vergleich
+ my $dmsg = shift; # auszugebender Meldungstext
+
+ my $name = $paref->{name};
+ my $debug = $paref->{debug};
+
+ if($debug =~ /$dreg/x) {
+ Log3 ($name, 1, "$name DEBUG> $dmsg");
+ }
+
+return;
+}
+
################################################################
# alle Readings eines Devices oder nur Reading-Regex
# löschen
@@ -12566,8 +12462,8 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
-
- - roofTopData
+
+ - rooftopData
(nur bei Verwendung Model SolCastAPI und ForecastSolarAPI)
Die erwarteten solaren Strahlungsdaten der definierten Strings werden von der gewählten API abgerufen.