# Phase 2 - Odoo REST API Testing Guide ## ✅ Was wurde implementiert ### Models (Phase 2.1) - **ows.iot.event**: Event Log mit unique `event_uid` - Alle Events von der Bridge werden geloggt - Auto-Linking zu mqtt.device und mqtt.session - Payload-Extraktion (power_w, state) - **mqtt.device**: Erweitert mit `device_id` (External ID) - Für API-Zugriff durch Bridge ### REST API Controller (Phase 2.2) - **GET /ows/iot/config** - Returns: Liste aller aktiven Devices mit session_config - Auth: public (später API-Key) - **POST /ows/iot/event** - Empfängt Events von Bridge - Duplikat-Check via event_uid (409 Conflict) - Auto-Processing: Session erstellen/updaten - Returns: 201 Created, 409 Duplicate, 400 Bad Request, 500 Error ### Bridge Client (Phase 2.3) - **OdooClient**: Echte REST API Calls - `get_config()` → GET /ows/iot/config - `send_event()` → POST /ows/iot/event (JSON-RPC) - Retry-Logic über EventQueue ## 🧪 Testing-Schritte ### 1. Odoo Modul upgraden ```bash cd /home/lotzm/gitea.hobbyhimmel/odoo/odoo docker compose -f docker-compose.dev.yaml exec odoo-dev odoo --upgrade open_workshop_mqtt ``` Oder über UI: Apps → open_workshop_mqtt → Upgrade ### 2. MQTT Device in Odoo anlegen UI: MQTT → Devices → Create **Beispiel-Konfiguration:** - **Name**: Shaper Origin - **Device ID**: `shellypmminig3-48f6eeb73a1c` - **MQTT Connection**: (wähle bestehende oder erstelle neue für local Mosquitto) - **Topic Pattern**: `shaperorigin/#` - **Parser Type**: Shelly PM Mini G3 - **Session Strategy**: Power Threshold (Dual) - **Strategy Configuration**: ```json { "standby_threshold_w": 20, "working_threshold_w": 100, "start_debounce_s": 3, "stop_debounce_s": 15, "message_timeout_s": 20, "heartbeat_interval_s": 300 } ``` ### 3. API manuell testen **Test 1: GET /ows/iot/config** ```bash curl http://localhost:8069/ows/iot/config ``` Expected Response: ```json { "status": "success", "devices": [ { "device_id": "shellypmminig3-48f6eeb73a1c", "mqtt_topic": "shaperorigin/status/pm1:0", "parser_type": "shelly_pm", "machine_name": "Shaper Origin", "session_config": { "strategy": "power_threshold", "standby_threshold_w": 20, ... } } ], "timestamp": "2026-02-05T15:30:00.000000Z" } ``` **Test 2: POST /ows/iot/event** ```bash curl -X POST http://localhost:8069/ows/iot/event \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "call", "params": { "event_uid": "test-' $(uuidgen) '", "event_type": "session_started", "device_id": "shellypmminig3-48f6eeb73a1c", "session_id": "test-session-123", "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)'", "payload": { "power_w": 47.9, "state": "starting" } }, "id": null }' ``` Expected Response: ```json { "jsonrpc": "2.0", "id": null, "result": { "status": "success", "message": "Event received and processed", "event_uid": "test-...", "event_id": 1, "code": 201 } } ``` **Test 3: Duplicate Event (sollte 409 zurückgeben)** ```bash # Gleichen curl nochmal ausführen → sollte code: 409 zurückgeben ``` ### 4. config.yaml.dev für echtes Odoo anpassen ```yaml odoo: base_url: "http://odoo-dev:8069" database: "your-db-name" # ← WICHTIG: Deinen DB-Namen eintragen username: "admin" api_key: "" # Aktuell nicht benötigt (auth='public') use_mock: false # ← VON true AUF false ÄNDERN ``` ### 5. Bridge im Docker Compose starten ```bash cd /home/lotzm/gitea.hobbyhimmel/odoo/odoo docker compose -f docker-compose.dev.yaml up -d iot-bridge docker compose -f docker-compose.dev.yaml logs -f iot-bridge ``` **Erwartete Logs:** ``` Loading configuration from /app/config.yaml INFO: bridge_started config_file=/app/config.yaml devices=1 INFO: using_real_odoo_client base_url=http://odoo-dev:8069 database=... INFO: config_loaded device_count=1 INFO: event_queue_started INFO: session_detector_initialized device=shellypmminig3-48f6eeb73a1c INFO: connected_to_mqtt broker=mosquitto port=1883 INFO: subscribed_to_topic topic=shaperorigin/status/pm1:0 INFO: bridge_ready status=running ``` ### 6. End-to-End Test **Option A: Mit echtem Shelly Device** - Sende MQTT-Nachrichten an lokalen Mosquitto - Bridge empfängt → Session Detection → Events an Odoo **Option B: Mit MQTT Simulator** ```bash mosquitto_pub -h localhost -t "shaperorigin/status/pm1:0" \ -m '{"apower": 45.5, "timestamp": 1234567890}' ``` **Prüfen in Odoo:** 1. IoT Events: `ows.iot.event` Records 2. MQTT Sessions: `mqtt.session` Records 3. Logs: Bridge Logs zeigen erfolgreiche API Calls ### 7. Troubleshooting **Problem: "ModuleNotFoundError: No module named 'requests'"** → Docker Image neu bauen (ist schon in requirements.txt) **Problem: "Connection refused to odoo-dev"** → Prüfe dass Odoo Container läuft: `docker compose ps` **Problem: "Database not found"** → Korrekten DB-Namen in config.yaml.dev eintragen **Problem: "Event UID constraint violation"** → Normal bei Restarts - Bridge sendet Events nochmal → API returned 409 (duplicate) → wird als Success behandelt ## 📊 Monitoring ### Odoo UI - **IoT Events**: Settings → Technical → IoT Events - **MQTT Sessions**: MQTT → Sessions - **MQTT Devices**: MQTT → Devices ### Bridge Logs ```bash docker compose -f docker-compose.dev.yaml logs -f iot-bridge ``` ### MQTT Messages (Debug) ```bash mosquitto_sub -h localhost -t "shaperorigin/#" -v ``` ## ✅ Success Criteria - [ ] GET /ows/iot/config returns device list - [ ] POST /ows/iot/event creates ows.iot.event record - [ ] Duplicate event_uid returns 409 - [ ] Bridge starts with use_mock=false - [ ] Bridge fetches config from Odoo - [ ] Bridge sends events to Odoo - [ ] mqtt.session is created for session_started event - [ ] mqtt.session is updated for session_updated event - [ ] mqtt.session is completed for session_stopped event - [ ] No errors in Bridge or Odoo logs ## 🎯 Nächste Schritte Nach erfolgreichem Test: - Phase 2 Commit - Optional: API-Key Authentication hinzufügen - Optional: Health-Check Endpoint für Bridge - Phase 3: Production Deployment