diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm index e1f779bb5..96dda2f4c 100644 --- a/fhem/contrib/DS_Starter/76_SolarForecast.pm +++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm @@ -160,9 +160,9 @@ BEGIN { # Versions History intern my %vNotesIntern = ( - "1.58.6" => "01.10.2025 __batChargeMgmt code changed, new sub ___batChargeSaveResults, remove reading Battery_ChargeRecommended_XX ". + "1.58.6" => "03.10.2025 __batChargeMgmt code changed, new sub ___batChargeSaveResults, remove reading Battery_ChargeRecommended_XX ". "_calcReadingsTomorrowPVFc: bugfix generating readings of tomorrow ". - "__batChargeOptTargetPower: complete rework, Attr ctrlBatSocManagementXX new key 'loadStrategy' ", + "__batChargeOptTargetPower: complete rework, Attr ctrlBatSocManagementXX new keys 'loadStrategy', 'weightOwnUse' ", "1.58.5" => "24.09.2025 __batChargeOptTargetPower: fix if battery load control is deactivated ", "1.58.4" => "23.09.2025 __batChargeOptTargetPower: user a better surplus value, excess based on average removed & some other code optimization ", "1.58.3" => "17.09.2025 __batChargeOptTargetPower: minor code change, consider bpinmax & lcintime ", @@ -7526,6 +7526,7 @@ sub _attrBatSocManagement { ## no critic "not used" loadAbort => { comp => '(?:100|[1-9]?[0-9]):\d+(?::(?:100|[1-9]?[0-9]))?', must => 0, act => 0 }, safetyMargin => { comp => '(?:100|[1-9]?\d)(?::(?:100|[1-9]?\d))?', must => 0, act => 0 }, loadStrategy => { comp => '(loadRelease|optPower)', must => 0, act => 0 }, + weightOwnUse => { comp => '(?:100|[1-9]?\d)(?::(?:100|[1-9]?\d))?', must => 0, act => 0 }, }; my ($a, $h) = parseParams ($aVal); @@ -11534,9 +11535,9 @@ sub __parseAttrBatSoc { my $name = shift; my $cgbt = shift // return; - my ($urMargin, $otpMargin); + my ($lrMargin, $otpMargin); my ($pa, $ph) = parseParams ($cgbt); - ($urMargin, $otpMargin) = split ':', $ph->{safetyMargin} if(defined $ph->{safetyMargin}); + ($lrMargin, $otpMargin) = split ':', $ph->{safetyMargin} if(defined $ph->{safetyMargin}); my $parsed = { lowSoc => $ph->{lowSoc}, @@ -11545,8 +11546,9 @@ sub __parseAttrBatSoc { careCycle => $ph->{careCycle} // CARECYCLEDEF, # Ladungszyklus (Maintenance) für maxSoC in Tagen lcslot => $ph->{lcSlot}, loadAbort => $ph->{loadAbort}, - loadStrategy => $ph->{loadStrategy}, - urMargin => $urMargin, + loadStrategy => $ph->{loadStrategy}, + weightOwnUse => $ph->{weightOwnUse}, + lrMargin => $lrMargin, otpMargin => $otpMargin, }; @@ -11649,35 +11651,38 @@ sub _batChargeMgmt { next; } - my $maxfctim = timestringToTimestamp (ReadingsVal ($name, 'Today_MaxPVforecastTime', '')) // $t; - my $rodpvfc = ReadingsNum ($name, 'RestOfDayPVforecast', 0); # PV Prognose Rest des Tages - my $tompvfc = ReadingsNum ($name, 'Tomorrow_PVforecast', 0); # PV Prognose nächster Tag - my $tomconfc = ReadingsNum ($name, 'Tomorrow_ConsumptionForecast', 0); # Verbrauchsprognose nächster Tag - my $batoptsoc = ReadingsNum ($name, 'Battery_OptimumTargetSoC_'.$bn, 0); # aktueller optimierter SoC - my $confcss = CurrentVal ($name, 'tdConFcTillSunset', 0); # Verbrauchsprognose bis Sonnenuntergang - my $csoc = BatteryVal ($name, $bn, 'bcharge', 0); # aktuelle Ladung in % - my $csocwh = BatteryVal ($name, $bn, 'bchargewh', 0); # aktuelle Ladung in Wh - my $bpinmax = BatteryVal ($name, $bn, 'bpinmax', INFINITE); # max. mögliche Ladeleistung W - my $bpoutmax = BatteryVal ($name, $bn, 'bpoutmax', INFINITE); # max. mögliche Entladeleistung W - my $bpowerin = BatteryVal ($name, $bn, 'bpowerin', INFINITE); # aktuelle Ladeleistung W - my $cgbt = AttrVal ($name, 'ctrlBatSocManagement'.$bn, undef); - my $sf = __batCapShareFactor ($hash, $bn); # Anteilsfaktor der Batterie XX Kapazität an Gesamtkapazität - my $strategy = 'loadRelease'; # 'loadRelease' oder 'optPower' - my $lowSoc = 0; - my $loadAbort = ''; - my ($lcslot, $urMargin, $otpMargin); + my $maxfctim = timestringToTimestamp (ReadingsVal ($name, 'Today_MaxPVforecastTime', '')) // $t; + my $rodpvfc = ReadingsNum ($name, 'RestOfDayPVforecast', 0); # PV Prognose Rest des Tages + my $tompvfc = ReadingsNum ($name, 'Tomorrow_PVforecast', 0); # PV Prognose nächster Tag + my $tomconfc = ReadingsNum ($name, 'Tomorrow_ConsumptionForecast', 0); # Verbrauchsprognose nächster Tag + my $batoptsoc = ReadingsNum ($name, 'Battery_OptimumTargetSoC_'.$bn, 0); # aktueller optimierter SoC + my $confcss = CurrentVal ($name, 'tdConFcTillSunset', 0); # Verbrauchsprognose bis Sonnenuntergang + my $csoc = BatteryVal ($name, $bn, 'bcharge', 0); # aktuelle Ladung in % + my $csocwh = BatteryVal ($name, $bn, 'bchargewh', 0); # aktuelle Ladung in Wh + my $bpinmax = BatteryVal ($name, $bn, 'bpinmax', INFINITE); # max. mögliche Ladeleistung W + my $bpoutmax = BatteryVal ($name, $bn, 'bpoutmax', INFINITE); # max. mögliche Entladeleistung W + my $bpowerin = BatteryVal ($name, $bn, 'bpowerin', INFINITE); # aktuelle Ladeleistung W + my $bpinreduced = BatteryVal ($name, $bn, 'bpinreduced', 0); # Standardwert bei <=lowSoC -> Anforderungsladung vom Grid + my $cgbt = AttrVal ($name, 'ctrlBatSocManagement'.$bn, undef); + my $sf = __batCapShareFactor ($hash, $bn); # Anteilsfaktor der Batterie XX Kapazität an Gesamtkapazität + my $strategy = 'loadRelease'; # 'loadRelease' oder 'optPower' + my $wou = 0; # Gewichtung Prognose-Verbrauch als Anteil "Eigennutzung" (https://forum.fhem.de/index.php?msg=1348429) + my $lowSoc = 0; + my $loadAbort = ''; + my $lrMargin = SFTYMARGIN_50; + my $otpMargin = SFTYMARGIN_20; + my $lcslot; if ($cgbt) { my $parsed = __parseAttrBatSoc ($name, $cgbt); - $lowSoc = $parsed->{lowSoc} // 0; + $lowSoc = $parsed->{lowSoc} // 0; $lcslot = $parsed->{lcslot}; $loadAbort = $parsed->{loadAbort}; - $urMargin = $parsed->{urMargin}; - $otpMargin = $parsed->{otpMargin}; + $lrMargin = $parsed->{lrMargin} // $lrMargin; # Sicherheitszuschlag LR (%) + $otpMargin = $parsed->{otpMargin} // $otpMargin; # Sicherheitszuschlag OTP (%) $strategy = $parsed->{loadStrategy} // $strategy; + $wou = $parsed->{weightOwnUse} // $wou; } - - my $margin = defined $urMargin ? $urMargin : SFTYMARGIN_50; # Sicherheitszuschlag (%) ## generelle Ladeabbruchbedingung evaluieren ############################################## @@ -11717,7 +11722,8 @@ sub _batChargeMgmt { Log3 ($name, 1, "$name DEBUG> Bat $bn ChargeMgmt - control time Slot - Slot start: $lcstart, Slot end: $lcend"); Log3 ($name, 1, "$name DEBUG> Bat $bn ChargeMgmt - Installed Battery capacity: $batinstcap Wh, Percentage of total capacity: ".(sprintf "%.1f", $sf*100)." %"); Log3 ($name, 1, "$name DEBUG> Bat $bn ChargeMgmt - The PV generation, consumption and surplus listed below are based on the battery's share of total installed capacity!"); - Log3 ($name, 1, "$name DEBUG> Bat $bn ChargeLR - used safety margin: $margin %"); + Log3 ($name, 1, "$name DEBUG> Bat $bn ChargeLR - used safety margin: $lrMargin %"); + Log3 ($name, 1, "$name DEBUG> Bat $bn ChargeLR - weighted self-consumption: $wou %"); } ## Auswertung für jede kommende Stunde @@ -11782,56 +11788,63 @@ sub _batChargeMgmt { } $spday = 0 if($spday < 0); # PV Überschuß Prognose bis Sonnenuntergang + $confc *= (100 - $wou) / 100 if($pvfc > 0); # Gewichtung Prognose-Verbrauch als Anteil "Eigennutzung" (https://forum.fhem.de/index.php?msg=1348429) my $surpls = sprintf "%.0f", ($pvfc - $confc); # PV-Überschuß der Stunde, wichtig keine Nachkommastellen! ## Steuerung nach Ladefreigabe ################################ - if ( $whneed * (1 + ($margin / 100)) >= $spday ) {$crel = 1} # Ladefreigabe wenn benötigte Ladeenergie >= Restüberschuß des Tages zzgl. Sicherheitsaufschlag - if ( !$num && ($pvCu - $curcon) >= $inplim ) {$crel = 1} # Ladefreigabe wenn akt. PV Leistung - Abschläge >= WR-Leistungsbegrenzung - if ( !$bpin && $gfeedin > $feedinlim ) {$crel = 1} # V 1.49.6 Ladefreigabe wenn akt. keine Bat-Ladung UND akt. Einspeisung > Einspeiselimit der Anlage - if ( $bpin && ($gfeedin - $bpin) > $feedinlim ) {$crel = 1} # V 1.49.6 Ladefreigabe wenn akt. Bat-Ladung UND Eispeisung - Bat-Ladung > Einspeiselimit der Anlage - if ( !$cgbt ) {$crel = 1} # Ladefreigabe wenn kein BatSoc-Management - if ( !$lcintime ) {$crel = 1} # Ladefreigabe wenn nicht innerhalb Zeitslot für Ladesteuerung - if ( $labortCond ) {$crel = 0} # keine Ladefreigabe bei genereller Abbruchbedingung + if ( $whneed * (1 + ($lrMargin / 100)) >= $spday ) {$crel = 1} # Ladefreigabe wenn benötigte Ladeenergie >= Restüberschuß des Tages zzgl. Sicherheitsaufschlag + if ( !$num && ($pvCu - $curcon) >= $inplim ) {$crel = 1} # Ladefreigabe wenn akt. PV Leistung - Abschläge >= WR-Leistungsbegrenzung + if ( !$bpin && $gfeedin > $feedinlim ) {$crel = 1} # V 1.49.6 Ladefreigabe wenn akt. keine Bat-Ladung UND akt. Einspeisung > Einspeiselimit der Anlage + if ( $bpin && ($gfeedin - $bpin) > $feedinlim ) {$crel = 1} # V 1.49.6 Ladefreigabe wenn akt. Bat-Ladung UND Eispeisung - Bat-Ladung > Einspeiselimit der Anlage + if ( !$cgbt ) {$crel = 1} # Ladefreigabe wenn kein BatSoc-Management + if ( !$lcintime ) {$crel = 1} # Ladefreigabe wenn nicht innerhalb Zeitslot für Ladesteuerung + if ( $labortCond ) {$crel = 0} # keine Ladefreigabe bei genereller Abbruchbedingung # Steuerhash für optimimierte Ladeleistung erstellen ###################################################### my $surplswh = max (0, $surpls); if ($strategy eq 'optPower' || $strategy eq 'loadRelease' && $today) { # bei loadRelease' nur den aktuellen Tag betrachten - $hsurp->{$fd}{$hod}{nhr} = $nhr; - $hsurp->{$fd}{$hod}{speff} = $surpls; # effektiver PV Überschuß bzw. effektiver Verbrauch wenn < 0 - $hsurp->{$fd}{$hod}{surplswh} = $surplswh.'.'.$hod; # absoluter Überschuß in Wh der Stunde mit Sortierhilfe - $hsurp->{$fd}{$hod}{$bn}{spday} = $spday; # (Rest)PV-Überschuß am laufenden Tag - $hsurp->{$fd}{$hod}{$bn}{initsocwh} = $socwh; - $hsurp->{$fd}{$hod}{$bn}{batinstcap} = $batinstcap; # installierte Batteriekapazität (Wh) - $hsurp->{$fd}{$hod}{$bn}{bpinmax} = $bpinmax; # max. mögliche Ladeleistung - $hsurp->{$fd}{$hod}{$bn}{bpoutmax} = $bpoutmax; # max. mögliche Entladeleistung - $hsurp->{$fd}{$hod}{$bn}{lowSocwh} = $lowSocwh; # eingestellter lowSoC in Wh - $hsurp->{$fd}{$hod}{$bn}{csocwh} = $csocwh; # aktueller SoC in Wh - $hsurp->{$fd}{$hod}{$bn}{otpMargin} = $otpMargin; # Sicherheitszuschlag für Berechnungen - $hsurp->{$fd}{$hod}{$bn}{lcintime} = $lcintime; # Ladesteuerung "In Time" oder "nicht In Time" - $hsurp->{$fd}{$hod}{$bn}{stt} = $stt; # Day/Time für Debuglog - $hsurp->{$fd}{$hod}{$bn}{strategy} = $strategy; # Ladestrategie + $hsurp->{$fd}{$hod}{nhr} = $nhr; + $hsurp->{$fd}{$hod}{speff} = $surpls; # effektiver PV Überschuß bzw. effektiver Verbrauch wenn < 0 + $hsurp->{$fd}{$hod}{surplswh} = $surplswh.'.'.$hod; # absoluter Überschuß in Wh der Stunde mit Sortierhilfe + $hsurp->{$fd}{$hod}{$bn}{spday} = $spday; # (Rest)PV-Überschuß am laufenden Tag + $hsurp->{$fd}{$hod}{$bn}{initsocwh} = $socwh; + $hsurp->{$fd}{$hod}{$bn}{batinstcap} = $batinstcap; # installierte Batteriekapazität (Wh) + $hsurp->{$fd}{$hod}{$bn}{bpinmax} = $bpinmax; # max. mögliche Ladeleistung + $hsurp->{$fd}{$hod}{$bn}{bpinreduced} = $bpinreduced; # Standardwert bei <=lowSoC -> Anforderungsladung vom Grid + $hsurp->{$fd}{$hod}{$bn}{bpoutmax} = $bpoutmax; # max. mögliche Entladeleistung + $hsurp->{$fd}{$hod}{$bn}{lowSocwh} = $lowSocwh; # eingestellter lowSoC in Wh + $hsurp->{$fd}{$hod}{$bn}{batoptsocwh} = $batoptsocwh; # optimaler SoC in Wh + $hsurp->{$fd}{$hod}{$bn}{csocwh} = $csocwh; # aktueller SoC in Wh + $hsurp->{$fd}{$hod}{$bn}{otpMargin} = $otpMargin; # Sicherheitszuschlag für Berechnungen + $hsurp->{$fd}{$hod}{$bn}{lcintime} = $lcintime; # Ladesteuerung "In Time" oder "nicht In Time" + $hsurp->{$fd}{$hod}{$bn}{stt} = $stt; # Day/Time für Debuglog + $hsurp->{$fd}{$hod}{$bn}{strategy} = $strategy; # Ladestrategie + $hsurp->{$fd}{$hod}{$bn}{weightOwnUse} = $wou; # Gewichtung Prognose-Verbrauch als Anteil "Eigennutzung" (https://forum.fhem.de/index.php?msg=1348429) } ## SOC-Prognose LR #################### my $speff = $surpls; # effektiver PV Überschuß bzw. effektiver Verbrauch wenn < 0 - $speff = $speff > 0 ? ($speff >= $bpinmax ? $bpinmax : $speff) : - $speff < 0 ? ($speff <= $bpoutmax * -1 ? $bpoutmax * -1 : $speff) : - $speff; + $speff = $speff > 0 ? ($speff >= $bpinmax ? $bpinmax : $speff) : + $speff < 0 ? ($speff <= -$bpoutmax ? -$bpoutmax : $speff) : + $speff; + + my $delta = $speff > 0 ? ($crel ? $speff * STOREFFDEF : 0) : # PV Überschuß (d.h. Aufladung) nur einbeziehen wenn Ladefreigabe + $speff < 0 ? $speff / STOREFFDEF : # Verbrauch einbeziehen + 0; - $socwh += $crel ? ($speff > 0 ? $speff * STOREFFDEF : $speff / STOREFFDEF) : - ($speff > 0 ? 0 : $speff / STOREFFDEF); # PV Überschuß (d.h. Aufladung) nur einbeziehen wenn Ladefreigabe + $socwh += $delta; - $socwh = $socwh < $lowSocwh ? $lowSocwh : - $socwh < $batoptsocwh ? $batoptsocwh : # SoC Prognose in Wh + $socwh = $socwh < $lowSocwh ? $lowSocwh : # SoC begrenzen + $socwh < $batoptsocwh ? $batoptsocwh : $socwh > $batinstcap ? $batinstcap : $socwh; - $socwh = sprintf "%.0f", $socwh; + $socwh = sprintf "%.0f", $socwh; # SoC Prognose in Wh $progsoc = sprintf "%.1f", (100 * $socwh / $batinstcap); # Prognose SoC in % ## Debuglog LR @@ -11897,6 +11910,9 @@ sub _batChargeMgmt { for my $bat (sort @batteries) { my $ssocwh = $hopt->{$shod}{$bat}{runwh} // '-'; + + ## SOC-Prognose OTP + ##################### my $fcendwh = $hopt->{$shod}{$bat}{fcendwh} // 0; $progsoc = sprintf "%.1f", (100 * $fcendwh / $hopt->{$shod}{$bat}{batinstcap}); # Prognose SoC in % @@ -11911,6 +11927,7 @@ sub _batChargeMgmt { hod => $shod, loopid => 'OTP', strategy => $hopt->{$shod}{$bat}{strategy}, + crel => 1, }; ___batChargeSaveResults ($paref, $values); @@ -11924,11 +11941,12 @@ sub _batChargeMgmt { my $ttt = $hopt->{$shod}{$bat}{stt}; if ($nhr eq '00') { - $pneedmin = $otp->{$bat}{target} // 0; - my $achievable = $hopt->{$shod}{$bat}{achievable}; - my $otpMargin = $hopt->{$shod}{$bat}{otpMargin}; - my $margin = defined $otpMargin ? $otpMargin : SFTYMARGIN_20; - Log3 ($name, 1, "$name DEBUG> Bat $bat ChargeOTP - used safety margin: $margin %"); + $pneedmin = $otp->{$bat}{target} // 0; + my $achievable = $hopt->{$shod}{$bat}{achievable}; + my $otpMargin = $hopt->{$shod}{$bat}{otpMargin}; + my $weightOwnUse = $hopt->{$shod}{$bat}{weightOwnUse}; + Log3 ($name, 1, "$name DEBUG> Bat $bat ChargeOTP - used safety margin: $otpMargin %"); + Log3 ($name, 1, "$name DEBUG> Bat $bat ChargeOTP - weighted self-consumption: $weightOwnUse %"); Log3 ($name, 1, "$name DEBUG> Bat $bat ChargeOTP - is the charging goal likely to be achieved? - $achievable"); } @@ -12006,7 +12024,7 @@ sub __batChargeOptTargetPower { my $sbatinstcap = $hsurp->{$hod}{$sbn}{batinstcap}; # Kapa dieser Batterie my $lowSocwh = $hsurp->{$hod}{$sbn}{lowSocwh}; # eingestellter lowSoc in Wh my $csocwh = $hsurp->{$hod}{$sbn}{csocwh}; # aktueller SoC in Wh - my $bpinreduced = BatteryVal ($name, $sbn, 'bpinreduced', 0); # Standardwert wenn z.B. kein Überschuß oder Zwangsladung vom Grid + my $bpinreduced = $hsurp->{$hod}{$sbn}{bpinreduced}; # Standardwert bei <=lowSoC -> Anforderungsladung vom Grid my $runwh = defined $hsurp->{$hod}{$sbn}{fcnextwh} ? # Auswahl des zu verwendenden Prognose-SOC (Wh) $hsurp->{$hod}{$sbn}{fcnextwh} : @@ -12016,12 +12034,14 @@ sub __batChargeOptTargetPower { ); $runwh = min ($runwh, $sbatinstcap); - $hsurp->{$hod}{$sbn}{runwh} = sprintf "%.0f", $runwh; + $hsurp->{$hod}{$sbn}{runwh} = sprintf "%.0f", $runwh; # Startwert für DebugLog - if (!$spls || !$hsurp->{$hod}{$sbn}{lcintime}) { # Ladesteuerung nicht "In Time" - $hsurp->{$hod}{$sbn}{achievable} = 'undetermined'; + if (!$spls) { # Ladesteuerung nicht "In Time" + $hsurp->{$hod}{$sbn}{achievable} = 'undetermined, calculation is starting with next hour with surplus'; $hsurp->{$hod}{$sbn}{pneedmin} = $bpinmax; - $hsurp->{$hod}{$sbn}{fcendwh} = sprintf "%.0f", $runwh; + + $runwh += $hsurp->{$hod}{speff} / STOREFFDEF; # um Verbrauch reduzieren + $hsurp->{$hod}{$sbn}{fcendwh} = sprintf "%.0f", $runwh; if ($nhr eq '00') { $otp->{$sbn}{target} = $csocwh <= $lowSocwh ? $bpinreduced : $bpinmax; @@ -12031,21 +12051,26 @@ sub __batChargeOptTargetPower { } my $otpMargin = $hsurp->{$hod}{$sbn}{otpMargin}; - my $margin = defined $otpMargin ? $otpMargin : SFTYMARGIN_20; my $runwhneed = $sbatinstcap - $runwh; + my $fref = ___batFindMinPhWh ($hsurp, \@remaining_hods, $runwhneed); my $needraw = min ($fref->{ph}, $spls); # Ladeleistung auf Surplus begrenzen - $needraw *= 1 + ($margin / 100); # 1. Sicherheitsaufschlag + $needraw *= 1 + ($otpMargin / 100); # 1. Sicherheitsaufschlag + $needraw = $bpinmax if(!$hsurp->{$hod}{$sbn}{lcintime}); $needraw = sprintf "%.0f", $needraw; - my $pneedmin = max ($needraw, $bpinreduced); # Mindestladeleistung bpinreduced sicherstellen + $needraw = max ($needraw, $bpinreduced); # Mindestladeleistung bpinreduced sicherstellen + $needraw = min ($needraw, $bpinmax); # Begrenzung auf max. mögliche Batterieleistung - $hsurp->{$hod}{$sbn}{achievable} = 'goal: '.(sprintf "%.0f", $runwhneed).' Wh -> '.($fref->{achievable} ? 'yes' : 'no'); - $hsurp->{$hod}{$sbn}{pneedmin} = min ($pneedmin, $hsurp->{$hod}{$sbn}{bpinmax}); # Begrenzung auf max. mögliche Batterieleistung + $hsurp->{$hod}{$sbn}{pneedmin} = $needraw; + $hsurp->{$hod}{$sbn}{achievable} = 'goal: '.(sprintf "%.0f", $runwhneed).' Wh -> '.($fref->{achievable} ? 'yes' : 'no'); + + ## NextHour 00 bearbeiten + ########################### if ($nhr eq '00') { my $target = max ($bpinreduced, $hsurp->{$hod}{$sbn}{pneedmin}); - $target *= 1 + ($margin / 100); # 2. Sicherheitsaufschlag + $target *= 1 + ($otpMargin / 100); # 2. Sicherheitsaufschlag my $gfeedin = CurrentVal ($name, 'gridfeedin', 0); # aktuelle Netzeinspeisung my $bpin = CurrentVal ($name, 'batpowerinsum', 0); # aktuelle Batterie Ladeleistung (Summe über alle Batterien) @@ -12059,6 +12084,8 @@ sub __batChargeOptTargetPower { $otp->{$sbn}{target} = $target; } + + $hsurp->{$hod}{$sbn}{fcendwh} = sprintf "%.0f", min ($sbatinstcap, $runwh + ($nhr eq '00' ? # Endwert Prognose aktuelle Stunde $otp->{$sbn}{target} : $hsurp->{$hod}{$sbn}{pneedmin} @@ -12071,6 +12098,17 @@ sub __batChargeOptTargetPower { return ($hsurp, $otp); } +################################################################ +# Weiterschreibung übergebenen SoC in Wh, Rückgabe +# weitergeschriebenen SoC in % +################################################################ +sub ___batSocWhForecast { + my $paref = shift; + + +return; +} + ############################################################################################### # Errechnet minimal benötigte konstante Ladeleistung: $ph Wh via Binärsuche Iteration # @@ -12150,7 +12188,7 @@ sub ___batChargeSaveResults { ## in Schleife 'loadRelease' setzen ##################################### - if ($loopid eq 'LR') { # nur in Schleife 'loadRelease' setzen + if ($loopid eq 'LR') { $data{$name}{nexthours}{'NextHour'.$nhr}{'rcdchargebat'.$bn} = $crel; $data{$name}{nexthours}{'NextHour'.$nhr}{'lcintimebat'.$bn} = $lcintime if($cgbt); # nur einmal bei 'loadRelease' setzen -> Ladesteuerung "In Time", "nicht In Time" oder nicht verwendet $data{$name}{nexthours}{'NextHour'.$nhr}{'strategybat'.$bn} = $strategy; @@ -12169,7 +12207,9 @@ sub ___batChargeSaveResults { ## in Schleife 'optPower' setzen ################################## if ($loopid eq 'OTP') { - if ($nhr eq '00') { # Target für aktuelle Stunde + $data{$name}{nexthours}{'NextHour'.$nhr}{'rcdchargebat'.$bn} = $crel; # immer Freigabe bei optPower (für Anzeige) + + if ($nhr eq '00') { # Target für aktuelle Stunde my $needmin = $otp->{$bn}{target} // 0; storeReading ('Battery_ChargeOptTargetPower_'.$bn, $needmin.' W'); } @@ -27041,7 +27081,7 @@ to ensure that the system configuration is correct.