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

76_Solarforcast: contrib 0.1.0

git-svn-id: https://svn.fhem.de/fhem/trunk@23372 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
nasseeder1 2020-12-17 15:52:48 +00:00
parent 7e35a1ef86
commit 178a214d5a

View File

@ -463,8 +463,8 @@ sub _setpvCorrectionFactor { ## no critic "not used"
my $fcdev = ReadingsVal($name, "currentForecastDev", ""); # aktuelles Forecast Device
my $params = {
myHash => $hash,
myName => $name,
hash => $hash,
name => $name,
t => $t,
chour => $chour,
daref => \@da
@ -612,8 +612,8 @@ sub centralTask {
my $chour = strftime "%H", localtime($t); # aktuelle Stunde
my $params = {
myHash => $hash,
myName => $name,
hash => $hash,
name => $name,
t => $t,
chour => $chour,
daref => \@da
@ -655,28 +655,28 @@ return $interval;
################################################################
sub _transferForecastValues {
my $paref = shift;
my $myHash = $paref->{myHash};
my $myName = $paref->{myName};
my $hash = $paref->{hash};
my $name = $paref->{name};
my $t = $paref->{t};
my $chour = $paref->{chour};
my $daref = $paref->{daref};
my $fcname = ReadingsVal($myName, "currentForecastDev", ""); # aktuelles Forecast Device
my $fcname = ReadingsVal($name, "currentForecastDev", ""); # aktuelles Forecast Device
return if(!$fcname || !$defs{$fcname});
my ($time_str,$epoche,$fd,$v);
my $fc0_SunRise = (split ":", ReadingsVal($fcname, "fc0_SunRise", "00:00"))[0]; # Sonnenaufgang heute (hh)
my $fc0_SunSet = (split ":", ReadingsVal($fcname, "fc0_SunSet", "00:00"))[0]; # Sonnenuntergang heute (hh)
my $fc1_SunRise = (split ":", ReadingsVal($fcname, "fc1_SunRise", "00:00"))[0]; # Sonnenaufgang morgen (hh)
my $fc1_SunSet = (split ":", ReadingsVal($fcname, "fc1_SunSet", "00:00"))[0]; # Sonnenuntergang morgen (hh)
my $fc0_SunRise = ReadingsVal($fcname, "fc0_SunRise", "00:00"); # Sonnenaufgang heute
my $fc0_SunSet = ReadingsVal($fcname, "fc0_SunSet", "00:00"); # Sonnenuntergang heute
my $fc1_SunRise = ReadingsVal($fcname, "fc1_SunRise", "00:00"); # Sonnenaufgang morgen
my $fc1_SunSet = ReadingsVal($fcname, "fc1_SunSet", "00:00"); # Sonnenuntergang morgen
push @$daref, "Today_HourSunRise:". $fc0_SunRise;
push @$daref, "Today_HourSunSet:". $fc0_SunSet;
push @$daref, "Tomorrow_HourSunRise:".$fc1_SunRise;
push @$daref, "Tomorrow_HourSunSet:". $fc1_SunSet;
push @$daref, "Today_SunRise:". $fc0_SunRise;
push @$daref, "Today_SunSet:". $fc0_SunSet;
push @$daref, "Tomorrow_SunRise:".$fc1_SunRise;
push @$daref, "Tomorrow_SunSet:". $fc1_SunSet;
deleteReadingspec ($myHash, "NextHour.*");
deleteReadingspec ($hash, "NextHour.*");
for my $num (0..47) {
my $fh = $chour + $num;
@ -687,7 +687,7 @@ sub _transferForecastValues {
$v = ReadingsVal($fcname, "fc${fd}_${fh}_Rad1h", 0);
Log3($myName, 5, "$myName - collect DWD data: device=$fcname, rad=fc${fd}_${fh}_Rad1h, wid=fc${fd}_${fh}_ww, Val=$v");
Log3($name, 5, "$name - collect DWD data: device=$fcname, rad=fc${fd}_${fh}_Rad1h, wid=fc${fd}_${fh}_ww, Val=$v");
## PV Forecast
###############
@ -700,12 +700,12 @@ sub _transferForecastValues {
$epoche = $t + (3600*$num);
}
my $calcpv = calcPVforecast ($myName, $v, $fh); # Vorhersage gewichtet kalkulieren
my $calcpv = calcPVforecast ($name, $v, $fh); # Vorhersage gewichtet kalkulieren
push @$daref, "${time_str}_PVforecast:".$calcpv." Wh";
push @$daref, "${time_str}_Time:" .TimeAdjust ($epoche); # Zeit fortschreiben
$myHash->{HELPER}{"fc${fd}_".sprintf("%02d",$fh)."_PVforecast"} = $v." Wh"; # original Vorhersagedaten zur Berechnung Auto-Korrekturfaktor in Helper speichern
$hash->{HELPER}{"fc${fd}_".sprintf("%02d",$fh)."_PVforecast"} = $v." Wh"; # original Vorhersagedaten zur Berechnung Auto-Korrekturfaktor in Helper speichern
if($fd == 0 && int $calcpv > 0) { # Vorhersagedaten des aktuellen Tages zum manuellen Vergleich in Reading speichern
push @$daref, "Today_Hour".sprintf("%02d",$fh)."_PVforecast:$calcpv Wh";
@ -725,7 +725,7 @@ sub _transferForecastValues {
$wid = "1".$wid; # "1" der WeatherID voranstellen wenn Nacht
}
$myHash->{HELPER}{"${time_str}_WeatherId"} = $wid;
$hash->{HELPER}{"${time_str}_WeatherId"} = $wid;
}
return;
@ -736,13 +736,13 @@ return;
################################################################
sub _transferInverterValues {
my $paref = shift;
my $myHash = $paref->{myHash};
my $myName = $paref->{myName};
my $hash = $paref->{hash};
my $name = $paref->{name};
my $t = $paref->{t};
my $chour = $paref->{chour};
my $daref = $paref->{daref};
my $indev = ReadingsVal($myName, "currentInverterDev", "");
my $indev = ReadingsVal($name, "currentInverterDev", "");
my ($a,$h) = parseParams ($indev);
$indev = $a->[0] // "";
return if(!$indev || !$defs{$indev});
@ -750,10 +750,10 @@ sub _transferInverterValues {
my $tlim = "0|23"; # Stunde 0/23 -> bestimmte Aktionen
if($chour =~ /^($tlim)$/x) {
deleteReadingspec ($myHash, "Today_Hour.*_PV.*");
#my @allrds = keys %{$myHash->{READINGS}};
deleteReadingspec ($hash, "Today_Hour.*_PV.*");
#my @allrds = keys %{$hash->{READINGS}};
#for my $key(@allrds) {
# readingsDelete($myHash, $key) if($key =~ m/^Today_Hour\d{2}_PVreal$/x);
# readingsDelete($hash, $key) if($key =~ m/^Today_Hour\d{2}_PVreal$/x);
#}
}
@ -762,7 +762,7 @@ sub _transferInverterValues {
my ($pvread,$pvunit) = split ":", $h->{pv}; # Readingname/Unit für aktuelle PV Erzeugung
my ($edread,$edunit) = split ":", $h->{etoday}; # Readingname/Unit für Tagesenergie
Log3($myName, 5, "$myName - collect Inverter data: device=$indev, pv=$pvread ($pvunit), etoday=$edread ($edunit)");
Log3($name, 5, "$name - collect Inverter data: device=$indev, pv=$pvread ($pvunit), etoday=$edread ($edunit)");
my $pvuf = $pvunit =~ /^kW$/xi ? 1000 : 1;
my $pv = ReadingsNum ($indev, $pvread, 0) * $pvuf; # aktuelle Erzeugung (W)
@ -774,8 +774,8 @@ sub _transferInverterValues {
my $edaypast = 0;
for my $h (0..int($chour)-1) { # alle bisherigen Erzeugungen des Tages summieren
deleteReadingspec ($myHash, "Today_Hour00_PV.*");
$edaypast += ReadingsNum ($myName, "Today_Hour".sprintf("%02d",$h)."_PVreal", 0);
deleteReadingspec ($hash, "Today_Hour00_PV.*");
$edaypast += ReadingsNum ($name, "Today_Hour".sprintf("%02d",$h)."_PVreal", 0);
}
my $ethishour = $etoday - $edaypast;
@ -790,13 +790,13 @@ return;
################################################################
sub _transferMeterValues {
my $paref = shift;
my $myHash = $paref->{myHash};
my $myName = $paref->{myName};
my $hash = $paref->{hash};
my $name = $paref->{name};
my $t = $paref->{t};
my $chour = $paref->{chour};
my $daref = $paref->{daref};
my $medev = ReadingsVal($myName, "currentMeterDev", ""); # aktuelles Meter device
my $medev = ReadingsVal($name, "currentMeterDev", ""); # aktuelles Meter device
my ($a,$h) = parseParams ($medev);
$medev = $a->[0] // "";
return if(!$medev || !$defs{$medev});
@ -805,7 +805,7 @@ sub _transferMeterValues {
#########################
my ($gc,$gcunit) = split ":", $h->{gcon}; # Readingname/Unit für aktuellen Netzbezug
Log3($myName, 5, "$myName - collect Meter data: device=$medev, gcon=$gc ($gcunit)");
Log3($name, 5, "$name - collect Meter data: device=$medev, gcon=$gc ($gcunit)");
my $gcuf = $gcunit =~ /^kW$/xi ? 1000 : 1;
my $co = ReadingsNum ($medev, $gc, 0) * $gcuf; # aktueller Bezug (-) oder Einspeisung
@ -859,7 +859,7 @@ return $ret;
################################################################
sub pageRefresh {
my ($hash) = @_;
my $hash = shift;
my $d = $hash->{NAME};
# Seitenrefresh festgelegt durch SolarForecast-Attribut "autoRefresh" und "autoRefreshFW"
@ -920,7 +920,8 @@ return;
# Grafik als HTML zurück liefern (z.B. für Widget)
################################################################
sub pageAsHtml {
my ($hash,$ftui) = @_;
my $hash = shift;
my $ftui = shift;
my $name = $hash->{NAME};
my $height;
@ -1826,59 +1827,59 @@ return $pv;
################################################################
sub calcVariance {
my $paref = shift;
my $myHash = $paref->{myHash};
my $myName = $paref->{myName};
my $hash = $paref->{hash};
my $name = $paref->{name};
my $chour = $paref->{chour};
my $dcauto = ReadingsVal ($myName, "pvCorrectionFactor_Auto", "off"); # nur bei "on" automatische Varianzkalkulation
my $dcauto = ReadingsVal ($name, "pvCorrectionFactor_Auto", "off"); # nur bei "on" automatische Varianzkalkulation
if($dcauto =~ /^off/x) {
Log3($myName, 4, "$myName - automatic Variance calculation is switched off.");
Log3($name, 4, "$name - automatic Variance calculation is switched off.");
return;
}
my $idts = $myHash->{HELPER}{INVERTERDEFTS}; # FHEM Start oder Definitionstimestamp des Inverterdevice
my $idts = $hash->{HELPER}{INVERTERDEFTS}; # FHEM Start oder Definitionstimestamp des Inverterdevice
return if(!$idts);
my $t = time; # aktuelle Unix-Zeit
if($t - $idts < 86400) {
my $rmh = sprintf "%.1f", ((86400 - ($t - $idts)) / 3600);
Log3($myName, 4, "$myName - Variance calculation in standby. It starts in $rmh hours.");
readingsSingleUpdate($myHash, "pvCorrectionFactor_Auto", "on (remains in standby for $rmh hours)", 0);
Log3($name, 4, "$name - Variance calculation in standby. It starts in $rmh hours.");
readingsSingleUpdate($hash, "pvCorrectionFactor_Auto", "on (remains in standby for $rmh hours)", 0);
return;
}
else {
readingsSingleUpdate($myHash, "pvCorrectionFactor_Auto", "on", 0);
readingsSingleUpdate($hash, "pvCorrectionFactor_Auto", "on", 0);
}
my @da;
for my $h (1..23) {
next if(!$chour || $h >= $chour);
my $fcval = $myHash->{HELPER}{"fc0_".sprintf("%02d",$h)."_PVforecast"} // 0;
my $fcval = $hash->{HELPER}{"fc0_".sprintf("%02d",$h)."_PVforecast"} // 0;
my $fcnum = int ((split " ", $fcval)[0]);
next if(!$fcnum);
my $pvval = ReadingsNum ($myName, "Today_Hour".sprintf("%02d",$h)."_PVreal", 0);
my $pvval = ReadingsNum ($name, "Today_Hour".sprintf("%02d",$h)."_PVreal", 0);
next if(!$pvval);
my $oldfac = ReadingsNum ($myName, "pvCorrectionFactor_".sprintf("%02d",$h), 1); # bisher definierter Korrekturfaktor
my $oldfac = ReadingsNum ($name, "pvCorrectionFactor_".sprintf("%02d",$h), 1); # bisher definierter Korrekturfaktor
$oldfac = 1 if(1*$oldfac == 0);
my $factor = sprintf "%.2f", ($pvval / $fcnum); # Faktor reale PV / Prognose
Log3($myName, 5, "$myName - Hour: ".sprintf("%02d",$h).", Today PVreal: $pvval, PVforecast: $fcnum");
Log3($name, 5, "$name - Hour: ".sprintf("%02d",$h).", Today PVreal: $pvval, PVforecast: $fcnum");
if(abs($factor - $oldfac) > $maxvariance) {
$factor = sprintf "%.2f", ($factor > $oldfac ? $oldfac + $maxvariance : $oldfac - $maxvariance);
Log3($myName, 4, "$myName - Use new limited Variance factor: $factor for hour: $h");
Log3($name, 4, "$name - Use new limited Variance factor: $factor for hour: $h");
}
else {
Log3($myName, 4, "$myName - new Variance factor: $factor for hour: $h calculated") if($factor != $oldfac);
Log3($name, 4, "$name - new Variance factor: $factor for hour: $h calculated") if($factor != $oldfac);
}
push @da, "pvCorrectionFactor_".sprintf("%02d",$h).":".$factor." (automatic)";
}
createReadings ($myHash, \@da);
createReadings ($hash, \@da);
return;
}