Works with Python websocket-client, WebSocket API authentication, and Lovelace configuration.
Home Assistant Dashboard Creation
Create and update Lovelace dashboards programmatically using the WebSocket API.
CRITICAL: Dashboard URL Path Requirements
Home Assistant requires dashboard URL paths to contain a hyphen:
- •✅ CORRECT: "climate-control", "mobile-app", "energy-monitor"
- •❌ WRONG: "climate", "mobile", "energy"
Rule: Always use kebab-case with at least one hyphen in the url_path field.
When to Use This Skill
Use this skill when you need to:
- •Create Home Assistant dashboards programmatically via WebSocket API
- •Automate dashboard creation and updates for multiple environments
- •Build dashboard generators for dynamic card configurations
- •Validate dashboard entities before deployment
- •Manage dashboards as code with version control
- •Programmatically update existing dashboard configurations
Do NOT use when:
- •You can use the Home Assistant UI dashboard editor (simpler for manual changes)
- •Building simple static dashboards (UI editor is more intuitive)
- •You haven't created a long-lived access token for API authentication
Usage
- •Connect to WebSocket: Authenticate with long-lived access token
- •Check if exists: Query existing dashboards with
lovelace/dashboards/list - •Create dashboard: Use
lovelace/dashboards/createwith url_path containing hyphen - •Save configuration: Update config with
lovelace/config/save - •Verify: Check HA UI and system logs for errors
Quick Start
import json
import websocket
HA_URL = "http://192.168.68.123:8123"
HA_TOKEN = os.environ["HA_LONG_LIVED_TOKEN"]
def create_dashboard(url_path: str, title: str, config: dict):
"""Create or update a dashboard.
Args:
url_path: Dashboard URL path (must contain hyphen, e.g., "climate-control")
title: Dashboard display title
config: Dashboard configuration dict
"""
# Validate url_path contains hyphen
if "-" not in url_path:
raise ValueError(f"url_path must contain hyphen: '{url_path}' -> '{url_path}-view'")
ws_url = HA_URL.replace("http://", "ws://") + "/api/websocket"
ws = websocket.create_connection(ws_url)
msg_id = 1
# 1. Receive auth_required
ws.recv()
# 2. Send auth
ws.send(json.dumps({"type": "auth", "access_token": HA_TOKEN}))
ws.recv() # auth_ok
# 3. Check if dashboard exists
ws.send(json.dumps({"id": msg_id, "type": "lovelace/dashboards/list"}))
msg_id += 1
response = json.loads(ws.recv())
exists = any(d["url_path"] == url_path for d in response.get("result", []))
# 4. Create if doesn't exist
if not exists:
ws.send(json.dumps({
"id": msg_id,
"type": "lovelace/dashboards/create",
"url_path": url_path, # Must contain hyphen!
"title": title,
"icon": "mdi:view-dashboard",
"show_in_sidebar": True,
}))
msg_id += 1
ws.recv()
# 5. Save configuration
ws.send(json.dumps({
"id": msg_id,
"type": "lovelace/config/save",
"url_path": url_path,
"config": config,
}))
ws.recv()
ws.close()
WebSocket Message Types
| Type | Purpose |
|---|---|
lovelace/dashboards/list | List all dashboards |
lovelace/dashboards/create | Create new dashboard |
lovelace/dashboards/delete | Delete dashboard |
lovelace/config/save | Save dashboard config |
lovelace/config | Get dashboard config |
system_log/list | Check for lovelace errors |
See references/card-types.md for dashboard configuration structure and common card types.
Error Checking
Validate Dashboard Configuration
# 1. Check system logs for lovelace errors
ws.send(json.dumps({"id": 1, "type": "system_log/list"}))
logs = json.loads(ws.recv())
# Filter for 'lovelace' or 'frontend' errors
# 2. Validate dashboard configuration
ws.send(json.dumps({
"id": 2,
"type": "lovelace/config",
"url_path": "climate-control" # Must contain hyphen
}))
config = json.loads(ws.recv())
# 3. Validate entity IDs exist
ws.send(json.dumps({"id": 3, "type": "get_states"}))
states = json.loads(ws.recv())
entity_ids = [s["entity_id"] for s in states["result"]]
# 4. Check if entities used in dashboard exist
for card in dashboard_config["views"][0]["cards"]:
if "entity" in card:
if card["entity"] not in entity_ids:
print(f"Warning: Entity {card['entity']} not found")
Common Error Patterns
- •URL path missing hyphen:
"url_path": "climate"→ Add hyphen:"climate-control" - •Entity doesn't exist: Check entity ID in Developer Tools → States
- •Custom card not installed: Install via HACS first
- •JavaScript errors: Check browser console (F12) for configuration errors
Entity Validation
Verify entity IDs exist before using them in dashboards.
See references/entity-patterns.md for entity validation functions and common entity patterns.
Supporting Files
- •scripts/create_dashboard.py - Complete working example with entity validation
- •references/card-types.md - Dashboard configuration structure and card types
- •references/entity-patterns.md - Entity validation and common patterns
Workflow
- •Design dashboard - Plan views and card layout
- •Validate entities - Check all entity IDs exist
- •Connect to WebSocket - Authenticate with HA
- •Check if exists - Query existing dashboards
- •Create dashboard - Create if new (ensure url_path has hyphen!)
- •Save configuration - Update dashboard config
- •Verify - Check in HA UI and system logs for errors
URL Path Examples
| Dashboard Type | Bad URL Path | Good URL Path |
|---|---|---|
| Climate monitoring | "climate" | "climate-control" |
| Mobile view | "mobile" | "mobile-app" |
| Energy tracking | "energy" | "energy-monitor" |
| Air quality | "air" | "air-quality" |
| Irrigation | "irrigation" | "irrigation-control" |
Troubleshooting
Dashboard not appearing in sidebar
- •Check
show_in_sidebar: Truein dashboard creation - •Verify
url_pathcontains hyphen - •Refresh browser (Ctrl+Shift+R)
- •Check HA logs for errors
Configuration not saving
- •Verify WebSocket authentication succeeded
- •Check
url_pathmatches existing dashboard - •Validate JSON structure (no syntax errors)
- •Check system logs via
system_log/list
Entity not found errors
- •Get all entities:
{"type": "get_states"} - •Compare with entities used in dashboard
- •Fix entity IDs or remove missing entities
- •Ensure entity has proper
state_classfor sensors