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:
@@ -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};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user