diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm
index c445679b9..e457ba93a 100644
--- a/fhem/contrib/DS_Starter/76_SolarForecast.pm
+++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm
@@ -38,6 +38,7 @@ eval "use JSON;1;" or my $jsonabs = "JSON"; ## no critic 'eval' #
use FHEM::SynoModules::SMUtils qw( evaljson
moduleVersion
+ addCHANGED
trim
); # Hilfsroutinen Modul
@@ -117,6 +118,7 @@ BEGIN {
# Versions History intern
my %vNotesIntern = (
+ "0.35.0" => "12.04.2021 create additional PVforecast events - PV forecast until the end of the coming day ",
"0.34.1" => "11.04.2021 further improvement of cloud dependent calculation autocorrection ",
"0.34.0" => "10.04.2021 only hours with the same cloud cover range are considered for pvCorrection, some fixes ",
"0.33.0" => "09.04.2021 new setter currentBatteryDev, bugfix in _transferMeterValues ",
@@ -348,7 +350,7 @@ my $defslidenum = 3;
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 $calcmaxd = 21; # Anzahl Tage (default) für Durchschnittermittlung zur Vorhersagekorrektur
+my $calcmaxd = 21; # Anzahl Tage (default) für Berechnung Vorhersagekorrektur
my @dwdattrmust = qw(Rad1h TTT Neff R101 ww SunUp SunRise SunSet); # Werte die im Attr forecastProperties des DWD_Opendata Devices mindestens gesetzt sein müssen
my $whistrepeat = 900; # Wiederholungsintervall Schreiben historische Daten
@@ -1525,9 +1527,10 @@ sub _additionalActivities {
my $name = $paref->{name};
my $chour = $paref->{chour};
my $daref = $paref->{daref};
- my $t = $paref->{t}; # Epoche Zeit
+ my $t = $paref->{t}; # Epoche Zeit
- my $date = strftime "%Y-%m-%d", localtime($t); # aktuelles Datum
+ my $type = $hash->{TYPE};
+ my $date = strftime "%Y-%m-%d", localtime($t); # aktuelles Datum
my ($ts,$ts1,$pvfc,$pvrl,$gcon);
@@ -1542,24 +1545,40 @@ sub _additionalActivities {
$gcon = ReadingsNum($name, "Today_Hour".sprintf("%02d",$chour)."_GridConsumption", 0);
push @$daref, "LastHourGridconsumptionReal<>".$gcon." Wh<>".$ts1;
- my $tlim = "00"; # bestimmte Aktionen
+ ## zusätzliche Events erzeugen - PV Vorhersage bis Ende des kommenden Tages
+ #############################################################################
+ for my $idx (sort keys %{$data{$type}{$name}{nexthours}}) {
+ my $nhts = NexthoursVal ($hash, $idx, "starttime", undef);
+ my $nhfc = NexthoursVal ($hash, $idx, "pvforecast", undef);
+ next if(!defined $nhts || !defined $nhfc);
+
+ my ($dt, $h) = $nhts =~ /([\w-]+)\s(\d{2})/xs;
+ addCHANGED ($hash, "PVforecast: ".$nhfc, $dt." ".$h.":59:59");
+ }
+
+ DoTrigger($name, undef, 1);
+
+ ## bestimmte einmalige Aktionen
+ ##################################
+ my $tlim = "00";
if($chour =~ /^($tlim)$/x) {
if(!exists $hash->{HELPER}{H00DONE}) {
$date = strftime "%Y-%m-%d", localtime($t-7200); # Vortag (2 h Differenz reichen aus)
$ts = $date." 23:59:59";
$pvfc = ReadingsNum($name, "Today_Hour24_PVforecast", 0);
- push @$daref, "LastHourPVforecast<>".$pvfc."<>".$ts1;
+ push @$daref, "LastHourPVforecast<>".$pvfc."<>".$ts;
$pvrl = ReadingsNum($name, "Today_Hour24_PVreal", 0);
- push @$daref, "LastHourPVreal<>".$pvrl."<>".$ts1;
+ push @$daref, "LastHourPVreal<>".$pvrl."<>".$ts;
$gcon = ReadingsNum($name, "Today_Hour24_GridConsumption", 0);
- push @$daref, "LastHourGridconsumptionReal<>".$gcon."<>".$ts1;
+ push @$daref, "LastHourGridconsumptionReal<>".$gcon."<>".$ts;
deleteReadingspec ($hash, "Today_Hour.*_Grid.*");
deleteReadingspec ($hash, "Today_Hour.*_PV.*");
deleteReadingspec ($hash, "powerTrigger_.*");
+ deleteReadingspec ($hash, "pvCorrectionFactor_.*_autocalc");
delete $hash->{HELPER}{INITETOTAL};
delete $hash->{HELPER}{INITCONTOTAL};
@@ -1625,15 +1644,12 @@ sub _transferDWDForecastValues {
my $calcpv = calcPVforecast ($params); # Vorhersage gewichtet kalkulieren
- $time_str = "NextHour".sprintf "%02d", $num;
- $epoche = $t + (3600*$num);
- my ($ta,$realts) = TimeAdjust ($epoche);
-
- # push @$daref, "CurrentHourPVforecast<>".$calcpv." Wh<>".$realts if($num == 0);
- #push @$daref, "${time_str}_Time<>" .$ta;
+ $time_str = "NextHour".sprintf "%02d", $num;
+ $epoche = $t + (3600*$num);
+ my ($ta,$tsdef,$realts) = TimeAdjust ($epoche);
$data{$type}{$name}{nexthours}{$time_str}{pvforecast} = $calcpv;
- $data{$type}{$name}{nexthours}{$time_str}{starttime} = $ta;
+ $data{$type}{$name}{nexthours}{$time_str}{starttime} = $tsdef;
$data{$type}{$name}{nexthours}{$time_str}{Rad1h} = $rad; # nur Info: original Vorhersage Strahlungsdaten
if($num < 23 && $fh < 24) { # Ringspeicher PV forecast Forum: https://forum.fhem.de/index.php/topic,117864.msg1133350.html#msg1133350
@@ -2640,16 +2656,10 @@ sub forecastGraphic {
##########################
# Werte aktuelle Stunde
##########################
-
- my $thishour;
- my $month;
- my $year;
- my $day_str;
my $day;
- my $t = NexthoursVal ($hash, "NextHour00", "starttime", AttrVal('global', 'language', '') eq 'DE' ? '00.00.0000 24' : '0000-00-00 24');
- ($year,$month,$day_str,$thishour) = $t =~ m/(\d{4})-(\d{2})-(\d{2})\s(\d{2})/x;
- ($day_str,$month,$year,$thishour) = $t =~ m/(\d{2}).(\d{2}).(\d{4})\s(\d{2})/x if (AttrVal('global', 'language', '') eq 'DE');
+ my $t = NexthoursVal ($hash, "NextHour00", "starttime", '0000-00-00 24');
+ my ($year,$month,$day_str,$thishour) = $t =~ m/(\d{4})-(\d{2})-(\d{2})\s(\d{2})/x;
$thishour++;
@@ -3266,16 +3276,17 @@ sub TimeAdjust {
my ($sec,$min,$hour,$day,$mon,$year) = (localtime(time))[0,1,2,3,4,5]; # Standard f. z.B. Readingstimstamp
$year += 1900;
$mon++;
- my $realts = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year,$mon,$day,$hour,$min,$sec);
+ my $realts = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year,$mon,$day,$hour,$min,$sec);
+ my $tsdef = sprintf("%04d-%02d-%02d %02d:%s", $lyear,$lmonth,$lday,$lhour,"00:00"); # engl. Variante für Logging-Timestamps etc.
if(AttrVal("global","language","EN") eq "DE") {
$ts = sprintf("%02d.%02d.%04d %02d:%s", $lday,$lmonth,$lyear,$lhour,"00:00");
}
else {
- $ts = sprintf("%04d-%02d-%02d %02d:%s", $lyear,$lmonth,$lday,$lhour,"00:00");
+ $ts = $tsdef;
}
-return ($ts,$realts);
+return ($ts,$tsdef,$realts);
}
################################################################
@@ -3370,7 +3381,9 @@ sub calcPVforecast {
$hcfound = "no - use raw correction factor";
$hc = $pvcorr; # nutze RAW-Korrekturfaktor
}
- }
+ }
+
+ $data{$type}{$name}{nexthours}{"NextHour".sprintf("%02d",$num)}{pvcorrf} = $hc;
my $pvsum = 0;
@@ -3440,12 +3453,6 @@ sub calcVariance {
return;
}
- my $tlim = "00"; # Stunde 00 -> löschen aller Autocalc Statusreadings des Tages
-
- if($chour =~ /^($tlim)$/x) {
- deleteReadingspec ($hash, "pvCorrectionFactor_.*_autocalc");
- }
-
my $idts = ReadingsTimestamp($name, "currentInverterDev", ""); # Definitionstimestamp des Inverterdevice
return if(!$idts);
@@ -3796,14 +3803,15 @@ sub listDataPool {
return qq{NextHours cache is empty.};
}
for my $idx (sort keys %{$h}) {
- my $nhts = NexthoursVal ($hash, $idx, "starttime", "-");
- my $nhfc = NexthoursVal ($hash, $idx, "pvforecast", "-");
- my $wid = NexthoursVal ($hash, $idx, "weatherid", "-");
- my $neff = NexthoursVal ($hash, $idx, "cloudcover", "-");
- my $r101 = NexthoursVal ($hash, $idx, "rainprob", "-");
- my $rad1h = NexthoursVal ($hash, $idx, "Rad1h", "-");
- $sq .= "\n" if($sq);
- $sq .= $idx." => starttime: $nhts, pvforecast: $nhfc, weatherid: $wid, cloudcover: $neff, rainprob: $r101, Rad1h: $rad1h";
+ my $nhts = NexthoursVal ($hash, $idx, "starttime", "-");
+ my $nhfc = NexthoursVal ($hash, $idx, "pvforecast", "-");
+ my $wid = NexthoursVal ($hash, $idx, "weatherid", "-");
+ my $neff = NexthoursVal ($hash, $idx, "cloudcover", "-");
+ my $r101 = NexthoursVal ($hash, $idx, "rainprob", "-");
+ my $rad1h = NexthoursVal ($hash, $idx, "Rad1h", "-");
+ my $pvcorrf = NexthoursVal ($hash, $idx, "pvcorrf", "-");
+ $sq .= "\n" if($sq);
+ $sq .= $idx." => starttime: $nhts, pvfc: $nhfc, wid: $wid, wcc: $neff, correff: $pvcorrf, wrp: $r101, Rad1h: $rad1h";
}
}
@@ -4196,7 +4204,7 @@ verfügbare Globalstrahlung ganz spezifisch in elektrische Energie umgewandelt.
pvfc | erwartete PV Erzeugung |
wid | ID des vorhergesagten Wetters |
wcc | vorhergesagter Grad der Bewölkung |
correff | effektiv verwendeter Korrekturfaktor abhängig vom vorhergesagten Grad der Bewölkung |
wrp | vorhergesagter Grad der Regenwahrscheinlichkeit |
Rad1h | vorhergesagte Globalstrahlung |