From 22c5f28d737488a5a94ffe87b929c43318a9c6a3 Mon Sep 17 00:00:00 2001 From: DS_Starter Date: Fri, 24 Oct 2025 21:17:58 +0000 Subject: [PATCH] 76_SolarForecast: contrib Version 1.59.6 git-svn-id: https://svn.fhem.de/fhem/trunk@30444 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/DS_Starter/76_SolarForecast.pm | 67 ++++++++++++--------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/fhem/contrib/DS_Starter/76_SolarForecast.pm b/fhem/contrib/DS_Starter/76_SolarForecast.pm index 0a1b8ca9e..731dd5bb6 100644 --- a/fhem/contrib/DS_Starter/76_SolarForecast.pm +++ b/fhem/contrib/DS_Starter/76_SolarForecast.pm @@ -160,12 +160,12 @@ BEGIN { # Versions History intern my %vNotesIntern = ( - "1.59.6" => "20.10.2025 ___ownSpecGetFWwidget: handling of line breaks in attributes & can hamdle a key=value pair separateley ". + "1.59.6" => "24.10.2025 ___ownSpecGetFWwidget: handling of line breaks in attributes & can hamdle a key=value pair separateley ". "Width of a text field in graphicHeaderOwnspec fixed to 10, edit commandref ". "__batChargeOptTargetPower: use an average for the charging power if optPower set and charging target are not achievable ". "__createOwnSpec: an empty field can be created within a line by simply using a colon (:). ". - "add new key pvshare to CustomerXX attributes -> __setConsRcmdState add pvshare calculation ". - "___doPlanning: code improvements ", + "add new key pvshare to CustomerXX attributes -> __setConsRcmdState add PV share calculation ". + "___doPlanning: code improvements and implement PV share needed ", "1.59.5" => "15.10.2025 new sub ___batAdjustPowerByMargin: implement optPower Safety margin decreasing proportionally to the linear surplus ". "new Reading Battery_TargetAchievable_XX, _batSocTarget: minor code change ", "1.59.4" => "14.10.2025 new subs, ctrlBatSocManagementXX: new key loadTarget, replace __batCapShareFactor by __batDeficitShareFactor ". @@ -12150,7 +12150,6 @@ sub __batChargeOptTargetPower { my $replacement = sprintf "%.0f", ($spls00 / 60 * (60 - int $minute)); # aktuelle (Rest)-Stunde -> zeitgewichteter PV-Überschuß $replacement .= '.'.$2; $hsurp->{$k}{surplswh} = $replacement; - #Log3 ($name, 1, "$name - spls00: $spls00, replacement: $replacement "); } last; # da Stunde 00 nur einmal vorkommt, können wir abbrechen @@ -12272,20 +12271,13 @@ sub __batChargeOptTargetPower { $target = ___batAdjustPowerByMargin ($name, $target, $bpinmax, $runwhneed, $otpMargin); } } - else { # Tagesziel nicht erreichbar: Aufschlag potenziert (zweifach wirksam) - #$hs2sunset -= 1; -#Log3 ($name, 1, "$name - target0: $target"); - #$target = $runwhneed > 0 && $hs2sunset > 0 ? $runwhneed / $hs2sunset : $target; -#Log3 ($name, 1, "$name - runwhneed: $runwhneed, hs2sunset: $hs2sunset, target: $target"); - #$target *= (1 + $otpMargin / 100) ** 2; -#Log3 ($name, 1, "$name - target1: $target"); - if ($strategy eq 'smartPower') { # smartPower: maximale Ladeleistung erzwingen - #$target = $bpinmax; + else { # Tagesziel nicht erreichbar: Aufschlag potenziert (zweifach wirksam) + if ($strategy eq 'smartPower') { # smartPower: agressivere Ladeleistung $hs2sunset -= 1; $target = $runwhneed > 0 && $hs2sunset > 0 ? $runwhneed / $hs2sunset : $target; } - $target *= (1 + $otpMargin / 100) ** 2; + $target *= (1 + $otpMargin / 100) ** 2; } my $gfeedin = CurrentVal ($name, 'gridfeedin', 0); # aktuelle Netzeinspeisung @@ -13343,7 +13335,6 @@ sub ___doPlanning { my $debug = $paref->{debug}; my $lang = $paref->{lang}; my $nh = $data{$name}{nexthours}; - my $cicfip = CurrentVal ($name, 'consForecastInPlanning', 0); # soll Consumption Vorhersage in die Überschußermittlung eingehen ? my $hash = $defs{$name}; @@ -13354,9 +13345,12 @@ sub ___doPlanning { return; } - debugLog ($paref, "consumerPlanning", qq{consumer "$c" - consider consumption forecast in consumer planning (attr 'plantControl'): }.($cicfip ? 'yes' : 'no')); - + my $cicfip = CurrentVal ($name, 'consForecastInPlanning', 0); # soll Consumption Vorhersage in die Überschußermittlung eingehen ? + my $pvshare = ConsumerVal ($name, $c, 'pvshare', 100); # Soll-Anteil PV-Energie an nompower: 100 - nur PV, 0 - kann mit vollem Netzstrom betrieben werden + my $shfactor = $pvshare / 100; my (%tmp, %max, %mtimes); + + debugLog ($paref, "consumerPlanning", qq{consumer "$c" - consider consumption forecast in consumer planning (attr 'plantControl'): }.($cicfip ? 'yes' : 'no')); ## max. PV-Forecast bzw. Überschuß (bei gesetzen consForecastInPlanning) ermitteln #################################################################################### @@ -13364,7 +13358,7 @@ sub ___doPlanning { my $pvfc = NexthoursVal ($name, $idx, 'pvfc', 0); my $confcex = NexthoursVal ($name, $idx, 'confcEx', 0); # prognostizierter Verbrauch ohne registrierte Consumer mit gesetzten Schlüssel exconfc - my $spexp = $pvfc - ($cicfip ? $confcex : 0); # prognostizierter Energieüberschuß (kann negativ sein) + my $spexp = $pvfc - ($cicfip ? $confcex : 0); # prognostizierte Leistung -> Überschuß oder negativ my ($hour) = $idx =~ /NextHour(\d+)/xs; $tmp{$spexp}{starttime} = NexthoursVal ($name, $idx, 'starttime', ''); @@ -13393,7 +13387,7 @@ sub ___doPlanning { my $epiece1 = $data{$name}{consumers}{$c}{epieces}{1}; - debugLog ($paref, "consumerPlanning", qq{consumer "$c" - first energy piece: $epiece1}); + debugLog ($paref, "consumerPlanning", qq{consumer "$c" - first energy piece: $epiece1, PV share needed: $pvshare %, energy piece share: }.$epiece1 * $shfactor); my $mode = getConsumerPlanningMode ($hash, $c); # Planungsmode 'can' oder 'must' my $calias = ConsumerVal ($name, $c, 'alias', ''); @@ -13428,7 +13422,7 @@ sub ___doPlanning { } for my $ts (sort{$a<=>$b} keys %mtimes) { - if ($mtimes{$ts}{spexp} >= $epiece1) { # die früheste Startzeit sofern Überschuß größer als Bedarf + if ($mtimes{$ts}{spexp} >= $epiece1 * $shfactor) { # die früheste Startzeit mit Leistung > als Bedarf my $starttime = $mtimes{$ts}{starttime}; $paref->{starttime} = $starttime; $starttime = ___switchonTimelimits ($paref); @@ -13493,6 +13487,10 @@ sub ___doPlanning { delete $paref->{supplement}; } } + + delete $paref->{maxref}; + delete $paref->{mintime}; + delete $paref->{stopdiff}; my $planstate = ConsumerVal ($name, $c, 'planstate', ''); my $planspmlt = ConsumerVal ($name, $c, 'planSupplement', ''); @@ -27140,7 +27138,7 @@ to ensure that the system configuration is correct.
-
  • consumerXX <Device>[:<Alias>] type=<type> power=<power> [switchdev=<device>]
    +
  • consumerXX <Device>[:<Alias>] type=<type> power=<power> [pvshare=<Value>] [switchdev=<device>]
    [aliasshort=<String>] [mode=<mode>] [icon=<Icon>[@<Color>]] [mintime=<Option>]
    [on=<command>] [off=<command>] [swstate=<Readingname>:<on-Regex>:<off-Regex>] [asynchron=<Option>]
    [notbefore=<Expression>] [notafter=<Expression>] [locktime=<offlt>[:<onlt>]]
    @@ -27175,10 +27173,12 @@ to ensure that the system configuration is correct. The remaining runtime is not affected by an interrupt!

    - The power key indicates the power consumption of the consumer.
    - Depending on this value, the switching times of the consumer are planned and the cycle of the consumer is started depending on + The key power specifies the power consumption of the consumer. The key pvshare can be used to specify the desired + percentage of PV to cover the power consumption.
    + Depending on these values, the switching times of the consumer are planned and the cycle of the consumer is started depending on the sufficient PV surplus at the time of planning.
    - If power=0 is set, the consumer is switched on as planned, regardless of whether there is sufficient PV surplus. + If power=0 or pvshare=0 is set, the consumer is switched on as planned, regardless of whether there is sufficient + PV surplus.

      @@ -27205,6 +27205,10 @@ to ensure that the system configuration is correct. power Power consumption of the consumer in W. This can be the nominal power according to the data sheet or a dynamically specified reference value. (can be set to "0") + pvshare Defines the PV share of consumer power (key ‘power’) that is considered sufficient for the consumer. (optional) + The setting 100% defines a required PV surplus of at least ‘power’. With 0%, the consumer does not require any PV surplus. + Value: 0..100, default: 100 (%) + switchdev The specified <device> is assigned to the consumer as a switch device (optional). Switching operations are performed with this device. The key is useful for consumers where energy measurement and switching is carried out with different devices e.g. Homematic or readingsProxy. If switchdev is specified, the keys on, off, swstate, auto, asynchronous refer to this device. @@ -29852,7 +29856,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden.
      -
    • consumerXX <Device>[:<Alias>] type=<type> power=<power> [switchdev=<device>]
      +
    • consumerXX <Device>[:<Alias>] type=<type> power=<power> [pvshare=<Wert>] [switchdev=<device>]
      [aliasshort=<String>] [mode=<mode>] [icon=<Icon>[@<Farbe>]] [mintime=<Option>]
      [on=<Kommando>] [off=<Kommando>] [swstate=<Readingname>:<on-Regex>:<off-Regex>] [asynchron=<Option>]
      [notbefore=<Ausdruck>] [notafter=<Ausdruck>] [locktime=<offlt>[:<onlt>]]
      @@ -29886,10 +29890,11 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden. Die verbleibende Laufzeit wird durch einen Interrupt nicht beeinflusst!

      - Der Schlüssel power gibt die Leistungsaufnahme des Verbrauchers an.
      - Abhängig von diesem Wert werden die Schaltzeiten des Verbrauchers geplant und der Zyklus des Verbrauchers in Abhängigkeit + Der Schlüssel power gibt die Leistungsaufnahme des Verbrauchers an. Mit dem Schlüssel pvshare kann der gewünschte + prozentuale PV-Anteil zur Deckung der Leistungsaufnahme festgelgt werden.
      + Abhängig von diesen Werten werden die Schaltzeiten des Verbrauchers geplant und der Zyklus des Verbrauchers in Abhängigkeit des ausreichenden PV-Überschußes zum Einplanungszeitpunkt gestartet.
      - Ist power=0 gesetzt, wird der Verbraucher unabhängig von einem ausreichend vorhandenem PV-Überschuß + Ist power=0 oder pvshare=0 gesetzt, wird der Verbraucher unabhängig von einem ausreichend vorhandenem PV-Überschuß wie eingeplant geschaltet.

      @@ -29917,6 +29922,10 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden. power Leistungsaufnahme des Verbrauchers in W. Es kann die nominale Leistung gemäß Datenblatt oder ein dynamisch vorgegebener Richtwert sein. (kann auf "0" gesetzt werden) + pvshare Legt den PV-Anteil der Verbraucherleistung (Schlüssel 'power') fest, der als ausreichend für den Verbraucher gewertet wird. (optional) + Die Einstellung 100% definiert einen benötigten PV-Überschuß von mindestens 'power'. Mit 0% benötigt der Verbraucher keinen PV-Überschuß. + Wert: 0..100, default: 100 (%) + switchdev Das angegebene <device> wird als Schalter Device dem Verbraucher zugeordnet (optional). Schaltvorgänge werden mit diesem Gerät ausgeführt. Der Schlüssel ist für Verbraucher nützlich bei denen Energiemessung und Schaltung mit verschiedenen Geräten vorgenommen wird, z.B. Homematic oder readingsProxy. Ist switchdev angegeben, beziehen sich die Schlüssel on, off, swstate, auto, asynchron auf dieses Gerät. @@ -29984,7 +29993,7 @@ die ordnungsgemäße Anlagenkonfiguration geprüft werden. {Perl-Code} - der in {..} eingeschlossene Perl-Code darf keine Leerzeichen enthalten. Die Variable $VALUE kann vom Code ausgewertet werden. Der return Wert muß im Erfolgsfall 'wahr' sein. - swoffcond vorrangige Bedingung um den Verbraucher auszuschalten (optional). Der geplante Zyklus wird gestoppt. + swoffcond Vorrangige Bedingung um den Verbraucher auszuschalten (optional). Der geplante Zyklus wird gestoppt. Device:Reading - die Device/Reading Kombination liefert den Prüfwert $VALUE ('undef' wird ignoriert) Die Prüfung kann als regulärer Ausdruck oder als in {..} eingeschlossener Perl-Code formuliert sein: Regex - regulärer Ausdruck zur Prüfung von $VALUE der im Erfolgsfall 'wahr' liefern muß