Skip to content

docs(power): production power-down/wake design (Opta I1 sensing, default-off bench gating) - #110

Merged
dorkmo merged 2 commits into
mainfrom
power-mgmt-design
Aug 23, 2026
Merged

docs(power): production power-down/wake design (Opta I1 sensing, default-off bench gating)#110
dorkmo merged 2 commits into
mainfrom
power-mgmt-design

Conversation

@dorkmo

@dorkmo dorkmo commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Design draft only — no implementation, no behavior change.

Adds DESIGN-CONTROLLER/POWER_MANAGEMENT.md capturing the production power-down / wake design discussed at the bench today, plus a one-paragraph pointer in TRACTOR_NODE.md:

  • Key-off sensing uses hardware the design already has: Opta expansion input I1 (ignition sense) and AI1 battery voltage (native 0-30 V), both already in the Modbus map (digital_inputs 0x0101, battery_mv 0x0102).
  • The H747 co-MCU owns the debounce (10 s continuous I1-low proposal), with battery_mv disambiguating key-off from electrical failure. Modbus silence keeps its existing safety-only meaning.
  • Clean-halt sequence bridged by the Max Carrier 18650 UPS slot (~30-60 s duty), farewell packet to the base, then power release — preferred via a self-holding relay so power-off is fully automatic.
  • Battery caveats gated before production: post-halt drain measurement, cold-charging (JEITA/NTC or LiFePO4/supercap substitution), crash-only rootfs hardening as backstop.
  • Bench compatibility by default-off gating: the consumer is enabled only by explicit provisioning (LIFETRAC_POWER_MGMT=1, name provisional). Absence of the flag IS bench mode — no ignition/VIN logic armed, radios testable with no Opta attached. Matches the LIFETRAC_NO_PARK_LAST env-gating pattern. Valve-safety watchdogs are explicitly out of this flag''s scope.
  • Base-station side: quiesce on farewell, idle-time channel surveys (RS-11.6: picks perish in hours), and a 927.5 MHz home-channel rendezvous at session start.

Open bench checks listed in-doc: /sys/class/power_supply/ exposure on the X8, post-halt 18650 drain, harness confirmation that ignition sense lands on I1.

No conflict with #109 (that PR touches only the two TODO.md files).

🤖 Generated with Claude Code

…ault-off gating

Design draft only, no implementation. Captures the bench discussion:
key-off sensing via the already-specced Opta I1 + battery_mv registers,
H747-owned debounce, battery-bridged clean halt with farewell packet,
self-holding power-relay release, base-station quiesce with idle-time
surveys and a 927.5 MHz rendezvous channel. The consumer is default OFF
(LIFETRAC_POWER_MGMT provisioned in production); absence of the flag IS
bench mode, so bench radio testing needs no power signals and no new
variable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 22, 2026 16:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This docs-only PR proposes production tractor power-down/wake behavior while preserving default-off bench operation.

Changes:

  • Adds the production power-management design.
  • Documents sensing, shutdown, battery, provisioning, and rendezvous behavior.
  • Links the design from TRACTOR_NODE.md.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.

File Summary
LifeTrac-v25/DESIGN-CONTROLLER/TRACTOR_NODE.md Adds a pointer to the power-management design.
LifeTrac-v25/DESIGN-CONTROLLER/POWER_MANAGEMENT.md Documents the proposed architecture; unresolved critical and moderate issues affect farewell transmission, sensing, relay handshakes, wake behavior, provisioning, and radio fallback.
Suppressed comments (4)

LifeTrac-v25/DESIGN-CONTROLLER/POWER_MANAGEMENT.md:57

  • on H747 command is not yet a defined shutdown path: the H7 command handler has no power-management opcode, and the existing X8 UART path only forwards camera-related commands. Without a defined H747→Linux shutdown request plus a Linux completion signal, the clean-halt and subsequent power-release steps cannot be sequenced deterministically.
### Linux shutdown sequence (on H747 command)

1. Hydraulic outputs are already safe (Opta watchdog + PSR chain — not this doc's
   job, and never gated by it).
2. Stop image/radio containers; park the LoRa radio in sleep.
3. Send a **farewell packet** to the base (see "Base station" below).
4. `sync` + clean halt.
5. Power release (see below).

LifeTrac-v25/DESIGN-CONTROLLER/POWER_MANAGEMENT.md:25

  • digital_inputs does not currently contain the proposed I1 signal: tractor_opta.ino writes only the E-stop loop and mode-switch bits (lines 346–348), and TODO.md still lists reading the D1608S inputs/ignition state as pending. Please label this as a proposed mapping until the Opta firmware publishes I1.
| Ignition present (digital) | Opta expansion input **I1 — ignition sense** ([TRACTOR_NODE.md](TRACTOR_NODE.md), I/O map) | `digital_inputs` 0x0101 |

LifeTrac-v25/DESIGN-CONTROLLER/POWER_MANAGEMENT.md:26

  • battery_mv is not currently a millivolt value: tractor_opta.ino:a0602_read() returns ae.pinCurrent(ch) as a raw ADC code, and the H7 forwards the values without conversion; TODO.md still lists scaling 0x0102–0x0107 as pending. The debounce design needs a defined calibration/threshold before using this register to distinguish a healthy from a collapsing rail.
| Battery rail voltage (analog) | **AI1 — battery voltage**, native 0–30 V range on the A0602 expansion (no external divider) | `battery_mv` 0x0102 |

LifeTrac-v25/DESIGN-CONTROLLER/POWER_MANAGEMENT.md:128

  • RS-11.7 is currently a proposed manual maintenance survey: its documented v0 pauses the RX daemon, recommends a channel, and leaves APPLY manual; the periodic automation and coordinated switch are still pending in TODO.md lines 2278–2294. This section presents that extension as already operational, without defining what happens to wake hails while the receiver is paused.
- **Idle-time channel surveys.** RS-11.6 established that channel picks perish in
  hours and a same-day survey is a correctness requirement. A quiesced base runs
  the survey automatically every few hours (the RS-11.7 automation, extended), so
  the current clean-channel pick is always ready when the tractor returns.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +54 to +57
2. Stop image/radio containers; park the LoRa radio in sleep.
3. Send a **farewell packet** to the base (see "Base station" below).
4. `sync` + clean halt.
5. Power release (see below).
Comment on lines +36 to +38
The **Max Carrier H747 co-MCU** owns the debounce and the shutdown decision. It is
the always-alive component (it survives Linux crashes and reboots by design) and it
already polls the Opta as Modbus master, so it sees I1 and `battery_mv` every cycle.
Comment on lines +64 to +68
Preferred: a **self-holding power relay** — energized at key-on, held by an X8/H747
output, released when halt completes. This makes power-off fully automatic, removes
any dependence on the operator throwing the master cutoff promptly, and shrinks the
18650's duty to the bridge window only. Fallback: operator opens the master cutoff;
acceptable, but then post-halt battery drain matters (below).
Comment on lines +121 to +124
- On receiving the tractor's **farewell packet**, the base stops the image pipeline
and drops to low-duty listen. The web UI stays up and shows "tractor off
(expected)" — distinct from lost-link, so nobody chases a phantom outage and the
base does not burn airtime on retries.
Comment on lines +129 to +133
- **Rendezvous protocol.** The tractor wakes with a weeks-stale channel pin. It
hails on a fixed **home channel, 927.5 MHz** (the only 3/3-clean channel across
the 2026-08 surveys; plausibly band-edge-protected). The base answers with
today's channel assignment; both hop; the session resumes. Session start is
therefore: hello on home channel → channel assignment → traffic.
Comment on lines +99 to +101
- Setting (name provisional): `LIFETRAC_POWER_MGMT=1` — reaches the H747 via its
config path at provisioning time; documented in
[SETTINGS_REFERENCE.md](SETTINGS_REFERENCE.md) once implemented.
Comment on lines +44 to +48
- `battery_mv` disambiguates: key-off shows I1 low with a healthy rail; a genuine
electrical failure shows the rail collapsing with I1 still high. The second case
should trigger an *urgent* shutdown (shorter debounce) plus a telemetry alarm.
- Modbus silence from the Opta keeps its existing meaning (safety event → coils
drop via the Opta's own watchdog). It is **never** interpreted as key-off.
Comment on lines +28 to +32
Power topology (already consistent with the TRACTOR_NODE.md wiring tree): the Opta
and Max Carrier are fed from the constant (master-cutoff-side) distribution, **not**
key-switched power. The ignition circuit lands only on I1. The Opta therefore stays
alive through the grace window and can report key-off; "weeks off" is the master
cutoff opening after shutdown completes.
…d against source

Copilot findings verified against tractor_opta.ino / tractor_h7.ino /
SETTINGS_REFERENCE.md before amending; every one was correct:

- farewell now sent BEFORE radio teardown (original sequence parked the
  radio first and could not transmit)
- I1/battery_mv mapping relabeled PROPOSED with verified current-state
  notes (Opta publishes only E-stop+mode bits; H7 reads only 0x0102 x6;
  analog block is raw ADC, mV scaling pending) + prerequisites checklist
- SHUTDOWN_REQ/ACK opcodes named as new X8-H747 UART surface
- self-holding relay release now has an explicit handshake + 300 s
  fail-safe cap, with crash-only rootfs a stated prerequisite
- battery_mv failure-mode caveat: staleness bound + independent
  H747-side rail measurement required (Modbus dies with the rail)
- wake path defined: key-on energizes hold coil directly (diode-OR);
  master cutoff documented as service disconnect requiring manual close
- enable gate moved from env var to persisted parameter delivered to
  H747 at boot, DISARMED default (env var mirrors Linux side only)
- rendezvous: hail SET from stability ranking replaces single channel;
  grid-offset caveat recorded (927.5 is not a chantab center; no table
  channel has bench stability data yet); survey-vs-hail listen windows
  bounded so a wake hail cannot be stranded

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dorkmo added a commit that referenced this pull request Aug 22, 2026
… ideas

From the 2026-08-22 session: PR #110 review surfaced that all bench
channel-stability data sits on the x.0/x.5 MHz survey grid while the
production FHSS table centers sit on x.25/x.75 (offset 250 kHz, zero
shared channels) -> RS-11.8 tracks chantab-grid survey passes. PM-1
tracks the power-down/wake design (PR #110) with its verified
implementation prerequisites and cheap bench checks. RS-12.9 gains two
idle-time items (/sys/class/power_supply check, optional chantab pass)
and bench ops ideas (overnight quiesce vs halt, smart plug). Root TODO
banner gets a dated update line.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dorkmo
dorkmo requested a balanced review from Copilot August 23, 2026 00:04
dorkmo added a commit that referenced this pull request Aug 23, 2026
…e order

Root banner now names the complete validated mitigation (-NoParkLast 1
PLUS LIFETRAC_NO_PARK_LAST_GAP_MS=80 strict hold, env-gated not
default) instead of implying the CLI flag alone suffices, and the
session block declares the merge-order prerequisite (#110 and #111
land the referenced design doc, evidence dirs, seq= change and CI fix
-- merge them before this PR so no reference dangles).

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

dorkmo commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

@copilot please perform a review and leave your comments in this PR

Copilot AI commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

@copilot please perform a review and leave your comments in this PR

Review of PR #110 (head 8778dff)

Docs-only design draft. The follow-up commit clearly absorbs the earlier 8 review findings and re-checks several claims against firmware — good progress. Remaining issues are about architecture ownership, topology consistency, and a few still-aspirational “existing” paths. Fine to merge as a living design if these stay tracked as open questions; several should be resolved in-doc before any firmware work starts.

What looks solid

  • Proposed vs current firmware state for I1 / digital_inputs / emit_telemetry() 0x0102×6 / raw ADC matches tractor_opta.ino and tractor_h7.ino.
  • Farewell-before-teardown ordering fix is correct.
  • Self-holding relay handshake + 300 s fail-safe + crash-only rootfs prerequisite is a real production bar.
  • Hail set + chantab grid caveat (927.5 not in table) matches sx1276_fhss_chantab.h (902.75–927.25).
  • Bench default-disarmed posture and valve-safety scope guard fail in the right direction.

Must-resolve before implementation

1. Farewell TX ownership is inverted (POWER_MANAGEMENT.md Linux shutdown sequence ~L95–99)

H747 owns the SX1276 and the shutdown decision; Linux has no direct LoRa TX path for control/telemetry frames (tractor_h7.ino is the radio master; X8 UART back-channel is camera opcodes only). “Linux sends farewell while the radio is still up” cannot execute on the current architecture.

Pick one and write it explicitly:

  1. H747 sends farewell (natural: owns radio + decision), optionally after Linux ACKs “ready to halt”, or
  2. New Linux→H747 opcode (TX_FAREWELL / similar) with completion before radio park.

Also split owners for “stop image/radio containers; park the LoRa radio”: containers = Linux, modem sleep = H747/L072.

2. “Existing Linux liveness signal” does not exist (~L115–117)

H747 stamps M4 alive_tick_ms and pumps GPS/IMU KISS from X8, but there is no dedicated Linux-liveness consumer for power release. Serial1 silence is ambiguous (service crash vs intentional stop vs no GPS).

Name the concrete signal this design will add, e.g.:

  • periodic Linux→H747 HOST_HB while up; release N seconds after last HB and after SHUTDOWN_ACK, or
  • explicit HALT_COMPLETE one-shot before halt, with the 300 s cap still covering a wedged host

3. “Existing parameter path” to H747 is aspirational (~L169–172)

params_service.py persists JSON and MQTT-publishes params/changed “so the M7 can reload via UART”, but tractor_h7.ino has no params subscriber and no boot-time param pull. Demote this to the same implementation-prerequisites checklist style used for I1/Modbus:

  • power section in DEFAULT_PARAMS + SETTINGS_REFERENCE row
  • X8→H747 param delivery opcode/frame (boot + on-change)
  • H747 DISARMED default if no frame within boot grace
  • bench image leaves the key absent/false

Until that lands, provisioning params.json alone cannot arm the bare-metal consumer (same class of bug as the old env-var gate).

4. Power topology language fights the hold-relay (~L51–54 vs wake/release)

§Power topology says Opta/Max Carrier are on constant battery-side distribution; §Wake/release says a self-holding relay drops all electronics so weeks-off draw is coil leakage only. Those only reconcile if the hold relay is the carrier/Opta feed and “constant” means “not vehicle ACC,” not “always hot behind the master cutoff.”

Please add an explicit production tree, e.g.:

battery → master cutoff → hold-relay contact → {Opta, Max Carrier VIN, UPS/charger}
ignition → diode-OR → hold-relay coil
H747 GPIO → diode-OR → hold-relay coil
I1 sense from ignition (pre- or post-relay — pick one)

State whether the UPS/18650 is upstream or downstream of the hold contact. TRACTOR_NODE.md wiring still has no hold relay — mark it pre-power-mgmt or update it.

5. Survey vs hail timing math does not close (~L217–222)

channel_survey_sniff.py defaults to --dwell-s 30 over 500 kHz steps across 902–928 (~50 × 30 s ≈ 25 minutes per full pass). Hail budget is “≥5 min before no-base.” On a single SX1276, a 5-minute hail loop can sit entirely inside a survey pass with zero listen windows.

“Never stranding” needs one of: much shorter production dwells, hard preemption into hail-listen, interleaved per-channel survey/listen, or two-radio (not v25). Give worst-case wake latency from “key-on while base is mid-survey.”


Moderate / clarity

6. safety_state = IGNITION_OFF (0x0100) already exists in TRACTOR_NODE.md / Opta enum but is unused here. Decide Opta-owned coarse state vs H747-owned raw I1 bit — avoid two parallel truths. Widening H7 to the mapped 0x0100–0x010B block would pick up both safety_state and digital_inputs in one request.

7. Key-on latch race (~L129–133): diode-OR wake is right, but define how long the operator must hold the key before H747 asserts hold, and what happens if the key returns off mid-X8-boot. Spec a ready/latched indicator or minimum hold time.

8. PR description is stale relative to 8778dff (still advertises LIFETRAC_POWER_MGMT=1 env gating and a single 927.5 MHz home channel). Update the PR body so reviewers don’t re-litigate fixed issues.

9. UPS role tension: TRACTOR_NODE.md still says ~30 min brown-out ride-through; this draft scopes the cell to a 30–60 s halt bridge (and prefers supercap). Call the supersession out.

Nit: consider one-liner links from BASE_STATION.md and TODO.md so farewell/quiesce/hail work doesn’t orphan.


Verdict

Valuable design capture; prior review items largely addressed. I would not start firmware from this doc until farewell ownership, Linux liveness, H747 param delivery, hold-relay wiring, and survey/hail concurrency are nailed down in the draft.

(Inline review API is not available to this agent session; findings are anchored to the sections above against head 8778dff.)

@dorkmo
dorkmo merged commit cf5950a into main Aug 23, 2026
1 check passed
@dorkmo
dorkmo deleted the power-mgmt-design branch August 23, 2026 18:49
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.

3 participants