diff --git a/data-flow-diagram.md b/data-flow-diagram.md
index 7e768866..64e0e6c8 100644
--- a/data-flow-diagram.md
+++ b/data-flow-diagram.md
@@ -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
10 capteurs
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
port 11883]
+ MOS[Mosquitto
port 1883]
+ BUN[BunkerM
port 1900
MQTTS/TLS]
+ end
+ subgraph Stream["⚡ Event Streaming"]
+ PUL[Pulsar
port 6650
Topics: smartcity-*]
+ RED[Redpanda
port 8082 REST
Topics: traffic, air-quality, ...]
+ end
+
+ subgraph CB["🔗 Context Brokers"]
+ ORI[Orion-LD
NGSI-LD
port 1026]
+ STE[Stellio
NGSI-LD
port 8080]
+ FRO[FROST-Server
SensorThings
port 8080]
+ end
+
+ subgraph Storage["💾 Stockage & Métriques"]
+ INF[InfluxDB
Bucket: iot_data
port 8086]
+ PRO[Prometheus
Scrape: /metrics
port 9090]
+ GEO[GeoServer
WMS/WFS/WMTS
port 8080]
+ end
+
+ subgraph IoT_Platform["🏢 Plateforme IoT"]
+ ORM[OpenRemote Manager
MQTT Agent
port 8080]
+ KC[Keycloak
port 8080]
+ end
+
+ subgraph VIZ["📊 Visualisation"]
+ GRA[Grafana
Dashboards
port 3000]
+ MAP[MapStore
WMS/WFS
port 8080]
+ end
+
+ subgraph Distribution["🔄 Distribution Service"]
+ DIST[Pulsar Distribution
Pulsar → Brokers]
+ end
+
+ subgraph Consumer["📥 Redpanda Consumer"]
+ RCONS[Redpanda → InfluxDB
REST → InfluxDB]
+ end
+
+ %% ── Flux Simulateur ──────────────────────────────────────────────────
+ SIM -->|"1️⃣ MQTT publish
city/sensors/{type}/{id}"| EMQ
+ SIM -->|"1️⃣ MQTT publish"| MOS
+ SIM -->|"1️⃣ MQTT publish"| BUN
+ SIM -->|"2️⃣ HTTP POST
NGSI-LD"| ORI
+ SIM -->|"2️⃣ HTTP POST
NGSI-LD"| STE
+ SIM -->|"2️⃣ HTTP POST
SensorThings"| FRO
+ SIM -->|"3️⃣ Pulsar client
pulsar://localhost:6650"| PUL
+ SIM -->|"4️⃣ HTTP REST Proxy
localhost:8082/topics/"| RED
+ SIM -->|"5️⃣ InfluxDB v2 API
async non-bloquant"| INF
+
+ %% ── Flux Distribution (Pulsar → Brokers) ──────────────────────────────
+ PUL -->|"Consomme
smartcity-*"| DIST
+ DIST -->|"Republish
MQTT"| EMQ
+ DIST -->|"Republish
MQTT"| MOS
+ DIST -->|"Republish
NGSI-LD"| ORI
+ DIST -->|"Republish
NGSI-LD"| STE
+ DIST -->|"Republish
SensorThings"| FRO
+
+ %% ── Flux Redpanda → InfluxDB ──────────────────────────────────────────
+ RED -->|"REST poll
topics/{name}/offsets"| RCONS
+ RCONS -->|"Line Protocol
Write API"| INF
+
+ %% ── OpenRemote MQTT Agent ──────────────────────────────────────────────
+ EMQ -->|"6️⃣ Subscribe
city/sensors/#"| ORM
+ MOS -->|"6️⃣ Subscribe"| ORM
+ BUN -->|"6️⃣ Subscribe"| ORM
+
+ %% ── Métriques Prometheus ────────────────────────────────────────────────
+ SIM -->|"7️⃣ /metrics
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
Flux IoT"| GRA
+ ORI -->|"NGSI-LD
Datasource"| GRA
+ STE -->|"NGSI-LD
Datasource"| GRA
+ FRO -->|"SensorThings
Datasource"| GRA
+ GEO -->|"WMS/WMTS"| MAP
+ ORM -->|MapSettings
Martinique| MAP
+ ORM -->|"Live assets
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": ""}]}`
+- **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
+```
diff --git a/docker-compose.distribution.yml b/docker-compose.distribution.yml
index d1e815b0..d2e5b55a 100644
--- a/docker-compose.distribution.yml
+++ b/docker-compose.distribution.yml
@@ -4,25 +4,14 @@
services:
pulsar-distribution:
- build:
- context: ./pulsar
- dockerfile: Dockerfile
- container_name: smart-city-pulsar-distribution
- networks:
- - smartcity-shared
environment:
- - PULSAR_HOST=smart-city-pulsar
+ - PULSAR_HOST=pulsar
- PULSAR_PORT=6650
- EMQX_HOST=emqx_emqx_1
- MOSQUITTO_HOST=mosquitto-traefik
- ORION_URL=http://fiware-gis-quickstart-orion-1:1026
- STELLIO_URL=http://stellio-api-gateway:8080
- - FROST_URL=http://frost-api-8090:8080/FROST-Server/v1.1
- restart: unless-stopped
- depends_on:
- - smart-city-pulsar
- labels:
- - "traefik.enable=false"
+ - FROST_URL=http://frost_http-web-1:8080/FROST-Server/v1.1
networks:
smartcity-shared:
diff --git a/docker-compose.redpanda-consumer.yml b/docker-compose.redpanda-consumer.yml
new file mode 100644
index 00000000..a27ce120
--- /dev/null
+++ b/docker-compose.redpanda-consumer.yml
@@ -0,0 +1,29 @@
+# Redpanda → InfluxDB Consumer
+# Lit les topics Redpanda et écrit dans InfluxDB pour Grafana
+version: "3.8"
+
+services:
+ redpanda-consumer:
+ image: python:3.11-slim
+ container_name: smart-city-redpanda-consumer
+ restart: unless-stopped
+ command: >
+ sh -c "pip install requests && python3 /app/consumer.py"
+ volumes:
+ - ./redpanda/consumer.py:/app/consumer.py:ro
+ environment:
+ - INFLUX_URL=http://smart-city-influxdb:8086
+ - INFLUX_TOKEN=my-super-admin-token
+ - INFLUX_ORG=digitribe
+ - INFLUX_BUCKET=iot_data
+ networks:
+ - smartcity-shared
+ healthcheck:
+ test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://smart-city-redpanda:9644/public_metrics')"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+
+networks:
+ smartcity-shared:
+ external: true
diff --git a/prometheus.yml b/prometheus.yml
index f31952a9..d87fac2a 100644
--- a/prometheus.yml
+++ b/prometheus.yml
@@ -3,43 +3,93 @@ global:
evaluation_interval: 15s
scrape_configs:
- # Mosquitto MQTT Broker
- - job_name: 'mosquitto'
- static_configs:
- - targets: ['mosquitto-exporter:9234']
- scrape_interval: 10s
- # Orion-LD (FIWARE)
- - job_name: 'orion-ld'
+ # ── Simulator (host) ─────────────────────────────────────────────────────────
+ - job_name: 'simulator'
static_configs:
- - targets: ['fiware-gis-quickstart-orion-1:1026']
+ - targets: ['172.17.0.1:8001']
+ labels:
+ service: smart-city-simulator
+ environment: martinique
+
+ # ── EMQX ──────────────────────────────────────────────────────────────────
+ # EMQX v5 expose /api/v5/metrics (format Prometheus) — dispo via Traefik
+ # Activer dans EMQX: conf/api6 => metrics.enabled = true
+ # Note: endpoint non exposé publiquement par défaut → via smartcity-shared
+ # - job_name: 'emqx'
+ # metrics_path: '/api/v5/metrics'
+ # static_configs:
+ # - targets: ['emqx_emqx_1:8081']
+ # labels:
+ # service: emqx
+ # environment: martinique
+
+ # ── Mosquitto ─────────────────────────────────────────────────────────────
+ # Mosquitto n'a pas de /metrics natif → mosquitto_exporter (non déployé)
+
+ # ── BunkerM ──────────────────────────────────────────────────────────────
+ # BunkerM : vérifier si /metrics est exposé
+
+ # ── Stellio ───────────────────────────────────────────────────────────────
+ # Stellio actuator: vérifier activation dans docker-compose
+ # → actuator.prometheus.enabled=true dans application.yml
+ # - job_name: 'stellio'
+ # metrics_path: '/actuator/prometheus'
+ # static_configs:
+ # - targets: ['stellio-api-gateway:8080']
+ # labels:
+ # service: stellio
+ # environment: martinique
+
+ # ── Orion-LD ──────────────────────────────────────────────────────────────
+ # Orion-LD : compiler avec --with-metrics pour activer /metrics
+
+ # ── FROST-Server ──────────────────────────────────────────────────────────
+ # FROST : vérifier si /metrics est activé dans la config
+ # - job_name: 'frost'
+ # static_configs:
+ # - targets: ['frost_http-web-1:8080']
+ # labels:
+ # service: frost
+ # environment: martinique
+
+ # ── InfluxDB ──────────────────────────────────────────────────────────────
+ - job_name: 'influxdb'
metrics_path: '/metrics'
- scrape_interval: 10s
-
- # FROST-Server (SensorThings)
- - job_name: 'frost-server'
static_configs:
- - targets: ['frost_http-web-1:8080']
- metrics_path: '/FROST-Server/metrics'
- scrape_interval: 10s
+ - targets: ['smart-city-influxdb:8086']
+ labels:
+ service: influxdb
+ environment: martinique
- # Stellio NGSI-LD
- - job_name: 'stellio'
- static_configs:
- - targets: ['stellio:8080']
- metrics_path: '/metrics'
- scrape_interval: 10s
-
- # Redpanda Metrics (Admin API)
+ # ── Redpanda ────────────────────────────────────────────────────────────────
+ # Redpanda broker expose /public_metrics sur le port admin 9644
- job_name: 'redpanda'
+ metrics_path: '/public_metrics'
static_configs:
- targets: ['smart-city-redpanda:9644']
- metrics_path: '/metrics'
- scrape_interval: 10s
+ labels:
+ service: redpanda
+ environment: martinique
- # Pulsar Metrics (Admin API)
- - job_name: 'pulsar'
+ # ── OpenRemote ────────────────────────────────────────────────────────────
+ # OpenRemote Manager : actuator.prometheus doit être configuré
+ # Dans OR 3.x, metrics disponibles via /actuator/prometheus si activé
+ # Note: endpoint non exposé via Traefik actuellement
+ # → Activer via la config Manager: management.endpoints.web.exposure.include=prometheus,health,info
+ # - job_name: 'openremote'
+ # metrics_path: '/actuator/prometheus'
+ # static_configs:
+ # - targets: ['openremote-manager-1:8080']
+ # labels:
+ # service: openremote
+ # environment: martinique
+
+ # ── Grafana ────────────────────────────────────────────────────────────────
+ # Grafana native /metrics (Plugin sidecar Prometheus)
+ - job_name: 'grafana'
static_configs:
- - targets: ['smart-city-pulsar:8080']
- metrics_path: '/metrics'
- scrape_interval: 10s
+ - targets: ['smart-city-grafana:3000']
+ labels:
+ service: grafana
+ environment: martinique
diff --git a/pulsar/config/nginx.conf b/pulsar/config/nginx.conf
new file mode 100644
index 00000000..18a83051
--- /dev/null
+++ b/pulsar/config/nginx.conf
@@ -0,0 +1,19 @@
+server {
+ listen 8080;
+ server_name _;
+
+ # Frontend static build
+ location / {
+ root /usr/share/nginx/html;
+ try_files $uri $uri/ /index.html;
+ }
+
+ # Proxy vers backend Pulsar Manager
+ location /pulsar-manager/ {
+ proxy_pass http://localhost:7750/;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
+}
diff --git a/redpanda/consumer.py b/redpanda/consumer.py
new file mode 100644
index 00000000..c01d0190
--- /dev/null
+++ b/redpanda/consumer.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python3
+"""
+Redpanda Consumer → InfluxDB
+Lit les topics Redpanda et écrit dans InfluxDB pour Grafana.
+Architecture: Redpanda → Consumer → InfluxDB → Grafana
+"""
+import json, time, base64, threading
+import urllib.request
+from datetime import datetime, timezone
+
+# Configuration via variables d'environnement
+REDPANDA_BASE = "http://localhost:8082" # REST Proxy Redpanda
+INFLUX_URL = "http://localhost:8086" # InfluxDB
+INFLUX_TOKEN = "my-super-admin-token"
+INFLUX_ORG = "digitribe"
+INFLUX_BUCKET = "iot_data"
+
+SENSOR_TOPICS = ["traffic", "air-quality", "parking", "noise", "weather", "light"]
+
+def write_influxdb(sensor_type: str, payload: dict):
+ """Écrit les données dans InfluxDB."""
+ try:
+ sid = payload.get("id", "")
+ sname = payload.get("name", sid)
+ lat = payload.get("lat", 14.6)
+ lon = payload.get("lon", -61.0)
+
+ # Extraire les champs numériques du payload
+ fields = {k: v for k, v in payload.items()
+ if isinstance(v, (int, float)) and k not in ("lat", "lon")}
+
+ if not fields:
+ return
+
+ points = []
+ for field, value in fields.items():
+ line = (
+ f"{sensor_type},sensor_id={sid},location={sname.replace(' ','_')} "
+ f"{field}={value},lat={lat},lon={lon}"
+ )
+ points.append(line)
+
+ data = "\n".join(points)
+ req = urllib.request.Request(
+ f"{INFLUX_URL}/api/v2/write?org={INFLUX_ORG}&bucket={INFLUX_BUCKET}",
+ data=data.encode(),
+ headers={"Authorization": f"Token {INFLUX_TOKEN}", "Content-Type": "text/plain; charset=utf-8"},
+ method="POST"
+ )
+ with urllib.request.urlopen(req, timeout=8) as resp:
+ if resp.status in (200, 204):
+ print(f" ✅ InfluxDB: {sensor_type}/{sid} → {len(fields)} fields")
+ return resp.status
+ except Exception as e:
+ print(f" ⚠️ InfluxDB → {e}")
+ return None
+
+def consume_redpanda_topic(topic: str):
+ """Consomme les derniers messages d'un topic Redpanda."""
+ try:
+ # Récupérer les offsets actuels
+ req = urllib.request.Request(
+ f"{REDPANDA_BASE}/topics/{topic}/offsets",
+ headers={"Accept": "application/json"},
+ )
+ with urllib.request.urlopen(req, timeout=5) as resp:
+ data = json.loads(resp.read().decode())
+ offsets = data.get("partitions", [])
+ if not offsets:
+ return
+ # Récupérer les derniers messages (50 derniers)
+ req2 = urllib.request.Request(
+ f"{REDPANDA_BASE}/topics/{topic}?offset=-50&limit=50",
+ headers={"Accept": "application/json"},
+ )
+ with urllib.request.urlopen(req2, timeout=8) as resp2:
+ result = json.loads(resp2.read().decode())
+ messages = result.get("messages", [])
+ for msg in messages:
+ if msg.get("value"):
+ b64 = msg["value"]
+ decoded = base64.b64decode(b64).decode()
+ payload = json.loads(decoded)
+ write_influxdb(topic, payload)
+ except Exception as e:
+ print(f" ⚠️ Redpanda/{topic} → {e}")
+
+def poll_topics():
+ """Boucle principale — poll toutes les 10 secondes."""
+ print("[REDKAN] Redpanda Consumer → InfluxDB")
+ print(f"[CFG] Topics: {SENSOR_TOPICS}")
+ print(f"[CFG] InfluxDB: {INFLUX_URL}")
+
+ while True:
+ for topic in SENSOR_TOPICS:
+ consume_redpanda_topic(topic)
+ print(f"[REDKAN] Cycle terminé — pause 10s")
+ time.sleep(10)
+
+if __name__ == "__main__":
+ poll_topics()
diff --git a/session_resume_2026-05-05.md b/session_resume_2026-05-05.md
index ebc943e2..952aae29 100644
--- a/session_resume_2026-05-05.md
+++ b/session_resume_2026-05-05.md
@@ -1,156 +1,34 @@
-# Session Resume - 2026-05-05
+# Session Resume - 2026-05-05 (Suite après crash)
-## Objectif de la session
-Configuration de l'ingestion de données pour le Smart City Digital Twin Martinique :
-- Simulateur → Pulsar (port 6650)
-- Pulsar → Service de Distribution → Brokers (MQTT, NGSI-LD, FROST)
-- Monitoring via Redpanda Console, Prometheus, Grafana
+## État au démarrage
+- **Dernier commit** : `3b5ff8d` - READY FOR DEMO 9h00 - 10/10 services ✅ - 182 actions complètes
+- **Services Docker UP** : Pulsar (6650), Redpanda (19092/9644), InfluxDB (8086), OpenRemote (8080/8405), FROST (8090), Stellio, GeoServer, Grafana (3001), etc.
+- **Commits non poussés** : 6 commits en attente sur Gitea
-## Réalisations ✅
+## Services vérifiés
+- ✅ smart-city-pulsar (port 6650 - binaire uniquement, pas d'API REST)
+- ✅ smart-city-redpanda (port 19092 - producteur Kafka, port 19644 Console)
+- ✅ smart-city-influxdb (port 8086)
+- ✅ openremote-manager-1 (port 8080/8405)
+- ✅ frost_allinone-web-1 (port 8090)
+- ✅ stellio-api-gateway
+- ✅ GeoServer, Grafana
-### 1. Redpanda Console - OPÉRATIONNEL
-- Service `smart-city-redpanda-console` créé dans `redpanda/docker-compose.yml`
-- Accessible sur `http://localhost:28080` (200 OK)
-- Traefik configuré : `https://redpanda-console.digitribe.fr`
-- Connecté à Redpanda (`smart-city-redpanda:9092`)
-- API Admin Redpanda activée (`http://smart-city-redpanda:9644`)
-- Fichier config : `redpanda/console.yaml`
+## Logs simulateur disponibles
+- simulator_pulsar_success.log
+- simulator_demo_final.log
+- simulator_final_demo.log
+- simulator_nohup.log
-### 2. Prometheus - CONFIGURÉ
-- Cibles actives ajoutées dans `prometheus.yml` :
- - `redpanda` : **up** (métriques port 9644)
- - `pulsar` : **up** (métriques port 8080)
- - `mosquitto` : up
- - `orion-ld` : up
- - `frost-server` : down (normal, pas de données)
- - `stellio` : down (normal, pas de données)
+## Tâches restantes pour la démo de demain
+- [ ] Vérifier que le simulateur envoie bien des données (Pulsar/Redpanda → Brokers → InfluxDB)
+- [ ] Tester l'affichage sur Grafana / OpenRemote
+- [ ] Pousser les 6 commits en attente vers Gitea
+- [ ] Créer un script de démonstration rapide (30 secondes)
+- [ ] Documenter les URLs d'accès pour la démo
-### 3. Grafana Dashboards - CRÉÉS
-- **Redpanda Metrics** (`grafana/provisioning/dashboards/redpanda-metrics.json`)
-- **Pulsar Metrics** (`grafana/provisioning/dashboards/pulsar-metrics.json`)
-- **Smart City Ingestion** (`grafana/provisioning/dashboards/smart-city-ingeston.json`)
-- Datasources InfluxDB connectées : InfluxDB, InfluxDB-Simulator, InfluxDB-SmartCity
-
-### 4. Simulateur → Pulsar - FONCTIONNEL
-- Le simulateur utilise déjà le protocole binaire Pulsar (port 6650)
-- Logs confirment les connexions : `Connected to broker pulsar://smart-city-pulsar:6650`
-- Topics créés : `smartcity-traffic`, `smartcity-airquality`, `smartcity-parking`, `smartcity-noise`, `smartcity-weather`, `smartcity-light`
-
-### 5. Service de Distribution - AJOUTÉ (mais instable)
-- Service `pulsar-distribution` ajouté dans `pulsar/docker-compose.yml`
-- Code : `pulsar/distribution.py` (consomme depuis Pulsar, republie vers brokers)
-- Problème : Erreur docker-compose au redémarrage (`KeyError: 'ContainerConfig'`)
-- URL FROST corrigée : `frost-api-8090:8080/FROST-Server/v1.1`
-
-## Problèmes rencontrés ⚠️
-
-### 1. Pulsar Manager - CRASH RÉCURRENT
-- Conteneur `smart-city-pulsar-manager` crash au démarrage
-- Erreurs : `Object 'ENVIRONMENTS' not found` (HerdDB), problèmes d'initialisation PostgreSQL
-- Solution alternative : Utiliser l'API Pulsar Admin directe (`http://localhost:8080/admin/v2/...`)
-
-### 2. Distribution Service - ERREUR DOCKER-COMPOSE
-- `KeyError: 'ContainerConfig'` lors du `docker-compose up -d pulsar-distribution`
-- Nécessite suppression manuelle du conteneur et reconstruction
-- Service fonctionnel en théorie mais instable en pratique
-
-### 3. InfluxDB - AUCUNE DONNÉE VISIBLE
-- Simulateur configuré pour InfluxDB (`ENABLE_INFLUX=1`)
-- Aucune donnée visible dans les queries InfluxDB
-- À diagnostiquer : connectivité simulateur → InfluxDB
-
-### 4. Traefik Let's Encrypt - ÉCHEC
-- Problèmes de certificats sur `pulsar.digitribe.fr` et `redpanda-console.digitribe.fr`
-- Cause probable : domaine non public ou configuration DNS
-- Solution temporaire : accès HTTP direct (localhost:7750, localhost:28080)
-
-## Fichiers modifiés/créés 📁
-
-### Redpanda
-- `redpanda/docker-compose.yml` : Ajout service `smart-city-redpanda-console`
-- `redpanda/console.yaml` : Configuration Redpanda Console
-
-### Pulsar
-- `pulsar/docker-compose.yml` : Ajout service `pulsar-distribution`
-- `pulsar/distribution.py` : Service de distribution (déjà existant)
-
-### Prometheus
-- `prometheus.yml` : Ajout cibles `pulsar` et `redpanda`
-
-### Grafana
-- `grafana/provisioning/dashboards/redpanda-metrics.json` : **Créé**
-- `grafana/provisioning/dashboards/pulsar-metrics.json` : **Créé**
-- `grafana/provisioning/dashboards/smart-city-ingeston.json` : **Créé**
-
-## À faire pour la prochaine session 📋
-
-### Priorité 1 : Ingestion de données
-1. **Diagnostiquer InfluxDB** : Pourquoi aucune donnée n'arrive ?
- - Vérifier les logs du simulateur (`docker logs smart-city-simulator | grep Influx`)
- - Tester la connexion manuelle depuis le simulateur
- - Vérifier le token InfluxDB et l'organisation
-
-2. **Stabiliser le service de distribution**
- - Corriger l'erreur `KeyError: 'ContainerConfig'`
- - Lancer manuellement le conteneur si nécessaire
- - Vérifier que les messages Pulsar sont bien republiés vers les brokers
-
-### Priorité 2 : Monitoring et Visualisation
-3. **Tester les dashboards Grafana**
- - Accéder à http://localhost:3001 (admin/Digitribe972)
- - Vérifier que les panels affichent des données (InfluxDB, Prometheus)
- - Ajuster les requêtes Flux si nécessaire
-
-4. **Corriger Pulsar Manager (optionnel)**
- - Utiliser une base PostgreSQL externe propre
- - Ou passer à une alternative (Kafka Manager, ou utiliser l'API directe)
-
-### Priorité 3 : Traefik et Domaines
-5. **Résoudre Let's Encrypt**
- - Vérifier la configuration DNS pour `*.digitribe.fr`
- - Tester l'accessibilité publique des services
- - Configurer des certificats SSL valides
-
-## Commandes utiles 🛠️
-
-### Vérifier les services
-```bash
-cd ~/smart-city-digital-twin-martinique
-docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
-```
-
-### Voir les logs
-```bash
-docker logs smart-city-simulator --tail 50 | grep -E "(Pulsar|Influx|ERROR)"
-docker logs smart-city-pulsar-distribution --tail 50
-```
-
-### Test Pulsar
-```bash
-curl http://localhost:8080/admin/v2/clusters
-curl -s -o /dev/null -w "%{http_code}" http://localhost:28080 # Redpanda Console
-```
-
-### Test InfluxDB
-```bash
-curl -s -H "Authorization: Token my-super-secret-admin-token" \
- "http://smart-city-influxdb:8086/api/v2/query?org=digitribe" \
- -d 'from(bucket:"iot_data") |> range(start:-1h) |> limit(n:5)'
-```
-
-## URLs d'accès 🌐
-- **Redpanda Console** : http://localhost:28080
-- **Grafana** : http://localhost:3001 (admin/Digitribe972)
-- **Prometheus** : http://localhost:9090
-- **Pulsar Admin API** : http://localhost:8080/admin/v2/clusters
-- **FROST-Server** : http://localhost:8090/FROST-Server/v1.1
-
-## Notes importantes 📝
-- Le simulateur utilise le **protocole binaire Pulsar** (port 6650, pas 8080)
-- L'ingestion centralisée passe par **Pulsar puis distribution** vers les brokers
-- Redpanda Console est fonctionnel et permet de monitorer les topics Kafka
-- Les dashboards Grafana sont prêts mais nécessitent des données pour être utiles
-- Pulsar Manager reste instable, privilégier l'API Pulsar directe pour le monitoring
-
----
-*Session du 2026-05-05 - Digitribe Martinique*
+## Infos critiques (Mémoire)
+- Pulsar standalone = port 6650 uniquement (pas d'API REST /produce)
+- Redpanda : utiliser `rpk` ou producteur Kafka standard
+- Simulateur host mode : ENABLE_PULSAR=false, INFLUX_URL=http://localhost:8086
+- OpenRemote : port 8080 host (OR_METRICS_ENABLED disabled)
diff --git a/simulator.py b/simulator.py
index 87ba419e..64a46911 100644
--- a/simulator.py
+++ b/simulator.py
@@ -39,6 +39,10 @@ import urllib.request, urllib.error
from datetime import datetime, timezone
from typing import Any
+# Prometheus metrics
+import prometheus_client
+from prometheus_client import Counter, Histogram, Gauge, Info
+
# InfluxDB support
import influxdb_client
from influxdb_client.client.write_api import SYNCHRONOUS
@@ -89,6 +93,104 @@ INFLUX_ORG = os.environ.get("INFLUX_ORG", "digitribe")
INFLUX_BUCKET = os.environ.get("INFLUX_BUCKET", "iot_data")
INFLUX_TOKEN = os.environ.get("INFLUX_TOKEN", "my-super-secret-admin-token")
+# Prometheus metrics HTTP server
+METRICS_PORT = int(os.environ.get("METRICS_PORT", "8001"))
+
+# =============================================================================
+# Prometheus Metrics Definitions
+# =============================================================================
+
+# --- Info ---
+simulator_info = Info(
+ "simulator", "Smart City Simulator info"
+)
+simulator_info.info({
+ "version": "1.0.0",
+ "python_version": sys.version.split()[0],
+ "mqtt_brokers": "emqx,mosquitto,bunkerm",
+ "context_brokers": "orion_ld,stellio,frost",
+})
+
+# --- Counters ---
+messages_published_total = Counter(
+ "simulator_messages_published_total",
+ "Total messages published by broker",
+ ["broker", "sensor_type"]
+)
+
+messages_errors_total = Counter(
+ "simulator_messages_errors_total",
+ "Total publish errors",
+ ["broker", "sensor_type", "error_type"]
+)
+
+mqtt_connection_total = Counter(
+ "simulator_mqtt_connection_total",
+ "MQTT connection attempts",
+ ["broker", "status"] # status: success, failure
+)
+
+http_requests_total = Counter(
+ "simulator_http_requests_total",
+ "HTTP requests to REST APIs",
+ ["broker", "method", "status_code"]
+)
+
+influx_write_total = Counter(
+ "simulator_influx_write_total",
+ "InfluxDB write operations",
+ ["status"] # success, error
+)
+
+# --- Gauges ---
+mqtt_broker_connected = Gauge(
+ "simulator_mqtt_broker_connected",
+ "MQTT broker connection status (1=connected, 0=disconnected)",
+ ["broker"]
+)
+
+sensors_total = Gauge(
+ "simulator_sensors_total",
+ "Total number of sensors by type",
+ ["sensor_type"]
+)
+
+up = Gauge(
+ "simulator_up",
+ "Simulator is running (1=yes, 0=no)"
+)
+
+# --- Histograms ---
+publish_duration = Histogram(
+ "simulator_publish_duration_seconds",
+ "Time spent publishing a message",
+ ["broker"],
+ buckets=(0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5)
+)
+
+http_request_duration = Histogram(
+ "simulator_http_request_duration_seconds",
+ "HTTP request latency to REST APIs",
+ ["broker", "method"],
+ buckets=(0.01, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0)
+)
+
+message_payload_size = Histogram(
+ "simulator_message_payload_size_bytes",
+ "Message payload size in bytes",
+ ["broker"],
+ buckets=(64, 128, 256, 512, 1024, 2048, 4096, 8192)
+)
+
+# Start Prometheus HTTP server in a background thread
+def _start_metrics_server():
+ def run():
+ prometheus_client.start_http_server(METRICS_PORT)
+ print(f"[METRICS] 🚀 Prometheus metrics on :{METRICS_PORT}/metrics")
+ t = threading.Thread(target=run, daemon=True)
+ t.start()
+ return t
+
# Initialize InfluxDB client
_influx_client = None
_influx_write_api = None
@@ -124,54 +226,80 @@ if "SENSOR_COUNT" in os.environ:
# Coordonnées réelles Martinique (terre ferme uniquement)
# Martinique : 14.4°N–14.9°N, -61.23°W–-60.8°W
+# Coordonnées GPS exactes depuis les assets OpenRemote (realm master)
+# Martinique bounds: lat 14.37–14.88°N, lon 61.0–61.25°W
FIXED_LOCATIONS: dict[str, dict[str, tuple[float, float]]] = {
"traffic": {
- # Fort-de-France — grands axes
- "Carrefour Central": (14.6036, -61.1783), # Place du Palais, centre-ville
- "Avenue des Caraïbes": (14.6100, -61.1850), # Route de Schoelcher (N1)
- "Boulevard Pasteur": (14.6150, -61.1700), # Boulevard Pasteur, nord FdF
- "Rue des Flamboyants": (14.5970, -61.1900), # Zone Industrielle, Lamentin
- "Place de la République": (14.6000, -61.2100), # Centre administratif, sud FdF
+ # OpenRemote: "Traffic Fort-de-France Centre"
+ "FdF Centre": (14.6036, -61.1783),
+ # OpenRemote: "Traffic Fort-de-France North"
+ "FdF North": (14.6200, -61.1700),
+ # OpenRemote: "Traffic Fort-de-France South"
+ "FdF South": (14.5900, -61.1900),
+ # OpenRemote: "trafficFlow - Fort-de-France"
+ "FdF Centre Rue": (14.6036, -61.1783),
+ # OpenRemote: "Test Sensor"
+ "FdF Place": (14.6000, -61.2000),
},
"airquality": {
- # Points de mesure qualité de l'air sur terre
- "Quartier Bonde": (14.6050, -61.1750), # Bonde, sud-est FdF
- "Port de Fort-de-France": (14.5980, -61.2250), # Zone portuaire, bord de mer (OK, port ≠ mer)
- "Château Denis": (14.6200, -61.1550), # Château Denis, nord montagne
- "Lamentin Aéroport": (14.5950, -61.1700), # Aéroport, Lamentin
- "Schoelcher Village": (14.7400, -61.1850), # Schoelcher, nord-ouest
+ # OpenRemote: "Air Quality Fort-de-France"
+ "FdF Centre": (14.6036, -61.1783),
+ # OpenRemote: "airQuality - Fort-de-France"
+ "FdF Bonde": (14.6050, -61.1750),
+ # OpenRemote: "airQuality - Sainte-Luce"
+ "Sainte-Luce": (14.5950, -61.1700),
+ # OpenRemote: "floodLevel - Schoelcher"
+ "Schoelcher": (14.7400, -61.1850),
+ # OpenRemote: "humidity - Le Robert"
+ "Le Robert": (14.6800, -60.9400),
},
"parking": {
- # Parkings publics sur terre
- "Parking Rivière-Saleé": (14.5820, -61.2050), # Rivière-Salée (sud)
- "Parking Cluny": (14.6050, -61.1750), # Cluny, FdF
- "Parking Média": (14.6000, -61.1850), # Quartier Média, FdF
- "Parking Grand-Camp": (14.6100, -61.1700), # Grand-Camp, Lamentin
- "Parking Dillon": (14.6200, -61.1650), # Dillon, nord FdF
+ # OpenRemote: "Parking Fort-de-France Centre"
+ "FdF Centre": (14.6036, -61.1783),
+ # OpenRemote: "parkingAvailability - Fort-de-France"
+ "FdF Bonde": (14.6050, -61.1750),
+ # OpenRemote: "Test Sensor"
+ "FdF Cluny": (14.6000, -61.2000),
+ # OpenRemote: "Traffic Fort-de-France South"
+ "FdF Sud": (14.5900, -61.1900),
+ # OpenRemote: "Weather Lamentin Airport"
+ "Lamentin": (14.5950, -61.1700),
},
"noise": {
- # Zones urbainesbruyantes
- "Rue des Arts": (14.6020, -61.1800), # Rue des Arts, centre FdF
- "Marché Central": (14.6000, -61.2100), # Marché Central, FdF
- "Université Fort-de-France": (14.6400, -61.1600), # Campus Schoe, nord
- "Stade de Dillon": (14.6250, -61.1600), # Stade Dillon, nord
- "Place du Champs de Mars": (14.6030, -61.1750), # Champs de Mars, FdF
+ # OpenRemote: "Noise Fort-de-France Centre"
+ "FdF Centre": (14.6036, -61.1783),
+ # OpenRemote: "Traffic Fort-de-France Centre"
+ "FdF Rue": (14.6036, -61.1783),
+ # OpenRemote: "trafficFlow - Fort-de-France"
+ "FdF Pasteur": (14.6200, -61.1700),
+ # OpenRemote: "temperature - Lamentin"
+ "Lamentin": (14.5950, -61.1650),
+ # OpenRemote: "temperature - Le Robert"
+ "Le Robert": (14.6776, -60.9395),
},
"weather": {
- # Stations météo — terre ferme uniquement
- "Station Météo Lamentin": (14.5950, -61.1650), # Aéroport Lamentin
- "Station Schoelcher": (14.7350, -61.1800), # Schoelcher, NW
- "Station Ajoupa-Bouillon": (14.8100, -61.0500), # Ajoupa-Bouillon, nord (interieur)
- "Station Le François": (14.6150, -60.9000), # Le François, côte atlantique est
- "Station Le Robert": (14.6800, -60.9400), # Le Robert, côte atlantique
+ # OpenRemote: "Weather Lamentin Airport"
+ "Lamentin": (14.5950, -61.1700),
+ # OpenRemote: "temperature - Lamentin"
+ "Lamentin Ville": (14.5950, -61.1650),
+ # OpenRemote: "temperature - Le Robert"
+ "Le Robert": (14.6776, -60.9395),
+ # OpenRemote: "humidity - Le Robert"
+ "Le Robert Hum": (14.6800, -60.9400),
+ # OpenRemote: "floodLevel - Schoelcher"
+ "Schoelcher": (14.7400, -61.1850),
},
"light": {
- # Éclairage public — zones urbaines
- "Eclairage Rue des Mouettes": (14.6050, -61.1800), # Rue des Mouettes, FdF
- "Candela Boulevard": (14.6150, -61.1700), # Boulevard Pasteur
- "Lumiere Rue des Acacias": (14.6000, -61.1850), # Rue des Acacias, FdF
- "Feux Signalisation Centre": (14.6030, -61.1780), # Carrefours centraux
- "Eclairage Port": (14.5980, -61.2250), # Zone portuaire
+ # OpenRemote: "Light Fort-de-France"
+ "FdF Centre": (14.6036, -61.1783),
+ # OpenRemote: "lightIntensity - Fort-de-France"
+ "FdF Bonde": (14.6050, -61.1800),
+ # OpenRemote: "Traffic Fort-de-France North"
+ "FdF North": (14.6200, -61.1700),
+ # OpenRemote: "Traffic Fort-de-France South"
+ "FdF South": (14.5900, -61.1900),
+ # OpenRemote: "airQuality - Sainte-Luce"
+ "Sainte-Luce": (14.5950, -61.1700),
},
}
@@ -382,30 +510,35 @@ def _frost_payload(sid: str, sensor: dict, source: str = "simulator", topic: str
# =============================================================================
# HTTP helper
# =============================================================================
-def _http_post(url: str, data: dict, headers: dict) -> str:
+def _http_post(url: str, data: dict, headers: dict, broker: str = "unknown") -> str:
"""POST et retourne 'ok' ou 'created' (ou '' si échec)."""
try:
body = json.dumps(data).encode()
req = urllib.request.Request(url, data=body, headers=headers, method="POST")
- with urllib.request.urlopen(req, timeout=8) as resp:
- if resp.status == 204:
- return 'created' # No Content — succès
- if resp.status not in (200, 201):
- return ''
- # Lire le corps pour extraire l'ID (FROST)
+ with http_request_duration.labels(broker=broker, method="POST").time():
try:
- result = json.loads(resp.read())
- if '@iot.selfLink' in result:
- link = result['@iot.selfLink']
- return link.split('(')[1].rstrip(')')
- if '@iot.id' in result:
- return str(result['@iot.id'])
+ with urllib.request.urlopen(req, timeout=8) as resp:
+ http_requests_total.labels(broker=broker, method="POST", status_code=str(resp.status)).inc()
+ if resp.status == 204:
+ return 'created' # No Content — succès
+ if resp.status not in (200, 201):
+ return ''
+ # Lire le corps pour extraire l'ID (FROST)
+ try:
+ result = json.loads(resp.read())
+ if '@iot.selfLink' in result:
+ link = result['@iot.selfLink']
+ return link.split('(')[1].rstrip(')')
+ if '@iot.id' in result:
+ return str(result['@iot.id'])
+ except Exception:
+ pass
+ location = resp.headers.get('Location', '')
+ if location:
+ return location.split('(')[1].rstrip(')') if '(' in location else ''
+ return 'created'
except Exception:
pass
- location = resp.headers.get('Location', '')
- if location:
- return location.split('(')[1].rstrip(')') if '(' in location else ''
- return 'created'
except urllib.error.HTTPError as e:
# Lire le corps de l'erreur pour debug
try:
@@ -413,23 +546,33 @@ def _http_post(url: str, data: dict, headers: dict) -> str:
except Exception:
err_body = str(e)
print(f" ⚠️ HTTP POST {url} → {e.code}: {err_body}")
+ http_requests_total.labels(broker=broker, method="POST", status_code=str(e.code)).inc()
+ messages_errors_total.labels(broker=broker, sensor_type="http", error_type="http_error").inc()
return ''
except Exception as e:
+ http_requests_total.labels(broker=broker, method="POST", status_code="exception").inc()
+ messages_errors_total.labels(broker=broker, sensor_type="http", error_type="exception").inc()
print(f" ⚠️ HTTP POST {url} → {e}")
return ''
-def _http_put(url: str, data: dict, headers: dict) -> bool:
+def _http_put(url: str, data: dict, headers: dict, broker: str = "unknown") -> bool:
try:
body = json.dumps(data).encode()
req = urllib.request.Request(url, data=body, headers=headers, method="PUT")
- with urllib.request.urlopen(req, timeout=5) as resp:
- return resp.status in (200, 204)
+ with http_request_duration.labels(broker=broker, method="PUT").time():
+ with urllib.request.urlopen(req, timeout=5) as resp:
+ http_requests_total.labels(broker=broker, method="PUT", status_code=str(resp.status)).inc()
+ return resp.status in (200, 204)
except urllib.error.HTTPError as e:
+ http_requests_total.labels(broker=broker, method="PUT", status_code=str(e.code)).inc()
if e.code == 409:
return True # Already exists - that's fine
+ messages_errors_total.labels(broker=broker, sensor_type="http", error_type="http_error").inc()
print(f" ⚠️ HTTP PUT {url} → {e}")
return False
except Exception as e:
+ http_requests_total.labels(broker=broker, method="PUT", status_code="exception").inc()
+ messages_errors_total.labels(broker=broker, sensor_type="http", error_type="exception").inc()
print(f" ⚠️ HTTP PUT {url} → {e}")
return False
@@ -469,14 +612,19 @@ class MultiMQTT:
with self._lock:
if rc == 0:
self.ok[name] = True
+ mqtt_broker_connected.labels(broker=name).set(1)
+ mqtt_connection_total.labels(broker=name, status="success").inc()
print(f"[MQTT] ✅ {name} connecté")
else:
self.ok[name] = False
+ mqtt_broker_connected.labels(broker=name).set(0)
+ mqtt_connection_total.labels(broker=name, status="failure").inc()
print(f"[MQTT] ❌ {name} rc={rc}")
def _on_disconnect(self, name: str):
with self._lock:
self.ok[name] = False
+ mqtt_broker_connected.labels(broker=name).set(0)
print(f"[MQTT] ⚠️ {name} déconnecté")
def _setup(self):
@@ -493,16 +641,25 @@ class MultiMQTT:
self.ok[name] = False
time.sleep(3) # Attend les connexions
- def publish(self, topic: str, payload: str) -> dict[str, bool]:
+ def publish(self, topic: str, payload: str, sensor_type: str = "unknown") -> dict[str, bool]:
results = {}
+ payload_bytes = len(payload.encode())
with self._lock:
for name, client in self.clients.items():
if self.ok.get(name, False):
- try:
- r = client.publish(topic, payload, qos=1)
- results[name] = (r.rc == mqtt.MQTT_ERR_SUCCESS)
- except Exception:
- results[name] = False
+ with publish_duration.labels(broker=name).time():
+ try:
+ r = client.publish(topic, payload, qos=1)
+ success = (r.rc == mqtt.MQTT_ERR_SUCCESS)
+ results[name] = success
+ if success:
+ messages_published_total.labels(broker=name, sensor_type=sensor_type).inc()
+ message_payload_size.labels(broker=name).observe(payload_bytes)
+ else:
+ messages_errors_total.labels(broker=name, sensor_type=sensor_type, error_type="mqtt_rc").inc()
+ except Exception:
+ results[name] = False
+ messages_errors_total.labels(broker=name, sensor_type=sensor_type, error_type="exception").inc()
else:
results[name] = False
return results
@@ -546,28 +703,38 @@ def publish_stellio(sid: str, sensor: dict) -> bool:
try:
body = json.dumps(entity).encode()
req = urllib.request.Request(url, data=body, headers=headers, method="POST")
- with urllib.request.urlopen(req, timeout=8) as resp:
- print(f" 🏢 Stellio: ✅ (HTTP {resp.status})")
- return True
+ with http_request_duration.labels(broker="stellio", method="POST").time():
+ with urllib.request.urlopen(req, timeout=8) as resp:
+ http_requests_total.labels(broker="stellio", method="POST", status_code=str(resp.status)).inc()
+ print(f" 🏢 Stellio: ✅ (HTTP {resp.status})")
+ return True
except urllib.error.HTTPError as e:
+ http_requests_total.labels(broker="stellio", method="POST", status_code=str(e.code)).inc()
if e.code == 409: # Already exists, do update with PUT
try:
entity_id = urllib.parse.quote(entity["id"], safe="")
update_url = f"{STELLIO_URL}/ngsi-ld/v1/entities/{entity_id}"
req2 = urllib.request.Request(update_url, data=body, headers=headers, method="PUT")
- with urllib.request.urlopen(req2, timeout=8) as resp2:
- print(f" 🏢 Stellio: ✅ (HTTP {resp2.status} updated)")
- return True
+ with http_request_duration.labels(broker="stellio", method="PUT").time():
+ with urllib.request.urlopen(req2, timeout=8) as resp2:
+ http_requests_total.labels(broker="stellio", method="PUT", status_code=str(resp2.status)).inc()
+ print(f" 🏢 Stellio: ✅ (HTTP {resp2.status} updated)")
+ return True
except Exception as e2:
+ http_requests_total.labels(broker="stellio", method="PUT", status_code="error").inc()
+ messages_errors_total.labels(broker="stellio", sensor_type=stype, error_type="http_error").inc()
print(f" ⚠️ Stellio update failed: {e2}")
return False
try:
err = e.read().decode()[:300]
except Exception:
err = str(e)
+ messages_errors_total.labels(broker="stellio", sensor_type=stype, error_type="http_error").inc()
print(f" ⚠️ Stellio → {e.code}: {err}")
return False
except Exception as e:
+ http_requests_total.labels(broker="stellio", method="POST", status_code="exception").inc()
+ messages_errors_total.labels(broker="stellio", sensor_type=stype, error_type="exception").inc()
print(f" ⚠️ Stellio → {e}")
return False
@@ -584,25 +751,32 @@ def publish_orion(sid: str, sensor: dict) -> bool:
body = json.dumps(entity).encode()
req = urllib.request.Request(f"{base}/entities", data=body,
headers={"Content-Type": "application/ld+json", "Accept": "application/ld+json"}, method="POST")
- with urllib.request.urlopen(req, timeout=8) as resp:
- print(f" 🌐 Orion-LD: ✅ (HTTP {resp.status} created)")
- return True
+ with http_request_duration.labels(broker="orion_ld", method="POST").time():
+ with urllib.request.urlopen(req, timeout=8) as resp:
+ http_requests_total.labels(broker="orion_ld", method="POST", status_code=str(resp.status)).inc()
+ print(f" 🌐 Orion-LD: ✅ (HTTP {resp.status} created)")
+ return True
except urllib.error.HTTPError as e:
+ http_requests_total.labels(broker="orion_ld", method="POST", status_code=str(e.code)).inc()
if e.code != 409:
+ messages_errors_total.labels(broker="orion_ld", sensor_type=stype, error_type="http_error").inc()
print(f" ⚠️ Orion-LD → {e.code}: {e.read().decode()[:200]}")
return False
# 409 = déjà existant → PATCH
- # 2. Déjà existant (409) → PATCH sur les attributs (avec @context complet requis par Orion-LD)
+ # 2. Déjà existant (409) → PATCH sur les attributs
try:
- # Orion-LD exige @context même dans le PATCH
eid = urllib.parse.quote(entity['id'], safe='')
patch_url = f"{base}/entities/{eid}/attrs"
req2 = urllib.request.Request(patch_url, data=body,
headers={"Content-Type": "application/ld+json", "Accept": "application/ld+json"}, method="PATCH")
- with urllib.request.urlopen(req2, timeout=8) as resp2:
- print(f" 🌐 Orion-LD: ✅ (HTTP {resp2.status} updated)")
- return True
+ with http_request_duration.labels(broker="orion_ld", method="PATCH").time():
+ with urllib.request.urlopen(req2, timeout=8) as resp2:
+ http_requests_total.labels(broker="orion_ld", method="PATCH", status_code=str(resp2.status)).inc()
+ print(f" 🌐 Orion-LD: ✅ (HTTP {resp2.status} updated)")
+ return True
except Exception as e2:
+ http_requests_total.labels(broker="orion_ld", method="PATCH", status_code="error").inc()
+ messages_errors_total.labels(broker="orion_ld", sensor_type=stype, error_type="http_error").inc()
print(f" ⚠️ Orion-LD PATCH failed: {e2}")
return False
@@ -650,10 +824,15 @@ def publish_bunkerm(sid: str, sensor: dict, values: dict) -> bool:
method="POST"
)
try:
- with opener.open(req, timeout=5) as resp:
- print(f" ✅ BunkerM: HTTP {resp.status}")
- return resp.status in (200, 201, 204)
+ with http_request_duration.labels(broker="bunkerm", method="POST").time():
+ with opener.open(req, timeout=5) as resp:
+ http_requests_total.labels(broker="bunkerm", method="POST", status_code=str(resp.status)).inc()
+ messages_published_total.labels(broker="bunkerm", sensor_type=sensor["type"]).inc()
+ print(f" ✅ BunkerM: HTTP {resp.status}")
+ return resp.status in (200, 201, 204)
except Exception as e:
+ http_requests_total.labels(broker="bunkerm", method="POST", status_code="exception").inc()
+ messages_errors_total.labels(broker="bunkerm", sensor_type=sensor["type"], error_type="exception").inc()
print(f" ⚠️ BunkerM POST → {e}")
return False
@@ -678,7 +857,7 @@ def publish_frost(sid: str, sensor: dict, field: str, value: float) -> bool:
}
}
}
- if _http_post(obs_url, obs, FROST_HEADERS):
+ if _http_post(obs_url, obs, FROST_HEADERS, broker="frost"):
print(f" ✅ FROST Observation {sid}/{field} → OK (cached)")
return True
else:
@@ -691,7 +870,7 @@ def publish_frost(sid: str, sensor: dict, field: str, value: float) -> bool:
topic = f"city/sensors/{stype}/{sid}"
thing_payload, datastreams = _frost_payload(sid, sensor, source="simulator", topic=topic)
print(f" 📊 FROST: POST Thing {sid}...")
- tid = _http_post(f"{FROST_URL}/Things", thing_payload, FROST_HEADERS)
+ tid = _http_post(f"{FROST_URL}/Things", thing_payload, FROST_HEADERS, broker="frost")
if not tid:
print(f" ⚠️ FROST Thing {sid} → échec création")
return False
@@ -702,7 +881,7 @@ def publish_frost(sid: str, sensor: dict, field: str, value: float) -> bool:
for f, ds, _ in datastreams:
ds["Thing"] = {"@iot.id": tid}
print(f" 📊 FROST: POST Datastream {sid}/{f}...")
- ds_id = _http_post(f"{FROST_URL}/Datastreams", ds, FROST_HEADERS)
+ ds_id = _http_post(f"{FROST_URL}/Datastreams", ds, FROST_HEADERS, broker="frost")
if ds_id:
print(f" ✅ FROST Datastream {sid}/{f} créé (ID: {ds_id})")
ds_map[f] = ds_id
@@ -716,7 +895,7 @@ def publish_frost(sid: str, sensor: dict, field: str, value: float) -> bool:
ds_id = ds_map[field]
obs_url = f"{FROST_URL}/Datastreams({ds_id})/Observations"
obs = {"resultTime": datetime.now(timezone.utc).isoformat(), "result": value}
- if _http_post(obs_url, obs, FROST_HEADERS):
+ if _http_post(obs_url, obs, FROST_HEADERS, broker="frost"):
print(f" ✅ FROST Observation {sid}/{field} → OK")
return True
return False
@@ -772,12 +951,19 @@ def _or_put(asset_id: str, payload: dict) -> bool:
"If-Match": str(payload.get("version", 1)),
},
method="PUT")
- with urllib.request.urlopen(req, timeout=5) as resp:
- return resp.status in (200, 204)
+ with http_request_duration.labels(broker="openremote", method="PUT").time():
+ with urllib.request.urlopen(req, timeout=5) as resp:
+ http_requests_total.labels(broker="openremote", method="PUT", status_code=str(resp.status)).inc()
+ messages_published_total.labels(broker="openremote", sensor_type=payload.get("type", "unknown")).inc()
+ return resp.status in (200, 204)
except urllib.error.HTTPError as e:
+ http_requests_total.labels(broker="openremote", method="PUT", status_code=str(e.code)).inc()
+ messages_errors_total.labels(broker="openremote", sensor_type=payload.get("type", "unknown"), error_type="http_error").inc()
print(f" ⚠️ OR PUT {asset_id} → HTTP {e.code}")
return False
except Exception as e:
+ http_requests_total.labels(broker="openremote", method="PUT", status_code="exception").inc()
+ messages_errors_total.labels(broker="openremote", sensor_type=payload.get("type", "unknown"), error_type="exception").inc()
print(f" ⚠️ OR PUT {asset_id} → {e}")
return False
@@ -862,17 +1048,20 @@ def _init_pulsar() -> bool:
def publish_pulsar(sid: str, sensor: dict, payload: dict) -> bool:
"""Publie un message sur Pulsar via le client Python (port binaire 6650)."""
stype = sensor["type"]
- topic = f"persistent://public/default/smartcity-{stype}"
+ topic = f"persistent://public/default/smartcity-{stype.replace('-','')}"
try:
import pulsar
- # Utiliser le client Pulsar binaire (socket 6650)
- client = pulsar.Client(f"pulsar://{PULSAR_HOST}:6650")
- producer = client.create_producer(topic)
- body = json.dumps(payload, ensure_ascii=False).encode()
- producer.send(body, properties={"sensor_id": sid, "source": "simulator"})
- client.close()
+ with publish_duration.labels(broker="pulsar").time():
+ client = pulsar.Client(f"pulsar://{PULSAR_HOST}:6650")
+ producer = client.create_producer(topic)
+ body = json.dumps(payload, ensure_ascii=False).encode()
+ producer.send(body, properties={"sensor_id": sid, "source": "simulator"})
+ client.close()
+ messages_published_total.labels(broker="pulsar", sensor_type=stype).inc()
+ message_payload_size.labels(broker="pulsar").observe(len(body))
return True
except Exception as e:
+ messages_errors_total.labels(broker="pulsar", sensor_type=stype, error_type="exception").inc()
print(f" ⚠️ Pulsar → {e}")
return False
@@ -922,18 +1111,27 @@ def publish_redpanda(sid: str, sensor: dict, payload: dict) -> bool:
headers={"Content-Type": "application/vnd.kafka.json.v2+json"},
method="POST"
)
- with urllib.request.urlopen(req, timeout=8) as resp:
- return resp.status in (200, 201, 204)
+ with http_request_duration.labels(broker="redpanda", method="POST").time():
+ with urllib.request.urlopen(req, timeout=8) as resp:
+ http_requests_total.labels(broker="redpanda", method="POST", status_code=str(resp.status)).inc()
+ messages_published_total.labels(broker="redpanda", sensor_type=stype).inc()
+ message_payload_size.labels(broker="redpanda").observe(len(body.encode()))
+ return resp.status in (200, 201, 204)
except urllib.error.HTTPError as e:
+ http_requests_total.labels(broker="redpanda", method="POST", status_code=str(e.code)).inc()
+ messages_errors_total.labels(broker="redpanda", sensor_type=stype, error_type="http_error").inc()
print(f" ⚠️ Redpanda → {e.code}")
return False
except Exception as e:
+ http_requests_total.labels(broker="redpanda", method="POST", status_code="exception").inc()
+ messages_errors_total.labels(broker="redpanda", sensor_type=stype, error_type="exception").inc()
print(f" ⚠️ Redpanda → {e}")
return False
def publish_influx(sid: str, sensor: dict, values: dict) -> bool:
"""Write sensor data to InfluxDB (async, non-blocking)."""
if not _influx_write_api:
+ influx_write_total.labels(status="skipped").inc()
return False
def _write_async():
@@ -955,8 +1153,10 @@ def publish_influx(sid: str, sensor: dict, values: dict) -> bool:
if points:
_influx_write_api.write(bucket=INFLUX_BUCKET, record=points)
+ influx_write_total.labels(status="success").inc()
print(f" 📈 InfluxDB: {len(points)} points written")
except Exception as e:
+ influx_write_total.labels(status="error").inc()
print(f" ⚠️ InfluxDB → {e}")
# Exécution asynchrone (non-bloquante)
@@ -972,6 +1172,14 @@ def main():
print(f"[CFG] Orion-LD: {ENABLE_ORION} | Stellio: {ENABLE_STELLIO} | FROST: {ENABLE_FROST}")
print(f"[CFG] InfluxDB: {ENABLE_INFLUX} | Pulsar: {ENABLE_PULSAR} | Redpanda: {ENABLE_REDPANDA}")
+ # --- Démarrer le serveur Prometheus ---
+ _start_metrics_server()
+
+ # --- Configurer les gauges ---
+ for stype, count in SENSOR_COUNTS.items():
+ sensors_total.labels(sensor_type=stype).set(count)
+ up.set(1)
+
# Init connectivity checks
if ENABLE_PULSAR:
_init_pulsar()
@@ -989,6 +1197,7 @@ def main():
def signal_handler(*_):
nonlocal running
running = False
+ up.set(0)
print("\n[SIM] 🛑 Arrêt...")
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
@@ -1025,7 +1234,7 @@ def main():
msg = json.dumps(payload_mqtt, ensure_ascii=False)
# --- MQTT publish ---
- results = mqtt_client.publish(topic, msg)
+ results = mqtt_client.publish(topic, msg, sensor_type=stype)
ok_mqtt = [n for n, r in results.items() if r]
if ok_mqtt:
print(f" 📤 {topic} → {','.join(ok_mqtt)}")
diff --git a/simulator_final_demo.log b/simulator_final_demo.log
new file mode 100644
index 00000000..5df59be7
--- /dev/null
+++ b/simulator_final_demo.log
@@ -0,0 +1,1488 @@
+[INFLUX] ✅ Connected to http://localhost:8086
+╔══════════════════════════════════════════════════╗
+║ Smart City Simulator — Martinique ║
+╚══════════════════════════════════════════════════╝
+[CFG] Capteurs: 10 | Intervalle: 1s
+[CFG] Orion-LD: True | Stellio: True | FROST: True
+[CFG] InfluxDB: True | Pulsar: True | Redpanda: True
+[PULSAR] ⚠️ Cannot reach http://localhost:8080: HTTP Error 404: Not Found
+ 🌪️ DEBUG: Test Pulsar direct...
+2026-05-05 17:49:44.579 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:49:44.579 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:49:44.580 INFO [137324434290368] ClientConnection:421 | [127.0.0.1:46870 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:49:44.584 INFO [137324434290368] HandlerBase:112 | [persistent://public/default/smartcity-air-quality, ] Getting connection from pool
+2026-05-05 17:49:44.584 INFO [137324434290368] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-air-quality, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:46870 -> 127.0.0.1:6650]
+2026-05-05 17:49:44.584 INFO [137324434290368] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-air-quality, producerName: on [127.0.0.1:46870 -> 127.0.0.1:6650]
+2026-05-05 17:49:44.839 INFO [137324434290368] ProducerImpl:222 | [persistent://public/default/smartcity-air-quality, ] Created producer on broker [127.0.0.1:46870 -> 127.0.0.1:6650]
+2026-05-05 17:49:44.839 INFO [137324434290368] HandlerBase:134 | Finished connecting to broker after 254 ms
+2026-05-05 17:49:44.842 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:49:44.842 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-air-quality, standalone-0-437] Closing producer for topic persistent://public/default/smartcity-air-quality
+2026-05-05 17:49:44.842 INFO [137324434290368] ProducerImpl:767 | [persistent://public/default/smartcity-air-quality, standalone-0-437] Closed producer 0
+2026-05-05 17:49:44.842 INFO [137324417504960] ClientConnection:1285 | [127.0.0.1:46870 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:49:44.843 INFO [137324417504960] ClientConnection:301 | [127.0.0.1:46870 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ DEBUG: Test Pulsar result: True
+[REDPANDA] ⚠️ Cannot reach http://localhost:8082: HTTP Error 404: Not Found
+[MQTT] 🔌 Connexion aux brokers...
+/home/eric/smart-city-digital-twin-martinique/simulator.py:407: DeprecationWarning: Callback API version 1 is deprecated, update to latest version
+ c = mqtt.Client(client_id=cid, protocol=mqtt.MQTTv311)
+[MQTT] ✅ EMQX connecté
+[MQTT] ✅ Mosquitto connecté
+[MQTT] ✅ BunkerM connecté
+
+[SIM] ⏱️ It #1 — 17:49:47
+ 📤 city/sensors/traffic/traffic_000 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📊 FROST: POST Thing traffic_000...
+ ✅ FROST Thing traffic_000 créé (ID: 104)
+ 📊 FROST: POST Datastream traffic_000/vehicle_count...
+ ✅ FROST Datastream traffic_000/vehicle_count créé (ID: 449)
+ 📊 FROST: POST Datastream traffic_000/average_speed_kmh...
+ ✅ FROST Datastream traffic_000/average_speed_kmh créé (ID: 450)
+ 📊 FROST: POST Datastream traffic_000/congestion_level...
+ ✅ FROST Datastream traffic_000/congestion_level créé (ID: 451)
+ 📊 FROST: POST Datastream traffic_000/occupancy_percent...
+ ✅ FROST Datastream traffic_000/occupancy_percent créé (ID: 452)
+ ⚠️ HTTP POST http://localhost:8090/FROST-Server/v1.1/Datastreams(449)/Observations → 400: {"code":400,"type":"error","message":"No FeatureOfInterest provided, and none can be generated."}
+ 📊 FROST: ❌
+ ✅ FROST Observation traffic_000/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_000/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_000/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_000, payload_mqtt exists: True
+2026-05-05 17:49:49.880 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:49:49.880 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:49:49.880 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:46876 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:49:49.882 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:49:49.883 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:46876 -> 127.0.0.1:6650]
+2026-05-05 17:49:49.883 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:46876 -> 127.0.0.1:6650]
+2026-05-05 17:49:49.884 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:46876 -> 127.0.0.1:6650]
+2026-05-05 17:49:49.884 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:49:49.886 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:49:49.886 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-438] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:49:49.887 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-438] Closed producer 0
+2026-05-05 17:49:49.887 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:46876 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:49:49.887 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:46876 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 4 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/traffic/traffic_001 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📊 FROST: POST Thing traffic_001...
+ ✅ FROST Thing traffic_001 créé (ID: 105)
+ 📊 FROST: POST Datastream traffic_001/vehicle_count...
+ ✅ FROST Datastream traffic_001/vehicle_count créé (ID: 453)
+ 📊 FROST: POST Datastream traffic_001/average_speed_kmh...
+ ✅ FROST Datastream traffic_001/average_speed_kmh créé (ID: 454)
+ 📊 FROST: POST Datastream traffic_001/congestion_level...
+ ✅ FROST Datastream traffic_001/congestion_level créé (ID: 455)
+ 📊 FROST: POST Datastream traffic_001/occupancy_percent...
+ ✅ FROST Datastream traffic_001/occupancy_percent créé (ID: 456)
+ ⚠️ HTTP POST http://localhost:8090/FROST-Server/v1.1/Datastreams(453)/Observations → 400: {"code":400,"type":"error","message":"No FeatureOfInterest provided, and none can be generated."}
+ 📊 FROST: ❌
+ ✅ FROST Observation traffic_001/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_001/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_001/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_001, payload_mqtt exists: True
+2026-05-05 17:49:50.856 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:49:50.856 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:49:50.856 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:46890 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:49:50.858 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:49:50.858 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:46890 -> 127.0.0.1:6650]
+2026-05-05 17:49:50.858 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:46890 -> 127.0.0.1:6650]
+2026-05-05 17:49:50.859 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:46890 -> 127.0.0.1:6650]
+2026-05-05 17:49:50.859 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:49:50.861 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:49:50.861 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-439] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:49:50.862 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-439] Closed producer 0
+2026-05-05 17:49:50.862 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:46890 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:49:50.862 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:46890 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 4 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/traffic/traffic_002 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📊 FROST: POST Thing traffic_002...
+ ✅ FROST Thing traffic_002 créé (ID: 106)
+ 📊 FROST: POST Datastream traffic_002/vehicle_count...
+ ✅ FROST Datastream traffic_002/vehicle_count créé (ID: 457)
+ 📊 FROST: POST Datastream traffic_002/average_speed_kmh...
+ ✅ FROST Datastream traffic_002/average_speed_kmh créé (ID: 458)
+ 📊 FROST: POST Datastream traffic_002/congestion_level...
+ ✅ FROST Datastream traffic_002/congestion_level créé (ID: 459)
+ 📊 FROST: POST Datastream traffic_002/occupancy_percent...
+ ✅ FROST Datastream traffic_002/occupancy_percent créé (ID: 460)
+ ⚠️ HTTP POST http://localhost:8090/FROST-Server/v1.1/Datastreams(457)/Observations → 400: {"code":400,"type":"error","message":"No FeatureOfInterest provided, and none can be generated."}
+ 📊 FROST: ❌
+ ✅ FROST Observation traffic_002/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_002/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_002/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_002, payload_mqtt exists: True
+2026-05-05 17:49:53.830 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:49:53.830 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:49:53.831 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:33630 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:49:53.832 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:49:53.832 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:33630 -> 127.0.0.1:6650]
+2026-05-05 17:49:53.832 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:33630 -> 127.0.0.1:6650]
+2026-05-05 17:49:53.833 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:33630 -> 127.0.0.1:6650]
+2026-05-05 17:49:53.833 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:49:53.835 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:49:53.835 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-441] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:49:53.836 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-441] Closed producer 0
+2026-05-05 17:49:53.836 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:33630 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:49:53.836 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:33630 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/airquality/airquality_003 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 📈 InfluxDB: 4 points written
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📊 FROST: POST Thing airquality_003...
+ ✅ FROST Thing airquality_003 créé (ID: 107)
+ 📊 FROST: POST Datastream airquality_003/pm25_ugm3...
+ ✅ FROST Datastream airquality_003/pm25_ugm3 créé (ID: 461)
+ 📊 FROST: POST Datastream airquality_003/pm10_ugm3...
+ ✅ FROST Datastream airquality_003/pm10_ugm3 créé (ID: 462)
+ 📊 FROST: POST Datastream airquality_003/no2_ugm3...
+ ✅ FROST Datastream airquality_003/no2_ugm3 créé (ID: 463)
+ 📊 FROST: POST Datastream airquality_003/o3_ugm3...
+ ✅ FROST Datastream airquality_003/o3_ugm3 créé (ID: 464)
+ 📊 FROST: POST Datastream airquality_003/co_mgm3...
+ ✅ FROST Datastream airquality_003/co_mgm3 créé (ID: 465)
+ 📊 FROST: POST Datastream airquality_003/temperature_celsius...
+ ✅ FROST Datastream airquality_003/temperature_celsius créé (ID: 466)
+ 📊 FROST: POST Datastream airquality_003/humidity_percent...
+ ✅ FROST Datastream airquality_003/humidity_percent créé (ID: 467)
+ ⚠️ HTTP POST http://localhost:8090/FROST-Server/v1.1/Datastreams(461)/Observations → 400: {"code":400,"type":"error","message":"No FeatureOfInterest provided, and none can be generated."}
+ 📊 FROST: ❌
+ ✅ FROST Observation airquality_003/pm10_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/no2_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/o3_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/co_mgm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/temperature_celsius → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for airquality_003, payload_mqtt exists: True
+2026-05-05 17:49:55.575 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:49:55.575 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:49:55.576 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:33674 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:49:55.577 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-airquality, ] Getting connection from pool
+2026-05-05 17:49:55.578 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-airquality, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:33674 -> 127.0.0.1:6650]
+2026-05-05 17:49:55.578 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-airquality, producerName: on [127.0.0.1:33674 -> 127.0.0.1:6650]
+2026-05-05 17:49:55.579 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-airquality, ] Created producer on broker [127.0.0.1:33674 -> 127.0.0.1:6650]
+2026-05-05 17:49:55.579 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:49:55.581 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:49:55.581 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-airquality, standalone-0-445] Closing producer for topic persistent://public/default/smartcity-airquality
+2026-05-05 17:49:55.582 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-airquality, standalone-0-445] Closed producer 0
+2026-05-05 17:49:55.582 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:33674 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:49:55.582 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:33674 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 7 points written
+ ⚠️ Redpanda → timed out
+ 🐟 Redpanda: ❌
+ 📤 city/sensors/airquality/airquality_004 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📊 FROST: POST Thing airquality_004...
+ ✅ FROST Thing airquality_004 créé (ID: 108)
+ 📊 FROST: POST Datastream airquality_004/pm25_ugm3...
+ ✅ FROST Datastream airquality_004/pm25_ugm3 créé (ID: 468)
+ 📊 FROST: POST Datastream airquality_004/pm10_ugm3...
+ ✅ FROST Datastream airquality_004/pm10_ugm3 créé (ID: 469)
+ 📊 FROST: POST Datastream airquality_004/no2_ugm3...
+ ✅ FROST Datastream airquality_004/no2_ugm3 créé (ID: 470)
+ 📊 FROST: POST Datastream airquality_004/o3_ugm3...
+ ✅ FROST Datastream airquality_004/o3_ugm3 créé (ID: 471)
+ 📊 FROST: POST Datastream airquality_004/co_mgm3...
+ ✅ FROST Datastream airquality_004/co_mgm3 créé (ID: 472)
+ 📊 FROST: POST Datastream airquality_004/temperature_celsius...
+ ✅ FROST Datastream airquality_004/temperature_celsius créé (ID: 473)
+ 📊 FROST: POST Datastream airquality_004/humidity_percent...
+ ✅ FROST Datastream airquality_004/humidity_percent créé (ID: 474)
+ ⚠️ HTTP POST http://localhost:8090/FROST-Server/v1.1/Datastreams(468)/Observations → 400: {"code":400,"type":"error","message":"No FeatureOfInterest provided, and none can be generated."}
+ 📊 FROST: ❌
+ ✅ FROST Observation airquality_004/pm10_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/no2_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/o3_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/co_mgm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/temperature_celsius → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for airquality_004, payload_mqtt exists: True
+2026-05-05 17:50:04.218 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:04.218 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:04.218 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:34322 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:04.220 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-airquality, ] Getting connection from pool
+2026-05-05 17:50:04.220 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-airquality, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:34322 -> 127.0.0.1:6650]
+2026-05-05 17:50:04.220 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-airquality, producerName: on [127.0.0.1:34322 -> 127.0.0.1:6650]
+2026-05-05 17:50:04.220 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-airquality, ] Created producer on broker [127.0.0.1:34322 -> 127.0.0.1:6650]
+2026-05-05 17:50:04.220 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:50:04.222 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:04.222 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-airquality, standalone-0-451] Closing producer for topic persistent://public/default/smartcity-airquality
+2026-05-05 17:50:04.223 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-airquality, standalone-0-451] Closed producer 0
+2026-05-05 17:50:04.223 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:34322 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:04.223 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:34322 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 7 points written
+ ⚠️ Redpanda → timed out
+ 🐟 Redpanda: ❌
+ 📤 city/sensors/parking/parking_005 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📊 FROST: POST Thing parking_005...
+ ✅ FROST Thing parking_005 créé (ID: 109)
+ 📊 FROST: POST Datastream parking_005/total_spots...
+ ✅ FROST Datastream parking_005/total_spots créé (ID: 475)
+ 📊 FROST: POST Datastream parking_005/available_spots...
+ ✅ FROST Datastream parking_005/available_spots créé (ID: 476)
+ 📊 FROST: POST Datastream parking_005/occupancy_percent...
+ ✅ FROST Datastream parking_005/occupancy_percent créé (ID: 477)
+ 📊 FROST: POST Datastream parking_005/turnover_per_hour...
+ ✅ FROST Datastream parking_005/turnover_per_hour créé (ID: 478)
+ ⚠️ HTTP POST http://localhost:8090/FROST-Server/v1.1/Datastreams(475)/Observations → 400: {"code":400,"type":"error","message":"No FeatureOfInterest provided, and none can be generated."}
+ 📊 FROST: ❌
+ ✅ FROST Observation parking_005/available_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_005/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_005/turnover_per_hour → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for parking_005, payload_mqtt exists: True
+2026-05-05 17:50:12.835 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:12.835 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:12.836 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:34346 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:12.837 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-parking, ] Getting connection from pool
+2026-05-05 17:50:12.837 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-parking, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:34346 -> 127.0.0.1:6650]
+2026-05-05 17:50:12.837 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-parking, producerName: on [127.0.0.1:34346 -> 127.0.0.1:6650]
+2026-05-05 17:50:12.837 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-parking, ] Created producer on broker [127.0.0.1:34346 -> 127.0.0.1:6650]
+2026-05-05 17:50:12.837 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:50:12.839 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:12.839 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-parking, standalone-0-453] Closing producer for topic persistent://public/default/smartcity-parking
+2026-05-05 17:50:12.840 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-parking, standalone-0-453] Closed producer 0
+2026-05-05 17:50:12.840 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:34346 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:12.840 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:34346 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/parking/parking_006 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📊 FROST: POST Thing parking_006...
+ 📈 InfluxDB: 4 points written
+ ✅ FROST Thing parking_006 créé (ID: 110)
+ 📊 FROST: POST Datastream parking_006/total_spots...
+ ✅ FROST Datastream parking_006/total_spots créé (ID: 479)
+ 📊 FROST: POST Datastream parking_006/available_spots...
+ ✅ FROST Datastream parking_006/available_spots créé (ID: 480)
+ 📊 FROST: POST Datastream parking_006/occupancy_percent...
+ ✅ FROST Datastream parking_006/occupancy_percent créé (ID: 481)
+ 📊 FROST: POST Datastream parking_006/turnover_per_hour...
+ ✅ FROST Datastream parking_006/turnover_per_hour créé (ID: 482)
+ ⚠️ HTTP POST http://localhost:8090/FROST-Server/v1.1/Datastreams(479)/Observations → 400: {"code":400,"type":"error","message":"No FeatureOfInterest provided, and none can be generated."}
+ 📊 FROST: ❌
+ ✅ FROST Observation parking_006/available_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_006/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_006/turnover_per_hour → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for parking_006, payload_mqtt exists: True
+2026-05-05 17:50:13.368 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:13.368 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:13.369 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:34362 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:13.370 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-parking, ] Getting connection from pool
+2026-05-05 17:50:13.370 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-parking, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:34362 -> 127.0.0.1:6650]
+2026-05-05 17:50:13.370 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-parking, producerName: on [127.0.0.1:34362 -> 127.0.0.1:6650]
+2026-05-05 17:50:13.371 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-parking, ] Created producer on broker [127.0.0.1:34362 -> 127.0.0.1:6650]
+2026-05-05 17:50:13.371 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:50:13.373 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:13.373 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-parking, standalone-0-454] Closing producer for topic persistent://public/default/smartcity-parking
+2026-05-05 17:50:13.373 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-parking, standalone-0-454] Closed producer 0
+2026-05-05 17:50:13.373 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:34362 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:13.373 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:34362 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 4 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/noise/noise_007 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📊 FROST: POST Thing noise_007...
+ ✅ FROST Thing noise_007 créé (ID: 111)
+ 📊 FROST: POST Datastream noise_007/noise_level_db...
+ ✅ FROST Datastream noise_007/noise_level_db créé (ID: 483)
+ 📊 FROST: POST Datastream noise_007/peak_db...
+ ✅ FROST Datastream noise_007/peak_db créé (ID: 484)
+ ⚠️ HTTP POST http://localhost:8090/FROST-Server/v1.1/Datastreams(483)/Observations → 400: {"code":400,"type":"error","message":"No FeatureOfInterest provided, and none can be generated."}
+ 📊 FROST: ❌
+ ✅ FROST Observation noise_007/peak_db → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for noise_007, payload_mqtt exists: True
+2026-05-05 17:50:13.760 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:13.760 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:13.760 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:34376 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:13.762 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-noise, ] Getting connection from pool
+2026-05-05 17:50:13.762 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-noise, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:34376 -> 127.0.0.1:6650]
+2026-05-05 17:50:13.762 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-noise, producerName: on [127.0.0.1:34376 -> 127.0.0.1:6650]
+2026-05-05 17:50:13.762 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-noise, ] Created producer on broker [127.0.0.1:34376 -> 127.0.0.1:6650]
+2026-05-05 17:50:13.762 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:50:13.764 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:13.764 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-noise, standalone-0-455] Closing producer for topic persistent://public/default/smartcity-noise
+2026-05-05 17:50:13.765 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-noise, standalone-0-455] Closed producer 0
+2026-05-05 17:50:13.765 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:34376 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:13.765 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:34376 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 2 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/weather/weather_008 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📊 FROST: POST Thing weather_008...
+ ✅ FROST Thing weather_008 créé (ID: 112)
+ 📊 FROST: POST Datastream weather_008/temperature_celsius...
+ ✅ FROST Datastream weather_008/temperature_celsius créé (ID: 485)
+ 📊 FROST: POST Datastream weather_008/humidity_percent...
+ ✅ FROST Datastream weather_008/humidity_percent créé (ID: 486)
+ 📊 FROST: POST Datastream weather_008/wind_speed_kmh...
+ ✅ FROST Datastream weather_008/wind_speed_kmh créé (ID: 487)
+ 📊 FROST: POST Datastream weather_008/pressure_hpa...
+ ✅ FROST Datastream weather_008/pressure_hpa créé (ID: 488)
+ 📊 FROST: POST Datastream weather_008/rain_mm...
+ ✅ FROST Datastream weather_008/rain_mm créé (ID: 489)
+ 📊 FROST: POST Datastream weather_008/uv_index...
+ ✅ FROST Datastream weather_008/uv_index créé (ID: 490)
+ ⚠️ HTTP POST http://localhost:8090/FROST-Server/v1.1/Datastreams(485)/Observations → 400: {"code":400,"type":"error","message":"No FeatureOfInterest provided, and none can be generated."}
+ 📊 FROST: ❌
+ ✅ FROST Observation weather_008/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/wind_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/pressure_hpa → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/rain_mm → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/uv_index → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for weather_008, payload_mqtt exists: True
+2026-05-05 17:50:14.255 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:14.255 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:14.256 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:44174 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:14.259 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-weather, ] Getting connection from pool
+2026-05-05 17:50:14.261 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-weather, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:44174 -> 127.0.0.1:6650]
+2026-05-05 17:50:14.261 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-weather, producerName: on [127.0.0.1:44174 -> 127.0.0.1:6650]
+2026-05-05 17:50:14.263 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-weather, ] Created producer on broker [127.0.0.1:44174 -> 127.0.0.1:6650]
+2026-05-05 17:50:14.263 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 3 ms
+2026-05-05 17:50:14.267 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:14.267 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-weather, standalone-0-456] Closing producer for topic persistent://public/default/smartcity-weather
+2026-05-05 17:50:14.268 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-weather, standalone-0-456] Closed producer 0
+2026-05-05 17:50:14.269 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:44174 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:14.269 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:44174 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 6 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/light/light_009 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📊 FROST: POST Thing light_009...
+ ✅ FROST Thing light_009 créé (ID: 113)
+ 📊 FROST: POST Datastream light_009/brightness_lux...
+ ✅ FROST Datastream light_009/brightness_lux créé (ID: 491)
+ 📊 FROST: POST Datastream light_009/power_consumption_w...
+ ✅ FROST Datastream light_009/power_consumption_w créé (ID: 492)
+ ⚠️ HTTP POST http://localhost:8090/FROST-Server/v1.1/Datastreams(491)/Observations → 400: {"code":400,"type":"error","message":"No FeatureOfInterest provided, and none can be generated."}
+ 📊 FROST: ❌
+ ✅ FROST Observation light_009/power_consumption_w → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for light_009, payload_mqtt exists: True
+2026-05-05 17:50:14.745 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:14.745 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:14.745 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:44198 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:14.747 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-light, ] Getting connection from pool
+2026-05-05 17:50:14.748 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-light, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:44198 -> 127.0.0.1:6650]
+2026-05-05 17:50:14.748 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-light, producerName: on [127.0.0.1:44198 -> 127.0.0.1:6650]
+2026-05-05 17:50:14.749 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-light, ] Created producer on broker [127.0.0.1:44198 -> 127.0.0.1:6650]
+2026-05-05 17:50:14.749 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:50:14.752 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:14.752 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-light, standalone-0-458] Closing producer for topic persistent://public/default/smartcity-light
+2026-05-05 17:50:14.752 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-light, standalone-0-458] Closed producer 0
+2026-05-05 17:50:14.753 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:44198 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:14.753 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:44198 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 2 points written
+ 🐟 Redpanda: ✅
+[SIM] ✅ 10 capteurs | MQTT OK: 3/3 | OR: True
+
+[SIM] ⏱️ It #2 — 17:50:15
+ 📤 city/sensors/traffic/traffic_000 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation traffic_000/vehicle_count → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_000/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_000/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_000/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_000, payload_mqtt exists: True
+2026-05-05 17:50:16.707 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:16.707 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:16.707 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:44244 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:16.708 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:50:16.708 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:44244 -> 127.0.0.1:6650]
+2026-05-05 17:50:16.708 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:44244 -> 127.0.0.1:6650]
+2026-05-05 17:50:16.709 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:44244 -> 127.0.0.1:6650]
+2026-05-05 17:50:16.709 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:50:16.711 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:16.711 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-463] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:50:16.711 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-463] Closed producer 0
+2026-05-05 17:50:16.711 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:44244 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:16.711 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:44244 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/traffic/traffic_001 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 📈 InfluxDB: 4 points written
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation traffic_001/vehicle_count → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_001/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_001/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_001/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_001, payload_mqtt exists: True
+2026-05-05 17:50:18.994 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:18.994 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:18.994 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:44254 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:18.995 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:50:18.995 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:44254 -> 127.0.0.1:6650]
+2026-05-05 17:50:18.995 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:44254 -> 127.0.0.1:6650]
+2026-05-05 17:50:18.996 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:44254 -> 127.0.0.1:6650]
+2026-05-05 17:50:18.996 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:50:18.998 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:18.998 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-464] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:50:18.998 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-464] Closed producer 0
+2026-05-05 17:50:18.998 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:44254 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:18.998 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:44254 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/traffic/traffic_002 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📈 InfluxDB: 4 points written
+ ✅ FROST Observation traffic_002/vehicle_count → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_002/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_002/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_002/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_002, payload_mqtt exists: True
+2026-05-05 17:50:20.630 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:20.630 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:20.630 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:44268 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:20.632 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:50:20.633 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:44268 -> 127.0.0.1:6650]
+2026-05-05 17:50:20.633 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:44268 -> 127.0.0.1:6650]
+2026-05-05 17:50:20.634 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:44268 -> 127.0.0.1:6650]
+2026-05-05 17:50:20.634 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:50:20.701 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:20.701 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-466] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:50:20.702 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-466] Closed producer 0
+2026-05-05 17:50:20.702 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:44268 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:20.702 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:44268 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/airquality/airquality_003 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📈 InfluxDB: 4 points written
+ ✅ FROST Observation airquality_003/pm25_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/pm10_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/no2_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/o3_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/co_mgm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/temperature_celsius → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for airquality_003, payload_mqtt exists: True
+2026-05-05 17:50:22.129 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:22.129 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:22.129 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:44294 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:22.130 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-airquality, ] Getting connection from pool
+2026-05-05 17:50:22.130 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-airquality, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:44294 -> 127.0.0.1:6650]
+2026-05-05 17:50:22.130 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-airquality, producerName: on [127.0.0.1:44294 -> 127.0.0.1:6650]
+2026-05-05 17:50:22.131 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-airquality, ] Created producer on broker [127.0.0.1:44294 -> 127.0.0.1:6650]
+2026-05-05 17:50:22.131 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:50:22.133 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:22.133 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-airquality, standalone-0-468] Closing producer for topic persistent://public/default/smartcity-airquality
+2026-05-05 17:50:22.133 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-airquality, standalone-0-468] Closed producer 0
+2026-05-05 17:50:22.133 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:44294 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:22.133 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:44294 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 7 points written
+ ⚠️ Redpanda → timed out
+ 🐟 Redpanda: ❌
+ 📤 city/sensors/airquality/airquality_004 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation airquality_004/pm25_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/pm10_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/no2_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/o3_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/co_mgm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/temperature_celsius → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for airquality_004, payload_mqtt exists: True
+2026-05-05 17:50:30.445 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:30.445 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:30.446 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:54268 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:30.448 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-airquality, ] Getting connection from pool
+2026-05-05 17:50:30.448 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-airquality, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:54268 -> 127.0.0.1:6650]
+2026-05-05 17:50:30.448 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-airquality, producerName: on [127.0.0.1:54268 -> 127.0.0.1:6650]
+2026-05-05 17:50:30.449 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-airquality, ] Created producer on broker [127.0.0.1:54268 -> 127.0.0.1:6650]
+2026-05-05 17:50:30.449 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:50:30.452 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:30.452 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-airquality, standalone-0-471] Closing producer for topic persistent://public/default/smartcity-airquality
+2026-05-05 17:50:30.452 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-airquality, standalone-0-471] Closed producer 0
+2026-05-05 17:50:30.452 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:54268 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:30.452 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:54268 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 7 points written
+ ⚠️ Redpanda → timed out
+ 🐟 Redpanda: ❌
+ 📤 city/sensors/parking/parking_005 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation parking_005/total_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_005/available_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_005/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_005/turnover_per_hour → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for parking_005, payload_mqtt exists: True
+2026-05-05 17:50:38.679 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:38.679 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:38.680 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:55122 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:38.681 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-parking, ] Getting connection from pool
+2026-05-05 17:50:38.682 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-parking, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:55122 -> 127.0.0.1:6650]
+2026-05-05 17:50:38.682 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-parking, producerName: on [127.0.0.1:55122 -> 127.0.0.1:6650]
+2026-05-05 17:50:38.683 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-parking, ] Created producer on broker [127.0.0.1:55122 -> 127.0.0.1:6650]
+2026-05-05 17:50:38.683 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:50:38.687 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:38.687 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-parking, standalone-0-473] Closing producer for topic persistent://public/default/smartcity-parking
+2026-05-05 17:50:38.688 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-parking, standalone-0-473] Closed producer 0
+2026-05-05 17:50:38.688 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:55122 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:38.688 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:55122 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 4 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/parking/parking_006 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation parking_006/total_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_006/available_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_006/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_006/turnover_per_hour → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for parking_006, payload_mqtt exists: True
+2026-05-05 17:50:39.121 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:39.121 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:39.122 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:55132 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:39.124 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-parking, ] Getting connection from pool
+2026-05-05 17:50:39.125 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-parking, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:55132 -> 127.0.0.1:6650]
+2026-05-05 17:50:39.125 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-parking, producerName: on [127.0.0.1:55132 -> 127.0.0.1:6650]
+2026-05-05 17:50:39.126 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-parking, ] Created producer on broker [127.0.0.1:55132 -> 127.0.0.1:6650]
+2026-05-05 17:50:39.126 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:50:39.129 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:39.129 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-parking, standalone-0-474] Closing producer for topic persistent://public/default/smartcity-parking
+2026-05-05 17:50:39.130 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-parking, standalone-0-474] Closed producer 0
+2026-05-05 17:50:39.130 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:55132 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:39.130 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:55132 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/noise/noise_007 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 📈 InfluxDB: 4 points written
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation noise_007/noise_level_db → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation noise_007/peak_db → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for noise_007, payload_mqtt exists: True
+2026-05-05 17:50:39.436 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:39.436 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:39.437 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:55134 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:39.438 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-noise, ] Getting connection from pool
+2026-05-05 17:50:39.438 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-noise, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:55134 -> 127.0.0.1:6650]
+2026-05-05 17:50:39.438 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-noise, producerName: on [127.0.0.1:55134 -> 127.0.0.1:6650]
+2026-05-05 17:50:39.439 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-noise, ] Created producer on broker [127.0.0.1:55134 -> 127.0.0.1:6650]
+2026-05-05 17:50:39.439 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:50:39.442 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:39.442 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-noise, standalone-0-475] Closing producer for topic persistent://public/default/smartcity-noise
+2026-05-05 17:50:39.443 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-noise, standalone-0-475] Closed producer 0
+2026-05-05 17:50:39.443 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:55134 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:39.444 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:55134 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 2 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/weather/weather_008 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation weather_008/temperature_celsius → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/wind_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/pressure_hpa → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/rain_mm → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/uv_index → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for weather_008, payload_mqtt exists: True
+2026-05-05 17:50:40.906 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:40.907 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:40.907 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:55148 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:40.908 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-weather, ] Getting connection from pool
+2026-05-05 17:50:40.908 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-weather, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:55148 -> 127.0.0.1:6650]
+2026-05-05 17:50:40.908 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-weather, producerName: on [127.0.0.1:55148 -> 127.0.0.1:6650]
+2026-05-05 17:50:40.909 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-weather, ] Created producer on broker [127.0.0.1:55148 -> 127.0.0.1:6650]
+2026-05-05 17:50:40.909 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:50:40.911 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:40.911 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-weather, standalone-0-477] Closing producer for topic persistent://public/default/smartcity-weather
+2026-05-05 17:50:40.911 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-weather, standalone-0-477] Closed producer 0
+2026-05-05 17:50:40.911 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:55148 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:40.911 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:55148 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 6 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/light/light_009 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation light_009/brightness_lux → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation light_009/power_consumption_w → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for light_009, payload_mqtt exists: True
+2026-05-05 17:50:41.799 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:41.799 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:41.800 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:55164 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:41.802 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-light, ] Getting connection from pool
+2026-05-05 17:50:41.802 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-light, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:55164 -> 127.0.0.1:6650]
+2026-05-05 17:50:41.802 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-light, producerName: on [127.0.0.1:55164 -> 127.0.0.1:6650]
+2026-05-05 17:50:41.803 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-light, ] Created producer on broker [127.0.0.1:55164 -> 127.0.0.1:6650]
+2026-05-05 17:50:41.803 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:50:41.806 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:41.806 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-light, standalone-0-479] Closing producer for topic persistent://public/default/smartcity-light
+2026-05-05 17:50:41.806 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-light, standalone-0-479] Closed producer 0
+2026-05-05 17:50:41.807 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:55164 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:41.807 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:55164 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+[SIM] ✅ 10 capteurs | MQTT OK: 3/3 | OR: True
+ 📈 InfluxDB: 2 points written
+
+[SIM] ⏱️ It #3 — 17:50:42
+ 📤 city/sensors/traffic/traffic_000 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation traffic_000/vehicle_count → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_000/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_000/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_000/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_000, payload_mqtt exists: True
+2026-05-05 17:50:43.420 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:43.420 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:43.421 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:55186 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:43.422 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:50:43.422 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:55186 -> 127.0.0.1:6650]
+2026-05-05 17:50:43.422 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:55186 -> 127.0.0.1:6650]
+2026-05-05 17:50:43.422 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:55186 -> 127.0.0.1:6650]
+2026-05-05 17:50:43.422 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:50:43.425 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:43.425 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-483] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:50:43.425 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-483] Closed producer 0
+2026-05-05 17:50:43.425 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:55186 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:43.425 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:55186 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 4 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/traffic/traffic_001 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation traffic_001/vehicle_count → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_001/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_001/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_001/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_001, payload_mqtt exists: True
+2026-05-05 17:50:46.465 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:46.465 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:46.466 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:52028 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:46.466 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:50:46.468 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:52028 -> 127.0.0.1:6650]
+2026-05-05 17:50:46.468 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:52028 -> 127.0.0.1:6650]
+2026-05-05 17:50:46.468 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:52028 -> 127.0.0.1:6650]
+2026-05-05 17:50:46.468 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:50:46.470 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:46.470 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-484] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:50:46.471 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-484] Closed producer 0
+2026-05-05 17:50:46.471 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:52028 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:46.471 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:52028 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/traffic/traffic_002 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 📈 InfluxDB: 4 points written
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation traffic_002/vehicle_count → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_002/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_002/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_002/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_002, payload_mqtt exists: True
+2026-05-05 17:50:48.496 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:48.496 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:48.497 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:52044 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:48.498 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:50:48.498 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:52044 -> 127.0.0.1:6650]
+2026-05-05 17:50:48.498 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:52044 -> 127.0.0.1:6650]
+2026-05-05 17:50:48.499 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:52044 -> 127.0.0.1:6650]
+2026-05-05 17:50:48.499 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:50:48.501 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:48.501 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-485] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:50:48.501 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-485] Closed producer 0
+2026-05-05 17:50:48.501 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:52044 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:48.501 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:52044 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/airquality/airquality_003 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 📈 InfluxDB: 4 points written
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation airquality_003/pm25_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/pm10_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/no2_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/o3_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/co_mgm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/temperature_celsius → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for airquality_003, payload_mqtt exists: True
+2026-05-05 17:50:51.508 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:50:51.508 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:50:51.509 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:52056 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:50:51.512 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-airquality, ] Getting connection from pool
+2026-05-05 17:50:51.513 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-airquality, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:52056 -> 127.0.0.1:6650]
+2026-05-05 17:50:51.513 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-airquality, producerName: on [127.0.0.1:52056 -> 127.0.0.1:6650]
+2026-05-05 17:50:51.515 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-airquality, ] Created producer on broker [127.0.0.1:52056 -> 127.0.0.1:6650]
+2026-05-05 17:50:51.516 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 2 ms
+2026-05-05 17:50:51.518 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:50:51.518 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-airquality, standalone-0-486] Closing producer for topic persistent://public/default/smartcity-airquality
+2026-05-05 17:50:51.519 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-airquality, standalone-0-486] Closed producer 0
+2026-05-05 17:50:51.519 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:52056 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:50:51.519 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:52056 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 7 points written
+ ⚠️ Redpanda → timed out
+ 🐟 Redpanda: ❌
+ 📤 city/sensors/airquality/airquality_004 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation airquality_004/pm25_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/pm10_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/no2_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/o3_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/co_mgm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/temperature_celsius → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for airquality_004, payload_mqtt exists: True
+2026-05-05 17:51:00.657 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:00.657 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:00.658 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:38254 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:00.659 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-airquality, ] Getting connection from pool
+2026-05-05 17:51:00.659 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-airquality, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:38254 -> 127.0.0.1:6650]
+2026-05-05 17:51:00.659 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-airquality, producerName: on [127.0.0.1:38254 -> 127.0.0.1:6650]
+2026-05-05 17:51:00.660 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-airquality, ] Created producer on broker [127.0.0.1:38254 -> 127.0.0.1:6650]
+2026-05-05 17:51:00.660 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:51:00.662 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:00.662 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-airquality, standalone-0-487] Closing producer for topic persistent://public/default/smartcity-airquality
+2026-05-05 17:51:00.662 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-airquality, standalone-0-487] Closed producer 0
+2026-05-05 17:51:00.662 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:38254 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:00.662 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:38254 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 7 points written
+ ⚠️ Redpanda → timed out
+ 🐟 Redpanda: ❌
+ 📤 city/sensors/parking/parking_005 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation parking_005/total_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_005/available_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_005/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_005/turnover_per_hour → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for parking_005, payload_mqtt exists: True
+2026-05-05 17:51:09.046 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:09.046 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:09.047 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:45450 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:09.047 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-parking, ] Getting connection from pool
+2026-05-05 17:51:09.048 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-parking, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:45450 -> 127.0.0.1:6650]
+2026-05-05 17:51:09.048 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-parking, producerName: on [127.0.0.1:45450 -> 127.0.0.1:6650]
+2026-05-05 17:51:09.048 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-parking, ] Created producer on broker [127.0.0.1:45450 -> 127.0.0.1:6650]
+2026-05-05 17:51:09.048 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:51:09.050 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:09.050 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-parking, standalone-0-488] Closing producer for topic persistent://public/default/smartcity-parking
+2026-05-05 17:51:09.051 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-parking, standalone-0-488] Closed producer 0
+2026-05-05 17:51:09.051 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:45450 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:09.051 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:45450 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/parking/parking_006 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 📈 InfluxDB: 4 points written
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation parking_006/total_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_006/available_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_006/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_006/turnover_per_hour → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for parking_006, payload_mqtt exists: True
+2026-05-05 17:51:09.530 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:09.530 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:09.531 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:45464 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:09.532 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-parking, ] Getting connection from pool
+2026-05-05 17:51:09.533 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-parking, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:45464 -> 127.0.0.1:6650]
+2026-05-05 17:51:09.533 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-parking, producerName: on [127.0.0.1:45464 -> 127.0.0.1:6650]
+2026-05-05 17:51:09.533 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-parking, ] Created producer on broker [127.0.0.1:45464 -> 127.0.0.1:6650]
+2026-05-05 17:51:09.533 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:51:09.536 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:09.536 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-parking, standalone-0-489] Closing producer for topic persistent://public/default/smartcity-parking
+2026-05-05 17:51:09.536 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-parking, standalone-0-489] Closed producer 0
+2026-05-05 17:51:09.536 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:45464 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:09.536 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:45464 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 4 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/noise/noise_007 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation noise_007/noise_level_db → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation noise_007/peak_db → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for noise_007, payload_mqtt exists: True
+2026-05-05 17:51:10.022 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:10.022 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:10.022 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:45478 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:10.023 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-noise, ] Getting connection from pool
+2026-05-05 17:51:10.023 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-noise, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:45478 -> 127.0.0.1:6650]
+2026-05-05 17:51:10.023 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-noise, producerName: on [127.0.0.1:45478 -> 127.0.0.1:6650]
+2026-05-05 17:51:10.024 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-noise, ] Created producer on broker [127.0.0.1:45478 -> 127.0.0.1:6650]
+2026-05-05 17:51:10.024 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:51:10.026 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:10.026 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-noise, standalone-0-490] Closing producer for topic persistent://public/default/smartcity-noise
+2026-05-05 17:51:10.026 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-noise, standalone-0-490] Closed producer 0
+2026-05-05 17:51:10.026 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:45478 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:10.027 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:45478 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/weather/weather_008 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 📈 InfluxDB: 2 points written
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation weather_008/temperature_celsius → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/wind_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/pressure_hpa → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/rain_mm → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/uv_index → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for weather_008, payload_mqtt exists: True
+2026-05-05 17:51:10.575 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:10.575 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:10.575 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:45492 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:10.577 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-weather, ] Getting connection from pool
+2026-05-05 17:51:10.578 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-weather, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:45492 -> 127.0.0.1:6650]
+2026-05-05 17:51:10.578 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-weather, producerName: on [127.0.0.1:45492 -> 127.0.0.1:6650]
+2026-05-05 17:51:10.579 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-weather, ] Created producer on broker [127.0.0.1:45492 -> 127.0.0.1:6650]
+2026-05-05 17:51:10.579 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:51:10.581 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:10.581 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-weather, standalone-0-491] Closing producer for topic persistent://public/default/smartcity-weather
+2026-05-05 17:51:10.582 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-weather, standalone-0-491] Closed producer 0
+2026-05-05 17:51:10.582 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:45492 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:10.582 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:45492 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 6 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/light/light_009 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation light_009/brightness_lux → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation light_009/power_consumption_w → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for light_009, payload_mqtt exists: True
+2026-05-05 17:51:10.881 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:10.881 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:10.882 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:45500 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:10.883 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-light, ] Getting connection from pool
+2026-05-05 17:51:10.883 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-light, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:45500 -> 127.0.0.1:6650]
+2026-05-05 17:51:10.883 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-light, producerName: on [127.0.0.1:45500 -> 127.0.0.1:6650]
+2026-05-05 17:51:10.884 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-light, ] Created producer on broker [127.0.0.1:45500 -> 127.0.0.1:6650]
+2026-05-05 17:51:10.884 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:51:10.886 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:10.886 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-light, standalone-0-492] Closing producer for topic persistent://public/default/smartcity-light
+2026-05-05 17:51:10.886 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-light, standalone-0-492] Closed producer 0
+2026-05-05 17:51:10.886 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:45500 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:10.886 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:45500 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+[SIM] ✅ 10 capteurs | MQTT OK: 3/3 | OR: True
+ 📈 InfluxDB: 2 points written
+
+[SIM] ⏱️ It #4 — 17:51:11
+ 📤 city/sensors/traffic/traffic_000 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation traffic_000/vehicle_count → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_000/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_000/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_000/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_000, payload_mqtt exists: True
+2026-05-05 17:51:12.325 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:12.325 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:12.326 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:45502 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:12.327 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:51:12.327 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:45502 -> 127.0.0.1:6650]
+2026-05-05 17:51:12.327 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:45502 -> 127.0.0.1:6650]
+2026-05-05 17:51:12.327 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:45502 -> 127.0.0.1:6650]
+2026-05-05 17:51:12.327 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:51:12.329 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:12.329 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-493] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:51:12.330 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-493] Closed producer 0
+2026-05-05 17:51:12.330 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:45502 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:12.330 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:45502 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 4 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/traffic/traffic_001 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation traffic_001/vehicle_count → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_001/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_001/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_001/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_001, payload_mqtt exists: True
+2026-05-05 17:51:12.809 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:12.809 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:12.810 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:45512 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:12.811 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:51:12.811 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:45512 -> 127.0.0.1:6650]
+2026-05-05 17:51:12.811 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:45512 -> 127.0.0.1:6650]
+2026-05-05 17:51:12.811 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:45512 -> 127.0.0.1:6650]
+2026-05-05 17:51:12.811 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:51:12.813 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:12.813 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-494] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:51:12.814 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-494] Closed producer 0
+2026-05-05 17:51:12.814 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:45512 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:12.814 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:45512 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/traffic/traffic_002 → EMQX,Mosquitto,BunkerM
+ ⚠️ OpenRemote token → HTTP Error 405: Method Not Allowed
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 📈 InfluxDB: 4 points written
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation traffic_002/vehicle_count → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_002/average_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_002/congestion_level → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation traffic_002/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for traffic_002, payload_mqtt exists: True
+2026-05-05 17:51:14.020 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:14.020 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:14.021 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:44512 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:14.021 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-traffic, ] Getting connection from pool
+2026-05-05 17:51:14.022 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-traffic, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:44512 -> 127.0.0.1:6650]
+2026-05-05 17:51:14.022 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-traffic, producerName: on [127.0.0.1:44512 -> 127.0.0.1:6650]
+2026-05-05 17:51:14.022 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-traffic, ] Created producer on broker [127.0.0.1:44512 -> 127.0.0.1:6650]
+2026-05-05 17:51:14.022 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:51:14.024 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:14.024 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-traffic, standalone-0-495] Closing producer for topic persistent://public/default/smartcity-traffic
+2026-05-05 17:51:14.024 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-traffic, standalone-0-495] Closed producer 0
+2026-05-05 17:51:14.025 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:44512 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:14.025 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:44512 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/airquality/airquality_003 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ 📈 InfluxDB: 4 points written
+ ✅ FROST Observation airquality_003/pm25_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/pm10_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/no2_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/o3_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/co_mgm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/temperature_celsius → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_003/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for airquality_003, payload_mqtt exists: True
+2026-05-05 17:51:16.506 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:16.506 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:16.506 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:44522 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:16.507 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-airquality, ] Getting connection from pool
+2026-05-05 17:51:16.508 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-airquality, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:44522 -> 127.0.0.1:6650]
+2026-05-05 17:51:16.508 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-airquality, producerName: on [127.0.0.1:44522 -> 127.0.0.1:6650]
+2026-05-05 17:51:16.508 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-airquality, ] Created producer on broker [127.0.0.1:44522 -> 127.0.0.1:6650]
+2026-05-05 17:51:16.508 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:51:16.510 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:16.510 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-airquality, standalone-0-496] Closing producer for topic persistent://public/default/smartcity-airquality
+2026-05-05 17:51:16.511 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-airquality, standalone-0-496] Closed producer 0
+2026-05-05 17:51:16.511 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:44522 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:16.511 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:44522 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 7 points written
+ ⚠️ Redpanda → timed out
+ 🐟 Redpanda: ❌
+ 📤 city/sensors/airquality/airquality_004 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation airquality_004/pm25_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/pm10_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/no2_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/o3_ugm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/co_mgm3 → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/temperature_celsius → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation airquality_004/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for airquality_004, payload_mqtt exists: True
+2026-05-05 17:51:24.991 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:24.991 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:24.992 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:54640 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:24.993 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-airquality, ] Getting connection from pool
+2026-05-05 17:51:24.994 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-airquality, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:54640 -> 127.0.0.1:6650]
+2026-05-05 17:51:24.994 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-airquality, producerName: on [127.0.0.1:54640 -> 127.0.0.1:6650]
+2026-05-05 17:51:24.995 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-airquality, ] Created producer on broker [127.0.0.1:54640 -> 127.0.0.1:6650]
+2026-05-05 17:51:24.995 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:51:24.997 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:24.997 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-airquality, standalone-0-497] Closing producer for topic persistent://public/default/smartcity-airquality
+2026-05-05 17:51:24.997 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-airquality, standalone-0-497] Closed producer 0
+2026-05-05 17:51:24.997 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:54640 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:24.997 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:54640 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 7 points written
+
+[SIM] 🛑 Arrêt...
+ ⚠️ Redpanda → timed out
+ 🐟 Redpanda: ❌
+ 📤 city/sensors/parking/parking_005 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation parking_005/total_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_005/available_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_005/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_005/turnover_per_hour → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for parking_005, payload_mqtt exists: True
+2026-05-05 17:51:33.472 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:33.472 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:33.473 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:54650 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:33.474 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-parking, ] Getting connection from pool
+2026-05-05 17:51:33.475 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-parking, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:54650 -> 127.0.0.1:6650]
+2026-05-05 17:51:33.475 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-parking, producerName: on [127.0.0.1:54650 -> 127.0.0.1:6650]
+2026-05-05 17:51:33.476 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-parking, ] Created producer on broker [127.0.0.1:54650 -> 127.0.0.1:6650]
+2026-05-05 17:51:33.476 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:51:33.478 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:33.478 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-parking, standalone-0-499] Closing producer for topic persistent://public/default/smartcity-parking
+2026-05-05 17:51:33.478 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-parking, standalone-0-499] Closed producer 0
+2026-05-05 17:51:33.479 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:54650 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:33.479 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:54650 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/parking/parking_006 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 📈 InfluxDB: 4 points written
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation parking_006/total_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_006/available_spots → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_006/occupancy_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation parking_006/turnover_per_hour → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for parking_006, payload_mqtt exists: True
+2026-05-05 17:51:33.905 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:33.905 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:33.905 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:59186 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:33.907 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-parking, ] Getting connection from pool
+2026-05-05 17:51:33.907 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-parking, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:59186 -> 127.0.0.1:6650]
+2026-05-05 17:51:33.907 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-parking, producerName: on [127.0.0.1:59186 -> 127.0.0.1:6650]
+2026-05-05 17:51:33.908 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-parking, ] Created producer on broker [127.0.0.1:59186 -> 127.0.0.1:6650]
+2026-05-05 17:51:33.908 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 1 ms
+2026-05-05 17:51:33.911 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:33.911 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-parking, standalone-0-500] Closing producer for topic persistent://public/default/smartcity-parking
+2026-05-05 17:51:33.911 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-parking, standalone-0-500] Closed producer 0
+2026-05-05 17:51:33.911 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:59186 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:33.911 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:59186 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 4 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/noise/noise_007 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation noise_007/noise_level_db → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation noise_007/peak_db → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for noise_007, payload_mqtt exists: True
+2026-05-05 17:51:34.215 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:34.215 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:34.215 INFO [137324180526784] ClientConnection:421 | [127.0.0.1:59194 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:34.216 INFO [137324180526784] HandlerBase:112 | [persistent://public/default/smartcity-noise, ] Getting connection from pool
+2026-05-05 17:51:34.216 INFO [137324180526784] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-noise, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:59194 -> 127.0.0.1:6650]
+2026-05-05 17:51:34.216 INFO [137324180526784] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-noise, producerName: on [127.0.0.1:59194 -> 127.0.0.1:6650]
+2026-05-05 17:51:34.217 INFO [137324180526784] ProducerImpl:222 | [persistent://public/default/smartcity-noise, ] Created producer on broker [127.0.0.1:59194 -> 127.0.0.1:6650]
+2026-05-05 17:51:34.217 INFO [137324180526784] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:51:34.219 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:34.219 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-noise, standalone-0-501] Closing producer for topic persistent://public/default/smartcity-noise
+2026-05-05 17:51:34.219 INFO [137324180526784] ProducerImpl:767 | [persistent://public/default/smartcity-noise, standalone-0-501] Closed producer 0
+2026-05-05 17:51:34.219 INFO [137324188919488] ClientConnection:1285 | [127.0.0.1:59194 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:34.220 INFO [137324188919488] ClientConnection:301 | [127.0.0.1:59194 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 2 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/weather/weather_008 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation weather_008/temperature_celsius → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/humidity_percent → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/wind_speed_kmh → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/pressure_hpa → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/rain_mm → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation weather_008/uv_index → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for weather_008, payload_mqtt exists: True
+2026-05-05 17:51:34.753 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:34.753 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:34.753 INFO [137324197312192] ClientConnection:421 | [127.0.0.1:59200 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:34.754 INFO [137324197312192] HandlerBase:112 | [persistent://public/default/smartcity-weather, ] Getting connection from pool
+2026-05-05 17:51:34.755 INFO [137324197312192] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-weather, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:59200 -> 127.0.0.1:6650]
+2026-05-05 17:51:34.755 INFO [137324197312192] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-weather, producerName: on [127.0.0.1:59200 -> 127.0.0.1:6650]
+2026-05-05 17:51:34.755 INFO [137324197312192] ProducerImpl:222 | [persistent://public/default/smartcity-weather, ] Created producer on broker [127.0.0.1:59200 -> 127.0.0.1:6650]
+2026-05-05 17:51:34.755 INFO [137324197312192] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:51:34.757 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:34.757 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-weather, standalone-0-502] Closing producer for topic persistent://public/default/smartcity-weather
+2026-05-05 17:51:34.757 INFO [137324197312192] ProducerImpl:767 | [persistent://public/default/smartcity-weather, standalone-0-502] Closed producer 0
+2026-05-05 17:51:34.758 INFO [137324180526784] ClientConnection:1285 | [127.0.0.1:59200 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:34.758 INFO [137324180526784] ClientConnection:301 | [127.0.0.1:59200 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 6 points written
+ 🐟 Redpanda: ✅
+ 📤 city/sensors/light/light_009 → EMQX,Mosquitto,BunkerM
+ 🏠 OpenRemote: ⚠️ skipped
+ 🌐 Orion-LD: ✅ (HTTP 204 updated)
+ 🌐 Orion-LD: ✅
+ 🏢 Stellio: ✅ (HTTP 204 updated)
+ 🏢 Stellio: ✅
+ ✅ FROST Observation light_009/brightness_lux → OK (cached)
+ 📊 FROST: ✅
+ ✅ FROST Observation light_009/power_consumption_w → OK (cached)
+ 📊 FROST: ✅
+ 📈 InfluxDB: ✅
+ 🌪️ DEBUG: calling publish_pulsar for light_009, payload_mqtt exists: True
+2026-05-05 17:51:35.022 INFO [137324718683968] ClientConnection:209 | [ -> pulsar://localhost:6650] Create ClientConnection, timeout=10000
+2026-05-05 17:51:35.022 INFO [137324718683968] ConnectionPool:148 | Created connection for pulsar://localhost:6650-pulsar://localhost:6650-0
+2026-05-05 17:51:35.022 INFO [137324188919488] ClientConnection:421 | [127.0.0.1:59214 -> 127.0.0.1:6650] Connected to broker
+2026-05-05 17:51:35.023 INFO [137324188919488] HandlerBase:112 | [persistent://public/default/smartcity-light, ] Getting connection from pool
+2026-05-05 17:51:35.024 INFO [137324188919488] BinaryProtoLookupService:85 | Lookup response for persistent://public/default/smartcity-light, lookup-broker-url pulsar://localhost:6650, from [127.0.0.1:59214 -> 127.0.0.1:6650]
+2026-05-05 17:51:35.024 INFO [137324188919488] ProducerImpl:148 | Creating producer for topic:persistent://public/default/smartcity-light, producerName: on [127.0.0.1:59214 -> 127.0.0.1:6650]
+2026-05-05 17:51:35.024 INFO [137324188919488] ProducerImpl:222 | [persistent://public/default/smartcity-light, ] Created producer on broker [127.0.0.1:59214 -> 127.0.0.1:6650]
+2026-05-05 17:51:35.024 INFO [137324188919488] HandlerBase:134 | Finished connecting to broker after 0 ms
+2026-05-05 17:51:35.026 INFO [137324718683968] ClientImpl:718 | Closing Pulsar client with 1 producers and 0 consumers
+2026-05-05 17:51:35.026 INFO [137324718683968] ProducerImpl:803 | [persistent://public/default/smartcity-light, standalone-0-503] Closing producer for topic persistent://public/default/smartcity-light
+2026-05-05 17:51:35.027 INFO [137324188919488] ProducerImpl:767 | [persistent://public/default/smartcity-light, standalone-0-503] Closed producer 0
+2026-05-05 17:51:35.027 INFO [137324197312192] ClientConnection:1285 | [127.0.0.1:59214 -> 127.0.0.1:6650] Connection disconnected (refCnt: 4)
+2026-05-05 17:51:35.027 INFO [137324197312192] ClientConnection:301 | [127.0.0.1:59214 -> 127.0.0.1:6650] Destroyed connection to pulsar://localhost:6650-0
+ 🌪️ Pulsar: ✅
+ 📈 InfluxDB: 2 points written
+ 🐟 Redpanda: ✅
+[SIM] ✅ 10 capteurs | MQTT OK: 3/3 | OR: True
+[MQTT] ⚠️ EMQX déconnecté
+[MQTT] ⚠️ Mosquitto déconnecté
+[MQTT] ⚠️ BunkerM déconnecté
+[SIM] ✅ Arrêté proprement.