fix: Simulateur MQTT 3/4 + OpenRemote master + Mapsettings
- MQTT OK: 3/4 (EMQX, Mosquitto, BunkerM) - OpenRemote: utilise realm master (token fonctionnel) - Realm smartcity recréé dans Keycloak - Assets IOTSensor créés dans master (30) et smartcity (30) - Mapsettings: layers iot-sensors + labels pour master et smartcity - INTERVAL=5s, réseau openremote_default ajouté - Dockerfile: --no-cache rebuild
This commit is contained in:
5
Dockerfile.exporter
Normal file
5
Dockerfile.exporter
Normal file
@@ -0,0 +1,5 @@
|
||||
FROM python:3.13-slim
|
||||
RUN pip install docker prometheus_client
|
||||
COPY docker_exporter.py /app/docker_exporter.py
|
||||
WORKDIR /app
|
||||
CMD ["python3", "docker_exporter.py", "8005"]
|
||||
Binary file not shown.
78
create_openremote_agents.sql
Normal file
78
create_openremote_agents.sql
Normal file
@@ -0,0 +1,78 @@
|
||||
-- Create 60 MQTT agents for OpenRemote using PL/pgSQL block
|
||||
-- Realm master: parent_id = '2LtWTTd29uPZLbuWMWUxBf'
|
||||
-- Realm smartcity: parent_id = 'e174aad5c7b5489e8b2efe'
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
|
||||
DO $$
|
||||
DECLARE
|
||||
sensor_types text[] := ARRAY['airquality', 'traffic', 'parking', 'noise', 'weather', 'waterquality'];
|
||||
realm_rec RECORD;
|
||||
sensor_type text;
|
||||
i integer;
|
||||
new_id text;
|
||||
new_name text;
|
||||
new_topic text;
|
||||
parent_id text;
|
||||
realm_name text;
|
||||
BEGIN
|
||||
-- Delete existing MQTT agents
|
||||
DELETE FROM asset WHERE type = 'urn:openremote:agent:mqtt';
|
||||
|
||||
-- Loop over realms
|
||||
FOR realm_rec IN SELECT * FROM (VALUES ('master', '2LtWTTd29uPZLbuWMWUxBf'), ('smartcity', 'e174aad5c7b5489e8b2efe')) AS t(realm, parent) LOOP
|
||||
realm_name := realm_rec.realm;
|
||||
parent_id := realm_rec.parent;
|
||||
|
||||
FOREACH sensor_type IN ARRAY sensor_types LOOP
|
||||
FOR i IN 1..5 LOOP
|
||||
new_id := LEFT(REPLACE(gen_random_uuid()::text, '-', ''), 22);
|
||||
new_name := 'MQTT-Agent-' || sensor_type || '-' || i;
|
||||
new_topic := 'smartcity/' || sensor_type || '/' || i;
|
||||
|
||||
INSERT INTO asset (id, name, type, realm, parent_id, created_on, access_public_read, version, attributes)
|
||||
VALUES (
|
||||
new_id,
|
||||
new_name,
|
||||
'urn:openremote:agent:mqtt',
|
||||
realm_name,
|
||||
parent_id,
|
||||
NOW(),
|
||||
false,
|
||||
1,
|
||||
jsonb_build_object(
|
||||
'name', jsonb_build_object('type', 'String', 'value', new_name),
|
||||
'agentLink', jsonb_build_object(
|
||||
'type', 'Property',
|
||||
'value', jsonb_build_object(
|
||||
'type', 'mqtt',
|
||||
'brokerUrl', 'tcp://openremote-manager-1:1883',
|
||||
'topicFilter', new_topic,
|
||||
'username', '',
|
||||
'password', '',
|
||||
'enabled', true
|
||||
)
|
||||
),
|
||||
'sensorType', jsonb_build_object('type', 'String', 'value', sensor_type),
|
||||
'location', jsonb_build_object(
|
||||
'type', 'GeoJSONPoint',
|
||||
'value', jsonb_build_object(
|
||||
'type', 'Point',
|
||||
'coordinates', jsonb_build_array(
|
||||
14.6091 + (random() - 0.5) * 0.1,
|
||||
-61.2155 + (random() - 0.5) * 0.1
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
END LOOP;
|
||||
END LOOP;
|
||||
END LOOP;
|
||||
END $$;
|
||||
|
||||
-- Verify insertion
|
||||
SELECT realm, COUNT(*) as agent_count
|
||||
FROM asset
|
||||
WHERE type = 'urn:openremote:agent:mqtt'
|
||||
GROUP BY realm;
|
||||
@@ -22,10 +22,10 @@ services:
|
||||
- ditto-mongodb
|
||||
environment:
|
||||
- DITTO_JWT_SECRET=my-ditto-secret-12345
|
||||
- MONGO_HOST=ditto-mongodb
|
||||
- MONGO_HOST=smart-city-ditto-mongodb
|
||||
- MONGO_PORT=27017
|
||||
- MONGO_DB=Policies
|
||||
# Supprimer MONGO_URI pour éviter confusion
|
||||
- AKKA_REMOTE_ENABLED=false
|
||||
networks:
|
||||
traefik-public:
|
||||
aliases:
|
||||
@@ -47,9 +47,10 @@ services:
|
||||
- ditto-policies
|
||||
environment:
|
||||
- DITTO_JWT_SECRET=my-ditto-secret-12345
|
||||
- MONGO_HOST=ditto-mongodb
|
||||
- MONGO_HOST=smart-city-ditto-mongodb
|
||||
- MONGO_PORT=27017
|
||||
- MONGO_DB=Things
|
||||
- AKKA_REMOTE_ENABLED=false
|
||||
networks:
|
||||
traefik-public:
|
||||
aliases:
|
||||
@@ -71,7 +72,11 @@ services:
|
||||
- ditto-policies
|
||||
environment:
|
||||
- DITTO_JWT_SECRET=my-ditto-secret-12345
|
||||
- DITTO_GATEWAY_PROXY_ENABLED=false
|
||||
- DITTO_GATEWAY_PROXY_ENABLED=true
|
||||
- AKKA_REMOTE_ENABLED=false
|
||||
- DITTO_GW_STREAMING_ENABLED=true
|
||||
- DITTO_GW_MQTT_BROKER=smart-city-mosquitto:1883
|
||||
- DITTO_GW_MQTT_TOPIC_FILTER=smartcity/#
|
||||
networks:
|
||||
traefik-public:
|
||||
aliases:
|
||||
|
||||
@@ -10,7 +10,6 @@ networks:
|
||||
volumes:
|
||||
influxdb_data:
|
||||
external: false
|
||||
name: digital-twin_influxdb_data
|
||||
|
||||
services:
|
||||
influxdb:
|
||||
@@ -24,10 +23,10 @@ services:
|
||||
environment:
|
||||
- DOCKER_INFLUXDB_INIT_MODE=setup
|
||||
- DOCKER_INFLUXDB_INIT_USERNAME=admin
|
||||
- DOCKER_INFLUXDB_INIT_PASSWORD=admin1234
|
||||
- DOCKER_INFLUXDB_INIT_PASSWORD=Digitribe972
|
||||
- DOCKER_INFLUXDB_INIT_ORG=digitribe
|
||||
- DOCKER_INFLUXDB_INIT_BUCKET=iot_data
|
||||
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=my-super-secret-admin-token
|
||||
- DOCKER_INFLUXDB_INIT_BUCKET=smartcity
|
||||
- DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=my-super-token
|
||||
volumes:
|
||||
- influxdb_data:/var/lib/influxdb2
|
||||
restart: unless-stopped
|
||||
|
||||
@@ -25,7 +25,7 @@ services:
|
||||
ports:
|
||||
- "4200:4200"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "-X", "POST", "-d", "{\"stmt\": \"SELECT 1\"}", "http://localhost:4200/_sql"]
|
||||
test: ["CMD-SHELL", "curl -s -f http://localhost:4200/ > /dev/null || exit 1"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
@@ -9,20 +9,27 @@ networks:
|
||||
external: true
|
||||
traefik-public:
|
||||
external: true
|
||||
openremote_default:
|
||||
external: true
|
||||
|
||||
services:
|
||||
# Smart City Simulator
|
||||
simulator:
|
||||
build: .
|
||||
container_name: smart-city-simulator
|
||||
tty: true
|
||||
stdin_open: true
|
||||
networks:
|
||||
- smartcity-shared
|
||||
- traefik-public
|
||||
- openremote_default
|
||||
environment:
|
||||
# MQTT Brokers
|
||||
- ENABLE_EMQX=true
|
||||
- ENABLE_MOSQUITTO=true
|
||||
- ENABLE_BUNKER=true
|
||||
# MQTT Brokers - ALL enabled
|
||||
- ENABLE_EMQX=1
|
||||
- ENABLE_MOSQUITTO=1
|
||||
- ENABLE_BUNKER=1
|
||||
- BUNKERM_HOST=bunkerm_bunkerm_1
|
||||
- BUNKERM_PORT=1900
|
||||
# Context Brokers (DESACTIVE - tout passe par les IoT Agents via MQTT)
|
||||
- ENABLE_ORION=false
|
||||
- ENABLE_STELLIO=false
|
||||
@@ -30,15 +37,21 @@ services:
|
||||
# Databases
|
||||
- ENABLE_INFLUX=true
|
||||
- INFLUX_URL=http://smart-city-influxdb:8086
|
||||
# Pulsar (Disabled for demo stability - was causing 0.0.0.0:0 errors)
|
||||
# OpenRemote
|
||||
- ENABLE_OPENREMOTE=1
|
||||
- OR_URL=http://openremote_manager_1:8080
|
||||
- OR_REALM=master
|
||||
- OR_TOKEN_REALM=master
|
||||
- OR_ADMIN_USER=admin
|
||||
- OR_ADMIN_PASS=Digitribe972
|
||||
- OR_CLIENT_SECRET=0oQjzTfiEELYmj5jFwT4iIuWUDtQDvVa
|
||||
# Pulsar (Disabled for demo stability)
|
||||
- ENABLE_PULSAR=false
|
||||
# - PULSAR_HOST=smart-city-pulsar
|
||||
# - PULSAR_PORT=6650
|
||||
# Redpanda (Disabled - troubleshooting)
|
||||
# Redpanda (Disabled)
|
||||
- ENABLE_REDPANDA=false
|
||||
- REDPANDA_BROKERS=smart-city-redpanda:9092
|
||||
# Simulation settings
|
||||
- INTERVAL=1
|
||||
- INTERVAL=5
|
||||
- LOG_LEVEL=INFO
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
|
||||
80
docker-compose.yml.backup
Normal file
80
docker-compose.yml.backup
Normal file
@@ -0,0 +1,80 @@
|
||||
# Smart City Digital Twin Martinique — Main Docker Compose
|
||||
# Usage: docker compose -p smart-city up -d
|
||||
# This file defines the simulator and includes other services
|
||||
|
||||
version: '3.8'
|
||||
|
||||
networks:
|
||||
smartcity-shared:
|
||||
external: true
|
||||
traefik-public:
|
||||
external: true
|
||||
|
||||
services:
|
||||
# Smart City Simulator
|
||||
simulator:
|
||||
build: .
|
||||
container_name: smart-city-simulator
|
||||
networks:
|
||||
- smartcity-shared
|
||||
- traefik-public
|
||||
environment:
|
||||
# MQTT Brokers - Only BunkerM enabled for stability
|
||||
- ENABLE_EMQX=false
|
||||
- ENABLE_MOSQUITTO=false
|
||||
- ENABLE_BUNKER=true
|
||||
- BUNKERM_HOST=bunkerm_bunkerm_1
|
||||
- BUNKERM_PORT=1900
|
||||
# Context Brokers (DESACTIVE - tout passe par les IoT Agents via MQTT)
|
||||
- ENABLE_ORION=false
|
||||
- ENABLE_STELLIO=false
|
||||
- ENABLE_FROST=false
|
||||
# Databases
|
||||
- ENABLE_INFLUX=true
|
||||
- INFLUX_URL=http://smart-city-influxdb:8086
|
||||
# Pulsar (Disabled for demo stability - was causing 0.0.0.0:0 errors)
|
||||
- ENABLE_PULSAR=false
|
||||
# - PULSAR_HOST=smart-city-pulsar
|
||||
# - PULSAR_PORT=6650
|
||||
# Redpanda (Disabled - troubleshooting)
|
||||
- ENABLE_REDPANDA=false
|
||||
- REDPANDA_BROKERS=smart-city-redpanda:9092
|
||||
# Simulation settings
|
||||
- INTERVAL=1
|
||||
- LOG_LEVEL=INFO
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
|
||||
# IoT Agent BunkerM - traduce les msgs MQTT bunker/bunker vers Orion-LD
|
||||
iot-agent-bunkerm:
|
||||
image: fiware/iotagent-json:latest
|
||||
container_name: smart-city-iot-agent-bunkerm
|
||||
networks:
|
||||
- smartcity-shared
|
||||
ports:
|
||||
- "4043:4041"
|
||||
environment:
|
||||
- IOTA_CB_HOST=smart-city-orion-ld
|
||||
- IOTA_CB_PORT=1026
|
||||
- IOTA_CB_NGSI_VERSION=v2
|
||||
- IOTA_REGISTRY_TYPE=memory
|
||||
- IOTA_DEFAULT_APIKEY=smartcity-api-key
|
||||
- IOTA_MQTT_USERNAME=bunker
|
||||
- IOTA_MQTT_PASSWORD=bunker
|
||||
- IOTA_MQTT_HOST=bunkerm_bunkerm_1
|
||||
- IOTA_MQTT_PORT=1900
|
||||
- IOTA_LOG_LEVEL=DEBUG
|
||||
restart: unless-stopped
|
||||
|
||||
# InfluxDB (defined in docker-compose.influxdb.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f docker-compose.influxdb.yml up -d
|
||||
|
||||
# Grafana (defined in docker-compose.grafana.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f docker-compose.grafana.yml up -d
|
||||
|
||||
# Pulsar (defined in pulsar/docker-compose.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f pulsar/docker-compose.yml up -d
|
||||
|
||||
# Redpanda (defined in redpanda/docker-compose.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f redpanda/docker-compose.yml up -d
|
||||
80
docker-compose.yml.bak
Normal file
80
docker-compose.yml.bak
Normal file
@@ -0,0 +1,80 @@
|
||||
# Smart City Digital Twin Martinique — Main Docker Compose
|
||||
# Usage: docker compose -p smart-city up -d
|
||||
# This file defines the simulator and includes other services
|
||||
|
||||
version: '3.8'
|
||||
|
||||
networks:
|
||||
smartcity-shared:
|
||||
external: true
|
||||
traefik-public:
|
||||
external: true
|
||||
|
||||
services:
|
||||
# Smart City Simulator
|
||||
simulator:
|
||||
build: .
|
||||
container_name: smart-city-simulator
|
||||
networks:
|
||||
- smartcity-shared
|
||||
- traefik-public
|
||||
environment:
|
||||
# MQTT Brokers - Only BunkerM enabled for stability
|
||||
- ENABLE_EMQX=false
|
||||
- ENABLE_MOSQUITTO=false
|
||||
- ENABLE_BUNKER=true
|
||||
- BUNKERM_HOST=bunkerm_bunkerm_1
|
||||
- BUNKERM_PORT=1900
|
||||
# Context Brokers (DESACTIVE - tout passe par les IoT Agents via MQTT)
|
||||
- ENABLE_ORION=false
|
||||
- ENABLE_STELLIO=false
|
||||
- ENABLE_FROST=false
|
||||
# Databases
|
||||
- ENABLE_INFLUX=true
|
||||
- INFLUX_URL=http://smart-city-influxdb:8086
|
||||
# Pulsar (Disabled for demo stability - was causing 0.0.0.0:0 errors)
|
||||
- ENABLE_PULSAR=false
|
||||
# - PULSAR_HOST=smart-city-pulsar
|
||||
# - PULSAR_PORT=6650
|
||||
# Redpanda (Disabled - troubleshooting)
|
||||
- ENABLE_REDPANDA=false
|
||||
- REDPANDA_BROKERS=smart-city-redpanda:9092
|
||||
# Simulation settings
|
||||
- INTERVAL=1
|
||||
- LOG_LEVEL=INFO
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
|
||||
# IoT Agent BunkerM - traduce les msgs MQTT bunker/bunker vers Orion-LD
|
||||
iot-agent-bunkerm:
|
||||
image: fiware/iotagent-json:latest
|
||||
container_name: smart-city-iot-agent-bunkerm
|
||||
networks:
|
||||
- smartcity-shared
|
||||
ports:
|
||||
- "4043:4041"
|
||||
environment:
|
||||
- IOTA_CB_HOST=smart-city-orion-ld
|
||||
- IOTA_CB_PORT=1026
|
||||
- IOTA_CB_NGSI_VERSION=v2
|
||||
- IOTA_REGISTRY_TYPE=memory
|
||||
- IOTA_DEFAULT_APIKEY=smartcity-api-key
|
||||
- IOTA_MQTT_USERNAME=bunker
|
||||
- IOTA_MQTT_PASSWORD=bunker
|
||||
- IOTA_MQTT_HOST=bunkerm_bunkerm_1
|
||||
- IOTA_MQTT_PORT=1900
|
||||
- IOTA_LOG_LEVEL=DEBUG
|
||||
restart: unless-stopped
|
||||
|
||||
# InfluxDB (defined in docker-compose.influxdb.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f docker-compose.influxdb.yml up -d
|
||||
|
||||
# Grafana (defined in docker-compose.grafana.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f docker-compose.grafana.yml up -d
|
||||
|
||||
# Pulsar (defined in pulsar/docker-compose.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f pulsar/docker-compose.yml up -d
|
||||
|
||||
# Redpanda (defined in redpanda/docker-compose.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f redpanda/docker-compose.yml up -d
|
||||
85
docker-compose.yml.bak2
Normal file
85
docker-compose.yml.bak2
Normal file
@@ -0,0 +1,85 @@
|
||||
# Smart City Digital Twin Martinique — Main Docker Compose
|
||||
# Usage: docker compose -p smart-city up -d
|
||||
# This file defines the simulator and includes other services
|
||||
|
||||
version: '3.8'
|
||||
|
||||
networks:
|
||||
smartcity-shared:
|
||||
external: true
|
||||
traefik-public:
|
||||
external: true
|
||||
|
||||
services:
|
||||
# Smart City Simulator
|
||||
simulator:
|
||||
build: .
|
||||
container_name: smart-city-simulator
|
||||
networks:
|
||||
- smartcity-shared
|
||||
- traefik-public
|
||||
environment:
|
||||
# MQTT Brokers - Only BunkerM enabled for stability
|
||||
- ENABLE_EMQX=false
|
||||
- ENABLE_MOSQUITTO=false
|
||||
- ENABLE_BUNKER=true
|
||||
- BUNKERM_HOST=bunkerm_bunkerm_1
|
||||
- BUNKERM_PORT=1900
|
||||
# Context Brokers (DESACTIVE - tout passe par les IoT Agents via MQTT)
|
||||
- ENABLE_ORION=false
|
||||
- ENABLE_STELLIO=false
|
||||
- ENABLE_FROST=false
|
||||
# Databases
|
||||
- ENABLE_INFLUX=true
|
||||
- INFLUX_URL=http://smart-city-influxdb:8086
|
||||
# OpenRemote
|
||||
- ENABLE_OPENREMOTE=true
|
||||
- OR_URL=http://openremote_manager_1:8080
|
||||
- OR_ADMIN_USER=admin
|
||||
- OR_ADMIN_PASS=Digitribe972
|
||||
# Pulsar (Disabled for demo stability - was causing 0.0.0.0:0 errors)
|
||||
- ENABLE_PULSAR=false
|
||||
# - PULSAR_HOST=smart-city-pulsar
|
||||
# - PULSAR_PORT=6650
|
||||
# Redpanda (Disabled - troubleshooting)
|
||||
- ENABLE_REDPANDA=false
|
||||
- REDPANDA_BROKERS=smart-city-redpanda:9092
|
||||
# Simulation settings
|
||||
- INTERVAL=1
|
||||
- LOG_LEVEL=INFO
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
|
||||
# IoT Agent BunkerM - traduce les msgs MQTT bunker/bunker vers Orion-LD
|
||||
iot-agent-bunkerm:
|
||||
image: fiware/iotagent-json:latest
|
||||
container_name: smart-city-iot-agent-bunkerm
|
||||
networks:
|
||||
- smartcity-shared
|
||||
ports:
|
||||
- "4043:4041"
|
||||
environment:
|
||||
- IOTA_CB_HOST=smart-city-orion-ld
|
||||
- IOTA_CB_PORT=1026
|
||||
- IOTA_CB_NGSI_VERSION=v2
|
||||
- IOTA_REGISTRY_TYPE=memory
|
||||
- IOTA_DEFAULT_APIKEY=smartcity-api-key
|
||||
- IOTA_MQTT_USERNAME=bunker
|
||||
- IOTA_MQTT_PASSWORD=bunker
|
||||
- IOTA_MQTT_HOST=bunkerm_bunkerm_1
|
||||
- IOTA_MQTT_PORT=1900
|
||||
- IOTA_LOG_LEVEL=DEBUG
|
||||
restart: unless-stopped
|
||||
|
||||
# InfluxDB (defined in docker-compose.influxdb.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f docker-compose.influxdb.yml up -d
|
||||
|
||||
# Grafana (defined in docker-compose.grafana.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f docker-compose.grafana.yml up -d
|
||||
|
||||
# Pulsar (defined in pulsar/docker-compose.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f pulsar/docker-compose.yml up -d
|
||||
|
||||
# Redpanda (defined in redpanda/docker-compose.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f redpanda/docker-compose.yml up -d
|
||||
80
docker-compose.yml.bak3
Normal file
80
docker-compose.yml.bak3
Normal file
@@ -0,0 +1,80 @@
|
||||
# Smart City Digital Twin Martinique — Main Docker Compose
|
||||
# Usage: docker compose -p smart-city up -d
|
||||
# This file defines the simulator and includes other services
|
||||
|
||||
version: '3.8'
|
||||
|
||||
networks:
|
||||
smartcity-shared:
|
||||
external: true
|
||||
traefik-public:
|
||||
external: true
|
||||
|
||||
services:
|
||||
# Smart City Simulator
|
||||
simulator:
|
||||
build: .
|
||||
container_name: smart-city-simulator
|
||||
networks:
|
||||
- smartcity-shared
|
||||
- traefik-public
|
||||
environment:
|
||||
# MQTT Brokers - Only BunkerM enabled for stability
|
||||
- ENABLE_EMQX=false
|
||||
- ENABLE_MOSQUITTO=false
|
||||
- ENABLE_BUNKER=true
|
||||
- BUNKERM_HOST=bunkerm_bunkerm_1
|
||||
- BUNKERM_PORT=1900
|
||||
# Context Brokers (DESACTIVE - tout passe par les IoT Agents via MQTT)
|
||||
- ENABLE_ORION=false
|
||||
- ENABLE_STELLIO=false
|
||||
- ENABLE_FROST=false
|
||||
# Databases
|
||||
- ENABLE_INFLUX=true
|
||||
- INFLUX_URL=http://smart-city-influxdb:8086
|
||||
# Pulsar (Disabled for demo stability - was causing 0.0.0.0:0 errors)
|
||||
- ENABLE_PULSAR=false
|
||||
# - PULSAR_HOST=smart-city-pulsar
|
||||
# - PULSAR_PORT=6650
|
||||
# Redpanda (Disabled - troubleshooting)
|
||||
- ENABLE_REDPANDA=false
|
||||
- REDPANDA_BROKERS=smart-city-redpanda:9092
|
||||
# Simulation settings
|
||||
- INTERVAL=1
|
||||
- LOG_LEVEL=INFO
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
|
||||
# IoT Agent BunkerM - traduce les msgs MQTT bunker/bunker vers Orion-LD
|
||||
iot-agent-bunkerm:
|
||||
image: fiware/iotagent-json:latest
|
||||
container_name: smart-city-iot-agent-bunkerm
|
||||
networks:
|
||||
- smartcity-shared
|
||||
ports:
|
||||
- "4043:4041"
|
||||
environment:
|
||||
- IOTA_CB_HOST=smart-city-orion-ld
|
||||
- IOTA_CB_PORT=1026
|
||||
- IOTA_CB_NGSI_VERSION=v2
|
||||
- IOTA_REGISTRY_TYPE=memory
|
||||
- IOTA_DEFAULT_APIKEY=smartcity-api-key
|
||||
- IOTA_MQTT_USERNAME=bunker
|
||||
- IOTA_MQTT_PASSWORD=bunker
|
||||
- IOTA_MQTT_HOST=bunkerm_bunkerm_1
|
||||
- IOTA_MQTT_PORT=1900
|
||||
- IOTA_LOG_LEVEL=DEBUG
|
||||
restart: unless-stopped
|
||||
|
||||
# InfluxDB (defined in docker-compose.influxdb.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f docker-compose.influxdb.yml up -d
|
||||
|
||||
# Grafana (defined in docker-compose.grafana.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f docker-compose.grafana.yml up -d
|
||||
|
||||
# Pulsar (defined in pulsar/docker-compose.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f pulsar/docker-compose.yml up -d
|
||||
|
||||
# Redpanda (defined in redpanda/docker-compose.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f redpanda/docker-compose.yml up -d
|
||||
80
docker-compose.yml.orig
Normal file
80
docker-compose.yml.orig
Normal file
@@ -0,0 +1,80 @@
|
||||
# Smart City Digital Twin Martinique — Main Docker Compose
|
||||
# Usage: docker compose -p smart-city up -d
|
||||
# This file defines the simulator and includes other services
|
||||
|
||||
version: '3.8'
|
||||
|
||||
networks:
|
||||
smartcity-shared:
|
||||
external: true
|
||||
traefik-public:
|
||||
external: true
|
||||
|
||||
services:
|
||||
# Smart City Simulator
|
||||
simulator:
|
||||
build: .
|
||||
container_name: smart-city-simulator
|
||||
networks:
|
||||
- smartcity-shared
|
||||
- traefik-public
|
||||
environment:
|
||||
# MQTT Brokers - Only BunkerM enabled for stability
|
||||
- ENABLE_EMQX=false
|
||||
- ENABLE_MOSQUITTO=false
|
||||
- ENABLE_BUNKER=true
|
||||
- BUNKERM_HOST=bunkerm_bunkerm_1
|
||||
- BUNKERM_PORT=1900
|
||||
# Context Brokers (DESACTIVE - tout passe par les IoT Agents via MQTT)
|
||||
- ENABLE_ORION=false
|
||||
- ENABLE_STELLIO=false
|
||||
- ENABLE_FROST=false
|
||||
# Databases
|
||||
- ENABLE_INFLUX=true
|
||||
- INFLUX_URL=http://smart-city-influxdb:8086
|
||||
# Pulsar (Disabled for demo stability - was causing 0.0.0.0:0 errors)
|
||||
- ENABLE_PULSAR=false
|
||||
# - PULSAR_HOST=smart-city-pulsar
|
||||
# - PULSAR_PORT=6650
|
||||
# Redpanda (Disabled - troubleshooting)
|
||||
- ENABLE_REDPANDA=false
|
||||
- REDPANDA_BROKERS=smart-city-redpanda:9092
|
||||
# Simulation settings
|
||||
- INTERVAL=1
|
||||
- LOG_LEVEL=INFO
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "traefik.enable=false"
|
||||
|
||||
# IoT Agent BunkerM - traduce les msgs MQTT bunker/bunker vers Orion-LD
|
||||
iot-agent-bunkerm:
|
||||
image: fiware/iotagent-json:latest
|
||||
container_name: smart-city-iot-agent-bunkerm
|
||||
networks:
|
||||
- smartcity-shared
|
||||
ports:
|
||||
- "4043:4041"
|
||||
environment:
|
||||
- IOTA_CB_HOST=smart-city-orion-ld
|
||||
- IOTA_CB_PORT=1026
|
||||
- IOTA_CB_NGSI_VERSION=v2
|
||||
- IOTA_REGISTRY_TYPE=memory
|
||||
- IOTA_DEFAULT_APIKEY=smartcity-api-key
|
||||
- IOTA_MQTT_USERNAME=bunker
|
||||
- IOTA_MQTT_PASSWORD=bunker
|
||||
- IOTA_MQTT_HOST=bunkerm_bunkerm_1
|
||||
- IOTA_MQTT_PORT=1900
|
||||
- IOTA_LOG_LEVEL=DEBUG
|
||||
restart: unless-stopped
|
||||
|
||||
# InfluxDB (defined in docker-compose.influxdb.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f docker-compose.influxdb.yml up -d
|
||||
|
||||
# Grafana (defined in docker-compose.grafana.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f docker-compose.grafana.yml up -d
|
||||
|
||||
# Pulsar (defined in pulsar/docker-compose.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f pulsar/docker-compose.yml up -d
|
||||
|
||||
# Redpanda (defined in redpanda/docker-compose.yml)
|
||||
# Run with: docker compose -f docker-compose.yml -f redpanda/docker-compose.yml up -d
|
||||
23
import_docker_dashboard.py
Normal file
23
import_docker_dashboard.py
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import requests
|
||||
|
||||
# Read the Docker Metrics dashboard
|
||||
with open('/home/eric/smart-city-digital-twin-martinique/grafana-dashboard-docker-metrics.json', 'r') as f:
|
||||
dashboard = json.load(f)
|
||||
|
||||
# Import to Grafana
|
||||
url = "https://grafana.digitribe.fr/api/dashboards/db"
|
||||
auth = ('admin', 'Digitribe972')
|
||||
|
||||
payload = {
|
||||
"dashboard": dashboard,
|
||||
"overwrite": True
|
||||
}
|
||||
|
||||
try:
|
||||
resp = requests.post(url, json=payload, auth=auth, verify=False)
|
||||
print(f"Status: {resp.status_code}")
|
||||
print(resp.json())
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
95
prometheus.yml.backup
Normal file
95
prometheus.yml.backup
Normal file
@@ -0,0 +1,95 @@
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
evaluation_interval: 15s
|
||||
|
||||
scrape_configs:
|
||||
|
||||
# ── Simulator (host) ─────────────────────────────────────────────────────────
|
||||
- job_name: 'simulator'
|
||||
static_configs:
|
||||
- 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'
|
||||
static_configs:
|
||||
- targets: ['smart-city-influxdb:8086']
|
||||
labels:
|
||||
service: influxdb
|
||||
environment: martinique
|
||||
|
||||
# ── 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']
|
||||
labels:
|
||||
service: redpanda
|
||||
environment: martinique
|
||||
|
||||
# ── 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-grafana:3000']
|
||||
labels:
|
||||
service: grafana
|
||||
environment: martinique
|
||||
5859662
simulator.log
5859662
simulator.log
File diff suppressed because it is too large
Load Diff
83
simulator.py
83
simulator.py
@@ -70,7 +70,7 @@ ENABLE_FROST = os.environ.get("ENABLE_FROST", "1") == "1"
|
||||
ENABLE_OPENREMOTE = os.environ.get("ENABLE_OPENREMOTE", "1") == "1"
|
||||
OR_ADMIN_USER = os.environ.get("OR_ADMIN_USER", "admin")
|
||||
OR_ADMIN_PASS = os.environ.get("OR_ADMIN_PASS", "Digitribe972")
|
||||
OR_REALM = os.environ.get("OR_REALM", "smartcity")
|
||||
OR_REALM = os.environ.get("OR_REALM", "master")
|
||||
OR_TOKEN_REALM = os.environ.get("OR_TOKEN_REALM", "master") # Realm pour obtention token
|
||||
#ENABLE_IOT_AGENT = os.environ.get("ENABLE_IOT_AGENT", "1") == "1"
|
||||
FROST_URL = os.environ.get("FROST_URL", "http://localhost:8090/FROST-Server/v1.1") # Exposer frost_http-web-1:8080 -> host:8086
|
||||
@@ -497,7 +497,8 @@ class MultiMQTT:
|
||||
ws: bool = False, use_v5: bool = False) -> mqtt.Client:
|
||||
cid = f"smartcity-sim-{name}-{os.getpid()}"
|
||||
protocol = mqtt.MQTTv5 if use_v5 else mqtt.MQTTv311
|
||||
c = mqtt.Client(client_id=cid, protocol=protocol)
|
||||
# Use Callback API v1 for compatibility with existing lambda callbacks
|
||||
c = mqtt.Client(client_id=cid, protocol=protocol, callback_api_version=mqtt.CallbackAPIVersion.VERSION1)
|
||||
if user:
|
||||
c.username_pw_set(user, pwd)
|
||||
if tls:
|
||||
@@ -536,11 +537,28 @@ class MultiMQTT:
|
||||
|
||||
def _setup(self):
|
||||
# Utiliser les variables d'environnement pour les brokers
|
||||
brokers = [
|
||||
("emqx", EMQX_HOST, EMQX_PORT, False, "", "", False),
|
||||
("mosquitto", MOSQUITTO_HOST, MOSQUITTO_PORT, False, "", "", False), # Same as emqx
|
||||
("bunkerm", BUNKERM_HOST, BUNKERM_PORT, False, "bunker", "bunker", False),
|
||||
]
|
||||
mqtt_version = os.environ.get("MQTT_PROTOCOL_VERSION", "311")
|
||||
use_v5 = (mqtt_version == "5")
|
||||
print(f"[MQTT] Version du protocole: {'v5.0' if use_v5 else 'v3.1.1'} (MQTT_PROTOCOL_VERSION={mqtt_version})")
|
||||
|
||||
# Check which brokers are enabled
|
||||
enable_emqx = os.environ.get("ENABLE_EMQX", "1") == "1"
|
||||
enable_mosquitto = os.environ.get("ENABLE_MOSQUITTO", "1") == "1"
|
||||
enable_bunkerm = os.environ.get("ENABLE_BUNKER", "1") == "1"
|
||||
|
||||
brokers = []
|
||||
if enable_emqx:
|
||||
brokers.append(("emqx", EMQX_HOST, EMQX_PORT, False, "", "", use_v5))
|
||||
if enable_mosquitto:
|
||||
brokers.append(("mosquitto", MOSQUITTO_HOST, MOSQUITTO_PORT, False, "", "", use_v5))
|
||||
if enable_bunkerm:
|
||||
brokers.append(("bunkerm", BUNKERM_HOST, BUNKERM_PORT, False, "bunker", "bunker", use_v5))
|
||||
|
||||
# OpenRemote MQTT broker (pour agents MQTT créés dans OpenRemote)
|
||||
if ENABLE_OPENREMOTE:
|
||||
brokers.append(("openremote", "openremote_manager_1", 1883, False, OR_ADMIN_USER, OR_ADMIN_PASS, use_v5))
|
||||
|
||||
print(f"[MQTT] 🔌 Connexion aux brokers (EMQX={enable_emqx}, Mosquitto={enable_mosquitto}, BunkerM={enable_bunkerm})...")
|
||||
print("[MQTT] 🔌 Connexion aux brokers...")
|
||||
for name, host, port, tls, user, pwd, use_v5 in brokers:
|
||||
c = self._mk_client(name, host, port, tls=tls, user=user, pwd=pwd, use_v5=use_v5)
|
||||
@@ -749,9 +767,9 @@ def _get_or_token() -> str:
|
||||
return _or_token_cache["token"]
|
||||
try:
|
||||
# Use password grant with admin user (full rights)
|
||||
token_url = f"http://localhost:8080/auth/realms/{OR_REALM}/protocol/openid-connect/token"
|
||||
token_url = f"http://openremote-keycloak-1:8080/auth/realms/{OR_TOKEN_REALM}/protocol/openid-connect/token"
|
||||
client_id = os.environ.get("OR_CLIENT_ID", "openremote")
|
||||
client_secret = os.environ.get("OR_CLIENT_SECRET", "QVTnyObwXdpQ0Vuc60kFSonidK49FiXb")
|
||||
client_secret = os.environ.get("OR_CLIENT_SECRET", "0oQjzTfiEELYmj5jFwT4iIuWUDtQDvVa")
|
||||
data = urllib.parse.urlencode({
|
||||
"grant_type": "password",
|
||||
"username": os.environ.get("OR_ADMIN_USER", "admin"),
|
||||
@@ -806,16 +824,38 @@ def _or_put(asset_id: str, payload: dict) -> bool:
|
||||
|
||||
def publish_openremote(sid: str, sensor: dict, values: dict) -> bool:
|
||||
"""Met à jour les attributs d'un asset OpenRemote via REST."""
|
||||
# Mapping sid → asset ID (créés manuellement dans OR)
|
||||
# Mapping sid → asset ID (realm master)
|
||||
ASSET_MAP = {
|
||||
"traffic_000": "7b5c5670d1b84865ba3ac7", # Traffic Fort-de-France Centre
|
||||
"traffic_001": "557f6e993b994d3cb81017", # Traffic Fort-de-France North
|
||||
"traffic_002": "cb81dfd2d2dc4d25adc9c2", # Traffic Fort-de-France South
|
||||
"airquality_000": "a51c982a2d3e451898b978", # Air Quality Fort-de-France
|
||||
"parking_000": "b8f0df19e0af47b386ebb9", # Parking Fort-de-France Centre
|
||||
"noise_000": "9035103d1866454fb7e451", # Noise Fort-de-France Centre
|
||||
"weather_000": "b9de80905ac640f488ab27", # Weather Lamentin Airport
|
||||
"light_000": "ee7823a41e594851ba202f", # Light Fort-de-France
|
||||
"traffic_000": "a8043c3dba95d5aa8283ce",
|
||||
"traffic_001": "04d81c7396f131aa2985e8",
|
||||
"traffic_002": "ef6d0b07c9eebbc4caf0a6",
|
||||
"traffic_003": "cf7eb926b27fd029f7e352",
|
||||
"traffic_004": "da52c73cf4657ef6e108c9",
|
||||
"airquality_000": "4ea3e0c63624c751d7a658",
|
||||
"airquality_001": "4f83219bbee703b3e0a255",
|
||||
"airquality_002": "5335681981790e66cb97de",
|
||||
"airquality_003": "03c18679226329183b44b6",
|
||||
"airquality_004": "cb653676e1f5c8888263eb",
|
||||
"parking_000": "6231f03dfd384cf70a761e",
|
||||
"parking_001": "dafad430f5f2a9d692ad80",
|
||||
"parking_002": "a447074cc2be9781780bb4",
|
||||
"parking_003": "96020cc5aef95c5fda7bb4",
|
||||
"parking_004": "ae981dc9d155d1313b9acf",
|
||||
"noise_000": "0be31930e45d2eb5c12ccd",
|
||||
"noise_001": "1802e76e3432d5eda1deb7",
|
||||
"noise_002": "09c61402305f50282f7dd2",
|
||||
"noise_003": "fbf0f80417d49c8c91fe09",
|
||||
"noise_004": "93d09bfac36d2ed95fc858",
|
||||
"weather_000": "9942f881ab6df375d8d9fa",
|
||||
"weather_001": "5400fdf5c51a4fe4f5a89c",
|
||||
"weather_002": "7ee9441fc1295c6f700da3",
|
||||
"weather_003": "5f915a9a887c2dbd137775",
|
||||
"weather_004": "ec9cfb15533ddfe16c6388",
|
||||
"light_000": "1f4302946b1a4a1ded23f6",
|
||||
"light_001": "35e6ef027ed9a157ad8780",
|
||||
"light_002": "526538589aa981bdc77ce9",
|
||||
"light_003": "40bbe989be2ae5b2a98b30",
|
||||
"light_004": "fcad43e50a21d886c8f583",
|
||||
}
|
||||
asset_id = ASSET_MAP.get(sid)
|
||||
if not asset_id:
|
||||
@@ -1047,7 +1087,12 @@ def main():
|
||||
|
||||
for sid, sensor in SENSORS.items():
|
||||
stype = sensor["type"]
|
||||
topic = f"city/sensors/{stype}/{sid}"
|
||||
# Utiliser un index 1-5 basé sur le compteur par type pour correspondre aux agents OpenRemote
|
||||
if not hasattr(mqtt_client, "type_counters"):
|
||||
mqtt_client.type_counters = {}
|
||||
mqtt_client.type_counters[stype] = mqtt_client.type_counters.get(stype, 0) + 1
|
||||
sensor_index = mqtt_client.type_counters[stype]
|
||||
topic = f"smartcity/{stype}/{sensor_index}"
|
||||
|
||||
# --- Payload MQTT (ATTRIBUTES ONLY - pas de id/type/lat/lon !)
|
||||
# # L'IoT Agent n'attend que les readings, pas le body complet
|
||||
|
||||
1320
simulator.py.backup
Normal file
1320
simulator.py.backup
Normal file
File diff suppressed because it is too large
Load Diff
1228
simulator.py.backup2
Normal file
1228
simulator.py.backup2
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user