Add support for passive devices (#171)
* Add support for passive devices * Fix a few issues * Fix broken handling of closing a connection This fixes the following error: AttributeError: 'NoneType' object has no attribute 'write' * Always use discovery broadcasts to trigger connects From now on there's no connect loop but all attempts are initiated by received discovery messages. * Fix cancelling of heartbeat task * Verify entry has been loaded before connecting * Don't reset seqno when switching to type_d device
This commit is contained in:
@@ -362,7 +362,7 @@ class TuyaProtocol(asyncio.Protocol, ContextualLogger):
|
||||
if "dps" in decoded_message:
|
||||
self.dps_cache.update(decoded_message["dps"])
|
||||
|
||||
listener = self.listener()
|
||||
listener = self.listener and self.listener()
|
||||
if listener is not None:
|
||||
listener.status_updated(self.dps_cache)
|
||||
|
||||
@@ -377,12 +377,17 @@ class TuyaProtocol(asyncio.Protocol, ContextualLogger):
|
||||
while True:
|
||||
try:
|
||||
await self.heartbeat()
|
||||
await asyncio.sleep(HEARTBEAT_INTERVAL)
|
||||
except asyncio.CancelledError:
|
||||
self.debug("Stopped heartbeat loop")
|
||||
raise
|
||||
except Exception as ex:
|
||||
self.exception("Heartbeat failed (%s), disconnecting", ex)
|
||||
break
|
||||
await asyncio.sleep(HEARTBEAT_INTERVAL)
|
||||
self.debug("Stopped heartbeat loop")
|
||||
self.close()
|
||||
|
||||
transport = self.transport
|
||||
self.transport = None
|
||||
transport.close()
|
||||
|
||||
self.transport = transport
|
||||
self.on_connected.set_result(True)
|
||||
@@ -396,24 +401,25 @@ class TuyaProtocol(asyncio.Protocol, ContextualLogger):
|
||||
"""Disconnected from device."""
|
||||
self.debug("Connection lost: %s", exc)
|
||||
try:
|
||||
self.close()
|
||||
listener = self.listener and self.listener()
|
||||
if listener is not None:
|
||||
listener.disconnected()
|
||||
except Exception:
|
||||
self.exception("Failed to close connection")
|
||||
finally:
|
||||
try:
|
||||
listener = self.listener()
|
||||
if listener is not None:
|
||||
listener.disconnected(exc)
|
||||
except Exception:
|
||||
self.exception("Failed to call disconnected callback")
|
||||
self.exception("Failed to call disconnected callback")
|
||||
|
||||
def close(self):
|
||||
async def close(self):
|
||||
"""Close connection and abort all outstanding listeners."""
|
||||
self.debug("Closing connection")
|
||||
if self.heartbeater is not None:
|
||||
self.heartbeater.cancel()
|
||||
try:
|
||||
await self.heartbeater
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
self.heartbeater = None
|
||||
if self.dispatcher is not None:
|
||||
self.dispatcher.abort()
|
||||
self.dispatcher = None
|
||||
if self.transport is not None:
|
||||
transport = self.transport
|
||||
self.transport = None
|
||||
@@ -572,7 +578,7 @@ class TuyaProtocol(asyncio.Protocol, ContextualLogger):
|
||||
|
||||
if data is not None:
|
||||
json_data["dps"] = data
|
||||
if command_hb == 0x0D:
|
||||
elif command_hb == 0x0D:
|
||||
json_data["dps"] = self.dps_to_request
|
||||
|
||||
payload = json.dumps(json_data).replace(" ", "").encode("utf-8")
|
||||
|
Reference in New Issue
Block a user