Home Assistant API disconnects from ESPHome when using expanded subnet range

I am struggling with troubleshooting this issue, I have found multiple issues where the entire device disconnects, but nothing recent where the only issue is updates from HA to ESPHome.

I have an ESP32-WROOM running ESPHome 2026.01.2 that consistently sends sensor data to HA, but stops accepting commands/updates from HA after boot. After approximately 10-30 seconds, I can no longer:

  • Turn the fan on/off
  • Change fan speed
  • Update number inputs

When the API disconnects/reconnects (showing “is unresponsive; disconnecting”), I get another brief 10-30 second window where controls work again, then it stops.

Setup:

  • ESPHome 2026.01.2 on ESP32-WROOM
  • Home Assistant 2025.10.2 in Docker with ipvlan (10.49.1.98)
  • Static IP: 10.49.0.50
  • 2.4GHz WiFi, single channel, mesh network (AP 8 feet away)
  • WiFi signal: -69dBm currently, -43 to -46dBm at boot
  • Power: 5V via VIN from buck converter
  • Pins: DHT11 on GPIO21, PWM fan on GPIO25
  • Network: Can consistently ping device, sensors update reliably in HA

Known issue in my config:
Lambda in temperature sensor overrides manual fan control on temp changes

Logs show:

  1. Boot successful, API connects (see first code block)
  2. Controls work for ~10-30 seconds after connection
  3. After timeout, API disconnects: WARNING Home Assistant 2025.10.2 (10.49.1.98): is unresponsive; disconnecting
  4. Immediate reconnect: INFO Successfully connected, controls work again briefly
  5. Cycle repeats

Log Output:
Boot is successful, I could have updated things here, but did not react in time, but debug info here could be helpful.

INFO Successful handshake with fireplace @ 10.49.0.50 in 0.104s
[15:16:05.023][I][app:206]: ESPHome version 2026.1.2 compiled on 2026-01-27 15:14:37 +0000
[15:16:05.029][I][app:213]: ESP32 Chip: ESP32 r3.1, 2 core(s)
[15:16:05.029][W][app:222]: Set minimum_chip_revision: "3.1" to reduce binary size
[15:16:05.032][C][logger:316]: Logger:
[15:16:05.032][C][logger:316]:   Max Level: VERBOSE
[15:16:05.032][C][logger:316]:   Initial Level: VERBOSE
[15:16:05.032][C][logger:322]:   Log Baud Rate: 115200
[15:16:05.032][C][logger:322]:   Hardware UART: UART0
[15:16:05.032][C][logger:332]:   Task Log Buffer Size: 768 bytes
[15:16:05.055][C][template.number:016]: Template Number 'Fireplace Low Temp Threshold'
[15:16:05.055][C][template.number:023]:   Unit of Measurement: '°F'
[15:16:05.055][C][template.number:049]:   Optimistic: YES
[15:16:05.060][C][template.number:452]:   Update Interval: 60.0s
[15:16:05.071][C][template.number:016]: Template Number 'Fireplace High Temp Threshold'
[15:16:05.071][C][template.number:023]:   Unit of Measurement: '°F'
[15:16:05.081][C][template.number:049]:   Optimistic: YES
[15:16:05.081][C][template.number:452]:   Update Interval: 60.0s
[15:16:05.083][C][template.number:016]: Template Number 'Fireplace Max Fan Speed'
[15:16:05.098][C][template.number:023]:   Unit of Measurement: '%'
[15:16:05.101][C][template.number:049]:   Optimistic: YES
[15:16:05.101][C][template.number:452]:   Update Interval: 60.0s
[15:16:05.114][C][uptime.sensor:016]: Uptime Sensor 'Uptime Sensor'
[15:16:05.114][C][uptime.sensor:016]:   State Class: 'total_increasing'
[15:16:05.114][C][uptime.sensor:016]:   Unit of Measurement: 's'
[15:16:05.114][C][uptime.sensor:016]:   Accuracy Decimals: 0
[15:16:05.117][C][uptime.sensor:026]:   Device Class: 'duration'
[15:16:05.117][C][uptime.sensor:030]:   Icon: 'mdi:timer-outline'
[15:16:05.127][C][uptime.sensor:033]:   Type: Seconds
[15:16:05.150][C][ledc.output:152]: Output:
[15:16:05.150][C][ledc.output:152]:   Channel: 0
[15:16:05.150][C][ledc.output:152]:   PWM Frequency: 25000.0 Hz
[15:16:05.150][C][ledc.output:152]:   Phase angle: 0.0°
[15:16:05.150][C][ledc.output:152]:   Bit depth: 11
[15:16:05.150][C][ledc.output:152]:   Pin GPIO25
[15:16:05.157][V][ledc.output:160]:   Max frequency for bit depth: 39062.500000
[15:16:05.157][V][ledc.output:160]:   Min frequency for bit depth: 9.536753
[15:16:05.157][V][ledc.output:160]:   Max frequency for bit depth-1: 78125.000000
[15:16:05.157][V][ledc.output:160]:   Min frequency for bit depth-1: 19.073505
[15:16:05.157][V][ledc.output:160]:   Max frequency for bit depth+1: 19531.250000
[15:16:05.157][V][ledc.output:160]:   Min frequency for bit depth+1: 4.768376
[15:16:05.157][V][ledc.output:160]:   Max res bits: 20
[15:16:05.157][V][ledc.output:160]:   Clock frequency: 80000000.000000
[15:16:05.172][C][dht:020]: DHT:
[15:16:05.172][C][dht:020]:   Model: DHT11
[15:16:05.172][C][dht:020]:   Internal pull-up: ON
[15:16:05.172][C][dht:152]:   Pin: GPIO21
[15:16:05.179][C][dht:452]:   Update Interval: 60.0s
[15:16:05.199][C][dht:016]:   Temperature 'Fireplace Temperature'
[15:16:05.199][C][dht:016]:     State Class: 'measurement'
[15:16:05.199][C][dht:016]:     Unit of Measurement: '°F'
[15:16:05.199][C][dht:016]:     Accuracy Decimals: 1
[15:16:05.200][C][dht:026]:     Device Class: 'temperature'
[15:16:05.210][C][dht:016]:   Humidity 'Fireplace Humidity'
[15:16:05.210][C][dht:016]:     State Class: 'measurement'
[15:16:05.210][C][dht:016]:     Unit of Measurement: '%'
[15:16:05.210][C][dht:016]:     Accuracy Decimals: 0
[15:16:05.228][C][dht:026]:     Device Class: 'humidity'
[15:16:05.228][C][speed.fan:021]: Speed Fan 'Fireplace Fan'
[15:16:05.237][C][speed.fan:290]:   Speed: YES
[15:16:05.237][C][speed.fan:290]:   Speed count: 100
[15:16:05.249][C][wifi:1304]: WiFi:
[15:16:05.249][C][wifi:1304]:   Local MAC: 64:B7:08:60:D5:68
[15:16:05.249][C][wifi:1304]:   Connected: YES
[15:16:05.249][C][wifi:1037]:   IP Address: 10.49.0.50
[15:16:05.261][C][wifi:1048]:   SSID: 'pepperoni pizza'
[15:16:05.261][C][wifi:1048]:   BSSID: 3C:7C:3F:B3:C9:11
[15:16:05.261][C][wifi:1048]:   Hostname: 'fireplace'
[15:16:05.261][C][wifi:1048]:   Signal strength: -43 dB ▂▄▆█
[15:16:05.261][C][wifi:1048]:   Channel: 1
[15:16:05.261][C][wifi:1048]:   Subnet: 255.255.252.0
[15:16:05.261][C][wifi:1048]:   Gateway: 10.49.1.1
[15:16:05.261][C][wifi:1048]:   DNS1: 0.0.0.0
[15:16:05.261][C][wifi:1048]:   DNS2: 0.0.0.0
[15:16:05.261][C][esphome.ota:075]: Over-The-Air updates:
[15:16:05.261][C][esphome.ota:075]:   Address: 10.49.0.50:3232
[15:16:05.261][C][esphome.ota:075]:   Version: 2
[15:16:05.267][C][esphome.ota:082]:   Password configured
[15:16:05.280][C][safe_mode:021]: Safe Mode:
[15:16:05.280][C][safe_mode:021]:   Successful after: 60s
[15:16:05.280][C][safe_mode:021]:   Invoke after: 10 attempts
[15:16:05.280][C][safe_mode:021]:   Duration: 300s
[15:16:05.292][C][safe_mode:038]:   Bootloader rollback: support unknown
[15:16:05.292][C][api:221]: Server:
[15:16:05.292][C][api:221]:   Address: 10.49.0.50:6053
[15:16:05.292][C][api:221]:   Listen backlog: 4
[15:16:05.292][C][api:221]:   Max connections: 8
[15:16:05.305][C][api:228]:   Noise encryption: YES
[15:16:05.323][C][wifi_signal.sensor:016]: WiFi Signal 'WiFi Signal Strength'
[15:16:05.323][C][wifi_signal.sensor:016]:   State Class: 'measurement'
[15:16:05.323][C][wifi_signal.sensor:016]:   Unit of Measurement: 'dBm'
[15:16:05.323][C][wifi_signal.sensor:016]:   Accuracy Decimals: 0
[15:16:05.323][C][wifi_signal.sensor:026]:   Device Class: 'signal_strength'
[15:16:05.345][C][mdns:177]: mDNS:
[15:16:05.345][C][mdns:177]:   Hostname: fireplace
[15:16:05.345][V][mdns:182]:   Services:
[15:16:05.345][V][mdns:184]:   - _esphomelib, _tcp, 6053
[15:16:05.353][V][mdns:187]:     TXT: version = 2026.1.2
[15:16:05.353][V][mdns:187]:     TXT: mac = 64b70860d568
[15:16:05.353][V][mdns:187]:     TXT: platform = ESP32
[15:16:05.360][V][mdns:187]:     TXT: board = nodemcu-32s
[15:16:05.360][V][mdns:187]:     TXT: network = wifi
[15:16:05.360][V][mdns:187]:     TXT: api_encryption = Noise_NNpsk0_25519_ChaChaPoly_SHA256
[15:16:25.760][V][sensor:080]: 'Uptime Sensor': Received new state 25.504000
[15:16:25.771][D][sensor:129]: 'Uptime Sensor' >> 26 s
[15:16:50.698][V][sensor:080]: 'Uptime Sensor': Received new state 50.506001
[15:16:50.708][D][sensor:129]: 'Uptime Sensor' >> 51 s
[15:17:00.371][I][safe_mode:066]: Boot seems successful; resetting boot loop counter

After a minute we get a disconnect, reconnect loop.

[15:18:35.015][W][api.connection:2221]: Home Assistant 2025.10.2 (10.49.1.98): is unresponsive; disconnecting
[15:18:35.015][V][api:192]: Remove connection Home Assistant 2025.10.2
[15:18:35.031][D][api:139]: Accept 10.49.1.98
[15:18:35.106][V][api.connection:1547]: Hello from client: 'Home Assistant 2025.10.2' | 10.49.1.98 | API Version 1.12
[15:18:35.109][D][api.connection:2221]: Home Assistant 2025.10.2 (10.49.1.98): connected
[15:18:39.324][D][number:064]: 'Fireplace High Temp Threshold': Setting value
[15:18:39.330][D][number:123]:   New value: 111.000000
[15:18:39.330][D][number:034]: 'Fireplace High Temp Threshold' >> 111.00
[15:18:39.891][D][number:064]: 'Fireplace High Temp Threshold': Setting value
[15:18:39.895][D][number:123]:   New value: 112.000000
[15:18:39.895][D][number:034]: 'Fireplace High Temp Threshold' >> 112.00
[15:18:40.421][D][number:064]: 'Fireplace High Temp Threshold': Setting value
[15:18:40.427][D][number:123]:   New value: 113.000000
[15:18:40.427][D][number:034]: 'Fireplace High Temp Threshold' >> 113.00
[15:18:40.896][D][number:064]: 'Fireplace High Temp Threshold': Setting value
[15:18:40.899][D][number:123]:   New value: 114.000000
[15:18:40.899][D][number:034]: 'Fireplace High Temp Threshold' >> 114.00
[15:18:49.123][D][number:064]: 'Fireplace Low Temp Threshold': Setting value
[15:18:49.123][D][number:123]:   New value: 68.000000
[15:18:49.123][D][number:034]: 'Fireplace Low Temp Threshold' >> 68.00
[15:18:53.413][D][number:064]: 'Fireplace High Temp Threshold': Setting value
[15:18:53.413][D][number:123]:   New value: 115.000000
[15:18:53.413][D][number:034]: 'Fireplace High Temp Threshold' >> 115.00
[15:18:55.701][V][sensor:080]: 'Uptime Sensor': Received new state 175.518005
[15:18:55.708][D][sensor:129]: 'Uptime Sensor' >> 176 s
[15:18:57.258][D][number:064]: 'Fireplace High Temp Threshold': Setting value
[15:18:57.267][D][number:123]:   New value: 114.000000
[15:18:57.267][D][number:034]: 'Fireplace High Temp Threshold' >> 114.00
[15:19:00.125][D][number:064]: 'Fireplace Low Temp Threshold': Setting value
[15:19:00.135][D][number:123]:   New value: 67.000000
[15:19:00.135][D][number:034]: 'Fireplace Low Temp Threshold' >> 67.00
[15:19:01.185][V][esp32.preferences:126]: Saving 3 items...
[15:19:01.190][V][esp32.preferences:140]: sync: key: 2195436266, len: 4
[15:19:01.199][V][esp32.preferences:140]: sync: key: 1676597230, len: 4
[15:19:01.203][V][esp32.preferences:150]: NVS data not changed skipping 3412239874  len=11
[15:19:01.207][D][esp32.preferences:155]: Writing 3 items: 1 cached, 2 written, 0 failed
[15:19:02.385][V][sensor:080]: 'WiFi Signal Strength': Received new state -45.000000
[15:19:02.386][D][sensor:129]: 'WiFi Signal Strength' >> -45 dBm
[15:19:02.599][D][number:064]: 'Fireplace Low Temp Threshold': Setting value
[15:19:02.599][D][number:123]:   New value: 66.000000
[15:19:02.599][D][number:034]: 'Fireplace Low Temp Threshold' >> 66.00
[15:19:04.127][D][dht:048]: Temperature 17.2°C Humidity 5.0%
[15:19:04.135][V][sensor:080]: 'Fireplace Temperature': Received new state 17.200001
[15:19:04.135][D][sensor:129]: 'Fireplace Temperature' >> 62.8 °F
[15:19:04.135][D][fan:050]: 'Fireplace Fan' - Setting:
[15:19:04.135][D][fan:053]:   State: OFF
[15:19:04.135][V][ledc.output:104]: Setting duty: 266 on channel 0
[15:19:04.136][D][fan:203]: 'Fireplace Fan' >>
[15:19:04.136][D][fan:203]:   State: OFF
[15:19:04.136][D][fan:208]:   Speed: 1
[15:19:04.136][V][sensor:080]: 'Fireplace Humidity': Received new state 5.000000
[15:19:04.173][D][sensor:129]: 'Fireplace Humidity' >> 5 %
[15:19:07.681][D][fan:050]: 'Fireplace Fan' - Setting:
[15:19:07.683][D][fan:053]:   State: ON
[15:19:07.683][V][ledc.output:104]: Setting duty: 284 on channel 0
[15:19:07.691][D][fan:203]: 'Fireplace Fan' >>
[15:19:07.691][D][fan:203]:   State: ON
[15:19:07.691][D][fan:208]:   Speed: 1
[15:19:10.898][D][fan:050]: 'Fireplace Fan' - Setting:
[15:19:10.899][D][fan:053]:   State: OFF
[15:19:10.899][V][ledc.output:104]: Setting duty: 266 on channel 0
[15:19:10.899][D][fan:203]: 'Fireplace Fan' >>
[15:19:10.899][D][fan:203]:   State: OFF
[15:19:10.908][D][fan:208]:   Speed: 1
[15:19:12.831][D][fan:050]: 'Fireplace Fan' - Setting:
[15:19:12.832][D][fan:053]:   State: ON
[15:19:12.839][V][ledc.output:104]: Setting duty: 284 on channel 0
[15:19:12.839][D][fan:203]: 'Fireplace Fan' >>
[15:19:12.839][D][fan:203]:   State: ON
[15:19:12.839][D][fan:208]:   Speed: 1
[15:19:14.495][D][fan:050]: 'Fireplace Fan' - Setting:
[15:19:14.495][D][fan:053]:   State: ON
[15:19:14.495][D][fan:059]:   Speed: 57
[15:19:14.501][V][ledc.output:104]: Setting duty: 1281 on channel 0
[15:19:14.501][D][fan:203]: 'Fireplace Fan' >>
[15:19:14.501][D][fan:203]:   State: ON
[15:19:14.502][D][fan:208]:   Speed: 57
[15:19:20.703][V][sensor:080]: 'Uptime Sensor': Received new state 200.518005
[15:19:20.712][D][sensor:129]: 'Uptime Sensor' >> 201 s

At this point is I could no longer update the entities.

[15:19:45.705][V][sensor:080]: 'Uptime Sensor': Received new state 225.520004
[15:19:45.710][D][sensor:129]: 'Uptime Sensor' >> 226 s
[15:20:01.179][V][esp32.preferences:126]: Saving 2 items...
[15:20:01.191][V][esp32.preferences:140]: sync: key: 3412239874, len: 11
[15:20:01.197][V][esp32.preferences:140]: sync: key: 2195436266, len: 4
[15:20:01.197][D][esp32.preferences:155]: Writing 2 items: 0 cached, 2 written, 0 failed
[15:20:02.372][V][sensor:080]: 'WiFi Signal Strength': Received new state -46.000000
[15:20:02.389][D][sensor:129]: 'WiFi Signal Strength' >> -46 dBm
[15:20:04.133][D][dht:048]: Temperature 17.0°C Humidity 8.0%
[15:20:04.133][V][sensor:080]: 'Fireplace Temperature': Received new state 17.000000
[15:20:04.133][D][sensor:129]: 'Fireplace Temperature' >> 62.8 °F
[15:20:04.133][D][fan:050]: 'Fireplace Fan' - Setting:
[15:20:04.138][D][fan:053]:   State: OFF
[15:20:04.139][V][ledc.output:104]: Setting duty: 266 on channel 0
[15:20:04.139][D][fan:203]: 'Fireplace Fan' >>
[15:20:04.139][D][fan:203]:   State: OFF
[15:20:04.142][D][fan:208]:   Speed: 57
[15:20:04.142][V][sensor:080]: 'Fireplace Humidity': Received new state 8.000000
[15:20:04.142][D][sensor:129]: 'Fireplace Humidity' >> 8 %
[15:20:10.701][V][sensor:080]: 'Uptime Sensor': Received new state 250.520004
[15:20:10.709][D][sensor:129]: 'Uptime Sensor' >> 251 s
[15:20:35.709][V][sensor:080]: 'Uptime Sensor': Received new state 275.527008
[15:20:35.714][D][sensor:129]: 'Uptime Sensor' >> 276 s
[15:21:00.706][V][sensor:080]: 'Uptime Sensor': Received new state 300.527008
[15:21:00.761][D][sensor:129]: 'Uptime Sensor' >> 301 s
[15:21:01.185][V][esp32.preferences:126]: Saving 1 items...
[15:21:01.195][V][esp32.preferences:140]: sync: key: 3412239874, len: 11
[15:21:01.195][D][esp32.preferences:155]: Writing 1 items: 0 cached, 1 written, 0 failed
[15:21:02.377][V][sensor:080]: 'WiFi Signal Strength': Received new state -46.000000
[15:21:02.383][D][sensor:129]: 'WiFi Signal Strength' >> -46 dBm
[15:21:04.124][D][dht:048]: Temperature 16.9°C Humidity 8.0%
[15:21:04.129][V][sensor:080]: 'Fireplace Temperature': Received new state 16.900000
[15:21:04.130][D][sensor:129]: 'Fireplace Temperature' >> 62.8 °F
[15:21:04.130][D][fan:050]: 'Fireplace Fan' - Setting:
[15:21:04.130][D][fan:053]:   State: OFF
[15:21:04.144][V][ledc.output:104]: Setting duty: 266 on channel 0
[15:21:04.144][D][fan:203]: 'Fireplace Fan' >>
[15:21:04.144][D][fan:203]:   State: OFF
[15:21:04.144][D][fan:208]:   Speed: 57
[15:21:04.152][V][sensor:080]: 'Fireplace Humidity': Received new state 8.000000
[15:21:04.152][D][sensor:129]: 'Fireplace Humidity' >> 8 %
[15:21:04.410][V][wifi:2107]: Roam check skipped, signal good (-46 dBm, attempt 1/3)
[15:21:25.710][V][sensor:080]: 'Uptime Sensor': Received new state 325.528992
[15:21:25.716][D][sensor:129]: 'Uptime Sensor' >> 326 s
[15:21:44.498][W][api.connection:2221]: Home Assistant 2025.10.2 (10.49.1.98): is unresponsive; disconnecting
[15:21:44.521][V][api:192]: Remove connection Home Assistant 2025.10.2
[15:21:44.530][D][api:139]: Accept 10.49.1.98
[15:21:44.600][V][api.connection:1547]: Hello from client: 'Home Assistant 2025.10.2' | 10.49.1.98 | API Version 1.12
[15:21:44.611][D][api.connection:2221]: Home Assistant 2025.10.2 (10.49.1.98): connected
[15:21:50.509][D][number:064]: 'Fireplace Low Temp Threshold': Setting value
[15:21:50.509][D][number:123]:   New value: 67.000000
[15:21:50.532][D][number:034]: 'Fireplace Low Temp Threshold' >> 67.00
[15:21:50.709][V][sensor:080]: 'Uptime Sensor': Received new state 350.531006
[15:21:50.715][D][sensor:129]: 'Uptime Sensor' >> 351 s

After the [15:21:44.611][D][api.connection:2221]: Home Assistant 2025.10.2 (10.49.1.98): connected line I can update again for a short period, usually around 10-30 seconds. Then I have to wait for the connection to reset.

Any help or ideas would be appreciated, external control is not a requirement for this project, but would definitly be a bonus.

fireplace.yaml

esphome:
  name: fireplace
esp32:
  board: nodemcu-32s
  framework:
    type: esp-idf
logger:
  level: VERBOSE
api:
  encryption: 
    key:!secret api_key
ota:
  - platform: esphome
    password: !secret ota_password
wifi:
  ssid: "pepperoni pizza"
  password: !wifi_password
  power_save_mode: none
  manual_ip:
    static_ip: 10.49.0.50
    gateway:  10.49.1.1
    subnet: 255.255.252.0
number:
  - platform: template
    name: "Fireplace Low Temp Threshold"
    id: low_temp_threshold
    optimistic: true
    min_value: 50
    max_value: 150
    step: 1
    initial_value: 70
    unit_of_measurement: "°F"
    mode: box
    restore_value: true
  - platform: template
    name: "Fireplace High Temp Threshold"
    id: high_temp_threshold
    optimistic: true
    min_value: 90
    max_value: 200
    step: 1
    initial_value: 98
    unit_of_measurement: "°F"
    mode: box
    restore_value: true
  - platform: template
    name: "Fireplace Max Fan Speed"
    id: max_fan_speed
    optimistic: true
    min_value: 1
    max_value: 100
    step: 1
    initial_value: 65
    unit_of_measurement: "%"
    mode: slider
    restore_value: true
sensor:
  - platform: dht
    pin: GPIO21
    model: DHT11
    temperature:
      id: "fireplace_temperature"
      name: "Fireplace Temperature"
      accuracy_decimals: 1
      filters:
         - exponential_moving_average:  
             alpha: 0.1
             send_every: 1
         - lambda: return x * (9.0/5.0) + 32.0;
      unit_of_measurement: "°F"
      on_value:
        then:
          - lambda: |-
              float temp = id(fireplace_temperature).state;
              float low_temp = id(low_temp_threshold).state;
              float high_temp = id(high_temp_threshold).state;
              float max_speed = id(max_fan_speed).state;
              if (temp <= low_temp) {
                // Below low threshold - turn off
                id(fireplace_fan).turn_off().perform();
              } else if (temp >= high_temp * 0.95) {
                // At or above 95% of high temp - max speed
                id(fireplace_fan).turn_on().set_speed(max_speed).perform();
              } else {
                // Between low and 95% of high - linear ramp
                float temp_range = (high_temp * 0.95) - low_temp;
                float temp_position = temp - low_temp;
                float speed_percent = (temp_position / temp_range) * max_speed;
                speed_percent = max(1.0f, min(max_speed, speed_percent));
                id(fireplace_fan).turn_on().set_speed((int)speed_percent).perform();
              }
    humidity:
      name: "Fireplace Humidity"
    update_interval: 60s
  - platform: wifi_signal
    name: "WiFi Signal Strength"
    id: wifisignal
    unit_of_measurement: "dBm"
    entity_category: "diagnostic"
    update_interval: 60s
  - platform: uptime
    type: seconds
    name: Uptime Sensor
    update_interval: 25s
output:
  - platform: ledc
    pin: GPIO25
    id: fireplace_fan_pwm
    frequency: 25000 Hz  # Above audible range
    min_power: 13%
fan:
  - platform: speed
    output: fireplace_fan_pwm
    id: fireplace_fan
    name: "Fireplace Fan"
    speed_count: 100  # Gives you 0-100% control

Pepperoni pizza fireplace? Yum! :wink:

Check your DNS settings. The requests may not be getting through your network configuration

Ha, yes, I name a good portion of things on my network based on food.

Thanks for the troubleshooting step.

  1. I set that to my networks primary DNS server, flashed and the same behavior persisted.
  2. I also updated to Home Assistant 2026.1.3. I somehow did not notice how out of date I was. Still no dice.

Could it be power related, if your PWM fan is drawing more current as it comes up to speed initially, and is naybe powered off the same power supply?

Is your ESP32 temperature OK, not too close to the fireplace?

Did you check if these can talk to each other?

What timeout?
To me it looks like HA doesn’t respond to esphome keepalive.
Do you have a lot going on on HA side?
Do you have other esphome devices having similar issues at the same time?

All valid questions. And one led me to a start of a solution!

When I moved the device to 10.49.1.xx the issue resolved. I am very confused

  • The network has a subnet mask of 255.255.252.0 which gives me a range of 10.49.0.1 - 10.49.3.254. So the esphome device was in my subnet with the ip of 10.49.0.50
  • both HA and esphome could talk to each other as ha could receive statistics and after the api reconnected ha could send updates to the fan/numbers

Taking @Karosm’s answer and my reading of the logs it seems like the keepalive got lost. I have more troubleshooting to do, but a path to a solution exists. Thanks! I will update if I figure out why the larger subnet may have been causing an issue.

If you are wondering why I care about the ip range, I do not have the networking equipment to do VLANS so I use IP ranges and my firewall to isolate devices that have no need to connect to the internet or potentially other devices on my network.


Answers for the other 2 questions for posterity

  1. PWM fans are powered off initially and when testing I have the same pattern even if they never turn on. The fans received 12v from the power supply directly, this also feeds into a buck converter to power the esp32 and dht11. The transformer supplies 5amps which should be more than enough, I calculated the entire setup draws less than 1 amp at full load.

? Maybe i have a misunderstanding of how PWM fans work, could they be drawing current even if they are switched off?

  1. Temp should be fine, currently sitting at 62. This was happening before I placed it under the fireplace and last night even with the fireplace on the top temperature was 96.

OK, cross off overheating and power supply draw, unless your fan is from an Airbus A380 engine…

“DNS: It’s always DNS” is the mantra! Except when it is sub-LANs…

If you found the documentation you followed a little confusing, could you please go back and add more detail to guide other folks that may encounter the same issues? Thanks.

I solved it. Thanks for your help, it was a networking issue.

I had forgotten to update the docker ipvlan when I expanded my network’s subnet.

I had set the subnet originally to 10.49.1.0/24. When I expanded my subnet at the gateway/router, I failed to also update the Docker vlan. After I updated the vlan to 10.49.0.0/22 and moved my ESPHome device back to 10.40.0.50, I feel confident the issue has been resolved.

The issue was not ESPHome related, it was docker networking and user error. The vlan’s routing was getting in the way as it did not know how to route the keepalive to the ESPHome device since it was outside of it’s known subnet.

I would never have solved it had I not tested moving it to 10.49.1.x based on feedback here. Thank you for indulging me.


For posterity, here is the terraform config before and after the fix. In case it is helpful for future searchers.

resource "docker_network" "vlan" {
  name   = "ipvlan"
  driver = "ipvlan"

  ipam_config {
    subnet   = "10.49.1.0/24"
    gateway  = "10.49.1.1"
    ip_range = "10.49.1.0/24" # optional
  }

  options = {
    parent = "enp2s0f0"
  }
}
resource "docker_network" "vlan" {
  name   = "ipvlan"
  driver = "ipvlan"

  ipam_config {
    subnet   = "10.49.0.0/22"
    gateway  = "10.49.1.1"
    ip_range = "10.49.0.0/22" # optional
  }

  options = {
    parent = "enp2s0f0"
  }
}
1 Like

If they are “switched off” only by pwm signal, yes, they still draw current, very little though.

Glad you solved it. In retrospect the clues were there in plain sight. Thanks for the guide for others to spot the issues.

Bonus: You’re a network whiz now!

1 Like