Files
smart-city-digital-twin-mar…/data-flow-diagram.md
Eric FELIXINE a05e13c30c feat(lorawan): ajout ChirpStack et The Things Stack
- Skills créés: chirpstack-lorawan, the-things-stack-lorawan
- docker-compose.chirpstack.yml: ChirpStack derrière Traefik
- docker-compose.the-things-stack.yml: TTS derrière Traefik
- data-flow-diagram.md: mise à jour avec LoRaWAN
- DOCKER-ARCHITECTURE: ajout conteneurs LoRaWAN
- Subdomaines Traefik: chirpstack, tts

Skills créés dans ~/.hermes/skills/iot/:
- chirpstack-lorawan
- the-things-stack-lorawan
2026-05-12 11:29:30 -04:00

257 lines
16 KiB
Markdown

# Smart City Digital Twin - Data Flow Diagram (Updated 2026-05-12)
## Architecture complète avec LoRaWAN
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Smart City Simulator (Python) │
│ Publie sur 3 brokers MQTT + REST vers OpenRemote │
└──────────┬────────────────────┬──────────────────────┬───────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ EMQX Broker │ │ Mosquitto Broker │ │ BunkerM Broker │
│ (port 11883) │ │ (port 1883) │ │ (port 1900) │
└────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘
│ │ │
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ IoT-Agent-EMQX │ │IoT-Agent-Mosquitto│ │IoT-Agent-BunkerM │
│ Port: 4041 │ │ Port: 4042 │ │ Port: 4043 │
└────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘
│ │ │
└───────────────────────┴──────────────────────┘
┌─────────────────────┐
│ Orion-LD Context │
│ Broker (port 1026)│
│ MongoDB backend │
└─────────┬───────────┘
│ Subscription → QuantumLeap
┌─────────────────────┐
│ QuantumLeap │
│ (port 8668) │
└─────────┬───────────┘
┌─────────────────────┐
│ CrateDB │
│ (ports 5432/4200)│
└─────────┬───────────┘
┌─────────────────────┐
│ Grafana │
│ (port 3001) │
└─────────────────────┘
═══════════════════════════════════════════════════════════════════════════════
LoRaWAN Layer
═══════════════════════════════════════════════════════════════════════════════
┌──────────────────┐ ┌──────────────────┐
│ Gateway LoRaWAN │ UDP │ Gateway LoRaWAN │
│ (EU868) │ 1700 │ (EU868) │
└────────┬─────────┘ └────────┬─────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ ChirpStack LoRaWAN Network Server │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ chirpstack │ │ gateway-bridge │ │ rest-api │ │
│ │ (port 8080) │ │ (UDP 1700) │ │ (port 8090) │ │
│ └────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ PostgreSQL │ │ Redis │ │ Mosquitto (MQTT) │ │
│ │ (chirpstack DB) │ │ (cache) │ │ (port 1883) │ │
│ └──────────────────┘ └──────────────────┘ └────────┬─────────┘ │
└──────────────────────────────────────────────────────┬─────────────────────┘
┌──────────────────┐
│ EMQX Broker │
│ (integration) │
└──────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ The Things Stack LoRaWAN Network Server │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ tts-stack │ │ tts-postgres │ │ tts-redis │ │
│ │ (port 1885) │ │ (TTN DB) │ │ (cache) │ │
│ └────────┬─────────┘ └──────────────────┘ └──────────────────┘ │
│ │ │
│ │ UDP 1700 (gateways) │
│ │ MQTT 1883 (events) │
│ │ HTTP 1884 (API) │
│ │ HTTP 1885 (Console) │
└───────────┬─────────────────────────────────────────────────────────────────┘
┌──────────────────┐
│ EMQX Broker │
│ (integration) │
└──────────────────┘
═══════════════════════════════════════════════════════════════════════════════
OpenRemote Manager
═══════════════════════════════════════════════════════════════════════════════
┌─────────────────────────────────────────────────────────────────────────────┐
│ OpenRemote Manager (Artemis MQTT) │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Manager UI │ │ Keycloak │ │ PostgreSQL │ │
│ │ (port 8080) │ │ (port 8080) │ │ (port 5432) │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
│ │
│ Assets IOTSensor avec agentLink MQTT + location (GeoJSON Point) │
│ Assets visualisés sur la carte Martinique (mapsettings.json) │
└─────────────────────────────────────────────────────────────────────────────┘
```
## 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
3. **Orion-LD** reçoit les entités NGSI-v2
- URL: `http://smart-city-orion-ld:1026`
- Entité: `urn:ngsi-ld:AirQualityObserved:airquality_001`
4. **Subscription Orion-LD → QuantumLeap**
- Notify URL: `http://smart-city-quantumleap:8668/v2/op/notify`
5. **QuantumLeap** stocke dans **CrateDB**
- Table: `quantumleap.etairqualityobserved`
6. **Grafana** visualise les données
- Datasource: `CrateDB-SmartCity`
7. **ChirpStack** gère les gateways et devices LoRaWAN
- Gateway Bridge (UDP 1700) → ChirpStack → MQTT → EMQX
- REST API (port 8090) pour gestion des devices/applications
8. **The Things Stack** gère les gateways et devices LoRaWAN (alternative)
- Gateway (UDP 1700) → TTS Stack → MQTT/REST API
- Console web (port 1885)
9. **OpenRemote** affiche les assets sur la map
- Assets IOTSensor avec location GeoJSON
- Agents MQTT pour mise à jour des valeurs
## Sous-domaines (Traefik)
### IoT Agents & Brokers
- `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)
### ChirpStack LoRaWAN
- `chirpstack.digitribe.fr` → ChirpStack Console (port 8080)
- `chirpstack-api.digitribe.fr` → ChirpStack REST API (port 8090)
- `chirpstack-ws.digitribe.fr` → Gateway Bridge WebSocket (port 3001)
### The Things Stack LoRaWAN
- `tts.digitribe.fr` → TTS Console (port 1885)
- `tts-api.digitribe.fr` → TTS REST API (port 1884)
### OpenRemote
- `openremote.digitribe.fr` → OpenRemote Manager (port 8080)
## 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)