Skip to content

Build from source

witekin edited this page Sep 14, 2026 · 5 revisions

Build the firmware yourself — to change something, add a board, or see how it works.

ESPHome Python 3.11+ GPL-3.0


🛠️ A maker page — building from source. Just want a working device? You don't need this → the browser installer flashes a ready-made build.

📖 On this page

WinterDash is an ESPHome project. You compile a master YAML for your board; it pulls in a set of shared packages and bakes the web pages into the firmware.

What you need

  • A computer with Python 3.11+ and git.
  • The source: git clone https://github.com/witekin/winterdash.git
  • A data USB cable (not charge-only) and, on Windows, the board's USB driver (CP210x or CH340) — same as the manual flashing step.

1. Set up the pinned toolchain

WinterDash pins an exact ESPHome version (in requirements.txt) so a build is reproducible. Use a virtual environment so a global pip can't drift it:

python -m venv .venv
# Windows:
.venv/Scripts/python -m pip install -r requirements.txt
# macOS / Linux:
.venv/bin/python -m pip install -r requirements.txt

From here, always call ESPHome through that interpreter (.venv/Scripts/python -m esphome … on Windows, .venv/bin/python -m esphome … elsewhere) — that's the enforcement that keeps the version pinned.

2. Your secrets file

Copy the template and set your own OTA password (WiFi is entered on the device later, so it stays blank):

cp esphome/secrets.yaml.example esphome/secrets.yaml

Edit esphome/secrets.yaml and set ota_password to a value of your own. secrets.yaml is git-ignored — it never leaves your machine.

The official prebuilt releases ship a public, documented OTA password (winterdash-ota) so anyone can update them over the air without compiling. Building from source is how you bake your own private one instead — worth doing if you don't want everyone on your network able to reflash the device.

3. Pick your board

Each board has its own master YAML:

Board Master
LilyGO TTGO T-Display, 16 MB esphome/esp32-tdisplay-16mb.yaml
LilyGO TTGO T-Display, 4 MB esphome/esp32-tdisplay-4mb.yaml
Screenless ESP32 (WROOM-32) esphome/esp32-wroom32.yaml
CYD (ESP32-2432S028R) esphome/esp32-cyd.yaml

A master is thin — it composes shared packages under esphome/packages/ (core, a board_*, and for the display boards a display_* + input_*). Some boards add an led_* for a status light — the screenless board a mono LED, the CYD an RGB one (its input is touch). That split is what lets one codebase serve several boards.

4. Build and flash (first time, over USB)

Plug the board in and run, for example:

.venv/Scripts/python -m esphome run esphome/esp32-tdisplay-16mb.yaml

ESPHome compiles, asks which serial port to use, and flashes over the cable. When it's done, the board boots into WiFi onboarding — continue with First-time setup.

5. Updates later (no cable)

Once the board is on your WiFi, flash over the air by pointing at its address (shown on the device's Network screen):

.venv/Scripts/python -m esphome run esphome/esp32-tdisplay-16mb.yaml --device winterdash-<mac>.local

The device asks for the ota_password you set in step 2.

Editing the web pages

The dashboard and setup pages live in web/ (dashboard.html, image-tool.html, onboarding.html) and are baked into the firmware as compressed headers. After editing one, regenerate the header before you build:

.venv/Scripts/python esphome/tools/gen_dashboard_h.py     # dashboard.html + image-tool.html
.venv/Scripts/python esphome/tools/gen_captive_index.py   # onboarding.html

The generators under esphome/tools/ (and the board-asset baker gen_board_assets.py) all ship with the source, so every baked blob can be rebuilt from its plain-text source — the build is fully reproducible.

Contributing changes

Found a bug, or built support for another board or charger? See CONTRIBUTING.

Clone this wiki locally