Skip to content

feat: level sensors, single-pump capability flag and INA226 power telemetry (PR-05)#12

Merged
cryptotomte merged 4 commits into
mainfrom
006-level-sensors-ina226
Jul 3, 2026
Merged

feat: level sensors, single-pump capability flag and INA226 power telemetry (PR-05)#12
cryptotomte merged 4 commits into
mainfrom
006-level-sensors-ina226

Conversation

@cryptotomte

Copy link
Copy Markdown
Owner

Summary

Implements PR-05 per specs/006-level-sensors-ina226/: XKC-Y26 level sensors behind a hardware-independent interface, the single-pump-node capability flag, and INA226 pump power telemetry — consuming hardware-driven requirements FW-3 and FW-5 from the rev2 design review.

  • Level sensors (ILevelSensor / DebouncedLevelSensor / GpioLevelSensor): board-owned polarity (FW-5: rev1 active HIGH, rev2 active LOW via 2N7002), 300 ms stability-window debounce (deliberate divergence — legacy reads bare pins), FW-3 settle gating (rev2 500 ms after sensor-rail power-on; rail control deferred to PR-14 per CP1 decision), explicit not-yet-valid state distinct from wet/dry, and a fault latch: a failed GPIO init pins the sensor invalid instead of letting a floating pin become a "valid" reading. Fail directions per board pinned as host-tested truths (parity checklist §3).
  • BOARD_HAS_RESERVOIR_PUMP (rev1=1, rev2=0 — single-pump decision, master PRD FR4): the rev2 profile has the reservoir pump pin removed so unguarded references fail at compile time; app_main/diag_console fully capability-gated — the rev2 binary contains exactly one pump (PR-14 contract), boot force-off invariant intact on both boards.
  • Ina226Sensor (IPowerSensor, rev2 only): TI identity check (0xFE/0xFF), config 0x4527 + CAL=2048 derived from the datasheet field layout (marked TODO(PR-14) for hardware confirmation), Kconfig shunt value (default 5 mΩ per BOM), datasheet scaling incl. signed current, snapshot-atomic reads, lazy re-init recovery — on the shared I2C bus from PR-03.
  • II2cBus extended with writeRegister16/readRegister16 (one-transaction big-endian — sanctioned by the PR-03 contract), through EspI2cBus and MockI2cBus (word-register overlay with a loud-abort guard against mis-shaped test scripts).
  • No new managed dependencies; dependencies.lock unchanged.

Full review cycle (5 agents + fixer F1–F15 + verification re-review, all VERIFIED/CLEAN). Notable catches: a short-circuited GPIO init, a fault-invisibility path that defeated the settle gate's purpose, and a driver/mock divergence that would have let ungated consumers pass host tests yet misread rev2 hardware.

Test plan

  • Host suite 164/0 on the linux preview target (debounce/settle/fault/polarity/fail-direction state-machine tests incl. exact window boundaries; INA226 scaling vectors, identity/error/recovery paths, snapshot atomicity; mock coherence; board-contract compile-time TUs)
  • rev1 + rev2 build green from clean checkout in espressif/idf:v6.0.1 (rev2 provably one-pump, rev1 INA226-free)
  • dependencies.lock unchanged
  • HIL on the rev1 rig — deferred by owner decision (run when hardware is delivered): specs/006-level-sensors-ina226/checklists/hil.md — includes the FR5 polarity bench measurement that fills the parity-checklist §3 recording slot

🤖 Generated with Claude Code

cryptotomte and others added 4 commits July 3, 2026 06:14
…(006)

Spec-kit artifact set for PR-05: feature spec with CP1 clarification (FW-3
settle-gate in the abstraction now, rail control deferred to the rev2
board profile/PR-14), research R1-R10 (per-sensor ILevelSensor with
300 ms stability-window debounce; BOARD_HAS_RESERVOIR_PUMP with
compile-time pin enforcement; Ina226Sensor with TI identity check and
datasheet scaling; II2cBus writeRegister16 extension sanctioned by the
005 contract), data model, contracts, quickstart and 27 tasks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…it seam

ILevelSensor/IPowerSensor/IDigitalInput interfaces; pure
DebouncedLevelSensor (settle -> warm-up -> tracking state machine,
300 ms stability window, board-owned polarity per FW-5, FW-3 settle
gating via notifyPowerOn); GpioLevelSensor raw input (pull-ups, R4);
LockedLevelSensor; level console command distinguishing not-yet-valid;
board.h capability table incl. BOARD_HAS_RESERVOIR_PUMP (rev2 pin
removed - rev2 target red until the T014 app_main gating lands next
commit); II2cBus writeRegister16/readRegister16 extension through
EspI2cBus and MockI2cBus. Host suite 139/0, rev1 green (T002-T013,
T023 pulled forward).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…metry

US2-US4 + polish: app_main/diag_console fully capability-gated
(BOARD_HAS_RESERVOIR_PUMP - rev2 binary contains exactly one pump,
compile-time enforced; force-off-first invariant capability-aware);
Ina226Sensor pure driver (TI identity check, config 0x4527 derived from
the datasheet field layout with TODO(PR-14) hardware confirmation,
CAL=2048 @ 0.5 mA/5 mOhm from Kconfig WS_INA226_SHUNT_MILLIOHM,
datasheet scaling incl. signed current) on the shared I2C bus with a
16-bit word-register overlay in MockI2cBus; power/level console
commands; MockLevelSensor with PR-11 truth-table consumer test;
fail-direction truths pinned per board; board-contract compile-time
TUs; firmware/CLAUDE.md + parity-checklist §6 divergences + line-96
measurement slot + HIL checklist. Full verification: host 156/0,
rev1+rev2 green from clean, dependencies.lock unchanged (T014-T027).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…dening

Review findings F1-F15: level GPIO init failures now fault-latch the
debounce state machine (isValid stays false until a deliberate
notifyPowerOn re-arm - a floating unconfigured pin can no longer become
a valid reading) with per-sensor init evaluation and logging (the ||
short-circuit skipped the high-mark init entirely); isWaterPresent()
returns false whenever invalid (was polarity-mapped construction
default - phantom water-present on rev2 during settle; driver, interface
doc and mock now agree); MockI2cBus aborts loudly on mismatched-shape
reads of setRegister16-scripted words; stable textual anchors replace
the self-broken parity-checklist line-97 citations; 8 new host tests
(fault latch, invalid-reads-false, INA226 snapshot atomicity,
calibration-write failure, identity-read failure, settle dead-time,
intra-settle chatter, rawState polarity independence) - suite 164/0,
rev1+rev2 green; comment/contract drift corrected incl. PRD macro
rename.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cryptotomte cryptotomte merged commit 1f91c60 into main Jul 3, 2026
3 checks passed
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