From c225f4b4eaf05f7c9fa78f1d1e706ba69d591444 Mon Sep 17 00:00:00 2001 From: Felipe Martins Diel <41558831+felipediel@users.noreply.github.com> Date: Wed, 27 Jan 2021 06:14:11 -0300 Subject: [PATCH] Implement remote.delete_command in the Broadlink integration (#44041) --- homeassistant/components/broadlink/remote.py | 65 +++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/broadlink/remote.py b/homeassistant/components/broadlink/remote.py index 5d0d618d7be..116c97aeb31 100644 --- a/homeassistant/components/broadlink/remote.py +++ b/homeassistant/components/broadlink/remote.py @@ -23,7 +23,10 @@ from homeassistant.components.remote import ( ATTR_DEVICE, ATTR_NUM_REPEATS, DEFAULT_DELAY_SECS, + DOMAIN as RM_DOMAIN, PLATFORM_SCHEMA, + SERVICE_DELETE_COMMAND, + SUPPORT_DELETE_COMMAND, SUPPORT_LEARN_COMMAND, RemoteEntity, ) @@ -48,6 +51,8 @@ COMMAND_TYPES = [COMMAND_TYPE_IR, COMMAND_TYPE_RF] CODE_STORAGE_VERSION = 1 FLAG_STORAGE_VERSION = 1 + +CODE_SAVE_DELAY = 15 FLAG_SAVE_DELAY = 15 COMMAND_SCHEMA = vol.Schema( @@ -74,6 +79,10 @@ SERVICE_LEARN_SCHEMA = COMMAND_SCHEMA.extend( } ) +SERVICE_DELETE_SCHEMA = COMMAND_SCHEMA.extend( + {vol.Required(ATTR_DEVICE): vol.All(cv.string, vol.Length(min=1))} +) + PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( {vol.Required(CONF_HOST): cv.string}, extra=vol.ALLOW_EXTRA ) @@ -149,7 +158,7 @@ class BroadlinkRemote(RemoteEntity, RestoreEntity): @property def supported_features(self): """Flag supported features.""" - return SUPPORT_LEARN_COMMAND + return SUPPORT_LEARN_COMMAND | SUPPORT_DELETE_COMMAND @property def device_info(self): @@ -196,6 +205,11 @@ class BroadlinkRemote(RemoteEntity, RestoreEntity): except ValueError as err: raise ValueError("Invalid code") from err + @callback + def get_codes(self): + """Return a dictionary of codes.""" + return self._codes + @callback def get_flags(self): """Return a dictionary of toggle flags. @@ -434,3 +448,52 @@ class BroadlinkRemote(RemoteEntity, RestoreEntity): self.hass.components.persistent_notification.async_dismiss( notification_id="learn_command" ) + + async def async_delete_command(self, **kwargs): + """Delete a list of commands from a remote.""" + kwargs = SERVICE_DELETE_SCHEMA(kwargs) + commands = kwargs[ATTR_COMMAND] + device = kwargs[ATTR_DEVICE] + service = f"{RM_DOMAIN}.{SERVICE_DELETE_COMMAND}" + + if not self._state: + _LOGGER.warning( + "%s canceled: %s entity is turned off", + service, + self.entity_id, + ) + return + + try: + codes = self._codes[device] + except KeyError as err: + err_msg = f"Device not found: {repr(device)}" + _LOGGER.error("Failed to call %s. %s", service, err_msg) + raise ValueError(err_msg) from err + + cmds_not_found = [] + for command in commands: + try: + del codes[command] + except KeyError: + cmds_not_found.append(command) + + if cmds_not_found: + if len(cmds_not_found) == 1: + err_msg = f"Command not found: {repr(cmds_not_found[0])}" + else: + err_msg = f"Commands not found: {repr(cmds_not_found)}" + + if len(cmds_not_found) == len(commands): + _LOGGER.error("Failed to call %s. %s", service, err_msg) + raise ValueError(err_msg) + + _LOGGER.error("Error during %s. %s", service, err_msg) + + # Clean up + if not codes: + del self._codes[device] + if self._flags.pop(device, None) is not None: + self._flag_storage.async_delay_save(self.get_flags, FLAG_SAVE_DELAY) + + self._code_storage.async_delay_save(self.get_codes, CODE_SAVE_DELAY)