Skip to content

Commit

Permalink
Move message handling call to inside the send command so that we can …
Browse files Browse the repository at this point in the history
…retry if necessary
  • Loading branch information
CodeFoodPixels committed Aug 31, 2023
1 parent bba9feb commit 7f344d3
Showing 1 changed file with 33 additions and 22 deletions.
55 changes: 33 additions & 22 deletions custom_components/robovac/tuyalocalapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -681,9 +681,6 @@ async def async_connect(self, callback=None):
raise ConnectionTimeoutException("Connection timed out") from e
self.reader, self.writer = await asyncio.open_connection(sock=sock)
self._connected = True
asyncio.ensure_future(self._async_handle_message())
asyncio.ensure_future(self._async_ping(self.ping_interval))
asyncio.ensure_future(self.async_get(callback))

async def async_disconnect(self):
_LOGGER.debug("Disconnected from {}".format(self))
Expand Down Expand Up @@ -737,16 +734,7 @@ def state_setter(self, new_values):
asyncio.ensure_future(self.async_set(new_values))

async def _async_handle_message(self):
try:
response_data = await self.reader.readuntil(MAGIC_SUFFIX_BYTES)
except socket.error as e:
_LOGGER.error("Connection to {} failed: {}".format(self, e))
self._dps["106"] = "CONNECTION_FAILED"
asyncio.ensure_future(self.async_disconnect())
return
except asyncio.IncompleteReadError as e:
_LOGGER.error("Incomplete read from: {} : {}".format(self, e))
return
response_data = await self.reader.readuntil(MAGIC_SUFFIX_BYTES)

try:
message = Message.from_bytes(response_data, self.cipher)
Expand All @@ -759,17 +747,40 @@ async def _async_handle_message(self):
for c in self._handlers.get(message.command, []):
asyncio.ensure_future(c(message, self))

asyncio.ensure_future(self._async_handle_message())

async def _async_send(self, message, retries=4):
try:
await self.async_connect()
except (socket.timeout, socket.error, OSError) as e:
_LOGGER.debug("Sending to {}: {}".format(self, message))
self.writer.write(message.bytes())
await self.writer.drain()
await self._async_handle_message()
except Exception as e:
if retries == 0:
raise ConnectionException(
"Failed to send data to {}".format(self)
) from e
await self.async_connect()
if isinstance(e, socket.error):
_LOGGER.error("Connection to {} failed: {}".format(self, e))
self._dps["106"] = "CONNECTION_FAILED"
asyncio.ensure_future(self.async_disconnect())
elif isinstance(e, asyncio.IncompleteReadError):
_LOGGER.error("Incomplete read from: {} : {}".format(self, e))
else:
_LOGGER.error("Failed to send data to {}".format(self))

return

if isinstance(e, socket.error):
_LOGGER.debug(
"Retrying send due to error. Connection to {} failed: {}".format(
self, e
)
)
elif isinstance(e, asyncio.IncompleteReadError):
_LOGGER.debug(
"Retrying send due to error.Incomplete read from: {} : {}".format(
self, e
)
)
else:
_LOGGER.debug(
"Retrying send due to error. Failed to send data to {}".format(self)
)
await self._async_send(message, retries=retries - 1)
_LOGGER.debug("Sending to {}: {}".format(self, message))
self.writer.write(message.bytes())

0 comments on commit 7f344d3

Please sign in to comment.