Add _handle_reset() and _make_setup_screen() to main.py; integrate ButtonHoldDetector and LEDController into the radar loop; LED lights immediately on hold, config is wiped, setup screen shown, then os.execvp hands off to planemapper-provision. Wipe failures log ERROR and abort without exec. Completes epic-4. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.0 KiB
Story 4.2: Config Wipe, Setup Screen & Return to Provisioning
Status: done
Story
As a user who has triggered a reset, I want the device to wipe its configuration, show a setup screen on the e-ink display, and restart into the provisioning flow, So that I can re-configure the device from scratch.
Acceptance Criteria
AC1: Given ButtonHoldDetector.check() returns True When the reset handler runs Then config.wipe() is called
AC2: Given config has been wiped When the reset handler continues Then display.show(setup_screen_image) is called
AC3: Given setup screen is shown When reset handler completes Then os.execvp('planemapper-provision', ['planemapper-provision']) replaces the current process
AC4: Given config.wipe() raises an unexpected error When the reset handler encounters it Then ERROR is logged and os.execvp is NOT called
Tasks / Subtasks
-
Task 1: Implement
_handle_reset()and_make_setup_screen()insrc/planemapper/main.py(AC: #1–#4)- 1.1 Add
import osto imports - 1.2 Add
from planemapper.provisioning.config import wipe as wipe_config - 1.3 Add
from planemapper.gpio_ctrl import ButtonHoldDetector, LEDController - 1.4 Implement
_make_setup_screen() -> Image.Image - 1.5 Implement
_handle_reset(display, led) -> None - 1.6 Update
main()to instantiateButtonHoldDetectorandLEDController - 1.7 Add reset check at top of loop
- 1.1 Add
-
Task 2: Write tests in
tests/test_reset.py(AC: #1–#4) -
Task 3: Run quality gates
- 3.1
python -m pytest tests/— all tests pass - 3.2
python -m ruff check .— zero violations - 3.3
python -m ruff format --check .— no formatting issues
- 3.1
Implementation Notes
_handle_reset flow
led.on()— immediate LED feedback before any wipe attemptwipe_config()— deletes config file; on failure, log ERROR, callled.off(), returndisplay.show(_make_setup_screen())— render "Resetting..." screenos.execvp("planemapper-provision", ["planemapper-provision"])— replaces process (never returns)
_make_setup_screen()
Returns a white 800×480 PIL Image with "Resetting..." text. Same pattern as _make_startup_screen().
main() loop update
ButtonHoldDetector and LEDController are instantiated once in main() before the loop. Inside the loop, button.check() is called once per cycle (non-blocking). If True, _handle_reset is called (which never returns on success).
TID251 per-file-ignore
main.py already has TID251 in per-file-ignores in pyproject.toml, so importing from planemapper.provisioning.config is allowed.
Patching in tests
wipe_configis patched atplanemapper.main.wipe_configos.execvpis patched atplanemapper.main.os.execvp
Files changed
| File | Change |
|---|---|
src/planemapper/main.py |
Add import os, new imports, _make_setup_screen(), _handle_reset(), update main() |
tests/test_reset.py |
New file with 3 tests |