Files
Traffic-Intersection-Monito…/qt_app_pyside1/create_intersection_dashboard.py
2025-08-26 13:24:53 -07:00

539 lines
24 KiB
Python

"""
Create a comprehensive Smart Intersection dashboard in Grafana with proper Flux queries
"""
import requests
import json
import time
from datetime import datetime
# Configuration
GRAFANA_URL = "http://localhost:3000"
GRAFANA_USER = "admin"
GRAFANA_PASSWORD = "admin" # Default password, change if you've modified it
INFLUX_BUCKET = "traffic_monitoring"
INFLUX_ORG = "smart-intersection-org"
def get_datasource_id():
"""Get the InfluxDB datasource ID"""
try:
response = requests.get(
f"{GRAFANA_URL}/api/datasources",
auth=(GRAFANA_USER, GRAFANA_PASSWORD)
)
if response.status_code != 200:
print(f"❌ Failed to get datasources: {response.status_code}")
return None
datasources = response.json()
for ds in datasources:
if "influx" in ds["type"].lower():
print(f"✅ Found InfluxDB datasource: {ds['name']} (ID: {ds['id']})")
return ds
print("❌ No InfluxDB datasource found")
return None
except Exception as e:
print(f"❌ Error getting datasource ID: {e}")
return None
def create_smart_intersection_dashboard(datasource):
"""Create a comprehensive dashboard for the Smart Intersection application"""
if not datasource:
print("❌ No datasource provided, cannot create dashboard")
return False
print(f"Creating Smart Intersection Dashboard with datasource: {datasource['name']}")
dashboard = {
"dashboard": {
"id": None,
"uid": "smart-intersection-monitoring",
"title": "Smart Intersection Monitoring",
"description": "Real-time monitoring dashboard for smart intersection metrics",
"tags": ["smart-intersection", "monitoring", "traffic"],
"timezone": "browser",
"refresh": "5s",
"time": {
"from": "now-15m",
"to": "now"
},
"panels": [
# Performance Overview Row
{
"id": 1,
"title": "Row - Performance Metrics",
"type": "row",
"collapsed": False,
"gridPos": {"h": 1, "w": 24, "x": 0, "y": 0}
},
# FPS Gauge
{
"id": 2,
"title": "FPS",
"type": "gauge",
"gridPos": {"h": 8, "w": 8, "x": 0, "y": 1},
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"options": {
"orientation": "auto",
"showThresholdLabels": False,
"showThresholdMarkers": True
},
"fieldConfig": {
"defaults": {
"color": {"mode": "thresholds"},
"decimals": 1,
"mappings": [],
"max": 30,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{"color": "red", "value": None},
{"color": "orange", "value": 15},
{"color": "green", "value": 24}
]
},
"unit": "fps"
},
"overrides": []
},
"targets": [
{
"refId": "A",
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -1m)\n |> filter(fn: (r) => r._measurement == "performance")\n |> filter(fn: (r) => r._field == "fps")\n |> last()'
}
]
},
# Processing Time
{
"id": 3,
"title": "Processing Time",
"type": "gauge",
"gridPos": {"h": 8, "w": 8, "x": 8, "y": 1},
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"options": {
"orientation": "auto",
"showThresholdLabels": False,
"showThresholdMarkers": True
},
"fieldConfig": {
"defaults": {
"color": {"mode": "thresholds"},
"decimals": 1,
"mappings": [],
"max": 200,
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{"color": "green", "value": None},
{"color": "orange", "value": 80},
{"color": "red", "value": 150}
]
},
"unit": "ms"
},
"overrides": []
},
"targets": [
{
"refId": "A",
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -1m)\n |> filter(fn: (r) => r._measurement == "performance")\n |> filter(fn: (r) => r._field == "processing_time_ms")\n |> last()'
}
]
},
# Device Info
{
"id": 4,
"title": "Device Info",
"type": "stat",
"gridPos": {"h": 8, "w": 8, "x": 16, "y": 1},
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": ["lastNotNull"],
"fields": "",
"values": False
},
"textMode": "auto"
},
"fieldConfig": {
"defaults": {
"color": {"mode": "thresholds"},
"mappings": [
{
"type": "value",
"options": {
"online": {"color": "green", "index": 0, "text": "🟢 Online"},
"offline": {"color": "red", "index": 1, "text": "🔴 Offline"}
}
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{"color": "green", "value": None}
]
}
},
"overrides": []
},
"targets": [
{
"refId": "A",
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -5m)\n |> filter(fn: (r) => r._measurement == "device_info")\n |> filter(fn: (r) => r._field == "status")\n |> last()\n |> yield(name: "device_status")'
},
{
"refId": "B",
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -5m)\n |> filter(fn: (r) => r._measurement == "device_info")\n |> filter(fn: (r) => r._field == "location")\n |> last()\n |> yield(name: "location")'
}
]
},
# Performance History
{
"id": 5,
"title": "Performance History",
"type": "timeseries",
"gridPos": {"h": 9, "w": 24, "x": 0, "y": 9},
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"options": {
"tooltip": {"mode": "multi", "sort": "none"},
"legend": {"showLegend": True},
},
"fieldConfig": {
"defaults": {
"color": {"mode": "palette-classic"},
"custom": {
"lineInterpolation": "smooth",
"fillOpacity": 10,
"spanNulls": False,
},
"unit": "fps"
},
"overrides": [
{
"matcher": {"id": "byName", "options": "processing_time_ms"},
"properties": [
{"id": "unit", "value": "ms"},
{"id": "color", "value": {"mode": "fixed", "fixedColor": "orange"}}
]
}
]
},
"targets": [
{
"refId": "A",
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -15m)\n |> filter(fn: (r) => r._measurement == "performance")\n |> filter(fn: (r) => r._field == "fps")\n |> aggregateWindow(every: 2s, fn: mean, createEmpty: false)\n |> yield(name: "fps")'
},
{
"refId": "B",
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -15m)\n |> filter(fn: (r) => r._measurement == "performance")\n |> filter(fn: (r) => r._field == "processing_time_ms")\n |> aggregateWindow(every: 2s, fn: mean, createEmpty: false)\n |> yield(name: "processing_time_ms")'
}
]
},
# Detection Row
{
"id": 6,
"title": "Row - Object Detection",
"type": "row",
"collapsed": False,
"gridPos": {"h": 1, "w": 24, "x": 0, "y": 18}
},
# Vehicle Count
{
"id": 7,
"title": "Vehicle Count",
"type": "stat",
"gridPos": {"h": 8, "w": 8, "x": 0, "y": 19},
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": ["lastNotNull"],
"fields": "",
"values": False
}
},
"fieldConfig": {
"defaults": {
"color": {"mode": "thresholds"},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{"color": "blue", "value": None}
]
},
"unit": "none"
},
"overrides": []
},
"targets": [
{
"refId": "A",
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -1m)\n |> filter(fn: (r) => r._measurement == "detection_events")\n |> filter(fn: (r) => r._field == "vehicle_count")\n |> last()'
}
]
},
# Red Light Violations
{
"id": 8,
"title": "Red Light Violations",
"type": "stat",
"gridPos": {"h": 8, "w": 8, "x": 8, "y": 19},
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": ["lastNotNull"],
"fields": "",
"values": False
}
},
"fieldConfig": {
"defaults": {
"color": {"mode": "thresholds"},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{"color": "green", "value": None},
{"color": "red", "value": 1}
]
},
"unit": "none"
},
"overrides": []
},
"targets": [
{
"refId": "A",
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -1h)\n |> filter(fn: (r) => r._measurement == "violation_events")\n |> filter(fn: (r) => r.violation_type == "red_light_violation")\n |> count()\n |> yield(name: "violations")'
}
]
},
# Traffic Light Status
{
"id": 9,
"title": "Traffic Light Status",
"type": "stat",
"gridPos": {"h": 8, "w": 8, "x": 16, "y": 19},
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"options": {
"colorMode": "value",
"graphMode": "none",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": ["lastNotNull"],
"fields": "",
"values": False
},
"textMode": "auto"
},
"fieldConfig": {
"defaults": {
"color": {"mode": "thresholds"},
"mappings": [
{
"type": "value",
"options": {
"RED": {"color": "red", "index": 0, "text": "🔴 RED"},
"YELLOW": {"color": "yellow", "index": 1, "text": "🟡 YELLOW"},
"GREEN": {"color": "green", "index": 2, "text": "🟢 GREEN"},
"UNKNOWN": {"color": "gray", "index": 3, "text": "❓ UNKNOWN"}
}
}
],
"thresholds": {
"mode": "absolute",
"steps": [
{"color": "red", "value": None}
]
}
},
"overrides": []
},
"targets": [
{
"refId": "A",
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -5m)\n |> filter(fn: (r) => r._measurement == "traffic_light_status")\n |> filter(fn: (r) => r._field == "color_numeric")\n |> last()\n |> map(fn: (r) => ({{ r with _value: if r._value == 1.0 then "RED" else if r._value == 2.0 then "YELLOW" else if r._value == 3.0 then "GREEN" else "UNKNOWN" }}))'
}
]
},
# Detection History
{
"id": 10,
"title": "Detection History",
"type": "timeseries",
"gridPos": {"h": 9, "w": 24, "x": 0, "y": 27},
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"options": {
"tooltip": {"mode": "multi", "sort": "none"},
"legend": {"showLegend": True}
},
"fieldConfig": {
"defaults": {
"color": {"mode": "palette-classic"},
"custom": {
"lineInterpolation": "linear",
"fillOpacity": 10,
"spanNulls": False,
},
"unit": "none"
},
"overrides": []
},
"targets": [
{
"refId": "A",
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -15m)\n |> filter(fn: (r) => r._measurement == "detection_events")\n |> filter(fn: (r) => r._field == "vehicle_count")\n |> aggregateWindow(every: 5s, fn: mean, createEmpty: false)'
},
{
"refId": "B",
"datasource": {
"type": datasource["type"],
"uid": datasource["uid"]
},
"query": f'from(bucket: "{INFLUX_BUCKET}")\n |> range(start: -15m)\n |> filter(fn: (r) => r._measurement == "violation_events")\n |> filter(fn: (r) => r._field == "count")\n |> aggregateWindow(every: 5s, fn: sum, createEmpty: false)'
}
]
}
]
},
"overwrite": True,
"message": "Created Smart Intersection Monitoring Dashboard"
}
try:
response = requests.post(
f"{GRAFANA_URL}/api/dashboards/db",
auth=(GRAFANA_USER, GRAFANA_PASSWORD),
headers={"Content-Type": "application/json"},
data=json.dumps(dashboard)
)
if response.status_code == 200:
result = response.json()
dashboard_url = f"{GRAFANA_URL}/d/{result['uid']}"
print(f"✅ Dashboard created successfully: {dashboard_url}")
print(f"👉 Please open this URL in your browser: {dashboard_url}")
return True
else:
print(f"❌ Failed to create dashboard: {response.status_code}")
print(f"Response: {response.text}")
return False
except Exception as e:
print(f"❌ Error creating dashboard: {e}")
return False
def main():
print("===== CREATING SMART INTERSECTION DASHBOARD =====")
print("This will create a comprehensive dashboard for your Smart Intersection application")
# Get the InfluxDB datasource
datasource = get_datasource_id()
if not datasource:
print("❌ Failed to get InfluxDB datasource, cannot proceed")
return
# Create the dashboard
success = create_smart_intersection_dashboard(datasource)
if success:
print("\n✅ Smart Intersection Dashboard created successfully!")
print("The dashboard includes:")
print(" - Real-time FPS and processing time gauges")
print(" - Device information panel")
print(" - Performance history graph")
print(" - Vehicle count statistics")
print(" - Red light violation tracking")
print(" - Traffic light status indicator")
print(" - Detection history graph")
print("\nEnsure your application is writing the following measurements to InfluxDB:")
print(" - 'performance' with fields 'fps' and 'processing_time_ms'")
print(" - 'detection_events' with field 'vehicle_count'")
print(" - 'violation_events' with field 'count' and tag 'violation_type'")
print(" - 'traffic_light' with field 'status'")
else:
print("\n❌ Failed to create Smart Intersection Dashboard")
if __name__ == "__main__":
main()