Introduction
I started with the ESPHome dashboard Raspberry Pi setup mainly because I got tired of random device reboots and mystery IPs. You know the drill—Wi-Fi drops, YAML typos, and wondering if your DHT22 died or just hates you.
With a Raspberry Pi 4 and a stack of ESP8266 boards, I wired up a PIR motion sensor, a DHT22 for room conditions, and a couple of LEDs to get some visual feedback. After installing the ESPHome CLI and flashing my first firmware with a USB cable that had clearly seen better days, I finally got the dashboard running. Now, I’ve got full control—live logs, OTA updates, and GPIO pins behaving like they’re supposed to.
If you’ve got a Raspberry Pi and a pile of parts, I’ll walk you through wiring, flashing, and monitoring every device—without throwing it across the room.
Key Takeaways
- ESPHome makes defining device behavior and sensors easy using readable YAML configs.
- A Raspberry Pi running the ESPHome dashboard offers a centralized, flexible setup hub.
- GPIO pins on ESP8266/ESP32 need careful selection due to boot behavior.
- OTA updates are efficient once a device is flashed and has a static IP address.
- ESPHome integrates natively with Home Assistant, allowing full automation and real-time control of sensors and outputs.
- YAML structure and formatting are critical — always validate before flashing.
What You Need to Get Started
Basic Hardware Checklist
- Raspberry Pi (Model 3B+ or 4 recommended)
- ESP32 or ESP8266 board (like ESP32-WROOM-32 or NodeMCU v3)
- MicroSD card (8GB minimum)
- USB data cable (not just a power cable)
- DHT22 sensor, PIR motion sensor, and optional LEDs or relays
- Power supply (5V 3A for the Pi, separate if needed for ESP boards)
Software Prerequisites
- Raspberry Pi OS Lite (headless install is fine)
- Python 3 and pip
- ESPHome CLI (
pip install esphome) - Serial drivers (usually preinstalled, but double-check for USB UART chips like CH340)
Wi-Fi Network Essentials
- 2.4GHz Wi-Fi (ESP8266 and ESP32 don’t support 5GHz)
- SSID and password handy
- Consider using a static IP for ESP devices
Helpful Tools
| Tool | Purpose |
|---|---|
esphome CLI | Build, flash, and monitor |
| Text editor | Edit YAML files (e.g. nano, VS Code) |
ping and nmap | Network discovery and testing |
| Multimeter | Check GPIO voltage if needed |
Initial Steps
- Flash Raspberry Pi OS onto the SD card.
- Boot up and run system updates:
sudo apt update && sudo apt upgrade. - Install Python tools:
sudo apt install python3-pip.
Installing ESPHome on Raspberry Pi
Goal: Set up a working ESPHome dashboard on your Raspberry Pi that lets you build firmware and monitor devices.
1. Flash Raspberry Pi OS (Lite)
Why Lite?
Lite uses fewer system resources and works fine headless (no monitor). This gives ESPHome more breathing room.
Steps:
- Go to the Raspberry Pi Imager and download it.
- Insert your microSD card (at least 8GB) into your computer.
- Open the imager:
- Choose OS: Raspberry Pi OS Lite (64-bit)
- Choose storage: your microSD card
- Click the gear icon (✏️) to preconfigure:
- Set hostname (e.g.,
esphomepi.local) - Enable SSH
- Set Wi-Fi SSID and password if you’re not using Ethernet
- Set hostname (e.g.,
- Click Write and wait for it to finish.
2. Boot and Connect via SSH
Insert the microSD card into the Raspberry Pi and power it on.
Wait ~1 minute. Then on your main computer (same network):
ssh pi@esphomepi.local
If that fails, find its IP using your router or a tool like nmap, then:
ssh pi@192.168.1.xxx
Password is whatever you set in the Imager.
3. Update the System
Always do this first:
sudo apt update && sudo apt upgrade -y
This gets you the latest security patches and libraries.
4. Install Python and PIP
ESPHome is written in Python, so install the dependencies:
sudo apt install -y python3 python3-pip
Verify it’s working:
python3 --version
pip3 --version
Both should return versions (e.g., Python 3.11.x, pip 23.x)
5. Install ESPHome CLI
Now install ESPHome globally:
sudo pip3 install esphome
Once installed, test it:
esphome version
If that command fails, your $PATH might not include the pip install location. Try:
export PATH=$PATH:~/.local/bin
Then run it again.
6. Create a Working Directory
This is where you’ll store your YAML files:
mkdir ~/esphome
cd ~/esphome
Then launch the dashboard (this will keep running):
esphome dashboard config/
It should say:
INFO Starting dashboard on http://0.0.0.0:6052/
On your browser, go to:
http://<your_pi_ip>:6052
If it loads, you’re in.
7. Make It a System Service (Optional but Recommended)
Let’s make sure the dashboard launches automatically at boot.
Create a systemd service file:
sudo nano /etc/systemd/system/esphome-dashboard.service
Paste this in:
[Unit]
Description=ESPHome Dashboard
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/esphome
ExecStart=/usr/local/bin/esphome dashboard config/
Restart=always
[Install]
WantedBy=multi-user.target
Save and exit (Ctrl+X, then Y, then Enter).
Enable and start the service:
sudo systemctl daemon-reexec
sudo systemctl enable esphome-dashboard
sudo systemctl start esphome-dashboard
Check if it’s working:
sudo systemctl status esphome-dashboard
Now, even after a power cut, your dashboard starts back up automatically.
Creating Your First Node and YAML Configuration
Goal:
Use the ESPHome dashboard to generate a new firmware project that defines your ESP device, Wi-Fi setup, and first components like sensors or relays.
1. Open the ESPHome Dashboard
From any computer on the same network, go to:
http://<your_rpi_ip>:6052
If you see a clean interface with a “+ NEW DEVICE” button, you’re ready.
2. Create a New Node
Click “+ NEW DEVICE”.
You’ll be prompted for a few key details:
- Name: Use something simple, lowercase, no spaces (e.g.
livingroom_sensor) - Platform: ESP8266 or ESP32 — choose based on your hardware
(ESP8266: NodeMCU, Wemos D1 Mini; ESP32: more GPIOs, more memory) - Wi-Fi Info: Enter your 2.4GHz SSID and password
(ESP devices do not support 5GHz Wi-Fi!) - OTA Password (optional): A good idea if you want security for future firmware uploads
When you hit “NEXT”, ESPHome generates a starter YAML file.
3. Understand the Generated YAML
Here’s what you’ll likely see:
esphome:
name: livingroom_sensor
platform: ESP8266
board: nodemcuv2
wifi:
ssid: "YourSSID"
password: "YourPassword"
logger:
api:
ota:
Line-by-line Breakdown:
esphome:→ Device info;name:becomes your hostname (e.g.,livingroom_sensor.local)platform:→ MCU family (ESP32 or ESP8266)board:→ Specific board model; affects pin mapping (NodeMCU =nodemcuv2)wifi:→ Connects device to your networklogger:→ Enables logs over serial or OTAapi:→ Allows Home Assistant to talk to itota:→ Lets you push firmware over Wi-Fi
4. Add Your First Sensor (e.g. DHT22)
Let’s say you have a DHT22 connected to GPIO14 (D5 on NodeMCU). Add this:
sensor:
- platform: dht
pin: D5
model: DHT22
temperature:
name: "Living Room Temperature"
humidity:
name: "Living Room Humidity"
update_interval: 60s
Explanation:
platform: dht→ Tells ESPHome what kind of sensor you’re usingpin:→ Which GPIO it’s wired to (can use names like D5 or GPIO14)model:→ DHT11, DHT22, or AM2302update_interval:→ How often to poll the sensor
Save the file. You’re ready to flash the firmware.
5. Choose Installation Method
Click “INSTALL” on the dashboard.
You’ll see a few options:
- Plug into this computer → If ESP is connected via USB to your PC
- Plug into this Raspberry Pi → If the Pi is connected to the ESP via USB
- Wirelessly → OTA (only works after the first flash)
- Manual download → For flashing via other tools
6. Flash the Device (First Time = USB Only)
Choose the port your ESP is connected to, such as /dev/ttyUSB0 or COM3.
ESPHome will:
- Compile the firmware
- Flash it over USB
- Show serial logs as it boots
Look for:
[D][wifi:033]: Connecting to WiFi...
[D][wifi:276]: Successfully connected!
[I][ota:113]: Boot seems successful, enabling OTA
That means you’re online and ready for wireless updates in the future.
Wiring and Connecting Hardware Components
Goal:
Physically connect sensors and outputs (like relays or LEDs) to your ESP board so ESPHome can control or read from them.
1. Understand GPIO Pin Labels
Most ESP8266 or ESP32 boards label pins using D0–D8, but ESPHome wants GPIO numbers.
Here’s how they typically match on a NodeMCU (ESP8266):
| Label | GPIO |
|---|---|
| D0 | GPIO16 |
| D1 | GPIO5 |
| D2 | GPIO4 |
| D3 | GPIO0 |
| D4 | GPIO2 |
| D5 | GPIO14 |
| D6 | GPIO12 |
| D7 | GPIO13 |
| D8 | GPIO15 |
Use GPIO numbers in your YAML.
Example: If your DHT22 is on D5, that’sGPIO14.
2. Wiring a DHT22 Sensor (Temperature + Humidity)
Parts needed:
- DHT22 (3-pin or 4-pin)
- 10k resistor (recommended for stability)
Wiring:
| DHT22 Pin | Connects To |
|---|---|
| VCC | 3.3V on ESP board |
| DATA | GPIO14 (D5) |
| GND | GND on ESP board |
| 10k resistor between VCC and DATA |
Why a resistor? It helps clean the signal for more reliable readings.
3. Wiring a PIR Motion Sensor (HC-SR501)
Parts needed:
- HC-SR501 module
Wiring:
| PIR Pin | Connects To |
|---|---|
| VCC | 5V or 3.3V (check your module) |
| OUT | GPIO5 (D1, for example) |
| GND | GND |
Some PIR modules only work reliably on 5V. If so, make sure the OUT pin doesn’t push 5V into a 3.3V ESP pin. Use a voltage divider or level shifter.
4. Wiring an LED or Relay Module
Relay Module (optocoupled 5V):
| Relay Pin | Connects To |
|---|---|
| VCC | 5V |
| GND | GND |
| IN | GPIO (e.g., GPIO13 / D7) |
LED with Resistor:
| LED Lead | Connects To |
|---|---|
| Long | GPIO with 330Ω resistor |
| Short | GND |
For GPIO output devices (like relays or LEDs), you’ll define them as
switch:oroutput:in YAML.
5. Power Tips
- Don’t power sensors directly from GPIO pins — they can’t handle more than ~12mA.
- Use a stable 3.3V or 5V source from the board’s regulator or separate power supply.
- If using many sensors or relays, consider a separate buck converter (like LM2596) to avoid brownouts.
6. Testing Your Wiring
After wiring is complete:
- Plug the device into power
- Watch for the onboard LED blinking (on some boards)
- Check logs from ESPHome:
esphome logs livingroom_sensor.yaml
You should see the sensor initializing:
[D][dht:048]: Got Temperature=22.6°C Humidity=48.1%
If not, recheck:
- Wiring (especially VCC and GND)
- Pull-up resistor (for DHT22)
- GPIO pin number used in YAML
GPIO Configuration in YAML
Goal:
Define how each GPIO pin on your ESP board behaves — input, output, pull-up, interrupt, or PWM — using YAML.
1. Controlling a Relay or LED (GPIO Output)
To control something like a relay or LED, define a switch in YAML:
switch:
- platform: gpio
pin: GPIO13
name: "Relay Output"
What this does:
platform: gpiotells ESPHome it’s a physical outputpin:is the GPIO number, not the board label (e.g., D7 = GPIO13)name:gives it a name for dashboards or Home Assistant
You can now toggle this relay or LED from the dashboard or automation.
2. Physical Button (GPIO Input)
Let’s say you wire a push-button between GPIO0 and GND. You want ESPHome to react when it’s pressed.
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT_PULLUP
inverted: true
name: "Button Press"
on_press:
- switch.toggle: relay_output
Explanation:
binary_sensor:means a 2-state device (ON/OFF)INPUT_PULLUPuses an internal resistor to keep the pin high unless pulled low by button pressinverted: trueflips the logic (press = LOW = ON)on_press:runs an action — here it toggles another switch (relay_output)
3. Using an ID for Reusable Outputs
This helps if you want to refer to the switch in multiple places:
switch:
- platform: gpio
pin: GPIO13
id: relay_output
name: "Relay Output"
Now you can trigger relay_output from a button or automation.
4. Using PWM for Dimming or Motor Speed
To control brightness or speed, define a PWM output and attach it to a light:
output:
- platform: esp8266_pwm
pin: GPIO12
frequency: 1000 Hz
id: pwm_dimmer
light:
- platform: monochromatic
output: pwm_dimmer
name: "Dimmer LED"
Notes:
- Use
esp32_pwmon ESP32 boards - Adjust
frequencyto avoid flicker - Use this with LED strips or small DC motors
5. Analog Read (ESP8266 Only Has 1 ADC Pin)
To read voltage from a photoresistor or similar sensor:
sensor:
- platform: adc
pin: A0
name: "Ambient Light"
update_interval: 30s
- Only use A0 (GPIO17 on ESP8266)
- ESP32 has more ADC pins (GPIO32–39 commonly)
6. Debouncing and Noise Filters
For inputs like buttons or vibration sensors, use filters:
filters:
- delayed_on: 50ms
- delayed_off: 50ms
This prevents false triggers from electrical noise.
7. Input Interrupts
Need precise detection for short signals (like from a pulse sensor)?
binary_sensor:
- platform: gpio
pin: GPIO4
name: "Pulse Sensor"
filters:
- delayed_on: 10ms
ESPHome handles this efficiently — you don’t need to poll constantly.
Reminder: Some GPIOs affect boot mode (ESP8266). Avoid using these for inputs or outputs unless you understand their constraints:
| GPIO | Boot Behavior Risk |
|---|---|
| GPIO0 | Must be HIGH on boot |
| GPIO2 | Must be HIGH |
| GPIO15 | Must be LOW |
Would you like to continue to Sensors and Entity Setup, where we expand on defining specific sensor types in detail?
Sensors and Entity Setup
Goal:
Define different types of sensors in your YAML config, so ESPHome can monitor values like temperature, humidity, motion, light, and more.
1. DHT22 – Temperature & Humidity Sensor
This is a common digital sensor. You already wired it to, say, GPIO14 (D5 on a NodeMCU). Here’s the full config:
sensor:
- platform: dht
pin: GPIO14
model: DHT22
temperature:
name: "Living Room Temperature"
unit_of_measurement: "°C"
accuracy_decimals: 1
device_class: temperature
state_class: measurement
humidity:
name: "Living Room Humidity"
unit_of_measurement: "%"
device_class: humidity
state_class: measurement
update_interval: 60s
What each line means:
platform: dht– tells ESPHome what type of sensormodel: DHT22– use DHT11 or AM2302 if that’s your modelunit_of_measurement– sets how it’s displayedaccuracy_decimals– how many digits after the decimal pointstate_class–measurementfor live data (helps with graphs and long-term stats)
2. PIR Motion Sensor – Binary Sensor
This sensor only sends HIGH or LOW — motion or no motion.
binary_sensor:
- platform: gpio
pin: GPIO5
name: "Motion Sensor"
device_class: motion
filters:
- delayed_on: 50ms
- delayed_off: 2s
Why use filters?
delayed_onavoids false positives from noisedelayed_offkeeps motion “active” for a moment after movement ends
3. Light Sensor – LDR (Analog)
If using a photoresistor (LDR) with a voltage divider:
sensor:
- platform: adc
pin: A0
name: "Ambient Light"
update_interval: 10s
filters:
- multiply: 3.3
A0is the only ADC pin on ESP8266multiplylets you scale voltage into meaningful values
ESP32 gives you more analog input pins like GPIO32–39.
4. Air Quality Sensor – MQ135 or CCS811
For analog gas sensors:
sensor:
- platform: adc
pin: A0
name: "Air Quality Raw"
update_interval: 15s
For digital sensors like CCS811 (I²C):
i2c:
sensor:
- platform: ccs811
eco2:
name: "CO2"
tvoc:
name: "TVOC"
update_interval: 60s
You must connect the SDA and SCL pins to the correct GPIOs, usually:
- ESP8266: SDA = GPIO4 (D2), SCL = GPIO5 (D1)
- ESP32: You can assign them freely in the
i2c:block
5. Water Leak Sensor (Digital)
Basic leak sensors behave like buttons — on when wet.
binary_sensor:
- platform: gpio
pin: GPIO12
name: "Water Leak"
device_class: moisture
6. Vibration Sensor – SW-420
Another binary sensor:
binary_sensor:
- platform: gpio
pin: GPIO4
name: "Vibration Detected"
device_class: vibration
You can combine this with a buzzer or send alerts.
7. Using device_class and state_class Properly
These metadata tags tell Home Assistant how to format and interpret the values.
Examples:
| Entity | Device Class | State Class |
|---|---|---|
| Temperature | temperature | measurement |
| Humidity | humidity | measurement |
| Light (binary) | light | binary_sensor |
| CO2 (CCS811) | carbon_dioxide | measurement |
| Leak sensor | moisture | binary_sensor |
8. Using Filters for Smoothing or Calibration
filters:
- offset: 1.2 # Add to reading
- multiply: 0.98 # Scale down reading
- median:
window_size: 5
send_every: 1
send_first_at: 1
Filters help if readings are jumpy or slightly off due to resistor values.
OTA Firmware Builds and Uploads
Goal:
Send new firmware to your ESP device over Wi-Fi (OTA: Over The Air), instead of needing to connect it by USB every time.
1. Why OTA Matters
After the first USB flash, all future updates can be sent wirelessly. That means:
- No plugging and unplugging your ESP
- Faster, remote updates
- Easier placement of sensors and devices
But it only works if the device boots successfully, connects to Wi-Fi, and the IP address is reachable.
2. Flashing the First Time (Required Before OTA)
From the ESPHome dashboard:
- Click your device
- Click “Install”
- Choose Plug into this computer or Plug into this Raspberry Pi
- Select the USB port (e.g.
/dev/ttyUSB0,COM3, etc.)
The dashboard will:
- Compile your firmware into a
.binfile - Flash it over USB
- Open a serial log so you can watch it boot
You should see output like:
[D][wifi:037]: Connected to WiFi SSID 'YourNetwork'
[D][api.connection:071]: API Server listening on 6053
[I][ota:111]: OTA Ready
If you get that, the device is now OTA-capable.
3. Set Up a Static IP Address (Highly Recommended)
If your device’s IP changes after a router reboot, OTA will fail.
Add this to your YAML:
wifi:
ssid: "YourSSID"
password: "YourPassword"
manual_ip:
static_ip: 192.168.1.150
gateway: 192.168.1.1
subnet: 255.255.255.0
Use an IP that’s outside your router’s DHCP pool to avoid conflicts.
4. Secure OTA with a Password
Add this in your YAML:
ota:
password: "something_secure"
This prevents unauthorized access. ESPHome will prompt you for this when uploading firmware.
5. Upload New Firmware Wirelessly
In the dashboard:
- Click “Install”
- Choose “Wirelessly”
- Wait as it builds, uploads, and reboots the device
Or use CLI:
esphome upload livingroom_sensor.yaml
This works as long as:
- Device is online
- IP address hasn’t changed
- OTA password is correct
6. Monitor OTA Logs for Success or Errors
esphome logs livingroom_sensor.yaml
You’ll see entries like:
[I][ota:046]: Start updating via OTA...
[I][ota:348]: Update successful!
Or errors:
| Error | What It Means |
|---|---|
Connection failed | Device not on network or wrong IP |
Auth failed | OTA password incorrect |
Timeout | Device crashed or Wi-Fi dropped |
OTA not ready | Device not fully booted |
7. Force Reflash with Manual .bin File (Fallback)
If OTA fails and USB isn’t available, flash using:
Steps:
- From dashboard: Click “Install” → “Manual Download”
- Save the
.binfile - Use the flasher tool to upload it via USB
Monitoring Device Logs and Sensor Output
Goal:
Use logs to monitor the real-time behavior of your ESP device, check sensor values, diagnose connection issues, and catch YAML misconfigurations.
1. Viewing Logs from the Dashboard
From the ESPHome dashboard:
- Click on your device
- Click “Logs”
- Choose “Wirelessly” or Serial port
You’ll get a terminal-like view with real-time output from your ESP.
2. Using ESPHome CLI for Logs (More Control)
Run this in your terminal:
esphome logs livingroom_sensor.yaml
It connects using OTA and streams logs to your terminal.
If the device isn’t reachable, you’ll see an error like:
ERROR Connecting to <IP>: OTA connection failed
Try again using USB:
esphome logs livingroom_sensor.yaml --device /dev/ttyUSB0
Replace
/dev/ttyUSB0with your actual USB port if needed.
3. What to Look For in Logs
Here’s a normal boot log:
[D][wifi:033]: Connecting to WiFi...
[I][wifi:451]: WiFi connected!
[D][sensor:123]: 'Living Room Temperature': Sending state 21.8 °C
[D][binary_sensor:045]: 'Motion Sensor': State changed to: ON
[I][ota:111]: OTA Ready
Explanation:
[D]= Debug,[I]= Info- Sensor values show up every time they update
- Binary sensors show state changes
- OTA message means it’s ready for wireless updates
4. Increasing or Reducing Log Verbosity
In your YAML, change the logger: block:
logger:
level: DEBUG
Available levels:
NONE– disables loggingERROR– only serious issuesWARN– unexpected behaviorINFO– status updatesDEBUG– good default for troubleshootingVERBOSE– detailed infoVERY_VERBOSE– all internals, very noisy
5. Diagnosing Common Problems via Logs
| Symptom | What to Look For |
|---|---|
| No sensor readings | [W][sensor:xxx] initialization failed |
| Device keeps rebooting | [E][main] Reboot loop detected |
| OTA not working | Missing [I][ota] line after boot |
| Device unreachable | Not connecting to Wi-Fi |
| YAML misconfigurations | Error parsing config or wrong GPIO |
6. Live Testing Inputs and Outputs
- Press a button → log shows
binary_sensorstate - Trigger a PIR sensor →
Motion Sensorturns ON - Toggle a relay from the dashboard →
switchlogs ON/OFF
Logs help you verify if your wiring and YAML both behave as expected.
Integrating ESPHome with Home Assistant
Goal:
Pair your ESPHome device with Home Assistant, allowing you to control switches, read sensors, and automate everything inside your smart home setup.
Automatic Discovery via API
ESPHome uses a native API that Home Assistant can detect on the same network. After the ESP boots with the api: component in your YAML, Home Assistant will automatically show a notification:
New ESPHome device discovered
Click the notification, follow the setup prompt, and enter your OTA password if you set one. Home Assistant will then add the device and all its entities to your system.
What entities you get depends on your YAML. For example:
- sensor.living_room_temperature
- binary_sensor.motion_sensor
- switch.relay_output
- light.dimmer_led
You’ll find these under Settings > Devices & Services > ESPHome.
If Discovery Doesn’t Work
You can manually add the device:
- Go to Settings > Devices & Services
- Click “Add Integration”
- Search for “ESPHome”
- Enter the device’s IP address (use the static IP you assigned earlier)
- Provide the OTA password if prompted
If the ESP isn’t discoverable, double-check that:
- It’s powered and booted
- The Wi-Fi credentials are correct
- Your network doesn’t isolate devices (like some mesh or guest networks)
Lovelace UI: View and Control Entities
Once your device is added:
- Go to Dashboards or Overview
- Click “Edit”
- Add an entity card for your new sensors or switches
For example, a motion sensor shows a person icon that lights up when motion is detected. A temperature sensor shows the current value with a color-coded bar. Relays can be toggled on/off directly from the dashboard.
Example Home Assistant Automation
Let’s say you want a light to turn on when motion is detected, and off 30 seconds later.
In Home Assistant’s YAML automation:
automation:
- alias: Turn on light with motion
trigger:
platform: state
entity_id: binary_sensor.motion_sensor
to: 'on'
action:
- service: switch.turn_on
entity_id: switch.relay_output
- delay: '00:00:30'
- service: switch.turn_off
entity_id: switch.relay_output
You can also build this visually using the Automation Editor.
OTA Firmware Updates via Home Assistant
Once integrated, Home Assistant’s ESPHome add-on can push updates:
- Go to Settings > Devices
- Click your ESPHome device
- Click “Update” if there’s a newer firmware
- Upload a new YAML if needed using the dashboard
You can also restart the ESP device remotely, view its logs, or disable specific entities from the Home Assistant interface.
Tips, Common Pitfalls, and YAML Best Practices
Avoid YAML Formatting Mistakes
YAML is picky. If you get even one space wrong, it might break the entire config or silently ignore a component. Follow these rules:
- Use spaces, not tabs
- Always indent with 2 spaces per level
- End colons with a space (e.g.,
name: "Sensor"notname:"Sensor") - Validate your YAML using the “Validate” button in the ESPHome dashboard before uploading
Bad indentation example (will fail silently):
switch:
- platform: gpio # wrong, dash not aligned
pin: GPIO12
Correct version:
switch:
- platform: gpio
pin: GPIO12
Set Static IPs for Reliability
OTA updates often fail when a device’s IP address changes. Avoid this by assigning a static IP either in:
- The router (via DHCP reservation), or
- Directly in the ESPHome YAML:
wifi:
ssid: "your_wifi"
password: "your_password"
manual_ip:
static_ip: 192.168.1.150
gateway: 192.168.1.1
subnet: 255.255.255.0
This ensures ESPHome always knows where your device is.
Use id: Fields for Reuse
Instead of relying on entity names alone, assign an ID to switches, outputs, or sensors so you can refer to them across YAML sections:
switch:
- platform: gpio
pin: GPIO14
id: fan_switch
name: "Fan"
Now you can toggle this switch elsewhere in the config:
on_press:
- switch.toggle: fan_switch
Know Which GPIO Pins to Avoid
Some pins have special functions on boot. Using them incorrectly can cause the device not to start.
On ESP8266:
- GPIO0: Must be HIGH to boot
- GPIO2: Must be HIGH
- GPIO15: Must be LOW
On ESP32, the rules vary by module, but common troublemakers are GPIO0 and GPIO2.
If your device won’t flash or boots into a loop, try moving your sensor to a safer pin like GPIO4 or GPIO5.
Use Comments Generously
Label what each section does and where each wire connects:
# DHT22 sensor on GPIO14 (D5 on NodeMCU)
sensor:
- platform: dht
pin: GPIO14
model: DHT22
This saves hours of confusion later when you forget why something was done that way.
Handle Noisy Inputs with Filters
Physical buttons, vibration sensors, and some PIR sensors may bounce or give false triggers. Use filters: to smooth the data:
filters:
- delayed_on: 50ms
- delayed_off: 100ms
You can also use debounce or median filters for analog sensors.
Wi-Fi Troubleshooting Tips
If your device disconnects randomly or fails to reconnect:
- Check that your router’s 2.4GHz network is enabled
- Avoid hidden SSIDs
- Move the ESP device closer to the access point during setup
- Avoid using channels 12 or 13, which some ESP chips struggle with
Avoid Copy-Paste Conflicts
If cloning YAML files for multiple devices, make sure to change:
name:underesphome- Static IP address (if used)
- OTA password (if needed)
- Board type (if you’re mixing ESP8266 and ESP32)
Maintenance and Updates
Keep ESPHome Updated on Your Raspberry Pi
ESPHome is constantly improved with new board support, bug fixes, and components. To update:
sudo pip3 install --upgrade esphome
After upgrading, restart the dashboard if you’re running it as a service:
sudo systemctl restart esphome-dashboard
This ensures the new version is active.
Rebuild Firmware for Existing Devices
You don’t need to reconfigure a device from scratch. Just:
- Open the ESPHome dashboard
- Click your device
- Click “Install”
- Choose “Wirelessly” to send updated firmware
This applies your latest YAML changes — for example, if you’ve added a sensor or changed an update interval.
If you added new YAML components, ESPHome recompiles everything automatically.
Back Up Your YAML Files
Your YAML configurations define your entire setup. They should be backed up just like any important file.
To back up all ESPHome configs:
cd ~/esphome
tar -czvf esphome-backup.tar.gz config/
Store that archive on a USB drive, your NAS, or cloud storage.
For version control (and optional GitHub backup):
git init
git add .
git commit -m "Initial backup"
Reflashing a “Bricked” Device
Sometimes a bad config or power issue prevents OTA from working. If the ESP won’t boot:
- Hold the “BOOT” or “FLASH” button while plugging the USB in
- Use
esphome run device.yamlagain to reflash via USB - If needed, erase the chip first:
esptool.py erase_flash
Then flash again from scratch.
Add Components to Existing Devices
Just edit the YAML and re-upload. For example, to add a motion sensor:
binary_sensor:
- platform: gpio
pin: GPIO5
name: "Motion"
device_class: motion
Then install wirelessly as usual. Home Assistant will auto-detect the new entity.
Rename Devices Without Reflashing
If you change name: under esphome, you need to reflash the device because it changes the hostname and OTA behavior.
If you just want to change the display name in Home Assistant, do it via the Home Assistant UI — it won’t affect the device config.
Would you like me to continue with the final section: Final Checklist and Test Deployment?
Final Checklist and Test Deployment
Do This Before Uploading New Firmware
You’ve added your YAML, connected your hardware, and you’re ready to flash the device. Before clicking “Install,” run through this checklist:
- YAML file validates with no errors
- Wi-Fi SSID and password are correct
- Static IP address (if used) is unique and outside your DHCP range
- Sensors are wired correctly: VCC, GND, and correct GPIO pin
- Pull-up resistor added to DHT22 or buttons (if needed)
- No critical GPIOs used for boot mode (especially on ESP8266)
- OTA password (if set) is written down or remembered
Watch for First Boot Logs
After flashing, check the logs using either the dashboard or CLI:
esphome logs your_config.yaml
Look for:
- Sensor values being reported
- API server ready message
- OTA update message
- Wi-Fi connection success
If something fails, the logs will tell you where — incorrect pin, failed component initialization, or Wi-Fi auth issues.
Confirm Sensors Are Responding
Trigger the physical sensors and check for log updates:
- Motion sensor: Walk past it, check for
ONstate - Button: Press it and confirm the state change
- Temperature: Breathe on the sensor or warm it with your hand
If nothing shows in the logs, recheck the wiring and your YAML.
Try an OTA Update to Test Stability
Make a small change — for example, update a sensor name:
name: "Room Temperature Sensor"
Upload wirelessly to confirm that OTA works. If it fails, check:
- That the device has a stable IP address
- If you set the correct OTA password
- Whether the ESP is rebooting due to power issues
Label and Document Your Setup
Once your device is deployed, label the following:
- Which GPIOs connect to what
- What sensors are attached and how
- Any special settings or resistor values used
Also consider keeping a text or Markdown file alongside your YAML with extra context — especially if you’re managing multiple devices.
Optional: Setup Remote Access to the Dashboard
If you want to manage the ESPHome dashboard from outside your local network:
- Set up a VPN like WireGuard or Tailscale
- Use a secure reverse proxy with HTTPS
- Avoid opening port 6052 to the public internet
This lets you manage devices remotely without security risks.
FAQ
How do I install ESPHome on a Raspberry Pi?
Install Python 3 and pip, then run pip3 install esphome. Launch the dashboard using esphome dashboard config/.
What board type should I use for ESP8266 or ESP32?
For NodeMCU boards, use nodemcuv2. For ESP32 DevKit boards, use esp32dev. Check your exact board’s documentation for accuracy.
Why does my sensor show “nan” or fail to initialize?
Double-check the wiring, especially VCC and DATA lines. DHT sensors need a 10k pull-up resistor between VCC and DATA.
How can I fix OTA uploads that keep failing?
Ensure the device has a static IP, is online, and that you’re using the correct OTA password. Check if your router isolates wireless clients.
Can I use ESPHome without Home Assistant?
Yes. ESPHome devices can run independently and be accessed via their dashboard or API. Home Assistant adds automation and integration.
What happens if I use a bad GPIO pin?
ESP boards may refuse to boot or enter a reboot loop. Always avoid GPIO0, GPIO2, and GPIO15 for inputs or outputs on ESP8266 unless you understand the boot behavior.
Do I need to reflash my ESP to rename a device?
Only if you’re changing the esphome: name: value. For display names or friendly names, use Home Assistant’s UI instead.
References
- ESPHome Documentation
- ESPHome GitHub
- Home Assistant Integrations
- Raspberry Pi OS Downloads
- ESPHome Command Line Docs




