Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/esphome-validate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Validate ESPHome boards
on:
pull_request:
push:
branches: [main]

jobs:
lint-and-compile:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install tools
run: |
python -m pip install --upgrade pip
pip install esphome yamllint

- name: Lint YAML
run: yamllint .

- name: Validate config files
run: esphome config boards/*/demo.yaml

- name: Compile demos
env:
PLATFORMIO_BUILD_CACHE_DIR: /tmp/esphome_cache_${{ github.run_id }}
run: esphome compile boards/*/demo.yaml
1 change: 1 addition & 0 deletions AGENTS.md
111 changes: 87 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
# ESPHomeCollection

This repository is where I share reusable ESPHome YAML definitions for various
boards and dev kits I acquire, to make it easier for others to use those boards.
Reusable, hardware-only ESPHome board definitions with simple demos. Keep hardware definition minimal and separate from application logic so users can compose clean projects.

## Core Principle
## Available Boards

My board definitions are clean, only defining the hardware. That allows you to
focus on the application logic. This separation of hardware and application
makes the code reusable and composable.
All board configurations are in the [`boards` directory](./boards/). Each board will be in a `boards/<board-slug>/` directory, with at least:

## Available Boards
* `board.yaml`: the hardware definition. No application logic, automation, api or wifi provisioning.
* `demo.yaml`: a simple firmware that illustrates and exercises the board components.

The board slug is lowercase, hyphenated (e.g., `esp32-s3-box-3`, `esp32-c3-devkitm-1`).

You can find all board configurations in the [`boards` directory](./boards/). Each board has a
`board.yaml` for the hardware definition and a `demo.yaml` for a sample application.

## Using a Board Definition in Your Project
## Usage

To use a board definition in your own project, include them as a package like this:

Expand All @@ -25,7 +23,10 @@ packages:

Replace `esp32-s3-box-3` with the directory name of the board you want to use.

See [ESPHome Packages] for how package imports work.
It's recommended to replace `@main` with a specific commit, in order to avoid breakages
from possibly backwards-imcompatible changes.
Copy link

Copilot AI Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a spelling error: 'imcompatible' should be 'incompatible'.

Suggested change
from possibly backwards-imcompatible changes.
from possibly backwards-incompatible changes.

Copilot uses AI. Check for mistakes.

See [ESPHome Packages] for details on how package imports work.

[ESPHome Packages]: https://esphome.io/components/packages.html

Expand All @@ -41,6 +42,7 @@ esphome run ./boards/${BOARD}/demo.yaml
If you don't want to explicitly clone the repository, create a local file (e.g. `demo.yaml`), where the entire content is the import of the demo:

```yaml
# demo.yaml
packages:
board: github://fortuna/ESPHomeCollection/boards/esp32-s3-box-3/demo.yaml@main
```
Expand All @@ -55,38 +57,99 @@ esphome run ./demo.yaml

## Development

You need to install the `esphome` and `yamllint` Python binaries.
Contributions of new boards are welcome.

On macOS, if you have Homebrew installed, you can use:
### Install the tooling

```sh
brew install esphome yamllint
pip install esphome yamllint
```

On other platforms, it may be easier to use `pipx run`, but you need `pipx` installed.
You may need to use `pip3` or `pipx` depending on your system.

To quickly validate a config, use `esphome config`. For example:
On macOS, if you have [Homebrew installed](https://brew.sh/), use:

```sh
esphome config boards/esp32-s3-box-3/demo.yaml
brew install esphome yamllint
```

You must run `esphome config` on the demo files, because the board definitions are incomplete ESPHome configs and will fail validation.
### Add a new board

1. **Create folder**: `boards/<board-slug>/`, where `<oard-slug>` is lowercase, hyphenated (e.g., `esp32-s3-box-3`, `esp32-c3-devkitm-1`).
Copy link

Copilot AI Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a typo: '' should be ''.

Suggested change
1. **Create folder**: `boards/<board-slug>/`, where `<oard-slug>` is lowercase, hyphenated (e.g., `esp32-s3-box-3`, `esp32-c3-devkitm-1`).
1. **Create folder**: `boards/<board-slug>/`, where `<board-slug>` is lowercase, hyphenated (e.g., `esp32-s3-box-3`, `esp32-c3-devkitm-1`).

Copilot uses AI. Check for mistakes.
1. **Author `board.yaml`** (hardware only):
* No `esphome:` entry.
* No `wifi:`, `api`, `ota`, `logger`, etc.
* `esp32:` block set for the exact devkit and `esp-idf` framework, for example:
```yaml
esp32:
board: esp32-c3-devkitm-1
framework:
type: esp-idf
```
* Define all the harware components (pins, buses, sensors, displays, audio, etc)
Copy link

Copilot AI Aug 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a spelling error: 'harware' should be 'hardware'.

Suggested change
* Define all the harware components (pins, buses, sensors, displays, audio, etc)
* Define all the hardware components (pins, buses, sensors, displays, audio, etc)

Copilot uses AI. Check for mistakes.
* **No app logic**, including logging and automations.

1. **Author `demo.yaml`** (minimal, friendly):
* Include the board and add the `esphome` and `logger` blocks:

```yaml
packages:
board: !include ./board.yaml

esphome:
name: board-demo
friendly_name: Board Demo

logger:
level: DEBUG
```
* Include minimal features to exercise hardware. Try to exercise all hardware components if possible. No `wifi`.

1. **Run checks**
* Run linter:
```sh
yamllint boards/<board>
```
The YAML style is defined in [.yamllint](./.yamllint).

* Build:
```sh
esphome compile boards/<board>/demo.yaml
```
This must use the `demo.yaml` because the board config is incomplete.

1. Flash it into an actual device to verify it works.
```sh
esphome run boards/<board>/demo.yaml
```

<!-- 1. **Docs**:
* Update **README** “Available Boards” with the new directory and a one-line description. -->

1. **Submit PR**:
* Title: `[board] <board-slug>: add board + demo`
* Ensure the tests pass.

Note: You can quickly validate all configs and lint them in one command:

To lint all files:
```sh
esphome config boards/*/demo.yaml && yamllint .
```

To build all the boards, it's recommended to set up a build cache:
```sh
yamllint .
export PLATFORMIO_BUILD_CACHE_DIR=/tmp/esphome_cache
esphome build boards/*/demo.yaml
```

You can validate all configs and lint them in one command:
### Clean up

To remove the generated files

```sh
esphome config boards/*/demo.yaml && yamllint .
rm -rf boards/*/{.esphome,.gitignore}
```

## TODO
- Add demos and test:
- M5Stack Atom Echo
- Add ESP32-C6 dev board
- Create nice index table
6 changes: 3 additions & 3 deletions boards/esp32-s3-box-3/demo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ media_player:
- wait_until:
speaker.is_playing: box_speaker
- logger.log: Speaker is playing
on_play:
on_play:
- logger.log: Media player playing
on_pause:
on_pause:
- logger.log: Media player paused
on_idle:
on_idle:
- logger.log: Media player is idle
- wait_until:
speaker.is_stopped: box_speaker
Expand Down
2 changes: 1 addition & 1 deletion boards/m5stack-atom-echo/demo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ rtttl:
- id: rtttl_player
speaker: echo_speaker
gain: 0.3
on_finished_playback:
on_finished_playback:
then:
- logger.log: Finished playing RTTTL tune.
4 changes: 0 additions & 4 deletions boards/waveshare-esp32-c3-mini/board.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ esp32:
board: esp32-c3-devkitm-1
framework:
type: esp-idf
# version: 5.2.1
# platform_version: 6.7.0
# sdkconfig_options:
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB: y

binary_sensor:
- id: boot_button
Expand Down