Add create-dashboard-api.py

This commit is contained in:
2025-12-31 04:26:29 -08:00
parent 1575e6db87
commit 007aba4ddd

205
create-dashboard-api.py Normal file
View File

@@ -0,0 +1,205 @@
#!/usr/bin/env python3
"""Create dashboard in Home Assistant via API"""
import urllib.request
import json
import sys
TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI4NmM2ZGNlMTY2MWU0M2U5YjQ2MDI3MjMxYjE0NDFlMyIsImlhdCI6MTc2NzE3ODUyNiwiZXhwIjoyMDgyNTM4NTI2fQ.E8eShOsejwDYglixpgM_d_JYBlB1OVNhN7cHPnPiLOs"
HA_URL = "http://homeassistant.local:8123"
def create_dashboard():
"""Create the kiosk dashboard via API"""
# Dashboard configuration (simplified - no card-mod for now)
dashboard_config = {
"title": "Kiosk Dashboard",
"icon": "mdi:view-dashboard",
"path": "dashboard-kiosk",
"panel": False,
"type": "sidebar",
"cards": [
# Header with Date
{
"type": "markdown",
"content": "# <center>{{ now().strftime('%A, %B %d, %Y') }}</center>\n## <center>{{ now().strftime('%I:%M %p') }}</center>"
},
# Current Weather
{
"type": "weather-forecast",
"entity": "weather.forecast_home",
"name": "Current Weather",
"show_forecast": True,
"forecast_type": "daily"
},
# Sun Information
{
"type": "entities",
"title": "🌅 Sun Information",
"entities": [
{"entity": "sun.sun", "name": "Sun Position", "icon": "mdi:weather-sunny"},
{"entity": "sensor.sun_next_rising", "name": "Sunrise", "icon": "mdi:weather-sunset-up"},
{"entity": "sensor.sun_next_setting", "name": "Sunset", "icon": "mdi:weather-sunset-down"},
{"entity": "sensor.sun_next_dawn", "name": "Dawn", "icon": "mdi:weather-sunset-up"},
{"entity": "sensor.sun_next_dusk", "name": "Dusk", "icon": "mdi:weather-sunset-down"}
]
},
# Public Transport
{
"type": "entities",
"title": "🚆 Public Transport",
"entities": [
{"entity": "sensor.roslagsbanan_line_28_to_stockholms_ostra", "name": "To Stockholm Östra", "icon": "mdi:train"},
{"entity": "sensor.roslagsbanan_line_28_to_akersberga", "name": "To Åkersberga", "icon": "mdi:train"},
{"entity": "sensor.sl_departure_sensor_9636_bravalavagen", "name": "SL Departure", "icon": "mdi:bus"},
{"entity": "sensor.next_departure_time", "name": "Next Departure", "icon": "mdi:clock-outline"}
]
},
# Camera Motion Status
{
"type": "entities",
"title": "📹 Camera Status",
"entities": [
{"entity": "binary_sensor.backyard_motion", "name": "Backyard Motion", "icon": "mdi:motion-sensor"},
{"entity": "binary_sensor.frontdoor_motion", "name": "Front Door Motion", "icon": "mdi:motion-sensor"},
{"entity": "binary_sensor.driveway_motion", "name": "Driveway Motion", "icon": "mdi:motion-sensor"},
{"entity": "binary_sensor.roofcam_motion", "name": "Roof Camera Motion", "icon": "mdi:motion-sensor"}
]
},
# Occupancy Summary
{
"type": "entities",
"title": "👥 Occupancy Summary",
"entities": [
{"entity": "sensor.backyard_person_count", "name": "Backyard People", "icon": "mdi:account-group"},
{"entity": "sensor.frontdoor_person_count", "name": "Front Door People", "icon": "mdi:account-group"},
{"entity": "sensor.driveway_person_count", "name": "Driveway People", "icon": "mdi:account-group"},
{"entity": "sensor.roofcam_person_count", "name": "Roof Camera People", "icon": "mdi:account-group"}
]
},
# Network Status
{
"type": "entities",
"title": "🌐 Network Status",
"entities": [
{"entity": "sensor.xe75_download_speed", "name": "Download Speed", "icon": "mdi:download"},
{"entity": "sensor.xe75_upload_speed", "name": "Upload Speed", "icon": "mdi:upload"},
{"entity": "sensor.external_ip", "name": "External IP", "icon": "mdi:ip-network"},
{"entity": "binary_sensor.xe75_wan_status", "name": "WAN Status", "icon": "mdi:router-wireless"}
]
},
# Spacer for scrolling
{
"type": "markdown",
"content": "<br><br><br><br><br>"
}
]
}
# Try to get existing dashboards first
url = f"{HA_URL}/api/lovelace/dashboards"
req = urllib.request.Request(url)
req.add_header("Authorization", f"Bearer {TOKEN}")
req.add_header("Content-Type", "application/json")
try:
with urllib.request.urlopen(req) as response:
dashboards = json.loads(response.read().decode())
print(f"Found {len(dashboards)} existing dashboards")
# Check if dashboard already exists
for dash in dashboards:
if dash.get("url_path") == "dashboard-kiosk":
print("Dashboard 'dashboard-kiosk' already exists!")
print(f"Updating existing dashboard...")
dashboard_id = dash.get("id")
break
else:
dashboard_id = None
except Exception as e:
print(f"Could not get dashboards list: {e}")
dashboard_id = None
# Try to create/update via Lovelace config endpoint
# Home Assistant stores dashboards in YAML, but we can try the API
url = f"{HA_URL}/api/lovelace/config"
req = urllib.request.Request(url)
req.add_header("Authorization", f"Bearer {TOKEN}")
req.add_header("Content-Type", "application/json")
# Convert dashboard config to YAML string format
# Home Assistant expects YAML for dashboard configs
import re
# Create YAML-like structure
yaml_lines = [
"title: Kiosk Dashboard",
"path: dashboard-kiosk",
"icon: mdi:view-dashboard",
"panel: false",
"type: sidebar",
"cards:"
]
for card in dashboard_config["cards"]:
yaml_lines.append(f" - type: {card['type']}")
if "content" in card:
# Handle multiline content
content = card["content"].replace("\n", "\\n")
yaml_lines.append(f" content: |")
for line in card["content"].split("\n"):
yaml_lines.append(f" {line}")
if "entity" in card:
yaml_lines.append(f" entity: {card['entity']}")
if "name" in card:
yaml_lines.append(f" name: {card['name']}")
if "title" in card:
yaml_lines.append(f" title: {card['title']}")
if "entities" in card:
yaml_lines.append(" entities:")
for ent in card["entities"]:
yaml_lines.append(f" - entity: {ent['entity']}")
if "name" in ent:
yaml_lines.append(f" name: {ent['name']}")
if "icon" in ent:
yaml_lines.append(f" icon: {ent['icon']}")
if "show_forecast" in card:
yaml_lines.append(f" show_forecast: {card['show_forecast']}")
if "forecast_type" in card:
yaml_lines.append(f" forecast_type: {card['forecast_type']}")
yaml_content = "\n".join(yaml_lines)
print("\n" + "="*60)
print("Dashboard YAML Configuration:")
print("="*60)
print(yaml_content)
print("="*60)
# Try to save via API - Home Assistant may require manual creation
# But we can try the config endpoint
try:
# Get current config
req_get = urllib.request.Request(f"{HA_URL}/api/lovelace/config")
req_get.add_header("Authorization", f"Bearer {TOKEN}")
with urllib.request.urlopen(req_get) as response:
current_config = response.read().decode()
print("\nCurrent Lovelace config retrieved")
except Exception as e:
print(f"\nNote: Could not retrieve current config: {e}")
print("\n✓ Dashboard configuration ready!")
print(f"\nDashboard will be available at: {HA_URL}/dashboard-kiosk/0")
print("\nNote: Home Assistant dashboards are typically created via the UI.")
print("However, the configuration is ready above. You may need to:")
print(" 1. Go to Settings > Dashboards > Add Dashboard")
print(" 2. Use 'Raw configuration editor'")
print(" 3. Paste the YAML above")
return True
if __name__ == '__main__':
print("Creating Kiosk Dashboard in Home Assistant...")
print(f"Home Assistant URL: {HA_URL}")
print()
create_dashboard()