Heidelberg Energy Control mit MODBUS und Überschussladen.

Begonnen von Buelo77, 09 März 2025, 13:46:56

Vorheriges Thema - Nächstes Thema

Buelo77

Hallo zusammen,
ich möchte gerne meine Lösung zur Heidelberg und Überschussladen teilen.

Als erstes die Randbedingungen:

Wechselrichter: Inselanlage ohne Einspeisung, 3 Phasen System mit MPP Solar PIP8048MAX
Solar:          21 kW Peak
Batterie:      2 Bänke mit 10kWh mit je 150Ampere Lade/Entladestrom
Wallbox:        Heidelberg Energy Control mit einem Modbus TCP to Modbus RTU Gateway Waweshare RS485 TO POE ETH

Ziel:
Überschussladen in einfachster Form erst einmal zu laufen zu bekommen.
Bedeutet, ich habe mich an den Batteriestrom orientiert.

Welche Faktoren sind von mir mit einbezogen:

- Wechselrichter dürfen nicht über 8.000 Watt
- Batteriestrom darf nicht über 60 Ampere
- SOC der Batterie über 90%

Damit habe ich erst einmal angefangen.

Hier ein Structure, wo ich die Stati der drei Wechselrichter und der beiden BMS zusammenfasse:

Internals:
   ATTR       MQTT2_WR1
   CHANGEDCNT 706619
   DEF        MQTT2_WR1 MQTT2_WR2 MQTT2_WR3
   FUUID      67717b3e-f33f-fd4b-5c15-d1a580f29bfb810b
   NAME       WR_Status_Structure
   NOTIFYDEV  MQTT2_WR2,MQTT2_WR3,global
   NR         87
   NTFY_ORDER 50-WR_Status_Structure
   STATE      Battery
   TYPE       structure
   eventCount 60308
   READINGS:
     2025-03-09 13:44:48   LastDevice      MQTT2_WR3
     2025-03-09 13:44:48   LastDevice_Abs  MQTT2_WR3
     2025-03-09 13:44:48   MAX_Amp_Batt    7.876
     2025-03-09 13:44:48   MAX_Power_Inv   2498
     2025-03-09 13:44:48   MIN_SOC_Battery 99
     2025-03-09 13:44:48   state           Battery
Attributes:
   event-on-change-reading .*
   room       Bitcoin Miner,Wallbox,Wechselrichter
   userReadings MAX_Power_Inv { List::Util::max(ReadingsNum("MQTT2_WR1",'WR1_AC_out_Watt',0),ReadingsNum("MQTT2_WR2",'WR2_AC_out_Watt',0),ReadingsNum("MQTT2_WR3",'WR3_AC_out_Watt',0)); }, MAX_Amp_Batt {List::Util::max(ReadingsNum("MQTT2_BMS_Watchdog1",'B1_Charge_Current',0),ReadingsNum("MQTT2_BMS_Watchdog2",'B2_Charge_Current',0)); }, MIN_SOC_Battery {List::Util::min(ReadingsNum("MQTT2_BMS_Watchdog1",'B1_Percent_Remain',0),ReadingsNum("MQTT2_BMS_Watchdog2",'B2_Percent_Remain',0)); }

MAX_Power_Inv, ist der höchste Leistungswert der 3 Wechselrichter.
MAX_Amp_Batt, ist der höchste Stromwert der 2 BMS.
MIN_SOC_Battery, ist der niedrigste SOC Wert der beiden Batteriebänke.

Hier das Modbus Objekt:

Internals:
   DEF        1 5 192.168.1.24:502 TCP
   DeviceName 192.168.1.24:502
   EXPECT     idle
   FD         4
   FUUID      6795230e-f33f-fd4b-ec16-5280861a60a88ee6
   IODev      ModbusWallbox
   Interval   5
   LASTOPEN   1741431619.8589
   MODBUSID   1
   MODE       master
   MODULEVERSION Modbus 4.5.6 - 7.11.2023
   NAME       ModbusWallbox
   NOTIFYDEV  global
   NR         90
   NTFY_ORDER 50-ModbusWallbox
   PARTIAL   
   PROTOCOL   TCP
   STATE      Load 100 A
   TCPConn    1
   TYPE       ModbusAttr
   devioLoglevel 3
   devioNoSTATE 1
   eventCount 70936
   nextOpenDelay 60
   DICACHE:
     3:
       UNPACK    
       EXPRS:
       EXTRAS:
       FNAMES:
     4:
       UNPACK    
       EXPRS:
       EXTRAS:
       FNAMES:
     6:
       UNPACK    
       EXPRS:
       EXTRAS:
       FNAMES:
   PICACHE:
     h258:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map        0:enable StandBy Funktion, 4:disable StandBy Funktion
       mapDefault
       revRegs   
       rmapDefault
     h259:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map        0:locked, 1:unlocked
       mapDefault
       revRegs   
       rmapDefault
     h261:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     h262:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i10:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i11:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i12:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i13:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map        0:locked, 1:unlocked
       mapDefault
       revRegs   
       rmapDefault
     i14:
       bswapRegs 
       decode    
       encode    
       expr       $val/1000
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i15:
       bswapRegs 
       decode    
       encode    
       expr       $val*65536
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i16:
       bswapRegs 
       decode    
       encode    
       expr       $val/1000
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i17:
       bswapRegs 
       decode    
       encode    
       expr       $val*65536/1000
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i18:
       bswapRegs 
       decode    
       encode    
       expr       $val/1000
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i200:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i203:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i5:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map        2:Unplugged_Wallbox_not_allow_charging, 3:Unplugged_Wallbox_allow_charging, 4:plugged_without_charging_request_Wallbox_not_allow_charging, 5:plugged_without_charging_request_Wallbox_allow_charging, 6:plugged_not_allow_charging, 7:plugged_allow_charging, 8:derating, 9:E, 10:F, 11:Error
       mapDefault
       revRegs   
       rmapDefault
     i6:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i7:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i8:
       bswapRegs 
       decode    
       encode    
       expr      
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
     i9:
       bswapRegs 
       decode    
       encode    
       expr       $val/10
       format    
       ignoreExpr
       map       
       mapDefault
       revRegs   
       rmapDefault
   QUEUE:
   READ:
     BUFFER    
   READINGS:
     2025-03-08 08:20:11   Application     Software svn-revNo 2739
     2025-03-09 13:52:22   Application Software svn-revNo 2739
     2025-03-08 08:20:14   Charging        State plugged_without_charging_request_Wallbox_not_allow_charging
     2025-03-09 13:52:21   Charging State  plugged_allow_charging
     2025-03-08 08:20:11   Energy          since Installation Low byte 29.619
     2025-03-09 13:52:22   Energy since Installation 131.072
     2025-03-09 13:52:22   Energy since Installation Low byte 26.941
     2025-03-09 13:52:22   Energy since PowerOn 0
     2025-03-09 13:52:22   Energy since PowerOn Low Byte 62.858
     2025-03-09 13:52:22   EnergySinceInstallationAll 158.013
     2025-03-09 13:52:20   FailSafe_Current 60
     2025-03-09 13:52:22   Hardware-Variant 128
     2025-03-08 08:20:14   L1              - Current RMS 0
     2025-03-09 13:52:21   L1 - Current RMS 99
     2025-03-08 08:20:14   L2              - Current RMS 0
     2025-03-09 13:52:21   L2 - Current RMS 98
     2025-03-08 08:20:14   L3              - Current RMS 0
     2025-03-09 13:52:21   L3 - Current RMS 98
     2025-03-09 13:42:48   Maximal_current 100
     2025-03-09 13:52:21   PCB-Temperatur  31.9
     2025-03-09 13:52:22   Power           6.947
     2025-03-09 13:52:20   Remote_lock     unlocked
     2025-03-09 13:52:20   Standby_Function_Control disable StandBy Funktion
     2025-03-08 08:20:10   Voltage         L1 236
     2025-03-09 13:52:21   Voltage L1      234
     2025-03-09 13:52:21   Voltage L3      233
     2025-03-08 08:20:10   extern          lock state unlocked
     2025-03-09 13:52:22   extern lock state unlocked
     2025-03-08 12:00:19   state           opened
   REMEMBER:
     lid        1
     lname      ModbusWallbox
     lrecv      1741524742.88095
     lsend      1741524742.86487
   UPDATECACHE:
     h258:
       adr        258
       len        1
       objCombi   h258
       reading    Standby_Function_Control
       span       1
       type       h
     h259:
       adr        259
       len        1
       objCombi   h259
       reading    Remote_lock
       span       1
       type       h
     h261:
       adr        261
       len        1
       objCombi   h261
       reading    Maximal_current
       span       1
       type       h
     h262:
       adr        262
       len        1
       objCombi   h262
       reading    FailSafe_Current
       span       1
       type       h
     i10:
       adr        10
       len        1
       objCombi   i10
       reading    Voltage L1
       span       1
       type       i
     i11:
       adr        11
       len        1
       objCombi   i11
       reading    Voltage L3
       span       1
       type       i
     i12:
       adr        12
       len        1
       objCombi   i12
       reading    Voltage L3
       span       1
       type       i
     i13:
       adr        13
       len        1
       objCombi   i13
       reading    extern lock state
       span       1
       type       i
     i14:
       adr        14
       len        1
       objCombi   i14
       reading    Power
       span       1
       type       i
     i15:
       adr        15
       len        1
       objCombi   i15
       reading    Energy since PowerOn
       span       1
       type       i
     i16:
       adr        16
       len        1
       objCombi   i16
       reading    Energy since PowerOn Low Byte
       span       1
       type       i
     i17:
       adr        17
       len        1
       objCombi   i17
       reading    Energy since Installation
       span       1
       type       i
     i18:
       adr        18
       len        1
       objCombi   i18
       reading    Energy since Installation Low byte
       span       1
       type       i
     i200:
       adr        200
       len        1
       objCombi   i200
       reading    Hardware-Variant
       span       1
       type       i
     i203:
       adr        203
       len        1
       objCombi   i203
       reading    Application Software svn-revNo
       span       1
       type       i
     i5:
       adr        5
       len        1
       objCombi   i5
       reading    Charging State
       span       1
       type       i
     i6:
       adr        6
       len        1
       objCombi   i6
       reading    L1 - Current RMS
       span       1
       type       i
     i7:
       adr        7
       len        1
       objCombi   i7
       reading    L2 - Current RMS
       span       1
       type       i
     i8:
       adr        8
       len        1
       objCombi   i8
       reading    L3 - Current RMS
       span       1
       type       i
     i9:
       adr        9
       len        1
       objCombi   i9
       reading    PCB-Temperatur
       span       1
       type       i
   defptr:
     ModbusWallbox 1
   gotReadings:
     Application Software svn-revNo 2739
   lastRead:
     h258       1741524740.58645
     h259       1741524740.72818
     h261       1741524740.8462
     h262       1741524740.96338
     i10        1741524741.67443
     i11        1741524741.79241
     i12        1741524741.91039
     i13        1741524742.02852
     i14        1741524742.14662
     i15        1741524742.26457
     i16        1741524742.38258
     i17        1741524742.5276
     i18        1741524742.64558
     i200       1741524742.76343
     i203       1741524742.8814
     i5         1741524741.0815
     i6         1741524741.19938
     i7         1741524741.32136
     i8         1741524741.43945
     i9         1741524741.55739
Attributes:
   comment    Power = 1kVA(Scheinleistung) = 0.8kW
Energy since PowerOn = 1 -->  65,536 kWh
Energy since PowerOn Low byte = kWh
Energy since Installation = 1 -->  65,536 kWh
Energy since Installation Low byte =  kWh

PCB-Temperatur = Grad Celsius
   event-on-change-reading .*
   obj-h258-map 0:enable StandBy Funktion, 4:disable StandBy Funktion
   obj-h258-poll 1
   obj-h258-reading Standby_Function_Control
   obj-h258-set 1
   obj-h259-map 0:locked, 1:unlocked
   obj-h259-poll 1
   obj-h259-reading Remote_lock
   obj-h259-set 1
   obj-h261-poll 1
   obj-h261-reading Maximal_current
   obj-h261-set 1
   obj-h262-poll 1
   obj-h262-reading FailSafe_Current
   obj-h262-set 1
   obj-i10-poll 1
   obj-i10-reading Voltage L1
   obj-i11-poll 1
   obj-i11-reading Voltage L3
   obj-i12-poll 1
   obj-i12-reading Voltage L3
   obj-i13-map 0:locked, 1:unlocked
   obj-i13-poll 1
   obj-i13-reading extern lock state
   obj-i14-expr $val/1000
   obj-i14-poll 1
   obj-i14-reading Power
   obj-i15-expr $val*65536
   obj-i15-poll 1
   obj-i15-reading Energy since PowerOn
   obj-i16-expr $val/1000
   obj-i16-poll 1
   obj-i16-reading Energy since PowerOn Low Byte
   obj-i17-expr $val*65536/1000
   obj-i17-poll 1
   obj-i17-reading Energy since Installation
   obj-i18-expr $val/1000
   obj-i18-poll 1
   obj-i18-reading Energy since Installation Low byte
   obj-i200-poll 1
   obj-i200-reading Hardware-Variant
   obj-i203-poll 1
   obj-i203-reading Application Software svn-revNo
   obj-i5-map 2:Unplugged_Wallbox_not_allow_charging, 3:Unplugged_Wallbox_allow_charging, 4:plugged_without_charging_request_Wallbox_not_allow_charging, 5:plugged_without_charging_request_Wallbox_allow_charging, 6:plugged_not_allow_charging, 7:plugged_allow_charging, 8:derating, 9:E, 10:F, 11:Error
   obj-i5-poll 1
   obj-i5-reading Charging State
   obj-i6-poll 1
   obj-i6-reading L1 - Current RMS
   obj-i7-poll 1
   obj-i7-reading L2 - Current RMS
   obj-i8-poll 1
   obj-i8-reading L3 - Current RMS
   obj-i9-expr $val/10
   obj-i9-poll 1
   obj-i9-reading PCB-Temperatur
   room       Wallbox
   stateFormat Load [$name:Maximal_current] A
   timestamp-on-change-reading Maximal_current
   userReadings EnergySinceInstallationAll { ReadingsVal("ModbusWallbox","Energy since Installation",0)+ReadingsVal("ModbusWallbox","Energy since Installation Low byte",0);; }
   verbose    2

Das ist nun das Notify:

[code]Internals:
   DEF        (.*WR_Status_Structure.MAX_Power_Inv:.*)
{        
    my $new_Maximal_current=0;

    # Ist ein Auto angesteckt oder nicht
    my $Status_Wallbox = ReadingsVal("ModbusWallbox",'Charging State','');

    # Wallbox laed oder nicht
    my $Status_Wallbox_Power = ReadingsNum("ModbusWallbox",'Power','');

    # Wie hoch ist der Ladestrom aktuell eingestellt
    my $Status_WB_Max_Curr = ReadingsNum('ModbusWallbox','Maximal_current','');

    # Laufen wir auf Batterie oder Netz
    my $Status_WR = ReadingsVal("WR_Status_Structure",'state','');
   
    # Wie hoch ist die WR Auslastung
    my $Status_WR_Pow = ReadingsNum("WR_Status_Structure",'MAX_Power_Inv','');
   
    # Wie hoch ist die Batterie Auslastung
    my $Status_WR_Amp = ReadingsNum("WR_Status_Structure",'MAX_Amp_Batt','');

    # SOC Batterie
    my $Status_SOC_Batt = ReadingsNum("WR_Status_Structure",'MIN_SOC_Battery','');
               
    # Sobald das Auto ausgesteckt ist, setze den Ladestrom der Wallbox auf 0
    if ("$Status_Wallbox" =~ "Unplugged_Wallbox_not_allow_charging|Unplugged_Wallbox_allow_charging" && $Status_WB_Max_Curr > 0) {
            fhem "set ModbusWallbox Maximal_current 0" ;
            Log 1, "n_Wallbox_Ueberschuss_Steuerung : Das Auto wurde ausgesteckt.";
    }

    # Das ist ein Überlastschutz
    if ( $Status_WR_Pow > 7000 || $Status_WR_Amp < -60) {
        if ($Status_WB_Max_Curr < 70) {
                fhem "set ModbusWallbox Maximal_current 0" ;
                Log 1, "n_Wallbox_Ueberschuss_Steuerung : Überlast erkannt Stoppe laden. WB Leistung:$Status_WR_Pow Endladestrom:$Status_WR_Amp";
        } else {
                fhem "set ModbusWallbox Maximal_current 60" ;
                Log 1, "n_Wallbox_Ueberschuss_Steuerung : Überlast erkannt reduziere auf 6 Ampere. WB Leistung:$Status_WR_Pow Endladestrom:$Status_WR_Amp";
        }
    }

    # Wenn Haus auf Batterie ist und
    # ein Auto eingesteckt ist und
    if ("$Status_WR" eq "Battery" && "$Status_Wallbox" =~ "plugged_allow_charging|plugged_without_charging_request_Wallbox_not_allow_charging") {
        # Kein Strom in das Auto und
        # Batterie über 90 Prozent ist und
        # Wechselrichter unter 4000 Watt sind und
        # Batteriestrom unter 0, dann setzte den zu ladenden Strom auf 6 Ampere
        # Wallbox laed noch nicht und wird eingeschaltet.
        if ($Status_Wallbox_Power == 0 && $Status_SOC_Batt > 90 && $Status_WR_Pow < 4000 && $Status_WR_Amp > 0) {   
            fhem "set ModbusWallbox Maximal_current 60" ;
            Log 1, "n_Wallbox_Ueberschuss_Steuerung : Wallbox war aus und wurde nun auf 6 Ampere gesetzt";
        }
       
        # Wenn WR Auslastung und Batterie Strom in normalen werten, setze den Ladestrom eins höher             
        if ($Status_Wallbox_Power > 0 && $Status_SOC_Batt > 90 && $Status_WR_Pow < 6000 && $Status_WR_Amp > 10) {
            if ($Status_WB_Max_Curr > 150) {
                $new_Maximal_current=160;
            }else {
                $new_Maximal_current=$Status_WB_Max_Curr+10;
            }
                       
            # Ermittle Zeit in sekunden vom Maximal_current
            my $Max_Curr_seconds = ReadingsAge("ModbusWallbox","Maximal_current",0);

            if ($Max_Curr_seconds > 6) {   
                fhem "set ModbusWallbox Maximal_current $new_Maximal_current" ;
                Log 1, "n_Wallbox_Ueberschuss_Steuerung : Wallbox wurde von $Status_WB_Max_Curr auf $new_Maximal_current gesetzt";
            }
        }

        # Sobald die Batterie entladen wird, setze den Ladestrom runter
        if ($Status_Wallbox_Power > 0 && $Status_WR_Amp < 0) {
            # Ermittle Zeit in sekunden vom Maximal_current
            my $Max_Curr_seconds = ReadingsAge("ModbusWallbox","Maximal_current",0);   
                       
            # Falls
            if ($Status_WB_Max_Curr < 70) {
                if ($Max_Curr_seconds > 10) {
                    $new_Maximal_current=0;
                } else {
                        $new_Maximal_current=$Status_WB_Max_Curr;
                }
            } else {
                $new_Maximal_current=$Status_WB_Max_Curr-10;
            }
                           
            fhem "set ModbusWallbox Maximal_current $new_Maximal_current" ;
            Log 1, "n_Wallbox_Ueberschuss_Steuerung : Wallbox wurde von $Status_WB_Max_Curr auf $new_Maximal_current gesetzt";
        }
      }

    # Wenn Haus auf Netz Strom ist und
    # ein Auto eingesteckt ist und
    if ("$Status_WR" eq "Line" && "$Status_Wallbox" eq "plugged_allow_charging") {

        # Kein Strom in das Auto und
        # Wechselrichter unter 4000 Watt sind und
        # Wallbox laed noch nicht und wird eingeschaltet.
        if ($Status_Wallbox_Power == 0 && $Status_WR_Pow < 4000) {   
            fhem "set ModbusWallbox Maximal_current 60" ;
            Log 1, "n_Wallbox_Ueberschuss_Steuerung : Wallbox war aus und wurde nun auf 6 Ampere gesetzt";
        }
                     
        if ($Status_Wallbox_Power > 0 && $Status_WR_Pow < 5000) {
            if ($Status_WB_Max_Curr > 150) {
                $new_Maximal_current=160;
            } else {
                # Setze den Ladestrom um 1 Ampere rauf
                $new_Maximal_current=$Status_WB_Max_Curr+10;
            }
                           
            fhem "set ModbusWallbox Maximal_current $new_Maximal_current" ;
            Log 1, "n_Wallbox_Ueberschuss_Steuerung : Wallbox wurde von $Status_WB_Max_Curr auf $new_Maximal_current gesetzt";
        }

        if ($Status_Wallbox_Power > 0 && $Status_WR_Pow > 6000) {   
            if ($Status_WB_Max_Curr < 70) {
                $new_Maximal_current=0;
            } else {
                # Setze den Ladestrom um 1 Ampere runter
                $new_Maximal_current=$Status_WB_Max_Curr-10;
            }
                           
            fhem "set ModbusWallbox Maximal_current $new_Maximal_current" ;
            Log 1, "n_Wallbox_Ueberschuss_Steuerung : Wallbox wurde von $Status_WB_Max_Curr auf $new_Maximal_current gesetzt";
        }
      }
}
   FUUID      62ed1174-f33f-9d1a-3e19-3abe64ef551cc99a
   NAME       n_Wallbox_Ueberschuss_Steuerung
   NR         69
   NTFY_ORDER 50-n_Wallbox_Ueberschuss_Steuerung
   REGEXP     (.*WR_Status_Structure.MAX_Power_Inv:.*)
   STATE      2025-03-09 13:49:54
   TRIGGERTIME 1741524594.86242
   TYPE       notify
   eventCount 24
   READINGS:
     2025-03-09 10:35:09   state           active
     2025-03-09 13:49:54   triggeredByDev  WR_Status_Structure
     2025-03-09 13:49:54   triggeredByEvent MAX_Power_Inv: 2393
Attributes:
   devStateIcon inactive:ios-off:active .*:ios-on-blue:inactive
   room       Automation,Wallbox
[/code]

Gruß Bülo

Buelo77

#1
Hier habe ich mal die Ladekurve der beiden Batteriebänke und die Auslastung der Wechselrichter angehängt.
Schön zu sehen, das die Batterie geladen wird bis sie ein SOC von 90% erreicht.
Ab da wird die Wallbox eingeschaltet und das Laden der Batteriebänke wird zwischen 0-10 Ampere gehalten.