mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-25 09:55:38 +00:00
76_Solarforcast: contrib 0.70.9
git-svn-id: https://svn.fhem.de/fhem/trunk@26578 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
ebfe4aa0a7
commit
13613d708c
@ -1,5 +1,5 @@
|
||||
########################################################################################################################
|
||||
# $Id: 76_SolarForecast.pm 21735 2022-10-23 23:53:24Z DS_Starter $
|
||||
# $Id: 76_SolarForecast.pm 21735 2022-10-24 23:53:24Z DS_Starter $
|
||||
#########################################################################################################################
|
||||
# 76_SolarForecast.pm
|
||||
#
|
||||
@ -129,7 +129,7 @@ BEGIN {
|
||||
|
||||
# Versions History intern
|
||||
my %vNotesIntern = (
|
||||
"0.70.9 "=> "23.10.2022 create additional percentile only for pvCorrectionFactor_Auto on, changed __solCast_ApiResponse ".
|
||||
"0.70.9 "=> "24.10.2022 create additional percentile only for pvCorrectionFactor_Auto on, changed __solCast_ApiResponse ".
|
||||
"changed _calcCAQwithSolCastPercentil ",
|
||||
"0.70.8 "=> "23.10.2022 change average calculation in _calcCAQwithSolCastPercentil, unuse Notify/createNotifyDev ".
|
||||
"extend Delete func, extend plantconfig check, revise commandref, change set reset pvCorrection ".
|
||||
@ -304,7 +304,78 @@ my %vNotesIntern = (
|
||||
"0.1.0" => "09.12.2020 initial Version "
|
||||
);
|
||||
|
||||
# Voreinstellungen
|
||||
## Konstanten
|
||||
###############
|
||||
my @chours = (5..21); # Stunden des Tages mit möglichen Korrekturwerten
|
||||
my $kJtokWh = 0.00027778; # Umrechnungsfaktor kJ in kWh
|
||||
my $defmaxvar = 0.5; # max. Varianz pro Tagesberechnung Autokorrekturfaktor
|
||||
my $definterval = 70; # Standard Abfrageintervall
|
||||
my $defslidenum = 3; # max. Anzahl der Arrayelemente in Schieberegistern
|
||||
|
||||
my $pvhcache = $attr{global}{modpath}."/FHEM/FhemUtils/PVH_SolarForecast_"; # Filename-Fragment für PV History (wird mit Devicename ergänzt)
|
||||
my $pvccache = $attr{global}{modpath}."/FHEM/FhemUtils/PVC_SolarForecast_"; # Filename-Fragment für PV Circular (wird mit Devicename ergänzt)
|
||||
my $plantcfg = $attr{global}{modpath}."/FHEM/FhemUtils/PVCfg_SolarForecast_"; # Filename-Fragment für PV Anlagenkonfiguration (wird mit Devicename ergänzt)
|
||||
my $csmcache = $attr{global}{modpath}."/FHEM/FhemUtils/PVCsm_SolarForecast_"; # Filename-Fragment für Consumer Status (wird mit Devicename ergänzt)
|
||||
my $scpicache = $attr{global}{modpath}."/FHEM/FhemUtils/ScApi_SolarForecast_"; # Filename-Fragment für Werte aus SolCast API (wird mit Devicename ergänzt)
|
||||
|
||||
my $calcmaxd = 30; # Anzahl Tage die zur Berechnung Vorhersagekorrektur verwendet werden
|
||||
my @dweattrmust = qw(TTT Neff R101 ww SunUp SunRise SunSet); # Werte die im Attr forecastProperties des Weather-DWD_Opendata Devices mindestens gesetzt sein müssen
|
||||
my @draattrmust = qw(Rad1h); # Werte die im Attr forecastProperties des Radiation-DWD_Opendata Devices mindestens gesetzt sein müssen
|
||||
my $whistrepeat = 900; # Wiederholungsintervall Cache File Daten schreiben
|
||||
|
||||
my $apirepetdef = 3600; # default Abrufintervall SolCast API
|
||||
my $apimaxreqs = 50; # max. täglich mögliche Requests SolCast API
|
||||
|
||||
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; # 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)
|
||||
my $epiecHCounts = 10; # Anzahl Werte für verbraucherspezifische Energiestück Ermittlung
|
||||
my @ctypes = qw(dishwasher dryer washingmachine heater charger other); # erlaubte Consumer Typen
|
||||
my $defmintime = 60; # default min. Einschalt- bzw. Zykluszeit in Minuten
|
||||
my $defctype = "other"; # default Verbrauchertyp
|
||||
my $defcmode = "can"; # default Planungsmode der Verbraucher
|
||||
|
||||
my $caicondef = 'clock@gold'; # default consumerAdviceIcon
|
||||
my $defflowGSize = 300; # default flowGraphicSize
|
||||
my $histhourdef = 2; # default Anzeige vorangegangene Stunden
|
||||
my $wthcolddef = 'C7C979'; # Wetter Icon Tag Default Farbe
|
||||
my $wthcolndef = 'C7C7C7'; # Wetter Icon Nacht Default Farbe
|
||||
my $b1coldef = 'FFAC63'; # Default Farbe Beam 1
|
||||
my $b1fontcoldef = '0D0D0D'; # Default Schriftfarbe Beam 1
|
||||
my $b2coldef = 'C4C4A7'; # Default Farbe Beam 2
|
||||
my $b2fontcoldef = '000000'; # Default Schriftfarbe Beam 2
|
||||
|
||||
my $defpopercent = 0.5; # Standard % aktuelle Leistung an nominaler Leistung gemäß Typenschild
|
||||
my $defhyst = 0; # default Hysterese
|
||||
|
||||
# Default CSS-Style
|
||||
my $cssdef = qq{.flowg.text { stroke: none; fill: gray; font-size: 32px;} \n}.
|
||||
qq{.flowg.sun_active { stroke: orange; fill: orange; } \n}.
|
||||
qq{.flowg.sun_inactive { stroke: gray; fill: gray; } \n}.
|
||||
qq{.flowg.bat25 { stroke: red; fill: red; } \n}.
|
||||
qq{.flowg.bat50 { stroke: yellow; fill: yellow; } \n}.
|
||||
qq{.flowg.bat75 { stroke: green; fill: green; } \n}.
|
||||
qq{.flowg.grid_color1 { fill: green; } \n}.
|
||||
qq{.flowg.grid_color2 { fill: red; } \n}.
|
||||
qq{.flowg.grid_color3 { fill: gray; } \n}.
|
||||
qq{.flowg.inactive_in { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } \n}.
|
||||
qq{.flowg.inactive_out { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } \n}.
|
||||
qq{.flowg.active_in { stroke: red; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}.
|
||||
qq{.flowg.active_out { stroke: yellow; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}.
|
||||
qq{.flowg.active_bat_in { stroke: yellow; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}.
|
||||
qq{.flowg.active_bat_out { stroke: green; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}
|
||||
;
|
||||
|
||||
# Steuerhashes
|
||||
###############
|
||||
|
||||
my %hset = ( # Hash der Set-Funktion
|
||||
consumerImmediatePlanning => { fn => \&_setconsumerImmediatePlanning },
|
||||
@ -617,74 +688,6 @@ my %weather_ids = (
|
||||
'100' => { s => '0', icon => 'weather_night', txtd => 'sternenklarer Himmel', txte => 'starry sky' },
|
||||
);
|
||||
|
||||
my @chours = (5..21); # Stunden des Tages mit möglichen Korrekturwerten
|
||||
my $kJtokWh = 0.00027778; # Umrechnungsfaktor kJ in kWh
|
||||
my $defmaxvar = 0.5; # max. Varianz pro Tagesberechnung Autokorrekturfaktor
|
||||
my $definterval = 70; # Standard Abfrageintervall
|
||||
my $defslidenum = 3; # max. Anzahl der Arrayelemente in Schieberegistern
|
||||
|
||||
my $pvhcache = $attr{global}{modpath}."/FHEM/FhemUtils/PVH_SolarForecast_"; # Filename-Fragment für PV History (wird mit Devicename ergänzt)
|
||||
my $pvccache = $attr{global}{modpath}."/FHEM/FhemUtils/PVC_SolarForecast_"; # Filename-Fragment für PV Circular (wird mit Devicename ergänzt)
|
||||
my $plantcfg = $attr{global}{modpath}."/FHEM/FhemUtils/PVCfg_SolarForecast_"; # Filename-Fragment für PV Anlagenkonfiguration (wird mit Devicename ergänzt)
|
||||
my $csmcache = $attr{global}{modpath}."/FHEM/FhemUtils/PVCsm_SolarForecast_"; # Filename-Fragment für Consumer Status (wird mit Devicename ergänzt)
|
||||
my $scpicache = $attr{global}{modpath}."/FHEM/FhemUtils/ScApi_SolarForecast_"; # Filename-Fragment für Werte aus SolCast API (wird mit Devicename ergänzt)
|
||||
|
||||
my $calcmaxd = 30; # Anzahl Tage die zur Berechnung Vorhersagekorrektur verwendet werden
|
||||
my @dweattrmust = qw(TTT Neff R101 ww SunUp SunRise SunSet); # Werte die im Attr forecastProperties des Weather-DWD_Opendata Devices mindestens gesetzt sein müssen
|
||||
my @draattrmust = qw(Rad1h); # Werte die im Attr forecastProperties des Radiation-DWD_Opendata Devices mindestens gesetzt sein müssen
|
||||
my $whistrepeat = 900; # Wiederholungsintervall Cache File Daten schreiben
|
||||
|
||||
my $apirepetdef = 3600; # default Abrufintervall SolCast API
|
||||
my $apimaxreqs = 50; # max. täglich mögliche Requests SolCast API
|
||||
|
||||
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; # 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)
|
||||
my $epiecHCounts = 10; # Anzahl Werte für verbraucherspezifische Energiestück Ermittlung
|
||||
my @ctypes = qw(dishwasher dryer washingmachine heater charger other); # erlaubte Consumer Typen
|
||||
my $defmintime = 60; # default min. Einschalt- bzw. Zykluszeit in Minuten
|
||||
my $defctype = "other"; # default Verbrauchertyp
|
||||
my $defcmode = "can"; # default Planungsmode der Verbraucher
|
||||
|
||||
my $caicondef = 'clock@gold'; # default consumerAdviceIcon
|
||||
my $defflowGSize = 300; # default flowGraphicSize
|
||||
my $histhourdef = 2; # default Anzeige vorangegangene Stunden
|
||||
my $wthcolddef = 'C7C979'; # Wetter Icon Tag Default Farbe
|
||||
my $wthcolndef = 'C7C7C7'; # Wetter Icon Nacht Default Farbe
|
||||
my $b1coldef = 'FFAC63'; # Default Farbe Beam 1
|
||||
my $b1fontcoldef = '0D0D0D'; # Default Schriftfarbe Beam 1
|
||||
my $b2coldef = 'C4C4A7'; # Default Farbe Beam 2
|
||||
my $b2fontcoldef = '000000'; # Default Schriftfarbe Beam 2
|
||||
|
||||
my $defpopercent = 0.5; # Standard % aktuelle Leistung an nominaler Leistung gemäß Typenschild
|
||||
my $defhyst = 0; # default Hysterese
|
||||
|
||||
# Default CSS-Style
|
||||
my $cssdef = qq{.flowg.text { stroke: none; fill: gray; font-size: 32px;} \n}.
|
||||
qq{.flowg.sun_active { stroke: orange; fill: orange; } \n}.
|
||||
qq{.flowg.sun_inactive { stroke: gray; fill: gray; } \n}.
|
||||
qq{.flowg.bat25 { stroke: red; fill: red; } \n}.
|
||||
qq{.flowg.bat50 { stroke: yellow; fill: yellow; } \n}.
|
||||
qq{.flowg.bat75 { stroke: green; fill: green; } \n}.
|
||||
qq{.flowg.grid_color1 { fill: green; } \n}.
|
||||
qq{.flowg.grid_color2 { fill: red; } \n}.
|
||||
qq{.flowg.grid_color3 { fill: gray; } \n}.
|
||||
qq{.flowg.inactive_in { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } \n}.
|
||||
qq{.flowg.inactive_out { stroke: gray; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.2; } \n}.
|
||||
qq{.flowg.active_in { stroke: red; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}.
|
||||
qq{.flowg.active_out { stroke: yellow; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}.
|
||||
qq{.flowg.active_bat_in { stroke: yellow; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}.
|
||||
qq{.flowg.active_bat_out { stroke: green; stroke-dashoffset: 20; stroke-dasharray: 10; opacity: 0.8; animation: dash 0.5s linear; animation-iteration-count: infinite; } \n}
|
||||
;
|
||||
|
||||
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 (wichtig auch für Kalkulation in __calcEnergyPieces !)
|
||||
@ -692,7 +695,16 @@ my %hef = (
|
||||
"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)
|
||||
"washingmachine" => { f => 0.30, m => 0.40, l => 0.30, mt => 120 },
|
||||
);
|
||||
);
|
||||
|
||||
my %hpctpl = ( # Percentile Template
|
||||
20 => { mp => 3 },
|
||||
30 => { mp => 2 },
|
||||
40 => { mp => 1 },
|
||||
60 => { mp => 1 },
|
||||
70 => { mp => 2 },
|
||||
80 => { mp => 3 },
|
||||
);
|
||||
|
||||
# Information zu verwendeten internen Datenhashes
|
||||
# $data{$type}{$name}{circular} # Ringspeicher
|
||||
@ -1948,9 +1960,7 @@ sub _getRoofTopData {
|
||||
##
|
||||
|
||||
$paref->{allstrings} = ReadingsVal($name, 'inverterStrings', '');
|
||||
|
||||
delete $data{$type}{$name}{current}{runTimeAPIResponseProc};
|
||||
|
||||
|
||||
__solCast_ApiRequest ($paref);
|
||||
|
||||
return;
|
||||
@ -2003,6 +2013,7 @@ sub __solCast_ApiRequest {
|
||||
timeout => 30,
|
||||
hash => $hash,
|
||||
caller => \&$caller,
|
||||
stc => [gettimeofday],
|
||||
allstrings => $allstrings,
|
||||
string => $string,
|
||||
method => "GET",
|
||||
@ -2027,6 +2038,7 @@ sub __solCast_ApiResponse {
|
||||
my $caller = $paref->{caller};
|
||||
my $string = $paref->{string};
|
||||
my $allstrings = $paref->{allstrings};
|
||||
my $stc = $paref->{stc}; # Startzeit API Abruf
|
||||
|
||||
my $type = $hash->{TYPE};
|
||||
my $t = time;
|
||||
@ -2043,7 +2055,8 @@ sub __solCast_ApiResponse {
|
||||
$data{$type}{$name}{solcastapi}{'?All'}{'?All'}{response_message} = $err;
|
||||
|
||||
readingsSingleUpdate($hash, "state", $msg, 1);
|
||||
$data{$type}{$name}{current}{runTimeAPIResponseProc} += sprintf "%.4f", tv_interval($sta); # API Laufzeit ermitteln
|
||||
$data{$type}{$name}{current}{runTimeLastAPIProc} = sprintf "%.4f", tv_interval($sta); # Verarbeitungszeit ermitteln
|
||||
$data{$type}{$name}{current}{runTimeLastAPIAnswer} = sprintf "%.4f", (tv_interval($stc) - tv_interval($sta)); # API Laufzeit ermitteln
|
||||
|
||||
return;
|
||||
}
|
||||
@ -2056,7 +2069,9 @@ sub __solCast_ApiResponse {
|
||||
Log3 ($name, 2, "$name - $msg");
|
||||
|
||||
readingsSingleUpdate($hash, "state", $msg, 1);
|
||||
$data{$type}{$name}{current}{runTimeAPIResponseProc} += sprintf "%.4f", tv_interval($sta); # API Laufzeit ermitteln
|
||||
$data{$type}{$name}{current}{runTimeLastAPIProc} = sprintf "%.4f", tv_interval($sta); # Verarbeitungszeit ermitteln
|
||||
$data{$type}{$name}{current}{runTimeLastAPIAnswer} = sprintf "%.4f", (tv_interval($stc) - tv_interval($sta)); # API Laufzeit ermitteln
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2085,8 +2100,9 @@ sub __solCast_ApiResponse {
|
||||
$data{$type}{$name}{solcastapi}{'?All'}{'?All'}{response_message} = $jdata->{'response_status'}{'message'};
|
||||
|
||||
readingsSingleUpdate($hash, "state", $msg, 1);
|
||||
$data{$type}{$name}{current}{runTimeAPIResponseProc} += sprintf "%.4f", tv_interval($sta); # API Laufzeit ermitteln
|
||||
|
||||
$data{$type}{$name}{current}{runTimeLastAPIProc} = sprintf "%.4f", tv_interval($sta); # Verarbeitungszeit ermitteln
|
||||
$data{$type}{$name}{current}{runTimeLastAPIAnswer} = sprintf "%.4f", (tv_interval($stc) - tv_interval($sta)); # API Laufzeit ermitteln
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2177,7 +2193,8 @@ sub __solCast_ApiResponse {
|
||||
allstrings => $allstrings
|
||||
};
|
||||
|
||||
$data{$type}{$name}{current}{runTimeAPIResponseProc} += sprintf "%.4f", tv_interval($sta); # API Laufzeit ermitteln
|
||||
$data{$type}{$name}{current}{runTimeLastAPIProc} = sprintf "%.4f", tv_interval($sta); # Verarbeitungszeit ermitteln
|
||||
$data{$type}{$name}{current}{runTimeLastAPIAnswer} = sprintf "%.4f", (tv_interval($stc) - tv_interval($sta)); # API Laufzeit ermitteln
|
||||
|
||||
return &$caller($param);
|
||||
}
|
||||
@ -3650,29 +3667,34 @@ sub __calcSolCastEstimates {
|
||||
|
||||
$peak *= 1000;
|
||||
|
||||
# my $edef = SolCastAPIVal ($hash, $string, $wantdt, 'pv_estimate', 0); # Back-Kompatibilität
|
||||
my $est50 = SolCastAPIVal ($hash, $string, $wantdt, 'pv_estimate50', 0);
|
||||
my $est50 = SolCastAPIVal ($hash, $string, $wantdt, 'pv_estimate50', 0);
|
||||
|
||||
if ($perc != 50) {
|
||||
my $est10 = SolCastAPIVal ($hash, $string, $wantdt, 'pv_estimate10', 0);
|
||||
my $est90 = SolCastAPIVal ($hash, $string, $wantdt, 'pv_estimate90', 0);
|
||||
|
||||
## Zusatzpercentile berechnen
|
||||
###############################
|
||||
my $lowdm = ($est50 - $est10) / 4;
|
||||
my $highdm = ($est90 - $est50) / 4;
|
||||
|
||||
$data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate20} = sprintf "%.0f", ($est50 - ($lowdm * 3));
|
||||
$data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate30} = sprintf "%.0f", ($est50 - ($lowdm * 2));
|
||||
$data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate40} = sprintf "%.0f", ($est50 - ($lowdm * 1));
|
||||
|
||||
$data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate60} = sprintf "%.0f", ($est50 + ($highdm * 1));
|
||||
$data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate70} = sprintf "%.0f", ($est50 + ($highdm * 2));
|
||||
$data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate80} = sprintf "%.0f", ($est50 + ($highdm * 3));
|
||||
## Zusatzpercentile berechnen - Muster:
|
||||
##
|
||||
## $data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate20} = sprintf "%.0f", ($est50 - ($lowdm * 3));
|
||||
## $data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate30} = sprintf "%.0f", ($est50 - ($lowdm * 2));
|
||||
## $data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate40} = sprintf "%.0f", ($est50 - ($lowdm * 1));
|
||||
##
|
||||
## $data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate60} = sprintf "%.0f", ($est50 + ($highdm * 1));
|
||||
## $data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate70} = sprintf "%.0f", ($est50 + ($highdm * 2));
|
||||
## $data{$type}{$name}{solcastapi}{$string}{$wantdt}{pv_estimate80} = sprintf "%.0f", ($est50 + ($highdm * 3));
|
||||
#################################################################################################################
|
||||
|
||||
if ($perc < 50) {
|
||||
my $est10 = SolCastAPIVal ($hash, $string, $wantdt, 'pv_estimate10', $est50);
|
||||
my $lowdm = ($est50 - $est10) / 4;
|
||||
$data{$type}{$name}{solcastapi}{$string}{$wantdt}{'pv_estimate'.$perc} = sprintf "%.0f", ($est50 - ($lowdm * $hpctpl{$perc}{mp}));
|
||||
}
|
||||
else {
|
||||
my $est90 = SolCastAPIVal ($hash, $string, $wantdt, 'pv_estimate90', $est50);
|
||||
my $highdm = ($est90 - $est50) / 4;
|
||||
$data{$type}{$name}{solcastapi}{$string}{$wantdt}{'pv_estimate'.$perc} = sprintf "%.0f", ($est50 + ($highdm * $hpctpl{$perc}{mp}));
|
||||
}
|
||||
}
|
||||
|
||||
my $est = SolCastAPIVal ($hash, $string, $wantdt, 'pv_estimate'.$perc, $est50);
|
||||
my $pv = sprintf "%.1f", ($est * $ccf * $rcf);
|
||||
my $est = SolCastAPIVal ($hash, $string, $wantdt, 'pv_estimate'.$perc, $est50);
|
||||
my $pv = sprintf "%.1f", ($est * $ccf * $rcf);
|
||||
|
||||
if(AttrVal ($name, 'verbose', 3) == 4) {
|
||||
$lh = { # Log-Hash zur Ausgabe
|
||||
|
Loading…
x
Reference in New Issue
Block a user