diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm
index 62e27add1..bf639d0f5 100644
--- a/fhem/contrib/DS_Starter/76_SolarForecast.pm
+++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm
@@ -118,6 +118,7 @@ BEGIN {
# Versions History intern
my %vNotesIntern = (
+ "0.40.0" => "25.04.2021 change checkdwdattr, new attr follow70percentRule ",
"0.39.0" => "24.04.2021 new attr sameWeekdaysForConsfc, readings Current_SelfConsumption, Current_SelfConsumptionRate, ".
"Current_AutarkyRate ",
"0.38.3" => "21.04.2021 minor fixes in sub calcVariance, Traffic light indicator for prediction quality, some more fixes ",
@@ -434,6 +435,7 @@ sub Initialize {
# "consumerAdviceIcon ".
"cloudFactorDamping:slider,0,1,100 ".
"disable:1,0 ".
+ "follow70percentRule:1,0 ".
"forcePageRefresh:1,0 ".
"headerAlignment:center,left,right ".
"headerDetail:all,co,pv,pvco,statusLink ".
@@ -1676,12 +1678,8 @@ sub _transferDWDForecastValues {
my $type = $hash->{TYPE};
my $uac = ReadingsVal($name, "pvCorrectionFactor_Auto", "off"); # Auto- oder manuelle Korrektur
- my @aneeded = checkdwdattr ($raname,\@draattrmust);
- if (@aneeded) {
- my $err = qq{ERROR - the attribute "forecastProperties" of device "$raname" must contain: }.join ",",@aneeded;
- $paref->{state} = $err;
- Log3($name, 2, "$name - $err");
- }
+ my $err = checkdwdattr ($name,$raname,\@draattrmust);
+ $paref->{state} = $err if($err);
for my $num (0..47) {
my ($fd,$fh) = _calcDayHourMove ($chour, $num);
@@ -1755,12 +1753,8 @@ sub _transferWeatherValues {
my $fcname = ReadingsVal($name, "currentForecastDev", ""); # Weather Forecast Device
return if(!$fcname || !$defs{$fcname});
- my @aneeded = checkdwdattr ($fcname,\@dweattrmust);
- if (@aneeded) {
- my $err = qq{ERROR - the attribute "forecastProperties" of device "$fcname" must contain: }.join ",",@aneeded;
- $paref->{state} = $err;
- Log3($name, 2, "$name - $err");
- }
+ my $err = checkdwdattr ($name,$fcname,\@dweattrmust);
+ $paref->{state} = $err if($err);
my $type = $hash->{TYPE};
my ($time_str);
@@ -2418,8 +2412,8 @@ sub _calcSummaries {
my $consumption = int ($pvgen - $gfeedin + $gcon - $batin + $batout);
my $selfconsumption = int ($pvgen - $gfeedin);
my $selfconsumptionrate = 0;
- $selfconsumptionrate = sprintf("%.0f", $selfconsumption / $pvgen * 100) if($pvgen);
my $autarkyrate = 0;
+ $selfconsumptionrate = sprintf("%.0f", $selfconsumption / $pvgen * 100) if($pvgen);
$autarkyrate = sprintf("%.0f", $selfconsumption / ($selfconsumption + $gcon) * 100) if($selfconsumption);
$data{$type}{$name}{current}{consumption} = $consumption;
@@ -3548,10 +3542,13 @@ return ($ts,$tsdef,$realts);
# benötigte Attribute im DWD Device checken
################################################################
sub checkdwdattr {
+ my $name = shift;
my $dwddev = shift;
my $amref = shift;
my @fcprop = map { trim($_) } split ",", AttrVal($dwddev, "forecastProperties", "pattern");
+ my $fcr = AttrVal($dwddev, "forecastResolution", 3);
+ my $err;
my @aneeded;
for my $am (@$amref) {
@@ -3559,7 +3556,18 @@ sub checkdwdattr {
push @aneeded, $am;
}
-return @aneeded;
+ if (@aneeded) {
+ $err = qq{ERROR - device "$dwddev" -> attribute "forecastProperties" must contain: }.join ",",@aneeded;
+ }
+
+ if($fcr != 1) {
+ $err .= ", " if($err);
+ $err .= qq{ERROR - device "$dwddev" -> attribute "forecastResolution" must be set to "1"};
+ }
+
+ Log3($name, 2, "$name - $err") if($err);
+
+return $err;
}
##################################################################################################
@@ -3654,7 +3662,8 @@ sub calcPVforecast {
delete $paref->{histname};
}
- my $pvsum = 0;
+ my $pvsum = 0;
+ my $peaksum = 0; # Summe der installierten Peak Leistung
for my $st (@strings) { # für jeden String der Config ..
my $peak = $stch->{"$st"}{peak}; # String Peak (kWp)
@@ -3691,15 +3700,22 @@ sub calcPVforecast {
Log3($name, 4, "$name - PV forecast calc for $reld Hour ".sprintf("%02d",$chour+1)." string: $st ->\n$sq");
- $pvsum += $pv;
+ $pvsum += $pv;
+ $peaksum += $peak * 1000; # kWp in Wp umrechnen
}
- my $kw = AttrVal ($name, 'Wh/kWh', 'Wh');
- if($kw eq "Wh") {
- $pvsum = int $pvsum;
- }
+ my $logao = qq{};
+ if (AttrVal ($name, "follow70percentRule", 0)) {
+ my $max70 = $peaksum/100 * 70;
+ if($pvsum > $max70) {
+ $pvsum = $max70;
+ $logao = qq{(reduced by 70 percent rule)};
+ }
+ }
- Log3($name, 4, "$name - PV forecast calc for $reld Hour ".sprintf("%02d",$chour+1)." summary: $pvsum");
+ $pvsum = int $pvsum;
+
+ Log3($name, 4, "$name - PV forecast calc for $reld Hour ".sprintf("%02d",$chour+1)." summary: $pvsum ".$logao);
return $pvsum;
}
@@ -5153,6 +5169,12 @@ verfügbare Globalstrahlung ganz spezifisch in elektrische Energie umgewandelt.
Aktiviert/deaktiviert das Device.
+
+
+