From 9de5f82924a4fd1119cea0da7dca3ecaac41befe Mon Sep 17 00:00:00 2001 From: Fredrik Wahlberg Date: Sat, 27 Dec 2025 14:54:52 +0100 Subject: [PATCH] Add implementation details to sensor auto-discovery task Clarifications added: - Storage: config/discovered_sensors.json with extended metadata - ntfy: Optional notifications via curl with token auth - CLI: sensorpajen approve-sensors (interactive only) - Config reload: Every 15 minutes, no service restart needed - Metadata: MAC, name, RSSI, timestamps, sample readings - Ignored sensors: Stored with timestamp and optional reason - Pre-filled comments with metadata for user to edit --- TASKS.md | 271 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 TASKS.md diff --git a/TASKS.md b/TASKS.md new file mode 100644 index 0000000..c6661d2 --- /dev/null +++ b/TASKS.md @@ -0,0 +1,271 @@ +# Tasks +## Task: Add Auto-Discovery and Approval Flow for Sensors + +### Problem Statement + +Adding new sensors currently requires manually editing `sensors.json`, which is error-prone and inconvenient. +The system should automatically detect new sensors and provide a controlled way for users to approve or ignore them. + +--- + +## Goal + +Implement **automatic sensor discovery** with a **user approval workflow** that: + +* Detects new sensors automatically +* Notifies the user when new sensors are discovered +* Allows the user to approve or ignore sensors via a script +* Automatically updates `sensors.json` for approved sensors +* Restarts the service after configuration changes + +--- + +## Scope + +### In Scope + +* Sensor auto-discovery +* Tracking newly discovered sensors +* Notification via `ntfy` +* Interactive user script for approving/ignoring sensors +* Updating `sensors.json` +* Restarting the service via systemd + +### Out of Scope + +* Web UI +* Authentication mechanisms beyond existing system access +* Changes to sensor hardware or firmware +* Long-term sensor management (removal, editing, etc.) + +--- + +## Functional Requirements + +### 1. Sensor Auto-Discovery + +* The service must detect sensors that are not present in `sensors.json` +* Each newly discovered sensor must have a stable unique identifier +* Discovered-but-unapproved sensors must **not** be added automatically + +--- + +### 2. Discovered Sensor Storage + +* Newly discovered sensors must be stored in `config/discovered_sensors.json` +* Stored data must include: + * `mac` - MAC address (unique identifier) + * `name` - Advertised device name (e.g., "ATC_1234AB") + * `rssi` - Signal strength in dBm + * `first_seen` - ISO timestamp of first discovery + * `last_seen` - ISO timestamp of most recent advertisement + * `sample_reading` - One example reading with temperature, humidity, battery data + * `status` - One of: "pending", "approved", "ignored" + * `ignored_at` - ISO timestamp when ignored (if status is "ignored") + * `ignore_reason` - Optional user-provided reason for ignoring +* Approved sensors must have their status updated to "approved" +* Ignored sensors must remain in the file with status "ignored" + +--- + +### 3. Notification via ntfy + +* When a new sensor is discovered: + * Send a notification to the configured `ntfy` topic via curl + * Include at least: + * Sensor MAC address + * Sensor name + * Last seen timestamp + * Instruction that user action is required +* Configuration (in `config/sensorpajen.env`): + * `NTFY_ENABLED` - true/false to enable/disable notifications + * `NTFY_URL` - ntfy server URL (e.g., "https://ntfy.sh") + * `NTFY_TOPIC` - Topic to publish to + * `NTFY_TOKEN` - Authentication token (sent in header) +* ntfy is optional - system must work without it: + * If `NTFY_ENABLED=false`, skip notifications + * If ntfy is unreachable, log error and continue + * Discovery and approval must work even if ntfy fails + +--- + +### 4. User Approval Script + +Provide a CLI command `sensorpajen approve-sensors` that: + +* Lists all sensors with status "pending" or "ignored" +* For each sensor, displays: + * MAC address + * Advertised name (e.g., "ATC_1234AB") + * Last seen timestamp + * Sample reading (temperature, humidity, battery) + * Current status (pending/ignored) +* For each sensor, allows the user to: + * Approve the sensor (add to `sensors.json`) + * Ignore the sensor (mark as ignored) + * Skip (leave as pending for later) +* If approving: + * Prompt for a sensor name (required, human-readable) + * Pre-fill comment field with extended metadata (MAC, device name, last seen, sample reading) + * Allow user to edit or keep the pre-filled comment (optional) +* If ignoring: + * Prompt for optional reason + * Update status to "ignored" with timestamp +* Interactive mode only (no batch/automated approval) + +--- + +### 5. Updating sensors.json + +* When a sensor is approved: + * Add it to `sensors.json` (only if MAC doesn't already exist) + * Include: + * `mac` - MAC address from discovery + * `name` - User-provided human-readable name + * `comment` - User-edited comment (pre-filled with metadata) +* The file must remain valid JSON +* Existing sensors must not be modified +* If MAC already exists in `sensors.json`, skip adding (renaming is done manually in the file) +* Update status to "approved" in `discovered_sensors.json` + +--- + +### 6. Configuration Reload + +* The service must automatically reload `sensors.json` every 15 minutes +* No service restart required after approval +* If `sensors.json` is modified: + * Load new sensor list + * Start monitoring newly added sensors + * Continue monitoring existing sensors without interruption +* Log configuration reload events + +--- + +## Non-Functional Requirements + +* Must be safe to run on a Raspberry Pi +* Must not require a GUI +* Must fail gracefully if: + + * `ntfy` is unreachable + * The user aborts the approval script +* Logging must clearly indicate: + + * Discovery events + * Notifications sent + * Approval or ignore decisions + +--- + +## Acceptance Criteria + +* A new sensor is automatically detected and added to `discovered_sensors.json` with status "pending" +* Extended metadata (MAC, name, RSSI, timestamps, sample reading) is stored +* A notification is sent via `ntfy` when a sensor is discovered (if enabled) +* The approval CLI command (`sensorpajen approve-sensors`) lists pending and ignored sensors +* The CLI displays MAC, name, last seen, and sample reading for each sensor +* The user can approve a sensor with a custom name +* The comment field is pre-filled with metadata and user can edit it +* The user can ignore a sensor with an optional reason +* Previously ignored sensors can be approved in a later CLI run +* Approved sensors appear correctly in `sensors.json` (mac + name + comment only) +* Sensors already in `sensors.json` are not added again (no duplicates) +* The service automatically reloads `sensors.json` every 15 minutes +* New sensors are monitored without service restart +* Ignored sensors are stored with `ignored_at` timestamp and optional `ignore_reason` +* ntfy failures do not prevent discovery or approval workflow + +--- + +## Notes for Implementation + +* Prefer environment-based configuration (no `.ini` files) +* Keep the discovery logic separate from user interaction logic +* Avoid race conditions between discovery and approval +* Assume multiple sensors may be discovered before user action +* Use MAC address as unique identifier for sensors +* ntfy notification format: `curl -H "Authorization: Bearer $NTFY_TOKEN" -d "message" $NTFY_URL/$NTFY_TOPIC` +* Config reload: Use a timer thread that checks file mtime or reloads every 15 minutes +* Pre-filled comment example: `"MAC: A4:C1:38:12:34:56, Name: ATC_1234AB, Last seen: 2025-12-27T14:30:00, Temp: 21.5°C, Humidity: 45%, Battery: 87%"` + +--- + +## Implementation Details + +### File Locations +* Discovered sensors: `config/discovered_sensors.json` +* Known sensors: `config/sensors.json` (existing) +* Configuration: `config/sensorpajen.env` (add ntfy settings) + +### New CLI Command +* Entry point: `sensorpajen approve-sensors` +* Add to `pyproject.toml` under `[project.scripts]` + +### Configuration Variables (add to sensorpajen.env) +```bash +# ntfy notifications (optional) +NTFY_ENABLED=true +NTFY_URL=https://ntfy.sh +NTFY_TOPIC=sensorpajen +NTFY_TOKEN=tk_xxxxxxxxxxxxx + +# Config reload interval (seconds) +CONFIG_RELOAD_INTERVAL=900 # 15 minutes +``` + +### discovered_sensors.json Structure +```json +[ + { + "mac": "A4:C1:38:12:34:56", + "name": "ATC_1234AB", + "rssi": -65, + "first_seen": "2025-12-27T14:30:15", + "last_seen": "2025-12-27T14:35:42", + "sample_reading": { + "temperature": 21.5, + "humidity": 45, + "battery_percent": 87, + "battery_voltage": 2950 + }, + "status": "pending" + }, + { + "mac": "A4:C1:38:AB:CD:EF", + "name": "ATC_ABCDEF", + "rssi": -72, + "first_seen": "2025-12-27T15:00:00", + "last_seen": "2025-12-27T15:10:00", + "sample_reading": { + "temperature": 19.8, + "humidity": 52, + "battery_percent": 65, + "battery_voltage": 2800 + }, + "status": "ignored", + "ignored_at": "2025-12-27T15:15:00", + "ignore_reason": "Test sensor, not needed" + } +] +``` + +### sensors.json Entry (after approval) +```json +{ + "mac": "A4:C1:38:12:34:56", + "name": "Living Room", + "comment": "MAC: A4:C1:38:12:34:56, Name: ATC_1234AB, Last seen: 2025-12-27T14:35:42, Temp: 21.5°C, Humidity: 45%, Battery: 87%" +} +``` + +--- + +If you want, I can also: + +* Split this into **multiple smaller tasks** +* Add a **definition of done** section +* Provide a **suggested file/module structure** +* Write a **follow-up roadmap entry** for sensor management + +Just tell me how you want to evolve it next.