feat(reset): config wipe, setup screen, and re-exec into provisioning (story 4-2)

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>
This commit is contained in:
Matt Edholm
2026-04-22 23:59:22 -04:00
parent 8e57f2d927
commit 7f34a7b926
5 changed files with 168 additions and 3 deletions
@@ -214,3 +214,17 @@ Description: `BUTTON_GPIO_PIN = 17` and `LED_GPIO_PIN = 27` are module-level con
Story: `4-1-gpio-button-hold-detection-and-led-feedback`
Category: Infrastructure/environment
Description: `ButtonHoldDetector.__init__` constructs a `gpiozero.Button` immediately. The radar main loop must construct `ButtonHoldDetector` at startup (not at import time), or the application will fail if GPIO is unavailable when the module is imported. This is currently safe because `gpio_ctrl.py` is not imported at module level in `main.py`, but any future reorganisation that imports it at the top of a module that runs on non-GPIO hardware will raise a `BadPinFactory` error unless a `MockFactory` is active.
---
## Story 4.2: Config Wipe, Setup Screen & Return to Provisioning
### [4-2] ButtonHoldDetector and LEDController raise at startup on Pi without GPIO
Story: `4-2-config-wipe-setup-screen-and-return-to-provisioning`
Category: Infrastructure/environment
Description: `ButtonHoldDetector` and `LEDController` are now instantiated unconditionally in `main()` before the loop begins. On a Pi without GPIO hardware (or without a `MockFactory` active), both constructors will raise a `BadPinFactory` error at startup, crashing the radar service before it can display anything. Same concern as story 4-1. Future hardening: wrap construction in a try/except and fall back to no-op stubs, or defer construction until first use.
### [4-2] os.execvp replaces process — no cleanup before re-exec
Story: `4-2-config-wipe-setup-screen-and-return-to-provisioning`
Category: Technical debt
Description: `os.execvp` replaces the current process image immediately. Any cleanup that would normally happen at shutdown — flushing log handlers, closing the SPI connection to the e-ink display, releasing GPIO pins — is not performed. Acceptable for MVP: the SPI and GPIO resources will be re-acquired by the provisioning process, and the OS reclaims file descriptors. A future improvement could flush logs and call `display.close()` (if such a method exists) before exec.