odoo_mqtt/IMPLEMENTATION_PLAN_DEVICE_STATUS.md
matthias.lotz ba588842ad feat: Add automatic API documentation generation and device status monitoring
- Implement build script (build_docs.py) with AST parser to auto-generate HTML docs from docstrings
- Add comprehensive Google-style docstrings to all controllers and models
- Create static/description/index.html for Odoo Apps UI with module overview
- Generate api_reference.html (20.5 KB) from source code, linked from Odoo UI
- Add DOCUMENTATION_STRATEGY.md with comparison of 5 documentation approaches
- Create API.md with complete REST API documentation

Device Status Monitoring:
- Implement device_status_monitor.py with health checks and offline detection
- Add /status endpoint for device health overview
- Automatic offline detection after message_timeout_s

Config Push Architecture:
- Add POST /config endpoint to IoT Bridge for dynamic device management
- Auto-push device config from Odoo on create/write/unlink
- Implement device_manager.py for runtime device updates

E2E Tests:
- All 6 E2E tests passing (Create, Update, Push, Delete, Restart, Status Monitor)
- Test coverage for device lifecycle and config synchronization

Documentation is auto-generated via: ./build_docs.sh
View in Odoo: Settings → Apps → Open Workshop MQTT → API Reference
2026-02-15 11:03:22 +01:00

4.3 KiB

Implementation Plan: Device Online/Offline Status

Overview

Wir leiten den Device Online/Offline Status von MQTT Message Activity (last_seen) ab. Die Bridge überwacht die Aktivität und informiert Odoo via Events. Odoo aktualisiert die bestehenden Status-Felder und zeigt sie in der UI an.

Wichtig: Die benötigten Felder existieren bereits in mqtt.device:

  • state (selection: offline/idle/active)
  • last_message_time (datetime)

Implementierung: Event-basierte Status-Updates

Bridge

  1. Track last_seen per device on every MQTT message.
  2. Add a background monitor that marks devices Offline after timeout.
  3. Emit status events to Odoo:
    • event_type: device_online, device_offline
    • payload: device_id, last_seen_at, reason
  4. Add optional MQTT LWT handling if available from devices.
  5. Persist last_seen state in /data to survive restart.

Odoo

  1. Bestehende Felder nutzen (mqtt.device):
    • state (offline/idle/active)
    • last_message_time (datetime)
  2. Event Controller erweitern (/ows/iot/event):
    • Event-Type device_online verarbeiten: state → 'idle', last_message_time aktualisieren
    • Event-Type device_offline verarbeiten: state → 'offline'
  3. Views aktualisieren:
    • Status-Anzeige mit Farb-Kodierung (grün=idle/active, grau=offline)
    • Last_message_time in List und Form View
    • Filter in List View: Online (idle/active), Offline

Data Model

Bestehende Felder (keine Änderungen nötig):

  • state: selection [offline, idle, active] - Current device status
  • last_message_time: datetime - Timestamp of last MQTT message

Configuration

  • BRIDGE_DEVICE_TIMEOUT_S (default 30)
  • BRIDGE_STATUS_CHECK_INTERVAL_S (default 5)

Implementation Steps

Phase 1: Bridge - Status Monitoring

  1. mqtt_client.py: Track last_seen timestamp pro device bei jedem MQTT Message
  2. Status Monitor Thread:
    • Background Task, läuft alle BRIDGE_STATUS_CHECK_INTERVAL_S (default: 5s)
    • Prüft jedes device: if (now - last_seen) > BRIDGE_DEVICE_TIMEOUT_S → Offline
    • State Transitions:
      • first_message → device_online event
      • timeout → device_offline event
  3. Persistenz: last_seen state in /data/device_status.json speichern (Restart-Recovery)
  4. Event Emission: device_online/device_offline via odoo_client.send_event()

Phase 2: Odoo - Event Processing

  1. iot_api.py (Event Controller):
    • Erweitere _process_event() für event_type='device_online':
      device.write({'state': 'idle', 'last_message_time': event_data['timestamp']})
      
    • Erweitere für event_type='device_offline':
      device.write({'state': 'offline'})
      
  2. Views aktualisieren:
    • mqtt_device_views.xml: Status-Badge mit Farbe (idle/active=success, offline=secondary)
    • List View: last_message_time column hinzufügen
    • Filter: "Online" (state in ['idle','active']), "Offline" (state='offline')

Phase 3: Testing

  1. Unit Tests (Bridge):
    • Test timeout detection logic
    • Test state persistence (save/load)
    • Test event emission
  2. Integration Tests:
    • iot_bridge/tests/tools/shelly_simulator.py erweitern:
      • scenario_online_test(): Kontinuierliches Senden
      • scenario_offline_test(): Stop-Senden für X Sekunden
    • Odoo Test: Prüfe state-Updates nach Online/Offline Events
  3. Test Cases:
    • Device wird Online: state='idle', last_message_time gesetzt
    • Device timeout: state='offline' nach TIMEOUT_S
    • Bridge restart: last_seen State recovered

Phase 4: Documentation

  1. README.md: Status Monitoring section
  2. API.md: device_online/device_offline event schema
  3. config.example.yaml: BRIDGE_DEVICE_TIMEOUT_S, BRIDGE_STATUS_CHECK_INTERVAL_S

Acceptance Tests

  • Start shelly_simulator: status wird 'idle' within 1 message
  • Stop simulator: status wird 'offline' nach TIMEOUT_S (default: 30s)
  • Restart bridge: last_seen state wird recovered, status korrekt innerhalb 1 timeout window
  • Multiple devices: Status-Updates unabhängig voneinander

Rollback Plan

  • Config Flag: BRIDGE_STATUS_MONITORING_ENABLED=false deaktiviert Status Monitor
  • Odoo: Ignoriere device_online/device_offline events (graceful degradation)

Notes

  • Event-basiert: Near real-time Status ohne Polling overhead
  • Bestehende Felder: Keine DB-Migration nötig
  • Backward Compatible: Alte Events funktionieren weiterhin