ha-error-checking
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWorks 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-controlOr 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:
- Check system logs for lovelace/frontend errors
- Validate dashboard config exists and is properly formatted
- Verify entity IDs exist in Home Assistant
- Check HACS cards are installed before use
- Validate card configurations for known issues (ApexCharts span, URL paths)
按照以下步骤调试Home Assistant仪表盘错误:
- 检查系统日志,查找Lovelace/前端错误
- 验证仪表盘配置是否存在且格式正确
- 确认实体ID在Home Assistant中存在
- 检查HACS卡片是否已安装再使用
- 验证卡片配置是否存在已知问题(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", ...}, ...]
undefinedundefinedFilter 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
undefinedundefinedValidate 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...")
undefinedvalidate_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...")
undefinedEntity 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) > 0python
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) > 0Known 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: must be one of: "minute", "hour", "day", "week", "month", "year", "isoWeek"
span.endpython
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, ""重要提示:的值只能是以下之一:"minute", "hour", "day", "week", "month", "year", "isoWeek"
span.endpython
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
undefinedapexcharts_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
undefinedSupporting 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
undefinedWRONG
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"} # ✅
}
undefinedcard = {
"type": "custom:apexcharts-card",
"span": {"end": "hour"} # ✅
}
undefined2. Dashboard URL Path Missing Hyphen
2. 仪表盘URL路径缺少连字符
Error: Dashboard doesn't appear in sidebar
Solution:
python
undefined**错误现象:**仪表盘未显示在侧边栏
解决方案:
python
undefinedWRONG
WRONG
url_path = "climate" # ❌
url_path = "climate" # ❌
CORRECT
CORRECT
url_path = "climate-control" # ✅
undefinedurl_path = "climate-control" # ✅
undefined3. Entity Not Found
3. 实体未找到
Error:
"Entity not found: sensor.temperature"Solution:
python
undefined错误信息:
"Entity not found: sensor.temperature"解决方案:
python
undefinedCheck 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 only accepts: minute, hour, day, week, month, year, isoWeek
span.end - 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的仅接受以下值:minute, hour, day, week, month, year, isoWeek
span.end - HACS仓库ID:mini-graph-card (151280062), apexcharts-card (331701152)
- 每次更新仪表盘后都要检查系统日志是否有错误
- 使用开发者工具 → 状态页面验证实体ID后再使用