# Smart City Digital Twin - Data Flow Diagram (Updated 2026-05-06) ## Architecture évoluée : 1 IoT-Agent par broker MQTT ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ Smart City Simulator (Python) │ │ Publie sur 3 brokers MQTT avec format IoT-Agent JSON │ └──────────┬────────────────────┬──────────────────────┬───────────────────┘ │ │ │ ▼ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ EMQX Broker │ │ Mosquitto Broker │ │ BunkerM Broker │ │ (port 11883) │ │ (port 1883) │ │ (port 1900) │ │ Topic: smart- │ │ Topic: smart- │ │ Topic: smart- │ │ city-api-key/ │ │ city-api-key/ │ │ city-api-key/ │ │ {id}/attrs │ │ {id}/attrs │ │ {id}/attrs │ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │ │ │ ▼ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ IoT-Agent-EMQX │ │IoT-Agent-Mosquitto│ │IoT-Agent-BunkerM │ │ Port: 4041 │ │ Port: 4042 │ │ Port: 4043 │ │ Apikey: smart- │ │ Apikey: smart- │ │ Apikey: smart- │ │ city-api-key │ │ city-api-key │ │ city-api-key │ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │ │ │ └───────────────────────┴──────────────────────┘ │ ▼ ┌─────────────────────┐ │ Orion-LD Context │ │ Broker (port 1026)│ │ MongoDB backend │ └─────────┬───────────┘ │ │ Subscription (id: 69fbb09af55b82cad2a38008) │ Forward to QuantumLeap ▼ ┌─────────────────────┐ │ QuantumLeap │ │ (port 8668) │ │ /v2/op/notify │ └─────────┬───────────┘ │ ▼ ┌─────────────────────┐ │ CrateDB │ │ (ports 5432/4200)│ │ DB: quantumleap │ └─────────┬───────────┘ │ ▼ ┌─────────────────────┐ │ Grafana │ │ (port 3001) │ │ Datasource: │ │ CrateDB-SmartCity│ └─────────────────────┘ ``` ## Flux de données (Step-by-step) 1. **Simulator** publie sur 3 brokers MQTT (EMQX:11883, Mosquitto:1883, BunkerM:1900) - Topic: `smartcity-api-key/{device_id}/attrs` - Format: `{"NO2": 45.5, "temperature": 26.0, "humidity": 70.0}` 2. **3 IoT-Agents** (un par broker) reçoivent les messages - iot-agent-emqx (port 4041) ← EMQX - iot-agent-mosquitto (port 4042) ← Mosquitto - iot-agent-bunkerm (port 4043) ← BunkerM - Chaque IoT-Agent a le service `smartcity-api-key` configuré - Chaque IoT-Agent a le device `airquality_001` enregistré 3. **Orion-LD** reçoit les entités NGSI-v2 - URL: `http://smart-city-orion-ld:1026` - Entité: `urn:ngsi-ld:AirQualityObserved:airquality_001` - Type: `AirQualityObserved` 4. **Subscription Orion-LD → QuantumLeap** - ID: `69fbb09af55b82cad2a38008` - Description: "Forward AirQualityObserved to QuantumLeap" - Notify URL: `http://smart-city-quantumleap:8668/v2/op/notify` - Attrs: NO2, temperature, humidity 5. **QuantumLeap** stocke dans **CrateDB** - Table: `quantumleap.etairqualityobserved` - Colonnes: entity_id, time_index, NO2, temperature, humidity 6. **Grafana** visualise les données - Datasource: `CrateDB-SmartCity` (ID: 23) - URL: `smart-city-cratedb:5432` - Database: `quantumleap` ## Services et Devices (provisionnés) ### IoT-Agent-EMQX (port 4041) - Service: `smartcity-api-key` → Orion-LD (`http://smart-city-orion-ld:1026`) - Device: `airquality_001` → `urn:ngsi-ld:AirQualityObserved:airquality_001` ### IoT-Agent-Mosquitto (port 4042) - Service: `smartcity-api-key` → Orion-LD (`http://smart-city-orion-ld:1026`) - Device: `airquality_001` → `urn:ngsi-ld:AirQualityObserved:airquality_001` ### IoT-Agent-BunkerM (port 4043) - Service: `smartcity-api-key` → Orion-LD (`http://smart-city-orion-ld:1026`) - Device: `airquality_001` → `urn:ngsi-ld:AirQualityObserved:airquality_001` ## Sous-domaines (Traefik) - `iot-agent-emqx.digitribe.fr` → IoT-Agent-EMQX (port 4041) - `iot-agent-mosquitto.digitribe.fr` → IoT-Agent-Mosquitto (port 4042) - `iot-agent-bunkerm.digitribe.fr` → IoT-Agent-BunkerM (port 4043) - `orion-ld.digitribe.fr` → Orion-LD (port 1026) - `quantum-leap.digitribe.fr` → QuantumLeap (port 8668) - `grafana.digitribe.fr` → Grafana (port 3001) ## Test du flux complet ```bash # 1. Publier un message MQTT (simuler le simulateur) mosquitto_pub -h localhost -p 11883 -t "smartcity-api-key/airquality_001/attrs" \ -m '{"NO2": 50.5, "temperature": 30.0, "humidity": 90.0}' # 2. Vérifier qu'Orion-LD a reçu l'entité curl -s http://localhost:1026/v2/entities -w "\nHTTP %{http_code}\n" # 3. Vérifier que QuantumLeap a reçu la notification docker logs smart-city-quantumleap --tail 20 | grep -i "notify\|airquality" # 4. Vérifier CrateDB docker exec smart-city-cratedb crash -c "SELECT * FROM quantumleap.etairqualityobserved LIMIT 5;" # 5. Vérifier Grafana curl -s http://localhost:3001/api/datasources -u admin:Digitribe972 | jq '.[] | select(.type=="postgres") | .name' ``` ## Fichiers modifiés (2026-05-06) - `docker-compose.iot-agent.yml` : 3 instances IoT-Agent (emqx, mosquitto, bunkerm) - `docker-compose.orion-ld.yml` : Orion-LD avec MongoDB existant - `docker-compose.quantumleap.yml` : Variables CRATE_HOST/PORT (fix) - `simulator.py` : Publication sur 3 brokers avec format IoT-Agent - `data-flow-diagram.md` : Ce fichier (mis à jour)