This repo contains code intended for easy re-use across ESPHome projects.
Everything under lib/ is an ESPHome package:
a config fragment you pull into your own device config rather than a
standalone config you flash on its own.
The examples below pin a release tag. Pinning means a change here can't break your next build without you asking for it:
packages:
wifi-diagnostics: github://romkey/esphome-lib/lib/wifi-diagnostics.yml@v0.2.0Use @main instead if you'd rather track the latest.
Every package declares its entity names, ids and entity categories as substitutions, with defaults matching what the package has always produced. Override any of them in your own config — substitutions in your config win over the ones inside a package:
substitutions:
wifi_signal_db_name: "Signal"
wifi_entity_category: "" # put these back on the main device card
packages:
wifi-diagnostics: github://romkey/esphome-lib/lib/wifi-diagnostics.yml@v0.2.0Each package lists its substitutions in a comment at the top of the file.
packages:
wifi-diagnostics: github://romkey/esphome-lib/lib/wifi-diagnostics.yml@v0.2.0packages:
ethernet-diagnostics: github://romkey/esphome-lib/lib/ethernet-diagnostics.yml@v0.2.0packages:
esp32-diagnostics: github://romkey/esphome-lib/lib/esp32.yml@v0.2.0packages:
restart: github://romkey/esphome-lib/lib/restart.yml@v0.2.0packages:
i2c-scan: github://romkey/esphome-lib/lib/i2c-scan.yml@v0.2.0This package scans the I2C bus on boot and exposes a "Scan I2C Bus" button to
rescan on demand. It defaults to a bus with the id i2c0:
i2c:
- id: i2c0
sda: GPIO21
scl: GPIO22If your bus is called something else, point the scanner at it:
substitutions:
i2c_scan_bus_id: bus_aTo scan a second bus, include the package twice and give the second copy its
own i2c_scan_bus_id, i2c_scan_results_id, i2c_scan_script_id and
i2c_scan_button_id so the ids stay unique.
packages:
wt32-eth01: github://romkey/esphome-lib/lib/wt32-eth01.yml@v0.2.0Provides the esp32 and ethernet blocks for the WT32-ETH01. Pair it with the
Ethernet diagnostics package above.
examples/ holds complete, buildable configs that use these packages. They are
what CI compiles, so they double as a regression test for the library.
| Example | What it covers |
|---|---|
examples/esp32-wifi.yaml |
ESP32 on WiFi with the ESP32, WiFi diagnostics, restart and I2C scan packages |
examples/wt32-eth01.yaml |
WT32-ETH01 with the board, Ethernet diagnostics, ESP32 and restart packages, and overridden substitutions |
The examples pull the packages from the local checkout with
!include ../lib/... so they build straight from a clone. In your own project,
use the github:// form shown above instead.
examples/secrets.yaml holds dummy credentials so the examples validate and
compile without any real secrets. Replace them before flashing anything.
You do not need ESPHome installed locally — docker-compose.yml
runs it in a container. The repo is mounted at /esphome-lib so the examples'
relative includes resolve, and ESPHome's data directory lives in a named volume
so the PlatformIO packages and ESP-IDF toolchain are downloaded once rather
than on every build.
Validate every example:
docker compose run --rm validateCompile every example (this is what CI does):
docker compose run --rm buildRun any other ESPHome subcommand:
docker compose run --rm esphome compile examples/wt32-eth01.yamlOpen the ESPHome web dashboard on http://localhost:6052:
docker compose up dashboardPin a specific ESPHome release instead of stable:
ESPHOME_VERSION=2026.7.4 docker compose run --rm buildCI runs on every push and pull request, and weekly on a schedule so that a new ESPHome release breaking one of these packages shows up on its own:
- Lint —
yamllintover the whole repo, configured in.yamllint.yml. - CI — validates and compiles each example against ESPHome
stable, and checks that the Compose setup works.
To run the linter the same way CI does:
yamllint -c .yamllint.yml --strict .