diff --git a/custom_components/localtuya/pytuya/__init__.py b/custom_components/localtuya/pytuya/__init__.py index ecd0b7d..16ae271 100644 --- a/custom_components/localtuya/pytuya/__init__.py +++ b/custom_components/localtuya/pytuya/__init__.py @@ -92,13 +92,13 @@ PAYLOAD_DICT = { STATUS: {"hexByte": 0x0A, "command": {"gwId": "", "devId": ""}}, SET: {"hexByte": 0x07, "command": {"devId": "", "uid": "", "t": ""}}, HEARTBEAT: {"hexByte": 0x09, "command": {}}, - UPDATEDPS: {"hexByte": 0x12, "command": {"dpId": [4, 5, 6, 18, 19, 20]}}, + UPDATEDPS: {"hexByte": 0x12, "command": {"dpId": [18, 19, 20]}}, }, "type_0d": { STATUS: {"hexByte": 0x0D, "command": {"devId": "", "uid": "", "t": ""}}, SET: {"hexByte": 0x07, "command": {"devId": "", "uid": "", "t": ""}}, HEARTBEAT: {"hexByte": 0x09, "command": {}}, - UPDATEDPS: {"hexByte": 0x12, "command": {"dpId": [4, 5, 6, 18, 19, 20]}}, + UPDATEDPS: {"hexByte": 0x12, "command": {"dpId": [18, 19, 20]}}, }, } @@ -211,11 +211,9 @@ class AESCipher: class MessageDispatcher(ContextualLogger): """Buffer and dispatcher for Tuya messages.""" - # Heartbeats and updatedps always respond with sequence number 0, - # so they can't be waited for like other messages. - # This is a hack to allow waiting for them. + # Heartbeats always respond with sequence number 0, so they can't be waited for like + # other messages. This is a hack to allow waiting for heartbeats. HEARTBEAT_SEQNO = -100 - UPDATEDPS_SEQNO = -101 def __init__(self, dev_id, listener): """Initialize a new MessageBuffer.""" @@ -300,26 +298,9 @@ class MessageDispatcher(ContextualLogger): sem.release() elif msg.cmd == 0x12: self.debug("Got normal updatedps response") - if self.UPDATEDPS_SEQNO in self.listeners: - sem = self.listeners[self.UPDATEDPS_SEQNO] - self.listeners[self.UPDATEDPS_SEQNO] = msg - if isinstance(sem, asyncio.Semaphore): - sem.release() elif msg.cmd == 0x08: - # If we have an open updatedps call then this is for it. - # Some devices send 0x12 and 0x08 in response to a updatedps. - # Empty DPS responses here are always for updatedps - # but hey we haven't decoded yet to know - if self.UPDATEDPS_SEQNO in self.listeners and isinstance( - self.listeners[self.UPDATEDPS_SEQNO], asyncio.Semaphore - ): - self.debug("Got status type updatedps response") - sem = self.listeners[self.UPDATEDPS_SEQNO] - self.listeners[self.UPDATEDPS_SEQNO] = msg - sem.release() - else: - self.debug("Got status update") - self.listener(msg) + self.debug("Got status update") + self.listener(msg) else: self.debug( "Got message type %d for unknown listener %d: %s", @@ -465,13 +446,12 @@ class TuyaProtocol(asyncio.Protocol, ContextualLogger): payload = self._generate_payload(command, dps) dev_type = self.dev_type - # Wait for special sequence number if heartbeat or updatedps - if command == HEARTBEAT: - seqno = MessageDispatcher.HEARTBEAT_SEQNO - elif command == UPDATEDPS: - seqno = MessageDispatcher.UPDATEDPS_SEQNO - else: - seqno = self.seqno - 1 + # Wait for special sequence number if heartbeat + seqno = ( + MessageDispatcher.HEARTBEAT_SEQNO + if command == HEARTBEAT + else (self.seqno - 1) + ) self.transport.write(payload) msg = await self.dispatcher.wait_for(seqno) @@ -509,10 +489,17 @@ class TuyaProtocol(asyncio.Protocol, ContextualLogger): Request device to update index. Args: - dps([int]): list of dps to update + dps([int]): list of dps to update, default=all detected """ if self.version == 3.3: - return await self.exchange(UPDATEDPS, dps) + if dps is None: + if not self.dps_cache: + await self.detect_available_dps() + if self.dps_cache: + dps = [int(dp) for dp in self.dps_cache][:255] + self.debug("updatedps() entry (dps %s)", dps) + payload = self._generate_payload(UPDATEDPS, dps) + self.transport.write(payload) return True async def set_dp(self, value, dp_index):