core: ESPHome unable to connect after esp changes IP
The problem
When an ESP is changing its IP address home assistant loses connectivity and needs a restart to connect again.
Environment
- Home Assistant Core release with the issue: 2021.1.0
- Last working Home Assistant Core release (if known): potentially never
- Operating environment (OS/Container/Supervised/Core): OS
- Integration causing this issue: esphome
- Link to integration documentation on our website: https://www.home-assistant.io/integrations/esphome/
Problem-relevant configuration.yaml
None
Traceback/Error logs
None
Additional information
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 28 (20 by maintainers)
I’ve spent a few hours on this and come to the following conclusions:
zeroconf
assumes the device has at most one ipv6. This clearly isn’t the case especially for airplay devices which seem to always have 3 ipv6 addresses.This results in lots of update churn each time it sees an IPv6 address as it thinks its new since the cache fetch is always returning the latest one.
The
ServiceInfo
class assumes its done when the first address appears in the cache. If the device sends the IPv6 address before the IPv4 it never populates the IPv4 one.The
ServiceInfo
class is attempting to use make use of the cache inServiceInfo.request
butout.add_answer_at_time(cached_entry, now)
is in theif not cached_entry:
block so its always called withNone
The cache is partially loaded a second time in
ServiceInfo.request
after already loading from cache becauseDNSQuestion(...)
is passed to the listener… and the problem here. The cache is updated before calling
update_service
with the record which means we sometimes (frequently in some cases) fail to callback the IP change because the ServiceBrowser thinks it is already up to date.Should be fixed with zeroconf 0.32
https://github.com/jstasiak/python-zeroconf/issues/643
Looks like we never fire off another config flow announcement when the IP changes.
In theory #47683 should have added support for this, but it seems like we need to do something else as well to get it to work
I’m running in a docker container on a Synology NAS connected via Ethernet.