Simulator: Add source+mqttTopic traceability for Fiware brokers

This commit is contained in:
Eric FELIXINE
2026-05-04 22:25:23 -04:00
parent 36e227c27a
commit cad1c06422

View File

@@ -193,7 +193,7 @@ STELLIO_INLINE_CONTEXT = [
"https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context.jsonld",
]
def _ngsi_payload(sid: str, sensor: dict, context: list | dict = ORION_CONTEXT) -> dict:
def _ngsi_payload(sid: str, sensor: dict, context: list | dict = ORION_CONTEXT, source: str = "simulator", topic: str = "") -> dict:
"""Construit un payload NGSI-LD avec Smart Data Models officiels."""
stype = sensor["type"]
model_type = SMART_MODEL_MAPPING.get(stype, "Device")
@@ -210,6 +210,11 @@ def _ngsi_payload(sid: str, sensor: dict, context: list | dict = ORION_CONTEXT)
"coordinates": [sensor["lon"], sensor["lat"]]}},
"name": {"type": "Property", "value": sensor["name"]},
"batteryLevel": {"type": "Property", "value": random.randint(60, 100)},
# NOUVEAU: Traçabilité MQTT (Conforme NGSI-LD)
# "source" est un champ standard NGSI-LD (ETSI)
# "mqttTopic" est une propriété personnalisée (étendue autorisée)
"source": {"type": "Property", "value": source},
"mqttTopic": {"type": "Property", "value": topic},
}
# Attributs spécifiques par type de modèle
@@ -264,7 +269,7 @@ def _ngsi_payload(sid: str, sensor: dict, context: list | dict = ORION_CONTEXT)
return payload
def _frost_payload(sid: str, sensor: dict) -> dict:
def _frost_payload(sid: str, sensor: dict, source: str = "simulator", topic: str = "") -> dict:
"""Construit un payload SensorThings pour FROST-Server."""
stype = sensor["type"]
ranges = SENSOR_RANGES.get(stype, {})
@@ -300,7 +305,12 @@ def _frost_payload(sid: str, sensor: dict) -> dict:
thing_payload = {
"name": f"Thing_{sid}",
"description": f"Smart City {stype} sensor in Martinique",
"properties": {"sensorType": stype, "region": "Martinique"},
"properties": {
"sensorType": stype,
"region": "Martinique",
"source": source, # Traçabilité
"mqttTopic": topic # Traçabilité
},
}
return thing_payload, datastreams
@@ -456,7 +466,10 @@ STELLIO_TENANT = os.environ.get("STELLIO_TENANT", "urn:ngsi-ld:tenant:default")
def publish_stellio(sid: str, sensor: dict) -> bool:
"""Publie sur Stellio via Traefik (gère le 409)."""
entity = _ngsi_payload(sid, sensor, context=STELLIO_INLINE_CONTEXT)
# Topic MQTT correspondant (pour traçabilité)
stype = sensor["type"]
topic = f"city/sensors/{stype}/{sid}"
entity = _ngsi_payload(sid, sensor, context=STELLIO_INLINE_CONTEXT, source="simulator", topic=topic)
# Stellio a besoin du @context pour résoudre les vocabulaires NGSI-LD
# (uri.etsi.org résolu depuis le JAR embarqué)
url = f"{STELLIO_URL}/ngsi-ld/v1/entities"
@@ -496,7 +509,10 @@ def publish_stellio(sid: str, sensor: dict) -> bool:
def publish_orion(sid: str, sensor: dict) -> bool:
"""Publie sur Orion-LD (POST create, PATCH update)."""
import socket
entity = _ngsi_payload(sid, sensor)
# Topic MQTT correspondant (pour traçabilité)
stype = sensor["type"]
topic = f"city/sensors/{stype}/{sid}"
entity = _ngsi_payload(sid, sensor, source="simulator", topic=topic)
if not hasattr(publish_orion, "orion_ip"):
try:
publish_orion.orion_ip = socket.gethostbyname("fiware-gis-quickstart-orion-1")
@@ -611,7 +627,10 @@ def publish_frost(sid: str, sensor: dict, field: str, value: float) -> bool:
return False
# Premier appel pour ce capteur : créer Thing + tous les Datastreams
thing_payload, datastreams = _frost_payload(sid, sensor)
# Topic MQTT pour traçabilité
stype = sensor["type"]
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)
if not tid: