When using Home Assistant to integrate with ESPHome managed devices, connection timeouts can occur. Normally this means that the device could not be reached temporarily only, and will eventually get connected again. However, a particular behavior creates quite a disturbance: Upon reconnection, all configured sensors are activated immediately. This triggers for example motion sensors, sending a false alert. If you have sophisticated automations running, working with false positives is quite a nuisance. So, how can we prevent this?
This article is a live documentation of my attempts to find the root cause of these problems and to fix them. I will start to investigate the network side first, check that network connectivity is given and that the Docker containers with which both Home Assistant and ESPHome run are properly connected. Then I will consider the ESPHome configuration options to improve WLAN connectivity. Finally, I will research how to configure Home Assistant to prevent the false positives sensor activation when it loses connection to a device.
The technical context of this article is Home Assistant 2024.11
and ESPHome 2024.10
, but it should work with newer versions as well.
This article originally appeared at my blog admantium.com.
Home Assistant Timeout Error
What is this timeout error anyway? You can see it in two places. First, in your Home Assistant dashboard, opening a sensor, you can see the message became unavailable
, followed by the false positives triggering of the sensor.
Second, you can see disconnect messages inside the log files of your Home Assistant installation. In my case, it’s a Docker container and access the docker logs from this container. But you can also access the logs from the Home Assistant Dashboard.
2024-12-27 10:40:13 WARNING (MainThread) [homeassistant.components.esphome] Can't connect to ESPHome API for None (192.168.3.213): Timeout while waiting for API response!
2024-12-27 10:40:22 WARNING (MainThread) [homeassistant.components.esphome] Error getting initial data for 192.168.3.213: Timeout while waiting for API response!
2024-12-27 10:40:33 WARNING (MainThread) [homeassistant.components.esphome] Can't connect to ESPHome API for None (192.168.3.213): Timeout while waiting for API response!
This message indicates the following error. Home Assistant works with ESPHome controlled devices directly via the API. And when it cannot connect, it assumes the device to be unavailable.
As explained in the introduction, if the connectivity is only disturbed temporarily. But when I look at the history stats of the connected motion sensor, each time the sensor switches back from unavailable
, it detects a motion event. An annoying false positive.
cleared (no motion detected)
11:11:58 AM - 3 hours ago
detected motion
11:11:04 AM - 3 hours ago
became unavailable
11:10:56 AM - 3 hours ago
When searching the internet for ESPHome API connection errors from Home Assistant, your will find plenty results! To pinpoint where the error is, I recommend checking things on this order:
- Network Connectivity
- WLAN Connectivity
- ESP Home Configuration
- Home Assistant Configuration
Let’s start.
Docker Container Connectivity Test
My Home Assistant installation runs as a Docker container. The first thing to check is that the container itself can reach the ESPHome devices IP, e.g. 192.168.3.213
. A simple ping
is sufficient:
$ ping 192.168.3.213
PING 192.168.3.213 (192.168.3.213) 56(84) bytes of data.
64 bytes from 192.168.3.213: icmp_seq=1 ttl=255 time=2.60 ms
64 bytes from 192.168.3.213: icmp_seq=2 ttl=255 time=2.32 ms
64 bytes from 192.168.3.213: icmp_seq=3 ttl=255 time=6.78 ms
64 bytes from 192.168.3.213: icmp_seq=4 ttl=255 time=2.83 ms
The command works, Home Assistant can reach the devices. To be sure, I also let this command run for several hours: No errors could be seen.
WLAN Connectivity Test
The next test is about checking that the ESP boards are connected properly to the WLAN. Interestingly, ESPHome provides a handy wifi_signal
sensor that checks the signal strength in dBm. Just add the following configuration stanza to the ESP device:
sensor:
- platform: wifi_signal
name: "WiFi Signal esp8266-02"
update_interval: 60s
After some time, I saw these results for my three devices
The bottom line shows the board with the motion sensor. It seems connected all the time. But to rule out any measurement error, I put the sensor into a new location, in an unobstructed line-of-sight to the router. And the next day, the chart shows a similar "always connected" state, but with better DBM measurements of course.
Still, the motion sensor log showed the same messages as before.
ESPHome Configuration: Improve Logging Messages
We need more information where the error originates. Each ESPHome device can have different levels of logging output. By setting a very verbose level, you will see detailed information of the boards program. Enabling is simple:
logger:
level: VERY_VERBOSE
Now log messages provide many more details:
[19:34:02][C][wifi_signal.sensor:009]: WiFi Signal 'WiFi Signal esp8266-01'
[19:34:02][C][wifi_signal.sensor:009]: Device Class: 'signal_strength'
[19:34:02][C][wifi_signal.sensor:009]: State Class: 'measurement'
[19:34:02][C][wifi_signal.sensor:009]: Unit of Measurement: 'dBm'
[19:34:02][C][wifi_signal.sensor:009]: Accuracy Decimals: 0
[19:34:02][V][wifi_signal.sensor:009]: Unique ID: '94b97e10625f-wifisignal'
[19:34:09][VV][api.service:327]: on_ping_request: PingRequest {}
....
[19:34:26][V][sensor:070]: 'WiFi Signal esp8266-01': Received new state -50.000000
[19:34:26][D][sensor:120]: 'WiFi Signal esp8266-01': Sending state -50.00000 dBm with 0 decimals of accuracy
[19:34:26][VV][api.service:140]: send_sensor_state_response: SensorStateResponse {
key: 2237076546
state: -50
missing_state: NO
}
With these settings in place, from the ESPHome dashboard, I opened the log from the board. And after some time, I could see these messages:
[10:10:45][VV][api.service:043]: send_ping_response: PingResponse {}
INFO 192.168.3.213: Unexpected error while reading incoming messages: [Errno 104] Connection reset by peer
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/aioesphomeapi/connection.py", line 505, in run_forever
await self._run_once()
File "/usr/local/lib/python3.9/dist-packages/aioesphomeapi/connection.py", line 480, in _run_once
pkt = await self._frame_helper.read_packet()
File "/usr/local/lib/python3.9/dist-packages/aioesphomeapi/connection.py", line 219, in read_packet
return await self._read_packet_plaintext()
File "/usr/local/lib/python3.9/dist-packages/aioesphomeapi/connection.py", line 197, in _read_packet_plaintext
preamble = await self._reader.readexactly(1)
File "/usr/lib/python3.9/asyncio/streams.py", line 723, in readexactly
await self._wait_for_data('readexactly')
File "/usr/lib/python3.9/asyncio/streams.py", line 517, in _wait_for_data
await self._waiter
File "/usr/lib/python3.9/asyncio/selector_events.py", line 856, in _read_ready__data_received
data = self._sock.recv(self.max_size)
ConnectionResetError: [Errno 104] Connection reset by peer
INFO Disconnected from ESPHome API for 192.168.3.213
WARNING Disconnected from API
INFO Successfully connected to 192.168.3.213
This is very precise: Connection reset by peer
. The boards connection was reset. It might by a WIFI problem after all.
ESP Home Configuration: Board and WIFI Settings
Ok, so the ESP board loses its WIFI connection. This problem, and the above mentioned Home Assistant error log message Timeout while waiting for API response!
lead to several solution suggestions. For completeness, and for others who have similar problems, I document them all here, but directly indicate what did not help in my case.
Use the most Recent Arduino Framework Version (No Effect)
According to a thread, Arduino libraries could be the source of the error. Unbeknown to me, you can define which version of the PlattformIO espressif8266 framework is used during compilation. See the available tags and add them to your configuration as shown:
esphome:
name: esp8266-01
platform: ESP8266
board: d1_mini
arduino_version: espressif8266@3.2.0
In an old thread, users were downgrading their ESPHome version because the disconnects just started to appear after an update. I could not see any change whatever version I used.
Add a Delay Function (No Effect)
This comment suggested to add a small delay function that runs continuously in the background. This looks as follows:
esphome:
name: esp8266-02
platform: ESP8266
board: d1_mini
on_loop:
then:
- lambda: delay(15);
Enable Fast Connect, Disable Power Save Mode, Set DNS (No Effect)
There are also two recent and still open GitHub issues: Warning: Disconnected from API and API constantly disconnecting. Following these threads, I saw the change the network settings to include DNS entries and disable power save mode for the WIFI connection. The resulting config is this:
wifi:
fast_connect: on
power_save_mode: none
manual_ip:
dns1: 192.168.69.11
WLAN Connectivity (Again)
The final thing I investigated is literally back to the beginnings. This thread suggested that disconnects happen when the WIFI router switches channels, and [in this thread](https://community.home-assistant.io/t/esphome-all-devices-periodically-disconnect-see-log-details/222098/ periodically reconnects were observed related to the router changing the WIFI channel.
At my place, its rather noisy with neighboring WIFI’s, so the outer is configured to switch to the best available channel for preventing package collisions. So, I changed the channel to a fixed one. Almost immediately, I could see a familiar error message in the ESP Home logs!
[09:25:45][VV][api.service:043]: send_ping_response: PingResponse {}
[09:26:08][W][wifi_esp8266:466]: Event: Disconnected ssid=[redacted] bssid=[redacted] reason='Beacon Timeout'
INFO 192.168.3.213: Unexpected error while reading incoming messages: 0 bytes read on a total of 1 expected bytes
And furthermore, looking into the Home Assistant History chart, I could see across all ESP boards and sensor this single disconnect event!
I found the culprit! Switching to a fixed channel solved the disconnect problem!
Home Assistant Configuration
With the network connectivity error solved, I only need to find a way of preventing any false positives when the sensor becomes unavailable for other reasons, like an OTA update or when my router is reset.
Essentially, the unavailable
event should not trigger the detected motion
event as shown in this log:
11:26:22 AM - 3 hours ago
became unavailable
11:26:20 AM - 3 hours ago
detected motion
11:26:02 AM - 3 hours ago
became unavailable
As almost all things in Home Assistant, you can configure this as well. In this Home Assistant community thread, a user suggested to change the behavior of the built-in history stats component so that it immediately resolves the unavailable
state. Simply expressed, this means to change the event "entity became unavailable" event to "immediately "ignore this unavailability ".
To achieve this, add this to your configuration.yaml
:
# note: add double brackets around the start/end expressions
sensor:
- platform: history_stats
name: Ignore
entity_id: binary_sensor.esp01_motion
state: "unavailable"
type: time
start: "now()"
end: "now()"
The next day, I was very happy: No more unavailable triggers, only true positives when I moved in front of the sensor. The problem was finally solved.
Conclusion
False positives alarms of sensor are annoying, especially when you have complex automations in places. To find the root source of this error, I systematically investigated four areas: Network connectivity, WIFI connectivity, ESPHome configuration and Home Assistant configuration. From the many potential error sources, and their solutions, here is what worked in my case: First, ensure that all boards are configured with static IP addresses and the WIFI routers 2.4 GHz network is available on a fixed channel. Second, add a custom configuration for Home Assistants History stat component to immediately ignore a motions sensor unavailable state. I hope this article is helpful to you too.
Top comments (0)