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
This commit is contained in:
271
TASKS.md
Normal file
271
TASKS.md
Normal file
@@ -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.
|
||||||
Reference in New Issue
Block a user