From ce4a107c9e5c886034d7a57073f8449417e6caeb Mon Sep 17 00:00:00 2001 From: ollo69 Date: Fri, 26 Jan 2024 22:26:48 +0000 Subject: [PATCH] Implement Hood ApiV1 device controls --- .../smartthinq_sensors/wideq/devices/hood.py | 74 ++++++++++++++----- .../wideq/devices/microwave.py | 33 +++++---- 2 files changed, 74 insertions(+), 33 deletions(-) diff --git a/custom_components/smartthinq_sensors/wideq/devices/hood.py b/custom_components/smartthinq_sensors/wideq/devices/hood.py index 761a8d40..7fbb779b 100644 --- a/custom_components/smartthinq_sensors/wideq/devices/hood.py +++ b/custom_components/smartthinq_sensors/wideq/devices/hood.py @@ -19,20 +19,34 @@ CMD_LAMPLEVEL = "lampLevel" CMD_VENTMODE = "ventOnOff" CMD_VENTLEVEL = "ventLevel" +CMD_VENTTIMER = "ventTimer" CMD_SET_VENTLAMP = "setCookStart" KEY_DATASET = "dataSetList" KEY_HOODSTATE = "hoodState" -CMD_VENTLAMP_DICT = { +CMD_VENTLAMP_V1_DICT = { + "cmd": "Control", + "cmdOpt": "Operation", + "value": "Start", + "data": "", +} + +CMD_VENTLAMP_V2_DICT = { "command": "Set", "ctrlKey": CMD_SET_VENTLAMP, - KEY_DATASET: {KEY_HOODSTATE: {}}, + KEY_DATASET: { + KEY_HOODSTATE: { + "contentType": 22, + "dataLength": 5, + CMD_VENTTIMER: 0, + } + }, } HOOD_CMD = { - CMD_SET_VENTLAMP: CMD_VENTLAMP_DICT, + CMD_SET_VENTLAMP: CMD_VENTLAMP_V2_DICT, } MODE_ENABLE = "ENABLE" @@ -70,8 +84,26 @@ def reset_status(self): return self._status # Settings - def _prepare_command_ventlamp(self): - """Prepare vent / lamp command.""" + def _prepare_command_ventlamp_v1(self, command): + """Prepare vent / lamp command for API V1 devices.""" + if not self._status: + return {} + + status_data = self._status.data + if (vent_level := command.get(CMD_VENTLEVEL)) is None: + vent_level = status_data.get(STATE_VENTLEVEL, "0") + if (lamp_level := command.get(CMD_LAMPLEVEL)) is None: + lamp_level = status_data.get(STATE_LAMPLEVEL, "0") + vent_state = "01" if int(vent_level) != 0 else "00" + lamp_state = "01" if int(lamp_level) != 0 else "00" + data = ( + f"2205{vent_state}{int(vent_level):02d}{lamp_state}{int(lamp_level):02d}00" + ) + + return {**CMD_VENTLAMP_V1_DICT, "data": data} + + def _prepare_command_ventlamp_v2(self): + """Prepare vent / lamp command for API V2 devices.""" if not self._status: return {} @@ -79,22 +111,34 @@ def _prepare_command_ventlamp(self): vent_level = status_data.get(STATE_VENTLEVEL, "0") lamp_level = status_data.get(STATE_LAMPLEVEL, "0") return { - CMD_VENTMODE: MODE_ENABLE if vent_level != "0" else MODE_DISABLE, + CMD_VENTMODE: MODE_ENABLE if int(vent_level) != 0 else MODE_DISABLE, CMD_VENTLEVEL: int(vent_level), - CMD_LAMPMODE: MODE_ENABLE if lamp_level != "0" else MODE_DISABLE, + CMD_LAMPMODE: MODE_ENABLE if int(lamp_level) != 0 else MODE_DISABLE, CMD_LAMPLEVEL: int(lamp_level), } + def _prepare_command_v1(self, ctrl_key, command, key, value): + """ + Prepare command for specific API V1 device. + Overwrite for specific device settings. + """ + if ctrl_key == CMD_SET_VENTLAMP: + return self._prepare_command_ventlamp_v1(command) + return None + def _prepare_command(self, ctrl_key, command, key, value): """ Prepare command for specific device. Overwrite for specific device settings. """ + if self._should_poll: + return self._prepare_command_v1(ctrl_key, command, key, value) + if (cmd_key := HOOD_CMD.get(ctrl_key)) is None: return None if ctrl_key == CMD_SET_VENTLAMP: - full_cmd = self._prepare_command_ventlamp() + full_cmd = self._prepare_command_ventlamp_v2() else: full_cmd = {} @@ -128,7 +172,7 @@ async def set_light_mode(self, mode: str): status = MODE_ENABLE if level != "0" else MODE_DISABLE cmd = {CMD_LAMPMODE: status, CMD_LAMPLEVEL: int(level)} - await self.set(CMD_SET_VENTLAMP, cmd, key=STATE_LAMPLEVEL, value=level) + await self.set_val(CMD_SET_VENTLAMP, cmd, key=STATE_LAMPLEVEL, value=level) # Vent @cached_property @@ -154,15 +198,11 @@ async def set_vent_speed(self, option: str): mode = MODE_ENABLE if level != "0" else MODE_DISABLE cmd = {CMD_VENTMODE: mode, CMD_VENTLEVEL: int(level)} - await self.set(CMD_SET_VENTLAMP, cmd, key=STATE_VENTLEVEL, value=level) + await self.set_val(CMD_SET_VENTLAMP, cmd, key=STATE_VENTLEVEL, value=level) - async def set( - self, ctrl_key, command, *, key=None, value=None, data=None, ctrl_path=None - ): - """Set a device's control for `key` to `value`.""" - await super().set( - ctrl_key, command, key=key, value=value, data=data, ctrl_path=ctrl_path - ) + async def set_val(self, ctrl_key, command, key=None, value=None): + """Set a device's control for hood and update status.""" + await self.set(ctrl_key, command) if self._status and key is not None: self._status.update_status(key, value) diff --git a/custom_components/smartthinq_sensors/wideq/devices/microwave.py b/custom_components/smartthinq_sensors/wideq/devices/microwave.py index 6331a37f..1d997cf0 100644 --- a/custom_components/smartthinq_sensors/wideq/devices/microwave.py +++ b/custom_components/smartthinq_sensors/wideq/devices/microwave.py @@ -140,9 +140,9 @@ def _prepare_command_ventlamp(self): vent_level = status_data.get(STATE_VENTLEVEL, "0") lamp_level = status_data.get(STATE_LAMPLEVEL, "0") return { - CMD_VENTMODE: MODE_ENABLE if vent_level != "0" else MODE_DISABLE, + CMD_VENTMODE: MODE_ENABLE if int(vent_level) != 0 else MODE_DISABLE, CMD_VENTLEVEL: int(vent_level), - CMD_LAMPMODE: MODE_ENABLE if lamp_level != "0" else MODE_DISABLE, + CMD_LAMPMODE: MODE_ENABLE if int(lamp_level) != 0 else MODE_DISABLE, CMD_LAMPLEVEL: int(lamp_level), } @@ -151,6 +151,9 @@ def _prepare_command(self, ctrl_key, command, key, value): Prepare command for specific device. Overwrite for specific device settings. """ + if self._should_poll: + raise ValueError("Control not supported for this device") + if (cmd_key := MW_CMD.get(ctrl_key)) is None: return None @@ -170,7 +173,7 @@ async def set_clock_display(self, turn_on: bool): """Set display clock on/off.""" state = MODE_CLKON if turn_on else MODE_CLKOFF cmd = {CMD_CLOCKDISPLAY: state} - await self.set(CMD_SET_PREFERENCE, cmd, key=STATE_CLOCKDISPLAY, value=state) + await self.set_val(CMD_SET_PREFERENCE, cmd, key=STATE_CLOCKDISPLAY, value=state) async def set_time(self, time_wanted: time | None = None): """Set time on microwave.""" @@ -182,14 +185,14 @@ async def set_time(self, time_wanted: time | None = None): CMD_TIMEMIN: time_wanted.minute, CMD_TIMESEC: time_wanted.second, } - await self.set(CMD_SET_PREFERENCE, cmd) + await self.set_val(CMD_SET_PREFERENCE, cmd) # Sound async def set_sound(self, turn_on: bool): """Set sound on/off.""" state = MODE_VOLON if turn_on else MODE_VOLOFF cmd = {CMD_SOUND: state} - await self.set(CMD_SET_PREFERENCE, cmd, key=STATE_SOUND, value=state) + await self.set_val(CMD_SET_PREFERENCE, cmd, key=STATE_SOUND, value=state) # Unit @cached_property @@ -202,7 +205,7 @@ async def set_defrost_weight_unit(self, unit: str): if unit not in self.defrost_weight_units: raise ValueError(f"Invalid display unit: {unit}") cmd = {CMD_DEFROSTWMODE: unit} - await self.set(CMD_SET_PREFERENCE, cmd, key=STATE_DEFROSTWMODE, value=unit) + await self.set_val(CMD_SET_PREFERENCE, cmd, key=STATE_DEFROSTWMODE, value=unit) # Display @cached_property @@ -216,7 +219,9 @@ async def set_display_scroll_speed(self, speed: str): raise ValueError(f"Invalid display scroll speed: {speed}") cmd = {CMD_DISPLAYSCROLL: speed} - await self.set(CMD_SET_PREFERENCE, cmd, key=STATE_DISPLAYSCROLL, value=speed) + await self.set_val( + CMD_SET_PREFERENCE, cmd, key=STATE_DISPLAYSCROLL, value=speed + ) # Light @cached_property @@ -242,7 +247,7 @@ async def set_light_mode(self, mode: str): status = MODE_ENABLE if level != "0" else MODE_DISABLE cmd = {CMD_LAMPMODE: status, CMD_LAMPLEVEL: int(level)} - await self.set(CMD_SET_VENTLAMP, cmd, key=STATE_LAMPLEVEL, value=level) + await self.set_val(CMD_SET_VENTLAMP, cmd, key=STATE_LAMPLEVEL, value=level) # Vent @cached_property @@ -268,15 +273,11 @@ async def set_vent_speed(self, option: str): mode = MODE_ENABLE if level != "0" else MODE_DISABLE cmd = {CMD_VENTMODE: mode, CMD_VENTLEVEL: int(level)} - await self.set(CMD_SET_VENTLAMP, cmd, key=STATE_VENTLEVEL, value=level) + await self.set_val(CMD_SET_VENTLAMP, cmd, key=STATE_VENTLEVEL, value=level) - async def set( - self, ctrl_key, command, *, key=None, value=None, data=None, ctrl_path=None - ): - """Set a device's control for `key` to `value`.""" - await super().set( - ctrl_key, command, key=key, value=value, data=data, ctrl_path=ctrl_path - ) + async def set_val(self, ctrl_key, command, key=None, value=None): + """Set a device's control for microwave and update status.""" + await self.set(ctrl_key, command) if self._status and key is not None: self._status.update_status(key, value)