handle updatedps response

This commit is contained in:
Martín Villagra
2021-11-26 23:47:00 +00:00
parent 515b3303e9
commit 9c6de40731

View File

@@ -91,13 +91,13 @@ PAYLOAD_DICT = {
STATUS: {"hexByte": 0x0A, "command": {"gwId": "", "devId": ""}}, STATUS: {"hexByte": 0x0A, "command": {"gwId": "", "devId": ""}},
SET: {"hexByte": 0x07, "command": {"devId": "", "uid": "", "t": ""}}, SET: {"hexByte": 0x07, "command": {"devId": "", "uid": "", "t": ""}},
HEARTBEAT: {"hexByte": 0x09, "command": {}}, HEARTBEAT: {"hexByte": 0x09, "command": {}},
UPDATEDPS: {"hexByte": 0x12, "command": {"dpId": [18, 19, 20]}}, UPDATEDPS: {"hexByte": 0x12, "command": {"dpId": [4, 5, 6, 18, 19, 20]}},
}, },
"type_0d": { "type_0d": {
STATUS: {"hexByte": 0x0D, "command": {"devId": "", "uid": "", "t": ""}}, STATUS: {"hexByte": 0x0D, "command": {"devId": "", "uid": "", "t": ""}},
SET: {"hexByte": 0x07, "command": {"devId": "", "uid": "", "t": ""}}, SET: {"hexByte": 0x07, "command": {"devId": "", "uid": "", "t": ""}},
HEARTBEAT: {"hexByte": 0x09, "command": {}}, HEARTBEAT: {"hexByte": 0x09, "command": {}},
UPDATEDPS: {"hexByte": 0x12, "command": {"dpId": [18, 19, 20]}}, UPDATEDPS: {"hexByte": 0x12, "command": {"dpId": [4, 5, 6, 18, 19, 20]}},
}, },
} }
@@ -210,9 +210,11 @@ class AESCipher:
class MessageDispatcher(ContextualLogger): class MessageDispatcher(ContextualLogger):
"""Buffer and dispatcher for Tuya messages.""" """Buffer and dispatcher for Tuya messages."""
# Heartbeats always respond with sequence number 0, so they can't be waited for like # Heartbeats and updatedps always respond with sequence number 0,
# other messages. This is a hack to allow waiting for heartbeats. # so they can't be waited for like other messages.
# This is a hack to allow waiting for them.
HEARTBEAT_SEQNO = -100 HEARTBEAT_SEQNO = -100
UPDATEDPS_SEQNO = -101
def __init__(self, dev_id, listener): def __init__(self, dev_id, listener):
"""Initialize a new MessageBuffer.""" """Initialize a new MessageBuffer."""
@@ -295,9 +297,28 @@ class MessageDispatcher(ContextualLogger):
sem = self.listeners[self.HEARTBEAT_SEQNO] sem = self.listeners[self.HEARTBEAT_SEQNO]
self.listeners[self.HEARTBEAT_SEQNO] = msg self.listeners[self.HEARTBEAT_SEQNO] = msg
sem.release() 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: elif msg.cmd == 0x08:
self.debug("Got status update") # If we have an open updatedps call then this is for it.
self.listener(msg) # 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)
else: else:
self.debug( self.debug(
"Got message type %d for unknown listener %d: %s", "Got message type %d for unknown listener %d: %s",
@@ -443,12 +464,13 @@ class TuyaProtocol(asyncio.Protocol, ContextualLogger):
payload = self._generate_payload(command, dps) payload = self._generate_payload(command, dps)
dev_type = self.dev_type dev_type = self.dev_type
# Wait for special sequence number if heartbeat # Wait for special sequence number if heartbeat or updatedps
seqno = ( if command == HEARTBEAT:
MessageDispatcher.HEARTBEAT_SEQNO seqno = MessageDispatcher.HEARTBEAT_SEQNO
if command == HEARTBEAT elif command == UPDATEDPS:
else (self.seqno - 1) seqno = MessageDispatcher.UPDATEDPS_SEQNO
) else:
seqno = self.seqno - 1
self.transport.write(payload) self.transport.write(payload)
msg = await self.dispatcher.wait_for(seqno) msg = await self.dispatcher.wait_for(seqno)
@@ -482,15 +504,10 @@ class TuyaProtocol(asyncio.Protocol, ContextualLogger):
return await self.exchange(HEARTBEAT) return await self.exchange(HEARTBEAT)
async def updatedps(self): async def updatedps(self):
""" """Request device to update index."""
Request device to update index. if self.version == 3.3:
return await self.exchange(UPDATEDPS)
Args: return True
index(array): list of dps to update (ex. [4, 5, 6, 18, 19, 20])
"""
self.debug("updatedps() entry (dev_type is %s)", self.dev_type)
payload = self._generate_payload(UPDATEDPS)
self.transport.write(payload)
async def set_dp(self, value, dp_index): async def set_dp(self, value, dp_index):
""" """