集成清单
每个集成都有一个清单文件来指定其基本信息。该文件在集成目录中存储为manifest.json。必须添加这样一个文件。
{
"domain": "hue",
"name": "Philips Hue",
"after_dependencies": ["http"],
"codeowners": ["@balloob"],
"dependencies": ["mqtt"],
"documentation": "https://www.home-assistant.io/components/hue",
"integration_type": "hub",
"iot_class": "local_polling",
"issue_tracker": "https://github.com/balloob/hue/issues",
"loggers": ["aiohue"],
"requirements": ["aiohue==1.9.1"],
"quality_scale": "platinum"
}
或者你可以复制到项目中的最小示例:
{
"domain": "your_domain_name",
"name": "Your Integration",
"codeowners": [],
"dependencies": [],
"documentation": "https://www.example.com",
"integration_type": "hub",
"iot_class": "cloud_polling",
"requirements": []
}
域(Domain)
域是由字符和下划线组成的短名称。这个域必须是唯一的且不能更改。移动应用集成的域示例:mobile_app。域键必须与该文件所在的目录匹配。
名称(Name)
集成的名称。
版本(Version)
对于核心集成,应省略此部分。对于自定义集成,版本是必需的,并且需要是AwesomeVersion能够识别的有效版本,如CalVer或SemVer。
集成类型(Integration type)
集成分为多种类型。每个集成必须在其清单中提供一个integration_type,以描述其主要功能。
注意:如果未设置,我们目前默认为hub。在过渡期间,此默认值是临时的,每个集成都应设置integration_type,并且在未来它将成为必填项。
类型 | 描述 |
---|---|
device | 提供单个设备,例如ESPHome。 |
entity | 提供基本实体平台,如传感器或灯光。一般不应使用此类型。 |
hardware | 提供硬件集成,如Raspbery Pi或Hardkernel。一般不应使用此类型。 |
helper | 提供一个实体来帮助用户进行自动化操作,如输入布尔值、导数或组。 |
hub | 提供一个集成中心,包含多个设备或服务,如Philips Hue。 |
service | 提供单个服务,如DuckDNS或AdGuard。 |
system | 提供系统集成,是保留类型,一般不应使用。 |
virtual | 本身不是一个集成,而是指向另一个集成或物联网标准。请参阅虚拟集成部分。 |
注意:hub与service或device的区别由集成的性质定义。hub提供通往多个其他设备或服务的网关。service和device是每个配置项提供单个设备或服务的集成。
文档(Documentation)
包含有关如何使用集成的文档的网站。如果此集成正在提交以包含在Home Assistant中,它应该是https://www.home-assistant.io/integrations/<域>
。
问题跟踪器(Issue tracker)
集成的问题跟踪器,用户如果遇到问题可以在此报告。如果此集成正在提交以包含在Home Assistant中,应省略此项。对于内置集成,Home Assistant将自动生成正确的链接。
依赖项(Dependencies)
依赖项是你希望Home Assistant在加载集成之前成功设置的其他Home Assistant集成。将一个集成添加到依赖项中,将确保在设置之前加载依赖的集成,但不保证所有依赖项配置项都已设置。如果你想从其他集成提供功能(如webhooks或MQTT连接),添加依赖项可能是必要的。如果依赖项是可选但非关键的,添加after依赖项可能是更好的选择。有关处理MQTT的更多详细信息,请参阅MQTT部分。内置集成应仅在dependencies中指定其他内置集成。自定义集成可以在dependencies中指定内置和自定义集成。
after依赖项(After dependencies)
此选项用于指定集成可能使用但不是必需的依赖项。当存在after_dependencies时,集成的设置将等待在after_dependencies中列出的集成(通过YAML或配置项进行配置)首先设置完成,然后再设置该集成。它还将确保安装after_dependencies的要求,以便可以安全地导入集成的方法,无论after_dependencies中列出的集成是否已配置。例如,如果camera集成在某些配置中可能使用stream集成,将stream添加到camera清单的after_dependencies中,将确保如果stream已配置,则在camera之前加载stream,并且stream的任何依赖项都已安装并可由camera导入。如果stream未配置,camera仍将加载。内置集成应仅在after_dependencies中指定其他内置集成。自定义集成可以在after_dependencies中指定内置和自定义集成。
代码所有者(Code owners)
负责此集成的GitHub用户名或团队名称。你至少应在此添加你的GitHub用户名,以及任何帮助你编写包含在内的代码的人。
配置流程(Config flow)
如果你的集成有配置流程来创建配置项,则指定config_flow键。指定后,文件config_flow.py需要存在于你的集成中。
{
"config_flow": true
}
单个配置项(Single config entry only)
如果你的集成仅支持一个配置项,则指定single_config_entry键。指定后,将不允许用户为此集成添加多个配置项。
{
"single_config_entry": true
}
要求(Requirements)
要求是你通常使用pip为组件安装的Python库或模块。如果不使用venv,Home Assistant将尝试将要求安装到Home Assistant配置目录的deps子目录中;如果在虚拟环境中运行,则安装到类似path/to/venv/lib/python3.6/site-packages的位置。这将确保在启动时所有要求都存在。如果步骤失败,如缺少模块编译所需的包或其他安装错误,组件将无法加载。要求是一个字符串数组。每个条目都是一个pip兼容的字符串。例如,媒体播放器Cast平台依赖于Python包PyChromecast v3.2.0:[“pychromecast==3.2.0”]。
开发和测试期间的自定义要求(Custom requirements during development & testing)
在组件开发期间,针对要求的不同版本进行测试可能很有用。以pychromecast为例,这可以通过两个步骤完成:
pip install pychromecast==3.2.0 --target ~/.homeassistant/deps
hass --skip-pip-packages pychromecast
这将使用指定版本,并防止Home Assistant尝试用requirements中指定的版本覆盖它。要防止任何包被自动覆盖而不指定依赖项,可以使用全局–skip-pip标志启动Home Assistant。
如果你需要对要求进行更改以支持你的组件,也可以使用pip install -e安装要求的开发版本:
git clone https://github.com/balloob/pychromecast.git
pip install -e./pychromecast
hass --skip-pip-packages pychromecast
也可以使用公共git仓库安装要求。例如,在要求依赖项发布到PyPI之前测试对其的更改时,这可能很有用。语法:
{
"requirements": ["git+https://github.com/<user>/<project>.git@<git ref>"]
}
<git ref>
可以是任何git引用:分支、标签、提交哈希等。有关git支持的详细信息,请参阅PIP文档。以下示例将直接从GitHub安装pycoolmaster库的except_connect分支:
{
"requirements": ["git+https://github.com/issacg/pycoolmaster.git@except_connect"]
}
自定义集成要求(Custom integration requirements)
自定义集成应仅包括Core requirements.txt中未要求的要求。
记录器(Loggers)
loggers字段是集成要求在其getLogger调用中使用的名称列表。
蓝牙(Bluetooth)
如果你的集成支持通过蓝牙发现,可以在清单中添加一个匹配器。如果用户加载了bluetooth集成,当发现设备时,将加载集成配置流程的bluetooth步骤。我们支持通过匹配connectable、local_name、service_uuid、service_data_uuid、manufacturer_id和manufacturer_data_start来监听蓝牙发现。manufacturer_data_start字段期望一个字节列表,编码为0 - 255的整数值。清单值是一个匹配器字典列表。如果在蓝牙数据中找到任何指定匹配器的所有项,则发现你的集成。由你的配置流程负责过滤重复项。local_name的匹配项在前三个字符中可能不包含任何模式。如果设备只需要广告数据,将connectable设置为false将选择接收来自不支持连接的蓝牙控制器的发现。以下示例将匹配Nespresso Prodigio机器:
{
"bluetooth": [
{
"local_name": "Prodigio_*"
}
]
}
以下示例将匹配用于SwitchBot机器人和窗帘设备的128位uuid的服务数据:
{
"bluetooth": [
{
"service_uuid": "cba20d00-224d-11e6-9fb8-0002a5d5c51b"
}
]
}
如果你想匹配16位uuid的服务数据,必须首先将其转换为128位uuid,方法是将00000000 - 0000 - 1000 - 8000 - 00805f9b34fb中的第3和第4个字节替换为16位uuid。例如,对于Switchbot传感器设备,16位uuid是0xfd3d,相应的128位uuid变为0000fd3d - 0000 - 1000 - 8000 - 00805f9b34fb。因此,以下示例将匹配用于SwitchBot传感器设备的16位uuid的服务数据:
{
"bluetooth": [
{
"service_data_uuid": "0000fd3d-0000-1000-8000-00805f9b34fb"
}
]
}
以下示例将匹配HomeKit设备:
{
"bluetooth": [
{
"manufacturer_id": 76,
"manufacturer_data_start": [6]
}
]
}
零配置(Zeroconf)
如果你的集成支持通过Zeroconf发现,可以在清单中添加类型。如果用户加载了zeroconf集成,当发现设备时,将加载集成配置流程的zeroconf步骤。Zeroconf是一个列表,因此你可以指定多个要匹配的类型。
{
"zeroconf": ["_googlecast._tcp.local."]
}
某些zeroconf类型非常通用(例如_printer._tcp.local.、_axis-video._tcp.local.或_http._tcp.local)。在这种情况下,你应该包含一个名称(name)或属性(properties)过滤器:
{
"zeroconf": [
{"type":"_axis-video._tcp.local.","properties":{"macaddress":"00408c*"}},
{"type":"_axis-video._tcp.local.","name":"example*"},
{"type":"_airplay._tcp.local.","properties":{"am":"audioaccessory*"}}
]
}
请注意,properties过滤器中的所有值必须为小写,并且可以包含fnmatch类型的通配符。
简单服务发现协议(SSDP)
如果你的集成支持通过SSDP发现,可以在清单中添加类型。如果用户加载了ssdp集成,当发现设备时,将加载集成配置流程的ssdp步骤。我们通过SSDP ST、USN、EXT和Server标头(标头名称小写)以及UPnP设备描述中的数据支持SSDP发现。清单值是一个匹配器字典列表,如果在SSDP/UPnP数据中找到任何指定匹配器的所有项,则发现你的集成。由你的配置流程负责过滤重复项。以下示例有一个由三个项组成的匹配器,所有这些项都必须匹配才能通过此配置进行发现。
{
"ssdp": [
{
"st": "roku:ecp",
"manufacturer": "Roku",
"deviceType": "urn:roku-com:device:player:1-0"
}
]
}
家庭套件(HomeKit)
如果你的集成支持通过HomeKit发现,可以在清单中添加支持的型号名称。如果用户加载了zeroconf集成,当发现设备时,将加载集成配置流程的homekit步骤。HomeKit发现通过测试发现的modelname是否以清单.json中指定的任何型号名称开头来工作。
{
"homekit": {
"models": [
"LIFX"
]
}
}
通过HomeKit发现并不意味着你必须使用HomeKit协议与设备通信。你可以根据需要以任何方式与设备通信。当由于清单中的此条目将发现信息路由到你的集成时,发现信息将不再路由到监听HomeKit zeroconf类型的集成。
MQTT
如果你的集成支持通过MQTT发现,可以在清单中添加用于发现的主题。如果用户加载了mqtt集成,当发现设备时,将加载集成配置流程的mqtt步骤。MQTT发现通过订阅清单.json中指定的MQTT主题来工作。
{
"mqtt": [
"tasmota/discovery/#"
]
}
如果你的集成需要mqtt,请确保将其添加到依赖项中。依赖于MQTT的集成应使用await mqtt.async_wait_for_mqtt_client(hass)等待MQTT客户端可用,然后才能订阅。async_wait_for_mqtt_client方法将阻塞并返回True,直到MQTT客户端可用。
DHCP
如果你的集成支持通过DHCP发现,可以在清单中添加类型。如果用户加载了dhcp集成,当发现设备时,将加载集成配置流程的dhcp步骤。我们通过主机名(hostname)和OUI被动监听DHCP发现,或者当registered_devices设置为true时匹配设备注册表中的mac地址。清单值是一个匹配器字典列表,如果在DHCP数据中找到任何指定匹配器的所有项,则发现你的集成。由你的配置流程负责过滤重复项。如果一个集成希望在设备上线时接收发现流以更新其IP地址,但主机名或OUI匹配太宽泛,并且它已使用CONNECTION_NETWORK_MAC在设备注册表中注册了mac地址,则应添加一个DHCP条目,并将registered_devices设置为true。如果集成支持zeroconf或ssdp,应优先使用它们而不是dhcp,因为它们通常提供更好的用户体验。以下示例有三个由两个项组成的匹配器。任何一个匹配器中的所有项都必须匹配才能通过此配置进行发现。例如:如果主机名是Rachio-XYZ且macaddress是00:9D:6B:55:12:AA,则会发现设备。如果主机名是Rachio-XYZ且macaddress是00:00:00:55:12:AA,则不会发现设备。如果主机名是NotRachio-XYZ且macaddress是00:9D:6B:55:12:AA,则不会发现设备。
{
"dhcp": [
{
"hostname": "rachio-*",
"macaddress": "009D6B*"
},
{
"hostname": "rachio-*",
"macaddress": "F0038C*"
},
{
"hostname": "rachio-*",
"macaddress": "74C63B*"
}
]
}
设置registered_devices为true的示例:
{
"dhcp": [
{
"hostname": "myintegration-*"
},
{
"registered_devices": true
}
]
}
USB
如果你的集成支持通过USB发现,可以在清单中添加类型。如果用户加载了usb集成,当发现设备时,将加载集成配置流程的usb步骤。我们通过从USB描述符中提取VID(供应商ID)、PID(设备ID)、序列号、制造商和描述来支持发现。有关识别这些值的帮助,请参阅如何识别设备。清单值是一个匹配器字典列表。如果在USB数据中找到任何指定匹配器的所有项,则发现你的集成。由你的配置流程负责过滤重复项。
注意:一些VID和PID组合被许多不相关的设备使用。例如,VID 10C4和PID EA60匹配任何Silicon Labs CP2102 USB-Serial桥接芯片。当匹配此类设备时,重要的是匹配description或其他标识符以避免意外发现。以下示例有两个由两个项组成的匹配器。任何一个匹配器中的所有项都必须匹配才能通过此配置进行发现。例如:如果vid是AAAA且pid是AAAA,则会发现设备。如果vid是AAAA且pid是FFFF,则不会发现设备。如果vid是CCCC且pid是AAAA,则不会发现设备。如果vid是1234,pid是ABCD,serial_number是12345678,manufacturer是Midway USB,description是Version 12 Zigbee Stick,则会发现设备。
{
"usb": [
{
"vid": "AAAA",
"pid": "AAAA"
},
{
"vid": "BBBB",
"pid": "BBBB"
},
{
"vid": "1234",
"pid": "ABCD",
"serial_number": "1234*",
"manufacturer": "*midway*",
"description": "*zigbee*"
}
]
}
集成质量等级(Integration quality scale)
集成质量等级根据代码质量和用户体验对集成进行评分。质量等级的每个级别都由一系列要求组成。如果一个集成满足所有要求,则被认为达到了该级别。如果你的集成没有评分,那么不要将其添加到集成的清单中。但是,请务必查看集成质量等级要求列表。它有助于极大地提高代码和用户体验。我们强烈建议对你的集成进行评分。
{
"quality_scale": "silver"
}
物联网类别(IoT class)
物联网类别描述了集成如何与设备或服务连接。有关物联网类别的更多信息,请阅读关于“物联网分类”的博客。清单中接受以下物联网类别:
- assumed_state:我们无法获取设备的状态。我们所能做的最好的就是根据我们的最后一个命令来假设状态。
- cloud_polling:此设备的集成通过云进行,需要活动的互联网连接。轮询状态意味着可能会稍后注意到更新。
- cloud_push:此设备的集成通过云进行,需要活动的互联网连接。一旦有新状态可用,Home Assistant将收到通知。
- local_polling:提供与设备的直接通信。轮询状态意味着可能会稍后注意到更新。
- local_push:提供与设备的直接通信。一旦有新状态可用,Home Assistant将收到通知。
- calculated:集成本身不处理通信,而是提供计算结果。
虚拟集成(Virtual integration)
有些产品由不以产品命名的集成支持。例如,Yale Home锁通过August集成进行集成,IKEA SYMFONISK产品线可以与Sonos集成一起使用。还有一些情况,产品线仅支持标准物联网标准,如Zigbee或Z-Wave。例如,U-tec ultraloq通过Z-Wave工作,没有特定的专用集成。对于最终用户来说,找到如何将这些产品与Home Assistant集成可能会很困惑。为了帮助解决上述情况,Home Assistant有“虚拟集成”。这些集成不是真正的集成,而是用于帮助用户找到适合其设备的正确集成。虚拟集成是仅具有单个清单文件而没有任何其他代码的集成。有两种类型的虚拟集成:由另一个集成支持的虚拟集成和使用现有物联网标准的虚拟集成。
注意:虚拟集成只能由Home Assistant Core提供,不能由自定义集成提供。
由……支持(Supported by)
“由……支持”虚拟集成是指向另一个集成以提供其实现的集成。例如,Yale Home锁通过August(august)集成进行集成。示例清单:
{
"domain": "yale_home",
"name": "Yale Home",
"integration_type": "virtual",
"supported_by": "august"
}
域(domain)和名称(name)与任何其他集成相同,但integration_type设置为virtual。此虚拟集成的域的徽标必须添加到我们的品牌存储库中,因此在这种情况下,使用Yale Home品牌。supported_by是为该产品提供实现的集成的域。在上面的示例中,Yale Home锁由August集成支持,并指向其域august。结果:Yale Home在我们的用户文档网站的集成下列出,带有自动生成的存根页面,引导用户使用该集成。Yale Home在Home Assistant中单击“添加集成”时列出。选择时,我们向用户解释该产品使用不同的集成进行集成,然后用户继续到Xioami Miio配置流程。
物联网标准(IoT standards)
“物联网标准”虚拟集成是使用现有物联网标准提供与设备连接的集成。例如,U-tec ultraloq通过Z-Wave工作,没有特定的专用集成。示例清单:
{
"domain": "ultraloq",
"name": "ultraloq",
"integration_type": "virtual",
"iot_standards": ["zwave"]
}
域(domain)和名称(name)与任何其他集成相同,但integration_type设置为virtual。此虚拟集成的域的徽标应添加到我们的品牌存储库中。iot_standards是该产品用于连接的标准。在上面的示例中,U-tech ultraloq产品使用Z-Wave与Home Assistant集成。结果:U-tech ultraloq在我们的用户文档网站的集成下列出,带有自动生成的存根页面,引导用户使用该集成。U-tech ultraloq在Home Assistant中单击“添加集成”时列出。选择时,我们指导用户添加此Z-Wave设备(如果Z-Wave尚未设置,则先设置Z-Wave)。
注意:品牌也支持设置物联网标准。最好在品牌级别设置物联网标准,仅在可能给最终用户造成混淆的情况下使用虚拟集成。
总结
本文档主要介绍了Home Assistant集成清单(manifest.json)的相关内容,包括清单文件的作用、各字段的含义及用法,如域(domain)、名称(name)、版本(version)、集成类型(integration_type)、文档(documentation)、问题跟踪器(issue tracker)、依赖项(dependencies和after_dependencies)、代码所有者(codeowners)、配置流程(config_flow)、单个配置项(single_config_entry)、要求(requirements)、记录器(loggers)、蓝牙(Bluetooth)、零配置(Zeroconf)、简单服务发现协议(SSDP)、家庭套件(HomeKit)、MQTT、DHCP、USB、集成质量等级(integration quality scale)、物联网类别(IoT class)以及虚拟集成(virtual integration)等,为开发人员创建和配置Home Assistant集成提供了全面的指导。