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
FHEM 6.4|RPi / QNAP-Container|SMAEM|SMAInverter|SolarForecast|DbLog|DbRep|Buderus-MQTT_EMS|MariaDB|
Fitzbox etc.|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP|ESP32-Digitizer-AI_on_the_edge|ESP32CAM

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

FHEM 6.4|RPi / QNAP-Container|SMAEM|SMAInverter|SolarForecast|DbLog|DbRep|Buderus-MQTT_EMS|MariaDB|
Fitzbox etc.|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP|ESP32-Digitizer-AI_on_the_edge|ESP32CAM

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
FHEM 6.4|RPi / QNAP-Container|SMAEM|SMAInverter|SolarForecast|DbLog|DbRep|Buderus-MQTT_EMS|MariaDB|
Fitzbox etc.|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP|ESP32-Digitizer-AI_on_the_edge|ESP32CAM

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\





FHEM 6.4|RPi / QNAP-Container|SMAEM|SMAInverter|SolarForecast|DbLog|DbRep|Buderus-MQTT_EMS|MariaDB|
Fitzbox etc.|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP|ESP32-Digitizer-AI_on_the_edge|ESP32CAM

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
FHEM 6.4|RPi / QNAP-Container|SMAEM|SMAInverter|SolarForecast|DbLog|DbRep|Buderus-MQTT_EMS|MariaDB|
Fitzbox etc.|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP|ESP32-Digitizer-AI_on_the_edge|ESP32CAM