From 0148f23cccf383fe6928461d6bfeb2684e1a8348 Mon Sep 17 00:00:00 2001 From: ndrsnhs Date: Thu, 18 Dec 2025 09:53:20 +0100 Subject: [PATCH 1/2] add possibility to charge --- .../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 | 19 +++++++++++++++++++ 5 files changed, 42 insertions(+), 4 deletions(-) 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 bf567720b6..cf25bec159 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_register(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_register(13049, 2, data_type=ModbusDataType.UINT_16, unit=unit) + self.__tcp_client.write_register(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_register(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 2465081473..603d7f728d 100644 --- a/packages/modules/devices/victron/victron/bat.py +++ b/packages/modules/devices/victron/victron/bat.py @@ -95,6 +95,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_register( 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_register(2902, 3, data_type=ModbusDataType.UINT_16, unit=modbus_id) + self.__tcp_client.write_register(39, 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_register( + 37, power_value & 0xFFFF, data_type=ModbusDataType.INT_16, unit=vebus_id) + if phases == 3: + self.__tcp_client.write_register( + 40, power_value & 0xFFFF, data_type=ModbusDataType.INT_16, unit=vebus_id) + self.__tcp_client.write_register( + 41, power_value & 0xFFFF, data_type=ModbusDataType.INT_16, unit=vebus_id) def power_limit_controllable(self) -> bool: return True From 8f0789b1ad73427345285d80472dedc09044419d Mon Sep 17 00:00:00 2001 From: LKuemmel <76958050+LKuemmel@users.noreply.github.com> Date: Mon, 23 Feb 2026 15:03:05 +0100 Subject: [PATCH 2/2] update write register methode --- packages/modules/devices/sigenergy/sigenergy/bat.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/modules/devices/sigenergy/sigenergy/bat.py b/packages/modules/devices/sigenergy/sigenergy/bat.py index 6429005374..05c0b0000d 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.client.write_registers(40048, [50], data_type=ModbusDataType.UINT_16, unit=unit) + self.client.write_register(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.client.write_registers(40048, [1000], data_type=ModbusDataType.UINT_16, unit=unit) + self.client.write_register(40048, [1000], data_type=ModbusDataType.UINT_16, unit=unit) self.last_mode = 'stop' def power_limit_controllable(self) -> bool: