From fbcc8063783e53b9480574536a034d338634f4e8 Mon Sep 17 00:00:00 2001 From: Alone Date: Thu, 16 Sep 2021 16:20:17 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=95=B9=EF=B8=8F=20add=20send=20ir=20comma?= =?UTF-8?q?nd=20via=20cloud?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- custom_components/xiaomi_miot/remote.py | 59 +++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/custom_components/xiaomi_miot/remote.py b/custom_components/xiaomi_miot/remote.py index 8f42ebf70..1e2b604eb 100644 --- a/custom_components/xiaomi_miot/remote.py +++ b/custom_components/xiaomi_miot/remote.py @@ -26,6 +26,10 @@ from .core.miot_spec import ( MiotSpec, ) +from .core.xiaomi_cloud import ( + MiotCloud, + MiCloudException, +) _LOGGER = logging.getLogger(__name__) DATA_KEY = f'{ENTITY_DOMAIN}.{DOMAIN}' @@ -64,6 +68,31 @@ def __init__(self, config, miot_spec: MiotSpec): self._attr_should_poll = False self._state_attrs.update({'entity_class': self.__class__.__name__}) + async def async_added_to_hass(self): + await super().async_added_to_hass() + did = self.miot_did + mic = self.miot_cloud + irs = [] + if did and isinstance(mic, MiotCloud): + dls = await mic.async_get_devices() or [] + for d in dls: + if did != d.get('parent_id'): + continue + ird = d.get('did') + rdt = await self.hass.async_add_executor_job( + partial(mic.request_miot_api, 'v2/irdevice/controller/keys', {'did': ird}) + ) or {} + kys = (rdt.get('result') or {}).get('keys', {}) + if not kys: + self.logger.info('%s: IR device %s(%s) have no keys: %s', self.name, ird, d.get('name'), rdt) + irs.append({ + 'did': ird, + 'name': d.get('name'), + 'keys': kys, + }) + if irs: + self._state_attrs['ir_devices'] = irs + def is_on(self): return True @@ -71,15 +100,39 @@ def send_remote_command(self, command, **kwargs): """Send commands to a device.""" repeat = kwargs.get(remote.ATTR_NUM_REPEATS, remote.DEFAULT_NUM_REPEATS) delays = kwargs.get(remote.ATTR_DELAY_SECS, remote.DEFAULT_DELAY_SECS) + did = kwargs.get(remote.ATTR_DEVICE) for _ in range(repeat): for cmd in command: try: - ret = self._device.play(cmd) - self.logger.debug('%s: Send IR command %s(%s) result: %s', self.name, cmd, kwargs, ret) - except DeviceException as exc: + if f'{cmd}'[:4] == 'key:': + ret = self.send_cloud_command(did, cmd) + else: + ret = self._device.play(cmd) + self.logger.info('%s: Send IR command %s(%s) result: %s', self.name, cmd, kwargs, ret) + except (DeviceException, MiCloudException) as exc: self.logger.error('%s: Send IR command %s(%s) failed: %s', self.name, cmd, kwargs, exc) time.sleep(delays) + def send_cloud_command(self, did, command): + key = f'{command}' + if key[:4] == 'key:': + key = key[4:] + try: + key = int(key) + except (TypeError, ValueError): + key = None + if not did or not key: + self.logger.warning('%s: IR command %s to %s invalid for cloud.', self.name, command, did) + return False + mic = self.miot_cloud + if not mic: + return False + res = mic.request_miot_api('v2/irdevice/controller/key/click', { + 'did': did, + 'key_id': key, + }) or {} + return res + async def async_send_command(self, command, **kwargs): """Send commands to a device.""" await self.hass.async_add_executor_job(