记录器

此集成默认情况下作为 history 集成的依赖项启用。

Important

此集成会不断保存数据。如果您使用默认配置,则数据将保存在安装 Home Assistant 的媒体上。如果是带有 SD 卡的 Raspberry Pi,这可能会影响系统的反应时间和存储介质(SD 卡)的使用寿命。因此,建议将 commit_interval 设置为更高的值,例如 30 秒,限制存储的数据量(例如,通过排除设备)或将数据存储在其他地方(例如,另一个系统)。

Home Assistant 使用 SQLAlchemy,这是一种对象关系映射(ORM)。这使得可以使用多种数据库解决方案。

支持的数据库解决方案包括:

尽管 SQLAlchemy 支持 Home Assistant 之外的数据库解决方案,但它在不同数据库上的行为可能不同,并且记录器所依赖的功能在不同数据库中可能表现不同,甚至根本无法工作。

默认和推荐的数据库引擎是 SQLite,不需要任何配置。数据库存储在您的 Home Assistant 配置目录(’/config/’)中,并命名为 home-assistant_v2.db

Caution

更改记录器使用的数据库可能会导致丢失现有历史记录。数据迁移不受支持。

要更改您安装中 recorder 集成的默认值,请将以下内容添加到您的 configuration.yamlconfiguration.yaml 文件是 Home Assistant 的主要配置文件。它列出了要加载的集成及其特定配置。在某些情况下,需要直接在 configuration.yaml 文件中手动编辑配置。大多数集成可以在 UI 中配置。 [Learn more] 文件中:

磁盘空间要求

最低要求是在任何时候都至少有与数据库大小相同的可用临时空间。表重建、修复或重新打包可能随时发生,这可能导致在操作期间数据的磁盘副本。在版本升级期间满足最低要求至关重要,因为此时模式可能会更改,此操作几乎总是需要临时复制部分数据库。

例如,如果您的数据库在磁盘上为 1.5 GiB,您始终必须至少有 1.5 GiB 的空间。

高级配置

# 示例 configuration.yaml 条目
recorder:

Configuration Variables

recorder map Required

启用记录器集成。仅允许一次。

db_url string (Optional)

指向您的数据库的 URL。这些示例可以在 这里 找到。

db_max_retries integer (Optional, default: 10)

记录器重试连接到数据库的最大次数。

db_retry_wait integer (Optional, default: 3)

记录器尝试连接到数据库时的等待时间(以秒为单位)。

auto_purge boolean (Optional, default: true)

每天晚上在当地时间 04:12 自动清除数据库。清除可以防止数据库无限增长,从而占用磁盘空间并可能使 Home Assistant 变慢。如果您禁用 auto_purge,建议您创建一个自动化定期调用 recorder.purge

auto_repack boolean (Optional, default: true)

在自动清除后每第二个星期天自动重新打包数据库。如果没有重新打包,即使在清除后,数据库的大小也可能不会减少,进而占用磁盘空间并可能使 Home Assistant 变慢。如果您禁用 auto_repack,建议您创建一个自动化定期调用 recorder.purge。如果禁用 auto_purge,此标志将无效。

purge_keep_days integer (Optional, default: 10)

指定在清除后要保留的历史天数。

commit_interval integer (Optional, default: 5)

提交事件和状态更改到数据库的频率(以秒为单位)。默认值 5 允许事件几乎立即提交,而在事件风暴发生时不会占用磁盘。增加此值将减少磁盘 I/O 并可能延长磁盘(SD 卡)的使用寿命,权衡是数据库将滞后(日志簿和历史记录不会滞后,因为更改会立即流式传输到它们)。如果设置为 0(零),将在事件处理后尽快进行提交。

exclude map (Optional)

配置应从记录中排除哪些集成。(配置过滤器)

domains list (Optional)

要排除在记录中的域列表。

entity_globs list (Optional)

从记录中排除所有与列出模式匹配的实体(例如,sensor.weather_*)。

entities list (Optional)

要排除在记录中的实体 ID 列表。

event_types list (Optional)

要排除在记录中的事件类型列表。

include map (Optional)

配置应包含在记录中的集成。如果设置,所有其他实体将不会被记录。(配置过滤器)

domains list (Optional)

要包含在记录中的域列表。

entity_globs list (Optional)

从记录中包含所有与列出模式匹配的实体(例如,sensor.weather_*)。

entities list (Optional)

要包含在记录中的实体 ID 列表。

配置过滤器

默认情况下,没有实体会被排除。为了限制暴露给 recorder 的实体,您可以使用 includeexclude 参数。

# 示例过滤器以包含指定域并排除指定实体
recorder:
  include:
    domains:
      - alarm_control_panel
      - light
    entity_globs:
      - binary_sensor.*_occupancy
  exclude:
    entities:
      - light.kitchen_light

Filters are applied as follows:

  1. 不使用过滤器
    • 包含所有实体
  2. 仅包含
    • 实体列表中的实体包含:include
    • 否则,实体匹配域包含:include
    • 否则,实体匹配通配符包含:include
    • 否则:排除
  3. 仅排除
    • 实体列表中的实体排除:exclude
    • 否则,实体匹配域排除:exclude
    • 否则,实体匹配通配符排除:exclude
    • 否则:包含
  4. 域和/或通配符包含(还可能有排除)
    • 实体列表中的实体包含:include
    • 否则,实体列表中的排除:exclude
    • 否则,实体匹配通配符包含:include
    • 否则,实体匹配通配符排除:exclude
    • 否则,实体匹配域包含:include
    • 否则:排除
  5. 域和/或通配符排除(没有域和/或通配符包含)
    • 实体列表中的实体包含:include
    • 否则,实体列表中的排除:exclude
    • 否则,实体匹配通配符排除:exclude
    • 否则,实体匹配域排除:exclude
    • 否则:包含
  6. 没有域和/或通配符的包含或排除
    • 实体列表中的实体包含:include
    • 否则:排除

以下字符可用于实体通配符:

* - 星号表示零个、一个或多个字符
? - 问号表示零个或一个字符

如果您只想在日志簿中隐藏事件,请查看 日志簿集成。但是,如果您对某些事件有隐私顾虑,或想让它们既不在历史中也不在日志簿中,您应使用 recorder 集成的 exclude/include 选项。这样它们就不会进入您的数据库,您可以通过排除某些经常记录的事件(如 sensor.last_boot)来减少存储并保持数据库的大小。

常见过滤示例

定义要 exclude(即黑名单)的域和实体非常方便,当您基本上对记录的信息满意,但只是想删除一些实体或域时。

# 示例 configuration.yaml 条目,包含排除
recorder:
  purge_keep_days: 5
  db_url: sqlite:////home/user/.homeassistant/test
  exclude:
    domains:
      - automation
      - update
    entity_globs:
      - sensor.sun*
      - weather.*
    entities:
      - sensor.date
      - sensor.last_boot # 来自 'systemmonitor' 传感器平台
      - sun.sun # 不记录太阳数据
    event_types:
      - call_service # 不记录操作

通过使用 include 配置定义要记录的域和实体(即白名单)在您的系统中有很多实体时非常方便,而且您的 exclude 列表可能会非常庞大,因此最好直接定义要记录的实体或域。

# 示例 configuration.yaml 条目,包含
recorder:
  include:
    domains:
      - sensor
      - switch
      - media_player

您还可以使用 include 列表来定义要记录的域/实体,并在 exclude 列表中排除其中一些。如果您例如包含了 sensor 域,但想排除一些特定传感器,这样合理。您可以包括 sensor 域并排除您不感兴趣的传感器实体,而不是将每个传感器实体添加到 includeentities 列表中。

# 示例 configuration.yaml 条目,包含和排除
recorder:
  include:
    domains:
      - sensor
      - switch
      - media_player
  exclude:
    entities:
      - sensor.last_boot
      - sensor.date
    entity_globs:
      - sensor.weather_*

操作

操作 purge

执行操作 recorder.purge 开始清除任务,该任务根据 keep_days 操作数据删除超过 x 天的事件和状态。 请注意,清除不会立即减少磁盘空间的使用,但会显著减缓进一步的增长。

数据属性 可选 说明
keep_days 在记录器数据库中保留的历史天数(默认为集成 purge_keep_days 配置)
repack 使用 SQLite 或 PostgreSQL 时,这将重写整个数据库。当使用 MySQL 或 MariaDB 时,它将优化或重新创建事件和状态表。这是一个重操作,在运行时可能会导致减速和增加磁盘空间使用。仅支持 SQLite、PostgreSQL、MySQL 和 MariaDB。
apply_filter 除基于时间的清除外,应用 entity_idevent_type 过滤器。在组合使用 include / exclude 过滤器时,删除伪添加的状态和事件。结合 repack: true 减少数据库大小。

操作 purge_entities

执行操作 recorder.purge_entities 开始一个任务,清除与任何指定的 entity_iddomainsentity_globs 字段匹配的事件和状态。必须提供三个选择标准字段中的至少一个。

数据属性 可选 说明
entity_id 应从记录器数据库中清除的实体 ID 列表。
domains 应从记录器数据库中清除的域列表。
entity_globs 识别要从记录器数据库中清除的实体的正则表达式列表。
keep_days 在匹配行的数据库中保留的历史天数。默认值为 0 天,将删除所有匹配行。

示例自动化以删除特定实体的数据行

以下自动化将删除 sensor.power_sensor_0 超过 5 天的历史记录,时间为每天的 04:15:00

alias: "清除嘈杂的功率传感器"
triggers:
  - trigger: time
    at: "04:15:00"
actions:
  - action: recorder.purge_entities
    data:
      keep_days: 5
      entity_id: sensor.power_sensor_0

操作 disable

执行操作 recorder.disable 停止将事件和状态保存到数据库。

操作 enable

执行操作 recorder.enable 重新开始将事件和状态保存到数据库。这是 recorder.disable 的相反操作。

处理磁盘损坏和硬件故障

在使用 SQLite 时,如果系统遇到无法恢复的磁盘损坏,它将将数据库移动到一旁,并创建一个新数据库以保持系统在线。在此情况下,必须确保有至少 2.5 倍的数据库大小的可用空闲磁盘空间。启动新数据库是系统最后的恢复选项,通常是由故障的闪存存储、不足的电源、非干净关机或其他硬件故障引起的。

在这种情况下,可以通过查阅 SQLite 恢复指南 来恢复旧数据库。

自定义数据库引擎

Warning

SQLite 是经过最多测试的,较新版本的 Home Assistant 在使用 SQLite 时进行了高度优化。

选择其他选项时,您应舒适地担任数据库管理员的角色,包括对外部数据库进行备份。

以下是与 db_url 配置选项配合使用的示例。

SQLite

sqlite:////PATH/TO/DB_NAME

MariaDB(省略 pymysql)

mysql://user:password@SERVER_IP/DB_NAME?charset=utf8mb4

MariaDB(省略 pymysql,使用 TLS 加密)

mysql://user:password@SERVER_IP/DB_NAME?charset=utf8mb4;ssl=true

MariaDB(省略 pymysql,Socket)

mysql://user:password@SERVER_IP/DB_NAME?unix_socket=/var/run/mysqld/mysqld.sock&charset=utf8mb4

MySQL

mysql://user:password@SERVER_IP/DB_NAME?charset=utf8mb4

MySQL(使用 TLS 加密)

mysql://user:password@SERVER_IP/DB_NAME?charset=utf8mb4;ssl=true

MySQL(Socket)

mysql://user:password@localhost/DB_NAME?unix_socket=/var/run/mysqld/mysqld.sock&charset=utf8mb4

MariaDB

mysql+pymysql://user:password@SERVER_IP/DB_NAME?charset=utf8mb4

MariaDB(Socket)

mysql+pymysql://user:password@localhost/DB_NAME?unix_socket=/var/run/mysqld/mysqld.sock&charset=utf8mb4

PostgreSQL

postgresql://user:password@SERVER_IP/DB_NAME

PostgreSQL(Socket)

postgresql://@/DB_NAME

PostgreSQL(自定义套接字目录)

postgresql://@/DB_NAME?host=/path/to/dir

Note

某些 MariaDB/MySQL 的安装可能需要将 ALTERNATE_PORT(第三方托管提供商或并行安装)添加到 SERVER_IP,例如,mysql://user:password@SERVER_IP:ALTERNATE_PORT/DB_NAME?charset=utf8mb4

Note

使用 MariaDB 或 MySQL 服务器时,将 +pymysql 添加到 URL 将使用纯 Python MySQL 库,它速度较慢,但如果 C MySQL 库不可用,可能是必需的。

使用官方 Docker 镜像时,C MySQL 库将始终可用。 pymysql 通常在没有安装 C MySQL 库的 venv 中使用。

Tip

当数据库与 recorder 实例在同一主机上(即 localhost)时,Unix Socket 连接始终带来性能优势。

Note

如果您想对 PostgreSQL 使用 Unix Sockets,您需要修改 pg_hba.conf。请参见 PostgreSQL

数据库启动

如果您在与 Home Assistant 同一台服务器上运行数据库服务器实例,则必须确保此操作在 Home Assistant 之前启动。对于运行 Systemd 的 Linux 实例(Raspberry Pi、Debian、Ubuntu 等),您应该编辑服务文件。 为了方便起见,已添加 db_max_retry 和 db_retry_wait 变量,以确保记录器足够多次重试与数据库的连接,以使您的数据库启动。

sudo nano /etc/systemd/system/home-assistant@homeassistant.service

并为数据库添加操作,例如 PostgreSQL:

[Unit]
Description=Home Assistant
After=network.target postgresql.service

保存文件并重新加载 systemctl

sudo systemctl daemon-reload

安装说明

并不是所有针对所选数据库引擎的 Python 绑定都可以直接安装。本节包含应帮助您将其工作的信息。

MariaDB 和 MySQL

Warning

MariaDB 版本 10.5.17、10.6.9、10.7.5 和 10.8.4 之前的版本存在性能回归,可能会导致在查询历史数据或清除数据库时系统过载。

请确保数据库服务器的默认字符集设置为 utf8mb4(请参阅 MariaDB 文档)。 如果您在虚拟环境中,请在安装下面描述的 mysqlclient Python 包之前不要忘记激活它。

pi@homeassistant:~ $ sudo -u homeassistant -H -s
homeassistant@homeassistant:~$ source /srv/homeassistant/bin/activate
(homeassistant) homeassistant@homeassistant:~$ pip3 install mysqlclient

对于 MariaDB,您可能需要安装一些依赖项。如果您使用 MariaDB 10.3,则必须安装 libmariadb-dev-compat 包。请根据您的 MariaDB 版本安装正确的包。

在 Python 端,我们使用 mysqlclient

sudo apt-get install libmariadbclient-dev libssl-dev
pip3 install mysqlclient

对于 MySQL,您可能需要安装一些依赖项。您可以选择 pymysqlmysqlclient

sudo apt-get install default-libmysqlclient-dev libssl-dev
pip3 install mysqlclient

在安装依赖项后,必须手动创建数据库。在启动期间,Home Assistant 将查找指定在 db_url 中的数据库。如果数据库不存在,它不会为您自动创建。

数据库引擎必须是 InnoDB,因为不支持 MyIASM

SET GLOBAL default_storage_engine = 'InnoDB';
CREATE DATABASE DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

其中 DB_NAME 是您的数据库名称

一旦 Home Assistant 找到数据库,并具有正确的权限,所有必需的表将自动创建并相应填充数据。

PostgreSQL

使用 utf8 编码创建 PostgreSQL 数据库。PostgreSQL 的默认编码为 SQL_ASCII。使用 postgres 用户帐户;

createdb -E utf8 DB_NAME

其中 DB_NAME 是您的数据库名称

如果正在使用的数据库不是 utf8,则将 ?client_encoding=utf8 添加到 db_url 可能会解决任何问题。

对于 PostgreSQL,您可能需要安装几项依赖:

sudo apt-get install postgresql-server-dev-X.Y
pip3 install psycopg2

要使用 Unix Sockets,首先从 postgres 用户帐户创建您的用户;

createuser USER_NAME

其中 USER_NAME 是运行 Home Assistant 实例的用户名称(请参见 确保您的安装安全)。

然后将以下行添加到您的 pg_hba.conf 中:

local DB_NAME USER_NAME peer

其中 DB_NAME 是您的数据库名称,USER_NAME 是运行 Home Assistant 实例的用户名称(请参见 确保您的安装安全)。

之后重新加载 PostgreSQL 配置:

$ sudo -i -u postgres psql -c "SELECT pg_reload_conf();"
 pg_reload_conf
----------------
 t
(1 row)

服务重启也可以。