Files
smart-city-digital-twin-mar…/create_dashboard_fixed.py

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}")