76_SolarForecast - Beispiele für ctrlUserExitFn / consumerXX / setupXXYY.. etc.

Begonnen von 300P, 26 Mai 2025, 15:38:55

Vorheriges Thema - Nächstes Thema

300P

In diesem Thread soll es allein um die Weitergabe von Praxisbeispielen die im SF-Modul (76_SolarForecast.pm) entweder ohne jegliche Anpassung oder auch mit weiteren (externen) Anpassungen bei der Einrichtung der eigenen Konfiguration übernommen werden könnten.
==>> Alles unter Ausschluss jeglicher Gewähr auf die Funktion der jeweiligen Codefragmente !  O:-)

Bitte möglichst jeweils die SF-Version dazu schreiben unter der es eingesetzt wird/wurde.
Manchmal müssen (leider) bekanntlich Anpassungen an den Beispielen und Attributen bei neueren Versionen vorgenommen werden, da Funktionen/Attribute umbenannt, zusammengefaßt, gelöscht oder erweitert werden/wurden. ;)

Anfallende Probleme zu den Beispielen und deren Klärung sollten möglichst nicht hier, sondern im normalen SF-Modul-Faden behandelt werden.
Der Grund dazu ist allein das die hier im Thread zur Verfügung gestellten Beispiele nicht in den allgemeinen Diskussionen untergehen sollen.

Link zum  <--SF-Modul--> und dessen Diskussion

Link zum  <--FHEM-Wiki des SF-Modules-->

Gruß
300P
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

300P

Hier das erste Beispiel
Nr          : 001
SF-Version  : 76_SolarForecast.pm:v1.52.5-s29997/2025-05-25
Bereich      : ctrlUserExitFn



Netzdienliches Laden innerhalb von Solarforecast mit SMA-Batterie-Wechselrichtern:

Für 1 BWR ist der Code etwas tiefer auch dabei

{
# BEGIN ######## Netzdienliches Laden ################
  my $dt    = timestringsFromOffset (time, 0);
  my $hour  = $dt->{hour};                                                # aktuelle Stunde in 24h format (00-23)
  my $timestart = 9;  # ab welcher Uhrzeit soll es sein                                      ===>> Wert evtl. anpassen
  my $timeend = 15;  # bis wieviel Uhr soll es sein                                          ===>> Wert evtl. anpassen

  if (int $hour >= $timestart && int $hour < $timeend ) {
          # Nur zwischen xy:00 bis max. xy:59 (!!!! $timeend -1 Stunde !!!!)  Uhr


    my $curpowerbatin01 = ReadingsNum ($name, 'Current_PowerBatIn_01', 0);
    my $curpowerbatin02 = ReadingsNum ($name, 'Current_PowerBatIn_02', 0);
    my $curpowerbatout01 = ReadingsNum ($name, 'Current_PowerBatOut_01', 0);
    my $curpowerbatout02 = ReadingsNum ($name, 'Current_PowerBatOut_02', 0);
    my $curbatcharge01 = CurrentVal ($name, 'Current_BatCharge_01', 0);        # SoC Bat01 aktuell
    my $curbatcharge02 = CurrentVal ($name, 'Current_BatCharge_02', 0);        # SoC Bat02 aktuell
    my $currentsurplus = (ReadingsNum ($name, 'Current_Surplus', 0) - 50);  # etwas abziehen zwecks weniger als Puffer
    my $batchargerequest01 = ReadingsNum ($name, 'Battery_ChargeRequest_01', 0); # Batterie01 muss geladen werden ?
    my $batchargerequest02 = ReadingsNum ($name, 'Battery_ChargeRequest_02', 0); # Batterie02 muss geladen werden ?
    my $gridfriendlychargebat01 = ReadingsNum ($name, 'Battery_ChargeRecommended_01', 0); # Batterie01 recommended ?
    my $gridfriendlychargebat02 = ReadingsNum ($name, 'Battery_ChargeRecommended_02', 0); # Batterie02 recommended ?
    my $curbatchargemin01= 30;  # erst ab Mindes-BAT01-SOC XY netzdienlich                                  ===>> Wert evtl. anpassen 0..30
    my $curbatchargemin02= 30;  # erst ab Mindes-BAT02-SOC XY netzdienlich                                  ===>> Wert evtl. anpassen 0..30
    my $bwr01 = "MB_SBS25";      # Name des 1ten BWR-Modbus-Device                                            ===>> Wert evtl. anpassen
    my $bwr02 = "MB_SBS25_2";    # Name des 2ten BWR-Modbus-Device                                            ===>> Wert evtl. anpassen


    if (int $gridfriendlychargebat01 eq 0 || $gridfriendlychargebat02 eq 0) {
            # Nur wenn die Batterieladung01 oder 02 SF-Systemseitig nicht empfohlen wird dann

        Log3 ($name, 5, qq{$name - userFn -> Gridfriendlyloadrecommended Battery01 $gridfriendlychargebat01 - Battery02 $gridfriendlychargebat02 });
      my $curbatcharge01 = CurrentVal ($name, 'Current_BatCharge_01', 0);        # SoC Bat01 aktuell
      my $curbatcharge02 = CurrentVal ($name, 'Current_BatCharge_02', 0);        # SoC Bat02 aktuell

        if (int $gridfriendlychargebat01 eq 0 && $batchargerequest01 eq 0 && $curbatcharge01 > $curbatchargemin01) {
              # wenn bei Bat01 = 0 -beides- und SOC groß genug ->>dann unterbinden Laden Bat01
              Log3 ($name, 5, qq{$name - userFn -> Gridfriendlyloadrecommended only Battery01 Reading = $gridfriendlychargebat01 });
              fhem("set $bwr01 Set_Leistung_W $currentsurplus"); #  Watt Netzleistung am Übergabemesspunkt (WR1)
              fhem("set $bwr01 Set_Aktiv 802");  # 802 - Steuerung aktiv (WR1)
              Log3 ($name, 3, qq{$name - userFn -> Batteryload $bwr01 => activ  - BatIn01 $curpowerbatin01  BatOut01 $curpowerbatout01  });
            }
      else {
            if (int $gridfriendlychargebat01 eq 1 || $batchargerequest01 eq 1 || (($curbatcharge01 - 3) <= $curbatchargemin01)) {
                  # wenn bei Bat01 = beides oder nur eins auf 1 steht ---dann bitte jetzt Steuerung  aus / kein Laden unterbinden Bat01
                  Log3 ($name, 5, qq{$name - userFn -> Gridfriendlyloadrecommended =>> Battery01 Reading = $gridfriendlychargebat01 and BatChargerequest =>> Battery01 Reading = $batchargerequest01 });
                  fhem("set $bwr01 Set_Leistung_W 0"); #  Watt Netzleistung am Übergabemesspunkt (WR1)
                  fhem("set $bwr01 Set_Aktiv 803");  # 803 - Steuerung nicht aktiv (WR1)
                  Log3 ($name, 3, qq{$name - userFn -> Batteryload $bwr01 => not activ  - BatIn01 $curpowerbatin01  BatOut01 $curpowerbatout01  });
                }
            }

        if (int $gridfriendlychargebat02 eq 0  && $batchargerequest02 eq 0 && $curbatcharge02 > $curbatchargemin02) {
              # wenn bei Bat02 = 0 -beides- und SOC groß genug  --->>dann unterbinden Laden Bat02
              Log3 ($name, 5, qq{$name - userFn -> Gridfriendlyloadrecommended only Battery02 Reading = $gridfriendlychargebat02 });
              fhem("set $bwr02 Set_Leistung_W $currentsurplus");  #  Watt Netzleistung am Übergabemesspunkt (WR2)
              fhem("set $bwr02 Set_Aktiv 802");  # 802 - Steuerung aktiv (WR2)
              Log3 ($name, 3, qq{$name - userFn -> Batteryload $bwr02 => not activ  - BatIn02 $curpowerbatin02  BatOut02 $curpowerbatout02 });
            }
      else {
            if (int $gridfriendlychargebat02 eq 1 || int $batchargerequest02 eq 1 || (($curbatcharge02 - 3) <= $curbatchargemin02)) {
                  # wenn bei Bat02 = beides oder nur eins auf 1 steht ---dann bitte jetzt Steuerung  aus / kein Laden unterbinden Bat02
                  Log3 ($name, 5, qq{$name - userFn -> Gridfriendlyloadrecommended =>> Battery02 Reading = $gridfriendlychargebat02 and BatChargerequest =>> Battery02 Reading = $batchargerequest02 });
                  fhem("set $bwr02 Set_Leistung_W 0"); #  Watt Netzleistung am Übergabemesspunkt (WR2)
                  fhem("set $bwr02 Set_Aktiv 803");  # 803 - Steuerung nicht aktiv (WR2)
                  Log3 ($name, 3, qq{$name - userFn -> Batteryload $bwr02 => not activ  - BatIn02 $curpowerbatin02  BatOut02 $curpowerbatout02  });
                }
            }

      }
  }
# ENDE ######## Netzdienliches Laden ################

}

Hier nur für 1 BWR:

{
# BEGIN ######## Netzdienliches Laden ################
  my $dt    = timestringsFromOffset (time, 0);
  my $hour  = $dt->{hour};                                                # aktuelle Stunde in 24h format (00-23)
  my $timestart = 9;  # ab welcher Uhrzeit soll es sein                                      ===>> Wert evtl. anpassen
  my $timeend = 15;  # bis wieviel Uhr soll es sein                                          ===>> Wert evtl. anpassen

  if (int $hour >= $timestart && int $hour < $timeend ) {
          # Nur zwischen xy:00 bis max. xy:59 (!!!! $timeend -1 Stunde !!!!)  Uhr


    my $curpowerbatin01 = ReadingsNum ($name, 'Current_PowerBatIn_01', 0);
    my $curpowerbatout01 = ReadingsNum ($name, 'Current_PowerBatOut_01', 0);
    my $curbatcharge01 = CurrentVal ($name, 'Current_BatCharge_01', 0);        # SoC Bat01 aktuell
    my $currentsurplus = (ReadingsNum ($name, 'Current_Surplus', 0) - 50);  # etwas abziehen zwecks weniger als Puffer
    my $batchargerequest01 = ReadingsNum ($name, 'Battery_ChargeRequest_01', 0); # Batterie01 muss geladen werden ?
    my $gridfriendlychargebat01 = ReadingsNum ($name, 'Battery_ChargeRecommended_01', 0); # Batterie01 recommended ?
    my $curbatchargemin01= 30;  # erst ab Mindes-BAT01-SOC XY netzdienlich                                  ===>> Wert evtl. anpassen 0..30
    my $bwr01 = "MB_SBS25";      # Name des 1ten BWR-Modbus-Device                                            ===>> Wert evtl. anpassen


    if (int $gridfriendlychargebat01 eq 0) {
            # Nur wenn die Batterieladung01 SF-Systemseitig nicht empfohlen wird dann

        Log3 ($name, 5, qq{$name - userFn -> Gridfriendlyloadrecommended Battery01 $gridfriendlychargebat01 });
      my $curbatcharge01 = CurrentVal ($name, 'Current_BatCharge_01', 0);        # SoC Bat01 aktuell

        if (int $gridfriendlychargebat01 eq 0 && $batchargerequest01 eq 0 && $curbatcharge01 > $curbatchargemin01) {
              # wenn bei Bat01 = 0 -beides- und SOC groß genug ->>dann unterbinden Laden Bat01
              Log3 ($name, 5, qq{$name - userFn -> Gridfriendlyloadrecommended only Battery01 Reading = $gridfriendlychargebat01 });
              fhem("set $bwr01 Set_Leistung_W $currentsurplus"); #  Watt Netzleistung am Übergabemesspunkt (WR1)
              fhem("set $bwr01 Set_Aktiv 802");  # 802 - Steuerung aktiv (WR1)
              Log3 ($name, 3, qq{$name - userFn -> Batteryload $bwr01 => activ  - BatIn01 $curpowerbatin01  BatOut01 $curpowerbatout01  });
            }
      else {
            if (int $gridfriendlychargebat01 eq 1 || $batchargerequest01 eq 1 || (($curbatcharge01 - 3) <= $curbatchargemin01)) {
                  # wenn bei Bat01 = beides oder nur eins auf 1 steht ---dann bitte jetzt Steuerung  aus / kein Laden unterbinden Bat01
                  Log3 ($name, 5, qq{$name - userFn -> Gridfriendlyloadrecommended =>> Battery01 Reading = $gridfriendlychargebat01 and BatChargerequest =>> Battery01 Reading = $batchargerequest01 });
                  fhem("set $bwr01 Set_Leistung_W 0"); #  Watt Netzleistung am Übergabemesspunkt (WR1)
                  fhem("set $bwr01 Set_Aktiv 803");  # 803 - Steuerung nicht aktiv (WR1)
                  Log3 ($name, 3, qq{$name - userFn -> Batteryload $bwr01 => not activ  - BatIn01 $curpowerbatin01  BatOut01 $curpowerbatout01  });
                }
            }
        }
    }
# ENDE ######## Netzdienliches Laden ################

}

ACHTUNG:
Voraussetzung ist das die Modbus-Device bereits existieren und sauber dazu passend eingerichtet sind !

obj-h40149-expr $val
obj-h40149-len 2
obj-h40149-name SBS25_Set_Leistung_W
obj-h40149-poll once
obj-h40149-reading Set_Leistung_W
obj-h40149-set 1
obj-h40149-unpack I>
obj-h40151-expr $val
obj-h40151-name SBS25_Set_Aktiv
obj-h40151-poll once
obj-h40151-reading Set_Aktiv
obj-h40151-set 1

Gruß
300P

Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

300P

Beispiel Nr : 002
SF-Version  : 76_SolarForecast.pm:v1.52.5-s29997/2025-05-25
Bereich     : ConsumerXX / ctrlUserExitFn

Netzdienliche Brauchwassererwärmung (WW-Erhitzung) am Tag per consumer06
und zusätzliche Nutzung der "überschüssigen" Rest-Batterieladung in der Nacht, jedoch unter bestimmten Bedingungen.

{
# BEGIN ######## WP-Heater in der Nacht mit Restladung der Batterien ################
  my $dt    = timestringsFromOffset (time, 0);
  my $hour  = $dt->{hour};                                # aktuelle Stunde in 24h format (00-23)
  my $timestart = 1;  # ab welcher Uhrzeit soll es sein.  ===>> Wert evtl. anpassen
  my $timeend = 8;    # bis wieviel Uhr soll es sein.     ===>> Wert evtl. anpassen

  if (int $hour >= $timestart && int $hour < $timeend ) {
          # Nur zwischen xy:00 bis max. xy:59 (!!!! $timeend -1 Stunde !!!!)  Uhr

      my $minsocbat = 20;   
      # nur bis mindesten XY SoC aller Batterien. ===>> Wert evtl. anpassen

      # Heater-Name bzw. consumerXX anpassen - hier ist consumer06 der "Heater"
      my $heater  = (split " ", AttrVal ($name, 'consumer06', ''))[0];   

      my $soctotal = CurrentVal ($name, 'batsoctotal', 0);         # SoC über alle Bat als Durchschnitt
      my $pvtot =  ReadingsNum ($name, 'RestOfDayPVforecast', 0);  # Restliche PV Prognose total heute in Wh
      my $caps  = CurrentVal ($name, 'batcapsum', 0);          # Summe installierte Bat Wh
      my $need  = $caps - ($soctotal/100 * $caps);             # benötigte Ladeenergie Bat bis 100% Ladung


      Log3 ($name, 5, qq{$name - userFn -> WWHeater Reading ist = $heater - aktuelle Stunde = $hour   aus $dt erzeugt });
      Log3 ($name, 5, qq{$name - userFn -> StartZeit von = $timestart bis EndeZeit = $timeend und mindestens ein SoC von $minsocbat % muss in den vorhandenen Batterien gegeben sein });
      Log3 ($name, 5, qq{$name - userFn -> Der PV-Tages-Restertrag betraegt $pvtot Wh ???mehr??? als die offene und noch zu ladende Batteriekapazitaet von $need Wh});

     if ($soctotal >= ($minsocbat - 2) && $pvtot > $need) { 
         # Zwischen xy:00 bis max. xy:59 (!!!! $timeend -1 Stunde !!!!)  Uhr
         # und % SoC-Vorgabe erfüllt
         # und der PV-Tages-Rest-Ertrag > 100% Batteriekapazitaet
         # send "on"-Kommando an Heater Device if(ne "on");
         if (ReadingsVal($heater,"state","") ne "on") {
              fhem ("set $heater on");
              Log3 ($name, 3, qq{$name - userFn -> $name Consumer $heater in $name set to --on--});
             }
         }
      else {
         if (($soctotal < $minsocbat) || ($pvtot <= $need)) { 
             # Wenn die (SoC-Vorgabe unterschritten !!!!! oder !!!! derTages-Rest-Ertrag < 100% Batteriekapazitaet)
             # danach sollte der Heater-ConsumerXY wieder nach "seinen" Regeln steuern...
             # send "off"-Kommando an Heater Device if(ne "off");
             if (ReadingsVal($heater,"state","") ne "off") {
                fhem ("set $heater off");
                Log3 ($name, 3, qq{$name - userFn -> $name Consumer $heater in $name set to --off--});
                }
             }
         }
    }
# ENDE ######## WP-Heater ################
}

Hier noch der consumer06, der im SF-Modul dazu bei mir existiert.  ;)

attr Forecast consumer06 FBDECT_fbahahttp_FF_FF_FF_FF_FF \
type=heater \
power=2170 \
mode=can \
icon=sani_buffer_electric_heater_side@orange \
mintime=SunPath \
on=on \
off=off \
asynchron=1\
notbefore=08:00 \
notafter=19:00 \
locktime=300:300 \
pcurr=power:W \
etotal=energy:Wh\
surpmeth=10 \
interruptable=1\
swstate=state:.*on.*:.*off.*


Gruß
300P
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

300P

Beispiel Nr : 003
SF-Version  : 76_SolarForecast.pm:v1.52.5-s29997/2025-05-25
Bereich    : graphicHeaderOwnspec

Ausführliche Anzeige im Header mit Istwerten / Vorhersagewerten / Verbrauchswerten / Batteriewerten / Parameterabänderungsmöglichkeit

attr Forecast graphicHeaderOwnspec #aktuelle&nbsp;;Werte\
Netz&nbsp;;aktuell:Current_GridConsumption\
Einspeisung&nbsp;;aktuell:Current_GridFeedIn\
Netz&nbsp;;Heute&nbsp;;bis&nbsp;;jetzt:special_todayGridConsumption\
Einspeisung&nbsp;;Heute&nbsp;;bis&nbsp;;jetzt:special_todayGridFeedIn\
#Verbrauch\
Heute&nbsp;;bis&nbsp;;jetzt:special_todayConsumption\
Heute&nbsp;;erwartet:special_todayConsumptionForecastDay\
Heute&nbsp;;bis&nbsp;;Sonnenuntergang:special_todayConForecastTillSunset\
Heute&nbsp;;bis&nbsp;;Sonnenaufgang&nbsp;;:special_conForecastTillNextSunrise\
#PV\
Heute&nbsp;;bis&nbsp;;jetzt:Today_PVreal\
Heute&nbsp;;erwartet:Today_PVforecast\
Morgen&nbsp;;erwartet:Tomorrow_PVforecast\
Übermorgen&nbsp;;erwartet:special_dayAfterTomorrowPVforecast\
#Batterie&nbsp;;Gesamt\
Ladung&nbsp;;aktuell:special_BatPowerIn_Sum\
Entladung&nbsp;;aktuell:special_BatPowerOut_Sum\
Ladung&nbsp;;heute:special_todayBatInSum\
Entladung&nbsp;;heute:special_todayBatOutSum\
#Batterie01&nbsp;;|&nbsp;;02\
Bat01-Ladeanforderung:Battery_ChargeRequest_01\
Bat01-Ladung&nbsp;;empfohlen:Battery_ChargeRecommended_01\
Bat02-Ladeanforderung:Battery_ChargeRequest_02\
Bat02-Ladung&nbsp;;empfohlen:Battery_ChargeRecommended_02\
#\
 :\
MaxPVForecastTime:Today_MaxPVforecastTime\
 :\
 :\
#\
Bat01-Ladung&nbsp;;heute:special_todayBatIn_01\
Bat01-Entladung&nbsp;;heute:special_todayBatOut_01\
Bat02-Ladung&nbsp;;heute:special_todayBatIn_02\
Bat02-Entladung&nbsp;;heute:special_todayBatOut_02\
#\
Bat01-Ladeleistung&nbsp;;aktuell:Current_PowerBatIn_01\
Bat01-Entladeleistung&nbsp;;aktuell:Current_PowerBatOut_01\
Bat02-Ladeleistung&nbsp;;aktuell:Current_PowerBatIn_02\
Bat02-Entladeleistung&nbsp;;aktuell:Current_PowerBatOut_02\
#\
Bat01-Ladestatus&nbsp;;aktuell:Current_BatCharge_01\
Bat01-Restapazität&nbsp;;aktuell:Current_CapBat_01\
Bat02-Ladestatus&nbsp;;aktuell:Current_BatCharge_02\
Bat02-Restapazität&nbsp;;aktuell:Current_CapBat_02\
#Settings\
Autokorrektur:pvCorrectionFactor_Auto\
Wetter:graphicShowWeather\
History:graphicHistoryHour\
ShowNight:graphicShowNight\
#\
Beam1:graphicBeam1Content\
Beam2:graphicBeam2Content\
:\
:\
#\
Beam3:graphicBeam3Content\
Beam4:graphicBeam4Content\
:\
:\
#\
Beam5:graphicBeam5Content\
Beam6:graphicBeam6Content\
Debug:ctrlDebug\





Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

300P

Beispiel Nr : 004
SF-Version : 76_SolarForecast.pm:v1.52.5-s29997/2025-05-25
Bereich      : setupBatteryDevXX / setupInverterDevXX

Beispielsetup
setupBatteryDevXY  : SMA-BWR SBS2.5 und SMA-BWR SBS3.7

attr Forecast setupBatteryDev01 SBS37 pin=-pout:kW pout=total_pac:kW pinmax=3680 poutmax=3680 intotal=bat_loadtotal:kWh outtotal=bat_unloadtotal:kWh charge=chargestatus cap=bat_residual_cap:Wh show=3:top icon=@yellow:@green:@red:@white asynchron=0
attr Forecast setupBatteryDev02 SBS25_2 pin=-pout:kW pout=total_pac:kW pinmax=2500 poutmax=2500 intotal=bat_loadtotal:kWh outtotal=bat_unloadtotal:kWh charge=chargestatus cap=bat_residual_cap:Wh show=3:top icon=@yellow:@green:@red:@blue asynchron=0


In den BWR gibt es je ein Userreading
attr SBSXY userReadings bat_residual_cap {ReadingsNum($name,"bat_rated_capacity",0)*ReadingsNum($name,"bat_capacity",0)*10}


Beispielsetup
setupInverterDevXY : SMA-WR SB2.5 (1 String) --- SMA-WR SB3.0 (2 String) und SMA-WR SB4.0 (2 String)
(die angegebenen Strings müssen aber real im SF-Modul angelegt sein)

attr Forecast setupInverterDev01 SB25 etotal=etotal:kWh asynchron=0 pvIn=string_sum_pdc:kW pvOut=total_pac:kW limit=70 strings=GarageSE capacity=2500
attr Forecast setupInverterDev02 SB30 etotal=etotal:kWh asynchron=0 pvIn=string_sum_pdc:kW pvOut=total_pac:kW limit=70 strings=GarageNW,HausNW capacity=3000
attr Forecast setupInverterDev03 SB40 etotal=etotal:kWh asynchron=0 pvIn=string_sum_pdc:kW pvOut=total_pac:kW limit=70 strings=HausSE1,HausSE2,HausSW capacity=4000
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

300P

Beispiel Nr : 005
SF-Version : 76_SolarForecast.pm:v2.10.1
Bereich      : Batteriesteuerung

Beispiel mit DOIF-Nutzung zur einfachen Batteriesteuerung unter SF-Readingnutzung "Battery_ChargeUnrestricted_XX"
(SMA-BWR SBS2.5 und SMA-BWR SBS3.7 funktionieren damit)
Genau hinsehen wie die Timeouts bei der externen Steuerung eingestellt sind.
Bei mir sind es extra 30 Minuten eingestellt. Deshalb reichen die eingetragenen 300 Sekunden bei "repeatcmd" 300:0:0 - weniger Last fürs System.

Dies übernimmt die Steuerung der Batterieladung mit 0 Watt für die Batterie:
set MB_SBS25 Set_Leistung_W 0, set MB_SBS25 Set_Aktiv 802
Dies gibt die Steuerung zurück an das SMA-BMS :
set MB_SBS25 Set_Aktiv 803
defmod di_SF_BatteryControl_01 DOIF ([08:00-15:00] and [Forecast:Today_PVforecast:d, 0] > [Forecast:Today_CONforecast:d, 0] and [Forecast:Battery_ChargeUnrestricted_01:d, 1] == 0 and [Forecast:Battery_ChargeUnrestricted_01:sec] < 200) \
  (set MB_SBS25 Set_Leistung_W 0, set MB_SBS25 Set_Aktiv 802, {Log 2, "di_SF_BatteryControl_01 - BatCtrl_01: MB_SBS25   Set_Leistung_W 0 ->> Lade die Batterie nicht wegen Battery_ChargeUnrestricted_01 = 0"}) \
DOELSEIF \
   ([08:00-15:00]) (set MB_SBS25 Set_Aktiv 803, {Log 2, "di_SF_BatteryControl_01 - BatCtrl_01:                    Automatik - Eigenverbrauchsregelung der Batterie ist wieder an (803)"})\
DOELSE\
  (set MB_SBS25 Set_Aktiv 803, {Log 2, "di_SF_BatteryControl_01 - BatCtrl_01: Feierabend/Nacht - Eigenverbrauchsregelung erzwungen (803)"})
attr di_SF_BatteryControl_01 DbLogExclude .*
attr di_SF_BatteryControl_01 comment Steuerung erfolgt aufgrund \
\
1. Zeitraum \
    Von 08.00 bis ??15:00?? Uhr (oder wie auch immer) wird geregelt\
\
\
2. SF-Reading "Today_PVforecast" > "Today_CONforecast"\
    \
    Nur wenn am gesamten Tag der Ertrag > als der erwartete Verbrauch ist greift diese DOIF-Steuerung ein  \
\
\
3. SF-Reading "Battery_ChargeUnrestricted_XX" \
\
    A  =>> 0 ->> Umschaltung auf Wert 802 und Vorgabe 0 Watt  (alle 300 Sekunden -wegen repeatcmd=300:0:0 !!)\
    Ereignismeldung im SMA-BWR 2.5 (nicht mehr bei dem SMA \
    "10421    Eigenverbrauchsregelung wurde gestoppt"  (nur bei SBS 2.5 - bei SBS3.7 nicht mehr)\
\
    ->- Es erfolgt ab kurze Zeit später (10-30 Sekunden) gar keine Batterieladung mehr (0 Watt)\
    Ladung fährt auf den vorgegeben Wert "0 Watt"  \
\
    B  =>> 1 ->> Umschaltung auf Wert 803 (1X -wegen repeatcmd=300:0:0 !!)\
        Ereignismeldung im SMA-BWR \
    "10420    Eigenverbrauchsregelung wurde gestartet"  (bei SBS2.5 - bei SBS3.7 nicht mehr)\
        ->- Es erfolgt dann kurze Zeit später (10-30 Sekunden) die normal eigenständige SMA-Batteriesteurung\
        Laden/Entladen erfolgt so wie SMA es "will"\
\
\
4. Außerhalb der o.g. Zeiten oder wenn keine der vorhergehenden Abfragen zutreffend sind  \
\
    A  Es erfolgt (1X -wegen repeatcmd=300:0:0 !!) das Umschaltung auf Wert 803 - egal welcher Wert in SF besteht\
        Ereignismeldung im SMA-BWR \
    "10420    Eigenverbrauchsregelung wurde gestartet"  (bei SBS2.5 - bei SBS3.7 nicht)\
        ->- Es erfolgt dann kurze Zeit später (10-30 Sekunden) die normal eigenständige SMA-Batteriesteurung\
        Laden/Entladen erfolgt so wie SMA es "will"\
\

attr di_SF_BatteryControl_01 group SF
attr di_SF_BatteryControl_01 repeatcmd 300:0:0
attr di_SF_BatteryControl_01 room 020_PV,DoIf_Labor
attr di_SF_BatteryControl_01 stateFormat BatteryChargeOptTargetPower_01 : [Forecast:Battery_ChargeOptTargetPower_01] - BatteryChargeUnrestricted_01 : [Forecast:Battery_ChargeUnrestricted_01] - BatteryCurrentBatCharge_01 : [Forecast:Current_BatCharge_01]  Überschuss : [Forecast:Current_Surplus]

setstate di_SF_BatteryControl_01 BatteryChargeOptTargetPower_01 : 3600 W - BatteryChargeUnrestricted_01 : 0 - BatteryCurrentBatCharge_01 : 67 %   Überschuss : 63 W
setstate di_SF_BatteryControl_01 2026-08-24 08:24:00 Device Forecast
setstate di_SF_BatteryControl_01 2026-08-24 08:08:37 cmd 0
setstate di_SF_BatteryControl_01 2026-08-24 08:06:19 cmd_event Forecast
setstate di_SF_BatteryControl_01 2026-08-24 08:06:19 cmd_nr 1
setstate di_SF_BatteryControl_01 2026-08-24 08:21:28 e_Forecast_Battery_ChargeUnrestricted_01 0
setstate di_SF_BatteryControl_01 2026-08-24 08:21:13 e_Forecast_Today_CONforecast 26724 Wh
setstate di_SF_BatteryControl_01 2026-08-24 08:24:00 e_Forecast_Today_PVforecast 54469 Wh
setstate di_SF_BatteryControl_01 2026-08-24 08:08:37 mode enabled
setstate di_SF_BatteryControl_01 2026-08-24 08:08:37 state initialized
setstate di_SF_BatteryControl_01 2026-08-24 08:08:37 timer_01_c01 25.08.2026 08:00:00
setstate di_SF_BatteryControl_01 2026-08-24 08:08:37 timer_02_c01 24.08.2026 15:00:00
setstate di_SF_BatteryControl_01 2026-08-24 08:08:37 timer_03_c02 25.08.2026 08:00:00
setstate di_SF_BatteryControl_01 2026-08-24 08:08:37 timer_04_c02 24.08.2026 15:00:00
setstate di_SF_BatteryControl_01 2026-08-24 08:06:19 wait_timer 24.08.2026 08:11:19 cmd_1 Forecast
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.