Skip to content

Your First Device

Scope: the whole first-device path — install ESPHome, write the greenhouse configuration, prove it valid, compile its twin for the host platform, run it — and an honest account of the one step this lab could not take. If you have a real board, your path forks from this one at exactly one signposted paragraph.

Install the tool

ESPHome is a Python package. A virtual environment keeps it (and the compiler toolchain it drives) out of your system's way:

$ python3 -m venv ~/esphome-venv
$ ~/esphome-venv/bin/pip install esphome
$ ~/esphome-venv/bin/esphome version
Version: 2026.10.0

Check: the version prints, as in chapter 1. Windows and macOS readers: the same pip install works; the differences arrive at flashing time (serial port names, USB drivers), not here. There is also a dashboard — a local web page for managing devices. In this version it has moved out of ESPHome itself into a separate tool, ESPHome Device Builder (the command says so, in terms, if you ask for the old one) — but everything the dashboard does, the command line does too, and the command line is what this guide can show you honestly. Nothing below needs it.

Write the configuration

One folder per device is the habit that survives contact with a second device:

greenhouse/
  greenhouse.yaml     the configuration
  secrets.yaml        its secrets (chapter 6)

The greenhouse configuration is printed in full in examples/greenhouse.yaml and anatomised in chapter 3; the specimen chapter (5) walks its working parts. Two pieces of it belong to you, not the example: anything behind a !secret reference, which you supply in your own secrets.yaml (examples/secrets.yaml.example is the shape), and the API encryption key, which must be 32 bytes, base64-encoded. Generate one and put it in the secrets file, not the configuration:

$ openssl rand -base64 32

Prove it before you build it

$ esphome config greenhouse.yaml
INFO Configuration is valid!

(Chapter 3 quotes the full form of this and of a failure.) No board is involved in this step, which is precisely its value: every mistake of name, pin, or reference is caught here, in seconds, by name.

Build the twin, run the logic

Before any firmware meets a chip, this guide asks a question most guides skip: does the logic do what the file says? ESPHome's host platform answers it. The twin configuration, examples/greenhouse-sim.yaml, is the same device re-aimed — host: instead of the board section, template (platform-faked) components instead of wired ones, and a lambda that raises the temperature 0.7 degrees every five seconds so the automation has something to meet.

It validates the same way (config, t02), and then it compiles — for real, the full code-generation and C++ build, about a minute on the build machine:

$ esphome compile greenhouse-sim.yaml
...
[133/133] LINK program
INFO Successfully compiled program to path '.../greenhouse-sim/program'

(Transcript t03, trimmed to its tail in chapter 9's discussion.) The result is an ordinary executable. Run it and it behaves like the device at boot — the lines below are its own output (transcript t04):

[I][app:073]: Running through setup()
[I][app:130]: setup() finished successfully!
[I][app:164]: ESPHome version 2026.10.0 compiled on 2026-10-22 02:39:52 +0000

followed by its configuration dump, which records — among much else — that its API server listens on port 6053 with Noise encryption on, and its update service on 8082 with a password configured. Chapter 8 connects a client to that server and watches the fan automation fire; chapter 7 sends it an update. The twin is not the device. But a configuration whose logic has survived the twin arrives at its first flash with the embarrassing mistakes already spent.

The build for real silicon, and the step beyond it

The ESP32 configuration was also compiled for real — not merely validated. The first such build is the large one: PlatformIO downloads the ESP-IDF framework (5.5.6 here) and the chip toolchain before a line of your code is compiled, and on the build machine that download, not the compile, was the wait. What came out the far end (transcript t08):

INFO Created: .../greenhouse/build/firmware.factory.bin
INFO Created: .../greenhouse/build/firmware.ota.bin
INFO Successfully compiled program.

Real artifacts with real sizes: firmware.ota.bin, the over-the-air image, is 860,944 bytes; firmware.factory.bin, the full first-flash image, 926,480. So the guide can certify the greenhouse file end to end as far as the compiler: every section, pin, and reference validated (t01), and the whole thing built into firmware a chip would accept.

With a board attached, one command walks the remaining step:

$ esphome run greenhouse.yaml

which validates, compiles as above, and writes the firmware over USB. From the second change onward the same command can offer the over-the-air route instead (chapter 7), and the cable becomes the rescue tool rather than the routine.

That flash is the lab's one documented-only step. No ESP32 was attached to the build bench; nothing here pretends a serial write it didn't watch. It is described from the project's documentation, and chapter 12 covers the ways a first flash commonly goes wrong and how each is recognised — which, for most beginners, makes the split a fair one: the afternoons are lost in the file, and the file is the part this guide could prove.