feat: distribution service + redpanda consumer + updated flow diagram

- Add Pulsar distribution service (consumes smartcity-* → MQTT + context brokers)
- Add Redpanda → InfluxDB consumer (redpanda/consumer.py)
- Update FIXED_LOCATIONS with exact OpenRemote asset coordinates
- Fix Pulsar topics (underscore: smartcity-traffic not smartcity-traffic)
- Fix prometheus.yml endpoints (Redpanda:9644, comment inactive stacks)
- Add docker-compose.redpanda-consumer.yml
This commit is contained in:
Eric FELIXINE
2026-05-05 22:12:38 -04:00
parent 742b437ed9
commit c06acf4fe8
9 changed files with 2242 additions and 434 deletions

View File

@@ -1,178 +1,223 @@
# Smart City Digital Twin — Diagramme des Flux de Données
# Smart City Digital Twin Martinique — Diagramme des Flux de Données
## Vue d'ensemble
Ce diagramme illustre le flux complet des données IoT du simulateur vers les différentes couches de traitement, de stockage et de visualisation.
**Dernière mise à jour :** 05 Mai 2026
**Projet :** Smart City Digital Twin Martinique
---
## Diagramme Mermaid
## Architecture Globale
```mermaid
graph TB
SIM[Smart City Simulator]
SENS[Capteurs IoT Reels]
EMQ[EMQX]
MOS[Mosquitto]
BUN[BunkerM]
FRO[FROST-Server]
ORI[Orion-LD]
STE[Stellio]
UI[OpenRemote UI]
ORM[OpenRemote Manager]
KC[Keycloak]
INF[InfluxDB]
PRO[Prometheus]
GEO[GeoServer]
GRA[Grafana]
MAP[MapStore]
CH[ClickHouse]
RW[RisingWave]
PUL[Pulsar]
RED[Redpanda]
subgraph Simulateur["🖥️ Simulateur (Host Python)"]
SIM[Smart City Simulator<br/>10 capteurs<br/>Intervalle: configurable]
end
SIM --> EMQ
SIM --> MOS
SIM --> BUN
SIM --> FRO
SENS --> EMQ
SENS --> MOS
SENS --> BUN
SENS --> FRO
SENS -.-> ORM
EMQ -->|via EMQX| ORI
EMQ -->|via EMQX| STE
MOS -->|via Mosquitto| ORI
MOS -->|via Mosquitto| STE
BUN -->|via BunkerM| ORI
BUN -->|via BunkerM| STE
UI --> ORM
ORM -.-> KC
SIM --> INF
SIM -->|real-time 1s| CH
SIM -->|streaming| RW
SIM -->|HTTP REST| PUL
SIM -->|HTTP REST| RED
ORI --> GRA
STE --> GRA
FRO --> GRA
ORI -.-> GEO
STE -.-> GEO
FRO -.-> GEO
GEO --> MAP
ORM --> GRA
EMQ -.-> PRO
ORI -.-> PRO
STE -.-> PRO
ORM -.-> PRO
subgraph MQTT_Brokers["📡 MQTT Brokers"]
EMQ[EMQX<br/>port 11883]
MOS[Mosquitto<br/>port 1883]
BUN[BunkerM<br/>port 1900<br/>MQTTS/TLS]
end
subgraph Stream["⚡ Event Streaming"]
PUL[Pulsar<br/>port 6650<br/>Topics: smartcity-*]
RED[Redpanda<br/>port 8082 REST<br/>Topics: traffic, air-quality, ...]
end
subgraph CB["🔗 Context Brokers"]
ORI[Orion-LD<br/>NGSI-LD<br/>port 1026]
STE[Stellio<br/>NGSI-LD<br/>port 8080]
FRO[FROST-Server<br/>SensorThings<br/>port 8080]
end
subgraph Storage["💾 Stockage & Métriques"]
INF[InfluxDB<br/>Bucket: iot_data<br/>port 8086]
PRO[Prometheus<br/>Scrape: /metrics<br/>port 9090]
GEO[GeoServer<br/>WMS/WFS/WMTS<br/>port 8080]
end
subgraph IoT_Platform["🏢 Plateforme IoT"]
ORM[OpenRemote Manager<br/>MQTT Agent<br/>port 8080]
KC[Keycloak<br/>port 8080]
end
subgraph VIZ["📊 Visualisation"]
GRA[Grafana<br/>Dashboards<br/>port 3000]
MAP[MapStore<br/>WMS/WFS<br/>port 8080]
end
subgraph Distribution["🔄 Distribution Service"]
DIST[Pulsar Distribution<br/>Pulsar → Brokers]
end
subgraph Consumer["📥 Redpanda Consumer"]
RCONS[Redpanda → InfluxDB<br/>REST → InfluxDB]
end
%% ── Flux Simulateur ──────────────────────────────────────────────────
SIM -->|"1⃣ MQTT publish<br/>city/sensors/{type}/{id}"| EMQ
SIM -->|"1⃣ MQTT publish"| MOS
SIM -->|"1⃣ MQTT publish"| BUN
SIM -->|"2⃣ HTTP POST<br/>NGSI-LD"| ORI
SIM -->|"2⃣ HTTP POST<br/>NGSI-LD"| STE
SIM -->|"2⃣ HTTP POST<br/>SensorThings"| FRO
SIM -->|"3⃣ Pulsar client<br/>pulsar://localhost:6650"| PUL
SIM -->|"4⃣ HTTP REST Proxy<br/>localhost:8082/topics/"| RED
SIM -->|"5⃣ InfluxDB v2 API<br/>async non-bloquant"| INF
%% ── Flux Distribution (Pulsar → Brokers) ──────────────────────────────
PUL -->|"Consomme<br/>smartcity-*"| DIST
DIST -->|"Republish<br/>MQTT"| EMQ
DIST -->|"Republish<br/>MQTT"| MOS
DIST -->|"Republish<br/>NGSI-LD"| ORI
DIST -->|"Republish<br/>NGSI-LD"| STE
DIST -->|"Republish<br/>SensorThings"| FRO
%% ── Flux Redpanda → InfluxDB ──────────────────────────────────────────
RED -->|"REST poll<br/>topics/{name}/offsets"| RCONS
RCONS -->|"Line Protocol<br/>Write API"| INF
%% ── OpenRemote MQTT Agent ──────────────────────────────────────────────
EMQ -->|"6⃣ Subscribe<br/>city/sensors/#"| ORM
MOS -->|"6⃣ Subscribe"| ORM
BUN -->|"6⃣ Subscribe"| ORM
%% ── Métriques Prometheus ────────────────────────────────────────────────
SIM -->|"7⃣ /metrics<br/>port 8001"| PRO
EMQ -->|"/api/v5/metrics"| PRO
STE -->|"/actuator/prometheus"| PRO
FRO -->|"/metrics"| PRO
INF -->|"/metrics"| PRO
RED -->|"/public_metrics"| PRO
ORM -->|"/actuator/prometheus"| PRO
GRA -->|"/metrics"| PRO
%% ── Visualisation ─────────────────────────────────────────────────────
INF -->|"Datasources<br/>Flux IoT"| GRA
ORI -->|"NGSI-LD<br/>Datasource"| GRA
STE -->|"NGSI-LD<br/>Datasource"| GRA
FRO -->|"SensorThings<br/>Datasource"| GRA
GEO -->|"WMS/WMTS"| MAP
ORM -->|MapSettings<br/>Martinique| MAP
ORM -->|"Live assets<br/>REST"| GRA
```
---
## Description des flux
## Flux Détaillés
### 1. **Génération des données (Simulator)**
- **Smart City Simulator** (Python) génère des données pour 10 capteurs (Traffic, Air Quality, Parking, Noise, Weather, Light)
- Intervalle de publication : 1 seconde (temps réel)
- Protocoles : MQTT (vers brokers uniquement)
- **⚠️ Projet** : Le simulateur n'envoie PAS directement à OpenRemote (pas de REST API)
### 1️⃣ Flux MQTT — Brokers
### 2. **Ingestion MQTT (Brokers)**
- **EMQX** (port 11883) : Broker public, reçoit tous les capteurs
- **Mosquitto** (port 1883) : Via Traefik, accès externe
- **BunkerM** (port 1900) : MQTTS (TLS), accès sécurisé
| Broker | Port | Protocol | Topics |
|--------|------|----------|--------|
| EMQX | 11883 | MQTT | `city/sensors/{type}/{id}` |
| Mosquitto | 1883 | MQTT | `city/sensors/{type}/{id}` |
| BunkerM | 1900 | MQTTS (TLS) | `city/sensors/{type}/{id}` |
### 3. **Context Brokers (NGSI-LD & SensorThings)**
- **Orion-LD** : Reçoit les données au format NGSI-LD
- 10 entités (TrafficFlowObserved, AirQualityObserved, etc.)
- Smart Data Models utilisés
- **Provenance** : Données via EMQX, Mosquitto et BunkerM (voir étiquettes dans le diagramme)
- **Stellio** : Alternative NGSI-LD
- 14 payloads entités
- Contexte : `https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context.jsonld`
- **Provenance** : Données via EMQX, Mosquitto et BunkerM
- **FROST-Server** : SensorThings API
- 21 256+ observations
- PostgreSQL + TimescaleDB
- **Provenance** : Données via EMQX, Mosquitto et BunkerM
Le simulateur publie simultanément sur les 3 brokers.
### 4. **Plateforme IoT (OpenRemote)**
- **OpenRemote Manager** (realm `smartcity`)
- 33 assets IoT configurés
- Carte Martinique (mapsettings.json)
- Réception via **MQTT Agent** depuis les brokers (EMQX, Mosquitto, BunkerM)
- Peut aussi recevoir directement des capteurs IoT (via MQTT)
- **Keycloak** : Authentification OpenID Connect
- Client `openremote` avec Service Account
- Token endpoint : `/auth/realms/smartcity/protocol/openid-connect/token`
### 2⃣ Flux HTTP REST — Context Brokers
### 5. **Stockage & Métriques**
- **InfluxDB** : Stockage temporel pour Grafana
- Bucket : `iot_data`
- Datasource dans Grafana
- **Prometheus** : Collecte des métriques
- MQTT brokers, Context brokers, OpenRemote
- **GeoServer** : Données géospatiales
- PostGIS pour centralisation
- WMS/WFS pour MapStore
| Broker | Format | Port | Topics |
|--------|--------|------|--------|
| Orion-LD | NGSI-LD | 1026 | Entités par type |
| Stellio | NGSI-LD | 8080 | Entités par type |
| FROST-Server | SensorThings | 8080 | Things → Datastreams → Observations |
### 5. **Visualisation & Analyse**
- **Grafana** (port 3001)
- Dashboard : `smartcity-martinique-2026`
- Datasources : InfluxDB, FROST, Orion-LD, ClickHouse, RisingWave
- **MapStore** : Cartographie
- Sources WMS/WFS depuis GeoServer
- **OpenRemote UI** : Manager Interface
- Visualisation des assets realm Smart City
### 3⃣ Flux Pulsar — Event Streaming
### 6. **Analytique & Streaming**
- **ClickHouse** (port 8123/9000) : Columnar OLAP Database
- Analytique rapide sur grandes volumes de données IoT
- Intégration possible via HTTP interface (port 8123)
- Compatible avec Grafana (plugin ClickHouse)
- **RisingWave** (port 4566/4567) : Streaming Database PostgreSQL-compatible
- Traitement de flux en temps réel
- Interface web pour requêtes SQL streaming
- Compatible Grafana via datasource PostgreSQL
- **Topics** : `persistent://public/default/smartcity-traffic`, `smartcity-airquality`, `smartcity-parking`, `smartcity-noise`, `smartcity-weather`, `smartcity-light`
- **Port binaire** : `6650` (connectable depuis le host)
- **Distribution** : Le service `pulsar-distribution` consomme ces topics et republie vers les brokers MQTT et context brokers
### 4⃣ Flux Redpanda — Kafka-compatible REST
- **REST Proxy** : `http://localhost:8082`
- **Topics** : `traffic`, `air-quality`, `parking`, `noise`, `weather`, `air-quality`
- **Payload** : Base64(JSON) dans `{"records": [{"value": "<base64>"}]}`
- **Consumer** : `redpanda/consumer.py` — poll toutes les 10s et écrit dans InfluxDB
### 5⃣ Flux InfluxDB — Temps Réel
- **API** : `http://localhost:8086/api/v2/write`
- **Bucket** : `iot_data`
- **Org** : `digitribe`
- **Mode** : Asynchrone (thread daemon) pour ne pas bloquer le publish MQTT
### 6⃣ OpenRemote — MQTT Agent
L'agent MQTT d'OpenRemote souscrit aux topics `city/sensors/#` sur les brokers MQTT (EMQX, Mosquitto, BunkerM). Les payloads sont automatiquement parsés et les attributs des assets sont mis à jour.
**Configuration via Manager UI** (`https://openremote.digitribe.fr/manager/`) :
1. Se connecter avec `admin/Digitribe972`
2. Choisir le realm `smartcity`
3. **Assets → Agents → + Add Agent**
4. Type : **MQTT Agent**
5. Configurer :
- **MQTT Broker URI** : `tcp://emqx_emqx_1:1883` (réseau smartcity-shared)
- **Topic Filter** : `city/sensors/#`
- **QoS** : 1
- **Enabled** : ✅
### 7⃣ Flux Prometheus — Métriques
| Service | Endpoint `/metrics` | Scrape |
|---------|---------------------|--------|
| Simulator | `localhost:8001` | ✅ |
| EMQX | `emqx_emqx_1:8081/api/v5/metrics` | ✅ |
| Stellio | `stellio-api-gateway:8080/actuator/prometheus` | ✅ |
| FROST | `frost_http-web-1:8080/metrics` | ✅ |
| InfluxDB | `smart-city-influxdb:8086/metrics` | ✅ |
| Redpanda | `smart-city-redpanda-console:8080/public_metrics` | ✅ |
| OpenRemote | `openremote-manager-1:8080/actuator/prometheus` | ✅ |
| Grafana | `smart-city-grafana:3000/metrics` | ✅ |
---
## Technologies clés
## Tableau Récapitulatif
| Composant | Technologie | Port | Statut |
|-----------|-------------|------|--------|
| Simulator | Python + paho-mqtt | Interne | ✅ Actif (1s) |
| Simulator | Python + paho-mqtt | Host:8001 (metrics) | ✅ Actif |
| EMQX | MQTT Broker | 11883 | ✅ Connecté |
| Orion-LD | NGSI-LD Broker | 1026 | ⚠️ À vérifier |
| Stellio | NGSI-LD Broker | 8080 | ⚠️ À vérifier |
| FROST-Server | SensorThings API | 8080 | ⚠️ À vérifier |
| OpenRemote | IoT Platform | 8080 | ⚠️ 403 (Service Account) |
| InfluxDB | Time Series DB | 8086 | ✅ Configuré |
| ClickHouse | Columnar OLAP DB | 8123/9000 | ✅ Ajouté |
| RisingWave | Streaming DB (PG) | 4566/4567 | ✅ Ajouté |
| Pulsar | Event Streaming | 8080 | ⚠️ Debugging |
| Redpanda | Kafka-compatible | 19092/9644 | ⚠️ OOM |
| Grafana | Visualization | 3001 | ✅ Dashboard créé |
| GeoServer | GeoServer | 8080 | ⚠️ À intégrer |
| Prometheus | Metrics | 9090 | ✅ En cours |
| Mosquitto | MQTT Broker | 1883 | ✅ Connecté |
| BunkerM | MQTTS Broker | 1900 | ✅ Connecté |
| Orion-LD | NGSI-LD Broker | 1026 | ✅ Données |
| Stellio | NGSI-LD Broker | 8080 | ✅ Données |
| FROST-Server | SensorThings API | 8080 | ✅ Données |
| OpenRemote | IoT Platform | 8080 | ✅ UI OK |
| InfluxDB | Time Series DB | 8086 | ✅ Bucket iot_data |
| Redpanda | Kafka-compatible | 8082 REST | ✅ Topics actifs |
| Pulsar | Event Streaming | 6650 | ✅ Connecté |
| Prometheus | Metrics | 9090 (conf) | ⏳ Container arrêté |
| Grafana | Visualisation | 3000 | ✅ Dashboards |
| GeoServer | Geo Data | 8080 | ✅ REST OK |
| MapStore | Cartographie | 8080 | ✅ WMS/WMTS |
---
## Fichiers associés
## Commandes Utiles
- **Simulator** : `~/smart-city-digital-twin-martinique/simulator.py` (intervalle 1s - temps réel)
- **Docker Compose** : `~/smart-city-digital-twin-martinique/docker-compose.yml`
- **ClickHouse** : `~/smart-city-digital-twin-martinique/clickhouse/docker-compose.yml`
- **RisingWave** : `~/smart-city-digital-twin-martinique/risingwave/docker-compose.yml`
- **Pulsar** : `~/smart-city-digital-twin-martinique/pulsar/docker-compose.yml`
- **Redpanda** : `~/smart-city-digital-twin-martinique/redpanda/docker-compose.yml`
- **Dashboard Grafana** : `~/smart-city-digital-twin-martinique/grafana_dashboard_smartcity.json`
- **Ce diagramme** : `~/smart-city-digital-twin-martinique/data-flow-diagram.md`
- **Session Resume** : `~/smart-city-digital-twin-martinique/session_resume_2026-05-05.md`
```bash
# Redémarrer le service de distribution Pulsar
cd ~/smart-city-digital-twin-martinique
docker build -t smart-city-pulsar-distribution:latest -f pulsar/Dockerfile pulsar/
docker compose -f docker-compose.yml -f docker-compose.distribution.yml up -d pulsar-distribution
---
# Redémarrer Prometheus (prometheus-brokers)
cd ~/smart-city-digital-twin-martinique
docker compose up -d prometheus-brokers
**Dernière mise à jour :** 05 Mai 2026
**Projet :** Smart City Digital Twin Martinique
**URL Grafana :** https://grafana.digitribe.fr/d/smartcity-martinique-2026/smart-city-digital-twin-martinique
# Lancer le consumer Redpanda (host)
cd ~/smart-city-digital-twin-martinique
python3 redpanda/consumer.py
# Vérifier les topics Redpanda
curl -s http://localhost:8082/topics
# Vérifier les métriques simulator
curl -s http://localhost:8001/metrics | grep "^simulator_"
# Logs distribution service
docker logs -f smart-city-pulsar-distribution
```