From cc87e83982d8fed0402d17cb27b2d03c06c7f240 Mon Sep 17 00:00:00 2001 From: ndrsnhs Date: Thu, 18 Dec 2025 09:53:20 +0100 Subject: [PATCH] add possibility to charge --- .../devices/kostal/kostal_plenticore/bat.py | 17 +++++++++++++--- .../devices/sigenergy/sigenergy/bat.py | 4 ++-- .../modules/devices/solarmax/solarmax/bat.py | 3 ++- .../devices/sonnen/sonnenbatterie/bat.py | 10 +++++++++- .../modules/devices/sungrow/sungrow/bat.py | 10 ++++++++++ .../modules/devices/victron/victron/bat.py | 20 +++++++++++++++++++ 6 files changed, 57 insertions(+), 7 deletions(-) diff --git a/packages/modules/devices/kostal/kostal_plenticore/bat.py b/packages/modules/devices/kostal/kostal_plenticore/bat.py index 5065a75174..63444e094c 100644 --- a/packages/modules/devices/kostal/kostal_plenticore/bat.py +++ b/packages/modules/devices/kostal/kostal_plenticore/bat.py @@ -67,20 +67,31 @@ def set_power_limit(self, power_limit: Optional[int]) -> None: # Wert wird nur einmal gesetzt damit die Eigenregelung nach Timeout greift log.debug("Keine Batteriesteuerung, Selbstregelung durch Wechselrichter") if self.last_mode is not None: - self.__tcp_client.write_registers(1034, [0], data_type=ModbusDataType.FLOAT_32, unit=unit) + self.client.write_registers(1034, [0], data_type=ModbusDataType.FLOAT_32, unit=unit, + wordorder=self.endianess) self.last_mode = None elif power_limit == 0: # wiederholt auf Stop setzen damit sich Register nicht zurücksetzt log.debug("Aktive Batteriesteuerung. Batterie wird auf Stop gesetzt und nicht entladen") - self.__tcp_client.write_registers(1034, [0], data_type=ModbusDataType.FLOAT_32, unit=unit) + self.client.write_registers(1034, [0], data_type=ModbusDataType.FLOAT_32, unit=unit, + wordorder=self.endianess) self.last_mode = 'stop' elif power_limit < 0: log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W entladen für den Hausverbrauch") # Die maximale Entladeleistung begrenzen auf 7000W power_value = int(min(abs(power_limit), 7000)) * -1 log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W entladen für den Hausverbrauch") - self.__tcp_client.write_registers(1034, [power_value], data_type=ModbusDataType.FLOAT_32, unit=unit) + self.client.write_registers(1034, [power_value], data_type=ModbusDataType.FLOAT_32, unit=unit, + wordorder=self.endianess) self.last_mode = 'discharge' + elif power_limit > 0: + log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W geladen") + # Die maximale Ladeleistung begrenzen auf 7000W + power_value = int(min(power_limit, 7000)) + log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W geladen") + self.client.write_registers(1034, [power_value], data_type=ModbusDataType.FLOAT_32, unit=unit, + wordorder=self.endianess) + self.last_mode = 'charge' def power_limit_controllable(self) -> bool: return True diff --git a/packages/modules/devices/sigenergy/sigenergy/bat.py b/packages/modules/devices/sigenergy/sigenergy/bat.py index b27756e92a..6429005374 100644 --- a/packages/modules/devices/sigenergy/sigenergy/bat.py +++ b/packages/modules/devices/sigenergy/sigenergy/bat.py @@ -55,13 +55,13 @@ def set_power_limit(self, power_limit: Optional[int]) -> None: log.debug("Keine Batteriesteuerung, Selbstregelung durch Wechselrichter") if self.last_mode is not None: # Entladesperre ab 5%, Ansonsten Eigenregelung - self.__tcp_client.write_registers(40048, [50], data_type=ModbusDataType.UINT_16, unit=unit) + self.client.write_registers(40048, [50], data_type=ModbusDataType.UINT_16, unit=unit) self.last_mode = None else: log.debug("Aktive Batteriesteuerung. Batterie wird auf Stop gesetzt und nicht entladen") if self.last_mode != 'stop': # Entladesperre auch bei 100% SoC - self.__tcp_client.write_registers(40048, [1000], data_type=ModbusDataType.UINT_16, unit=unit) + self.client.write_registers(40048, [1000], data_type=ModbusDataType.UINT_16, unit=unit) self.last_mode = 'stop' def power_limit_controllable(self) -> bool: diff --git a/packages/modules/devices/solarmax/solarmax/bat.py b/packages/modules/devices/solarmax/solarmax/bat.py index 97e91d9f79..96364cc257 100644 --- a/packages/modules/devices/solarmax/solarmax/bat.py +++ b/packages/modules/devices/solarmax/solarmax/bat.py @@ -55,7 +55,8 @@ def set_power_limit(self, power_limit: Optional[int]) -> None: if self.last_mode is not None: self.__tcp_client.write_registers(142, [0], data_type=ModbusDataType.INT_16, unit=unit) self.last_mode = None - elif power_limit == 0: + elif power_limit >= 0: + # Solarmax kann nicht aktiv laden log.debug("Aktive Batteriesteuerung. Batterie wird auf Stop gesetzt und nicht entladen") self.__tcp_client.write_registers(140, [0], data_type=ModbusDataType.INT_16, unit=unit) self.__tcp_client.write_registers(141, [0], data_type=ModbusDataType.INT_16, unit=unit) diff --git a/packages/modules/devices/sonnen/sonnenbatterie/bat.py b/packages/modules/devices/sonnen/sonnenbatterie/bat.py index 0705216c59..bbf321b7fb 100644 --- a/packages/modules/devices/sonnen/sonnenbatterie/bat.py +++ b/packages/modules/devices/sonnen/sonnenbatterie/bat.py @@ -45,12 +45,20 @@ def initialize(self) -> None: self.api = JsonApi(host=self.__device_address, api_version=JsonApiVersion.V2 if self.__device_variant == 3 else JsonApiVersion.V1, auth_token=self.__api_v2_token if self.__device_variant == 3 else None) + self.last_mode = 'Undefined' def update(self) -> None: self.store.set(self.api.update_battery(sim_counter=self.sim_counter)) def set_power_limit(self, power_limit: Optional[int]) -> None: - self.api.set_power_limit(power_limit=power_limit) + if power_limit is None: + # Wert wird nur einmal gesetzt + if self.last_mode is not None: + self.api.set_power_limit(power_limit=power_limit) + self.last_mode = None + else: + self.api.set_power_limit(power_limit=power_limit) + self.last_mode = 'active' def power_limit_controllable(self) -> bool: return self.api.power_limit_controllable() diff --git a/packages/modules/devices/sungrow/sungrow/bat.py b/packages/modules/devices/sungrow/sungrow/bat.py index ef99e62237..0a8dc097a7 100644 --- a/packages/modules/devices/sungrow/sungrow/bat.py +++ b/packages/modules/devices/sungrow/sungrow/bat.py @@ -140,6 +140,16 @@ def set_power_limit(self, power_limit: Optional[int]) -> None: power_value = int(min(abs(power_limit), 5000)) log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W entladen für den Hausverbrauch") self.__tcp_client.write_registers(13051, [power_value], data_type=ModbusDataType.UINT_16, unit=unit) + elif power_limit > 0: + log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_limit} W geladen") + if self.last_mode != 'charge': + self.__tcp_client.write_registers(13049, [2], data_type=ModbusDataType.UINT_16, unit=unit) + self.__tcp_client.write_registers(13050, [0xAA], data_type=ModbusDataType.UINT_16, unit=unit) + self.last_mode = 'charge' + # Die maximale Entladeleistung begrenzen auf 5000W, maximaler Wertebereich Modbusregister. + power_value = int(min(power_limit, 5000)) + log.debug(f"Aktive Batteriesteuerung. Batterie wird mit {power_value} W geladen") + self.__tcp_client.write_registers(13051, [power_value], data_type=ModbusDataType.UINT_16, unit=unit) def power_limit_controllable(self) -> bool: return True diff --git a/packages/modules/devices/victron/victron/bat.py b/packages/modules/devices/victron/victron/bat.py index 3cfdf58048..8ee912ae94 100644 --- a/packages/modules/devices/victron/victron/bat.py +++ b/packages/modules/devices/victron/victron/bat.py @@ -67,6 +67,7 @@ def set_power_limit(self, power_limit: Optional[int]) -> None: if self.last_mode is not None: # ESS Mode 1 für Selbstregelung mit Phasenkompensation setzen self.__tcp_client.write_registers(2902, [1], data_type=ModbusDataType.UINT_16, unit=modbus_id) + self.__tcp_client.write_registers(38, [0], data_type=ModbusDataType.UINT_16, unit=vebus_id) self.__tcp_client.write_registers(39, [0], data_type=ModbusDataType.UINT_16, unit=vebus_id) self.last_mode = None elif power_limit == 0: @@ -95,6 +96,25 @@ def set_power_limit(self, power_limit: Optional[int]) -> None: 40, [power_value & 0xFFFF], data_type=ModbusDataType.INT_16, unit=vebus_id) self.__tcp_client.write_registers( 41, [power_value & 0xFFFF], data_type=ModbusDataType.INT_16, unit=vebus_id) + elif power_limit > 0: + if self.last_mode != 'charge': + # ESS Mode 3 für externe Steuerung und auf L1 wird entladen + self.__tcp_client.write_registers(2902, [3], data_type=ModbusDataType.UINT_16, unit=modbus_id) + self.__tcp_client.write_registers(38, [0], data_type=ModbusDataType.UINT_16, unit=vebus_id) + self.last_mode = 'charge' + # Die maximale Entladeleistung begrenzen auf 5000W + if phases == 3: + power_limit = power_limit / 3 + power_value = int(min(power_limit, 5000)) + log.debug(f"Aktive Batteriesteuerung. Victron mit {phases} Phase(n). " + f"Batterie wird mit {power_value} W pro Phase geladen.") + self.__tcp_client.write_registers( + 37, [power_value & 0xFFFF], data_type=ModbusDataType.INT_16, unit=vebus_id) + if phases == 3: + self.__tcp_client.write_registers( + 40, [power_value & 0xFFFF], data_type=ModbusDataType.INT_16, unit=vebus_id) + self.__tcp_client.write_registers( + 41, [power_value & 0xFFFF], data_type=ModbusDataType.INT_16, unit=vebus_id) def power_limit_controllable(self) -> bool: return True