拆分配置

所以你使用 Home Assistant 一段时间了,您的 configuration.yamlconfiguration.yaml 文件是 Home Assistant 的主要配置文件。它列出了要加载的集成及其特定配置。在某些情况下,需要直接在 configuration.yaml 文件中手动编辑配置。大多数集成可以在 UI 中配置。 [Learn more] 文件让人痛心,因为它变得如此庞大。或者,您只是想开始采用分布式的方法。下面是如何将 configuration.yamlconfiguration.yaml 文件是 Home Assistant 的主要配置文件。它列出了要加载的集成及其特定配置。在某些情况下,需要直接在 configuration.yaml 文件中手动编辑配置。大多数集成可以在 UI 中配置。 [Learn more] 拆分成更易于管理(可读)的小块。

示例配置文件以获得灵感

首先,几个社区成员提供了干净的(去除 API 密钥/密码)配置版本供查看。你可以在 GitHub 上查看示例配置列表

由于注释代码并不总是发生,请继续阅读以详细了解配置文件的结构。

分析配置文件

在这一部分中,我们将使用一些示例配置文件并更详细地查看它们的结构和格式。

现在你可能会想,configuration.yamlconfiguration.yaml 文件是 Home Assistant 的主要配置文件。它列出了要加载的集成及其特定配置。在某些情况下,需要直接在 configuration.yaml 文件中手动编辑配置。大多数集成可以在 UI 中配置。 [Learn more] 会在拆分过程中被替换。然而,它实际上仍然存在,尽管它的形式会简洁得多。

核心配置文件

在这个简化版本中,我们仍然需要可以称之为核心片段的内容:

homeassistant:
  # Home Assistant 运行的位置名称
  name: "我的 Home Assistant 实例"
  # 计算太阳升起和落下的时间所需的位置
  latitude: 37
  longitude: -121
  # 'metric' 为公制,'us_customary' 为美国习惯单位
  unit_system: us_customary
  # 从这里选择您的时区: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  time_zone: "America/Los_Angeles"
  customize: !include customize.yaml

缩进、包含、注释和模块化

注意 homeassistant: 后的每一行都缩进两个(2)空格。由于 Home Assistant 的配置文件基于 YAML 语言,因此缩进和间距非常重要。同样注意 customize: 下似乎奇怪的条目。

!include customize.yaml 是告诉 Home Assistant 在该点插入 customize.yaml 解析内容的语句。所包含文件的内容必须是有效的 YAML 数据。在该位置可以插入。这就是我们将一个大的、不易读的文件(当它变大时)拆分成更易于管理的小块的方式。

在开始拆分不同的组件之前,让我们看一下其他集成(在我们的示例中)将保留在基础文件中的内容:

history:
frontend:
logbook:
http:
  api_password: "我不告诉你!"

ifttt:
  key: ["不告诉"]

mqtt:
  sensor:
    - name: "测试传感器 1"
      state_topic: "test/some_topic1"
    - name: "测试传感器 2"
      state_topic: "test/some_topic2"

和核心片段一样,缩进是有区别的:

  • 集成头(如 mqtt:)应该完全左对齐(即没有缩进)。
  • 键(sensor:)应该缩进两个(2)空格。
  • sensor 下的列表 - 应该再缩进两个(2)空格,后跟一个空格。
  • mqtt 传感器列表包含两个(2)配置,每个有两个(2)键。

注释

符号 #(井号)在命令解释中表示“注释”。换句话说,任何以 # 开头的行将被软件忽略。它仅供人类使用。注释可以将文件分隔以提高可读性,同时在保留条目的情况下关闭功能。

模块化和粒度

虽然其中一些集成在技术上可以移动到单独的文件中,但它们是如此小或“临时”,以至于分开是多余的。

现在,假设在 Home Assistant 配置目录中为以下每个文件创建了一个空白文件:

automation.yaml
zone.yaml
sensor.yaml
switch.yaml
device_tracker.yaml
customize.yaml

automation.yaml 将保存所有的自动化集成细节。zone.yaml 将保存区域集成细节,等等。这些文件可以命名为任何名称,但给它们一个与其功能相匹配的名称将使跟踪变得更容易。

在基础配置文件中,添加以下条目:

automation: !include automation.yaml
zone: !include zone.yaml
sensor: !include sensor.yaml
switch: !include switch.yaml
device_tracker: !include device_tracker.yaml

包含语句和包来拆分文件

嵌套 !include 语句(在一个文件中包含的 !include)也会有效。

一些集成支持多个顶级 !include 语句。这包括定义 IoT 域的集成。例如,lightswitchsensor;以及 automationscripttemplate 集成,如果您为每一个提供不同的标签。

其他集成的配置可以通过使用包来拆分。要了解有关包的更多信息,请参见 Packages 页面。

顶级密钥

light 平台的多个顶级密钥示例。

light:
- platform: group
  name: "床头灯"
  entities:
    - light.left_bedside_light
    - light.right_bedside_light

# 在单独的文件中定义更多灯光组
light groups: !include light-groups.yaml

# 在不同的文件中定义一些灯光开关映射
light switches: !include light-switches.yaml

其中 light-groups.yaml 可能如下所示:

- platform: group
  name: "户外灯光"
  entities:
    - light.porch_lights
    - light.patio_lights

light-switches.yaml 包含:

- platform: switch
  name: "庭院灯"
  entity_id: switch.patio_lights
  
- platform: switch
  name: "落地灯"
  entity_id: switch.floor_lamp_plug

好的,因此我们有了基础文件中的单个集成和包含语句,这些额外的文件中放什么呢?

让我们看看我们的示例中的 device_tracker.yaml 文件:

- platform: owntracks
- platform: nmap_tracker
  home_interval: 3
  hosts: 192.168.2.0/24

  track_new_devices: true
  interval_seconds: 40
  consider_home: 120

这个小示例说明了“拆分”文件是如何工作的。在这种情况下,我们从两个(2)设备跟踪条目(owntracksnmap)开始。这些文件遵循 “样式 1”,也就是说,一个完全左对齐的前导条目(- platform: owntracks),后跟缩进两个(2)空格的参数条目。

这个(大的)传感器配置给了我们另一个例子:

### sensor.yaml
### METEOBRIDGE #############################################
- platform: tcp
  name: "户外温度 (Meteobridge)"
  host: 192.168.2.82
  timeout: 6
  payload: "Content-type: text/xml; charset=UTF-8\n\n"
  value_template: "{{value.split (' ')[2]}}"
  unit: C
- platform: tcp
  name: "户外湿度 (Meteobridge)"
  host: 192.168.2.82
  port: 5556
  timeout: 6
  payload: "Content-type: text/xml; charset=UTF-8\n\n"
  value_template: "{{value.split (' ')[3]}}"
  unit: Percent

#### STEAM FRIENDS ##################################
- platform: steam_online
  api_key: ["不告诉"]
  accounts:
    - 76561198012067051

#### TIME/DATE ##################################
- platform: time_date
  display_options:
    - "time"
    - "date"
- platform: worldclock
  time_zone: Etc/UTC
  name: "UTC"
- platform: worldclock
  time_zone: America/New_York
  name: "安阿伯"

你会注意到,这个示例包括一个二级参数部分(在 steam 部分下),以及更好的示例说明了注释如何用于将文件分解成多个部分。

以上所有内容都可以在使用包拆分文件时应用。要了解更多关于包的信息,请参见 Packages 页面。

到此为止。

如果您遇到问题,请查看配置目录中的 home-assistant.log 以及您的缩进。如果一切都失败了,请访问我们的 Discord 聊天服务器,并随意询问。

调试配置文件

如果你有很多配置文件,Home Assistant 提供了一个 CLI,允许您查看其如何解释这些文件。每种安装类型在常见任务中都有自己的部分:

高级用法

我们提供四个高级选项,以一次包含整个目录。请注意,您的文件必须具有 .yaml 文件扩展名;不支持 .yml

这将允许您在 .yaml 文件中 !include 具有 .yml 扩展名的文件;而这些 .yml 文件不会被以下命令本身导入。

  • !include_dir_list 将返回目录的内容,作为列表,每个文件内容作为列表中的一项。列表条目的顺序基于文件名的字母数字排序。
  • !include_dir_named 将返回目录的内容,作为字典,映射文件名 => 文件内容。
  • !include_dir_merge_list 将返回目录的内容,作为合并所有文件(应该包含列表)的一个大列表。
  • !include_dir_merge_named 将返回目录的内容,作为字典,通过加载每个文件并将其合并到一个大字典。

这些操作是递归的。例如,使用 !include_dir_list automation,将包含下面显示的所有 6 个文件:

.
└── .homeassistant
    ├── automation
    │   ├── lights
    │   │   ├── turn_light_off_bedroom.yaml
    │   │   ├── turn_light_off_lounge.yaml
    │   │   ├── turn_light_on_bedroom.yaml
    │   │   └── turn_light_on_lounge.yaml
    │   ├── say_hello.yaml
    │   └── sensors
    │       └── react.yaml
    └── configuration.yaml (未包含)

示例: !include_dir_list

configuration.yaml

automation:
  - alias: "自动化 1"
    triggers:
      - trigger: state
        entity_id: device_tracker.iphone
        to: "home"
    actions:
      - action: light.turn_on
        target:
          entity_id: light.entryway
  - alias: "自动化 2"
    triggers:
      - trigger: state
        entity_id: device_tracker.iphone
        from: "home"
    actions:
      - action: light.turn_off
        target:
          entity_id: light.entryway

可以变为:

configuration.yaml

automation: !include_dir_list automation/presence/

automation/presence/automation1.yaml

alias: "自动化 1"
triggers:
  - trigger: state
    entity_id: device_tracker.iphone
    to: "home"
actions:
  - action: light.turn_on
    target:
      entity_id: light.entryway

automation/presence/automation2.yaml

alias: "自动化 2"
triggers:
  - trigger: state
    entity_id: device_tracker.iphone
    from: "home"
actions:
  - action: light.turn_off
    target:
      entity_id: light.entryway

重要的是要注意,每个文件在使用 !include_dir_list 时必须只包含 一个 条目。

示例: !include_dir_named

configuration.yaml


alexa:
  intents:
    LocateIntent:
      actions:
        action: notify.pushover
        data:
          message: "您的位置通过 Alexa 查询。"
      speech:
        type: plaintext
        text: >
          {%- for state in states.device_tracker -%}
            {%- if state.name.lower() == User.lower() -%}
              {{ state.name }} 在 {{ state.state }}
            {%- endif -%}
          {%- else -%}
            对不起。Pootie!我不知道 {{User}} 在哪里。
          {%- endfor -%}
    WhereAreWeIntent:
      speech:
        type: plaintext
        text: >
          {%- if is_state('device_tracker.iphone', 'home') -%}
            iPhone 在家。
          {%- else -%}
            iPhone 不在家。
          {% endif %}

可以变为:

configuration.yaml

alexa:
  intents: !include_dir_named alexa/

alexa/LocateIntent.yaml


actions:
  action: notify.pushover
  data:
    message: "您的位置通过 Alexa 查询。"
speech:
  type: plaintext
  text: >
    {%- for state in states.device_tracker -%}
      {%- if state.name.lower() == User.lower() -%}
        {{ state.name }} 在 {{ state.state }}
      {%- endif -%}
    {%- else -%}
      对不起。Pootie!我不知道 {{User}} 在哪里。
    {%- endfor -%}

alexa/WhereAreWeIntent.yaml


speech:
  type: plaintext
  text: >
    {%- if is_state('device_tracker.iphone', 'home') -%}
      iPhone 在家。
    {%- else -%}
      iPhone 不在家。
    {% endif %}

示例: !include_dir_merge_list

configuration.yaml

automation:
  - alias: "自动化 1"
    triggers:
      - trigger: state
        entity_id: device_tracker.iphone
        to: "home"
    actions:
      - action: light.turn_on
        target:
          entity_id: light.entryway
  - alias: "自动化 2"
    triggers:
      - trigger: state
        entity_id: device_tracker.iphone
        from: "home"
    actions:
      - action: light.turn_off
        target:
          entity_id: light.entryway

可以变为:

configuration.yaml

automation: !include_dir_merge_list automation/

automation/presence.yaml

- alias: "自动化 1"
  triggers:
    - trigger: state
      entity_id: device_tracker.iphone
      to: "home"
  actions:
    - action: light.turn_on
      target:
        entity_id: light.entryway
- alias: "自动化 2"
  triggers:
    - trigger: state
      entity_id: device_tracker.iphone
      from: "home"
  actions:
    - action: light.turn_off
      target:
        entity_id: light.entryway

重要的是要注意,在使用 !include_dir_merge_list 时,每个文件必须包含一个列表(每个列表项用短横线 [-] 表示)。每个文件可以包含一个或多个条目。

示例: !include_dir_merge_named

configuration.yaml

group:
  bedroom:
    name: "卧室"
    entities:
      - light.bedroom_lamp
      - light.bedroom_overhead
  hallway:
    name: "走廊"
    entities:
      - light.hallway
      - thermostat.home
  front_yard:
    name: "前院"
    entities:
      - light.front_porch
      - light.security
      - light.pathway
      - sensor.mailbox
      - camera.front_porch

可以变为:

configuration.yaml

group: !include_dir_merge_named group/

group/interior.yaml

bedroom:
  name: "卧室"
  entities:
    - light.bedroom_lamp
    - light.bedroom_overhead
hallway:
  name: "走廊"
  entities:
    - light.hallway
    - thermostat.home

group/exterior.yaml

front_yard:
  name: "前院"
  entities:
    - light.front_porch
    - light.security
    - light.pathway
    - sensor.mailbox
    - camera.front_porch

示例:将 !include_dir_merge_list 与 automations.yaml 结合

您想要采用高级方法拆分自动化,但仍想能够创建 UI 中的自动化?在前面的章节中,我们写到了嵌套 !includes。下面是我们如何为自动化实现这一点。

使用诸如 manualui 的标签允许在配置中使用多个键:

configuration.yaml


# 我自己的手动自动化
automation manual: !include_dir_merge_list automations/

# 我在 UI 中创建的自动化
automation ui: !include automations.yaml