Home Assistant 报表生成与历史数据统计:如何把用电、温湿度变成看得懂的报表
2026/9/8 10:54:26 网站建设 项目流程

Home Assistant 报表生成与历史数据统计:如何把用电、温湿度变成看得懂的报表

【免费下载链接】core:house_with_garden: Open source home automation that puts local control and privacy first.项目地址: https://gitcode.com/GitHub_Trending/co/core

月底电费账单跳涨 80 块,你却说不清是空调、烘干机还是那台跑了一整月的矿……不对,NAS 干的。这就是 Home Assistant 历史数据统计要解决的问题:它把你家的传感器、智能插座状态持续存进数据库,再按 5 分钟和小时两级自动聚合成统计报表,你随时能查、能导、能画。

先跑通:三步拿到第一张历史曲线

想看到数据,只需要确认三件事:Recorder(状态记录器,负责把设备状态写进数据库)在跑、你要查的实体没被排除、你手里有一个长期访问令牌。

第一步,确认 Recorder 已启用。默认配置下它写入 SQLite,什么都不用改。想换库或调保留期,在configuration.yaml里加:

recorder: db_url: mysql://hass:secret@db-server/homeassistant?charset=utf8mb4 purge_keep_days: 90 # 原始状态默认只留 10 天,这里延长到 90 exclude: entity_globs: - sensor.*_rssi # 这类噪音数据不记录

第二步,用 REST 接口拉一段历史。把令牌、时间范围和实体 ID 填进去:

curl -H "Authorization: Bearer 你的长期令牌" \ "http://homeassistant.local:8123/api/history/period/2026-08-01T00:00:00Z?end_time=2026-08-29T00:00:00Z&filter_entity_id=utility_meter.energy_grid&minimal_response=true"

返回的是按实体分组的 JSON,每个条目含state、属性、last_updated。想看完整状态属性就去掉minimal_response

第三步,在 Lovelace 仪表板放一个 History 卡片指向同一个实体——它底层走的是同一套历史查询。到这里,你已经有了"原始流水"。

原理拆解:三层数据是怎么叠起来的

Home Assistant 的历史数据不是一张大表,而是三层流水账:

存什么谁写典型用途
states 表每次状态变化的原始记录Recorder精确回溯"几点几分发生了什么"
history 查询层对 states 的显著变化筛选与压缩History 组件前端曲线、REST/WS 查询
statistics 表5 分钟/小时两级聚合值(均值、极值、求和)Recorder 定时任务能源账单、月度对比等报表

第一层是流水账:设备每报一次新值就落一行。第二层做减法——只保留"显著变化"(状态值本身变了才算,仅属性更新会被过滤),这就是你查曲线时不会看到一堆重复点的原因,核心实现在 history 组件 的get_significant_states

第三层是真正的"报表"。两个定时任务在后台轮转:每到 5 分钟边界,把该区间内的状态压成一行(均值、最大、最小;对能源这类只增不减的计量实体额外算 sum);整点时再对 4 个 5 分钟行做二次聚合,落一行小时统计。入口函数是 recorder 统计源码 里的compile_statistics,跑完会发出recorder.statistics_short_term_generatedrecorder.statistics_hourly_generated事件,你可以拿这两个事件当"报表新鲜出炉"的触发器。

一句话记忆:states 是流水,history 是筛选过的流水,statistics 是账本。电费这种"累计值"问题,只有账本层能直接答。

实战用例:从查询到图表

用 WebSocket 查统计,适合仪表板实时刷新。前端和脚本都可以复用同一通道。连接ws://homeassistant.local:8123/api/websocket后,先认证,再发:

const sock = new WebSocket("ws://homeassistant.local:8123/api/websocket"); sock.onopen = () => { sock.send(JSON.stringify({ id: 1, type: "auth", access_token: "你的长期令牌" })); }; sock.onmessage = (e) => { const r = JSON.parse(e.data); if (r.id === 1 && r.type === "auth_ok") { // 拉最近 30 天的小时级统计,报表数据一次到位 sock.send(JSON.stringify({ id: 2, type: "recorder/get_statistics_during_period", start_time: new Date(Date.now() - 30 * 864e5).toISOString(), statistic_ids: ["utility_meter.energy_grid"], period_type: "hour" })); } else if (r.id === 2 && r.success) { renderChart(r.result.statistics); // 每行含 start, mean, sum, max, min } };

用 REST 导出 CSV,适合月度复盘。把上一条 curl 的结果喂给任何脚本都行;end_timefilter_entity_id都是可选项,不传时间默认取最近一天。

画一张"小时 × 日期"热力图。拿到导出数据后按日期、小时透视一下,用任意绘图库(Matplotlib 或前端 ECharts)渲染:行是日期、列是 0–23 时、颜色深浅代表该小时用电 sum。哪一周、哪个时段在偷偷耗电,一眼可见。这比逐日看柱状图快得多,也更容易发现"周三晚 21 点必有峰值"这种规律。

避坑清单

  • 曲线断点、查不到数据→ 该实体被exclude或全局排除规则挡掉了,或原始数据已被purge_keep_days清掉 → 检查 Recorder 排除项,关键计量实体单独保留,并确认查询时间范围没超出保留期。
  • 5 分钟统计缺行→ 缺行多发生在 HA 停机跨越统计边界时,重启后会触发回填 → 若长期缺行,看日志中 statistics 相关报错;能源实体缺行会直接让 sum 偏低,建议对recorder.statistics_short_term_generated事件做监控。
  • 同一实体在报表里单位跳变(比如 ℃ 变 ℉)→ 统计元数据记录了首次登记时的单位 → 实体单位变更后需让 Recorder 重建该统计元数据(修复任务会自动提示),手动核对 statistics_meta。
  • 查询慢、前端卡顿→ 时间范围过大 + 返回完整属性 → 缩短窗口、加minimal_response、用filter_entity_id收窄实体;MySQL 环境下确认start_time过滤走了索引。
  • MySQL 部署连接不稳→ SQLite 之外换库后要设连接池参数并关注日志 → 数据量大时建议独立数据库实例,别和主库挤在一起。

收尾

到这里,你手里已经有了三层数据(流水、筛选流水、聚合账本)和三把钥匙(REST、WebSocket、脚本导出)。Home Assistant 的报表能力本质上是"先记账、后对账":把原始状态留足、让两级聚合去跑,你要的月度电费对比、温度波动分析就只是换一种查询而已。

延伸方向:把小时统计接进自动化,比如连续 3 天同时段峰值超阈值就发通知,让报表从"回看"变成"预警"。

【免费下载链接】core:house_with_garden: Open source home automation that puts local control and privacy first.项目地址: https://gitcode.com/GitHub_Trending/co/core

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询