Remote Control and Monitoring System Using ESP-01 and Home Assistant
01 Overview
This project presents a modular remote control and monitoring system using two ESP-01 (ESP8266/ESP8285) Wi-Fi modules. Node 1 functions as the temperature monitoring and relay control node, equipped with a DS18B20 temperature sensor connected to GPIO2 and one relay connected to GPIO0. Node 2 functions as a dedicated relay control node, operating two relays through GPIO2 and GPIO0. Together, the two nodes control a total of three relays while monitoring the ambient temperature through a single dashboard.
A significant portion of this project focused on configuring the software environment rather than assembling the hardware. Home Assistant and ESPHome were installed in Docker containers running on a Windows computer. This setup required resolving several networking and communication issues to ensure reliable connectivity between both ESP-01 nodes and Home Assistant. The complete configuration and troubleshooting process is documented in this project to assist others who wish to build a similar system.
After the system was successfully configured, Home Assistant detected both Node 1 and Node 2, displaying all three relays as controllable switches and the temperature as a real-time sensor reading on a single dashboard. A temperature protection automation was also implemented: whenever the temperature exceeds 35°C, all three relays automatically turn off to protect the connected devices. The relays remain off until they are manually reactivated by the user through the dashboard.
Project Use Case
This remote control and monitoring system is suited for any scenario where devices need to be controlled remotely while also being monitored for safety conditions. Key use cases include:
- Home Automation — Allows users to remotely control lights, fans, and other electrical appliances through the Home Assistant dashboard without replacing existing devices with expensive smart appliances.
- Temperature-Based Protection — Automatically turns off all connected relays when temperature exceeds 35°C, protecting equipment from heat damage without requiring user intervention.
- Learning and Development — Serves as a practical platform for learning IoT technologies, including ESPHome, Home Assistant, and Docker, while demonstrating how they work together in a home automation system.
- Easy to Use — The Home Assistant dashboard provides a user-friendly interface that allows users to monitor temperature, control relays, create automations, and expand the system without requiring programming knowledge.
02 Hardware and Software Components
Gather everything below before you start. This is your checklist — names, models, and versions only.
Hardware Components
| Component | Description |
|---|---|
| ESP-01 / ESP-01S (ESP8266) x2 | Node 1 — DS18B20 temperature sensor (GPIO2) and Relay 2 (GPIO0); Node 2 — Relay 3 (GPIO2) and Relay 4 (GPIO0) |
| DS18B20 Temperature Sensor x1 | One-wire digital temperature probe connected to Node 1 via GPIO2 with a 4.7kΩ pull-up resistor to 3.3V |
| 3-Channel Relay Module | One relay channel connected to Node 1 (GPIO0) and two relay channels connected to Node 2 (GPIO2 and GPIO0) — all active-LOW (SRD-05VDC-SL-C) |
| 4.7kΩ Resistor x1 | Pull-up resistor for the DS18B20 one-wire data line — required for correct sensor operation |
| FT232R USB to Serial Module x1 | For initial USB flashing of each ESP-01 — can be reused across both nodes |
| MB102 Breadboard Power Supply Module (3.3V / 5V) x1 | Stable power supply for all components. Accepts 6.5V–12V via DC jack. |
| Jumper Wires (M-M, M-F) | For all flashing and relay connections |
| Windows PC | Acts as the host machine for Docker, Home Assistant, and the ESPHome dashboard |
| 12V DC Power Adapter x1 | Powers the MB102 via DC jack (recommended: 12V, 1A or higher) |
| Breadboard x1 | Prototyping and connections |
| Pushbutton x2 | Manual reset button for each ESP-01 node — press to pull RST to GND and restart the module |
Software Tools
| Software | Version / Details |
|---|---|
| Windows Subsystem for Linux (WSL2) | Provides the Linux environment Docker actually runs in |
| Ubuntu (via WSL2) | The Linux distribution hosting Docker Engine, ESPHome, and Home Assistant |
| Docker Engine | Installed directly inside Ubuntu via get.docker.com — not Docker Desktop (see Section 05) |
| Docker Compose | Orchestrates the Home Assistant and ESPHome containers as one stack |
| Home Assistant (Container edition) |
ghcr.io/home-assistant/home-assistant:stable — the dashboard, automation engine, and device registry |
| ESPHome (Dashboard edition) |
ghcr.io/esphome/esphome — compiles and flashes firmware, manages device YAML |
| ESPHome One-Wire (dallas_temp) | Built-in ESPHome component that communicates with the DS18B20 temperature sensor over the One-Wire protocol via GPIO2 on Node 1 — no separate installation required |
| Home Assistant Automation Engine | Built-in Home Assistant feature used to create the temperature protection automation — automatically turns off all three relays when temperature exceeds 35°C |
| esptool.js (web.esphome.io) | Browser-based USB flashing tool, used for the first flash of each node |
| Windows Task Scheduler | Automates startup of WSL2, Docker, and both containers on every login |
03 Application Discussion
Here is what each component does and why it is part of this project.
ESP-01 (ESP8266) Wi-Fi Module
The ESP-01 is one of the smallest and most affordable Wi-Fi modules based on the ESP8266 microcontroller. Despite its compact size, it provides only two usable General-Purpose Input/Output (GPIO) pins: GPIO0 and GPIO2. In this project, two ESP-01 modules are assigned different roles to maximize their limited I/O capabilities. Node 1 uses GPIO2 to interface with the DS18B20 temperature sensor and GPIO0 to control Relay 2. Meanwhile, Node 2 uses GPIO2 and GPIO0 to control Relay 3 and Relay 4, respectively. This modular design allows each node to perform a dedicated function, simplifies system management, and provides flexibility for future expansion by enabling additional nodes to be integrated as needed.
DS18B20 Temperature Sensor
The DS18B20 is a digital temperature sensor that communicates using the One-Wire protocol, allowing data transmission over a single signal wire. In this project, the sensor is connected to Node 1 through GPIO2 and requires a 4.7 kΩ pull-up resistor between the data line and the 3.3 V supply for proper operation. Without this resistor, the sensor will not communicate correctly with the ESP-01, regardless of the ESPHome YAML configuration. The DS18B20 measures the ambient temperature and transmits the readings to Home Assistant through ESPHome at 30-second intervals. These real-time temperature readings are used to trigger a Home Assistant automation that automatically turns off all three relays whenever the temperature exceeds 35°C, providing protection for the connected devices.
3-Channel Relay Module (SRD-05VDC-SL-C)
The project uses a total of three relay channels across both nodes. Node 1 controls one relay through GPIO0, and Node 2 controls two relays through GPIO2 and GPIO0. All relay channels use SRD-05VDC-SL-C modules which are active-LOW, meaning the relay turns on when the GPIO pin outputs a LOW signal instead of a HIGH signal. This behavior is configured in the ESPHome firmware using the inverted: true switch option, ensuring that the ON/OFF state displayed in Home Assistant matches the physical relay state correctly.
ESPHome
ESPHome is a firmware framework used to program ESP8266 and ESP32 devices, such as the ESP-01. It uses YAML configuration files to generate the firmware and allows the devices to communicate with Home Assistant through the ESPHome API. In this project, ESPHome is also used to flash the firmware to the ESP-01 modules and perform wireless (OTA) updates. Since the project uses Home Assistant Container instead of Home Assistant OS, ESPHome runs in its own Docker container.
Home Assistant
Home Assistant serves as the central control system of the project. It connects to each ESP-01 node through the ESPHome integration and displays each relay as a switch and the temperature as a live sensor reading on the dashboard. Users can easily monitor and control all relays through a web browser, create automations, and manage the system without needing to write any code.
Docker & WSL2
Docker is used to run Home Assistant and ESPHome in separate containers, allowing both applications to run without being installed directly on Windows. Since Docker cannot run natively on Windows, it uses WSL2 (Windows Subsystem for Linux), which provides a Linux environment for running Docker. In this project, Docker Engine was installed directly inside the WSL2 Ubuntu environment instead of using Docker Desktop. This setup provides a lightweight and flexible environment for running the home automation system.
FT232R USB to UART Module
Since the ESP-01 has no onboard USB port, this adapter bridges its serial TX/RX pins to a USB port on the PC, presenting itself as a COM port. It is required for the very first firmware flash of each node, since a brand-new device cannot yet be reached wirelessly (OTA) until it already has working Wi-Fi firmware on it.
04 Hardware Setup
Wire the components to the board using the tables below.
Node 1 — ESP-01 Temperature Sensor and Relay 2
| ESP-01 Pin | Connects To | Description |
|---|---|---|
| GPIO2 | DS18B20 Data (DQ) | One-wire temperature sensor data line — requires 4.7kΩ pull-up resistor to 3.3V |
| GPIO0 | IN1 on relay module | Controls Relay 2 — active LOW |
| CH_PD (EN) | 3.3V rail | Must be tied HIGH for the module to boot at all |
| RST | Pushbutton (one leg) | Manual reset — pulls RST to GND when pressed |
| GND | Pushbutton (other leg) | Ground connection for the reset button |
Assembly Instructions
- Place the Node 1 ESP-01 module on the breadboard.
- Connect GPIO2 to the DS18B20 data (DQ) pin.
- Connect a 4.7kΩ resistor between the DS18B20 data pin and the 3.3V rail.
- Connect GPIO0 to IN1 on the relay module to control Relay 2.
- Connect CH_PD (EN) directly to the 3.3V rail — this pin must be HIGH for the ESP-01 to power on.
- Connect one leg of the pushbutton to RST and the other leg to GND.
Node 2 — ESP-01 Relay Control (Relay 3 & Relay 4)
| ESP-01 Pin | Relay Module Pin | Description |
|---|---|---|
| GPIO2 | IN1 | Controls Relay 3 — active LOW |
| GPIO0 | IN2 | Controls Relay 4 — active LOW |
| CH_PD (EN) | 3.3V rail | Must be tied HIGH for the module to boot at all |
| RST | Pushbutton (one leg) | Manual reset — pulls RST to GND when pressed |
| GND | Pushbutton (other leg) | Ground connection for the reset button |
Assembly Instructions
- Place the Node 2 ESP-01 module on a separate section of the breadboard.
- Connect GPIO2 to IN1 on the relay module to control Relay 3.
- Connect GPIO0 to IN2 on the relay module to control Relay 4.
- Connect CH_PD (EN) directly to the 3.3V rail — this pin must be HIGH for the ESP-01 to power on.
- Connect one leg of the pushbutton to RST and the other leg to GND.
Shared Components — MB102 Power Supply and Flashing
| Pin / Signal | Connects To |
|---|---|
| MB102 3.3V rail | VCC of both ESP-01 modules and DS18B20 VCC |
| MB102 5V rail | VCC of the relay module (coil power) |
| MB102 GND rail | GND of both ESP-01 modules, relay module, and DS18B20 |
| DC adapter (6.5–12V) | MB102 DC jack input |
| USB-TTL adapter TX | RX of the ESP-01 being flashed |
| USB-TTL adapter RX | TX of the ESP-01 being flashed |
| USB-TTL adapter GND | MB102 GND rail |
| GPIO0 → GND | Flash mode only — disconnect after flashing |
Assembly Instructions
- Place the MB102 power supply module at one end of the breadboard.
- Set one onboard jumper to 3.3V and connect that rail to the VCC of both ESP-01 modules and the DS18B20.
- Set the other onboard jumper to 5V and connect that rail to the VCC of the relay module.
- Connect the MB102 GND rail to the GND of both ESP-01 modules, the relay module, and the DS18B20.
- Connect the DC power adapter to the MB102's DC jack input.
- When flashing a node, connect the USB-TTL adapter's TX to that ESP-01's RX, and RX to that ESP-01's TX, with GND shared to the MB102 GND rail.
- Pull GPIO0 to GND on the node being flashed before powering it on, to enter flash mode.
- After flashing completes, disconnect GPIO0 from GND and disconnect the USB-TTL adapter before moving to the other node.
05 Software Setup
This is the core of the project. Follow these steps in order — several of them exist specifically because of problems encountered while building this exact system, and skipping them will reproduce those same problems.
Step 1 — Enable WSL2
- Open PowerShell.
- Run:
wsl --install
- Restart the PC when prompted. Ubuntu installs automatically as the default distribution.
Step 2 — First Launch of Ubuntu
- Ubuntu opens automatically after reboot, or launch it from the Start menu.
- Create a Unix username (lowercase, no spaces) and a password when prompted.
Step 3 — Install Docker Engine Directly Inside Ubuntu
Docker Desktop was the original plan, but installation stalled due to insufficient free space on the Windows drive. Rather than fight that constraint, Docker Engine was installed directly inside the Ubuntu/WSL2 environment — a lighter-weight path with no separate Windows application at all.
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo service docker start
curl: (23) client returned ERROR on write means the download was interrupted. Run cd ~ first to confirm you are in the Linux home directory (not /mnt/c/...), then retry the curl command.Step 4 — Set Up the Project Folder and Docker Compose Stack
- Create the project structure:
mkdir -p ~/smart-home/homeassistant
mkdir -p ~/smart-home/esphome
- Create the Compose file directly via terminal:
cat > ~/smart-home/docker-compose.yml << 'EOF'
services:
homeassistant:
container_name: homeassistant
image: ghcr.io/home-assistant/home-assistant:stable
restart: unless-stopped
privileged: true
network_mode: host
volumes:
- ./homeassistant:/config
environment:
- TZ=Asia/Manila
esphome:
container_name: esphome
image: ghcr.io/esphome/esphome
restart: unless-stopped
network_mode: host
volumes:
- ./esphome:/config
EOF
- Start the stack:
cd ~/smart-home
sudo docker compose up -d
sudo docker ps
Confirm both containers show Up, then open:
- Home Assistant — http://localhost:8123
- ESPHome Dashboard — http://localhost:6052
cd ~/smart-home and getting "No such file or directory" almost always means the command was typed into PowerShell instead of Ubuntu. Type wsl first to enter Ubuntu.Step 5 — Fix WSL2's Hidden Local-Network Isolation
This is the single most consequential issue in the whole project. A normal ping from Windows PowerShell to an ESP-01's IP address can succeed perfectly, while Home Assistant still reports the device as offline. The reason: WSL2's default networking mode isolates the Linux environment — and therefore every Docker container inside it — from the host's real local network.
This is confirmed directly by testing from inside the container itself:
sudo docker exec -it homeassistant ping -c 4 <esp-node-ip>
100% packet loss here confirms the issue. The fix is to switch WSL2 to mirrored networking mode:
wsl --shutdown
notepad "$env:USERPROFILE\.wslconfig"
Add the following content to that file:
[wsl2]
networkingMode=mirrored
vmIdleTimeout=-1
Save, then restart WSL and the stack:
wsl
sudo service docker start
cd ~/smart-home
sudo docker compose up -d
ip route and make sure each device's static IP still matches that range.Step 6 — Assign Static IPs and Avoid Multi-Node Collisions
Without a fixed IP, DHCP can hand an ESP-01 a different address every time it reconnects, and Home Assistant's reliance on mDNS to rediscover it proved unreliable inside this Docker/WSL2 setup. The fix is a hardcoded static IP per device (shown in full in Section 06). When running more than one node, each device must have a unique static_ip and a unique name — reusing either causes the two physical devices to intermittently fight over the same network identity.
To find your current gateway and pick a safe static IP, run the following commands in WSL:
ip route # look for "default via" — that is your gateway
arp -a # shows all devices currently on the network — pick an unused address
ip route first to confirm the current gateway before troubleshooting connectivity issues.Step 7 — First Flash via USB
- Wire the ESP-01 to the USB-to-TTL adapter per Section 04, with GPIO0 pulled to GND.
- Open the ESPHome dashboard at http://localhost:6052 and create a new device.
- Paste in the YAML configuration from Section 06 for that node.
- Click Install → Plug into this computer (or use web.esphome.io directly with the "Manual download" firmware file).
- After flashing completes, disconnect GPIO0 from GND and power-cycle the board.
Step 8 — Add Each Node to Home Assistant
- In Home Assistant, go to Settings > Devices & Services > Add Integration > ESPHome.
- Enter the node's static IP as the Host, leave Port at
6053. - When prompted, paste the device's
api.encryption.keyfrom its YAML.
Step 9 — Automate Startup So It Survives a Reboot
Docker Engine installed this way does not auto-start with Windows the way Docker Desktop does. Both Docker and WSL2 idle-shutdown issues need to be solved together.
- Create the startup script:
cat > ~/start-smarthome.sh << 'EOF'
#!/bin/bash
sudo service docker start
sleep 5
cd ~/smart-home
sudo docker compose up -d
EOF
chmod +x ~/start-smarthome.sh
- Allow this script to run without an interactive password prompt:
sudo visudo
Add this line at the bottom (replace YOUR_USERNAME):
YOUR_USERNAME ALL=(ALL) NOPASSWD: /usr/sbin/service docker start, /usr/bin/docker compose up -d
- Register a Windows scheduled task (run from an Administrator PowerShell window):
schtasks /create /tn "StartSmartHome" /tr "wsl.exe -d Ubuntu /home/YOUR_USERNAME/start-smarthome.sh" /sc onlogon /rl highest
Step 10 — Create the Temperature Protection Automation
Once both nodes are online in Home Assistant, create an automation that automatically turns off all three relays when the temperature sensor on Node 1 exceeds 35°C. The relays stay off until the user manually turns them back on.
- Go to Settings → Automations & Scenes → Create Automation
- Click Start with an empty automation
- Click the three-dot menu (⋮) in the top right → Edit in YAML
- Replace everything with the following:
alias: Turn off relays when temperature exceeds 35°C
description: >
Automatically turns off Relay 2, Relay 3, and Relay 4 when the
temperature sensor reads above 35°C. The user must manually
turn the relays back on.
triggers:
- entity_id: sensor.control_system_node_1_temperature
above: 35
trigger: numeric_state
actions:
- action: switch.turn_off
target:
entity_id: switch.control_system_node_1_relay_2
- action: switch.turn_off
target:
entity_id: switch.control_system_node_2_relay_3
- action: switch.turn_off
target:
entity_id: switch.control_system_node_2_relay_4
mode: single
- Click Save and confirm the automation is enabled (toggle is blue) in the automations list.
06 Code
Each node uses its own ESPHome YAML configuration. Replace the placeholder Wi-Fi credentials, encryption key, and network values for your own setup before flashing.
Node 1 Configuration — Temperature Sensor and Relay 2
esphome:
name: control-system-node-1
friendly_name: Control-System Node 1
esp8266:
board: esp8285
logger:
baud_rate: 0
api:
encryption:
key: "YOUR_NODE1_API_KEY"
ota:
- platform: esphome
password: YOUR_OTA_PASSWORD
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 10.0.0.51
gateway: 10.0.0.1
subnet: 255.255.255.0
ap:
ssid: "Control-System Node 1 Fallback Hotspot"
password: "YOUR_FALLBACK_PASSWORD"
captive_portal:
one_wire:
- platform: gpio
pin: GPIO2
sensor:
- platform: dallas_temp
name: "Temperature"
update_interval: 30s
switch:
- platform: gpio
pin: GPIO0
name: "Relay 2"
inverted: true
Node 2 Configuration — Relay 3 & Relay 4
esphome:
name: control-system-node-2
friendly_name: Control System Node 2
esp8266:
board: esp8285
logger:
baud_rate: 0
api:
encryption:
key: "YOUR_NODE2_API_KEY"
ota:
- platform: esphome
password: YOUR_OTA_PASSWORD
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 10.0.0.52
gateway: 10.0.0.1
subnet: 255.255.255.0
ap:
ssid: "Control System Node 2 Fallback Hotspot"
password: "YOUR_FALLBACK_PASSWORD"
captive_portal:
switch:
- platform: gpio
pin: GPIO2
name: "Relay 3"
inverted: true
- platform: gpio
pin: GPIO0
name: "Relay 4"
inverted: true
secrets.yaml (shared by both nodes)
wifi_ssid: "YOUR_WIFI_SSID"
wifi_password: "YOUR_WIFI_PASSWORD"
static_ip values, the name fields, and the api.encryption.key values must be unique per node. Reusing a static_ip across two physical devices causes them to intermittently take over each other's address, making both unreliable.docker-compose.yml (full stack)
services:
homeassistant:
container_name: homeassistant
image: ghcr.io/home-assistant/home-assistant:stable
restart: unless-stopped
privileged: true
network_mode: host
volumes:
- ./homeassistant:/config
environment:
- TZ=Asia/Manila
esphome:
container_name: esphome
image: ghcr.io/esphome/esphome
restart: unless-stopped
network_mode: host
volumes:
- ./esphome:/config
07 Code Breakdown
Here is what each part of the configuration does. Read this after flashing to understand how the system actually works.
ESPHome YAML Fields
| Field | Purpose |
|---|---|
| esphome.name | The device's unique identifier. Must differ between Node 1 and Node 2 — Home Assistant uses this to distinguish devices. |
| esp8266.board | Tells the compiler which physical chip variant to target — esp8285 for this hardware. |
| logger.baud_rate: 0 | Disables serial logging on the TX pin (GPIO1) to prevent crashes caused by UART output interfering with normal operation. Without this, the ESP-01 may reboot unexpectedly. |
| api.encryption.key | A unique per-device key used to encrypt the connection between Home Assistant and the ESPHome native API. Generated automatically when the device is first created in the dashboard. |
| ota | Enables wireless firmware updates after the first USB flash, using the ESPHome native OTA backend. |
| wifi.manual_ip | Forces a fixed IP, gateway, and subnet instead of relying on DHCP — the fix for devices intermittently going "offline" after a reconnect. |
| wifi.ap | Defines a fallback access point the device broadcasts if it cannot reach the configured Wi-Fi network — useful for re-configuring a device that lost its connection. |
| one_wire | Enables the One-Wire protocol on GPIO2 of Node 1, allowing the DS18B20 temperature sensor to communicate over a single data wire. |
| sensor (dallas_temp) | Reads temperature from the DS18B20 sensor every 30 seconds and reports it to Home Assistant as a live sensor entity. |
| switch (gpio platform) | Defines one relay entity per GPIO pin. inverted: true matches the active-LOW behavior of the SRD-05VDC-SL-C relay modules used in this project. |
docker-compose.yml Fields
| Field | Purpose |
|---|---|
| image | Specifies the official container image pulled from GitHub Container Registry for each service. |
| restart: unless-stopped | Ensures both containers automatically restart if Docker's daemon restarts — this is what allows the auto-start automation in Section 05, Step 9 to work. |
| network_mode: host | Lets each container share the host's (WSL2's) network stack directly, which is necessary for reaching devices on the local Wi-Fi network — though this alone was not sufficient until WSL2's mirrored networking mode was also enabled. |
| volumes | Maps each container's /config folder to a folder on the actual filesystem, so configuration and device data survive even if the container itself is deleted and recreated. |
08 Testing and Calibration
After setup, verify each of the following to confirm the system is working correctly end-to-end.
Container-Level Network Test
Run the following from inside Ubuntu after both containers are up:
sudo docker exec -it homeassistant ping -c 4 10.0.0.51
sudo docker exec -it homeassistant ping -c 4 10.0.0.52
Both should report 0% packet loss. This is the single most reliable indicator that the whole network chain is correctly configured.
ping succeeding while this command fails confirms the WSL2 isolation issue from Section 05, Step 5 — not a problem with the ESP-01 itself.ESPHome Dashboard Logs Test
Open each device's logs in the ESPHome dashboard. A correctly connected node shows lines similar to:
[I][wifi:1575]: Connected
[C][wifi:1237]: IP Address: 10.0.0.51
[D][api.connection]: Home Assistant ... connected
manual_ip, the network's gateway/subnet likely changed (common on mobile hotspots) — re-check with ip route and update the YAML accordingly.Temperature Sensor Test
In Home Assistant, go to the dashboard and locate the Temperature entity from Node 1. It should display a live reading in °C rather than "Unknown". If it shows Unknown, check that the 4.7kΩ pull-up resistor is correctly wired between the DS18B20 data pin and 3.3V.
Home Assistant Relay Control Test
Under Settings > Devices & Services, both nodes should appear with their relay switch entities listed and toggleable. Toggling a switch in the UI should produce an audible relay click within roughly one second.
inverted value for that switch needs to be flipped to match the relay module's actual logic.Temperature Automation Test
To test the temperature protection automation:
- Manually turn on all three relays from the Home Assistant dashboard.
- Hold the DS18B20 sensor between your fingers for about one minute to warm it above 35°C.
- Watch the dashboard — all three relays should automatically turn off within one second of the temperature exceeding 35°C.
- Release the sensor and let it cool. Confirm the relays stay off even after the temperature drops below 35°C.
- Manually turn the relays back on from the dashboard to confirm user control is working correctly.
Reboot Persistence Test
Fully restart the Windows PC, log back in, wait roughly 30–40 seconds without opening any terminal, then load http://localhost:8123 directly. If the automation from Section 05, Step 9 is correctly configured, the dashboard loads with no manual intervention.
vmIdleTimeout=-1 is present in .wslconfig to prevent WSL2 from shutting down after the startup script finishes.09 System Demonstration
10 Conclusion
The completed system demonstrates that a reliable, self-hosted remote control and monitoring system can be built using two ESP-01 modules, ESPHome, and Home Assistant running on a Windows laptop with Docker Engine and WSL2, eliminating the need for dedicated server hardware.
A key finding of this project is that the primary challenges were related to software configuration rather than hardware. Proper networking setup, including static IP addresses and WSL2 mirrored networking, was essential to ensure stable communication between Home Assistant and the ESP-01 nodes.
The integration of the DS18B20 temperature sensor and Home Assistant automation added an important safety feature by automatically turning off all three relays whenever the temperature exceeds 35°C, while still allowing manual reactivation through the dashboard.
Overall, the project provides a reliable, low-cost, and expandable IoT solution that demonstrates the practical integration of ESPHome, Home Assistant, Docker, and WSL2 for remote monitoring and control.
Recommendations
To further improve the system, the following enhancements are recommended:
- Use a dedicated Wi-Fi router instead of a mobile hotspot to eliminate AP isolation issues and prevent subnet changes that require reconfiguration of static IPs.
- Expand the system by adding more ESP-01 nodes to control additional relays. The modular design makes it easy to increase the number of controllable devices without modifying the existing setup.
11 References
- Espressif Systems — ESP8266 Technical Reference Manual
- ESPHome — Official Documentation
- ESPHome — Dallas Temperature Component Documentation
- Home Assistant — Official Documentation (Container Installation)
- Home Assistant — Automations Documentation
- Microsoft — WSL2 Networking Documentation (Mirrored Mode)
- Docker — Official Engine Installation Documentation (get.docker.com)
- Docker — Compose File Reference
- FTDI — FT232R USB UART IC Datasheet
12 Project Authors
- Joshua T. Colendres
- McRaven B. Batapa
