Add retry logic to recieving messages
This commit is contained in:
parent
40480cc319
commit
bea3817c5e
|
|
@ -347,6 +347,10 @@ class RequestResponseCommandMismatch(TuyaException):
|
|||
"""The command in the response didn't match the one from the request."""
|
||||
|
||||
|
||||
class ResponseTimeoutException(TuyaException):
|
||||
"""Did not recieve a response to the request within the timeout"""
|
||||
|
||||
|
||||
class TuyaCipher:
|
||||
"""Tuya cryptographic helpers."""
|
||||
|
||||
|
|
@ -445,10 +449,10 @@ class Message:
|
|||
payload = b""
|
||||
self.payload = payload
|
||||
self.command = command
|
||||
self.original_sequence = sequence
|
||||
if sequence is None:
|
||||
# Use millisecond process time as the sequence number. Not ideal,
|
||||
# but good for one month's continuous connection time though.
|
||||
sequence = int(time.perf_counter() * 1000) & 0xFFFFFFFF
|
||||
self.set_sequence()
|
||||
else:
|
||||
self.sequence = sequence
|
||||
self.encrypt = False
|
||||
self.device = None
|
||||
|
|
@ -465,6 +469,9 @@ class Message:
|
|||
"<Device {}>".format(self.device) if self.device else None,
|
||||
)
|
||||
|
||||
def set_sequence(self):
|
||||
self.sequence = int(time.perf_counter() * 1000) & 0xFFFFFFFF
|
||||
|
||||
def hex(self):
|
||||
return self.bytes().hex()
|
||||
|
||||
|
|
@ -496,7 +503,7 @@ class Message:
|
|||
|
||||
__bytes__ = bytes
|
||||
|
||||
async def async_send(self, device):
|
||||
async def async_send(self, device, retries=4):
|
||||
device._listeners[self.sequence] = asyncio.Semaphore(0)
|
||||
await device._async_send(self)
|
||||
try:
|
||||
|
|
@ -504,13 +511,24 @@ class Message:
|
|||
device._listeners[self.sequence].acquire(), timeout=device.timeout
|
||||
)
|
||||
except:
|
||||
_LOGGER.debug(
|
||||
del device._listeners[self.sequence]
|
||||
if retries == 0:
|
||||
raise ResponseTimeoutException(
|
||||
"Timed out waiting for response to sequence number {}".format(
|
||||
self.sequence
|
||||
)
|
||||
)
|
||||
del device._listeners[self.sequence]
|
||||
raise
|
||||
|
||||
_LOGGER.debug(
|
||||
"Timed out waiting for response to sequence number {}. Retrying".format(
|
||||
self.sequence
|
||||
)
|
||||
)
|
||||
|
||||
if self.original_sequence is None:
|
||||
self.set_sequence()
|
||||
|
||||
return self.async_send(device, retries - 1)
|
||||
|
||||
return device._listeners.pop(self.sequence)
|
||||
|
||||
|
|
@ -734,9 +752,9 @@ class TuyaDevice:
|
|||
response_data = await self.reader.readuntil(MAGIC_SUFFIX_BYTES)
|
||||
message = Message.from_bytes(response_data, self.cipher)
|
||||
except InvalidMessage as e:
|
||||
_LOGGER.error("Invalid message from {}: {}".format(self, e))
|
||||
_LOGGER.debug("Invalid message from {}: {}".format(self, e))
|
||||
except MessageDecodeFailed as e:
|
||||
_LOGGER.error("Failed to decrypt message from {}".format(self))
|
||||
_LOGGER.debug("Failed to decrypt message from {}".format(self))
|
||||
else:
|
||||
_LOGGER.debug("Received message from {}: {}".format(self, message))
|
||||
if message.sequence in self._listeners:
|
||||
|
|
|
|||
Loading…
Reference in New Issue