Open WizBangCrash opened 4 years ago
It sounds very reasonable that the device would go to sleep, the esp8266 is quite power hungry (assuming it's using one of those). At first I was thinking that this would not be possible, as we wouldn't know when the device would be available. But since all devices send broadcast messages to reveal their presence, we can probably use that. I was thinking we could introduce a "passive" mode, where we would not connect to the device unless we get a broadcast message. We would also not run a re-connect loop again for this. Should work assuming the device sends these broadcasts, but I assume it does since you could pair with it.
I would like to clear a few things first though:
I can prepare a change that listens for broadcasts and prints them with a time stamp. That way you can run the script, make sure no broadcasts are received, wake the device, observe the time of the first and last broadcast. Then you can leave the device idle and see if it sends any broadcasts later (for periodical check up).
Ok, so, I have pushed this:
https://github.com/rospogrigio/localtuya-homeassistant/tree/broadcast_test
If you check out that branch, you should be able to run:
python3 custom_components/localtuya/discovery.py id_of_device_here
It should print the broadcasts if present. You will have to wake your device first, e.g. by opening or closing a door/window. Then you can try to answer my questions above. You do not have to run this script on the same machine as Home Assistant, but you need cryptography
installed.
That was quick work! I have run the discovery tool and it would seem that the sensor only connects to the WiFi when a state change occurs or I press its button. I left the discovery running for over 30mins after the first button press and did not receive another broadcast until I moved the sensor to simulate the door opening and then another when I put the sensor back (door closed). Here are the 3 broadcasts:
2020-10-17 21:50:48.625460 {'ip': '192.168.3.64', 'gwId': 'bf1ec414b7846970adir9a', 'active': 2, 'ablilty': 0, 'encrypt': True, 'productKey': 'key8ky3d8eshuygm', 'version': '3.3'}
2020-10-17 22:23:09.997498 {'ip': '192.168.3.64', 'gwId': 'bf1ec414b7846970adir9a', 'active': 2, 'ablilty': 0, 'encrypt': True, 'productKey': 'key8ky3d8eshuygm', 'version': '3.3'}
2020-10-17 22:23:25.354703 {'ip': '192.168.3.64', 'gwId': 'bf1ec414b7846970adir9a', 'active': 2, 'ablilty': 0, 'encrypt': True, 'productKey': 'key8ky3d8eshuygm', 'version': '3.3'}
I am going to leave discovery running overnight and see if it ever sends anything unsolicited.
I thought this might help too as it shows how quickly the device connects and disconnects from the WiFi. Its connected only for 5 seconds. This is a snippet from the router logs:
Oct 17 21:23:04 wlceventd: WLCEVENTD wlceventd_proc_event(500): wl0.2: Auth 18:69:D8:59:52:AE, status: Successful (0)
Oct 17 21:23:04 wlceventd: WLCEVENTD wlceventd_proc_event(529): wl0.2: Assoc 18:69:D8:59:52:AE, status: Successful (0)
Oct 17 21:23:10 wlceventd: WLCEVENTD wlceventd_proc_event(481): wl0.2: Disassoc 18:69:D8:59:52:AE, status: 0, reason: Disassociated because sending station is leaving (or has left) BSS (8)
Oct 17 21:23:19 wlceventd: WLCEVENTD wlceventd_proc_event(500): wl0.2: Auth 18:69:D8:59:52:AE, status: Successful (0)
Oct 17 21:23:19 wlceventd: WLCEVENTD wlceventd_proc_event(529): wl0.2: Assoc 18:69:D8:59:52:AE, status: Successful (0)
Oct 17 21:23:26 wlceventd: WLCEVENTD wlceventd_proc_event(481): wl0.2: Disassoc 18:69:D8:59:52:AE, status: 0, reason: Disassociated because sending station is leaving (or has left) BSS (8)
Looks like the sensor called in once overnight:
2020-10-17 21:50:48.625460 {'ip': '192.168.3.64', 'gwId': 'bf1ec414b7846970adir9a', 'active': 2, 'ablilty': 0, 'encrypt': True, 'productKey': 'key8ky3d8eshuygm', 'version': '3.3'}
2020-10-17 22:23:09.997498 {'ip': '192.168.3.64', 'gwId': 'bf1ec414b7846970adir9a', 'active': 2, 'ablilty': 0, 'encrypt': True, 'productKey': 'key8ky3d8eshuygm', 'version': '3.3'}
2020-10-17 22:23:25.354703 {'ip': '192.168.3.64', 'gwId': 'bf1ec414b7846970adir9a', 'active': 2, 'ablilty': 0, 'encrypt': True, 'productKey': 'key8ky3d8eshuygm', 'version': '3.3'}
2020-10-18 06:41:47.029543 {'ip': '192.168.3.64', 'gwId': 'bf1ec414b7846970adir9a', 'active': 2, 'ablilty': 0, 'encrypt': True, 'productKey': 'key8ky3d8eshuygm', 'version': '3.3'}
Hopefully 5s is enough to connect, but it's not a guarantee. Still, we should probably try to see if we can get it to work. Would be great to have #86 merged first though, as the implementation depends on it.
I've left the discovery app running all day and it would seem that the sensor does an unsolicited broadcast once every 12 hours even if there are no changes. I assume this to let the Tuya software know the device is still out there, alive and to report battery level.
Sounds reasonable enough. Maybe we can add some kind of check for that. Or at least provide a time stamp for when the device was last connected (via an attribute or so).
One other thing I noted is that the sensor has a DP ID of 2 which is the battery level (%), but the binary_sensor does not give me the option to map this DPI ID as an attribute :-(
Hmm, does that DP not show up in the list? Can you provide some logs from when it succeeds to connect? Also, wouldn't you want a `sensor‘ for that?
I'm still fairly new to Home Assistant and still relatively confused about Devices, Entities and Attributes. To me it makes sense for the battery to be an attribute of the entity. I can always create a sensor using a template as I did with the previous power switch.
The DPI ID was in the drop down list, but I didn't have an attribute to map it to (like I did with the voltage for instance, when I added the switch).
My logs are currently set to INFO
so don't show anything other than:
2020-10-19 11:22:45 INFO (MainThread) [homeassistant.components.binary_sensor] Setting up binary_sensor.localtuya
2020-10-19 11:22:45 INFO (MainThread) [homeassistant.helpers.entity_registry] Registered new binary_sensor.localtuya entity: binary_sensor.doorsensor_2
2020-10-19 11:23:03 ERROR (MainThread) [custom_components.localtuya.common] Connect to 192.168.3.47 failed
Traceback (most recent call last):
File "/config/custom_components/localtuya/common.py", line 141, in _make_connection
self._interface = await pytuya.connect(
File "/config/custom_components/localtuya/pytuya/__init__.py", line 587, in connect
_, protocol = await loop.create_connection(
File "/usr/local/lib/python3.8/asyncio/base_events.py", line 1025, in create_connection
raise exceptions[0]
File "/usr/local/lib/python3.8/asyncio/base_events.py", line 1010, in create_connection
sock = await self._connect_sock(
File "/usr/local/lib/python3.8/asyncio/base_events.py", line 924, in _connect_sock
await self.sock_connect(sock, address)
File "/usr/local/lib/python3.8/asyncio/selector_events.py", line 494, in sock_connect
return await fut
File "/usr/local/lib/python3.8/asyncio/selector_events.py", line 526, in _sock_connect_cb
raise OSError(err, f'Connect call failed {address}')
OSError: [Errno 113] Connect call failed ('192.168.3.47', 6668)
Both the sensor
and binary_sensor
are generic platforms that lets you create sensors based on any DP. The value of the DP becomes the state of the sensor (I.e. what you pick as "ID"). So I would suggest that you set up a sensor, pick DP 2 as "ID", battery as device class and % as unit of measurement. Should be what you want.
@postlund Thank you. That just cleared some misunderstandings I had about devices and entities. Now I have both my door sensors linked and with a battery entity too. A bit off topic for this thread, but why create separate entities and not have the battery as an attribute of the binary sensor? I've looked in https://developers.home-assistant.io to try and understand the relationships, but haven't found anything that makes it clear.
@WizBangCrash The main attribute of an entity is its state, e.g. on/off for a switch/light, open/closed for a cover, etc. In some cases there are additional information about an entity that might be interesting, like battery level, power usage, weather forecast for the upcoming days, and while it's perfectly possible to create additional entities for these, it's usually more practical to just add them as "state attributes". Normally this is what developers do. Some prefer to separate certain fields and create a new entity nonetheless. One reason for this is that some other integrations that take input from entities and provide new output, only support reading main state. One such example is integration
, which can take a sensor outputting power usage (in watts) and produce total consumed kWh. It however does not support using attributes as input, so you would need to create a template sensor that extracts the attribute. Automations have gotten support for dealing with attributes in the last few months or so (so it's a legacy reason as well). Finally, you might be interested in a graph of the value and if you have it as it's own sensor you get that quite nicely.
@WizBangCrash I now give you: #106. Would be great if you can give it a try. It should hopefully connect OK and all that, but once the device disconnects/goes to sleep, entities will be unavailable. It's ok when doing automations I guess, but not something to show in the frontend. Will have to think about how to deal with that (maybe we want to be optimistic and always report the last known state?) without messing with the architecture too much. First and foremost we should conclude if the connection logic works or not.
@postlund Thanks for this. I've run out of time this evening to do any further testing. Things seem to be working, but the binary_sensor state goes from unavailable
to on
to unavailable
or unavailable
to off
to unavailable
. I'm not seeing transitions from on
to off
.
Here is a snippet from the logs. Let me know if you need anything else, or a specific test run.
BTW is their a command line tool to capture state change events, or is the Developer Tools UI the only way to see these events?
2020-10-20 23:26:28 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Sending command heartbeat (device type: type_0a)
2020-10-20 23:26:28 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Send payload: b'{}'
2020-10-20 23:26:28 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Waiting for sequence number -100
2020-10-20 23:26:28 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Sending command heartbeat (device type: type_0a)
2020-10-20 23:26:28 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Send payload: b'{}'
2020-10-20 23:26:28 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Waiting for sequence number -100
2020-10-20 23:26:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:26:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Got heartbeat response
2020-10-20 23:26:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:26:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Got heartbeat response
2020-10-20 23:26:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Decrypted payload: {}
2020-10-20 23:26:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Decrypted payload: {}
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya] Passive device bf1ec414b7846970adir9z found with IP 192.168.3.84
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.common] Connecting to 192.168.3.84 (bf1ec414b7846970adir9z)
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.common] Waiting 0 seconds before connecting
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.common] Connecting to 192.168.3.84
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Started heartbeat loop
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Sending command heartbeat (device type: type_0a)
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Send payload: b'{}'
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Waiting for sequence number -100
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.common] Retrieving initial state
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Sending command status (device type: type_0a)
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Send payload: b'{"gwId":"bf1ec414b7846970adir9z","devId":"bf1ec414b7846970adir9z"}'
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Waiting for sequence number 1
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Got heartbeat response
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Decrypted payload: {}
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=1, cmd=10, retcode=0, payload=b'\xcf\xd8\\\xc5\xd7\x93A\x88\x10"p\xbf\xfb~\xeb\x01\x82B\xec\x95[>~\xc1\x95\x8e\x97\x83"=\xaf\xe1', crc=533511910)
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Dispatching sequence number 1
2020-10-20 23:26:47 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Decrypted payload: {"dps":{"1":true,"2":93}}
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Sending command heartbeat (device type: type_0a)
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Send payload: b'{}'
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Waiting for sequence number -100
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Sending command heartbeat (device type: type_0a)
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Send payload: b'{}'
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Waiting for sequence number -100
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Got heartbeat response
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Decrypted payload: {}
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Got heartbeat response
2020-10-20 23:26:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Decrypted payload: {}
2020-10-20 23:27:04 DEBUG (MainThread) [custom_components.localtuya] Passive device bf1ec414b7846970adir9z found with IP 192.168.3.84
2020-10-20 23:27:04 DEBUG (MainThread) [custom_components.localtuya.common] Already connecting to 192.168.3.84 (bf1ec414b7846970adir9z) - False, None, bf1ec414b7846970adir9z
2020-10-20 23:27:07 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Sending command heartbeat (device type: type_0a)
2020-10-20 23:27:07 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Send payload: b'{}'
2020-10-20 23:27:07 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Waiting for sequence number -100
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Sending command heartbeat (device type: type_0a)
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Send payload: b'{}'
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Waiting for sequence number -100
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Sending command heartbeat (device type: type_0a)
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Send payload: b'{}'
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Waiting for sequence number -100
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Got heartbeat response
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Decrypted payload: {}
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Got heartbeat response
2020-10-20 23:27:09 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Decrypted payload: {}
2020-10-20 23:27:12 ERROR (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Heartbeat failed (), disconnecting
Traceback (most recent call last):
File "/config/custom_components/localtuya/pytuya/__init__.py", line 346, in heartbeat_loop
await self.heartbeat()
File "/config/custom_components/localtuya/pytuya/__init__.py", line 435, in heartbeat
return await self.exchange(HEARTBEAT)
File "/config/custom_components/localtuya/pytuya/__init__.py", line 407, in exchange
msg = await self.dispatcher.wait_for(seqno)
File "/config/custom_components/localtuya/pytuya/__init__.py", line 206, in wait_for
await asyncio.wait_for(self.listeners[seqno].acquire(), timeout=timeout)
File "/usr/local/lib/python3.8/asyncio/tasks.py", line 490, in wait_for
raise exceptions.TimeoutError()
asyncio.exceptions.TimeoutError
2020-10-20 23:27:12 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Stopped heartbeat loop
2020-10-20 23:27:12 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Closing connection
2020-10-20 23:27:12 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Connection lost: None
2020-10-20 23:27:12 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Closing connection
2020-10-20 23:27:12 DEBUG (MainThread) [custom_components.localtuya.common] Disconnected from bf1ec414b7846970adir9z: None
2020-10-20 23:27:12 DEBUG (MainThread) [custom_components.localtuya.common] No automatic re-connect due to passive device
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Sending command heartbeat (device type: type_0a)
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Send payload: b'{}'
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Waiting for sequence number -100
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Got heartbeat response
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Decrypted payload: {}
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Sending command heartbeat (device type: type_0a)
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Send payload: b'{}'
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Waiting for sequence number -100
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Got heartbeat response
2020-10-20 23:27:29 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Decrypted payload: {}
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya] Passive device bf1ec414b7846970adir9z found with IP 192.168.3.84
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.common] Connecting to 192.168.3.84 (bf1ec414b7846970adir9z)
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.common] Waiting 0 seconds before connecting
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.common] Connecting to 192.168.3.84
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Started heartbeat loop
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Sending command heartbeat (device type: type_0a)
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Send payload: b'{}'
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Waiting for sequence number -100
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.common] Retrieving initial state
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Sending command status (device type: type_0a)
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Send payload: b'{"gwId":"bf1ec414b7846970adir9z","devId":"bf1ec414b7846970adir9z"}'
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Waiting for sequence number 1
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Got heartbeat response
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Decrypted payload: {}
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=1, cmd=10, retcode=0, payload=b'\xcf\xd8\\\xc5\xd7\x93A\x88\x10"p\xbf\xfb~\xeb\x01\x07\xd0!\xc9\x81\x8f(s<w6\xc0`\\\xeaU', crc=937446002)
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Dispatching sequence number 1
2020-10-20 23:27:40 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Decrypted payload: {"dps":{"1":true,"2":92}}
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Sending command heartbeat (device type: type_0a)
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Send payload: b'{}'
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Waiting for sequence number -100
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Got heartbeat response
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Decrypted payload: {}
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Sending command heartbeat (device type: type_0a)
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Send payload: b'{}'
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Waiting for sequence number -100
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Got heartbeat response
2020-10-20 23:27:49 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Decrypted payload: {}
2020-10-20 23:28:00 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Sending command heartbeat (device type: type_0a)
2020-10-20 23:28:00 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Send payload: b'{}'
2020-10-20 23:28:00 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bf1ec414b7846970adir9z] Waiting for sequence number -100
@postlund After re-reading your post from last night I realise that what I recorded is what you stated would happen i.e. the device will always show as unavailable once it has gone to sleep.
I have been recording the broadcasts from two sensors that I have and both of them are sending broadcasts every 8 hours if left inactive (not 12 hours as I originally thought).
My feeling is that the state should not be set to unavailable for passive devices. With the Tuya app it seemed to report the last known state. I never saw it report as unavailable
.
I'll do some experiments to see what happens when the wifi is out of range or down. I want to see if the sensor does a broadcast as soon as it is able to reconnect to the WiFi. If that is the case then the window of "missing" state changes would be very small and reporting the "Last Known State" would be more helpful than reporting the device is unavailable.
The unavailable state would then only be necessary when you reboot HASS and have no way of knowing the last state of the device.
Yes, it sounds like it works exactly as I anticipated. Some work will be needed to deal with the state. I think I have an idea, will make a prototype and see if it works. Maybe we should have like a "timeout timer" that moves the sensor to unavailable after that time (we could hard code let's say 12h for now)? Maybe we could also restore the state between restarts, assuming the timer value has not passed. Will have to look into that.
You can interact with HA from cli with this (never used it myself though):
https://github.com/home-assistant-ecosystem/home-assistant-cli
My door sensor is the only tuya thing I still would like to add to Home Assistant. Following this with interest. If I can also be of any assistance, please let me know!
I'll see if I can put so e time into this tonight, think I had some stuff left regarding availability after timeout.
I have updated the PR and it should be more usable now. The state is maintained after disconnect and even between restarts of Home Assistant. There is no "timeout" management though, so you will not get any indication if the devices phones home or not. But each entity belonging to a passive device will get a last_seen
property with a time stamp when connection was recently lost. So it's possible to monitor that with an automation for instance. Let me know if it works!
(The timeout management is pretty tricky to do right, so I will leave that for the future)
Thanks @postlund
I upgraded tonight and something isn't quite right. I removed the passive devices and re-added them so that that get the last_seen
attribute, but now it only detects the first state change ("open") and does not detect the "close".
The battery sensor also does not get updated.
Here is a snippet of the logs:
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya] Passive device bfc4f31c5e846b09a2tude found with IP 192.168.123.47
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.common] Connecting to 192.168.123.47 (bfc4f31c5e846b09a2tude)
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.common] Waiting 0 seconds before connecting
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.common] Connecting to 192.168.123.47
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Started heartbeat loop
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Sending command heartbeat (device type: type_0a)
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Send payload: b'{}'
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Waiting for sequence number -100
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.common] Retrieving initial state
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Sending command status (device type: type_0a)
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Send payload: b'{"gwId":"bfc4f31c5e846b09a2tude","devId":"bfc4f31c5e846b09a2tude"}'
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Waiting for sequence number 1
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Got heartbeat response
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Decrypted payload: {}
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=1, cmd=10, retcode=0, payload=b":\xe6\x8d\x15G\xc8Y\xc1\xc0\x0e{\x9b\x16\x01\xb2u\x18q\xd1i\x96\xd5L\x1b\xba|'\xeb\xab1)\xc3", crc=2919320230)
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Dispatching sequence number 1
2020-10-27 23:43:35 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Decrypted payload: {"dps":{"1":true}}
2020-10-27 23:43:35 DEBUG (SyncWorker_27) [custom_components.localtuya.common] Entity sensor.doorsensor_2 is requesting unknown DPS index 2
2020-10-27 23:43:35 ERROR (SyncWorker_27) [homeassistant.util.logging] Exception in _update_handler when dispatching 'localtuya_bfc4f31c5e846b09a2tude': ({'1': True},)
Traceback (most recent call last):
File "/config/custom_components/localtuya/common.py", line 247, in _update_handler
self.status_updated()
File "/config/custom_components/localtuya/sensor.py", line 67, in status_updated
state = round(state * scale_factor, DEFAULT_PRECISION)
TypeError: unsupported operand type(s) for *: 'NoneType' and 'float'
2020-10-27 23:43:51 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Sending command heartbeat (device type: type_0a)
2020-10-27 23:43:51 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Send payload: b'{}'
2020-10-27 23:43:51 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Waiting for sequence number -100
2020-10-27 23:43:51 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-27 23:43:51 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Got heartbeat response
2020-10-27 23:43:51 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209dd30] Decrypted payload: {}
2020-10-27 23:43:52 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Sending command heartbeat (device type: type_0a)
2020-10-27 23:43:52 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Send payload: b'{}'
2020-10-27 23:43:52 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Waiting for sequence number -100
2020-10-27 23:43:52 DEBUG (MainThread) [custom_components.localtuya.pytuya] Dispatching message TuyaMessage(seqno=0, cmd=9, retcode=0, payload=b'', crc=2958142211)
2020-10-27 23:43:52 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Got heartbeat response
2020-10-27 23:43:52 DEBUG (MainThread) [custom_components.localtuya.pytuya] [34884024f4cfa209fdab] Decrypted payload: {}
2020-10-27 23:43:55 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Sending command heartbeat (device type: type_0a)
2020-10-27 23:43:55 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Send payload: b'{}'
2020-10-27 23:43:55 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Waiting for sequence number -100
2020-10-27 23:44:00 ERROR (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Heartbeat failed (), disconnecting
Traceback (most recent call last):
File "/config/custom_components/localtuya/pytuya/__init__.py", line 346, in heartbeat_loop
await self.heartbeat()
File "/config/custom_components/localtuya/pytuya/__init__.py", line 435, in heartbeat
return await self.exchange(HEARTBEAT)
File "/config/custom_components/localtuya/pytuya/__init__.py", line 407, in exchange
msg = await self.dispatcher.wait_for(seqno)
File "/config/custom_components/localtuya/pytuya/__init__.py", line 206, in wait_for
await asyncio.wait_for(self.listeners[seqno].acquire(), timeout=timeout)
File "/usr/local/lib/python3.8/asyncio/tasks.py", line 490, in wait_for
raise exceptions.TimeoutError()
asyncio.exceptions.TimeoutError
2020-10-27 23:44:00 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Stopped heartbeat loop
2020-10-27 23:44:00 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Closing connection
2020-10-27 23:44:00 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Connection lost: None
2020-10-27 23:44:00 DEBUG (MainThread) [custom_components.localtuya.pytuya] [bfc4f31c5e846b09a2tude] Closing connection
2020-10-27 23:44:00 DEBUG (MainThread) [custom_components.localtuya.common] Disconnected from bfc4f31c5e846b09a2tude: None
2020-10-27 23:44:00 DEBUG (MainThread) [custom_components.localtuya.common] No automatic re-connect due to passive device
2020-10-27 23:44:00 DEBUG (SyncWorker_48) [custom_components.localtuya.common] Passive device disconnected, keeping old state
2020-10-27 23:44:00 DEBUG (SyncWorker_13) [custom_components.localtuya.common] Passive device disconnected, keeping old state
Not sure what is happening with the initial retrieval of DPS. Seems like only "1" is returned, but some parts are missing in the log. Let's just wait until we have #124 in place, after that we will get device id on every log point which makes it easier to debug.
Cleaned all my devices out this evening and just added a single door sensor. Found a few things:
true
. I see connections being made each time I open/close the sensor but the debug messages always report dps index 1 as true
, never false
last_seen
attribute never seems to be created in the entity so the code at line 266 of common.py
always fails.Regarding point 2 of my last post. I have two binary sensors and one of them seems to have stopped reporting the true state of the sensor i.e. it's always reporting true now. I switched to the other sensor this evening and it is reporting the true state, but I noticed two things:
I had to change the code at line 262 in common.py to the following to stop the TypeError
exception always occurring:
state = await self.async_get_last_state()
if state and self._config_entry.data.get(CONF_PASSIVE_DEVICE):
# if not (state or self._config_entry.data.get(CONF_PASSIVE_DEVICE)):
# return
last_seen = state.attributes.get(ATTR_LAST_SEEN)
if last_seen:
self._last_seen = datetime.fromisoformat(last_seen)
_LOGGER.debug("Passive device set last_seen: %s", self._last_seen)
self._status = state.attributes.get(ATTR_OLD_STATE, {})
self.status_updated()
Also, If a sensor state change occurs before the Timeout
exception shown in the previous but one post, the state change is not recorded.
Ok, so...
True
, it will of course always report true.Generally if you get a timeout error, should result in a disconnect (followed by a re-connect) because it's most likely a non-recoverable error will result in upcoming errors. This especially apply to heartbeats as those should never fail.
Hmm.
Any update on this? Finally achieved blocking the tuya devices from the internet (by buying a new router) and would like to move the last two Tuya devices I still have to local tuya as well (that's the door sensor, and the light it triggers). No pressure, but just wondering if there is any update, and anything I can do to assist.
@TheFes Currently no updates, should probably try to move along.
@WizBangCrash Sorry for not responding, I missed you message.
Should probably be quite easy to allow a custom default value. I feel a bit tired right now, so my head don't help me to think about the details. But I will look into it. The value is cached by Home Assistant, so it's restored to previous value after a restart.
The sensors not reporting the true state are tricky to handle. Is that really the case or are we missing to connect when it changes state?
I've been thinking about breaking this setting up into two separate options. One for the passive part, where re-connects are only triggered when a device is discovered (I.e. broadcast message is received) and one for the state restore/maintain part. That way it's possible to use the passive setting for regular devices as well, which should work fine in most cases (assuming device is on same network as Home Assistant). Any thoughts on that?
@TheFes Do you mind sharing with me how you have blocked the devices from the internet?
@postlund No worries. I'm in the process of moving home at the moment, so don't have the time I would like to spend on this.
I think a custom default value would work if you can implement it. That way, at least you can set it to something you know it is most likely to be until it polls in or changes.
I will debug the sensors not reporting the true state as soon as I have moved into my new home and set Home Assistant back up again. I am sure I did something wrong as they were reporting correctly and then stopped after I made some changes.
WRT breaking it into two parts. If you can implement all devices (passive and regular) in a common way, but have a passive option where, when set, the device ignores disconnections and is updated on the reception of broadcast messages. I would think this would be easier to understand and maintain. i.e. any device can be passive, it just means that disconnections won't be reported and updates will be triggered via broadcast messages. I haven't had a chance to dig into the code yet, or look at the actual session details of a device, so I hope this makes sense.
@WizBangCrash I've bought a new router to replace the one provided by my provider. It has an option to block devices from the internet, while keeping them availalbe in the local network. My previous router only provided a MAC filter, which would kick the devices from the whole network. It's a Fritz!box 7590, but I'm sure other routers can provide this functionality as well.
@WizBangCrash Could you share your config for the door/window-sensor with me? Did you use a binary sensor?
Also really interesting to see how I can get my motion sensors to work.. Do I need to add them as binary_sensors or sensors?
- host: 192.168.0.38
device_id: *deleted*
local_key: *deleted*
friendly_name: 81b1
protocol_version: "3.3"
entities:
- platform: sensor
friendly_name: 81b1_battery
device_class: battery
id: 3
- platform: binary_sensor
friendly_name: 81b1_opening
device_class: opening
id: 1
I know about sensors getting to sleep but even if I open doors and I see that sensor renew ip i still have "Unavailable"
@bigretromike Which version of the component are you running? You must use master
as the latest released version does not have the necessary changes.
@postlund 3.1 because master would not work initially. I will try master then.
@bigretromike It depends on when you tried, there were some issues that should be fixed now. Otherwise please report the problem so we can fix it.
@bigretromike It depends on when you tried, there were some issues that should be fixed now. Otherwise please report the problem so we can fix it.
yes, there is still issue: https://github.com/rospogrigio/localtuya/issues/258
I dont know it this error prevents sensor from work, but all 5 plugs work fine, yet non door/window sensor is updated.
After commenting out that one smart power plug so I skip the error part, my 3 tuya door/window sensors are still without any data, and not error in logs - after comenting out that one plug and deleting it from integration, door/window sensor with latest-master, dont work - or I did something wrong when adding them:
- host: 192.168.0.38
device_id: *deleted*
local_key: *deleted*
friendly_name: 81b1
protocol_version: "3.3"
entities:
- platform: sensor
friendly_name: 81b1_battery
device_class: battery
id: 3
- platform: binary_sensor
friendly_name: 81b1_opening
device_class: opening
id: 1
@postlund currently on master.
# DOOR SENSOR
- host: 192.168.0.38
device_id: *deleted*
local_key: *deleted*
friendly_name: 81b1
protocol_version: "3.3"
entities:
- platform: sensor
friendly_name: 81b1_battery
device_class: battery
id: 3
- platform: binary_sensor
friendly_name: 81b1_opening
device_class: opening
id: 1
Both entities are Unavailable
even if I open window and leave it open.
After opening I can see that device access network on router, but nothing get updated.
I double check key/devId, those are correct.
@bigretromike Can you enable debug logs so we can see if the discovery message is received at all?
I don't see anything other that adding sensors, no communication. The door sensor are never in discovered devices inside integration.
Can you paste the log here so I can see? Also, how are you running Home Assistant? We rely on broadcasts sent by the devices so you need to make sure Home Assistant is on the same network as the devices or forward the broadcasts (port 6666 and 6667 UDP). If you run in docker, make sure you run in host mode.
Can you paste the log here so I can see? Also, how are you running Home Assistant? We rely on broadcasts sent by the devices so you need to make sure Home Assistant is on the same network as the devices or forward the broadcasts (port 6666 and 6667 UDP). If you run in docker, make sure you run in host mode.
I wouldn't like to announce data from that log to public, You got it on maila.
I'm running armbian buster with hassio installation that run on bare-metal.
I am also trying to get my motion sensors to work. The problem for me is that I don't now the right DP's for motion and/or battery. Using the test.py script i cannot retrieve the DP's because it doesn't connect long enough to the network to detect it. I am using this config (DP's could be wrong..). Any idea how I can retrieve the right DP? At the moment I don't know whether it just doesn't work or my DP's are incorrect.
I'd like to help if need some testing and logs. Have 1 PIR sensor, 2 magnet sensors, smoke and water sensors... all seem to be pasive, they connect to wifi only about 1-2 pings and that not enough to debug dps...
@postlund I've just bought a Tuya door sensor (Mirabella Genio) and I haven't been able to get it to work with LocalTuya at all - I've configured it as per the docs but even when it comes online briefly when the door is opened/closed, HA reports the status and battery level as unavailable - I've confirmed that it does connect to the router when it comes online.
@postlund I've also tested the motion sensor. Only at the first motion test the motion sensor was available in Home assistant. Running the latest versions.
@postlund I've just bought a Tuya door sensor (Mirabella Genio) and I haven't been able to get it to work with LocalTuya at all - I've configured it as per the docs but even when it comes online briefly when the door is opened/closed, HA reports the status and battery level as unavailable - I've confirmed that it does connect to the router when it comes online.
Having the exact same problem with the same device (model no. I002575). I can confirm the device connecting to the router for a brief moment. I've defined the device via YAML in HA, but neither of the defined entities ever show anything other than "Unavailable".
localtuya:
- host: 10.0.***.***
device_id: *****
local_key: *****
friendly_name: MirabellaGenio contact sensor
protocol_version: "3.3"
entities:
- platform: binary_sensor
friendly_name: Sensor status
id: 1
device_class: opening
- platform: sensor
friendly_name: Battery level
id: 3
device_class: battery
I have the Genio PIR sensor and have been have not been able to get it working with localtuya. It works with the ordinary tuya integration, but I would like to see if it works faster locally.
I have powered the PIR sensor via its USB port rather than batteries, and now it doesn't seem to go to sleep anymore (it doesn't drop off my router any more). It responds faster than it did using batteries (using the standard tuya integration). But I can't seem to connect to it. When I use the test.py script, it fails with: "WARNING:localtuya.pytuya:Failed to get status: [WinError 10061] No connection could be made because the target machine actively refused it". I have turned off my phone and disabled the device in the standard tuya integration. Is there anything else I can try?
Came across your integration today and managed to set up my GoSund switched outlets with no trouble . Thanks.
I also have a Door Sensor (https://www.amazon.co.uk/gp/product/B07GXTV4C1/ref=ppx_yo_dt_b_asin_title_o07_s00?ie=UTF8&psc=1) and wondered if you plan to add support for this type of device?
It links with no problem and worked for about 5 mins and then became
unavailable
and has stayed that way ever since. Looking at the logs it can no longer connect to the device. I believe the device is only connected to the WiFi for a very brief period each time the state changes in order to save battery life.