On March 5, 2026, we brought a fresh ESP32 HVAC board online and documented a cleaner workflow for future installs.
This post is the practical version of what happened: what worked, what confused us, and the exact flow we will use from now on.
The Goal
We wanted to:
- Connect a new ESP32 board over USB.
- Flash a minimal ESPHome base firmware.
- Join Wi-Fi.
- Make it visible in Home Assistant.
- Move to OTA updates so future zone-control flashes are wireless.
Step 1: Confirm Serial Connectivity First
Before touching configs, we validated USB serial access.
What we checked:
- Which COM port the board appears on (
COM13in our case). - That the port could be opened.
- That serial boot logs were readable.
This immediately told us the hardware link was good, even before Wi-Fi or Home Assistant were involved.
Step 2: Understand Boot Mode (Critical)
At one point the board reported:
DOWNLOAD_BOOTwaiting for download
That means it was in ESP32 UART bootloader mode (flash mode), not normal app mode.
Useful rule:
- Hold
BOOTto force flash mode for uploads. - Release
BOOTand reset normally to run firmware.
Step 3: Flash a Minimal ESPHome Base Firmware
We flashed a small base config that included:
wifiapiotaweb_servercaptive_portal
This is the bring-up firmware. It gives you enough to manage the board remotely without loading full zone logic yet.
Step 4: Verify Wi-Fi in Serial Logs
After flashing, serial logs showed initial auth failures, then successful connection.
Final result:
- Hostname:
esp-hvac-base - IP:
192.168.2.194 - OTA/API/Web ports reachable
Important takeaway: do not assume failure after first auth retries. Wait for a full retry cycle and confirm IP assignment.
Step 5: Home Assistant Discovery Nuance
This is where people get tripped up.
The device appeared in Home Assistant > Devices & Services as discovered, but did not automatically appear in the ESPHome dashboard project list.
Why:
- Devices & Services discovery comes from HA Core (zeroconf/mDNS + integration flow).
- ESPHome dashboard list is based on YAML projects present in
/config/esphome.
So discovery and dashboard project visibility are related, but not identical.
Step 6: The New Standard Flow
For every new board:
- Plug board in via USB.
- Confirm COM port + serial logs.
- Flash base ESPHome firmware (Wi-Fi + API + OTA + web).
- Confirm Wi-Fi IP from serial logs.
- In HA, complete discovered ESPHome integration setup (or add manually by IP).
- In ESPHome dashboard, create/import matching YAML project.
- Do all future flashes wirelessly (OTA).
Security And Config Hygiene
- Store Wi-Fi in
secrets.yaml(!secret wifi_ssid,!secret wifi_password). - Avoid hardcoding credentials in shared YAML.
- Keep a dedicated base firmware for recovery and onboarding.
- Move to encrypted API keys once base onboarding is stable.
Why This Flow Is Better
- Faster bring-up on replacement boards.
- Less USB plugging and unplugging after first flash.
- Clear separation between board online and application config.
- Easier debugging because each stage has a single success signal:
- USB success: serial logs.
- Wi-Fi success: IP assigned.
- HA success: config entry.
- OTA success: wireless upload works.
Final Outcome
The board is online, reachable, and OTA-ready.
We now have a repeatable onboarding flow that is easier to troubleshoot and safer for future zone-control deployments.
Leave a Reply