ha-error-checking

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
Works with Home Assistant WebSocket API, Python websocket library, and YAML configurations.
适用于Home Assistant WebSocket API、Python websocket库和YAML配置。

Home Assistant Error Checking and Validation

Home Assistant 错误检查与验证

Debug and validate Home Assistant dashboards, configurations, and entity usage programmatically.
以编程方式调试和验证Home Assistant仪表盘、配置以及实体使用情况。

Quick Start

快速开始

Use the automation script for fast dashboard validation:
bash
python ~/.claude/skills/ha-error-checking/scripts/check_dashboard.py climate-control
Or use the Quick Start workflow below for custom checks.
使用自动化脚本快速验证仪表盘:
bash
python ~/.claude/skills/ha-error-checking/scripts/check_dashboard.py climate-control
或者使用下方的快速开始工作流进行自定义检查。

Quick Start Workflow

快速开始工作流

python
import json
import websocket
import os

HA_URL = "http://192.168.68.123:8123"
HA_TOKEN = os.environ["HA_LONG_LIVED_TOKEN"]

def check_dashboard_errors(url_path: str):
    """Check for errors in a specific dashboard."""
    ws_url = HA_URL.replace("http://", "ws://") + "/api/websocket"
    ws = websocket.create_connection(ws_url)
    msg_id = 1

    # 1. Auth
    ws.recv()
    ws.send(json.dumps({"type": "auth", "access_token": HA_TOKEN}))
    ws.recv()

    # 2. Check system logs for lovelace errors
    ws.send(json.dumps({"id": msg_id, "type": "system_log/list"}))
    msg_id += 1
    logs = json.loads(ws.recv())

    lovelace_errors = [
        log for log in logs.get("result", [])
        if "lovelace" in log.get("name", "").lower()
        or "frontend" in log.get("name", "").lower()
    ]

    # 3. Validate dashboard config
    ws.send(json.dumps({
        "id": msg_id,
        "type": "lovelace/config",
        "url_path": url_path
    }))
    msg_id += 1
    config_response = json.loads(ws.recv())

    # 4. Get all entity states
    ws.send(json.dumps({"id": msg_id, "type": "get_states"}))
    msg_id += 1
    states_response = json.loads(ws.recv())

    ws.close()

    return {
        "lovelace_errors": lovelace_errors,
        "config": config_response.get("result"),
        "available_entities": [s["entity_id"] for s in states_response.get("result", [])]
    }
python
import json
import websocket
import os

HA_URL = "http://192.168.68.123:8123"
HA_TOKEN = os.environ["HA_LONG_LIVED_TOKEN"]

def check_dashboard_errors(url_path: str):
    """Check for errors in a specific dashboard."""
    ws_url = HA_URL.replace("http://", "ws://") + "/api/websocket"
    ws = websocket.create_connection(ws_url)
    msg_id = 1

    # 1. Auth
    ws.recv()
    ws.send(json.dumps({"type": "auth", "access_token": HA_TOKEN}))
    ws.recv()

    # 2. Check system logs for lovelace errors
    ws.send(json.dumps({"id": msg_id, "type": "system_log/list"}))
    msg_id += 1
    logs = json.loads(ws.recv())

    lovelace_errors = [
        log for log in logs.get("result", [])
        if "lovelace" in log.get("name", "").lower()
        or "frontend" in log.get("name", "").lower()
    ]

    # 3. Validate dashboard config
    ws.send(json.dumps({
        "id": msg_id,
        "type": "lovelace/config",
        "url_path": url_path
    }))
    msg_id += 1
    config_response = json.loads(ws.recv())

    # 4. Get all entity states
    ws.send(json.dumps({"id": msg_id, "type": "get_states"}))
    msg_id += 1
    states_response = json.loads(ws.recv())

    ws.close()

    return {
        "lovelace_errors": lovelace_errors,
        "config": config_response.get("result"),
        "available_entities": [s["entity_id"] for s in states_response.get("result", [])]
    }

Usage

使用方法

Follow these steps to debug Home Assistant dashboard errors:
  1. Check system logs for lovelace/frontend errors
  2. Validate dashboard config exists and is properly formatted
  3. Verify entity IDs exist in Home Assistant
  4. Check HACS cards are installed before use
  5. Validate card configurations for known issues (ApexCharts span, URL paths)
按照以下步骤调试Home Assistant仪表盘错误:
  1. 检查系统日志,查找Lovelace/前端错误
  2. 验证仪表盘配置是否存在且格式正确
  3. 确认实体ID在Home Assistant中存在
  4. 检查HACS卡片是否已安装再使用
  5. 验证卡片配置是否存在已知问题(ApexCharts span、URL路径)

System Logs - Check for Errors

系统日志 - 错误检查

Get All System Logs

获取所有系统日志

python
ws.send(json.dumps({"id": 1, "type": "system_log/list"}))
response = json.loads(ws.recv())

logs = response.get("result", [])
python
ws.send(json.dumps({"id": 1, "type": "system_log/list"}))
response = json.loads(ws.recv())

logs = response.get("result", [])

Structure: [{"name": "homeassistant.components.lovelace", "message": "...", "level": "ERROR", ...}, ...]

Structure: [{"name": "homeassistant.components.lovelace", "message": "...", "level": "ERROR", ...}, ...]

undefined
undefined

Filter for Lovelace/Frontend Errors

筛选Lovelace/前端错误

python
lovelace_errors = [
    log for log in logs
    if "lovelace" in log.get("name", "").lower()
    or "frontend" in log.get("name", "").lower()
]

for error in lovelace_errors:
    print(f"[{error['level']}] {error['name']}: {error['message']}")
python
lovelace_errors = [
    log for log in logs
    if "lovelace" in log.get("name", "").lower()
    or "frontend" in log.get("name", "").lower()
]

for error in lovelace_errors:
    print(f"[{error['level']}] {error['name']}: {error['message']}")

Dashboard Configuration Validation

仪表盘配置验证

Get Dashboard Config

获取仪表盘配置

python
ws.send(json.dumps({
    "id": 1,
    "type": "lovelace/config",
    "url_path": "climate-control"  # Must contain hyphen
}))
response = json.loads(ws.recv())

config = response.get("result")
python
ws.send(json.dumps({
    "id": 1,
    "type": "lovelace/config",
    "url_path": "climate-control"  # Must contain hyphen
}))
response = json.loads(ws.recv())

config = response.get("result")

Returns the full dashboard configuration dict

Returns the full dashboard configuration dict

undefined
undefined

Validate Dashboard Exists

验证仪表盘是否存在

python
ws.send(json.dumps({"id": 1, "type": "lovelace/dashboards/list"}))
response = json.loads(ws.recv())

dashboards = response.get("result", [])
dashboard_paths = [d["url_path"] for d in dashboards]

if "climate-control" in dashboard_paths:
    print("Dashboard exists")
else:
    print("Dashboard not found")
python
ws.send(json.dumps({"id": 1, "type": "lovelace/dashboards/list"}))
response = json.loads(ws.recv())

dashboards = response.get("result", [])
dashboard_paths = [d["url_path"] for d in dashboards]

if "climate-control" in dashboard_paths:
    print("Dashboard exists")
else:
    print("Dashboard not found")

Check Dashboard URL Path Format

检查仪表盘URL路径格式

CRITICAL: Dashboard URL paths must contain a hyphen.
python
def validate_url_path(url_path: str) -> tuple[bool, str]:
    """Validate dashboard URL path format.

    Returns:
        (is_valid, error_message)
    """
    if "-" not in url_path:
        return False, f"URL path must contain hyphen: '{url_path}' -> '{url_path}-view'"

    if " " in url_path:
        return False, f"URL path cannot contain spaces: '{url_path}'"

    if not url_path.islower():
        return False, f"URL path must be lowercase: '{url_path}'"

    return True, ""
**重要提示:**仪表盘URL路径必须包含连字符。
python
def validate_url_path(url_path: str) -> tuple[bool, str]:
    """Validate dashboard URL path format.

    Returns:
        (is_valid, error_message)
    """
    if "-" not in url_path:
        return False, f"URL path must contain hyphen: '{url_path}' -> '{url_path}-view'"

    if " " in url_path:
        return False, f"URL path cannot contain spaces: '{url_path}'"

    if not url_path.islower():
        return False, f"URL path must be lowercase: '{url_path}'"

    return True, ""

Examples

Examples

validate_url_path("climate") # ❌ (False, "URL path must contain hyphen...") validate_url_path("climate-control") # ✅ (True, "") validate_url_path("Climate-Control") # ❌ (False, "URL path must be lowercase...")
undefined
validate_url_path("climate") # ❌ (False, "URL path must contain hyphen...") validate_url_path("climate-control") # ✅ (True, "") validate_url_path("Climate-Control") # ❌ (False, "URL path must be lowercase...")
undefined

Entity Validation

实体验证

Get All Available Entities

获取所有可用实体

python
ws.send(json.dumps({"id": 1, "type": "get_states"}))
response = json.loads(ws.recv())

entities = response.get("result", [])
entity_ids = [e["entity_id"] for e in entities]
python
ws.send(json.dumps({"id": 1, "type": "get_states"}))
response = json.loads(ws.recv())

entities = response.get("result", [])
entity_ids = [e["entity_id"] for e in entities]

Group by domain

Group by domain

from collections import defaultdict by_domain = defaultdict(list) for entity_id in entity_ids: domain = entity_id.split(".")[0] by_domain[domain].append(entity_id)
print(f"Total entities: {len(entity_ids)}") print(f"Sensors: {len(by_domain['sensor'])}") print(f"Climate: {len(by_domain['climate'])}")

See `examples/examples.md` for entity extraction from dashboard configs and pattern matching.
from collections import defaultdict by_domain = defaultdict(list) for entity_id in entity_ids: domain = entity_id.split(".")[0] by_domain[domain].append(entity_id)
print(f"Total entities: {len(entity_ids)}") print(f"Sensors: {len(by_domain['sensor'])}") print(f"Climate: {len(by_domain['climate'])}")

查看`examples/examples.md`获取从仪表盘配置提取实体和模式匹配的方法。

HACS Card Installation Validation

HACS卡片安装验证

Check if Card is Installed

检查卡片是否已安装

python
def check_hacs_card_installed(ws, repository_id: int) -> bool:
    """Check if a HACS card is installed by repository ID."""
    ws.send(json.dumps({
        "id": 1,
        "type": "hacs/repositories/list"
    }))
    response = json.loads(ws.recv())

    repositories = response.get("result", [])
    installed = [r for r in repositories if r.get("id") == repository_id]

    return len(installed) > 0
python
def check_hacs_card_installed(ws, repository_id: int) -> bool:
    """Check if a HACS card is installed by repository ID."""
    ws.send(json.dumps({
        "id": 1,
        "type": "hacs/repositories/list"
    }))
    response = json.loads(ws.recv())

    repositories = response.get("result", [])
    installed = [r for r in repositories if r.get("id") == repository_id]

    return len(installed) > 0

Known repository IDs

Known repository IDs

HACS_CARDS = { "mini-graph-card": 151280062, "bubble-card": 680112919, "modern-circular-gauge": 871730343, "lovelace-mushroom": 444350375, "apexcharts-card": 331701152, }
HACS_CARDS = { "mini-graph-card": 151280062, "bubble-card": 680112919, "modern-circular-gauge": 871730343, "lovelace-mushroom": 444350375, "apexcharts-card": 331701152, }

Check installation

Check installation

if check_hacs_card_installed(ws, HACS_CARDS["apexcharts-card"]): print("ApexCharts card is installed") else: print("ApexCharts card NOT installed - install via HACS first")

See `examples/examples.md` for programmatic HACS card installation.
if check_hacs_card_installed(ws, HACS_CARDS["apexcharts-card"]): print("ApexCharts card is installed") else: print("ApexCharts card NOT installed - install via HACS first")

查看`examples/examples.md`获取程序化安装HACS卡片的方法。

Card Configuration Validation

卡片配置验证

Validate ApexCharts Span Configuration

验证ApexCharts Span配置

CRITICAL:
span.end
must be one of: "minute", "hour", "day", "week", "month", "year", "isoWeek"
python
VALID_SPAN_END_VALUES = ["minute", "hour", "day", "week", "month", "year", "isoWeek"]

def validate_apexcharts_span(card_config: dict) -> tuple[bool, str]:
    """Validate ApexCharts span configuration.

    Returns:
        (is_valid, error_message)
    """
    if "span" not in card_config:
        return True, ""  # span is optional

    span = card_config["span"]
    if "end" not in span:
        return True, ""  # end is optional within span

    end_value = span["end"]
    if end_value not in VALID_SPAN_END_VALUES:
        return False, f"Invalid span.end: '{end_value}'. Must be one of: {VALID_SPAN_END_VALUES}"

    return True, ""
重要提示:
span.end
的值只能是以下之一:"minute", "hour", "day", "week", "month", "year", "isoWeek"
python
VALID_SPAN_END_VALUES = ["minute", "hour", "day", "week", "month", "year", "isoWeek"]

def validate_apexcharts_span(card_config: dict) -> tuple[bool, str]:
    """Validate ApexCharts span configuration.

    Returns:
        (is_valid, error_message)
    """
    if "span" not in card_config:
        return True, ""  # span is optional

    span = card_config["span"]
    if "end" not in span:
        return True, ""  # end is optional within span

    end_value = span["end"]
    if end_value not in VALID_SPAN_END_VALUES:
        return False, f"Invalid span.end: '{end_value}'. Must be one of: {VALID_SPAN_END_VALUES}"

    return True, ""

Usage

Usage

apexcharts_card = { "type": "custom:apexcharts-card", "span": {"end": "now"} # ❌ Invalid }
is_valid, error = validate_apexcharts_span(apexcharts_card) if not is_valid: print(f"Error: {error}") # Fix it apexcharts_card["span"]["end"] = "hour" # ✅ Valid
undefined
apexcharts_card = { "type": "custom:apexcharts-card", "span": {"end": "now"} # ❌ Invalid }
is_valid, error = validate_apexcharts_span(apexcharts_card) if not is_valid: print(f"Error: {error}") # Fix it apexcharts_card["span"]["end"] = "hour" # ✅ Valid
undefined

Supporting Files

配套文件

  • examples/examples.md - Comprehensive workflows (complete dashboard validation, entity extraction, pattern matching, HACS installation, custom card validation)
  • references/reference.md - Error patterns, known entity IDs, troubleshooting solutions, best practices
  • scripts/check_dashboard.py - Automated dashboard validation script
  • examples/examples.md - 完整工作流(仪表盘全面验证、实体提取、模式匹配、HACS安装、自定义卡片验证)
  • references/reference.md - 错误模式、已知实体ID、故障排除方案、最佳实践
  • scripts/check_dashboard.py - 自动化仪表盘验证脚本

Common Error Patterns

常见错误模式

1. ApexCharts Span Error

1. ApexCharts Span错误

Error:
"Invalid value for span.end: now"
Solution:
python
undefined
错误信息:
"Invalid value for span.end: now"
解决方案:
python
undefined

WRONG

WRONG

card = { "type": "custom:apexcharts-card", "span": {"end": "now"} # ❌ }
card = { "type": "custom:apexcharts-card", "span": {"end": "now"} # ❌ }

CORRECT

CORRECT

card = { "type": "custom:apexcharts-card", "span": {"end": "hour"} # ✅ }
undefined
card = { "type": "custom:apexcharts-card", "span": {"end": "hour"} # ✅ }
undefined

2. Dashboard URL Path Missing Hyphen

2. 仪表盘URL路径缺少连字符

Error: Dashboard doesn't appear in sidebar
Solution:
python
undefined
**错误现象:**仪表盘未显示在侧边栏
解决方案:
python
undefined

WRONG

WRONG

url_path = "climate" # ❌
url_path = "climate" # ❌

CORRECT

CORRECT

url_path = "climate-control" # ✅
undefined
url_path = "climate-control" # ✅
undefined

3. Entity Not Found

3. 实体未找到

Error:
"Entity not found: sensor.temperature"
Solution:
python
undefined
错误信息:
"Entity not found: sensor.temperature"
解决方案:
python
undefined

Check entity exists

Check entity exists

all_entities = get_all_entity_ids(ws) if "sensor.temperature" not in all_entities: print("Entity not found - check spelling in Developer Tools → States")
# Find similar entities
similar = [e for e in all_entities if "temperature" in e]
print(f"Did you mean: {similar}")

See `references/reference.md` for complete error patterns, browser debugging steps, best practices, and troubleshooting checklist.
all_entities = get_all_entity_ids(ws) if "sensor.temperature" not in all_entities: print("Entity not found - check spelling in Developer Tools → States")
# Find similar entities
similar = [e for e in all_entities if "temperature" in e]
print(f"Did you mean: {similar}")

查看`references/reference.md`获取完整的错误模式、浏览器调试步骤、最佳实践和故障排除清单。

Notes

注意事项

  • Dashboard URL paths MUST contain a hyphen (e.g., "climate-control" not "climate")
  • ApexCharts
    span.end
    only accepts: minute, hour, day, week, month, year, isoWeek
  • HACS repository IDs: mini-graph-card (151280062), apexcharts-card (331701152)
  • Check system logs after every dashboard update for errors
  • Use Developer Tools → States to verify entity IDs before use
  • 仪表盘URL路径必须包含连字符(例如:"climate-control"而非"climate")
  • ApexCharts的
    span.end
    仅接受以下值:minute, hour, day, week, month, year, isoWeek
  • HACS仓库ID:mini-graph-card (151280062), apexcharts-card (331701152)
  • 每次更新仪表盘后都要检查系统日志是否有错误
  • 使用开发者工具 → 状态页面验证实体ID后再使用