スキル一覧に戻る
dawiddutoit

ha-dashboard-create

by dawiddutoit

Collection of Claude Code skills, agents, and plugins

0🍴 0📅 2026年1月20日
GitHubで見るManusで実行

SKILL.md


name: ha-dashboard-create description: "Create and update Home Assistant Lovelace dashboards programmatically via WebSocket API. Use when building custom dashboards, automating dashboard creation, or managing multiple dashboards for different users/views. Covers WebSocket protocol, dashboard structure, view configuration, and card layout patterns."

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.

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()

Dashboard Configuration Structure

dashboard_config = {
    "views": [
        {
            "title": "Overview",
            "path": "overview",  # View path (no hyphen required)
            "cards": [
                # Card configurations here
            ],
        },
        {
            "title": "Climate",
            "path": "climate",  # View path (no hyphen required)
            "cards": [
                # More cards
            ],
        },
    ],
}

Note: View paths (within a dashboard) don't require hyphens, only the dashboard url_path does.

WebSocket Message Types

TypePurpose
lovelace/dashboards/listList all dashboards
lovelace/dashboards/createCreate new dashboard
lovelace/dashboards/deleteDelete dashboard
lovelace/config/saveSave dashboard config
lovelace/configGet dashboard config
system_log/listCheck for lovelace errors

Common Card Types

Entities Card

{
    "type": "entities",
    "title": "Climate",
    "entities": [
        "climate.snorlug",
        "climate.val_hella_wam",
        "climate.mines_of_moria",
    ],
}

Gauge Card

{
    "type": "gauge",
    "entity": "sensor.officeht_temperature",
    "name": "Temperature",
    "min": 0,
    "max": 50,
    "severity": {
        "green": 18,
        "yellow": 26,
        "red": 35,
    },
}

Grid Layout

{
    "type": "grid",
    "columns": 3,
    "square": False,
    "cards": [
        # Cards here
    ],
}

Vertical Stack

{
    "type": "vertical-stack",
    "cards": [
        # Multiple cards stacked vertically
    ],
}

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

  1. URL path missing hyphen: "url_path": "climate" → Add hyphen: "climate-control"
  2. Entity doesn't exist: Check entity ID in Developer Tools → States
  3. Custom card not installed: Install via HACS first
  4. JavaScript errors: Check browser console (F12) for configuration errors

Entity Validation

Verify Entity IDs Before Creating Dashboard

def get_entity_ids(ws) -> list[str]:
    """Get all available entity IDs from HA."""
    ws.send(json.dumps({"id": 1, "type": "get_states"}))
    response = json.loads(ws.recv())
    return [state["entity_id"] for state in response.get("result", [])]

def validate_dashboard_entities(config: dict, available_entities: set[str]) -> list[str]:
    """Validate all entities in dashboard exist.

    Returns:
        List of missing entity IDs
    """
    used_entities = []
    missing = []

    for view in config.get("views", []):
        for card in view.get("cards", []):
            # Extract entities from card (handles different card types)
            if "entity" in card:
                used_entities.append(card["entity"])
            if "entities" in card:
                used_entities.extend(card["entities"])

    for entity in used_entities:
        # Handle entity strings and dicts
        entity_id = entity if isinstance(entity, str) else entity.get("entity")
        if entity_id and entity_id not in available_entities:
            missing.append(entity_id)

    return missing

# Usage
ws = connect_to_ha()
available = set(get_entity_ids(ws))
missing = validate_dashboard_entities(dashboard_config, available)

if missing:
    print(f"Warning: Missing entities: {missing}")

Entity ID Patterns (from HA instance)

Enviro+ Sensors

enviro_sensors = [
    "sensor.enviro_sensor_temperature",
    "sensor.enviro_sensor_humidity",
    "sensor.enviro_sensor_pressure",
    "sensor.enviro_sensor_light",
    "sensor.enviro_sensor_pm1_0",
    "sensor.enviro_sensor_pm2_5",
    "sensor.enviro_sensor_pm10",
]

Office Sensors

office_sensors = [
    "sensor.officeht_temperature",
    "sensor.officeht_humidity",
    "sensor.officeht_battery",
]

Climate Devices

climate_devices = [
    "climate.snorlug",
    "climate.val_hella_wam",
    "climate.mines_of_moria",
]

Shelly Power Monitoring

power_sensors = [
    "sensor.shellyplus1pm_*_switch_0_power",
    "sensor.shellyswitch25_*_channel_1_power",
]

Complete Example

See scripts/create_dashboard.py for a complete working example.

Workflow

  1. Design dashboard - Plan views and card layout
  2. Validate entities - Check all entity IDs exist
  3. Connect to WebSocket - Authenticate with HA
  4. Check if exists - Query existing dashboards
  5. Create dashboard - Create if new (ensure url_path has hyphen!)
  6. Save configuration - Update dashboard config
  7. Verify - Check in HA UI and system logs for errors

URL Path Examples

Dashboard TypeBad URL PathGood 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

  1. Check show_in_sidebar: True in dashboard creation
  2. Verify url_path contains hyphen
  3. Refresh browser (Ctrl+Shift+R)
  4. Check HA logs for errors

Configuration not saving

  1. Verify WebSocket authentication succeeded
  2. Check url_path matches existing dashboard
  3. Validate JSON structure (no syntax errors)
  4. Check system logs via system_log/list

Entity not found errors

  1. Get all entities: {"type": "get_states"}
  2. Compare with entities used in dashboard
  3. Fix entity IDs or remove missing entities
  4. Ensure entity has proper state_class for sensors

Resources

スコア

総合スコア

50/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です