ESPHome Replication Plan - jaas666/my-flo GitHub Wiki
ESPHome Replication Plan
Goal: reproduce the device's local behavior in ESPHome, using what is documented in Device Overview, Network Protocol, and Hardware GPIO Map.
What to skip entirely
- Cloud registration/pairing (
/device-api/v2/register, token flow) — the unit also has an offline mode, so it is not required for local operation. - Captive-portal onboarding — ESPHome's own WiFi provisioning (or Improv/dashboard import) replaces this.
- TLS cert handling — the cloud uses a public CA bundle with no pinning, so there is nothing to replicate.
What to build
- Valve control —
switchon GPIO9/GPIO10 (see Hardware GPIO Map) driven as a two-wire output, wrapped in ascriptthat holds the valve open for the dose time, then returns to idle. The latching valve's feedback and retry is left out; the draft is a simple timed pulse. - Dispense triggers:
- a template
buttonfor a manual dose. The front button (GPIO6, pull-up, active low) is reported as a sensor only: on the factory unit it wakes the unit and keeps it awake rather than dispensing. - Scheduling (
SCHEDULE DISPENSE) runs on the device (4 daily time slots, each with a dose count), so it keeps working with HA down. HA only edits the slots and views history. REMOTE DISPENSE→ just a Home Assistant service call to the same script.
- a template
- Battery monitoring —
sensor.adcon GPIO8 (ADC1 channel 7, 11dB atten — see Hardware GPIO Map), mapped from 2200–3000 mV to a percentage, withbinary_sensorthresholds at 20% (low) and 10% (critical) and dispensing blocked below 20%. - Bottle/float sensor — if your unit has a float, a
binary_sensoron GPIO7. - Counters — ESPHome
globalsornumberentities for the used-dose count and the dose limit, exposed to Home Assistant, replacing the cloud dashboard's role.
Design rule: standalone first
The unit must keep working with Home Assistant, and even WiFi, unavailable. HA is an optional controller and history/monitoring front end. In esphome/iflo.yaml this means:
- Schedule, dose limits, counters, last-dose time and the valve failsafe live on the device and are saved to flash.
- The clock comes from SNTP (HA also sets it when connected). Without any time source after a power loss, scheduled doses are skipped until the clock is valid again.
- ESPHome's default reboot timers for "no API client" and "no WiFi" are disabled, so an HA or router outage doesn't reboot-loop the unit.
- A local web UI (digest-auth) and the fallback AP allow control and WiFi changes with no HA.
- While HA is down it only sees the persisted counters and last-dose time on reconnect, not each individual dose (an on-device event log is an open task).
Status: draft config
A first draft lives in the repo at esphome/iflo.yaml (core local function only: timed valve dose with a hard max-open failsafe, battery %, dose counters/limits, on-device 4-slot schedule, SNTP clock, local web UI). It passes esphome config and is not tested on hardware. Deliberately left out of this first build: deep sleep/wake (always-on WiFi drains the battery, so bench/USB power only), valve feedback/retry, and lost-dispense catch-up.
Safety gate: the config reads the hardware-model strap pins (GPIO18/19/20, see Hardware GPIO Map) and refuses to open the valve unless all three read low (the simple-valve model). See Flashing and Recovery before flashing a real unit.
Power model
The unit is battery powered and mostly asleep, so the target build needs deep sleep. The factory unit wakes on a timer, the front button (GPIO6), a bottle change (GPIO13), the float switch (GPIO7) and external power (GPIO16); see Power and Sleep. Plan: wake on the timer, the button (ext1) and the bottle eject (ext0, inverted level); the float switch and external power need a ULP program or timer polling, which ESPHome lacks. Wake on those plus a timer set to the earlier of the next schedule slot and a maximum sync interval, stay awake for a short window (about 60 s) so Home Assistant can connect, and offer a "stay awake" switch. While asleep the unit still runs its schedule on its own.
Development environment
The repo ships a VS Code dev container and a docker-compose.yml with ESPHome and esptool pinned, so nothing has to be installed locally except Docker. See the repo README. The container builds only; flash from the host.
Open items
- GPIO40, 39, 41, 42 are probably the LEDs and GPIO15/GPIO2 the second driver IC; probe the PCB to confirm.
- The float switch is GPIO7 and the bottle eject switch GPIO13 (see Hardware GPIO Map); both are pull-up inputs (active low) in the draft; confirm on a unit.
- The latching/feedback valve (model 3, all straps high) is not implemented in the draft.
- The dose-time units (probably tenths of a second) and the battery divider ratio are unverified; the draft exposes them as adjustable values.
- How to get wired access for the first flash (see Flashing and Recovery).