76_SolarForecast: contrib Version 1.60.4

git-svn-id: https://svn.fhem.de/fhem/trunk@30523 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
DS_Starter
2025-11-12 10:45:36 +00:00
parent 19290ed0ea
commit 6acd3f40e3

View File

@@ -12066,7 +12066,6 @@ sub _batChargeMgmt {
$hsurp->{$fd}{$hod}{nhr} = $nhr; $hsurp->{$fd}{$hod}{nhr} = $nhr;
$hsurp->{$fd}{$hod}{speff} = $surpls; # effektiver PV Überschuß bzw. effektiver Verbrauch wenn < 0 $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}{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; # durch LR fortgeschriebener SoC $hsurp->{$fd}{$hod}{$bn}{initsocwh} = $socwh; # durch LR fortgeschriebener SoC
$hsurp->{$fd}{$hod}{$bn}{batinstcap} = $batinstcap; # installierte Batteriekapazität (Wh) $hsurp->{$fd}{$hod}{$bn}{batinstcap} = $batinstcap; # installierte Batteriekapazität (Wh)
$hsurp->{$fd}{$hod}{$bn}{goalwh} = $goalwh; # Ladeziel $hsurp->{$fd}{$hod}{$bn}{goalwh} = $goalwh; # Ladeziel
@@ -12164,7 +12163,7 @@ sub _batChargeMgmt {
########################################### ###########################################
for my $shod (sort { $a <=> $b } keys %{$hopt}) { for my $shod (sort { $a <=> $b } keys %{$hopt}) {
my $nhr = $hopt->{$shod}{nhr}; my $nhr = $hopt->{$shod}{nhr};
my @batteries = grep { !/^(?:fd|speff|surplswh|nhr)$/xs } keys %{$hopt->{24}}; my @batteries = grep { !/^(?:fd|speff|surplswh|spday|nhr)$/xs } keys %{$hopt->{24}};
for my $bat (sort @batteries) { for my $bat (sort @batteries) {
next if(!defined $hopt->{$shod}{$bat}{batinstcap}); next if(!defined $hopt->{$shod}{$bat}{batinstcap});
@@ -12196,24 +12195,25 @@ sub _batChargeMgmt {
## Debuglog OTP ## Debuglog OTP
################# #################
if ($paref->{debug} =~ /batteryManagement/ && $strategy ne 'loadRelease') { if ($paref->{debug} =~ /batteryManagement/ && $strategy ne 'loadRelease') {
my $spday = $hopt->{$shod}{spday};
my $lcintime = $hopt->{$shod}{$bat}{lcintime}; my $lcintime = $hopt->{$shod}{$bat}{lcintime};
my $spls = int $hopt->{$shod}{surplswh}; my $spls = int $hopt->{$shod}{surplswh};
my $pneedmin = $hopt->{$shod}{$bat}{pneedmin}; my $pneedmin = $hopt->{$shod}{$bat}{pneedmin};
my $ttt = $hopt->{$shod}{$bat}{stt}; my $ttt = $hopt->{$shod}{$bat}{stt};
my $crel = $hopt->{$shod}{$bat}{loadrel}; my $crel = $hopt->{$shod}{$bat}{loadrel};
my $spday = $hopt->{$shod}{$bat}{spday};
my $frefph = $hopt->{$shod}{$bat}{frefph} // '-'; my $frefph = $hopt->{$shod}{$bat}{frefph} // '-';
my $iter = $hopt->{$shod}{$bat}{iterations} // '-'; my $iter = $hopt->{$shod}{$bat}{iterations} // '-';
if ($nhr eq '00') { if ($nhr eq '00') {
$pneedmin = $otp->{$bat}{target} // 0; $pneedmin = $otp->{$bat}{target} // 0;
my $ratio = $otp->{$bat}{ratio} // '<unknown>'; my $ratio = $otp->{$bat}{ratio} // '<unknown>';
my $remainSurp = $otp->{$bat}{remainingSurp} // '<unknown>';
my $achievelog = $hopt->{$shod}{$bat}{achievelog}; my $achievelog = $hopt->{$shod}{$bat}{achievelog};
my $otpMargin = $hopt->{$shod}{$bat}{otpMargin}; my $otpMargin = $hopt->{$shod}{$bat}{otpMargin};
Log3 ($name, 1, "$name DEBUG> ChargeOTP Bat $bat - used safety margin: $otpMargin %"); Log3 ($name, 1, "$name DEBUG> ChargeOTP Bat $bat - used safety margin: $otpMargin %");
Log3 ($name, 1, "$name DEBUG> ChargeOTP Bat $bat - $achievelog"); Log3 ($name, 1, "$name DEBUG> ChargeOTP Bat $bat - $achievelog");
Log3 ($name, 1, "$name DEBUG> ChargeOTP Bat $bat - current Ratio of surplus / energy requirement to achieve the load target: $ratio %") if($strategy eq 'smartPower'); Log3 ($name, 1, "$name DEBUG> ChargeOTP Bat $bat - Ratio of remaining surplus $remainSurp Wh / energy requirement to achieve the load target: $ratio %") if($strategy eq 'smartPower');
} }
Log3 ($name, 1, "$name DEBUG> ChargeOTP Bat $bat $ttt - hod:$shod/$nhr, lr/lc:$crel/$lcintime, SocS/E:$ssocwh/$fcendwh Wh, SurpH/D:$spls/$spday Wh, OTP:$pneedmin/$frefph W"); Log3 ($name, 1, "$name DEBUG> ChargeOTP Bat $bat $ttt - hod:$shod/$nhr, lr/lc:$crel/$lcintime, SocS/E:$ssocwh/$fcendwh Wh, SurpH/D:$spls/$spday Wh, OTP:$pneedmin/$frefph W");
@@ -12281,10 +12281,10 @@ sub __batChargeOptTargetPower {
####################################################################### #######################################################################
my $replacement; my $replacement;
for my $k (keys %$hsurp) { for my $k (sort { $a <=> $b } keys %{$hsurp}) {
my $nh = $hsurp->{$k}{nhr}; my $nhr = $hsurp->{$k}{nhr};
if ($nh eq '00') { if ($nhr eq '00') {
my $val = $hsurp->{$k}{surplswh}; my $val = $hsurp->{$k}{surplswh};
if (defined $val && $val =~ /^(\d+)\.(\w+)$/) { if (defined $val && $val =~ /^(\d+)\.(\w+)$/) {
@@ -12292,12 +12292,12 @@ sub __batChargeOptTargetPower {
$replacement .= '.'.$2; $replacement .= '.'.$2;
} }
last; # da Stunde 00 nur einmal vorkommt, können wir abbrechen last;
} }
} }
my $fipl = CurrentVal ($name, 'feedinPowerLimit', INFINITE); my $fipl = CurrentVal ($name, 'feedinPowerLimit', INFINITE);
my @batteries = grep { !/^(?:fd|speff|surplswh|nhr)$/xs } keys %{$hsurp->{24}}; my @batteries = grep { !/^(?:fd|speff|surplswh|spday|nhr)$/xs } keys %{$hsurp->{24}};
my @sortedhods = sort { $hsurp->{$a}{surplswh} <=> $hsurp->{$b}{surplswh} } keys %{$hsurp}; # Stunden aufsteigend nach PV-Überschuß sortiert ohne Zeitgewichtung h 00 my @sortedhods = sort { $hsurp->{$a}{surplswh} <=> $hsurp->{$b}{surplswh} } keys %{$hsurp}; # Stunden aufsteigend nach PV-Überschuß sortiert ohne Zeitgewichtung h 00
my ($fcendwh, $diff, $otp, $ratio); my ($fcendwh, $diff, $otp, $ratio);
@@ -12315,6 +12315,7 @@ sub __batChargeOptTargetPower {
$replacement, $replacement,
\@sortedhods \@sortedhods
); );
$hsurp->{$hod}{spday} = $remainingSurp_o; # PV Überschuß Resttag
my ($remainingSurp, $remainingHodsRef); my ($remainingSurp, $remainingHodsRef);
@@ -12365,15 +12366,15 @@ sub __batChargeOptTargetPower {
my $runwhneed = $goalwh - $runwh; my $runwhneed = $goalwh - $runwh;
my $achievable = 1; my $achievable = 1;
if ($runwhneed > 0 && $remainingSurp * $befficiency < $runwhneed) { # Erreichbarkeit des Ziels (benötigte Ladeenergie total) prüfen if ($runwhneed > 0 && $remainingSurp < ($runwhneed / $befficiency)) { # Erreichbarkeit des Ziels (benötigte Ladeenergie total) prüfen
$achievable = 0; $achievable = 0;
} }
storeReading ('Battery_TargetAchievable_'.$sbn, $achievable) if($nhr eq '00'); storeReading ('Battery_TargetAchievable_'.$sbn, $achievable) if($nhr eq '00');
$hsurp->{$hod}{$sbn}{loadrel} = $runwhneed > 0 ? 1 : 0; # Ladefreigabe abhängig von Ziel-SoC Erfüllung $hsurp->{$hod}{$sbn}{loadrel} = $runwhneed > 0 ? 1 : 0; # Ladefreigabe abhängig von Ziel-SoC Erfüllung
$hsurp->{$hod}{$sbn}{achievelog} = "charging target: $goalwh Wh, remaining: ". $hsurp->{$hod}{$sbn}{achievelog} = "charging target: $goalwh Wh, E requirement incl. efficiency: ".
(sprintf "%.0f", $runwhneed).' Wh -> target likely achievable? '. (sprintf "%.0f", ($runwhneed / $befficiency)).' Wh -> target likely achievable? '.
($achievable ? 'yes' : 'no'); ($achievable ? 'yes' : 'no');
## kein Überschuß ## kein Überschuß
@@ -12481,7 +12482,8 @@ sub __batChargeOptTargetPower {
$befficiency $befficiency
); );
$otp->{$sbn}{ratio} = sprintf ("%.2f", $ratio); $otp->{$sbn}{ratio} = sprintf ("%.2f", $ratio);
$otp->{$sbn}{remainingSurp} = $remainingSurp;
} }
my $gfeedin = CurrentVal ($name, 'gridfeedin', 0); # aktuelle Netzeinspeisung my $gfeedin = CurrentVal ($name, 'gridfeedin', 0); # aktuelle Netzeinspeisung
@@ -12545,6 +12547,7 @@ sub ___batRemainHodsAndSurp {
my $val = defined $hsurp->{$h}{nhr} && $hsurp->{$h}{nhr} eq '00' my $val = defined $hsurp->{$h}{nhr} && $hsurp->{$h}{nhr} eq '00'
? int ($replacement) // 0 ? int ($replacement) // 0
: $hsurp->{$h}{surplswh}; : $hsurp->{$h}{surplswh};
$remainingSurp += int $val; $remainingSurp += int $val;
} }
@@ -12557,14 +12560,14 @@ return ($remainingSurp, \@remaining_hods);
# Forum: https://forum.fhem.de/index.php?msg=1349579 # Forum: https://forum.fhem.de/index.php?msg=1349579
################################################################ ################################################################
sub ___batAdjustPowerByMargin { sub ___batAdjustPowerByMargin {
my ($limpower, $pinmax, $whneed, $otpMargin, $remainingSurp, $befficiency) = @_; my ($limpower, $pinmax, $runwhneed, $otpMargin, $remainingSurp, $befficiency) = @_;
my $pow; my $pow;
my $ratio = 0; my $ratio = 0;
return ($limpower, $ratio) if(!defined $whneed || $whneed <= 0); return ($limpower, $ratio) if(!defined $runwhneed || $runwhneed <= 0);
$ratio = $remainingSurp * 100 / ($whneed / $befficiency); $ratio = $remainingSurp * 100 / ($runwhneed / $befficiency);
$limpower = min ($limpower, $pinmax); # limpower !> pinmax um invertierte Interpolation zu vermeiden $limpower = min ($limpower, $pinmax); # limpower !> pinmax um invertierte Interpolation zu vermeiden
if ($limpower <= 0 || !$otpMargin) {$pow = $limpower} if ($limpower <= 0 || !$otpMargin) {$pow = $limpower}
@@ -12713,6 +12716,8 @@ sub ___batFindMinPhWh {
: $hsurp->{$_}{surplswh} // 0 : $hsurp->{$_}{surplswh} // 0
} @hods; } @hods;
$max_cap //= 0;
return { ph => (sprintf "%.0f", $max_cap), iterations => $loop, blur => (sprintf "%.4f", 0) }; return { ph => (sprintf "%.0f", $max_cap), iterations => $loop, blur => (sprintf "%.4f", 0) };
} }