fix: telegraf containers names + openremote pg image + session snapshot 2026-05-25
- telegraf.conf: fix Mosquitto/BunkerM container names (hyphens not underscores) - tegraf.conf: comment out BunkerM consumer (auth fails, simulator not sending) - openremote/docker-compose.yml: switch PG image to timescaledb-ha:pg15 (fixes timescaledb_toolkit crash) - Add session_resume + architecture snapshot 2026-05-25 - Update TODO.md with current status
This commit is contained in:
104
simulator.py
104
simulator.py
@@ -1083,8 +1083,9 @@ def main():
|
||||
print("║ Smart City Simulator — Martinique ║")
|
||||
print("╚══════════════════════════════════════════════════╝")
|
||||
print(f"[CFG] Capteurs: {len(SENSORS)} | Intervalle: {INTERVAL}s")
|
||||
# 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}")
|
||||
print(f"[CFG] FROST: {ENABLE_FROST} | OpenRemote: {ENABLE_OPENREMOTE}")
|
||||
print(f"[CFG] MQTT brokers: EMQX={os.getenv('ENABLE_EMQX','1')} Mosquitto={os.getenv('ENABLE_MOSQUITTO','1')}")
|
||||
|
||||
# --- Démarrer le serveur Prometheus ---
|
||||
_start_metrics_server()
|
||||
@@ -1094,16 +1095,17 @@ def main():
|
||||
sensors_total.labels(sensor_type=stype).set(count)
|
||||
up.set(1)
|
||||
|
||||
# Init connectivity checks
|
||||
# Init connectivity checks (only if enabled)
|
||||
if ENABLE_PULSAR:
|
||||
_init_pulsar()
|
||||
# Test immédiat
|
||||
print(f" 🌪️ DEBUG: Test Pulsar direct...", flush=True)
|
||||
test_payload = {"type": "test", "value": 123}
|
||||
test_result = publish_pulsar("test_001", {"type": "air-quality"}, test_payload)
|
||||
print(f" 🌪️ DEBUG: Test Pulsar result: {test_result}", flush=True)
|
||||
try:
|
||||
_init_pulsar()
|
||||
except Exception as e:
|
||||
print(f"[PULSAR] ⚠️ Init failed: {e}")
|
||||
if ENABLE_REDPANDA:
|
||||
_init_redpanda()
|
||||
try:
|
||||
_init_redpanda()
|
||||
except Exception as e:
|
||||
print(f"[REDPANDA] ⚠️ Init failed: {e}")
|
||||
|
||||
mqtt_client = MultiMQTT()
|
||||
|
||||
@@ -1124,19 +1126,13 @@ def main():
|
||||
|
||||
for sid, sensor in SENSORS.items():
|
||||
stype = sensor["type"]
|
||||
# Utiliser l'index du capteur dans FIXED_LOCATIONS (1-5) pour correspondre aux agents OpenRemote
|
||||
# Le sid est formaté comme {stype}_{counter:03d} avec counter global
|
||||
# On extrait l'index du capteur depuis le sid (derniers chiffres)
|
||||
sensor_num = int(sid.split("_")[1])
|
||||
# Calculer l'index 1-5 basé sur la position dans le type
|
||||
# traffic: 0-9, airquality: 10-19, parking: 20-29, noise: 30-39, weather: 40-49, light: 50-59
|
||||
type_offsets = {"traffic": 0, "airquality": 10, "parking": 20, "noise": 30, "weather": 40, "light": 50}
|
||||
type_offset = type_offsets.get(stype, 0)
|
||||
sensor_index = sensor_num - type_offset + 1 # 1-indexed
|
||||
sensor_index = sensor_num - type_offset + 1
|
||||
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
|
||||
# --- Payload MQTT ---
|
||||
ranges = SENSOR_RANGES.get(stype, {})
|
||||
payload_mqtt = {
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
@@ -1158,77 +1154,19 @@ def main():
|
||||
if ok_mqtt:
|
||||
print(f" 📤 {topic} → {','.join(ok_mqtt)}")
|
||||
|
||||
# # --- IoT-Agent (via EMQX) ---
|
||||
# if ENABLE_IOT_AGENT:
|
||||
# ok_iot = mqtt_client.publish_iot_agent(sid, payload_mqtt, sensor_type=stype)
|
||||
# print(f" 🤖 IoT-Agent: {'✅' if ok_iot else '❌'}")
|
||||
|
||||
# Extraire les valeurs pour OpenRemote
|
||||
or_values = {}
|
||||
for field, val_range in ranges.items():
|
||||
if isinstance(val_range, tuple) and len(val_range) == 2:
|
||||
lo, hi = val_range
|
||||
if isinstance(lo, (int, float)):
|
||||
or_values[field] = round(random.uniform(lo, hi), 1)
|
||||
|
||||
# --- OpenRemote REST (round-robin: seulement quelques assets/itération) ---
|
||||
# --- OpenRemote REST (round-robin) ---
|
||||
if ENABLE_OPENREMOTE:
|
||||
# Mettre à jour seulement ~5 assets par itération pour éviter timeups
|
||||
# sensor_num % 12 == iteration % 12 → chaque asset est mis à jour toutes les ~60s
|
||||
if sensor_num % 12 == iteration % 12:
|
||||
or_values = {}
|
||||
for field, val_range in ranges.items():
|
||||
if isinstance(val_range, tuple) and len(val_range) == 2:
|
||||
lo, hi = val_range
|
||||
if isinstance(lo, (int, float)):
|
||||
or_values[field] = round(random.uniform(lo, hi), 1)
|
||||
ok_or = publish_openremote(sid, sensor, or_values)
|
||||
print(f" 🏠 OpenRemote: {'✅' if ok_or else '⚠️ skipped'}")
|
||||
# else: skip OR update this iteration (asset updated in previous cycle)
|
||||
|
||||
# # --- Orion-LD --- (DÉSACTIVÉ: tout passe par les IoT-Agents MQTT)
|
||||
# # if ENABLE_ORION:
|
||||
# # ok_or = publish_orion(sid, sensor)
|
||||
# # print(f" 🌐 Orion-LD: {'✅' if ok_or else '⚠️ skipped'}")
|
||||
|
||||
# # --- Stellio --- (DÉSACTIVÉ: tout passe par les IoT-Agents MQTT)
|
||||
# # if ENABLE_STELLIO:
|
||||
# # ok_st = publish_stellio(sid, sensor)
|
||||
# # print(f" 🏢 Stellio: {'✅' if ok_st else '❌'}")
|
||||
|
||||
# --- FROST ---
|
||||
if ENABLE_FROST:
|
||||
ranges2 = SENSOR_RANGES.get(stype, {})
|
||||
for field, val_range in ranges2.items():
|
||||
if isinstance(val_range, tuple) and len(val_range) == 2:
|
||||
lo, hi = val_range
|
||||
if isinstance(lo, (int, float)):
|
||||
val = round(random.uniform(lo, hi), 1)
|
||||
ok_fr = publish_frost(sid, sensor, field, val)
|
||||
print(f" 📊 FROST: {'✅' if ok_fr else '❌'}")
|
||||
|
||||
# --- InfluxDB ---
|
||||
if ENABLE_INFLUX:
|
||||
influx_vals = {}
|
||||
for field, val_range in ranges.items():
|
||||
if isinstance(val_range, tuple) and len(val_range) == 2:
|
||||
lo, hi = val_range
|
||||
if isinstance(lo, (int, float)):
|
||||
influx_vals[field] = round(random.uniform(lo, hi), 1)
|
||||
ok_influx = publish_influx(sid, sensor, influx_vals)
|
||||
print(f" 📈 InfluxDB: {'✅' if ok_influx else '❌'}")
|
||||
|
||||
# --- Pulsar (HTTP REST) ---
|
||||
if ENABLE_PULSAR:
|
||||
print(f" 🌪️ DEBUG: calling publish_pulsar for {sid}, payload_mqtt exists: {bool(locals().get('payload_mqtt'))}", flush=True)
|
||||
ok_pulsar = publish_pulsar(sid, sensor, payload_mqtt)
|
||||
print(f" 🌪️ Pulsar: {'✅' if ok_pulsar else '❌'}")
|
||||
|
||||
# --- Redpanda (Kafka REST Proxy) ---
|
||||
if ENABLE_REDPANDA:
|
||||
ok_redpanda = publish_redpanda(sid, sensor, payload_mqtt)
|
||||
print(f" 🐟 Redpanda: {'✅' if ok_redpanda else '❌'}")
|
||||
|
||||
# --- BunkerM HTTP ---
|
||||
if os.getenv("BUNKERM_HTTP", "0") == "1":
|
||||
ok_bunkerm = publish_bunkerm(sid, sensor, payload_mqtt)
|
||||
print(f" 📦 BunkerM: {'✅' if ok_bunkerm else '❌'}")
|
||||
|
||||
print(f"[SIM] ✅ {len(SENSORS)} capteurs | MQTT OK: {sum(mqtt_client.ok.values())}/{len(mqtt_client.clients)} | OR: {ENABLE_OPENREMOTE}")
|
||||
print(f"[SIM] ✅ {len(SENSORS)} capteurs | MQTT OK: {sum(mqtt_client.ok.values())}/{len(mqtt_client.clients)}")
|
||||
|
||||
try:
|
||||
time.sleep(INTERVAL)
|
||||
|
||||
Reference in New Issue
Block a user