From 07394c81b74e3afcefc77c1399dfcce9fb22a243 Mon Sep 17 00:00:00 2001 From: Chris Nussbaum Date: Wed, 30 Sep 2026 10:36:13 -0500 Subject: [PATCH 1/2] Layer the device base packages into common/chip/network `device_base.yaml` mixed three unrelated concerns into one file: the chip-agnostic core (api, ota, logger, diagnostics, time), and wifi -- both the `wifi:` block itself and the wifi-only diagnostics (signal sensor, wifi-info text sensor). Because wifi was baked into the core, there was no way to build an ethernet device without either duplicating the whole core or including a wifi stack the board doesn't have. The static-IP/DHCP split made it worse: `wifi/wifi.yaml` and `wifi/wifi_dhcp.yaml` were near-identical copies of the same block, and every device carried `ip_address`/`ip_subnet`/`ip_gateway` substitutions whether or not it used them. Devices now include exactly one combo package, which is nothing but a `packages:` block pulling in one common, one chip and one network layer. Adding an ethernet board is a two-line file rather than a fork of the core. Changes: - Split `device_base.yaml` into `device_common.yaml` (chip- and network-agnostic core), `device_esp32.yaml` / `device_esp8266.yaml` (platform block only), and `device_wifi.yaml` / `device_eth.yaml` (network stack plus its own diagnostics). - Add the combo packages devices actually include: `device_esp32_wifi.yaml`, `device_esp8266_wifi.yaml`, `device_esp32_eth.yaml`. There is no esp8266+eth combo -- no such device exists here. - Add `text_sensor/ethernet_info.yaml` for the eth layer's IP-address diagnostic, mirroring `text_sensor/wifi_info.yaml`. The `ethernet:` block itself stays in the device yaml, since PHY/pin wiring is board-specific. - Drop `wifi/wifi_dhcp.yaml` and collapse `wifi/wifi.yaml` to the DHCP form. Static IPs are handled by DHCP reservations on the router, so the `manual_ip:` variant and its substitutions are gone. `wifi.yaml` now sources `wifi_ssid`/`wifi_password` itself instead of relying on `device_common.yaml` to define them for it. - Rename `econet_base.yaml` to `econet.yaml` and repoint it at `device_esp32_wifi.yaml`; rename every device's `device_base:` package key to `device:`, now that it names a combo rather than a base. - Drop the OTA and AP passwords (`password: ${pwd}` in `ota/ota.yaml` and `wifi/wifi.yaml`) along with `ap_timeout`. **This changes behaviour on upgrade:** the first OTA push to each device must still use the old password (the running firmware enforces it), but every push after that is unauthenticated, as is the fallback AP. The per-device `pwd:` substitutions are left in the device yamls for now but are no longer referenced by anything. - Widen the CI build-cache key from `device_base*.yaml` to `device_*.yaml` so it still hashes the renamed files. - bt-proxy-basement: drop `connection_slots` from 4 to 3. - Add `.claude/settings.json` denying reads of `devices/secrets.yaml`. - Update CLAUDE.md for the new package layout, and document that Bash filesystem commands must be scoped -- `devices/.esphome/` holds ~38k toolchain files on an SMB share, and Bash doesn't honour .gitignore the way Grep/Glob do. Verified with `pre-commit run --all-files` clean and `esphome config` on bt-proxy-basement (esp32+wifi), master-bed (esp8266+wifi), network-equipment (topgreener package) and hvac (econet package). Co-authored-by: Claude Opus 5 --- .claude/settings.json | 7 +++++++ .github/workflows/ci.yml | 2 +- CLAUDE.md | 13 ++++++++----- devices/basement-bath-shower-light-heat.yaml | 2 +- devices/basement-fridge.yaml | 2 +- devices/basement-tv.yaml | 2 +- devices/bt-proxy-basement.yaml | 4 ++-- devices/coffee-maker.yaml | 2 +- devices/emporia-vue2.yaml | 2 +- devices/family-room-tv.yaml | 2 +- devices/fire-pit-fountain.yaml | 2 +- devices/garage-fridge.yaml | 2 +- devices/garage-lights.yaml | 2 +- devices/hvac.yaml | 2 +- devices/kitchen-fridge.yaml | 2 +- devices/main-garage-door.yaml | 2 +- devices/master-bed.yaml | 2 +- devices/network-equipment.yaml | 2 +- .../{device_base.yaml => device_common.yaml} | 5 ----- .../{device_base_esp32.yaml => device_esp32.yaml} | 3 --- devices/packages/device_esp32_eth.yaml | 4 ++++ devices/packages/device_esp32_wifi.yaml | 4 ++++ ...device_base_esp8266.yaml => device_esp8266.yaml} | 3 --- devices/packages/device_esp8266_wifi.yaml | 4 ++++ devices/packages/device_eth.yaml | 2 ++ devices/packages/device_wifi.yaml | 4 ++++ devices/packages/{econet_base.yaml => econet.yaml} | 2 +- devices/packages/ota/ota.yaml | 1 - devices/packages/shelly_1l.yaml | 2 +- devices/packages/text_sensor/ethernet_info.yaml | 5 +++++ devices/packages/topgreener_smart_plug.yaml | 2 +- devices/packages/wifi/wifi.yaml | 10 ++++------ devices/packages/wifi/wifi_dhcp.yaml | 10 ---------- devices/pool-lights.yaml | 2 +- devices/pool.yaml | 2 +- devices/second-garage-door.yaml | 2 +- devices/sump-pump.yaml | 2 +- devices/washing-machine.yaml | 2 +- devices/water-heater.yaml | 2 +- 39 files changed, 68 insertions(+), 59 deletions(-) create mode 100644 .claude/settings.json rename devices/packages/{device_base.yaml => device_common.yaml} (75%) rename devices/packages/{device_base_esp32.yaml => device_esp32.yaml} (75%) create mode 100644 devices/packages/device_esp32_eth.yaml create mode 100644 devices/packages/device_esp32_wifi.yaml rename devices/packages/{device_base_esp8266.yaml => device_esp8266.yaml} (66%) create mode 100644 devices/packages/device_esp8266_wifi.yaml create mode 100644 devices/packages/device_eth.yaml create mode 100644 devices/packages/device_wifi.yaml rename devices/packages/{econet_base.yaml => econet.yaml} (72%) create mode 100644 devices/packages/text_sensor/ethernet_info.yaml delete mode 100644 devices/packages/wifi/wifi_dhcp.yaml diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..ea35784 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "deny": [ + "Read(./devices/secrets.yaml)" + ] + } +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3bb610c..886b03f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,7 +102,7 @@ jobs: path: | ~/.platformio ~/.esphome-idf - key: build-${{ matrix.platform }}-${{ hashFiles('devices/packages/device_base*.yaml') }} + key: build-${{ matrix.platform }}-${{ hashFiles('devices/packages/device_*.yaml') }} restore-keys: build-${{ matrix.platform }}- - name: Install ESPHome run: pip install esphome diff --git a/CLAUDE.md b/CLAUDE.md index c5bac7e..039297e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -79,7 +79,7 @@ Installed via `pipx install esphome`, which creates its own isolated virtualenv ``` On a fresh machine ESPHome downloads roughly 6 GB into that prefix on the first compile. To migrate an existing install instead of re-downloading, move `%LOCALAPPDATA%\esphome\Cache\idf` to the new prefix, then delete `tools\`, `penvs\` and `idf-env.json` inside it — those re-extract from the `dist\` archive cache that moves along with them. -**2. Build to a local drive, not the UNC share.** This repo lives on `\\nas\docker\esphome\config`, and `devices/packages/device_base.yaml` sets `build_path: ./build/${device_id}`, which resolves (relative to the device yaml) to `devices/build/${device_id}` on that share. `cmd.exe` cannot use a UNC path as a working directory, so ninja's *link* step runs from `C:\Windows` and fails with `ld.exe: cannot open output file ...: Permission denied`. The compile steps succeed first, which makes this read as a linker bug rather than a path problem. Override `build_path` to a local path (e.g. `C:/eh/bld/`) when compiling from Windows. Source files can stay on the share — gcc handles UNC paths fine; only the working directory is the problem. +**2. Build to a local drive, not the UNC share.** This repo lives on `\\nas\docker\esphome\config`, and `devices/packages/device_common.yaml` sets `build_path: ./build/${device_id}`, which resolves (relative to the device yaml) to `devices/build/${device_id}` on that share. `cmd.exe` cannot use a UNC path as a working directory, so ninja's *link* step runs from `C:\Windows` and fails with `ld.exe: cannot open output file ...: Permission denied`. The compile steps succeed first, which makes this read as a linker bug rather than a path problem. Override `build_path` to a local path (e.g. `C:/eh/bld/`) when compiling from Windows. Source files can stay on the share — gcc handles UNC paths fine; only the working directory is the problem. **3. Don't run any other `esphome` command while a compile is in progress.** Even `esphome config` rewrites state under `devices/.esphome/`, and because that directory is shared with the build, cmake sees a changed input and re-runs configure mid-build. The initial configure succeeds off the resolved dependency lock, but a *re-run* re-resolves component manifests and dies on `devices/.esphome/pio_components/idf/*/esphome/noise-c/idf_component.yml`, which contains `override_path: /config/.esphome/...` — a container path, written by the Docker ESPHome where `devices/` is mounted at `/config`. Windows resolves it against the UNC root as `\\nas\docker\config\...`, which doesn't exist, and the build dies with `The "override_path" field ... does not point to a directory`. That cache is gitignored and regenerable, so leave it alone rather than "fixing" it — the container needs those paths. Just validate before you build, then stay off the config directory until it finishes. @@ -98,10 +98,12 @@ The `no-commit-to-branch` pre-commit hook blocks commits directly on `master`. A `devices/` is the directory mounted as `/config` in the ESPHome Device Builder container — the dashboard only scans the top level of its config dir, which is why the device yamls, their `packages/`, and `secrets.yaml` all live together there while everything repo-level (`components/`, `docs/`, `scripts/`, lint config) stays at the repo root. `components/` is bind-mounted alongside it so that `path: ../components` resolves identically inside the container and from a host `esphome` CLI run. **`devices/packages/`** holds shared YAML fragments included by devices via the `packages:` key, layered like this: -- `device_base.yaml` — the common core every device gets: wifi, api, ota, logger, status/uptime/wifi sensors, restart button, version/wifi-info text sensors, time. -- `device_base_esp32.yaml` / `device_base_esp8266.yaml` — platform block (`esp32:`/`esp8266:`) plus an include of `device_base.yaml`. Devices include one of these, not `device_base.yaml` directly. -- `econet_base.yaml` — extends the esp32 base for Econet-driven HVAC boards, internalizing a couple of entities via `!extend`. -- `wifi/wifi_dhcp.yaml` vs `wifi/wifi.yaml` — DHCP vs static-IP wifi variants. +- Devices include exactly one *combo* package — `device_esp32_wifi.yaml`, `device_esp8266_wifi.yaml` or `device_esp32_eth.yaml` — never the layers below it directly. Each combo is nothing but a `packages:` block pulling in one common, one chip and one network layer. +- `device_common.yaml` — the core every device gets regardless of chip or network: `esphome:`/`preferences:` boilerplate plus api, ota, logger, status/uptime sensors, restart button, version text sensor, time. +- `device_esp32.yaml` / `device_esp8266.yaml` — just the platform block (`esp32:`/`esp8266:`) and its substitutions. +- `device_wifi.yaml` / `device_eth.yaml` — the network layer and its diagnostics: wifi pulls in `wifi/wifi.yaml`, the wifi-signal sensor and the wifi-info text sensor; eth pulls in the ethernet-info text sensor (the `ethernet:` block itself is board-specific and stays in the device yaml). +- There is no `device_esp8266_eth.yaml` — no such device exists here. +- `econet.yaml` — extends `device_esp32_wifi.yaml` for Econet-driven HVAC boards, internalizing a couple of entities via `!extend`. - `devices/secrets.yaml` (untracked, gitignored) holds actual secret values; every device/package references secrets with `!secret key_name`. `devices/packages/secrets.yaml` and the various per-device `secrets.yaml` files just include that one. The `!extend` tag is used throughout to modify entities defined by an included package/component (e.g. marking a base sensor `internal: true`, or attaching an `on_value`/`on_time` trigger to `wifi_rssi`/`time_source` in `pool.yaml`) instead of redefining them. @@ -125,3 +127,4 @@ Components are consumed either from disk (`external_components: - source: {type: - YAML: 2-space indent, double-quoted strings, LF line endings (`.gitattributes` forces LF for `*.yaml`/`*.yml` even on this Windows checkout). - Python (`components/**/*.py`): standard ESPHome component style; flake8 ignores docstring rules (`D1xx`) since ESPHome components aren't expected to have docstrings, and line length is capped at 120. +- Bash filesystem commands must be scoped. `devices/.esphome/` holds ~38k ESP-IDF toolchain/build-cache files, and this checkout lives on an SMB share. Grep/Glob honor `.gitignore` and skip it, but Bash does not — a bare `find`/`du`/`ls -R` from the repo root walks all of it and times out. Target a specific subdirectory, or use `-maxdepth` / `-prune`, instead of recursing from the root. diff --git a/devices/basement-bath-shower-light-heat.yaml b/devices/basement-bath-shower-light-heat.yaml index b421d00..609690e 100644 --- a/devices/basement-bath-shower-light-heat.yaml +++ b/devices/basement-bath-shower-light-heat.yaml @@ -6,7 +6,7 @@ substitutions: pwd: !secret basement_bathroom_shower_light_heat_pwd packages: - device_base: !include ./packages/device_base_esp8266.yaml + device: !include ./packages/device_esp8266_wifi.yaml binary_sensor: - platform: gpio diff --git a/devices/basement-fridge.yaml b/devices/basement-fridge.yaml index 72b5a3f..5da17f3 100644 --- a/devices/basement-fridge.yaml +++ b/devices/basement-fridge.yaml @@ -5,4 +5,4 @@ substitutions: pwd: !secret basement_fridge_pwd packages: - device_base: !include ./packages/topgreener_smart_plug.yaml + device: !include ./packages/topgreener_smart_plug.yaml diff --git a/devices/basement-tv.yaml b/devices/basement-tv.yaml index 7b032a2..2a2a873 100644 --- a/devices/basement-tv.yaml +++ b/devices/basement-tv.yaml @@ -5,4 +5,4 @@ substitutions: pwd: !secret basement_tv_pwd packages: - device_base: !include ./packages/topgreener_smart_plug.yaml + device: !include ./packages/topgreener_smart_plug.yaml diff --git a/devices/bt-proxy-basement.yaml b/devices/bt-proxy-basement.yaml index 1b96696..f4e0e16 100644 --- a/devices/bt-proxy-basement.yaml +++ b/devices/bt-proxy-basement.yaml @@ -5,9 +5,9 @@ substitutions: pwd: !secret bt_proxy_basement_pwd packages: - device_base: !include ./packages/device_base_esp32.yaml + device: !include ./packages/device_esp32_wifi.yaml bluetooth_proxy: active: true cache_services: true - connection_slots: 4 + connection_slots: 3 diff --git a/devices/coffee-maker.yaml b/devices/coffee-maker.yaml index b11f855..060dd6f 100644 --- a/devices/coffee-maker.yaml +++ b/devices/coffee-maker.yaml @@ -6,7 +6,7 @@ substitutions: pwd: !secret coffee_maker_pwd packages: - device_base: !include ./packages/device_base_esp8266.yaml + device: !include ./packages/device_esp8266_wifi.yaml binary_sensor: - platform: gpio diff --git a/devices/emporia-vue2.yaml b/devices/emporia-vue2.yaml index db8b656..98ccfeb 100644 --- a/devices/emporia-vue2.yaml +++ b/devices/emporia-vue2.yaml @@ -6,7 +6,7 @@ substitutions: pwd: !secret emporia_vue2_pwd packages: - device_base: !include ./packages/device_base_esp32.yaml + device: !include ./packages/device_esp32_wifi.yaml api: services: diff --git a/devices/family-room-tv.yaml b/devices/family-room-tv.yaml index a02e11e..889505f 100644 --- a/devices/family-room-tv.yaml +++ b/devices/family-room-tv.yaml @@ -5,4 +5,4 @@ substitutions: pwd: !secret family_room_tv_pwd packages: - device_base: !include ./packages/topgreener_smart_plug.yaml + device: !include ./packages/topgreener_smart_plug.yaml diff --git a/devices/fire-pit-fountain.yaml b/devices/fire-pit-fountain.yaml index a9567a9..41cafdb 100644 --- a/devices/fire-pit-fountain.yaml +++ b/devices/fire-pit-fountain.yaml @@ -6,7 +6,7 @@ substitutions: pwd: !secret fire_pit_fountain_pwd packages: - device_base: !include ./packages/device_base_esp8266.yaml + device: !include ./packages/device_esp8266_wifi.yaml binary_sensor: - platform: gpio diff --git a/devices/garage-fridge.yaml b/devices/garage-fridge.yaml index 2dec07b..6bc0149 100644 --- a/devices/garage-fridge.yaml +++ b/devices/garage-fridge.yaml @@ -6,7 +6,7 @@ substitutions: log_baud_rate: '0' packages: - device_base: !include ./packages/device_base_esp32.yaml + device: !include ./packages/device_esp32_wifi.yaml esp32: cpu_frequency: 160MHZ diff --git a/devices/garage-lights.yaml b/devices/garage-lights.yaml index c08baf3..b4465a3 100644 --- a/devices/garage-lights.yaml +++ b/devices/garage-lights.yaml @@ -6,4 +6,4 @@ substitutions: light_wattage: '378' packages: - device_base: !include ./packages/shelly_1l.yaml + device: !include ./packages/shelly_1l.yaml diff --git a/devices/hvac.yaml b/devices/hvac.yaml index 3913e78..b2a6124 100644 --- a/devices/hvac.yaml +++ b/devices/hvac.yaml @@ -24,7 +24,7 @@ packages: hvac-zone-yaml/econet_hvac_zone2.yaml, hvac-zone-yaml/econet_hvac_zone3.yaml ] - device_base: !include ./packages/econet_base.yaml + device: !include ./packages/econet.yaml climate: - platform: econet_zone_control diff --git a/devices/kitchen-fridge.yaml b/devices/kitchen-fridge.yaml index 35b7099..ffc932b 100644 --- a/devices/kitchen-fridge.yaml +++ b/devices/kitchen-fridge.yaml @@ -5,4 +5,4 @@ substitutions: pwd: !secret kitchen_fridge_pwd packages: - device_base: !include ./packages/topgreener_smart_plug.yaml + device: !include ./packages/topgreener_smart_plug.yaml diff --git a/devices/main-garage-door.yaml b/devices/main-garage-door.yaml index 880531d..95d9c55 100644 --- a/devices/main-garage-door.yaml +++ b/devices/main-garage-door.yaml @@ -8,7 +8,7 @@ substitutions: packages: ratgdo: github://ratgdo/esphome-ratgdo/v25iboard.yaml@main - device_base: !include ./packages/device_base_esp8266.yaml + device: !include ./packages/device_esp8266_wifi.yaml button: - id: !remove ${id_prefix}_restart diff --git a/devices/master-bed.yaml b/devices/master-bed.yaml index 51209d3..b86519a 100644 --- a/devices/master-bed.yaml +++ b/devices/master-bed.yaml @@ -6,7 +6,7 @@ substitutions: pwd: !secret master_bed_pwd packages: - device_base: !include ./packages/device_base_esp8266.yaml + device: !include ./packages/device_esp8266_wifi.yaml external_components: - source: diff --git a/devices/network-equipment.yaml b/devices/network-equipment.yaml index 1033165..0888763 100644 --- a/devices/network-equipment.yaml +++ b/devices/network-equipment.yaml @@ -5,4 +5,4 @@ substitutions: pwd: !secret network_equipment_pwd packages: - device_base: !include ./packages/topgreener_smart_plug.yaml + device: !include ./packages/topgreener_smart_plug.yaml diff --git a/devices/packages/device_base.yaml b/devices/packages/device_common.yaml similarity index 75% rename from devices/packages/device_base.yaml rename to devices/packages/device_common.yaml index 4f629f4..8c785fe 100644 --- a/devices/packages/device_base.yaml +++ b/devices/packages/device_common.yaml @@ -1,8 +1,6 @@ substitutions: log_level: none log_baud_rate: '115200' - wifi_ssid: !secret wifi_ssid - wifi_password: !secret wifi_password flash_write_interval: 10min esphome: @@ -15,14 +13,11 @@ preferences: flash_write_interval: ${flash_write_interval} packages: - wifi: !include wifi/wifi_dhcp.yaml api: !include api/api.yaml ota: !include ota/ota.yaml logger: !include logger/logger.yaml status_sensor: !include binary_sensor/status.yaml uptime_sensor: !include sensor/uptime.yaml - wifi_sensor: !include sensor/wifi.yaml restart_button: !include button/restart.yaml version_sensor: !include text_sensor/version.yaml - wifi_info_sensor: !include text_sensor/wifi_info.yaml time: !include time/time.yaml diff --git a/devices/packages/device_base_esp32.yaml b/devices/packages/device_esp32.yaml similarity index 75% rename from devices/packages/device_base_esp32.yaml rename to devices/packages/device_esp32.yaml index 71d3833..2ec4e51 100644 --- a/devices/packages/device_base_esp32.yaml +++ b/devices/packages/device_esp32.yaml @@ -6,6 +6,3 @@ esp32: variant: ${esp32_variant} framework: type: ${framework_type} - -packages: - base: !include device_base.yaml diff --git a/devices/packages/device_esp32_eth.yaml b/devices/packages/device_esp32_eth.yaml new file mode 100644 index 0000000..bce6524 --- /dev/null +++ b/devices/packages/device_esp32_eth.yaml @@ -0,0 +1,4 @@ +packages: + common: !include device_common.yaml + esp32: !include device_esp32.yaml + eth: !include device_eth.yaml diff --git a/devices/packages/device_esp32_wifi.yaml b/devices/packages/device_esp32_wifi.yaml new file mode 100644 index 0000000..5d287e7 --- /dev/null +++ b/devices/packages/device_esp32_wifi.yaml @@ -0,0 +1,4 @@ +packages: + common: !include device_common.yaml + esp32: !include device_esp32.yaml + wifi: !include device_wifi.yaml diff --git a/devices/packages/device_base_esp8266.yaml b/devices/packages/device_esp8266.yaml similarity index 66% rename from devices/packages/device_base_esp8266.yaml rename to devices/packages/device_esp8266.yaml index de07042..dcde1db 100644 --- a/devices/packages/device_base_esp8266.yaml +++ b/devices/packages/device_esp8266.yaml @@ -4,6 +4,3 @@ substitutions: esp8266: board: ${board} restore_from_flash: true - -packages: - base: !include device_base.yaml diff --git a/devices/packages/device_esp8266_wifi.yaml b/devices/packages/device_esp8266_wifi.yaml new file mode 100644 index 0000000..302aab1 --- /dev/null +++ b/devices/packages/device_esp8266_wifi.yaml @@ -0,0 +1,4 @@ +packages: + common: !include device_common.yaml + esp8266: !include device_esp8266.yaml + wifi: !include device_wifi.yaml diff --git a/devices/packages/device_eth.yaml b/devices/packages/device_eth.yaml new file mode 100644 index 0000000..ad132ef --- /dev/null +++ b/devices/packages/device_eth.yaml @@ -0,0 +1,2 @@ +packages: + eth_info_sensor: !include text_sensor/ethernet_info.yaml diff --git a/devices/packages/device_wifi.yaml b/devices/packages/device_wifi.yaml new file mode 100644 index 0000000..4067715 --- /dev/null +++ b/devices/packages/device_wifi.yaml @@ -0,0 +1,4 @@ +packages: + wifi: !include wifi/wifi.yaml + wifi_sensor: !include sensor/wifi.yaml + wifi_info_sensor: !include text_sensor/wifi_info.yaml diff --git a/devices/packages/econet_base.yaml b/devices/packages/econet.yaml similarity index 72% rename from devices/packages/econet_base.yaml rename to devices/packages/econet.yaml index 3c104c4..96a6536 100644 --- a/devices/packages/econet_base.yaml +++ b/devices/packages/econet.yaml @@ -1,5 +1,5 @@ packages: - device_base: !include ./device_base_esp32.yaml + device: !include ./device_esp32_wifi.yaml button: - id: !extend restart_esp diff --git a/devices/packages/ota/ota.yaml b/devices/packages/ota/ota.yaml index 2bd82b6..97e3dbc 100644 --- a/devices/packages/ota/ota.yaml +++ b/devices/packages/ota/ota.yaml @@ -1,4 +1,3 @@ ota: - platform: esphome id: esphome_ota - password: ${pwd} diff --git a/devices/packages/shelly_1l.yaml b/devices/packages/shelly_1l.yaml index a03dd20..4ddc1f0 100644 --- a/devices/packages/shelly_1l.yaml +++ b/devices/packages/shelly_1l.yaml @@ -3,7 +3,7 @@ substitutions: light_wattage: '0' packages: - base: !include device_base_esp8266.yaml + device: !include device_esp8266_wifi.yaml binary_sensor: - platform: gpio diff --git a/devices/packages/text_sensor/ethernet_info.yaml b/devices/packages/text_sensor/ethernet_info.yaml new file mode 100644 index 0000000..3e26c30 --- /dev/null +++ b/devices/packages/text_sensor/ethernet_info.yaml @@ -0,0 +1,5 @@ +text_sensor: + - platform: ethernet_info + ip_address: + name: IP Address + icon: mdi:ip-network diff --git a/devices/packages/topgreener_smart_plug.yaml b/devices/packages/topgreener_smart_plug.yaml index 3c59db5..e0f4b5d 100644 --- a/devices/packages/topgreener_smart_plug.yaml +++ b/devices/packages/topgreener_smart_plug.yaml @@ -5,7 +5,7 @@ substitutions: log_baud_rate: '0' packages: - base: !include device_base_esp8266.yaml + device: !include device_esp8266_wifi.yaml binary_sensor: - platform: gpio diff --git a/devices/packages/wifi/wifi.yaml b/devices/packages/wifi/wifi.yaml index 65efe95..bb7036a 100644 --- a/devices/packages/wifi/wifi.yaml +++ b/devices/packages/wifi/wifi.yaml @@ -1,16 +1,14 @@ +substitutions: + wifi_ssid: !secret wifi_ssid + wifi_password: !secret wifi_password + wifi: ssid: ${wifi_ssid} password: ${wifi_password} fast_connect: true power_save_mode: none min_auth_mode: WPA2 - manual_ip: - static_ip: ${ip_address} - subnet: ${ip_subnet} - gateway: ${ip_gateway} ap: ssid: ${device_id} - password: ${pwd} - ap_timeout: 5min captive_portal: diff --git a/devices/packages/wifi/wifi_dhcp.yaml b/devices/packages/wifi/wifi_dhcp.yaml deleted file mode 100644 index 010cc7e..0000000 --- a/devices/packages/wifi/wifi_dhcp.yaml +++ /dev/null @@ -1,10 +0,0 @@ -wifi: - ssid: ${wifi_ssid} - password: ${wifi_password} - fast_connect: true - power_save_mode: none - min_auth_mode: WPA2 - ap: - ssid: ${device_id} - -captive_portal: diff --git a/devices/pool-lights.yaml b/devices/pool-lights.yaml index 194fd03..bf38833 100644 --- a/devices/pool-lights.yaml +++ b/devices/pool-lights.yaml @@ -6,7 +6,7 @@ substitutions: pwd: !secret pool_lights_pwd packages: - device_base: !include ./packages/device_base_esp8266.yaml + device: !include ./packages/device_esp8266_wifi.yaml external_components: - source: diff --git a/devices/pool.yaml b/devices/pool.yaml index 684f962..d61e6ca 100644 --- a/devices/pool.yaml +++ b/devices/pool.yaml @@ -9,7 +9,7 @@ substitutions: log_level: DEBUG packages: - device_base: !include ./packages/device_base_esp32.yaml + device: !include ./packages/device_esp32_wifi.yaml external_components: - source: diff --git a/devices/second-garage-door.yaml b/devices/second-garage-door.yaml index ca8400d..c74054b 100644 --- a/devices/second-garage-door.yaml +++ b/devices/second-garage-door.yaml @@ -19,7 +19,7 @@ packages: ref: main files: [base_drycontact.yaml] refresh: 1s - device_base: !include ./packages/device_base_esp8266.yaml + device: !include ./packages/device_esp8266_wifi.yaml button: - id: !remove ${id_prefix}_restart diff --git a/devices/sump-pump.yaml b/devices/sump-pump.yaml index 61d0667..3cabcd6 100644 --- a/devices/sump-pump.yaml +++ b/devices/sump-pump.yaml @@ -5,4 +5,4 @@ substitutions: pwd: !secret sump_pump_pwd packages: - device_base: !include ./packages/topgreener_smart_plug.yaml + device: !include ./packages/topgreener_smart_plug.yaml diff --git a/devices/washing-machine.yaml b/devices/washing-machine.yaml index cc1401c..e9e426b 100644 --- a/devices/washing-machine.yaml +++ b/devices/washing-machine.yaml @@ -5,4 +5,4 @@ substitutions: pwd: !secret washing_machine_pwd packages: - device_base: !include ./packages/topgreener_smart_plug.yaml + device: !include ./packages/topgreener_smart_plug.yaml diff --git a/devices/water-heater.yaml b/devices/water-heater.yaml index d5b0c64..e026ffd 100644 --- a/devices/water-heater.yaml +++ b/devices/water-heater.yaml @@ -15,7 +15,7 @@ packages: url: https://github.com/esphome-econet/esphome-econet ref: main file: econet_heatpump_water_heater.yaml - device_base: !include ./packages/econet_base.yaml + device: !include ./packages/econet.yaml climate: - id: !extend econet_climate From 190b1ec4ea9aac7f515831dfc4d68fb3aa5baa5a Mon Sep 17 00:00:00 2001 From: Chris Nussbaum Date: Wed, 30 Sep 2026 11:02:00 -0500 Subject: [PATCH 2/2] Pool: pin pzem6l24 to the last commit that builds on a release `external_components: source: github://pr#17849` tracks the head of upstream's pzem6l24 PR. That PR merged on 2026-09-27, and on 2026-09-23 it picked up `automation.register_apply_action` for its `reset_energy` action (esphome/esphome#19469). That helper merged into dev *after* the 2026.9 branch cut, so it is in no released ESPHome -- every `esphome config`/`compile` of pool.yaml against 2026.9.1 now dies with `module 'esphome.automation' has no attribute 'register_apply_action'`, which took CI's `esphome config` and `compile pool` jobs down with it. Tracking a PR head was always going to break the moment that head moved past the installed release. The goal here is compatibility with a *released* ESPHome, not dev, so pin the ref instead of chasing it. Changes: - Pin the pzem6l24 source to esphome/esphome at `36d39416f0a7cdabb536d5a7434222de462c3e89` -- the last commit on that PR before the `register_apply_action` switch, still on the stable `automation.register_action`. The `github://pr#N` shorthand accepts no ref (`validate_source_shorthand` only parses `@ref` for the `user/repo` form), so this uses the explicit `type: git` source. - Change `refresh: 1h` to `refresh: never`: a pinned SHA is immutable, so re-fetching it hourly only costs time. - Comment the pin with why it exists and when it can be dropped, so it gets removed once a release carries `register_apply_action` rather than silently freezing the component forever. Verified with `esphome config pool.yaml` locally (valid, and the pinned SHA fetches fine -- GitHub serves reachable commits by id). Co-authored-by: Claude Opus 5 --- devices/pool.yaml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/devices/pool.yaml b/devices/pool.yaml index d61e6ca..011a6c1 100644 --- a/devices/pool.yaml +++ b/devices/pool.yaml @@ -16,9 +16,16 @@ external_components: type: local path: ../components components: [pool_controller] - - source: github://pr#17849 + # Pinned to the last pzem6l24 commit before upstream switched reset_energy to + # automation.register_apply_action (esphome/esphome#19469, merged 2026-09-23). + # That helper landed after the 2026.9 branch cut, so the PR head no longer + # validates against any released ESPHome. Unpin once a release carries it. + - source: + type: git + url: https://github.com/esphome/esphome.git + ref: 36d39416f0a7cdabb536d5a7434222de462c3e89 components: [pzem6l24] - refresh: 1h + refresh: never # esphome: # on_boot: