网络与发现
某些集成在启用后可能需要通过mDNS/Zeroconf、SSDP或其他方法在网络上发现设备。主要用例是查找没有已知固定IP地址的设备,或者用于可以动态添加和删除任意数量兼容可发现设备的集成。
Home Assistant有内置的助手来支持mDNS/Zeroconf和SSDP。如果你的集成使用其他需要确定使用哪些网络接口来广播流量的发现方法,网络集成提供了一个助手API来访问用户的接口偏好。
mDNS/Zeroconf
Home Assistant使用python-zeroconf包来支持mDNS。由于不建议在单个主机上运行多个mDNS实现,Home Assistant提供了内部助手API来访问正在运行的Zeroconf和AsyncZeroconf`实例。
在使用这些助手之前,请确保在集成的manifest.json中的dependencies中添加zeroconf。
获取AsyncZeroconf对象
from homeassistant.components import zeroconf
...
aiozc = await zeroconf.async_get_async_instance(hass)
获取Zeroconf对象
from homeassistant.components import zeroconf
...
zc = await zeroconf.async_get_instance(hass)
使用AsyncZeroconf和Zeroconf对象
python-zeroconf提供了如何使用这两个对象的示例。
SSDP
Home Assistant通过SSDP提供内置发现功能。
在使用这些助手之前,请确保在集成的manifest.json中的dependencies中添加ssdp。
获取发现的设备列表
可以使用以下内置助手API获取发现的SSDP设备列表。SSDP集成提供了以下助手API来从缓存中查找现有的SSDP发现:ssdp.async_get_discovery_info_by_udn_st、ssdp.async_get_discovery_info_by_st、ssdp.async_get_discovery_info_by_udn。
ssdp.async_get_discovery_info_by_udn_st- 作用:
- 这是一个与简单服务发现协议(SSDP)相关的异步函数。它用于根据唯一设备名称(UDN)和服务类型(ST)来获取设备发现信息。在智能家居或网络设备发现的场景中,当需要定位特定设备并且知道其UDN和ST时,可以使用这个函数。例如,在Home Assistant等智能家居平台中,通过这个函数可以查找特定设备(通过UDN唯一标识)并且属于特定服务类型(如灯光设备服务类型、传感器服务类型等)的相关发现信息,这些信息可能包括设备的位置(IP地址等)、设备的功能描述等内容。
- 参数和返回值:
- 它通常接受两个参数,即唯一设备名称(UDN)和服务类型(ST)。返回值是一个异步操作的结果,最终会返回符合给定UDN和ST条件的设备发现信息。这个返回信息的格式通常是符合SSDP规范的XML或其他数据格式,包含设备的详细描述信息,如设备的基本信息、服务描述等。
- 作用:
ssdp.async_get_discovery_info_by_st- 作用:
- 同样是一个SSDP相关的异步函数。这个函数主要是根据服务类型(ST)来获取设备发现信息。当只关心特定服务类型的设备,而不依赖于唯一设备名称时,可以使用这个函数。比如,想要查找所有属于“智能摄像头”服务类型的设备发现信息,就可以调用这个函数。它会在网络中搜索所有声明了该服务类型的设备,并返回它们的发现信息。
- 参数和返回值:
- 它只接受一个参数,即服务类型(ST)。返回值是一个异步操作的结果,返回的是一个包含所有符合给定服务类型的设备发现信息的集合。这些信息有助于进一步了解和连接这些设备,以便在智能家居系统等环境中对它们进行管理和控制。
- 作用:
ssdp.async_get_discovery_info_by_udn- 作用:
- 也是一个SSDP相关的异步函数,用于根据唯一设备名称(UDN)获取设备发现信息。当已经知道设备的UDN,并且想要获取该设备的详细发现信息(如设备的位置、提供的服务等)时,就可以使用这个函数。它主要聚焦于单个设备,通过UDN来唯一确定要查找的设备。
- 参数和返回值:
- 它接受一个参数,即唯一设备名称(UDN)。返回值是一个异步操作的结果,返回符合给定UDN的设备发现信息。这个信息对于后续与特定设备进行通信、配置等操作非常关键,因为它包含了设备的基本属性和服务信息等内容。
- 作用:
查找特定设备
ssdp.async_get_discovery_info_by_udn_st API在提供SSDP、UDN和ST时返回单个discovery_info或None。
from homeassistant.components import ssdp
...
discovery_info = await ssdp.async_get_discovery_info_by_udn_st(hass, udn, st)
按ST查找设备
如果你想查找特定类型的发现设备,调用ssdp.async_get_discovery_info_by_st将返回与SSDP ST匹配的所有发现设备的列表。以下示例返回网络上发现的每个Sonos播放器的发现信息列表。
from homeassistant.components import ssdp
...
discovery_infos = await ssdp.async_get_discovery_info_by_st(hass, "urn:schemas-upnp-org:device:ZonePlayer:1")
for discovery_info in discovery_infos:
...
按UDN查找设备
如果你想查看特定UDN提供的服务列表,调用ssdp.async_get_discovery_info_by_udn将返回与UPNP UDN匹配的所有发现设备的列表。
from homeassistant.components import ssdp
...
discovery_infos = await ssdp.async_get_discovery_info_by_udn(hass, udn)
for discovery_info in discovery_infos:
...
订阅SSDP发现
某些集成可能需要立即知道设备何时被发现。SSDP集成提供了一个注册API,以便在发现与特定键值匹配的新设备时接收回调。manifest.json中ssdp的相同格式用于匹配。
提供了ssdp.async_register_callback函数来启用此功能。该函数返回一个回调,调用时将取消注册。
以下示例展示了在网络上发现Sonos播放器时注册以获取回调。
from homeassistant.components import ssdp
...
entry.async_on_unload(
ssdp.async_register_callback(
hass, _async_discovered_player, {"st": "urn:schemas-upnp-org:device:ZonePlayer:1"}
)
)
以下示例展示了在存在x-rincon-bootseq标头时注册以获取回调。
from homeassistant.components import ssdp
from homeassistant.const import MATCH_ALL
...
entry.async_on_unload(
ssdp.async_register_callback(
hass, _async_discovered_player, {"x-rincon-bootseq": MATCH_ALL}
)
)
网络
对于使用非内置发现方法且需要访问用户网络适配器配置的集成,应使用以下助手API。
from homeassistant.components import network
...
adapters = await network.async_get_adapters(hass)
async_get_adapters数据结构示例
[
{
"auto": true,
"default": false,
"enabled": true,
"ipv4": [],
"ipv6": [
{
"address": "2001:db8::",
"network_prefix": 8,
"flowinfo": 1,
"scope_id": 1
}
],
"name": "eth0"
},
{
"auto": true,
"default": false,
"enabled": true,
"ipv4": [{"address": "192.168.1.5", "network_prefix": 23}],
"ipv6": [],
"name": "eth1"
},
{
"auto": false,
"default": false,
"enabled": false,
"ipv4": [{"address": "169.254.3.2", "network_prefix": 16}],
"ipv6": [],
"name": "vtun0"
}
]
从适配器获取IP网络
from ipaddress import ip_network
from homeassistant.components import network
...
adapters = await network.async_get_adapters(hass)
for adapter in adapters:
for ip_info in adapter["ipv4"]:
local_ip = ip_info["address"]
network_prefix = ip_info["network_prefix"]
ip_net = ip_network(f"{local_ip}/{network_prefix}", False)
USB
USB集成在启动时、访问集成页面时以及如果底层系统支持pyudev,在设备插入时发现新的USB设备。
检查特定适配器是否已插入
调用async_is_plugged_in API来检查系统上是否存在特定适配器。
from homeassistant.components import usb
...
if not usb.async_is_plugged_in(hass, {"serial_number": "A1234", "manufacturer": "xtech"}):
raise ConfigEntryNotReady("The USB device is missing")
知道何时查找新的兼容USB设备
调用async_register_scan_request_callback API来请求在可能有新的兼容USB设备可用时进行回调。
from homeassistant.components import usb
from homeassistant.core import callback
...
@callback
def _async_check_for_usb() -> None:
"""检查新的兼容蓝牙USB适配器。"""
entry.async_on_unload(
bluetooth.async_register_scan_request_callback(hass, _async_check_for_usb)
)
2717

被折叠的 条评论
为什么被折叠?



