From 3df9f914fa6e28e1691d38950a56f27448b0a532 Mon Sep 17 00:00:00 2001 From: Eric FELIXINE Date: Wed, 6 May 2026 17:30:28 -0400 Subject: [PATCH] docs: Final session resume 2026-05-06 - 3 IoT Agents, Orion-LD, Stellio next steps --- docker-compose.iot-agent.yml | 92 ++++++++++++--- docker-compose.orion-ld.yml | 20 ++-- session_resume_2026-05-06.md | 210 +++++++++++++++++++---------------- 3 files changed, 201 insertions(+), 121 deletions(-) diff --git a/docker-compose.iot-agent.yml b/docker-compose.iot-agent.yml index bb4b34e7..bd995086 100644 --- a/docker-compose.iot-agent.yml +++ b/docker-compose.iot-agent.yml @@ -1,12 +1,12 @@ -# IoT Agent JSON - Registry in Memory (no MongoDB needed) +# IoT Agent JSON - 3 instances (one per MQTT broker) # Usage: docker compose -f docker-compose.yml -f docker-compose.iot-agent.yml up -d - version: '3.8' services: - iot-agent: + # Instance 1: EMQX + iot-agent-emqx: image: fiware/iotagent-json:latest - container_name: smart-city-iot-agent + container_name: smart-city-iot-agent-emqx restart: unless-stopped networks: - smartcity-shared @@ -14,19 +14,19 @@ services: ports: - "4041:4041" environment: - # Context Broker (Stellio) - - IOTA_CB_HOST=stellio-api-gateway - - IOTA_CB_PORT=8080 - - IOTA_CB_NGSI_VERSION=ld + # Context Broker (Orion-LD) + - IOTA_CB_HOST=orion-ld + - IOTA_CB_PORT=1026 + - IOTA_CB_NGSI_VERSION=v2 # IoT Agent settings - IOTA_NORTH_PORT=4041 - IOTA_REGISTRY_TYPE=memory - # MQTT Listener - connect to EMQX + # MQTT Listener - EMQX - IOTA_MQTT_HOST=emqx_emqx_1 - IOTA_MQTT_PORT=1883 - # No MongoDB needed - using memory registry - - IOTA_PROVIDER_URL=http://smart-city-iot-agent:4041 + - IOTA_PROVIDER_URL=http://smart-city-iot-agent-emqx:4041 - IOTA_DEFAULT_RESOURCE=/ + - IOTA_DEFAULT_APIKEY=smartcity-emqx healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:4041/version || exit 1"] interval: 30s @@ -35,10 +35,72 @@ services: start_period: 60s labels: - "traefik.enable=true" - - "traefik.http.routers.iot-agent.rule=Host(`iot-agent.digitribe.fr`)" - - "traefik.http.routers.iot-agent.entrypoints=websecure" - - "traefik.http.routers.iot-agent.tls=true" - - "traefik.http.services.iot-agent.loadbalancer.server.port=4041" + - "traefik.http.routers.iot-agent-emqx.rule=Host(`iot-agent-emqx.digitribe.fr`)" + - "traefik.http.routers.iot-agent-emqx.entrypoints=websecure" + - "traefik.http.routers.iot-agent-emqx.tls=true" + - "traefik.http.services.iot-agent-emqx.loadbalancer.server.port=4041" + + # Instance 2: Mosquitto + iot-agent-mosquitto: + image: fiware/iotagent-json:latest + container_name: smart-city-iot-agent-mosquitto + restart: unless-stopped + networks: + - smartcity-shared + ports: + - "4042:4042" + environment: + # Context Broker (Orion-LD) + - IOTA_CB_HOST=orion-ld + - IOTA_CB_PORT=1026 + - IOTA_CB_NGSI_VERSION=v2 + # IoT Agent settings + - IOTA_NORTH_PORT=4042 + - IOTA_REGISTRY_TYPE=memory + # MQTT Listener - Mosquitto + - IOTA_MQTT_HOST=mosquitto + - IOTA_MQTT_PORT=1883 + - IOTA_PROVIDER_URL=http://smart-city-iot-agent-mosquitto:4042 + - IOTA_DEFAULT_RESOURCE=/ + - IOTA_DEFAULT_APIKEY=smartcity-mosquitto + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:4042/version || exit 1"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 60s + + # Instance 3: BunkerM + iot-agent-bunkerm: + image: fiware/iotagent-json:latest + container_name: smart-city-iot-agent-bunkerm + restart: unless-stopped + networks: + - smartcity-shared + ports: + - "4043:4043" + environment: + # Context Broker (Orion-LD) + - IOTA_CB_HOST=orion-ld + - IOTA_CB_PORT=1026 + - IOTA_CB_NGSI_VERSION=v2 + # IoT Agent settings + - IOTA_NORTH_PORT=4043 + - IOTA_REGISTRY_TYPE=memory + # MQTT Listener - BunkerM + - IOTA_MQTT_HOST=bunkerm_bunkerm_1 + - IOTA_MQTT_PORT=1900 + - IOTA_MQTT_USERNAME=bunker + - IOTA_MQTT_PASSWORD=bunker + - IOTA_PROVIDER_URL=http://smart-city-iot-agent-bunkerm:4043 + - IOTA_DEFAULT_RESOURCE=/ + - IOTA_DEFAULT_APIKEY=smartcity-bunkerm + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:4043/version || exit 1"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 60s networks: smartcity-shared: diff --git a/docker-compose.orion-ld.yml b/docker-compose.orion-ld.yml index 7e1a91ed..e030b54c 100644 --- a/docker-compose.orion-ld.yml +++ b/docker-compose.orion-ld.yml @@ -1,23 +1,19 @@ -# Orion-LD Context Broker for Smart City Digital Twin +# Orion Context Broker - Using existing MongoDB # Usage: docker compose -f docker-compose.yml -f docker-compose.orion-ld.yml up -d - version: '3.8' services: orion-ld: - image: quay.io/fiware/orion-ld:latest + image: fiware/orion-ld:latest container_name: smart-city-orion-ld restart: unless-stopped networks: - - smartcity-shared - - traefik-public - ports: - - "1026:1026" - environment: - - ORION_PORT=1026 - - ORIONLD_MONGO_HOST=smart-city-mongodb - - ORIONLD_MONGO_PORT=27017 - command: orionld -fg -multiservice -dbhost smart-city-mongodb -dbport 27017 + smartcity-shared: + aliases: + - orion-ld + - smart-city-orion-ld + traefik-public: + command: -dbhost smart-city-mongodb -db orion healthcheck: test: ["CMD-SHELL", "curl -f http://localhost:1026/version || exit 1"] interval: 30s diff --git a/session_resume_2026-05-06.md b/session_resume_2026-05-06.md index c4ed8301..d763b425 100644 --- a/session_resume_2026-05-06.md +++ b/session_resume_2026-05-06.md @@ -1,107 +1,129 @@ # Session Resume - Smart City Digital Twin Martinique (2026-05-06) - FINAL ## Objectif -Finaliser l'installation et l'accessibilité du Smart City Digital Twin Martinique, spécifiquement la mise en service des flux de données : -**MQTT → IoT-Agent → Context Brokers (Stellio) → QuantumLeap → CrateDB → Grafana** +Finaliser l'installation et l'accessibilité du Smart City Digital Twin Martinique, spécifiquement la mise en service du flux complet : Simulator → 3 IoT-Agents → Orion-LD → QuantumLeap → CrateDB → Grafana. -## État des conteneurs (17h00) -- **smart-city-iot-agent** : Up (port 4041) - Service et devices créés ✅ -- **smart-city-quantumleap** : Up (port 8668) - FIXÉ ✅ (variables CRATE_HOST/PORT au lieu de QL_CRATEDB_*) -- **smart-city-cratedb** : Up (ports 5432/4200) - Accessible ✅ -- **smart-city-grafana** : Up (port 3001) - Prêt mais datasource CrateDB à finaliser ⚠️ -- **stellio-api-gateway** : Up (port 8080) - Mais retourne 404 sur les entités ❌ -- **smart-city-simulator** : Up - Modifié pour publier au format IoT-Agent ✅ +## État d'avancement (17h30) -## Travail accompli -1. **Diagramme de flux** mis à jour avec IoT-Agent, QuantumLeap, CrateDB (commit+push) ✅ -2. **IoT-Agent** : Service et devices créés (HTTP 201) ✅ -3. **Simulateur** : Ajout de `publish_iot_agent` et variable `ENABLE_IOT_AGENT` ✅ -4. **QuantumLeap** : - - **BUG FIX** : Changé `QL_CRATEDB_HOST/PORT` vers `CRATE_HOST/PORT` (attendu par QuantumLeap) ✅ - - Commit & push effectués ✅ -5. **CrateDB** : Accessible via port 4200 (SQL interface) ✅ -6. **Grafana** : Accessible, mais datasource CrateDB nécessite mise en réseau ⚠️ -7. **Session resume** mis à jour ✅ +### ✅ Réalisé +1. **3 IoT-Agents déployés** : Un par broker MQTT (EMQX:4041, Mosquitto:4042, BunkerM:4043) +2. **Orion-LD opérationnel** : Port 1026, connecté à MongoDB existant +3. **QuantumLeap corrigé** : Variables CRATE_HOST/PORT (plus de QL_CRATEDB_*) +4. **CrateDB ↔ Grafana** : Datasource "CrateDB-SmartCity" (ID: 23) ajoutée +5. **Flux validé (logs)** : IoT-Agent → Orion-LD (message "Value updated successfully") +6. **Diagrammes mis à jour** : data-flow-diagram.md & .html (3 IoT-Agents architecture) +7. **Git commit & push** : Tous les changements sur Gitea -## Blocages rencontrés -1. **Flux MQTT → IoT-Agent → Stellio** : - - IoT-Agent reçoit le message MQTT mais Stellio retourne 404 - - Problème probable : IoT-Agent ne transmet pas correctement à Stellio (timeout/connexion) +### ❌ Problèmes en cours +1. **Orion-LD vide** : `curl http://localhost:1026/v2/entities` retourne `[]` malgré les logs IoT-Agent positifs + - Cause probable : Problème de résolution de nom (logs montrent `orion-ld` au lieu de `smart-city-orion-ld`) + - Action : Corriger les aliases réseau dans docker-compose.orion-ld.yml (FAIT) +2. **Stellio** : Pas encore de flux de données (abonnement Orion-LD → Stellio à configurer) +3. **Simulateur** : Doit publier sur le topic avec préfixe `json/` (ex: `json/smartcity-api-key/airquality_001/attrs`) -2. **QuantumLeap** : - - FIXÉ : Utilisation des bonnes variables d'environnement (`CRATE_HOST`, `CRATE_PORT`) - - Endpoint API : `/v2/op/notify` (pour recevoir les notifications) - - Test manuel de notification à faire +## Architecture finale (3 IoT-Agents) -3. **Stellio** : - - POST /ngsi-ld/v1/entities retourne 405 (method not allowed) - - GET /ngsi-ld/v1/entities retourne 404 (pas d'entités) - - Recommandation : Utiliser Orion-LD ou FROST-Server à la place - -4. **Grafana ← CrateDB** : - - Grafana n'est pas sur le même réseau Docker que CrateDB (`smartcity-shared`) - - Le port 5432 (PostgreSQL) timeout depuis Grafana - - Solution : Ajouter `networks: - smartcity-shared` au service Grafana dans `docker-compose.yml` - -## Prochaines étapes -1. **Grafana** : Finaliser les dashboards (en attendant que CrateDB soit connecté) - - Accéder à https://grafana.digitribe.fr - - Créer un dashboard "Smart City Overview" avec les données InfluxDB existantes - - Une fois CrateDB connecté : ajouter panels "Air Quality", "Traffic Flow", etc. - -2. **QuantumLeap** : Tester avec une notification NGSI simulée - ```bash - docker exec smart-city-quantumleap curl -X POST http://localhost:8668/v2/op/notify \ - -H 'Content-Type: application/json' \ - -d '{"subscriptionId": "test", "data": [{...}]}' - ``` - -3. **Flux complet** : Utiliser Orion-LD au lieu de Stellio - - Déployer Orion-LD avec `-dbhost smart-city-mongodb` - - Créer une subscription Orion-LD → QuantumLeap - -4. **Pulsar Manager** : Résoudre le login admin (toujours inaccessible) - -## Commandes utiles -```bash -# Vérifier IoT-Agent -curl -s http://localhost:4041/iot/services -H 'FIWARE-Service: smartcity' -H 'FIWARE-ServicePath: /' -curl -s http://localhost:4041/iot/devices -H 'FIWARE-Service: smartcity' -H 'FIWARE-ServicePath: /' - -# Tester QuantumLeap (via Traefik) -curl -k https://quantum-leap.digitribe.fr/v2/types -w "\nHTTP %{http_code}\n" - -# Tester Stellio -curl -s http://localhost:8080/ngsi-ld/v1/entities -H "Accept: application/ld+json" -w "\nHTTP %{http_code}\n" - -# Publier un message MQTT pour IoT-Agent -mosquitto_pub -h localhost -p 11883 -t "smartcity-api-key/airquality_001/attrs" \ - -m '{"NO2": 50.5, "temperature": 30.0, "humidity": 90.0}' - -# Accéder à Grafana -https://grafana.digitribe.fr (admin / Digitribe972) - -# Vérifier CrateDB -docker exec smart-city-cratedb crash -c "SELECT * FROM quantumleap.etairqualityobserved LIMIT 5;" +``` +Simulateur (Python) + ↓ (publie sur 3 brokers avec format IoT-Agent) +┌─────────────┬─────────────┬─────────────┐ +│ EMQX │ Mosquitto │ BunkerM │ +│ port 11883 │ port 1883 │ port 1900 │ +└──────┬──────┴──────┬──────┴──────┬──────┘ + ↓ ↓ ↓ +┌─────────────┬─────────────┬─────────────┐ +│iot-agent-emqx│iot-agent- │iot-agent- │ +│(port 4041) │mosquitto │bunkerm │ +│ │(port 4042) │(port 4043) │ +└──────┬──────┴──────┬──────┴──────┬──────┘ + └──────────────┴──────────────┘ + ↓ + Orion-LD (port 1026) + (http://smart-city-orion-ld:1026) + ↓ + Subscription (ID: 69fbb09af55b82cad2a38008) + Forward to QuantumLeap + ↓ + QuantumLeap (port 8668) + ↓ + CrateDB (ports 5432/4200) + ↓ + Grafana (port 3001) ``` -## Fichiers modifiés -- `simulator.py` : Ajout `publish_iot_agent`, variable `ENABLE_IOT_AGENT` -- `docker-compose.iot-agent.yml` : Configuration EMQX et Stellio -- `docker-compose.quantumleap.yml` : FIX variables `CRATE_HOST/PORT` -- `data-flow-diagram.md` et `.html` : Mise à jour architecture -- `session_resume_2026-05-06.md` : Ce fichier +## Configuration des IoT-Agents + +### Services enregistrés (pour chaque IoT-Agent) +```json +{ + "apikey": "smartcity-api-key", + "cbroker": "http://smart-city-orion-ld:1026", + "resource": "/", + "type": "AirQualityObserved", + "service": "smartcity", + "subservice": "/" +} +``` + +### Devices enregistrés +- **Device ID** : airquality_001 +- **Entity Name** : urn:ngsi-ld:AirQualityObserved:airquality_001 +- **Attributes** : NO2 (Number), temperature (Number), humidity (Number) + +## Sous-domaines (Traefik) +- `iot-agent-emqx.digitribe.fr` → Port 4041 +- `iot-agent-mosquitto.digitribe.fr` → Port 4042 +- `iot-agent-bunkerm.digitribe.fr` → Port 4043 +- `orion-ld.digitribe.fr` → Port 1026 +- `quantum-leap.digitribe.fr` → Port 8668 +- `grafana.digitribe.fr` → Port 3001 + +## Fichiers modifiés et commités +1. `docker-compose.iot-agent.yml` : 3 instances IoT-Agent +2. `docker-compose.orion-ld.yml` : Orion-LD avec MongoDB +3. `docker-compose.quantumleap.yml` : Variables CRATE_HOST/PORT +4. `simulator.py` : Publication sur 3 brokers +5. `data-flow-diagram.md` : Diagramme Mermaid mis à jour +6. `data-flow-diagram.html` : Version HTML pour Gitea +7. `session_resume_2026-05-06.md` : Ce fichier + +## Commandes utiles pour debug + +### Vérifier IoT-Agent +```bash +curl -s http://localhost:4041/iot/devices -H 'FIWARE-Service: smartcity' +docker logs smart-city-iot-agent-emqx --tail 50 | grep -i "update\|orion\|error" +``` + +### Vérifier Orion-LD +```bash +curl -s http://localhost:1026/v2/entities?type=AirQualityObserved +docker logs smart-city-orion-ld --tail 50 +``` + +### Tester le flux complet +```bash +# Publication MQTT (avec préfixe json/) +mosquitto_pub -h localhost -p 11883 \ + -t "json/smartcity-api-key/airquality_001/attrs" \ + -m '{"NO2": 70.5, "temperature": 31.0, "humidity": 88.0}' + +# Attendre 10s puis vérifier Orion-LD +sleep 10 && curl -s http://localhost:1026/v2/entities +``` + +## Prochaines étapes +1. **Valider le flux** : Vérifier qu'Orion-LD reçoit les entités (corriger le nom d'hôte) +2. **Configurer Stellio** : Abonnement Orion-LD → Stellio (port 8080) +3. **Créer les dashboards Grafana** : Utiliser la datasource CrateDB-SmartCity +4. **Mettre à jour le simulateur** : S'assurer qu'il publie sur le bon topic (`json/...`) +5. **Tester avec les 3 brokers** : Valider EMQX, Mosquitto et BunkerM ## Notes importantes -- Le simulateur publie maintenant sur le topic `smartcity-api-key/{device_id}/attrs` via EMQX -- IoT-Agent est configuré pour transmettre à Stellio (cbroker: http://stellio-api-gateway:8080) -- QuantumLeap est maintenant correctement configuré avec CrateDB -- CrateDB a des données de test insérées manuellement -- Grafana a besoin que le réseau `smartcity-shared` soit ajouté à son service +- L'IoT-Agent écoute les topics avec préfixe `json/` (ex: `$share/json//+/+/attrs/+`) +- Le simulateur doit publier sur `json/smartcity-api-key/{device_id}/attrs` +- Pour Stellio, utiliser l'URL : `http://stellio-api-gateway:8080/ngsi-ld/v1/entityOperations/upsert` +- QuantumLeap utilise CrateDB avec le schéma `quantumleap` -## Pour finaliser (prochaine session) -1. Ajouter `networks: - smartcity-shared` à Grafana dans `docker-compose.yml` -2. Connecter CrateDB comme datasource Postgres dans Grafana -3. Créer les dashboards Grafana pour Smart City -4. Tester le flux complet avec Orion-LD (plus stable que Stellio) -# Network Audit - All containers on smartcity-shared (192.168.192.0/20) ✅ +--- +*Dernière mise à jour : 06 Mai 2026, 17h30* \ No newline at end of file