Open Lurker00 opened 2 weeks ago
It seems it should work:
for cid, device in listener.sub_devices.items():
if cid not in on_devs:
if isinstance(device, ContextualLogger):
contextualLogger: ContextualLogger = device
contextualLogger.warning(f"Sub-device is offline: {cid}")
else:
self.warning(f"Sub-device disconnected: {cid}")
device.disconnected()
but I didn't try yet (not at home). The else:
should never happen, though.
But a parameter "offline" seems a better solution, because it makes possible here: https://github.com/xZetsubou/hass-localtuya/blob/d48ee13cebbeaef14b9f9914f48140ef985795ac/custom_components/localtuya/coordinator.py#L480-L483 change to something like this:
def disconnected(self, offline=False):
...
delay = (0 if offline else 3) + sleep_time
and call in _action()
device.disconnected(offline=True)
The "ContextualLogger" is Sub Class inside Listener Class so isinstance(device, ContextualLogger)
will always be true.
What do you exactly mean by false alarms can you explain more? does it disconnect a device that is online? can you also put the logs comes from _action() "Sub-Devices States Update ..."
What do you exactly mean by false alarms
It produces a warning when the device is not reported as offline by the gateway. The feature request #253 was to warn about a sub-device went offline as reported by its gateway. But, you see, currently, disconnected()
is called from different places, without any knowledge about disconnect reason, while disconnects may happen even when all the devices are online.
can you also put the logs comes from _action()
"Sub-Devices States Update ..."
That's what I've already done in the second log lines block, after 2 empty lines. They are from another case, when _action()
detected offline state. The first block does not contain lines from _action()
, because there was no an offline report from the gateway.
Probably, I need to explain:
When a sub-device is reported offline by a gateway, it usualy means dead battery or weak signal (Zigbee or Bluetooth). It requires an action from the user.
Devices disconnect for many reasons, and usualy re-connect is successful in some seconds, or even fraction of a second. Only if the subsequent reconnect was not successful (_shutdown_entities
was called), it worth to pay attention. But, with the current implementation, the warning was produced with subsequent successful reconnect.
Not only delay
calculation, but also, the line
https://github.com/xZetsubou/hass-localtuya/blob/d48ee13cebbeaef14b9f9914f48140ef985795ac/custom_components/localtuya/coordinator.py#L476
should be changed to
if not self._is_closing and not offline and not self._quick_retry:
Instead, the attempt to reconnect may happen only after 5 seconds (RECONNECT_INTERVAL
). Before 2024.6.0, I saw successful reconnects in less than a second.
Here is how it works with the suggested changes (in https://github.com/xZetsubou/hass-localtuya/issues/272#issuecomment-2158247518 and https://github.com/xZetsubou/hass-localtuya/issues/272#issuecomment-2158551629):
Reconnect in < 300 ms. _shutdown_entities
wasn't called. No a warning meaning sub-device went offline.
So in short, there is no issue with the warnings it just not specified if it's because it's offline or not? that's is it?
Not so easy.
For me, it seems the whole logic of handling different reasons of disconnects (sub-device went offline, connection was lost for whatever reason, or LocalTuya closes the connection itself for whatever reason) is broken. _shutdown_entities
shall not be called at all when quick retry is possible. Also, the warning in _shutdown_entities
produces too many useless messages when the connection with a gateway can't be re-established via quick retry.
I insist that the warning about a sub-device went offilne shall be issued in the place of the event: in _action
.
Also, I believe that quick retry attempt (both delay
calculation and call to self.async_connect()
in disconnected()
) shall be made with a knowledge of the disconnect reason. My current implementation can be incorrect, but it works better than your's.
My current code with warnings produced in disconnected
is good for my current tests, to receive Telegram notifications about such events without additional automation involved. It is not required in the release version.
tbh I don't prefer sending the warnings from the core module pytuya
rather then doing that we can just add exec
arg for disconnected as and pass the reason within it. I also don't like warnings at all. The core shouldn't act as a class for Home Assistant.
If _shutdown_entities
haven't been called and the quick retry fails then this will only break the entities as it shows that it's available but it's not. this what is the delay for as it will shut them down if the device doesn't reconnected within 3 seconds after the quick retry.
Also the reconnect task I'm going to actually refactor it and the should be inside the TuyaDevice object. and in LocalTuya HASS Object.
I'll make the changes within a few days.
The core shouldn't act as a class for Home Assistant
Thank you for explanation! Now I understand your point.
I'm going to actually refactor
Thanks a lot for your efforts! LocalTuya is already much better than a couple of months ago, when I started to use it.
LocalTuya Version
2024.6.0
Home Assistant Version
2024.6.1
Environment
What happened?
In #253 I asked for a warning when a sub-device was detected offline. You've implemented it a different way, whcih leads to false alarms.
Consider the first block of log records ("Disconnected" and "Disconnected gateway" are produced from
def disconnected(self)
, also some debug messages I changed to info, and added "Sub-devices heartbeat started"). There are no messages from this code piece: https://github.com/xZetsubou/hass-localtuya/blob/50e56ff87ead0477dd438e16084b21aa4627e85c/custom_components/localtuya/core/pytuya/__init__.py#L846-L849 (in my mod, it is info rather than warning). Obviously, it was just a disconnect that happens time to time, and the connection was restored in 5 seconds. See the second block how it looks like when the gateway reports devices offline.So, I'd ask you to return to #253 and implement it the way to produce the warning only when the gateway lists a sub-device offline (line 848 above). Warnings produced here: https://github.com/xZetsubou/hass-localtuya/blob/d48ee13cebbeaef14b9f9914f48140ef985795ac/custom_components/localtuya/coordinator.py#L439-L442 don't work as they should.
E.g. it can be implemented as an optional second parameter to
def disconnected(self)
method, with a special value to call fromasync def _action()
to produce such a warning. Or, is it possible to call there fromdevice
rather thanself
:somehow? The
sub_devices
dictionary containsTuyaListener
objects, but here they are, actually, alsoContextualLogger
objects. I'm still not a Python expert.Steps to reproduce.
Don't know
Relevant log output
Diagnostics information.
No response