Files
sensorpajen/TASKS.md
Fredrik Wahlberg 9de5f82924 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
2025-12-27 14:54:52 +01:00

8.5 KiB

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)

# 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

[
  {
    "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)

{
  "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.