Skip to content

[RFC] Multi-device support via ESPHome packages#21

Closed
flowcool wants to merge 7 commits into
JGAguado:V2R1from
flowcool:feat/rfc-multi-device-packages
Closed

[RFC] Multi-device support via ESPHome packages#21
flowcool wants to merge 7 commits into
JGAguado:V2R1from
flowcool:feat/rfc-multi-device-packages

Conversation

@flowcool

@flowcool flowcool commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Status update (2026-06-16): This RFC is now fully implemented and validated in production on 8 devices. See fork flowcool/Smart_Plant, branch feat/packages-refactor. All 8 devices running the packages-based firmware (MQTT, deep sleep, display, sensors confirmed). A clean implementation PR will follow once this RFC gets feedback.


Original proposal

I'm opening this PR to share an architectural approach and get @JGAguado's feedback before going further. Nothing in this PR should affect the existing configuration.yaml or onboarding for single-plant users.

Context

Running 8 Smart Plant boards at home. With the current flat configuration.yaml, every fix has to be manually copied to 7 other files (~390 lines each).

Proposed approach

Use ESPHome's packages: feature to split into:

  1. A shared base package (smart_plant_base.yaml) — all common firmware
  2. A tiny per-device file (~20 lines) — plant-specific substitutions only
packages:
  base: github://JGAguado/Smart_Plant/examples/multi-device/packages/smart_plant_base.yaml@V2R1

ESPHome fetches the base at compile time. Every push propagates to all devices on the next flash.

What this PR adds

  • examples/multi-device/packages/smart_plant_base.yaml
  • examples/multi-device/my-lemon-tree.yaml (example per-device file)

No changes to existing docs/source/files/configuration.yaml.

🤖 Assisted with Claude Code

flowcool and others added 7 commits June 16, 2026 09:36
This is a discussion proposal — not a merge request for the current
single-device configuration.yaml.

## Context

I'm running 8 Smart Plant boards at home. With the current flat
configuration.yaml, maintaining 8 copies means:
- every bug fix or improvement must be applied 8 times
- calibration values are scattered across 8 files
- inconsistencies creep in over time

## Proposed structure

    examples/multi-device/
    ├── packages/
    │   └── smart_plant_base.yaml   # all shared config (~250 lines)
    └── my-lemon-tree.yaml          # per-plant overrides (~20 lines)

The base package contains everything that is currently in
configuration.yaml. Each device file only defines its substitutions
(name, timezone, label image, soil calibration, gauge ranges) and
includes the package with a single !include.

Benefits:
- A bug fix in smart_plant_base.yaml propagates to all devices on the
  next OTA — no copy-paste
- Soil calibration is clearly visible per device, not buried in a
  shared file
- New plant = 15-line file, not a 400-line copy

Also included in the base:
- All fixes from PRs JGAguado#18 (SNTP), JGAguado#19 (power_save_mode / timezone)
- draw_gauge refactored as a C++ lambda to eliminate the 4×50-line
  repeated block
- device_class: battery on the battery_level sensor

## Questions for @JGAguado

1. Would you consider adding this as an `examples/` directory rather
   than replacing configuration.yaml? The single-file config would
   remain the default for users with one plant; this would be an
   opt-in for multi-plant setups.
2. The draw_gauge lambda refactor inside the display lambda — is that
   acceptable in terms of ESPHome compatibility across versions?
3. Are there plans to migrate the project to esp-idf framework? That
   would affect some of the deep sleep optimisations.

Note: I've been working on this refactoring with AI assistance
(Claude Code) for my personal multi-plant setup. The PRs in this
series are the result of a careful diff between the upstream config
and my production setup. Happy to iterate on any of this.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace api: with mqtt: (MQTT required for deep-sleep compatibility)
- Add substitutions: device_comment, mqtt_topic_prefix, ota_password,
  ap_ssid — all previously hardcoded per-device
- Improve on_boot: Wire.begin() + wait for mqtt.connected + wait for
  valid SNTP time (replaces fixed 20s delay, fixes 1970 display bug)
- Update my-lemon-tree.yaml to show static IP override pattern and
  github:// package URL for zero-local-copy deployment

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… init

Wire is not in scope in ESPHome lambdas without explicit include; the i2c:
component already initializes the bus before on_boot runs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bypasses mDNS resolution (which fails with name_add_mac_suffix: true).
Device files set use_address to their static IP; default falls back to
device_name for setups without static IP.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes the 30s blocking wait for SNTP in on_boot — display already
handles the missing-time case gracefully with dashes. Adds on_time_sync
callback instead: display refreshes immediately the moment SNTP syncs,
regardless of network latency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pool.ntp.org alone can be slow on some networks (ESP32 UDP stack init
latency + retry cycles). Adding cloudflare and google as fallbacks
increases the chance of a fast first sync without any local IP dependency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DNS resolution can fail on ESP32 depending on router/DHCP config.
Using Cloudflare (162.159.200.1) and Google (216.239.35.0) stable
anycast IPs as primary servers with pool.ntp.org as hostname fallback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@flowcool

Copy link
Copy Markdown
Contributor Author

Superseded by #22 — clean implementation PR with full production validation (8 devices, 2+ days). Closing this RFC.

@flowcool flowcool closed this Jun 18, 2026
@flowcool flowcool deleted the feat/rfc-multi-device-packages branch June 18, 2026 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant