76_SolarForecast: contrib Version 1.59.6

git-svn-id: https://svn.fhem.de/fhem/trunk@30454 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
DS_Starter
2025-10-27 20:26:30 +00:00
parent 7b2b80f5db
commit fa49978f03

View File

@@ -12066,6 +12066,7 @@ sub _batChargeMgmt {
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 $spday = $hopt->{$shod}{$bat}{spday};
my $frefph = $hopt->{$shod}{$bat}{frefph} // '-';
if ($nhr eq '00') { if ($nhr eq '00') {
$pneedmin = $otp->{$bat}{target} // 0; $pneedmin = $otp->{$bat}{target} // 0;
@@ -12076,7 +12077,7 @@ sub _batChargeMgmt {
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 $ttt - hod: $shod/$nhr, lr/lc: $crel/$lcintime, SoC S/E: $ssocwh/$fcendwh Wh, Surp h/d: $spls/$spday Wh, OTP: $pneedmin 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");
} }
} }
} }
@@ -12137,9 +12138,10 @@ sub __batChargeOptTargetPower {
my $name = $paref->{name}; my $name = $paref->{name};
my $hsurp = $paref->{hsurp}; # Hashref Überschußhash my $hsurp = $paref->{hsurp}; # Hashref Überschußhash
## Surplus der Stunde 00 in Variable extrahieren und im Hash durch Zeitgewichtung ersetzen ## Surplus der Stunde 00 mit Zeitgewichtung in $replacement speichern
############################################################################################ #######################################################################
my $spls00 = 0; #my $spls00 = 0;
my $replacement;
for my $k (keys %$hsurp) { for my $k (keys %$hsurp) {
my $nh = $hsurp->{$k}{nhr}; my $nh = $hsurp->{$k}{nhr};
@@ -12148,10 +12150,10 @@ sub __batChargeOptTargetPower {
my $val = $hsurp->{$k}{surplswh}; my $val = $hsurp->{$k}{surplswh};
if (defined $val && $val =~ /^(\d+)\.(\w+)$/) { if (defined $val && $val =~ /^(\d+)\.(\w+)$/) {
$spls00 = $1; #my $spls00 = $1;
my $replacement = sprintf "%.0f", ($spls00 / 60 * (60 - int $minute)); # aktuelle (Rest)-Stunde -> zeitgewichteter PV-Überschuß $replacement = sprintf "%.0f", ($1 / 60 * (60 - int $minute)); # aktuelle (Rest)-Stunde -> zeitgewichteter PV-Überschuß
$replacement .= '.'.$2; $replacement .= '.'.$2;
$hsurp->{$k}{surplswh} = $replacement; #$hsurp->{$k}{surplswh} = $replacement;
} }
last; # da Stunde 00 nur einmal vorkommt, können wir abbrechen last; # da Stunde 00 nur einmal vorkommt, können wir abbrechen
@@ -12159,8 +12161,8 @@ sub __batChargeOptTargetPower {
} }
my $fipl = CurrentVal ($name, 'feedinPowerLimit', INFINITE); my $fipl = CurrentVal ($name, 'feedinPowerLimit', INFINITE);
my @sortedhods = sort { $hsurp->{$a}{surplswh} <=> $hsurp->{$b}{surplswh} } keys %{$hsurp}; # Stunden aufsteigend nach PV-Überschuß sortiert
my @batteries = grep { !/^(?:fd|speff|surplswh|nhr)$/xs } keys %{$hsurp->{24}}; my @batteries = grep { !/^(?:fd|speff|surplswh|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 ($fcendwh, $diff); my ($fcendwh, $diff);
my $otp; my $otp;
@@ -12170,14 +12172,21 @@ sub __batChargeOptTargetPower {
next if(!defined $nhr); next if(!defined $nhr);
my $spls = int ($hsurp->{$hod}{surplswh} // 0); my $spls = int ($hsurp->{$hod}{surplswh} // 0);
$spls = $spls00 if($nhr eq '00'); # aktuelle Stunde: zeitgewichteter PV-Überschuß mit Original ersetzen # $spls = $spls00 if($nhr eq '00'); # aktuelle Stunde: zeitgewichteter PV-Überschuß mit Original ersetzen
my $nexthod = sprintf "%02d", (int $hod + 1); my $nexthod = sprintf "%02d", (int $hod + 1);
my $nextnhr = $hsurp->{$nexthod}{nhr}; my $nextnhr = $hsurp->{$nexthod}{nhr};
my @remaining_hods = grep { int $_ >= int $hod } @sortedhods; my @remaining_hods = grep { int $_ >= int $hod } @sortedhods;
my $total = 0; my $total = 0;
$total += $hsurp->{$_}{surplswh} for @remaining_hods; # Gesamtkapazität aller Stunden mit PV-Überschuß ermitteln # $total += $hsurp->{$_}{surplswh} for @remaining_hods; # Gesamtwert aller Stunden mit PV-Überschuß ermitteln
for my $h (@remaining_hods) { # Gesamtwert aller Stunden mit PV-Überschuß ermitteln
my $val = $hsurp->{$h}{nhr} eq '00'
? $replacement // 0
: $hsurp->{$h}{surplswh};
$total += int $val;
}
for my $sbn (sort { $a <=> $b } @batteries) { # jede Batterie for my $sbn (sort { $a <=> $b } @batteries) { # jede Batterie
my $bpinmax = $hsurp->{$hod}{$sbn}{bpinmax}; # Bat max. mögliche Ladelesitung my $bpinmax = $hsurp->{$hod}{$sbn}{bpinmax}; # Bat max. mögliche Ladelesitung
@@ -12245,22 +12254,24 @@ sub __batChargeOptTargetPower {
######################### #########################
my $otpMargin = $hsurp->{$hod}{$sbn}{otpMargin}; my $otpMargin = $hsurp->{$hod}{$sbn}{otpMargin};
my $fref = ___batFindMinPhWh ($hsurp, \@remaining_hods, $runwhneed); my $fref = ___batFindMinPhWh ($hsurp, \@remaining_hods, $runwhneed);
my $minpower = $achievable || $strategy eq 'optPower' my $limpower = $achievable || $strategy eq 'optPower'
? min ($fref->{ph}, $spls) # Ladeleistung auf den kleineren Wert begrenzen (es kommen Nachberechnungen) ? min ($fref->{ph}, $spls) # Ladeleistung auf den kleineren Wert begrenzen (es kommen Nachberechnungen)
: $fref->{ph}; : $fref->{ph};
#Log3 ($name, 1, "$name - ph: $fref->{ph}") if($name eq "SolCast"); #Log3 ($name, 1, "$name - ph: $fref->{ph}") if($name eq "SolCast");
$minpower = $bpinmax if(!$hsurp->{$hod}{$sbn}{lcintime}); $limpower = $bpinmax if(!$hsurp->{$hod}{$sbn}{lcintime});
$minpower = max ($minpower, $bpinreduced); # Mindestladeleistung bpinreduced sicherstellen $limpower = max ($limpower, $bpinreduced); # Mindestladeleistung bpinreduced sicherstellen
$hsurp->{$hod}{$sbn}{frefph} = $fref->{ph};
## Prognose ## Prognose
############ ############
my $pneedmin = $minpower * (1 + $otpMargin / 100); # optPower: Sicherheitsaufschlag my $pneedmin = $limpower * (1 + $otpMargin / 100); # optPower: Sicherheitsaufschlag
if ($strategy eq 'smartPower') { if ($strategy eq 'smartPower') {
$pneedmin = ___batAdjustPowerByMargin ($name, # smartPower: Sicherheitsaufschlag abfallend proportional zum linearen Überschuss $pneedmin = ___batAdjustPowerByMargin ($name, # smartPower: Sicherheitsaufschlag abfallend proportional zum linearen Überschuss
$minpower, $limpower,
$bpinmax, $bpinmax,
$runwhneed, $runwhneed,
$otpMargin, $otpMargin,
@@ -12276,14 +12287,14 @@ sub __batChargeOptTargetPower {
## NextHour 00 (aktuelle Stunde) behandeln ## NextHour 00 (aktuelle Stunde) behandeln
############################################ ############################################
if ($nhr eq '00') { if ($nhr eq '00') {
my $target = $minpower > 0 ? $minpower / $befficiency : 0; # Zielleistung mit Batterie Effizienzgrad erhöhen my $target = $limpower > 0 ? $limpower / $befficiency : 0; # Zielleistung mit Batterie Effizienzgrad erhöhen
if ($achievable) { # Tagesziel erreichbar: Basisziel um otpMargin% erhöhen if ($achievable) { # Tagesziel erreichbar: Basisziel um otpMargin% erhöhen
$target *= 1 + ($otpMargin / 100); # optPower: Sicherheitsaufschlag $target *= 1 + ($otpMargin / 100); # optPower: Sicherheitsaufschlag
#if ($strategy eq 'smartPower') { # smartPower: Sicherheitsaufschlag linear absenkend #if ($strategy eq 'smartPower') { # smartPower: Sicherheitsaufschlag linear absenkend
# $target = ___batAdjustPowerByMargin ($name, # Sicherheitsaufschlag abfallend proportional zum linearen Überschuss # $target = ___batAdjustPowerByMargin ($name, # Sicherheitsaufschlag abfallend proportional zum linearen Überschuss
# $minpower, # $limpower,
# $bpinmax, # $bpinmax,
# $runwhneed, # $runwhneed,
# $otpMargin, # $otpMargin,
@@ -12303,7 +12314,7 @@ sub __batChargeOptTargetPower {
if ($strategy eq 'smartPower') { # smartPower: Sicherheitsaufschlag linear absenkend if ($strategy eq 'smartPower') { # smartPower: Sicherheitsaufschlag linear absenkend
$target = ___batAdjustPowerByMargin ($name, # Sicherheitsaufschlag abfallend proportional zum linearen Überschuss $target = ___batAdjustPowerByMargin ($name, # Sicherheitsaufschlag abfallend proportional zum linearen Überschuss
$minpower, $limpower,
$bpinmax, $bpinmax,
$runwhneed, $runwhneed,
$otpMargin, $otpMargin,
@@ -12350,15 +12361,15 @@ return ($hsurp, $otp);
# Forum: https://forum.fhem.de/index.php?msg=1349579 # Forum: https://forum.fhem.de/index.php?msg=1349579
################################################################ ################################################################
sub ___batAdjustPowerByMargin { sub ___batAdjustPowerByMargin {
my ($name, $minpower, $pinmax, $whneed, $otpMargin, $spday) = @_; my ($name, $limpower, $pinmax, $whneed, $otpMargin, $spday) = @_;
my $ratio = 0; my $ratio = 0;
$ratio = $spday * 100 / $whneed if($whneed); $ratio = $spday * 100 / $whneed if($whneed);
return $pinmax if($minpower == $pinmax || $ratio <= 100); return $pinmax if($limpower == $pinmax || $ratio <= 100);
return $minpower * (1 + $otpMargin / 100) if($minpower == 0 || !$otpMargin || $ratio >= 100 + $otpMargin); return $limpower * (1 + $otpMargin / 100) if($limpower == 0 || !$otpMargin || $ratio >= 100 + $otpMargin);
my $pow = $pinmax - ($pinmax - $minpower) * ($ratio - 100) / $otpMargin; my $pow = $pinmax - ($pinmax - $limpower) * ($ratio - 100) / $otpMargin;
return $pow; return $pow;
} }
@@ -20629,6 +20640,8 @@ sub aiAddInstance {
$data{$name}{aidectree}{object}{$tn}{enum} = $aiAddedToTrain; $data{$name}{aidectree}{object}{$tn}{enum} = $aiAddedToTrain;
} }
delete $data{$name}{aidectree}{aitrained};
$paref->{cst} = $cst; $paref->{cst} = $cst;
$serial = aiTrain ($paref); $serial = aiTrain ($paref);
delete $paref->{cst}; delete $paref->{cst};
@@ -20690,10 +20703,10 @@ sub aiTrain {
} }
$data{$name}{aidectree}{aitrained} = \@ensemble; $data{$name}{aidectree}{aitrained} = \@ensemble;
$err = writeCacheToFile ($hash, 'aitrained', $aitrained.$name); $err = writeCacheToFile ($hash, 'aitrained', $aitrained.$name);
my $rn; delete $data{$name}{aidectree}{aitrained};
my $rn;
if (!$err) { if (!$err) {
$rn = delete $entities{rn}; $rn = delete $entities{rn};