From 353299063d63846e7080effc61f0e30763725e74 Mon Sep 17 00:00:00 2001 From: "andreas.sylvan" Date: Fri, 12 Jan 2024 01:35:39 +0100 Subject: [PATCH] Support toggling features * Support toggling Ionizer, UILight and SafetyLock * Add Swedish translation * Small fix for translations * Handle incorrect fan speed percentage ( hopefully fixing https://github.com/JohNan/homeassistant-wellbeing/issues/66) Tested on A9/AX9 --- custom_components/wellbeing/api.py | 7 +++ custom_components/wellbeing/const.py | 3 +- custom_components/wellbeing/fan.py | 14 +++++- custom_components/wellbeing/switch.py | 45 +++++++++++++++++++ .../wellbeing/translations/en.json | 7 ++- .../wellbeing/translations/fr.json | 2 +- .../wellbeing/translations/nb.json | 2 +- .../wellbeing/translations/pl.json | 2 +- .../wellbeing/translations/se.json | 38 ++++++++++++++++ 9 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 custom_components/wellbeing/switch.py create mode 100644 custom_components/wellbeing/translations/se.json diff --git a/custom_components/wellbeing/api.py b/custom_components/wellbeing/api.py index cf00289..7947641 100644 --- a/custom_components/wellbeing/api.py +++ b/custom_components/wellbeing/api.py @@ -434,6 +434,13 @@ async def set_work_mode(self, pnc_id: str, mode: Mode): result = await self._send_command(self._current_access_token, pnc_id, data) _LOGGER.debug(f"Set Fan Speed: {result}") + async def set_feature_state(self, pnc_id: str, feature: str, state: bool): + """Set the state of a feature (Ionizer, UILight, SafetyLock).""" + # Construct the command directly using the feature name + data = {feature: state} + await self._send_command(self._current_access_token, pnc_id, data) + _LOGGER.debug(f"Set {feature} State to {state}") + async def _send_command(self, access_token: str, pnc_id: str, command: dict) -> None: """Get data from the API.""" headers = { diff --git a/custom_components/wellbeing/const.py b/custom_components/wellbeing/const.py index fcc2d44..584c080 100644 --- a/custom_components/wellbeing/const.py +++ b/custom_components/wellbeing/const.py @@ -15,7 +15,8 @@ SENSOR = "sensor" SWITCH = "switch" FAN = "fan" -PLATFORMS = [SENSOR, FAN, BINARY_SENSOR] +SWITCH = "switch" +PLATFORMS = [SENSOR, FAN, BINARY_SENSOR, SWITCH] # Configuration and options CONF_ENABLED = "enabled" diff --git a/custom_components/wellbeing/fan.py b/custom_components/wellbeing/fan.py index 515340f..9e5ae17 100644 --- a/custom_components/wellbeing/fan.py +++ b/custom_components/wellbeing/fan.py @@ -114,9 +114,18 @@ async def async_set_preset_mode(self, preset_mode: str) -> None: def is_on(self): return self.preset_mode is not Mode.OFF - async def async_turn_on(self, speed: str = None, percentage: int = None, - preset_mode: str = None, **kwargs) -> None: + async def async_turn_on(self, speed: str = None, percentage: int = None, preset_mode: str = None, **kwargs) -> None: self._preset_mode = Mode(preset_mode or Mode.AUTO.value) + + # Handle incorrect percentage + if percentage is not None and isinstance(percentage, str): + try: + percentage = int(percentage) + except ValueError: + _LOGGER.error(f"Invalid percentage value: {percentage}") + return + + # Proceed with the provided or default percentage self._speed = math.floor(percentage_to_ranged_value(self._speed_range, percentage or 10)) self.get_appliance.clear_mode() self.get_entity.clear_state() @@ -127,6 +136,7 @@ async def async_turn_on(self, speed: str = None, percentage: int = None, await asyncio.sleep(10) await self.coordinator.async_request_refresh() + async def async_turn_off(self, **kwargs) -> None: """Turn off the entity.""" self._preset_mode = Mode.OFF diff --git a/custom_components/wellbeing/switch.py b/custom_components/wellbeing/switch.py new file mode 100644 index 0000000..0b52c58 --- /dev/null +++ b/custom_components/wellbeing/switch.py @@ -0,0 +1,45 @@ +"""Switch platform for Wellbeing.""" +from homeassistant.components.switch import SwitchEntity +from .const import DOMAIN +from .entity import WellbeingEntity + +async def async_setup_entry(hass, entry, async_add_devices): + """Setup switch platform.""" + coordinator = hass.data[DOMAIN][entry.entry_id] + appliances = coordinator.data.get('appliances', None) + + if appliances is not None: + for pnc_id, appliance in appliances.appliances.items(): + # Assuming that the appliance supports these features + async_add_devices([ + WellbeingSwitch(coordinator, entry, pnc_id, "Ionizer"), + WellbeingSwitch(coordinator, entry, pnc_id, "UILight"), + WellbeingSwitch(coordinator, entry, pnc_id, "SafetyLock"), + ]) + +class WellbeingSwitch(WellbeingEntity, SwitchEntity): + """Wellbeing Switch class.""" + + def __init__(self, coordinator, config_entry, pnc_id, function): + super().__init__(coordinator, config_entry, pnc_id, "binary_sensor", function) + self._function = function + self._is_on = self.get_entity.state + + @property + def is_on(self): + """Return true if switch is on.""" + return self._is_on + + async def async_turn_on(self, **kwargs): + """Turn the switch on.""" + await self.coordinator.api.set_feature_state(self.pnc_id, self._function, True) + self._is_on = True + self.async_write_ha_state() + await self.coordinator.async_request_refresh() + + async def async_turn_off(self, **kwargs): + """Turn the switch off.""" + await self.coordinator.api.set_feature_state(self.pnc_id, self._function, False) + self._is_on = False + self.async_write_ha_state() + await self.coordinator.async_request_refresh() diff --git a/custom_components/wellbeing/translations/en.json b/custom_components/wellbeing/translations/en.json index 041a79e..475262c 100644 --- a/custom_components/wellbeing/translations/en.json +++ b/custom_components/wellbeing/translations/en.json @@ -13,7 +13,7 @@ "password": "Password" }, "description": "Enter the password for {username}.", - "title": "Reauthenticate an August account" + "title": "Reauthenticate an Electrolux account" } }, "error": { @@ -27,7 +27,10 @@ "step": { "user": { "data": { - "scan_interval": "API update interval (seconds)" + "scan_interval": "API update interval (seconds)", + "binary_sensor": "Binary sensor activated", + "sensor": "Sensor activated", + "switch": "Switch activated" } } } diff --git a/custom_components/wellbeing/translations/fr.json b/custom_components/wellbeing/translations/fr.json index 5844ad2..bc966b8 100644 --- a/custom_components/wellbeing/translations/fr.json +++ b/custom_components/wellbeing/translations/fr.json @@ -13,7 +13,7 @@ "password": "Password" }, "description": "Enter the password for {username}.", - "title": "Reauthenticate an August account" + "title": "Reauthenticate an Electrolux account" } }, "error": { diff --git a/custom_components/wellbeing/translations/nb.json b/custom_components/wellbeing/translations/nb.json index 55f707a..f87a4aa 100644 --- a/custom_components/wellbeing/translations/nb.json +++ b/custom_components/wellbeing/translations/nb.json @@ -13,7 +13,7 @@ "password": "Password" }, "description": "Enter the password for {username}.", - "title": "Reauthenticate an August account" + "title": "Reauthenticate an Electrolux account" } }, "error": { diff --git a/custom_components/wellbeing/translations/pl.json b/custom_components/wellbeing/translations/pl.json index 52a3249..aa5155d 100644 --- a/custom_components/wellbeing/translations/pl.json +++ b/custom_components/wellbeing/translations/pl.json @@ -13,7 +13,7 @@ "password": "Password" }, "description": "Enter the password for {username}.", - "title": "Reauthenticate an August account" + "title": "Reauthenticate an Electrolux account" } }, "error": { diff --git a/custom_components/wellbeing/translations/se.json b/custom_components/wellbeing/translations/se.json new file mode 100644 index 0000000..d8c2722 --- /dev/null +++ b/custom_components/wellbeing/translations/se.json @@ -0,0 +1,38 @@ +{ + "config": { + "step": { + "user": { + "description": "Om du behöver hjälp med konfigurationen, se här: https://github.com/JohNan/homeassistant-wellbeing", + "data": { + "username": "Användarnamn", + "password": "Lösenord" + } + }, + "reauth_validate": { + "data": { + "password": "Lösenord" + }, + "description": "Ange lösenord för {username}.", + "title": "Återautentisera Electrolux-kontot" + } + }, + "error": { + "auth": "Användarnamn eller lösenord är felaktigt." + }, + "abort": { + "single_instance_allowed": "Endast en instans är tillåten." + } + }, + "options": { + "step": { + "user": { + "data": { + "scan_interval": "API-uppdateringsintervall (sekunder)", + "binary_sensor": "Binär sensor aktiverad", + "sensor": "Sensor aktiverad", + "switch": "Brytare aktiverad" + } + } + } + } +}