177 lines
8.1 KiB
Python
177 lines
8.1 KiB
Python
#!/usr/bin/env python3
|
|
import json
|
|
|
|
# UID de la source InfluxDB (à récupérer via l'API Grafana)
|
|
# On va utiliser l'UID par défaut ou le récupérer
|
|
import requests
|
|
import os
|
|
|
|
# Récupérer l'UID de la datasource InfluxDB
|
|
try:
|
|
resp = requests.get('http://grafana.digitribe.fr/api/datasources', auth=('admin', 'Digitribe972'))
|
|
ds_uid = None
|
|
if resp.ok:
|
|
for ds in resp.json():
|
|
if 'influx' in ds['type'].lower():
|
|
ds_uid = ds['uid']
|
|
print(f"Datasource InfluxDB trouvée: {ds['name']} (UID: {ds_uid})")
|
|
break
|
|
except:
|
|
pass
|
|
|
|
if not ds_uid:
|
|
ds_uid = 'influxdb' # Fallback
|
|
print(f"Utilisation UID par défaut: {ds_uid}")
|
|
|
|
dashboard = {
|
|
"annotations": {"list": []},
|
|
"editable": True,
|
|
"fiscalYearStartMonth": 0,
|
|
"graphTooltip": 0,
|
|
"id": None,
|
|
"links": [],
|
|
"panels": [
|
|
# Air Quality Panel
|
|
{
|
|
"title": "Air Quality - PM2.5",
|
|
"type": "timeseries",
|
|
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 0},
|
|
"targets": [
|
|
{
|
|
"query": 'from(bucket:"smartcity")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r["_measurement"] == "airquality")\n |> filter(fn: (r) => r["_field"] == "pm25_ugm3")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: "mean")',
|
|
"refId": "A"
|
|
}
|
|
],
|
|
"datasource": {"type": "influxdb", "uid": ds_uid},
|
|
},
|
|
{
|
|
"title": "Air Quality - CO",
|
|
"type": "timeseries",
|
|
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 0},
|
|
"targets": [
|
|
{
|
|
"query": 'from(bucket:"smartcity")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r["_measurement"] == "airquality")\n |> filter(fn: (r) => r["_field"] == "co_mgm3")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: "mean")',
|
|
"refId": "A"
|
|
}
|
|
],
|
|
"datasource": {"type": "influxdb", "uid": ds_uid},
|
|
},
|
|
# Traffic Panel
|
|
{
|
|
"title": "Traffic - Average Speed",
|
|
"type": "timeseries",
|
|
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 8},
|
|
"targets": [
|
|
{
|
|
"query": 'from(bucket:"smartcity")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r["_measurement"] == "traffic")\n |> filter(fn: (r) => r["_field"] == "average_speed_kmh")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: "mean")',
|
|
"refId": "A"
|
|
}
|
|
],
|
|
"datasource": {"type": "influxdb", "uid": ds_uid},
|
|
},
|
|
{
|
|
"title": "Traffic - Congestion",
|
|
"type": "timeseries",
|
|
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 8},
|
|
"targets": [
|
|
{
|
|
"query": 'from(bucket:"smartcity")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r["_measurement"] == "traffic")\n |> filter(fn: (r) => r["_field"] == "congestion_level")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: "mean")',
|
|
"refId": "A"
|
|
}
|
|
],
|
|
"datasource": {"type": "influxdb", "uid": ds_uid},
|
|
},
|
|
# Parking Panel
|
|
{
|
|
"title": "Parking - Available Spots",
|
|
"type": "timeseries",
|
|
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 16},
|
|
"targets": [
|
|
{
|
|
"query": 'from(bucket:"smartcity")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r["_measurement"] == "parking")\n |> filter(fn: (r) => r["_field"] == "available_spots")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: "mean")',
|
|
"refId": "A"
|
|
}
|
|
],
|
|
"datasource": {"type": "influxdb", "uid": ds_uid},
|
|
},
|
|
{
|
|
"title": "Parking - Occupancy %",
|
|
"type": "timeseries",
|
|
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 16},
|
|
"targets": [
|
|
{
|
|
"query": 'from(bucket:"smartcity")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r["_measurement"] == "parking")\n |> filter(fn: (r) => r["_field"] == "occupancy_percent")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: "mean")',
|
|
"refId": "A"
|
|
}
|
|
],
|
|
"datasource": {"type": "influxdb", "uid": ds_uid},
|
|
},
|
|
# Noise Panel
|
|
{
|
|
"title": "Noise Level (dB)",
|
|
"type": "timeseries",
|
|
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 24},
|
|
"targets": [
|
|
{
|
|
"query": 'from(bucket:"smartcity")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r["_measurement"] == "noise")\n |> filter(fn: (r) => r["_field"] == "noise_level_db")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: "mean")',
|
|
"refId": "A"
|
|
}
|
|
],
|
|
"datasource": {"type": "influxdb", "uid": ds_uid},
|
|
},
|
|
# Weather Panel
|
|
{
|
|
"title": "Weather - Temperature",
|
|
"type": "timeseries",
|
|
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 24},
|
|
"targets": [
|
|
{
|
|
"query": 'from(bucket:"smartcity")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r["_measurement"] == "weather")\n |> filter(fn: (r) => r["_field"] == "temperature_celsius")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: "mean")',
|
|
"refId": "A"
|
|
}
|
|
],
|
|
"datasource": {"type": "influxdb", "uid": ds_uid},
|
|
},
|
|
# Light Panel
|
|
{
|
|
"title": "Light - Brightness",
|
|
"type": "timeseries",
|
|
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 32},
|
|
"targets": [
|
|
{
|
|
"query": 'from(bucket:"smartcity")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r["_measurement"] == "light")\n |> filter(fn: (r) => r["_field"] == "brightness_lux")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: "mean")',
|
|
"refId": "A"
|
|
}
|
|
],
|
|
"datasource": {"type": "influxdb", "uid": ds_uid},
|
|
},
|
|
{
|
|
"title": "Light - Power Consumption",
|
|
"type": "timeseries",
|
|
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 32},
|
|
"targets": [
|
|
{
|
|
"query": 'from(bucket:"smartcity")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r["_measurement"] == "light")\n |> filter(fn: (r) => r["_field"] == "power_consumption_w")\n |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)\n |> yield(name: "mean")',
|
|
"refId": "A"
|
|
}
|
|
],
|
|
"datasource": {"type": "influxdb", "uid": ds_uid},
|
|
}
|
|
],
|
|
"schemaVersion": 38,
|
|
"style": "dark",
|
|
"tags": ["smart-city", "martinique", "iot"],
|
|
"templating": {"list": []},
|
|
"time": {"from": "now-1h", "to": "now"},
|
|
"title": "Smart City Digital Twin - Martinique (Fixed)",
|
|
"uid": "smartcity-martinique-2026-v2",
|
|
"version": 2
|
|
}
|
|
|
|
# Sauvegarder
|
|
with open('/home/eric/smart-city-digital-twin-martinique/grafana-dashboard-fixed.json', 'w') as f:
|
|
json.dump(dashboard, f, indent=2)
|
|
|
|
print("✅ Dashboard avec bonnes requêtes Flux créé")
|
|
print(f" Fichier: grafana-dashboard-fixed.json")
|
|
print(f" Datasource UID: {ds_uid}") |