实体
有关实体的一般介绍,请参阅实体架构。
基本实现
下面是一个示例开关实体,用于在内存中跟踪状态。 示例中的开关代表设备的主要功能, 因此实体与设备具有相同的名称。
请参阅实体命名,了解如何为实体设置名称。
这就是构建开关实体所需的全部内容!继续阅读以了解更多信息或查看视频教程。
更新实体
一个实体代表一个设备。有多种策略可以使您的实体与设备状态保持同步,最流行的一种是轮询。
轮询
通过轮询,Home Assistant 会不时地(取决于组件的更新间隔)要求实体获取最新状态。当 should_poll 属性返回 True(默认值)时,Home Assistant 将轮询实体。您可以使用 update() 或异步方法 async_update() 实现更新逻辑。此方法应从设备获取最新状态并将其存储在实例变量中,以便属性返回它。
订阅更新
当您订阅更新时,您的代码负责让 Home Assistant 知道有可用更新。确保您有 should_poll 属性返回 False。
每当您从订阅中收到新状态时,您都可以通过调用 schedule_update_ha_state() 或异步回调 async_schedule_update_ha_state() 告诉 Home Assistant 有可用更新。如果您希望 Home Assistant 在将更新写入 Home Assistant 之前调用您的更新方法,请将布尔值 True 传递给该方法。
通用属性
实体基类具有所有 Home Assistant 实体共有的一些属性。这些属性可以添加到任何实体,无论其类型如何。所有这些属性都是可选的,不需要实现。
当状态写入状态机时,始终会调用这些属性。
允许更改 device_class、supported_features 或域的 capability_attributes 中包含的任意属性。但是,这些实体属性通常默认不会变化,而且某些实体消费者可能不会及时感知更新,因此建议仅在确有必要时、以适度频率更改。
例如,此类更改将导致语音助手集成与支持的云服务重新同步。
当 extra_state_attributes 也频繁更改时,生成大量状态更改的实体可以快速增加数据库的大小。通过删除非关键属性或创建其他 sensor 实体,最大限度地减少这些实体的 extra_state_attributes 数量。
注册表属性
以下属性用于填充实体和设备注册表。每次将实体添加到 Home Assistant 时都会读取它们。仅当 unique_id 不为 None 时,这些属性才有效。
高级属性
以下属性也可用于实体。然而,它们仅供高级使用,应谨慎使用。当状态写入状态机时,始终会调用这些属性。
系统属性
以下属性由 Home Assistant 使用和控制,不应被集成覆盖。
实体命名
避免将实体名称写死为英文字符串;名称应使用国际化机制进行翻译。不应翻译的名称包括专有名词、型号名以及第三方库提供的名称。
某些实体会根据其设备类别自动命名,其中包括 binary_sensor、button、number 和 sensor 实体,并且在许多情况下不需要命名。
例如,设备类别设置为 temperature 的未命名传感器将被命名为“Temperature”。
如果实体提供实体名称的翻译,则使用的名称取决于创建时的系统(后端)语言,而不是用户的 UI 语言。例如,如果您的后端设置为德语,则新实体将以德语命名 - 即使用户稍后将其 UI 切换为法语。更改后端语言只会影响更改后创建的实体;现有实体保留其原始名称。
has_entity_name True(新集成必需)
实体的名称属性仅标识实体所代表的数据点,不应包含设备的名称或实体的类型。因此,对于代表其设备的电量使用情况的传感器,这将是“电量使用情况”。
如果实体代表设备的单个主要功能,则实体的名称属性通常应返回 None。
例如,设备的“主要功能”是智能灯泡的 LightEntity。
friendly_name 状态属性由实体名称和设备名称组合生成,规则如下:
- 该实体不是设备的成员:
friendly_name = entity.name - 该实体是设备的成员,并且
entity.name不是None:friendly_name = f"{device.name} {entity.name}" - 该实体是设备的成员,
entity.name是None:friendly_name = f"{device.name}"
entity_id 由实体名称和设备名称组合生成,规则如下:
- 该实体不是设备的成员,例如辅助实体“大家都在家”:
entity_id = binary_sensor.everyone_is_home - 该实体是设备的成员,并且
entity.name不是None,例如名为“夜灯”的设备的电池:entity_id = sensor.nightlight_battery - 该实体是设备的成员,
entity.name是None,例如名为“夜灯”的设备的灯光:entity_id = light.nightlight
实体名称应以大写字母开头,其余单词均小写(当然除非它是专有名词或大写缩写)。
作为设备主要功能的开关实体示例
注:此示例使用类属性实现实体属性;其他实现方式请参阅属性实现。
注意:示例并不完整,必须实现 unique_id 属性,并且实体必须已在设备注册表中注册。
开关实体示例:该实体不是设备的主要功能,或不属于某个设备:
注:此示例使用类属性实现实体属性;其他实现方式请参阅属性实现。
注意:如果实体属于某个设备,则必须实现 unique_id 属性,并且实体必须已在设备注册表中注册。
未翻译的开关实体示例:该实体不是设备的主要功能,或不属于某个设备:
has_entity_name 未实现或 False(已弃用)
实体的名称属性可以是设备名称和实体所表示的数据点的组合。
属性实现
属性方法
为每个属性编写一个属性方法通常只需要几行代码,例如:
实体类或实例属性
或者,也可以用更简洁的方式设置实体类属性或实例属性,例如:
这与第一个示例完全等价,但依赖于基类中属性的默认实现。
这些属性名以 _attr_ 开头,后接实际属性名。例如,默认的
device_class 属性返回 _attr_device_class 类属性。
并非所有实体类都支持通过 _attr_ 设置对应的实体属性。
具体支持哪些属性,请参考各实体类的文档。
如果集成需要访问自己的属性,则应访问属性 (self.name),而不是类或实例属性 (self._attr_name)。
实体描述
设置实体属性的第三种方式是使用实体描述。为此,需要在 Entity 实例上设置名为 entity_description 的属性,并将其赋值为一个 EntityDescription 实例。实体描述是一个数据类,其字段对应大多数可用的 Entity 属性。每个支持实体平台的实体集成(例如 switch 集成)都会定义自己的 EntityDescription 子类,供希望使用实体描述的实现平台使用。
默认情况下,EntityDescription 实例有一个名为 key 的必填属性。它是一个字符串,对于该实现平台的所有实体描述都必须唯一。常见做法是将它包含在所描述实体的 unique_id 中。
使用实体描述的主要好处是它以声明的方式定义平台的不同实体类型,使得当存在许多不同的实体类型时代码更容易阅读。
示例
下面的代码片段给出了何时实现属性函数、何时使用类或实例属性以及何时使用实体描述的最佳实践示例。
生命周期挂钩
使用这些生命周期挂钩在实体发生某些事件时执行代码。所有生命周期挂钩都是异步方法。
async_added_to_hass()
当实体首次写入状态机之前分配了实体 ID 和 hass 对象时调用。示例用途:恢复状态、订阅更新或设置回调/调度函数/侦听器。
async_will_remove_from_hass()
当实体即将从 Home Assistant 中删除时调用。使用示例:与服务器断开连接或取消订阅更新。
图标
Home Assistant 中的每个实体都有一个图标,作为视觉提示,便于在前端识别实体。Home Assistant 使用Material Design Icons 图标集。
在大多数情况下,Home Assistant 会根据实体的域、device_class 和 state 自动选择图标。如果可能,最好使用默认图标,以提供一致的体验并避免用户混淆。但是,可以覆盖默认值并为实体提供自定义图标。
无论提供什么图标,用户始终可以在前端根据自己的喜好自定义图标。
有两种方式可以为实体提供自定义图标:提供图标翻译,或直接提供图标标识符。
图标翻译
这是为实体提供自定义图标的首选方式。图标翻译的工作方式与常规国际化机制类似,但它不是将实体状态翻译成文本,而是将实体状态映射到对应图标。
请注意,状态翻译键必须使用 snake_case,与其他翻译键保持一致。
实体的 translation_key 属性定义要使用的图标翻译键。该属性用于在集成的 icons.json 文件的 entity 部分中查找翻译。
为了区分实体及其翻译,请使用不同的翻译键。下面的示例展示了 Moon 域 sensor 实体的 icons.json,其 translation_key 属性设置为 phase:
请注意,图标值以 mdi: 加上图标标识符组成。当实体状态未出现在 state 部分时,将使用 default 图标。state 部分是可选的;如果未提供,则所有状态都使用 default 图标。
如果前端支持显示状态属性图标,还可以为实体的状态属性提供图标。示例包括气候预设和风扇模式;其他状态属性则不能这样做。下面的示例为 climate 实体提供图标,其 translation_key 属性设置为 ubercool。该实体具有 preset_mode 状态属性,可设置为 vacation 或 night;前端会在气候卡等位置使用这些图标。
请注意,状态属性翻译键必须使用 snake_case,与其他翻译键保持一致。
图标属性
为实体提供图标的另一种方法是设置实体的 icon 属性,该属性返回引用 mdi 图标的字符串。由于此属性是一种方法,因此可以根据自定义逻辑返回不同的图标,这与图标翻译不同。例如,可以根据状态计算图标,如下例所示,或者根据不属于实体状态的内容返回不同的图标。
无法使用 icon 属性为状态属性提供图标。请注意,不鼓励使用 icon 属性;优先使用上述图标翻译。
从记录器历史记录中排除状态属性
不适合状态历史记录的状态属性应通过将其包含在 _entity_component_unrecorded_attributes 或 _unrecorded_attributes 中而从状态历史记录中排除。
_entity_component_unrecorded_attributes: frozenset[str]可以在基本组件类中设置,例如在light.LightEntity中_unrecorded_attributes: frozenset[str]可以设置在集成平台中,例如在平台hue.light中定义的实体类中。
MATCH_ALL 常量可用于排除所有属性,而不必逐个列出。这对于会提供未知属性的集成,或只想一次性排除全部属性的场景非常有用。
使用 MATCH_ALL 常量不会停止 device_class、state_class、unit_of_measurement 和 friendly_name 的记录,因为它们还可能用于其他目的,因此不应被排除在记录之外。
从记录中排除的平台状态属性示例包括 image 实体的 entity_picture 属性(过一段时间后会失效)以及 fan 实体的 preset_modes 属性(通常不会变化)。
从记录中排除的集成特定状态属性示例包括平台 trafikverket.camera 中不会变化的 description 和 location 状态属性。
_entity_component_unrecorded_attributes 和 _unrecorded_attributes 必须声明为类属性;实例属性将被忽略。
更改实体模型
如果您想为实体或其任意子类型(灯、开关等)添加新功能,需要先在我们的架构仓库中发起讨论。只有不同厂商之间通用的功能才会被考虑纳入。

