diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm index 0f9154637..8d8f19474 100644 --- a/fhem/contrib/DS_Starter/76_SolarForecast.pm +++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm @@ -160,6 +160,7 @@ BEGIN { # Versions History intern my %vNotesIntern = ( + "1.58.3" => "16.09.2025 __batChargeOptTargetPower: minor code change, consider bpinmax ", "1.58.2" => "11.09.2025 __batChargeOptTargetPower: a lot of Code improvements, Attr flowGraphicControl->shiftx: unrestrict possible values ", "1.58.1" => "08.09.2025 edit comref, ctrlBatSocManagementXX->safetyMargin: Separate specification of surcharges for calculation of load ". "clearance and performance optimization ", @@ -1088,8 +1089,8 @@ my %htitles = ( DE => qq{SoC Prognose} }, socbaths => { EN => qq{SoC at the end of the hour}, DE => qq{SoC am Ende der Stunde} }, - lcactive => { EN => qq{Charge management activated}, - DE => qq{Lademanagement aktiviert} }, + lcready => { EN => qq{Charge management ready}, + DE => qq{Lademanagement bereit} }, bcharrel => { EN => qq{Charging release (activate release for charging the battery if necessary)}, DE => qq{Ladefreigabe (evtl. Freigabe zum Laden der Batterie aktivieren)} }, bncharel => { EN => qq{only charge if the feed-in limit is exceeded}, @@ -11825,6 +11826,7 @@ sub _batChargeMgmt { $hsurp->{$hod}{$bn}{whneedmanaged} = $whneed; # benötigte Ladeenergie Batterie x gemäß Ladesteuerung $hsurp->{$hod}{$bn}{socwh} = $socwh; $hsurp->{$hod}{$bn}{batinstcap} = $batinstcap; + $hsurp->{$hod}{$bn}{bpinmax} = $bpinmax; # max. mögliche Ladeleistung $hsurp->{$hod}{$bn}{otpMargin} = $otpMargin; # Sicherheitszuschlag für Berechnungen } @@ -11890,7 +11892,7 @@ return; ################################################################ # Erstellung Optimum Ladeleistung für jede Batterie # (Erreichung des max. möglichen SoC mit möglichst geringer -# Ladeleistung verteilt über die Tagstunden mit PV-Überschuß) +# Ladeleistung verteilt über die Tagstunden mit PV-Überschuß) ################################################################ sub __batChargeOptTargetPower { my $paref = shift; @@ -11919,7 +11921,7 @@ sub __batChargeOptTargetPower { my $bpinreduced = BatteryVal ($name, $sbn, 'bpinreduced', 0); # Standardwert wenn z.B. kein Überschuß oder Zwangsladung vom Grid - if (!$spls) { # auf kleine Sollladeleistung setzen wenn kein Überschuß + if (!$spls) { # auf kleine Sollladeleistung setzen wenn kein Überschuß $hsurp->{$shod}{$sbn}{pneedmin} = $bpinreduced; storeReading ('Battery_ChargeOptTargetPower_'.$sbn, $bpinreduced.' W') if($hsurp->{$shod}{nhr} eq '00'); next; @@ -11934,20 +11936,23 @@ sub __batChargeOptTargetPower { my $margin = defined $otpMargin ? $otpMargin : SFTYMARGIN_20; $needraw *= 1 + ($margin / 100); # Sicherheitsaufschlag - if ($spls - $needraw > $fipl) { # Einspeiselimit berücksichtigen - $needraw += ($spls - $needraw) - $fipl; - } + #if ($spls - $needraw > $fipl) { # Einspeiselimit berücksichtigen + # $needraw += ($spls - $needraw) - $fipl; + #} $needraw = max (0, $needraw); $hsurp->{$shod}{$sbn}{runwh} = sprintf "%.0f", $runwh; $hsurp->{$shod}{$sbn}{sphrs} = $sphrs; # Reststunden mit diesem Überschuß - $hsurp->{$shod}{$sbn}{pneedmin} = sprintf "%.0f", $spls > $needraw ? # Mindestladeleistung bzw. Energie bei 1h (Wh) + my $pneedmin = sprintf "%.0f", $spls > $needraw ? # Mindestladeleistung bzw. Energie bei 1h (Wh) $needraw ? $needraw : $bpinreduced : - $spls; + $spls; + $hsurp->{$shod}{$sbn}{pneedmin} = min ($pneedmin, $hsurp->{$shod}{$sbn}{bpinmax}); # Begrenzung auf max. mögliche Batterieleistung + + #$hsurp->{$shod}{$sbn}{pneedmin} = sprintf "%.0f", ($needraw ? $needraw : $bpinreduced); # Mindestladeleistung bzw. Energie bei 1h (Wh) my $newshod = sprintf "%02d", (int $shod + 1); - $hsurp->{$newshod}{$sbn}{fcnextwh} = $runwh + $hsurp->{$shod}{$sbn}{pneedmin} if(defined $hsurp->{$newshod}); - $otp->{$sbn}{target} = $hsurp->{$shod}{$sbn}{pneedmin} if($hsurp->{$shod}{nhr} eq '00'); + $hsurp->{$newshod}{$sbn}{fcnextwh} = $runwh + $hsurp->{$shod}{$sbn}{pneedmin} if(defined $hsurp->{$newshod}); + $otp->{$sbn}{target} = $hsurp->{$shod}{$sbn}{pneedmin} if($hsurp->{$shod}{nhr} eq '00'); if ($hsurp->{$shod}{$sbn}{pneedmin} < INFINITE) { my $maxneed = $otp->{$sbn}{maxneed} // 0; @@ -11967,20 +11972,31 @@ sub __batChargeOptTargetPower { my $target = $otp->{$bn}{target}; next if(!defined $target); - my $avg = 0; - my $mv = $otp->{$bn}{maxvals} // 0; - my $sn = $otp->{$bn}{sumneed} // 0; - $avg = sprintf "%.0f", ($sn / $mv) if($mv); - $target = max ($avg, $target); + my $avg = 0; + my $mv = $otp->{$bn}{maxvals} // 0; + my $sn = $otp->{$bn}{sumneed} // 0; + $avg = sprintf "%.0f", ($sn / $mv) if($mv); + $target = max ($avg, $target); + + my $gfeedin = CurrentVal ($name, 'gridfeedin', 0); # aktuelle Netzeinspeisung + my $bpin = CurrentVal ($name, 'batpowerinsum', 0); # aktuelle Batterie Ladeleistung (Summe über alle Batterien) + my $inc = 0; + + if ( !$bpin && $gfeedin > $fipl ) {$inc = $gfeedin - $fipl} # Ladefreigabe wenn akt. keine Bat-Ladung UND akt. Einspeisung > Einspeiselimit der Anlage + if ( $bpin && ($gfeedin - $bpin) > $fipl ) {$inc = $bpin + (($gfeedin - $bpin) - $fipl)} # Ladefreigabe wenn akt. Bat-Ladung UND Eispeisung - Bat-Ladung > Einspeiselimit der Anlage + + if ($inc) { # Einspeiselimit berücksichtigen + $target = max ($target, $inc); + } $otp->{$bn}{target} = $target; + storeReading ('Battery_ChargeOptTargetPower_'.$bn, $target.' W'); + if ($paref->{debug} =~ /batteryManagement/) { my $mn = $otp->{$bn}{maxneed} // 0; Log3 ($name, 1, "$name DEBUG> ChargeOTP - max OTP Bat $bn: $mn W, sum need: $sn Wh, number hrs: $mv, average: $avg W"); } - - storeReading ('Battery_ChargeOptTargetPower_'.$bn, $target.' W'); } if ($paref->{debug} =~ /batteryManagement/) { @@ -11997,10 +12013,11 @@ sub __batChargeOptTargetPower { my $otpMargin = $hsurp->{$k}{$bat}{otpMargin}; my $margin = defined $otpMargin ? $otpMargin : SFTYMARGIN_20; my $spls = int $hsurp->{$k}{spswh}; - my $needmin = $hsurp->{$k}{$bat}{pneedmin}; + my $needmin = $hsurp->{$k}{$bat}{pneedmin} // 0; - if ($hsurp->{$k}{nhr} eq '00') { # Target für aktuelle Stunde - $needmin = max ($needmin, $otp->{$bat}{target}); + if ($hsurp->{$k}{nhr} eq '00') { # Target für aktuelle Stunde + my $target = $otp->{$bat}{target} // 0; + $needmin = max ($needmin, $target); } Log3 ($name, 1, "$name DEBUG> Bat $bat ChargeOTP - hod: $k, Start SoC: $ssoc Wh, Surplus: $spls Wh $sphrs, OTP: $needmin W, safety: $margin %"); @@ -19186,7 +19203,7 @@ sub __substituteIcon { } } - $pretxt .= "\n".$htitles{lcactive}{$lang}.": ".(defined $msg2 ? ($msg2 == 1 ? $htitles{simplyes}{$lang} : $htitles{simpleno}{$lang}) : '-'); + $pretxt .= "\n".$htitles{lcready}{$lang}.": ".(defined $msg2 ? ($msg2 == 1 ? $htitles{simplyes}{$lang} : $htitles{simpleno}{$lang}) : '-'); if (defined $pcurr) { # aktueller Zustand if ($pcurr > 0) { # Batterie wird aufgeladen @@ -26856,9 +26873,9 @@ to ensure that the system configuration is correct.