news 2026/10/13 6:47:31

Home-AssistantConfig 仪表盘维护实战:YAML 渲染校验与 sections 列布局模式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Home-AssistantConfig 仪表盘维护实战:YAML 渲染校验与 sections 列布局模式
  • 智能家居
  • 物联网

【免费下载链接】Home-AssistantConfig

:house: Home Assistant configuration & Documentation for my Smart House. Write-ups, videos, part lists, and links throughout. Be sure to :star: it. Updated FREQUENTLY!

项目地址:https://gitcode.com/gh_mirrors/ho/Home-AssistantConfig
点击查看免费下载

导读

本文围绕 config/dashboards/SCRATCHPAD.md 记录的两条核心维护经验展开:一是保证 YAML 托管(Lovelace YAML mode)的仪表盘在渲染时"不缺 include、不缺资源",并在重启 Home Assistant 之前完成校验;二是在使用type: sections视图时,避免max_columns: 1造成的居中细长列问题,改用max_columns: 4配合单节columns: 1的组合。读完本文,你将掌握 Home-AssistantConfig 仓库中仪表盘从"编辑 YAML"到"渲染前校验"再到"安全重启"的完整工作流,理解底层校验器validate_dashboards.py的实现原理与测试覆盖,并学会可复制的 sections 列布局模式。


一、为什么需要 SCRATCHPAD:YAML 仪表盘维护的痛点

Home Assistant 默认把仪表盘与 UI 资源存放在config/.storage/(运行时状态),而本仓库刻意将仪表盘全部迁移为 YAML 文件,托管在config/dashboards/下。这样做的收益在 config/dashboards/README.md 中写得很清楚:YAML 仪表盘让 UI 进入版本控制,并可以被自动化工具直接编辑。

但 YAML 托管也引入两类典型故障:

  1. 渲染残缺:视图通过!include、!include_dir_list等标签加载局部文件,一旦 include 路径写错、被 include 的文件里出现重复键或语法错误、甚至出现循环 include,前端渲染会直接失败;
  2. 重启翻车:仪表盘 YAML 与configuration.yaml不一致(例如仍在使用已被 Home Assistant 2026.8 移除的lovelace.mode: yaml旧配置),重启后整个 Lovelace 打不开。

SCRATCHPAD.md 正是这一维护场景的"停车位":它记录当前待办("让 YAML 仪表盘保持正常渲染,无缺失 include/资源";"重启 Home Assistant 前先校验仪表盘")以及沉淀下来的布局模式。接下来我们逐一展开,并用仓库源码佐证每个做法。


二、让 YAML 仪表盘"渲染不缺件":include 与资源完整性校验

2.1 校验器入口与运行方式

仓库在 tools/validate_dashboards.py 实现了一个"严格校验 YAML 托管 Lovelace 仪表盘"的独立工具(模块 docstring 原话:Strict validation for YAML-managed Home Assistant Lovelace dashboards)。运行方式有两种:

  • Python 直跑(依赖仅PyYAML==6.0.3,见 requirements-dev.txt):

    python tools/validate_dashboards.py

    校验通过时输出类似:

    OK: validated 4 dashboards, 24 routes, 312 YAML files, and 156 static entity references

    失败时以退出码2在 stderr 打印ERROR: ...(见 validate_dashboards.py 的main)。

  • PowerShell 包装tools/validate_dashboards.ps1:自动探测py -3或python,把仓库根目录解析为Split-Path -Parent $PSScriptRoot后转调validate_dashboards.py并透传退出码。

另外还提供--routes-json参数,把校验通过后的完整路由表以 JSON 输出,方便下游脚本使用(validate_dashboards.py)。

2.2 两层校验管线

validate_repository()(validate_dashboards.py)串联了五道检查,对应 SCRATCHPAD"无缺失 includes/resources"的目标:

检查阶段方法作用
头部规范validate_headers()每个 dashboard YAML 必须带标准文件头(######################################################################分隔线,以及@CCOSTAN、vcloudinfo、Original Repo三行说明),缺失即报错
配置声明validate_configuration()校验 config/configuration.yaml 中lovelace段:resource_mode必须是yaml,resources必须用!include,每个dashboards条目必须mode: yaml且带filename;同时禁止旧版lovelace.mode声明(该字段已在 HA 2026.8 移除)
include 图解析resolve_value()/load_file()/_load_directory()递归解析!include、!include_dir_list、!include_dir_merge_list、!include_dir_named、!include_dir_merge_named,并对 merge 类标签做类型与重复键检查
视图结构validate_dashboard()每个 dashboard 必须解析为 mapping、views非空、每个 view 的path匹配^[A-Za-z0-9_-]+$且全局不重复;path缺省时按 Home Assistant 规则取视图下标字符串
孤儿文件validate_no_orphans()config/dashboards/下所有.yaml若未被任何 include 图引用,判定为孤儿并报错

2.3 底层实现的几个关键设计

  • 自定义 Loader 兼容 HA 语义:HomeAssistantLoader继承yaml.SafeLoader,重写construct_mapping检测重复键(found duplicate key ...),并通过移除 YAML 1.1 布尔隐式解析器,让on/off/yes/no按 HA 习惯保持字符串(validate_dashboards.py)。这正是"渲染不缺件"之外保证"渲染语义正确"的关键。
  • include 路径防逃逸:resolve_target()支持绝对容器路径/config/...与相对路径,但解析后强制relative_to(self.config_dir),任何试图跳出config/的 include 都会被拒绝(validate_dashboards.py)。
  • 循环 include 检测:用_visiting集合记录解析栈,path in self._visiting时抛出cyclic YAML include detected(validate_dashboards.py)。
  • 注释中的 include 会被忽略:_yaml_files只按目录扫描,!include只从解析后的值树触发,因此注释掉的 include 不影响校验(测试test_commented_include_is_ignored佐证,见 tests/test_validate_dashboards.py)。

2.4 实体引用校验:防止"渲染出来却是空卡片"

SCRATCHPAD 强调"无缺失",除了 include/资源,本仓库还把校验延伸到实体引用。collect_entity_references()从解析后的文档树里收集entity、entity_id、camera_image键以及entities列表中的实体 ID;随后validate_entity_references()(validate_dashboards.py)把引用与三份"已知清单"做比对:

  1. repository_entity_catalog():除 dashboards 目录外,全仓库.yaml中出现的实体 ID(即config/packages/、config/automation/等处的定义);
  2. live_entity_catalog():config/.storage/core.entity_registry与core.restore_state中的实体(本地 HA 实际注册表,文件存在时才读取);
  3. read_entity_allowlist():tools/dashboard_entity_allowlist.txt 中手写维护的白名单,用于补充"由 UI 管理的 helper、集成或生成名"的实体(文件头注释原文即说明用途)。

比对结果分三类报错:仪表盘中引用了三份清单都查不到的实体(unknown static dashboard entity references)、白名单里已不被仪表盘引用的过期条目(stale dashboard entity allowlist entries)、以及白名单条目在 live storage 中也不存在(allowlisted dashboard entities are absent from live storage)。白名单文件本身也有严格约束——每条必须是合法实体 ID(^[a-z][a-z0-9_]*\.[a-z0-9_]+$),且要求保持排序。

2.5 测试佐证:故障模式全覆盖

tests/test_validate_dashboards.py 用tempfile构造迷你仓库夹具(configuration.yaml+ui-lovelace.yaml+overview/dashboard.yaml+ 视图文件),逐一验证校验器的故障拦截能力:

  • test_valid_fixture_builds_routes:合法夹具应产出路由("/lovelace", "/lovelace/home"),且sensor.real进入实体引用集合;
  • test_malformed_dashboard_yaml_fails:追加broken: [应报invalid YAML;
  • test_missing_entrypoint_include_fails:把入口 include 指向不存在的文件应报missing include file;
  • test_nonexistent_static_entity_fails:把视图实体从sensor.real改成sensor.missing应报未知实体;
  • test_duplicate_view_path_fails:两个视图共用path: home应报duplicate view path;
  • test_orphaned_dashboard_file_fails:新增未被引用的overview/orphan.yaml应报orphaned dashboard YAML;
  • test_duplicate_yaml_key_fails:追加重复path:键应报duplicate key。

这组用例直接对应"重启前校验"清单里最常踩的坑,可作为你自己仪表盘仓库测试用例的范本。


三、重启前校验:容器/受管环境下的配置检查

SCRATCHPAD 第二条待办是"Validate dashboards before restarting Home Assistant"(重启前先校验仪表盘)。仓库为此提供了两层手段:

  1. 仓库层:上一节的validate_dashboards.py在提交前拦截静态问题;
  2. 运行时层:tools/ha_check_config.ps1 在目标主机上真正跑一次 Home Assistant 的配置检查,与homeassistant.helpers.check_config.async_check_ha_config_file等价。

ha_check_config.ps1支持三个参数(脚本头部param()声明):

参数默认值说明
TargetHostdocker_10SSH 目标主机(本仓库的 HA 容器宿主)
ContainerNamehome-assistant容器名
ConfigPath/config容器内配置目录
Modeautoauto/container/supervised三选一

三种模式的分工(见 ha_check_config.ps1):

  • supervised:远程执行ha core check(Supervisor CLI);
  • container:远程执行一段 bash,先确认docker可用且容器在运行,再docker exec -i -e CONFIG_DIR=/config home-assistant python -把内嵌的 Python 检查脚本灌进容器执行;
  • auto:先探测haCLI,没有再探测docker,都没有则退出码 127。

内嵌 Python 脚本(ha_check_config.ps1)的调用链是:bootstrap.async_load_base_functionality(hass)初始化 HA 核心 →async_check_ha_config_file(hass)执行完整配置校验 → 有res.errors时逐条打印并返回 1,否则打印Configuration valid(有 warnings 也一并列出)。配合 PowerShell 侧的Quote-BashArg(单引号转义防注入)与Set-StrictMode -Version Latest,这套脚本可以直接用于"编辑完仪表盘 → SSH 到宿主 → 容器内校验 → 通过后再重启"的发布流程。

注意:这是本仓库面向其"docker_10 宿主 + home-assistant 容器"环境的真实方案;若你的 HA 是 supervised 安装,直接使用Mode=supervised即可。


四、sections 列布局模式:为什么避开max_columns: 1

SCRATCHPAD 沉淀了一条明确的布局经验:

如果某个视图看起来像"居中的细长列",避免使用max_columns: 1;优先max_columns: 4,配合单个 section/card 使用columns: 1。

4.1 问题本质

在type: sections视图中,max_columns决定整页网格的最大列数。一旦设为1,所有section 都会被压缩进唯一的窄列里,卡片互相堆叠、行高被拉长,视觉上就是一条居中的"细香肠"列——即使你只想让其中一节变窄,其他节也被迫跟着变窄。而把页面放宽到max_columns: 4,则每个 section 都能通过column_span(跨列)和自身的columns独立控制宽度:需要窄列的那节声明columns: 1,其余节照常跨满多列。这样既得到"窄列"的视觉意图,又保留了页面整体的高密度布局。

4.2 仓库中的实际应用

实例一:Overview 首页顶部的"状态胶囊条"。在 config/dashboards/overview/sections/00_summary.yaml 中,优先级状态条声明为:

type: grid column_span: 4 columns: 1 square: false

它所在的父视图 config/dashboards/overview/views/01_home.yaml 使用max_columns: 3,而这一节自己column_span: 4(跨满) +columns: 1(内部只排一列)。section 内部的 7 个按钮卡片(Systems 状态、两个车库门、前门锁、窗户、上下楼温控、扫地机)由custom:layout-card的grid-template-columns: repeat(7, minmax(0, 1fr))排成等宽胶囊行,并在(max-width: 600px)媒体查询下退化为 4 列(00_summary.yaml)。这正是"页面宽、单节窄/单行"模式下columns: 1的正确用法——节内仍然可以借助 layout-card 自己管理横向排布。

实例二:Systems(infrastructure)的标准视图约定。config/dashboards/README.md 明确写道:

Systems views are desktop-first and dense by default: usetype: sections,max_columns: 4, anddense_section_placement: trueon every standard view.

仓库内几乎所有 Systems 视图都遵循该约定,例如 config/dashboards/infrastructure/views/01_hvac.yaml 的声明:

type: sections max_columns: 4 dense_section_placement: true badges: [] sections: !include /config/dashboards/infrastructure/partials/hvac_sections.yaml cards: []

dense_section_placement: true让 section 紧凑排列、去掉卡片间多余的垂直空隙;max_columns: 4为多列 KPI 面板(Proxmox 主机健康、Docker 容器、网络等)提供足够网格。同样的模式还见于 config/dashboards/infrastructure/views/02_proxmox.yaml。作为对照,Overview 首页因为是"人的日常首页"而非高密度运维页,使用的是max_columns: 3(01_home.yaml)——说明列数选择应当服务于内容密度与使用场景,而不是机械套用一个数字。

实例三:卡片模板的"单列即窄列"语义。共享按钮卡片模板定义在 config/dashboards/infrastructure/templates/button_card_templates.yaml,其中bearstone_infra_base通过grid-template-columns: 40px 1fr让图标与名称/状态并排("i n" / "i s"网格区域),确保"单列卡片"自身宽度缩到最小时图标和文字也不会重叠。这说明:真正决定窄列可用性的,是卡片模板的响应式设计,而max_columns只是网格外壳。

4.3 可复制的决策规则

结合 SCRATCHPAD 与仓库实践,可以提炼出以下决策清单:

  1. 普通桌面优先的运维视图:type: sections+max_columns: 4+dense_section_placement: true;
  2. 只想让某一块内容变窄:不要改max_columns,改那一节的column_span(占几列)与columns(节内排几列);需要跨满整行时用column_span: 4+columns: 1;
  3. 任何时候都不要用max_columns: 1来"制造窄列",它会拖垮整页布局;
  4. 窄列内部若还要横向排多个小卡片,交给custom:layout-card的grid-template-columns+mediaquery处理,而不是堆叠vertical-stack。

五、完整维护工作流:从编辑到安全重启

把 SCRATCHPAD 的两条待办串起来,就是本仓库仪表盘维护的端到端流程:

  1. 编辑:在config/dashboards/<dashboard>/下修改视图、partials、popups 或 templates。include 一律使用以/config/开头的绝对容器路径(README 约定:!include /config/dashboards/overview/partials/some_cards.yaml);新增视图文件时文件名加01_、02_前缀,因为视图由!include_dir_list加载并按文件名排序(config/dashboards/README.md 的 Conventions 节)。
  2. 静态校验:运行python tools/validate_dashboards.py(或 PowerShell 包装),确认头部规范、include 图完整、view path 合法、无孤儿文件、实体引用全部有出处。
  3. 运行时校验:运行.\tools\ha_check_config.ps1 -TargetHost <host> -Mode auto,在容器/Supervisor 内跑真实配置检查,确认Configuration valid。
  4. 重启:校验通过后再重启 Home Assistant。README 的原话是:"It is safe to restart Home Assistant after dashboard changes as long as a configuration check passes first."(配置检查通过的前提下,仪表盘改动后重启是安全的。)

此外还有两条迁移期的硬约束值得留意(config/dashboards/README.md 的 Migration/Cutover Notes):迁移期间不要用与现有 storage 仪表盘相同的 dashboard ID/key 创建 YAML 仪表盘;确认 YAML 仪表盘渲染正常后,再到Settings -> Dashboards隐藏或删除旧 storage 仪表盘。


六、结语

SCRATCHPAD 虽短,却是本仓库仪表盘工程的"维护操作手册摘要":渲染完整性靠validate_dashboards.py的 include 图解析与实体引用校验兜底,重启安全靠ha_check_config.ps1的运行时检查兜底,视觉质量靠max_columns: 4+ 单节columns: 1的布局模式兜底。三个环节环环相扣,全部有源码与测试佐证。如果你的智能家居也在走"YAML 仪表盘版本化"路线,这套"编辑 → 静态校验 → 运行时校验 → 重启"的流程和 sections 列布局决策规则,可以直接照搬进自己的仓库。

延伸阅读(仓库内路径)

  • 维护摘要:config/dashboards/SCRATCHPAD.md
  • 仪表盘结构与约定:config/dashboards/README.md
  • 静态校验器:tools/validate_dashboards.py、tools/validate_dashboards.ps1
  • 校验器测试:tests/test_validate_dashboards.py
  • 实体白名单:tools/dashboard_entity_allowlist.txt
  • 运行时配置检查:tools/ha_check_config.ps1
  • Lovelace 声明与资源:config/configuration.yaml、config/dashboards/resources.yaml
  • 布局模式实例:config/dashboards/overview/sections/00_summary.yaml、config/dashboards/infrastructure/views/01_hvac.yaml
  • 智能家居
  • 物联网

【免费下载链接】Home-AssistantConfig

:house: Home Assistant configuration & Documentation for my Smart House. Write-ups, videos, part lists, and links throughout. Be sure to :star: it. Updated FREQUENTLY!

项目地址:https://gitcode.com/gh_mirrors/ho/Home-AssistantConfig
点击查看免费下载

相关推荐

上一篇:LeetCode 2971 详解:Find Polygon With the Largest Perimeter——排序、前缀和与最大堆三种解法
下一篇:Zephyr RTOS 在 Infineon XMC4500 Relax Kit 上的开发指南:硬件特性、构建烧录与 J-Link 调试实战

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/13 6:46:42

agent-skills 实战:让大模型从会聊天到能干活

1. 从“会聊天”到“能干活”&#xff1a;agent-skills 到底在解决什么问题如果你最近半年一直在折腾大模型应用&#xff0c;大概率会有一种强烈的割裂感&#xff1a;模型在对话框里上知天文下知地理&#xff0c;可一旦让它去真实环境里干点活——读一份本地表格、调一个内部接…

作者头像 李华
网站建设 2026/10/13 6:44:31

从日志管理到AI自治:企业监控体系演进之路

前几年排查线上问题&#xff0c;我的标准动作还是先开三四个终端&#xff1a;一个tail -f应用日志&#xff0c;一个跑grep过滤关键字&#xff0c;再开一个盯df -h。日志、告警、监控彼此割裂&#xff0c;出了问题靠人肉顺着日志一步步找&#xff0c;运气好几分钟&#xff0c;运…

作者头像 李华
网站建设 2026/10/13 6:44:26

企业级AI Agent混合架构实战:LangGraph编排+RAG知识库+MCP工具集成

1. 为什么企业级 Agent 不能直接“套模板”先聊个现象。现在一搜“AI Agent 架构”&#xff0c;满屏都是 LangGraph 单节点 ReAct、AutoGPT 式自主循环&#xff0c;看着很热闹。但真要往企业生产环境里放&#xff0c;十有八九会撞上几个绕不开的问题&#xff1a;Agent 跑着跑着…

作者头像 李华
网站建设 2026/10/13 6:43:32

蓝桥杯回文日期题:历法规则与字符串翻转的工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/13 6:42:56

Scrapling 安装指南:3 条命令从 pip 到首次抓取请求

Scrapling 安装指南&#xff1a;3 条命令从 pip 到首次抓取请求 【免费下载链接】Scrapling &#x1f577;️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Dont be shy, join here: https://discord.gg/EMgGbDc…

作者头像 李华