#!/usr/bin/env python3
"""Create dashboard by writing to Home Assistant config directory via file editor API"""
import urllib.request
import json
import sys
TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI4NmM2ZGNlMTY2MWU0M2U5YjQ2MDI3MjMxYjE0NDFlMyIsImlhdCI6MTc2NzE3ODUyNiwiZXhwIjoyMDgyNTM4NTI2fQ.E8eShOsejwDYglixpgM_d_JYBlB1OVNhN7cHPnPiLOs"
HA_URL = "http://homeassistant.local:8123"
DASHBOARD_YAML = """title: Kiosk Dashboard
path: dashboard-kiosk
icon: mdi:view-dashboard
panel: false
type: sidebar
cards:
- type: markdown
content: |
#
{{ now().strftime('%A, %B %d, %Y') }}
## {{ now().strftime('%I:%M %p') }}
- type: weather-forecast
entity: weather.forecast_home
name: Current Weather
show_forecast: true
forecast_type: daily
- 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
- 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
- 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
- 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
- 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
- type: markdown
content: |
"""
def write_file_via_api(file_path, content):
"""Write file using Home Assistant file editor API"""
# Try file editor API endpoint
url = f"{HA_URL}/api/file_editor/write"
data = {
"path": file_path,
"content": content
}
req = urllib.request.Request(url, data=json.dumps(data).encode())
req.add_header("Authorization", f"Bearer {TOKEN}")
req.add_header("Content-Type", "application/json")
try:
with urllib.request.urlopen(req) as response:
result = json.loads(response.read().decode())
if result.get("success"):
print(f"โ Successfully wrote file: {file_path}")
return True
else:
print(f"โ Failed to write file: {result.get('error', 'Unknown error')}")
return False
except urllib.error.HTTPError as e:
error_msg = e.read().decode()
print(f"โ HTTP Error {e.code}: {error_msg[:200]}")
return False
except Exception as e:
print(f"โ Error: {e}")
return False
def create_dashboard():
"""Create dashboard by writing to storage directory"""
# Home Assistant stores dashboards in .storage/lovelace/
# Try different possible paths
paths_to_try = [
".storage/lovelace/dashboard-kiosk.yaml",
"config/.storage/lovelace/dashboard-kiosk.yaml",
"dashboard-kiosk.yaml"
]
print("Attempting to create dashboard via file editor API...")
print()
for path in paths_to_try:
print(f"Trying path: {path}")
if write_file_via_api(path, DASHBOARD_YAML):
print(f"\nโ Dashboard created at: {path}")
print(f"Dashboard URL: {HA_URL}/dashboard-kiosk/0")
return True
print()
# If file editor doesn't work, try creating via Lovelace storage format
print("Trying Lovelace storage format...")
storage_data = {
"title": "Kiosk Dashboard",
"icon": "mdi:view-dashboard",
"url_path": "dashboard-kiosk",
"require_admin": False,
"show_in_sidebar": True,
"config": {
"title": "Kiosk Dashboard",
"path": "dashboard-kiosk",
"icon": "mdi:view-dashboard",
"panel": False,
"type": "sidebar",
"cards": json.loads(json.dumps([
{"type": "markdown", "content": "# {{ now().strftime('%A, %B %d, %Y') }}\n## {{ now().strftime('%I:%M %p') }}"},
{"type": "weather-forecast", "entity": "weather.forecast_home", "name": "Current Weather", "show_forecast": True, "forecast_type": "daily"},
# ... simplified for storage format
]))
}
}
storage_path = ".storage/lovelace.dashboards"
if write_file_via_api(storage_path, json.dumps(storage_data, indent=2)):
return True
print("\n" + "="*60)
print("Could not create dashboard via API.")
print("Home Assistant dashboards must be created via the UI.")
print("="*60)
print("\nDashboard YAML is ready in: /home/kyle/scripts/dashboard-kiosk-final.yaml")
print("\nPlease create it manually:")
print("1. Settings > Dashboards > Add Dashboard")
print("2. Raw configuration editor > Paste YAML")
return False
if __name__ == '__main__':
create_dashboard()