发布于 2026-01-06 1 阅读
0

Home Assistant:使用 InfluxDB 收集传感器数据

Home Assistant:使用 InfluxDB 收集传感器数据

Home Assistant (HA) 是一款功能强大的物联网 (IoT) 设备及其传感器管理解决方案。它有助于简化数据采集,并提供用户友好的家庭自动化功能。在默认配置下,HA 会将所有状态变化存储在其内部的 SQLite 数据库中。然而,对于物联网开发人员来说,使用和处理时序数据库(例如 InfluxDB)才是常态。那么,我们能否也使用 HA 将传感器数据存储在时序数据库中呢?简而言之:可以。详细来说:可以,但 HA 对如何以及保存哪些数据有明确的、不可配置的约定,因此请仔细查看相关细节……

本文是一份完整的 Home Assistant 时间序列数据库功能设置、结构和使用指南。您将了解如何启用 HA 将数据写入自定义 InfluxDB,查看数据结构示例,并学习如何使用聚合和保留策略自定义存储的数据。

本文的技术背景是 Home Assistant 2022.11 和 ESPHome 2022.11.3,但也应该适用于更新的版本。

本文最初发表于我的博客admantium.com

为 Home Assistant 配置 InfluxDB

在开始之前,我们先回顾一下。当您收集传感器数据并运行 Home Assistant 实例时,实际上有两种选择。第一种选择是为每个开发板显式配置一个 MQTT 连接,并为每个要记录的传感器数据配置一个 MQTT 发布器。但顾名思义,这需要为所有开发板和所有传感器分别配置。第二种选择,也是本文将要探讨的,是自动将 Home Assistant 注册到 InfluxDB 的每个状态更新镜像到 InfluxDB。这不仅可以避免上述问题,还可以标准化测量数据,并仅记录所有传感器或基于状态的实体。

要启用 InfluxDB 连接,官方文档说明需要将以下
设置添加到 Home Assistant 安装目录下的 configuration.yaml 文件中。为了便于理解,我们将其分为两部分:连接设置,用于指定主机名、端口和数据库名称;以及测量设置,用于定义测量值的命名方式、使用的标签以及数据库中应包含或排除的实体。

influxdb:
  ### Connection Setting ###
  api_version: 2
  ssl: false
  host: influxdb
  port: 8086
  bucket: home_assistant

  ### measurements setup ###
  tags:
    source: ha
  tags_attributes:
    - friendly_name
  default_measurement: units
  exclude:
    entities:
      - zone.home
    domains:
      - persistent_notification
      - person
  include:
    domains:
      - sensor
      - binary_sensor
      - sun
    entities:
      - weather.home
Enter fullscreen mode Exit fullscreen mode

然后你需要重启 Home Assistant 进程或服务。就我而言,这是一个需要重新启用的 Docker 容器。

> docker-compose restart home_assistant
> docker-compose logs -f home_assistant
Enter fullscreen mode Exit fullscreen mode

为确保配置正确应用,请检查日志文件:

home_assistant    | 2022-01-16 12:15:04 ERROR (MainThread) [homeassistant.config] Invalid config for [influxdb]: token and bucket are required when api_version is 2 for dictionary value @ data['influxdb']. Got OrderedDict([('api_version', 2), ('ssl', False), ('host', 'influxdb'), ('port', 8086), ('bucket', 'home_assistant'), ('tags', OrderedDict([('source', 'ha')])), ('tags_attributes', ['friendly_name']), ('default_measurement', 'units')]). (See /config/configuration.yaml, line 14). Please check the docs at https://www.home-assistant.io/integrations/influxdb
home_assistant    | 2022-01-16 12:15:04 ERROR (MainThread) [homeassistant.setup] Setup failed for influxdb: Invalid config.
Enter fullscreen mode Exit fullscreen mode

如果看到此信息,说明您运行的 InfluxDB 版本低于 2.0,因此需要按如下方式更改连接设置:

influxdb:
  host: influxdb
  port: 8086
  database: home_assistant
  username: ''
  password: ''
  ssl: false
  verify_ssl: false
  max_retries: 3
  default_measurement: state
Enter fullscreen mode Exit fullscreen mode

从现在开始,指定的 InfluxDB 数据库/存储桶将填充记录的值。

测量数据库概述

我们来看看这些数据的结构。使用你喜欢的工具连接到 InfluxDB 并进行探索。

> show measurements
name: measurements
name
----
%
IAQ
V
dBm
h
hPa
m
ms
ppm
s
state
°C
Ω
>

Enter fullscreen mode Exit fullscreen mode

第一个令人惊讶的地方是这些测量单位的名称:它们本身就是被测量的单位!让我们先来了解一下它们的含义。

测量名称 单元 解释
% 百分比 电池电量百分比
室内空气质量 空气质量指数 由 BME680 计算得出
V 伏特 电池电压水平
分贝米 分贝毫瓦 无线连接强度
h 小时 及时报告的测量和状态变化
百帕 赫克托帕斯卡 来自 BME680 传感器的气压
分钟 记录我的电路板动态睡眠时间的设置
每百万 每百万个粒子 测量二氧化碳颗粒的数量
状态 杂项 本次测量会记录所有传感器的所有状态变化。
摄氏度 摄氏度 温度测量
Ω 电阻 BME680传感器的电阻测量值用于计算室内空气质量(IAQ)。

好的,我们来研究一下测量表本身的结构。首先,我们来看一下数值的测量,然后再看一下状态的测量。

测量数据库的结构

这些测量方法本身的结构非常相似:

> select * from "dBm" LIMIT 10
name: dBm
time                device_class_str domain entity_id              friendly_name friendly_name_str      state_class_str value
----                ---------------- ------ ---------              ------------- -----------------      --------------- -----
1642857893213061120 signal_strength  sensor wifi_signal_esp8266_01 826601        WiFi Signal esp8266-01 measurement     -68
1642857986913826048 signal_strength  sensor wifi_signal_esp8266_01 826601        WiFi Signal esp8266-01 measurement     -69
1642858046926774016 signal_strength  sensor wifi_signal_esp8266_01 826601        WiFi Signal esp8266-01 measurement     -71
1642858106919809024 signal_strength  sensor wifi_signal_esp8266_01 826601        WiFi Signal esp8266-01 measurement     -70
Enter fullscreen mode Exit fullscreen mode

表格列内容如下:

钥匙 类型 描述
时间 时代 测量时间戳
设备类字符串 细绳 例如,“°C”表示温度,“dBm”表示信号强度。
领域 细绳 领域构成价值的逻辑结构或起源,例如“传感器”或“光”。
实体 ID 细绳 实体的ID
友好名称 整数 friendl_name_str 的内部 ID
friendly_name_str 细绳 用户可配置的设备备用名称,可用于代替其内部 ID
icon_str 细绳 指定 HA 仪表板分配给此值的图标名称
state_class_str 细绳 数据的来源,这里总是“测量”。
价值 * 具体测量值

州数据库的结构

这个特殊的数据库会跟踪您 Home Assistant 安装中的所有状态变化。它的结构取决于您集成的实体数量——传感器越多,数据库中的列就越多。

这是我刚开始使用 Home Assistant 时的数据库:

> select * from state limit 1

name: state
time                access_token access_token_str device_class_str domain editable entity_id entity_id_str                                      entity_picture_str friendly_name friendly_name_str icon_str id            latitude longitude newest_version_str passive radius release_notes_str state   supported_color_modes_str supported_features value
----                ------------ ---------------- ---------------- ------ -------- --------- -------------                                      ------------------ ------------- ----------------- -------- --            -------- --------- ------------------ ------- ------ ----------------- -----   ------------------------- ------------------ -----
1642332817702238976                                                scene           new_scene ['camera.esp32camera', 'light.esp32_camera_light']                                  New Scene                  1636879982536                                                                        scening
Enter fullscreen mode Exit fullscreen mode

这是撰写本文时的状态,当时新增了温度传感器、运动传感器和 LED 灯。

select * from "state" Limit 1
name: state
time                access_token access_token_str azimuth brightness color_mode_str current device_class_str domain editable effect_list_str effect_str elevation entity_id entity_id_str                                      entity_picture_str friendly_name friendly_name_str hs_color_str icon_str id            initial_str last_triggered last_triggered_str latitude longitude max message_str min mode_str newest_version_str next_dawn next_dawn_str next_dusk next_dusk_str next_midnight next_midnight_str next_noon next_noon_str next_rising next_rising_str next_setting next_setting_str passive pattern_str radius release_notes_str rgb_color rgb_color_str rising state   step supported_color_modes_str supported_features title_str value xy_color_str
----                ------------ ---------------- ------- ---------- -------------- ------- ---------------- ------ -------- --------------- ---------- --------- --------- -------------                                      ------------------ ------------- ----------------- ------------ -------- --            ----------- -------------- ------------------ -------- --------- --- ----------- --- -------- ------------------ --------- ------------- --------- ------------- ------------- ----------------- --------- ------------- ----------- --------------- ------------ ---------------- ------- ----------- ------ ----------------- --------- ------------- ------ -----   ---- ------------------------- ------------------ --------- ----- ------------
1642332817702238976                                                                                          scene                                                new_scene ['camera.esp32camera', 'light.esp32_camera_light']                                  New Scene                               1636879982536                                                                                                                                                                                                                                                                                                                                                                scening
Enter fullscreen mode Exit fullscreen mode

如您所见,这些值很多,但其中大多数仅在非常特定的状态更改时才会被记录。让我们通过一个具体的例子来理解它们:将 LED 灯设置为“开”。

姓名 状态 描述
标签
时间(UTC) 164475370095578​​0000 状态变更时间戳
访问令牌
access_token_str
方位角
亮度 31 此LED的亮度值
color_mode_str RGB 表示颜色寻址方式的字符串
当前的
设备类字符串
领域 领域之光
可编辑
effect_list_str ['无', '彩虹', '脉冲'] 为 LED 配置的效果名称
effect_str 没有任何
海拔
实体 ID rgb_led_ring 实体 ID
entity_id_str
entity_picture_str
友好名称
friendly_name_str RGB LED环 给出的友好名称
hs_color_str (14.717,62.353) 色调和饱和度值
icon_str
ID
initial_str
上次触发
last_triggered_str
纬度
经度
最大限度
消息字符串
最小
mode_str
最新版本字符串
下一个道
next_dawn_str
下一个黄昏
下一个黄昏
下一个午夜
next_midnight_str
下一个中午
next_noon_str
下一个崛起
下一个上升的
下一个设置
next_setting_str
被动的
pattern_str
半径
发行说明字符串
RGB颜色 25513596 配置的 RGB 颜色简写
rgb_color_str (255、135、96) 配置的 RGB 颜色的长表示法
上升
状态 有效的状态变化
supported_color_modes_str ['rgb'] 针对此 LED 的颜色模式
支持的功能 44 功能的内部 ID
标题字符串
价值 1 表示状态变化的布尔值
xy_color_str (0.552,0.346) xy 色彩

有了这些理解,让我们将数据可视化。

Grafana传感器测量仪表盘

InfluxDB 数据的可视化给我们带来了一个有趣的难题。一方面,Home Assistant 会为其数据库中收集的所有数据提供传感器可视化功能。这很方便,而且无需任何配置。另一方面,你也可以将任何 InfluxDB 数据添加到 Home Assistant 的仪表盘卡片中¹。但是,既然默认的可视化功能已经开箱即用,你还有必要这样做吗?

对于我其他的 InfluxDB 数据(主要是来自我的 Linux 工作站和 Raspberry Pi 的硬件指标),我已经使用 Grafana 仪表盘进行可视化。因此,我想添加一个新的 Grafana 仪表盘来可视化存储在 InfluxDB 中的 Home Assistant 传感器数据。

第一个图表只需几分钟即可设置完成:

  1. 配置 InfluxDB Home Assistant 数据库。在 Grafana 主视图中,转到“配置”=>“数据源”,然后单击“新建数据源”。在此处,输入 InfluxDB 服务器的 URL 和端口,并在“数据库”字段中输入home_assistant
  2. 创建一个新的仪表盘,例如命名为“家庭助手传感器”。
  3. 在仪表盘中创建一个新面板:选择 Home Assistant InfluxDB 数据源,此时会显示一个功能丰富的查询编辑器界面。在这里,选择您感兴趣的指标及其平均值。

这样,您将获得一个图表。但您可能会遇到同一时间戳和数据出现多个重复值的情况。这种情况发生在您为同一实体配置了多个集成时,例如同时使用 ESPHome API 和 MQTT 集成读取温度数据。

让我们考虑以下示例:从同一个传感器进行多次温度测量,但entity_id测量值不同。

name time (UTC) device_class_str domain entity_id friendly_name friendly_name_str state_class_str value
°C  1644341442651680000 temperature sensor bme680_temperature 680 BME680 Temperature  measurement 8.6
°C  1644341442671660000 temperature sensor bme680_temperature_2 680
BME680 Temperature  measurement 8.6
°C  1644343135338740000 temperature sensor bme680_temperature_2 680 BME680 Temperature  measurement 8.9
Enter fullscreen mode Exit fullscreen mode

解决数据重复问题有多种方法。一方面,您可以从数据库中删除时间戳相同但实体 ID 不同的条目。另一方面,您可以使用自定义保留策略,根据需要筛选和聚合数据。更简单的方法是,如果您只关注数据可视化,可以使用自定义SELECT语句将多个数据点合并为平均值。

在撰写本文时,我仍在向 Home Assistant 添加新的设备和实体,因此无法排除出现更多重复授权的可能性。所以,我选择了最简单的解决方案,创建了一个自定义查询,对 10 分钟时间跨度内的数据取平均值。查询语句如下:

SELECT mean("value")
FROM "°C"
WHERE ("entity_id" = 'bme680_temperature' OR "entity_id" = 'bme680_temperature_2')
GROUP BY time(10m) fill(previous)
Enter fullscreen mode Exit fullscreen mode

查询检查器按要求返回了值:

通过类似的查询,我可以将收集到的所有温度和湿度数据汇总到这些图表中:

我对这个结果很满意。

结论

Home Assistant 会收集所有已配置设备的状态变化和传感器数据。但您可以通过配置对 InfluxDB 实例的访问,获取这些数据的额外副本,以时间序列数据库条目的形式存储。此数据库完全是额外的,Home Assistant 会将所有数据存储在其自身的数据库和已配置的 InfluxDB 中。现在,您可以开始读取和可视化这些数据了。

为了帮助您入门,本文还探讨了 Home Assistant 如何存储数据:传感器数据被收集到以测量值命名的表中,例如 `<summary>`、`<state>`VdBm` °C<state>`,状态变化则被记录在state测量值中。您已经了解了表列及其含义。最后,我还展示了如何基于这些测量值创建 Grafana 仪表板,并解决了 Home Assistant 为多个已配置实体存储类似测量值时可能出现的重复数据问题。

脚注


  1. 如果您想直接在 Home Assistant中可视化 InfluxDB 数据,请阅读这篇分步指南。↩ 

文章来源:https://dev.to/admantium/home-assistant-collecting-sensor-data-with-influxdb-3mfl