diff --git a/custom_components/goodwe/number.py b/custom_components/goodwe/number.py index 45dd10d..dee33d9 100644 --- a/custom_components/goodwe/number.py +++ b/custom_components/goodwe/number.py @@ -96,7 +96,21 @@ class GoodweNumberEntityDescription( native_min_value=0, native_max_value=100, getter=lambda inv: inv.read_setting("eco_mode_1"), - mapper=lambda v: v.power, + mapper=lambda v: abs(v.power) if v else 0, + setter=None, + filter=lambda inv: True, + ), + GoodweNumberEntityDescription( + key="eco_mode_soc", + name="Eco mode SoC", + icon="mdi:battery-charging-low", + entity_category=EntityCategory.CONFIG, + native_unit_of_measurement=PERCENTAGE, + native_step=1, + native_min_value=0, + native_max_value=100, + getter=lambda inv: inv.read_setting("eco_mode_1"), + mapper=lambda v: v.max_charge if v else 0, setter=None, filter=lambda inv: True, ), diff --git a/custom_components/goodwe/select.py b/custom_components/goodwe/select.py index 94f3feb..87c3341 100644 --- a/custom_components/goodwe/select.py +++ b/custom_components/goodwe/select.py @@ -53,39 +53,46 @@ async def async_setup_entry( # read current operating mode from the inverter try: active_mode = await inverter.get_operation_mode() + eco_mode = await inverter.read_setting("eco_mode_1") + current_eco_power = abs(eco_mode.power) if eco_mode else 0 + current_eco_soc = eco_mode.max_charge if eco_mode else 0 except (InverterError, ValueError): # Inverter model does not support this setting _LOGGER.debug("Could not read inverter operation mode") else: - active_power = None - try: - if active_mode: - active_power = (await inverter.read_setting("eco_mode_1")).power - except (InverterError, ValueError): - _LOGGER.debug("Could not read inverter eco mode") - active_power = 0 - entity = InverterOperationModeEntity( device_info, OPERATION_MODE, inverter, [v for k, v in _MODE_TO_OPTION.items() if k in supported_modes], _MODE_TO_OPTION[active_mode], - active_power, + current_eco_power, + current_eco_soc, ) async_add_entities([entity]) - eco_mode_entity_id = entity_registry.async_get(hass).async_get_entity_id( + eco_mode_power_entity_id = entity_registry.async_get(hass).async_get_entity_id( Platform.NUMBER, DOMAIN, f"{DOMAIN}-eco_mode_power-{inverter.serial_number}", ) - if eco_mode_entity_id: + if eco_mode_power_entity_id: async_track_state_change_event( hass, - eco_mode_entity_id, + eco_mode_power_entity_id, entity.update_eco_mode_power, ) + eco_mode_soc_entity_id = entity_registry.async_get(hass).async_get_entity_id( + Platform.NUMBER, + DOMAIN, + f"{DOMAIN}-eco_mode_soc-{inverter.serial_number}", + ) + if eco_mode_soc_entity_id: + async_track_state_change_event( + hass, + eco_mode_soc_entity_id, + entity.update_eco_mode_soc, + ) class InverterOperationModeEntity(SelectEntity): @@ -100,7 +107,8 @@ def __init__( inverter: Inverter, supported_options: list[str], current_mode: str, - current_power: int, + current_eco_power: int, + current_eco_soc: int, ) -> None: """Initialize the inverter operation mode setting entity.""" self.entity_description = description @@ -109,12 +117,19 @@ def __init__( self._attr_options = supported_options self._attr_current_option = current_mode self._inverter: Inverter = inverter - self._eco_mode_power = current_power + self._eco_mode_power = current_eco_power + self._eco_mode_soc = current_eco_soc async def async_select_option(self, option: str) -> None: """Change the selected option.""" + _LOGGER.debug( + "Settin operation mode to %s, power %d, max SoC %d", + option, + self._eco_mode_power, + self._eco_mode_soc, + ) await self._inverter.set_operation_mode( - _OPTION_TO_MODE[option], self._eco_mode_power + _OPTION_TO_MODE[option], self._eco_mode_power, self._eco_mode_soc ) self._attr_current_option = option self.async_write_ha_state() @@ -123,11 +138,26 @@ async def update_eco_mode_power(self, event: Event) -> None: """Update eco mode power value in inverter (when in eco mode)""" self._eco_mode_power = int(float(event.data.get("new_state").state)) if event.data.get("old_state"): - operation_mode = _OPTION_TO_MODE(self.current_option) + operation_mode = _OPTION_TO_MODE[self.current_option] + if operation_mode in ( + OperationMode.ECO_CHARGE, + OperationMode.ECO_DISCHARGE, + ): + _LOGGER.debug("Setting eco mode power to %d", self._eco_mode_power) + await self._inverter.set_operation_mode( + operation_mode, self._eco_mode_power, self._eco_mode_soc + ) + + async def update_eco_mode_soc(self, event: Event) -> None: + """Update eco mode SoC value in inverter (when in eco mode)""" + self._eco_mode_soc = int(float(event.data.get("new_state").state)) + if event.data.get("old_state"): + operation_mode = _OPTION_TO_MODE[self.current_option] if operation_mode in ( OperationMode.ECO_CHARGE, OperationMode.ECO_DISCHARGE, ): + _LOGGER.debug("Setting eco mode SoC to %d", self._eco_mode_soc) await self._inverter.set_operation_mode( - operation_mode, self._eco_mode_power + operation_mode, self._eco_mode_power, self._eco_mode_soc )