mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 12:49:34 +00:00
76_SolarForecast: contrib 1.16.3
git-svn-id: https://svn.fhem.de/fhem/trunk@28552 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
e9821b39ff
commit
914598bf7e
@ -161,7 +161,8 @@ my %vNotesIntern = (
|
|||||||
"1.16.3" => "24.02.2024 store pvcorrf, quality, pvrlsum, pvfcsum, dnumsum with value <sunalt2bin>.<cloud2bin> in pvCircular ".
|
"1.16.3" => "24.02.2024 store pvcorrf, quality, pvrlsum, pvfcsum, dnumsum with value <sunalt2bin>.<cloud2bin> in pvCircular ".
|
||||||
"get pvcorrf / quality from neff in combination with sun altitude (CircularSunCloudkorrVal) ".
|
"get pvcorrf / quality from neff in combination with sun altitude (CircularSunCloudkorrVal) ".
|
||||||
"delete CircularCloudkorrVal, show sun position in beamgrafic weather mouse over ".
|
"delete CircularCloudkorrVal, show sun position in beamgrafic weather mouse over ".
|
||||||
"split pvCorrection into pvCorrectionRead and pvCorrectionWrite ",
|
"split pvCorrection into pvCorrectionRead and pvCorrectionWrite ".
|
||||||
|
"_checkSetupNotComplete: improve setup Wizzard for ForecastSolar-API ",
|
||||||
"1.16.2" => "22.02.2024 minor changes, R101 -> RR1c, totalrain instead of weatherrainprob, delete wrp r101 ".
|
"1.16.2" => "22.02.2024 minor changes, R101 -> RR1c, totalrain instead of weatherrainprob, delete wrp r101 ".
|
||||||
"delete wrp from circular & airaw, remove rain2bin, __getDWDSolarData: change \$runh, ".
|
"delete wrp from circular & airaw, remove rain2bin, __getDWDSolarData: change \$runh, ".
|
||||||
"fix Illegal division by zero Forum: https://forum.fhem.de/index.php?msg=1304009 ".
|
"fix Illegal division by zero Forum: https://forum.fhem.de/index.php?msg=1304009 ".
|
||||||
@ -1449,6 +1450,13 @@ sub _setcurrentRadiationAPI { ## no critic "not used"
|
|||||||
my $rmf = reqModFail();
|
my $rmf = reqModFail();
|
||||||
return "You have to install the required perl module: ".$rmf if($rmf);
|
return "You have to install the required perl module: ".$rmf if($rmf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readingsSingleUpdate ($hash, "currentRadiationAPI", $prop, 1);
|
||||||
|
createAssociatedWith ($hash);
|
||||||
|
writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben
|
||||||
|
setModel ($hash); # Model setzen
|
||||||
|
|
||||||
|
return if(_checkSetupNotComplete ($hash)); # keine Stringkonfiguration wenn Setup noch nicht komplett
|
||||||
|
|
||||||
if ($prop eq 'ForecastSolar-API') {
|
if ($prop eq 'ForecastSolar-API') {
|
||||||
my ($set, $lat, $lon) = locCoordinates();
|
my ($set, $lat, $lon) = locCoordinates();
|
||||||
@ -1461,15 +1469,6 @@ sub _setcurrentRadiationAPI { ## no critic "not used"
|
|||||||
return qq{Please complete command "set $name moduleAzimuth".} if(!$dir);
|
return qq{Please complete command "set $name moduleAzimuth".} if(!$dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($prop eq 'VictronVRM-API') {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
readingsSingleUpdate ($hash, "currentRadiationAPI", $prop, 1);
|
|
||||||
createAssociatedWith ($hash);
|
|
||||||
writeCacheToFile ($hash, "plantconfig", $plantcfg.$name); # Anlagenkonfiguration File schreiben
|
|
||||||
setModel ($hash); # Model setzen
|
|
||||||
|
|
||||||
my $type = $hash->{TYPE};
|
my $type = $hash->{TYPE};
|
||||||
$data{$type}{$name}{current}{allStringsFullfilled} = 0; # Stringkonfiguration neu prüfen lassen
|
$data{$type}{$name}{current}{allStringsFullfilled} = 0; # Stringkonfiguration neu prüfen lassen
|
||||||
|
|
||||||
@ -5823,7 +5822,7 @@ sub centralTask {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CurrentVal ($hash, 'allStringsFullfilled', 0)) { # die String Konfiguration erstellen wenn noch nicht erfolgreich ausgeführt
|
if (!CurrentVal ($hash, 'allStringsFullfilled', 0)) { # die String Konfiguration erstellen wenn noch nicht erfolgreich ausgeführt
|
||||||
my $ret = createStringConfig ($hash);
|
my $ret = createStringConfig ($hash);
|
||||||
|
|
||||||
if ($ret) {
|
if ($ret) {
|
||||||
@ -7508,31 +7507,31 @@ sub _batSocTarget {
|
|||||||
|
|
||||||
## Aufladewahrscheinlichkeit beachten
|
## Aufladewahrscheinlichkeit beachten
|
||||||
#######################################
|
#######################################
|
||||||
my $pvfctm = ReadingsNum ($name, 'Tomorrow_PVforecast', 0); # PV Prognose morgen
|
my $pvfctm = ReadingsNum ($name, 'Tomorrow_PVforecast', 0); # PV Prognose morgen
|
||||||
my $pvfctd = ReadingsNum ($name, 'RestOfDayPVforecast', 0); # PV Prognose Rest heute
|
my $pvfctd = ReadingsNum ($name, 'RestOfDayPVforecast', 0); # PV Prognose Rest heute
|
||||||
my $csopt = ReadingsNum ($name, 'Battery_OptimumTargetSoC', $lowSoc); # aktuelles SoC Optimum
|
my $csopt = ReadingsNum ($name, 'Battery_OptimumTargetSoC', $lowSoc); # aktuelles SoC Optimum
|
||||||
|
|
||||||
my $pvexpect = $pvfctm > $pvfctd ? $pvfctm : $pvfctd;
|
my $pvexpect = $pvfctm > $pvfctd ? $pvfctm : $pvfctd;
|
||||||
|
my $batinstcap = CurrentVal ($hash, 'batinstcap', 0); # installierte Batteriekapazität Wh
|
||||||
|
my $cantarget = 100 - (100 / $batinstcap) * $pvexpect; # berechneter möglicher Min SOC nach Berücksichtigung Ladewahrscheinlichkeit
|
||||||
|
|
||||||
my $batinstcap = CurrentVal ($hash, 'batinstcap', 0); # installierte Batteriekapazität Wh
|
my $newtarget = sprintf "%.0f", ($cantarget < $target ? $cantarget : $target); # Abgleich möglicher Min SOC gg. berechneten Min SOC
|
||||||
my $cantarget = 100 - (100 / $batinstcap) * $pvexpect; # berechneter möglicher Min SOC nach Berücksichtigung Ladewahrscheinlichkeit
|
|
||||||
|
|
||||||
my $newtarget = sprintf "%.0f", ($cantarget < $target ? $cantarget : $target); # Abgleich möglicher Min SOC gg. berechneten Min SOC
|
|
||||||
my $logadd = '';
|
my $logadd = '';
|
||||||
|
|
||||||
if ($newtarget > $csopt && $t > $delayts) { # Erhöhung des SoC (wird ab Sonnenuntergang angewendet)
|
if ($newtarget > $csopt && $t > $delayts) { # Erhöhung des SoC (wird ab Sonnenuntergang angewendet)
|
||||||
$target = $newtarget;
|
$target = $newtarget;
|
||||||
$logadd = "(new target > $csopt % and Sunset has passed)";
|
$logadd = "(new target > $csopt % and Sunset has passed)";
|
||||||
}
|
}
|
||||||
elsif ($newtarget > $csopt && $t <= $delayts) { # bisheriges Optimum bleibt vorerst
|
elsif ($newtarget > $csopt && $t <= $delayts) { # bisheriges Optimum bleibt vorerst
|
||||||
$target = $csopt;
|
$target = $csopt;
|
||||||
$nt = (timestampToTimestring ($delayts, $paref->{lang}))[0];
|
$nt = (timestampToTimestring ($delayts, $paref->{lang}))[0];
|
||||||
$logadd = "(calculated new target $newtarget % is only activated after $nt)";
|
$logadd = "(calculated new target $newtarget % is only activated after $nt)";
|
||||||
}
|
}
|
||||||
elsif ($newtarget < $csopt) { # Targetminderung sofort umsetzen -> Freiplatz für Ladeprognose
|
elsif ($newtarget < $csopt) { # Targetminderung sofort umsetzen -> Freiplatz für Ladeprognose
|
||||||
$target = $newtarget;
|
$target = $newtarget;
|
||||||
$logadd = "(new target < current Target SoC $csopt)";
|
$logadd = "(new target < current Target SoC $csopt)";
|
||||||
}
|
}
|
||||||
else { # bisheriges Optimum bleibt
|
else { # bisheriges Optimum bleibt
|
||||||
$target = $newtarget;
|
$target = $newtarget;
|
||||||
$logadd = "(no change)";
|
$logadd = "(no change)";
|
||||||
}
|
}
|
||||||
@ -7670,33 +7669,33 @@ sub _createSummaries {
|
|||||||
$pvfc = 0 if($pvfc < 0); # PV Prognose darf nicht negativ sein
|
$pvfc = 0 if($pvfc < 0); # PV Prognose darf nicht negativ sein
|
||||||
$confc = 0 if($confc < 0); # Verbrauchsprognose darf nicht negativ sein
|
$confc = 0 if($confc < 0); # Verbrauchsprognose darf nicht negativ sein
|
||||||
|
|
||||||
if($h == 1) {
|
if ($h == 1) {
|
||||||
$next1HoursSum->{PV} += $pvfc / 60 * $minute;
|
$next1HoursSum->{PV} += $pvfc / 60 * $minute;
|
||||||
$next1HoursSum->{Consumption} += $confc / 60 * $minute;
|
$next1HoursSum->{Consumption} += $confc / 60 * $minute;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($h <= 2) {
|
if ($h <= 2) {
|
||||||
$next2HoursSum->{PV} += $pvfc if($h < 2);
|
$next2HoursSum->{PV} += $pvfc if($h < 2);
|
||||||
$next2HoursSum->{PV} += $pvfc / 60 * $minute if($h == 2);
|
$next2HoursSum->{PV} += $pvfc / 60 * $minute if($h == 2);
|
||||||
$next2HoursSum->{Consumption} += $confc if($h < 2);
|
$next2HoursSum->{Consumption} += $confc if($h < 2);
|
||||||
$next2HoursSum->{Consumption} += $confc / 60 * $minute if($h == 2);
|
$next2HoursSum->{Consumption} += $confc / 60 * $minute if($h == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($h <= 3) {
|
if ($h <= 3) {
|
||||||
$next3HoursSum->{PV} += $pvfc if($h < 3);
|
$next3HoursSum->{PV} += $pvfc if($h < 3);
|
||||||
$next3HoursSum->{PV} += $pvfc / 60 * $minute if($h == 3);
|
$next3HoursSum->{PV} += $pvfc / 60 * $minute if($h == 3);
|
||||||
$next3HoursSum->{Consumption} += $confc if($h < 3);
|
$next3HoursSum->{Consumption} += $confc if($h < 3);
|
||||||
$next3HoursSum->{Consumption} += $confc / 60 * $minute if($h == 3);
|
$next3HoursSum->{Consumption} += $confc / 60 * $minute if($h == 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($h <= 4) {
|
if ($h <= 4) {
|
||||||
$next4HoursSum->{PV} += $pvfc if($h < 4);
|
$next4HoursSum->{PV} += $pvfc if($h < 4);
|
||||||
$next4HoursSum->{PV} += $pvfc / 60 * $minute if($h == 4);
|
$next4HoursSum->{PV} += $pvfc / 60 * $minute if($h == 4);
|
||||||
$next4HoursSum->{Consumption} += $confc if($h < 4);
|
$next4HoursSum->{Consumption} += $confc if($h < 4);
|
||||||
$next4HoursSum->{Consumption} += $confc / 60 * $minute if($h == 4);
|
$next4HoursSum->{Consumption} += $confc / 60 * $minute if($h == 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($istdy) {
|
if ($istdy) {
|
||||||
$restOfDaySum->{PV} += $pvfc;
|
$restOfDaySum->{PV} += $pvfc;
|
||||||
$restOfDaySum->{Consumption} += $confc;
|
$restOfDaySum->{Consumption} += $confc;
|
||||||
$tdConFcTillSunset += $confc if($don);
|
$tdConFcTillSunset += $confc if($don);
|
||||||
@ -9653,7 +9652,7 @@ sub _calcCaQcomplex {
|
|||||||
storeReading ('.pvCorrectionFactor_'.sprintf("%02d",$h).'_cloudcover', 'done');
|
storeReading ('.pvCorrectionFactor_'.sprintf("%02d",$h).'_cloudcover', 'done');
|
||||||
|
|
||||||
if ($acu =~ /on_complex/xs) {
|
if ($acu =~ /on_complex/xs) {
|
||||||
storeReading ('pvCorrectionFactor_'.sprintf("%02d",$h), $factor." (automatic - old factor: $oldfac, Sun Alt range: $sabin, Cloud range: $crang, days in range: $dnum)");
|
storeReading ('pvCorrectionFactor_'.sprintf("%02d",$h), $factor." (automatic - old factor: $oldfac, Sun Alt range: $sabin, Cloud range: $crang, Days in range: $dnum)");
|
||||||
storeReading ('pvCorrectionFactor_'.sprintf("%02d",$h).'_autocalc', 'done');
|
storeReading ('pvCorrectionFactor_'.sprintf("%02d",$h).'_autocalc', 'done');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9715,7 +9714,7 @@ sub _calcCaQsimple {
|
|||||||
storeReading ('.pvCorrectionFactor_'.sprintf("%02d",$h).'_apipercentil', 'done');
|
storeReading ('.pvCorrectionFactor_'.sprintf("%02d",$h).'_apipercentil', 'done');
|
||||||
|
|
||||||
if ($acu =~ /on_simple/xs) {
|
if ($acu =~ /on_simple/xs) {
|
||||||
storeReading ('pvCorrectionFactor_'.sprintf("%02d",$h), $factor." (automatic - old factor: $oldfac, days in range: $dnum)");
|
storeReading ('pvCorrectionFactor_'.sprintf("%02d",$h), $factor." (automatic - old factor: $oldfac, Days in range: $dnum)");
|
||||||
storeReading ('pvCorrectionFactor_'.sprintf("%02d",$h).'_autocalc', 'done');
|
storeReading ('pvCorrectionFactor_'.sprintf("%02d",$h).'_autocalc', 'done');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9742,7 +9741,7 @@ sub __calcNewFactor {
|
|||||||
my $pvrlsum = $pvrl;
|
my $pvrlsum = $pvrl;
|
||||||
my $pvfcsum = $pvfc;
|
my $pvfcsum = $pvfc;
|
||||||
|
|
||||||
debugLog ($paref, 'pvCorrectionWrite', "$calc Corrf -> start calculation correction factor for hour: $h");
|
debugLog ($paref, 'pvCorrectionWrite', "$calc Corrf -> Start calculation correction factor for hour: $h");
|
||||||
|
|
||||||
my ($oldfac, $oldq) = CircularSunCloudkorrVal ($hash, sprintf("%02d",$h), $sabin, $crang, 0); # bisher definierter Korrekturfaktor / Qualität
|
my ($oldfac, $oldq) = CircularSunCloudkorrVal ($hash, sprintf("%02d",$h), $sabin, $crang, 0); # bisher definierter Korrekturfaktor / Qualität
|
||||||
my ($pvhis, $fchis, $dnum) = CircularSumVal ($hash, sprintf("%02d",$h), $sabin, $crang, 0);
|
my ($pvhis, $fchis, $dnum) = CircularSumVal ($hash, sprintf("%02d",$h), $sabin, $crang, 0);
|
||||||
@ -9785,7 +9784,7 @@ sub __calcNewFactor {
|
|||||||
my $qual = __calcFcQuality ($pvfc, $pvrl); # Qualität der Vorhersage für die vergangene Stunde
|
my $qual = __calcFcQuality ($pvfc, $pvrl); # Qualität der Vorhersage für die vergangene Stunde
|
||||||
|
|
||||||
debugLog ($paref, 'pvCorrectionWrite', "$calc Corrf -> determined values - hour: $h, Sun Altitude range: $sabin, Cloud range: $crang, old factor: $oldfac, new factor: $factor, days: $dnum");
|
debugLog ($paref, 'pvCorrectionWrite', "$calc Corrf -> determined values - hour: $h, Sun Altitude range: $sabin, Cloud range: $crang, old factor: $oldfac, new factor: $factor, days: $dnum");
|
||||||
debugLog ($paref, 'pvCorrectionWrite|saveData2Cache', "$calc Corrf -> write correction values into Circular - hour: $h, Sun Altitude range: $sabin, Cloud range: $crang, factor: $factor, quality: $qual");
|
debugLog ($paref, 'pvCorrectionWrite|saveData2Cache', "$calc Corrf -> write correction values into Circular - hour: $h, Sun Altitude range: $sabin, Cloud range: $crang, factor: $factor, quality: $qual, days: $dnum");
|
||||||
|
|
||||||
if ($crang ne 'simple') {
|
if ($crang ne 'simple') {
|
||||||
my $idx = $sabin.'.'.$crang; # value für pvcorrf Sonne Altitude
|
my $idx = $sabin.'.'.$crang; # value für pvcorrf Sonne Altitude
|
||||||
@ -10540,8 +10539,8 @@ sub _checkSetupNotComplete {
|
|||||||
my $medev = ReadingsVal ($name, 'currentMeterDev', undef); # Meter Device
|
my $medev = ReadingsVal ($name, 'currentMeterDev', undef); # Meter Device
|
||||||
|
|
||||||
my $peaks = ReadingsVal ($name, 'modulePeakString', undef); # String Peak
|
my $peaks = ReadingsVal ($name, 'modulePeakString', undef); # String Peak
|
||||||
my $dir = ReadingsVal ($name, 'moduleAzimuth', undef); # Modulausrichtung Konfig (Azimut)
|
my $maz = ReadingsVal ($name, 'moduleAzimuth', undef); # Modulausrichtung Konfig (Azimut)
|
||||||
my $ta = ReadingsVal ($name, 'moduleDeclination', undef); # Modul Neigungswinkel Konfig
|
my $mdec = ReadingsVal ($name, 'moduleDeclination', undef); # Modul Neigungswinkel Konfig
|
||||||
my $mrt = ReadingsVal ($name, 'moduleRoofTops', undef); # RoofTop Konfiguration (SolCast API)
|
my $mrt = ReadingsVal ($name, 'moduleRoofTops', undef); # RoofTop Konfiguration (SolCast API)
|
||||||
|
|
||||||
my $vrmcr = SolCastAPIVal ($hash, '?VRM', '?API', 'credentials', ''); # Victron VRM Credentials gesetzt
|
my $vrmcr = SolCastAPIVal ($hash, '?VRM', '?API', 'credentials', ''); # Victron VRM Credentials gesetzt
|
||||||
@ -10577,9 +10576,9 @@ sub _checkSetupNotComplete {
|
|||||||
my $chkicon = "<a onClick=$cmdplchk>$img</a>";
|
my $chkicon = "<a onClick=$cmdplchk>$img</a>";
|
||||||
my $chktitle = $htitles{plchk}{$lang};
|
my $chktitle = $htitles{plchk}{$lang};
|
||||||
|
|
||||||
if (!$is || !$wedev || !$radev || !$indev || !$medev || !$peaks ||
|
if (!$is || !$wedev || !$radev || !$indev || !$medev || !$peaks ||
|
||||||
(isSolCastUsed ($hash) ? (!$rip || !$mrt) : isVictronKiUsed ($hash) ? !$vrmcr : (!$dir || !$ta )) ||
|
(isSolCastUsed ($hash) ? (!$rip || !$mrt) : isVictronKiUsed ($hash) ? !$vrmcr : (!$maz || !$mdec )) ||
|
||||||
(isForecastSolarUsed ($hash) ? !$coset : '') ||
|
(isForecastSolarUsed ($hash) ? !$coset : '') ||
|
||||||
!defined $pv0) {
|
!defined $pv0) {
|
||||||
$ret .= "<table class='roomoverview'>";
|
$ret .= "<table class='roomoverview'>";
|
||||||
$ret .= "<tr style='height:".$height."px'>";
|
$ret .= "<tr style='height:".$height."px'>";
|
||||||
@ -10589,6 +10588,12 @@ sub _checkSetupNotComplete {
|
|||||||
if (!$wedev) { ## no critic 'Cascading'
|
if (!$wedev) { ## no critic 'Cascading'
|
||||||
$ret .= $hqtxt{cfd}{$lang};
|
$ret .= $hqtxt{cfd}{$lang};
|
||||||
}
|
}
|
||||||
|
elsif (!$is) {
|
||||||
|
$ret .= $hqtxt{ist}{$lang};
|
||||||
|
}
|
||||||
|
elsif (!$peaks) {
|
||||||
|
$ret .= $hqtxt{mps}{$lang};
|
||||||
|
}
|
||||||
elsif (!$radev) {
|
elsif (!$radev) {
|
||||||
$ret .= $hqtxt{crd}{$lang};
|
$ret .= $hqtxt{crd}{$lang};
|
||||||
}
|
}
|
||||||
@ -10598,22 +10603,16 @@ sub _checkSetupNotComplete {
|
|||||||
elsif (!$medev) {
|
elsif (!$medev) {
|
||||||
$ret .= $hqtxt{mid}{$lang};
|
$ret .= $hqtxt{mid}{$lang};
|
||||||
}
|
}
|
||||||
elsif (!$is) {
|
|
||||||
$ret .= $hqtxt{ist}{$lang};
|
|
||||||
}
|
|
||||||
elsif (!$peaks) {
|
|
||||||
$ret .= $hqtxt{mps}{$lang};
|
|
||||||
}
|
|
||||||
elsif (!$rip && isSolCastUsed ($hash)) {
|
elsif (!$rip && isSolCastUsed ($hash)) {
|
||||||
$ret .= $hqtxt{rip}{$lang};
|
$ret .= $hqtxt{rip}{$lang};
|
||||||
}
|
}
|
||||||
elsif (!$mrt && isSolCastUsed ($hash)) {
|
elsif (!$mrt && isSolCastUsed ($hash)) {
|
||||||
$ret .= $hqtxt{mrt}{$lang};
|
$ret .= $hqtxt{mrt}{$lang};
|
||||||
}
|
}
|
||||||
elsif (!$dir && !isSolCastUsed ($hash) && !isVictronKiUsed ($hash)) {
|
elsif (!$maz && !isSolCastUsed ($hash) && !isVictronKiUsed ($hash)) {
|
||||||
$ret .= $hqtxt{mdr}{$lang};
|
$ret .= $hqtxt{mdr}{$lang};
|
||||||
}
|
}
|
||||||
elsif (!$ta && !isSolCastUsed ($hash) && !isVictronKiUsed ($hash)) {
|
elsif (!$mdec && !isSolCastUsed ($hash) && !isVictronKiUsed ($hash)) {
|
||||||
$ret .= $hqtxt{mta}{$lang};
|
$ret .= $hqtxt{mta}{$lang};
|
||||||
}
|
}
|
||||||
elsif (!$vrmcr && isVictronKiUsed ($hash)) {
|
elsif (!$vrmcr && isVictronKiUsed ($hash)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user