Try this code
# ─────────────── Default values ───────────────
substitutions:
friendly_name: "UNSET_FRIENDLY_NAME"
device_id: "UNSET_DEVICE_ID"
description: "UNSET DESCRIPTION"
area: "UNSET AREA"
is_esp_32: "true"
logger: "INFO"
inside_temp_sensor_id: sensor.climate_temperature_2
inside_temp_name: "OFFICE"
outside_temp_sensor_id: sensor.climate_temperature
outside_temp_name: "OUTSIDE"
# ─────────────── Wi‑Fi: keep the link alive & reboot if lost ───────────────
wifi: # <<< NEW
ssid: !secret wifi_ssid
password: !secret wifi_pass
power_save_mode: none # stay awake → quicker reconnect
reboot_timeout: 5min # full restart only if Wi‑Fi gone 5 min
# optional – comment if you don’t care
# manual_ip: # avoids DHCP dance right when router reboots
# static_ip: 192.168.1.120
# gateway: 192.168.1.1
# subnet: 255.255.255.0
on_disconnect: # blink RGB while offline <<< NEW
then:
- light.turn_on:
id: rgb_led
red: 100%
on_connect:
then:
- light.turn_off: rgb_led
# ─────────────── Native API: don’t reboot just because HA is down ──────────
api: # <<< NEW
reboot_timeout: 0s # Wi‑Fi watchdog already covers us
encryption:
key: !secret api_key
ota:
password: !secret ota_pass
# ─────────────── Logging ───────────────
logger:
level: INFO
# ─────────────── Pins, buses, framework (unchanged) ───────────────
i2c:
- id: bus_a
sda: GPIO1
scl: GPIO2
scan: false
spi:
clk_pin: GPIO7
miso_pin: GPIO5
mosi_pin: GPIO6
one_wire:
- pin: GPIO10
platform: gpio
esp32:
board: esp32-c6-devkitc-1
variant: esp32c6
flash_size: 4MB
framework:
type: esp-idf
version: 5.3.1
platform_version: 6.9.0
sdkconfig_options:
CONFIG_ESPTOOLPY_FLASHSIZE_DETECT: y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB: y
CONFIG_OPENTHREAD_ENABLED: n
CONFIG_USE_MINIMAL_MDNS: y
# Memory optimisation
COMPILER_OPTIMIZATION_SIZE: y
COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE:y
CONFIG_HEAP_POISONING_DISABLED: y
esphome:
friendly_name: $friendly_name
name: $device_id
name_add_mac_suffix: false
comment: "${description}"
area: $area
includes:
- ./common/yaml/functions.h
project:
name: "Waveshare.ESP32-C6-LCD-1-47in"
version: "v"
platformio_options:
board_build.flash_mode: dio
build_flags:
- "-DI2C_NUM_1=I2C_NUM_0"
- "-Wl,-Map,output.map"
board_build.arduino.memory_type: qio_opi
platform_packages:
- platformio/toolchain-xtensa-esp-elf @ 14.2.0+20241119
# (lights, sensors, fonts, colours … unchanged – trimmed for brevity)
# ─────────────── Display with watchdog feed ───────────────
display:
- platform: st7789v
cs_pin: GPIO14
dc_pin:
number: GPIO15
ignore_strapping_warning: true
reset_pin: GPIO21
model: Waveshare 1.47in 172X320
id: tft_ha
rotation: 0
pages:
- id: page1
lambda: |-
App.feed_wdt(); // <<< NEW – yield to RTOS first
// id(tft_ha).update(); // (uncomment if you ever cache tiles)
/* … your original drawing code here – untouched … */
// inside the heavy for‑loop that draws the gradient,
// add an extra feed every ~32 pixels so a huge bar
// can’t starve networking for >100 ms
for (int i = rect_start_x; i <= rect_end_x; i++) {
DRAW_TEMP_COL(i);
if ((i & 31) == 0) App.feed_wdt(); // <<< NEW
}
/* … rest of the lambda unchanged … */
# ─────────────────────────────────────────────────────────────
yields often enough to keep the watchdog happy and gives the Wi‑Fi stack clear rules for surviving your 02 : 29 router reboot.
Tweak | Purpose |
---|---|
wifi.power_save_mode: none | Keeps the radio awake so reconnect is immediate. |
wifi.reboot_timeout: 5min | Hard‑reset if the stack wedges after a long outage. |
api.reboot_timeout: 0s | Don’t reset just because Home Assistant is offline. |
App.feed_wdt() at top of lambda | Gives control back to the RTOS before the heavy drawing work. |
Extra feed_wdt every 32 pixels | Stops the gradient loop from blocking the TCP/IP task during outages. |
LED feedback on on_disconnect / on_connect | Visual clue that the node is offline while the router reboots. |