GeoServer workspace Digitribe + InfluxDB support + data flow diagrams
This commit is contained in:
63
simulator.py
63
simulator.py
@@ -29,6 +29,10 @@ import urllib.request, urllib.error
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any
|
||||
|
||||
# InfluxDB support
|
||||
import influxdb_client
|
||||
from influxdb_client.client.write_api import SYNCHRONOUS
|
||||
|
||||
# =============================================================================
|
||||
# Configuration
|
||||
# =============================================================================
|
||||
@@ -45,6 +49,24 @@ OR_REALM = os.environ.get("OR_REALM", "smartcity")
|
||||
OR_TOKEN_REALM = os.environ.get("OR_TOKEN_REALM", "master") # Realm pour obtention token
|
||||
FROST_URL = os.environ.get("FROST_URL", "http://frost_http-web-1:8080/FROST-Server/v1.1")
|
||||
|
||||
# InfluxDB config
|
||||
ENABLE_INFLUX = os.environ.get("ENABLE_INFLUX", "1") == "1"
|
||||
INFLUX_URL = os.environ.get("INFLUX_URL", "http://digital-twin-influxdb:8086")
|
||||
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")
|
||||
|
||||
# Initialize InfluxDB client
|
||||
_influx_client = None
|
||||
_influx_write_api = None
|
||||
if ENABLE_INFLUX:
|
||||
try:
|
||||
_influx_client = influxdb_client.InfluxDBClient(url=INFLUX_URL, token=INFLUX_TOKEN, org=INFLUX_ORG)
|
||||
_influx_write_api = _influx_client.write_api(write_options=SYNCHRONOUS)
|
||||
print(f"[INFLUX] ✅ Connected to {INFLUX_URL}")
|
||||
except Exception as e:
|
||||
print(f"[INFLUX] ❌ Connection failed: {e}")
|
||||
|
||||
SENSOR_COUNTS = {
|
||||
"traffic": int(os.environ.get("SENSOR_COUNT_traffic", "3")),
|
||||
"airquality": int(os.environ.get("SENSOR_COUNT_airquality", "2")),
|
||||
@@ -724,7 +746,35 @@ def publish_openremote(sid: str, sensor: dict, values: dict) -> bool:
|
||||
"attributes": attrs,
|
||||
}
|
||||
return _or_put(asset_id, payload)
|
||||
# =============================================================================
|
||||
|
||||
def publish_influx(sid: str, sensor: dict, values: dict) -> bool:
|
||||
"""Write sensor data to InfluxDB."""
|
||||
if not _influx_write_api:
|
||||
return False
|
||||
try:
|
||||
stype = sensor["type"]
|
||||
lat = sensor.get("lat", BASE_LAT)
|
||||
lon = sensor.get("lon", BASE_LON)
|
||||
|
||||
points = []
|
||||
for field, value in values.items():
|
||||
if isinstance(value, (int, float)):
|
||||
p = influxdb_client.Point(stype)\
|
||||
.tag("sensor_id", sid)\
|
||||
.tag("location", sensor.get("name", sid))\
|
||||
.field(field, float(value))\
|
||||
.field("lat", float(lat))\
|
||||
.field("lon", float(lon))
|
||||
points.append(p)
|
||||
|
||||
if points:
|
||||
_influx_write_api.write(bucket=INFLUX_BUCKET, record=points)
|
||||
print(f" 📈 InfluxDB: {len(points)} points written")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f" ⚠️ InfluxDB → {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
print("╔══════════════════════════════════════════════════╗")
|
||||
print("║ Smart City Simulator — Martinique ║")
|
||||
@@ -812,6 +862,17 @@ def main():
|
||||
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 '❌'}")
|
||||
|
||||
# --- BunkerM HTTP ---
|
||||
if os.getenv("BUNKERM_HTTP", "0") == "1":
|
||||
|
||||
Reference in New Issue
Block a user