Allow integrations to request dhcp discovery flows for registered devices (#66528)

pull/66581/head
J. Nick Koston 2022-02-15 11:02:52 -06:00 committed by GitHub
parent 2b43293363
commit f069a37f7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 239 additions and 647 deletions

View File

@ -1,4 +1,5 @@
"""The dhcp integration."""
from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
@ -35,7 +36,12 @@ from homeassistant.const import (
from homeassistant.core import Event, HomeAssistant, State, callback
from homeassistant.data_entry_flow import BaseServiceInfo
from homeassistant.helpers import discovery_flow
from homeassistant.helpers.device_registry import format_mac
from homeassistant.helpers.device_registry import (
CONNECTION_NETWORK_MAC,
DeviceRegistry,
async_get,
format_mac,
)
from homeassistant.helpers.event import (
async_track_state_added_domain,
async_track_time_interval,
@ -54,9 +60,11 @@ MESSAGE_TYPE = "message-type"
HOSTNAME: Final = "hostname"
MAC_ADDRESS: Final = "macaddress"
IP_ADDRESS: Final = "ip"
REGISTERED_DEVICES: Final = "registered_devices"
DHCP_REQUEST = 3
SCAN_INTERVAL = timedelta(minutes=60)
_LOGGER = logging.getLogger(__name__)
@ -180,7 +188,20 @@ class WatcherBase:
)
matched_domains = set()
device_domains = set()
dev_reg: DeviceRegistry = async_get(self.hass)
if device := dev_reg.async_get_device(
identifiers=set(), connections={(CONNECTION_NETWORK_MAC, uppercase_mac)}
):
for entry_id in device.config_entries:
if entry := self.hass.config_entries.async_get_entry(entry_id):
device_domains.add(entry.domain)
for entry in self._integration_matchers:
if entry.get(REGISTERED_DEVICES) and not entry["domain"] in device_domains:
continue
if MAC_ADDRESS in entry and not fnmatch.fnmatch(
uppercase_mac, entry[MAC_ADDRESS]
):
@ -192,14 +213,12 @@ class WatcherBase:
continue
_LOGGER.debug("Matched %s against %s", data, entry)
if entry["domain"] in matched_domains:
# Only match once per domain
continue
matched_domains.add(entry["domain"])
for domain in matched_domains:
discovery_flow.async_create_flow(
self.hass,
entry["domain"],
domain,
{"source": config_entries.SOURCE_DHCP},
DhcpServiceInfo(
ip=ip_address,

View File

@ -2,639 +2,153 @@
To update, run python3 -m script.hassfest
"""
from __future__ import annotations
# fmt: off
DHCP = [
{
"domain": "august",
"hostname": "connect",
"macaddress": "D86162*"
},
{
"domain": "august",
"hostname": "connect",
"macaddress": "B8B7F1*"
},
{
"domain": "august",
"hostname": "connect",
"macaddress": "2C9FFB*"
},
{
"domain": "august",
"hostname": "august*",
"macaddress": "E076D0*"
},
{
"domain": "axis",
"hostname": "axis-00408c*",
"macaddress": "00408C*"
},
{
"domain": "axis",
"hostname": "axis-accc8e*",
"macaddress": "ACCC8E*"
},
{
"domain": "axis",
"hostname": "axis-b8a44f*",
"macaddress": "B8A44F*"
},
{
"domain": "blink",
"hostname": "blink*",
"macaddress": "B85F98*"
},
{
"domain": "blink",
"hostname": "blink*",
"macaddress": "00037F*"
},
{
"domain": "blink",
"hostname": "blink*",
"macaddress": "20A171*"
},
{
"domain": "broadlink",
"macaddress": "34EA34*"
},
{
"domain": "broadlink",
"macaddress": "24DFA7*"
},
{
"domain": "broadlink",
"macaddress": "A043B0*"
},
{
"domain": "broadlink",
"macaddress": "B4430D*"
},
{
"domain": "elkm1",
"macaddress": "00409D*"
},
{
"domain": "emonitor",
"hostname": "emonitor*",
"macaddress": "0090C2*"
},
{
"domain": "flume",
"hostname": "flume-gw-*"
},
{
"domain": "flux_led",
"macaddress": "18B905*",
"hostname": "[ba][lk]*"
},
{
"domain": "flux_led",
"macaddress": "249494*",
"hostname": "[ba][lk]*"
},
{
"domain": "flux_led",
"macaddress": "7CB94C*",
"hostname": "[ba][lk]*"
},
{
"domain": "flux_led",
"macaddress": "ACCF23*",
"hostname": "[hba][flk]*"
},
{
"domain": "flux_led",
"macaddress": "B4E842*",
"hostname": "[ba][lk]*"
},
{
"domain": "flux_led",
"macaddress": "F0FE6B*",
"hostname": "[hba][flk]*"
},
{
"domain": "flux_led",
"macaddress": "8CCE4E*",
"hostname": "lwip*"
},
{
"domain": "flux_led",
"hostname": "zengge_[0-9a-f][0-9a-f]_*"
},
{
"domain": "flux_led",
"macaddress": "C82E47*",
"hostname": "sta*"
},
{
"domain": "fronius",
"macaddress": "0003AC*"
},
{
"domain": "goalzero",
"hostname": "yeti*"
},
{
"domain": "gogogate2",
"hostname": "ismartgate*"
},
{
"domain": "guardian",
"hostname": "gvc*",
"macaddress": "30AEA4*"
},
{
"domain": "guardian",
"hostname": "gvc*",
"macaddress": "B4E62D*"
},
{
"domain": "guardian",
"hostname": "guardian*",
"macaddress": "30AEA4*"
},
{
"domain": "hunterdouglas_powerview",
"hostname": "hunter*",
"macaddress": "002674*"
},
{
"domain": "isy994",
"hostname": "isy*",
"macaddress": "0021B9*"
},
{
"domain": "lyric",
"hostname": "lyric-*",
"macaddress": "48A2E6*"
},
{
"domain": "lyric",
"hostname": "lyric-*",
"macaddress": "B82CA0*"
},
{
"domain": "lyric",
"hostname": "lyric-*",
"macaddress": "00D02D*"
},
{
"domain": "myq",
"macaddress": "645299*"
},
{
"domain": "nest",
"macaddress": "18B430*"
},
{
"domain": "nest",
"macaddress": "641666*"
},
{
"domain": "nest",
"macaddress": "D8EB46*"
},
{
"domain": "nest",
"macaddress": "1C53F9*"
},
{
"domain": "nexia",
"hostname": "xl857-*",
"macaddress": "000231*"
},
{
"domain": "nuheat",
"hostname": "nuheat",
"macaddress": "002338*"
},
{
"domain": "nuki",
"hostname": "nuki_bridge_*"
},
{
"domain": "oncue",
"hostname": "kohlergen*",
"macaddress": "00146F*"
},
{
"domain": "overkiz",
"hostname": "gateway*",
"macaddress": "F8811A*"
},
{
"domain": "powerwall",
"hostname": "1118431-*"
},
{
"domain": "rachio",
"hostname": "rachio-*",
"macaddress": "009D6B*"
},
{
"domain": "rachio",
"hostname": "rachio-*",
"macaddress": "F0038C*"
},
{
"domain": "rachio",
"hostname": "rachio-*",
"macaddress": "74C63B*"
},
{
"domain": "rainforest_eagle",
"macaddress": "D8D5B9*"
},
{
"domain": "ring",
"hostname": "ring*",
"macaddress": "0CAE7D*"
},
{
"domain": "roomba",
"hostname": "irobot-*",
"macaddress": "501479*"
},
{
"domain": "roomba",
"hostname": "roomba-*",
"macaddress": "80A589*"
},
{
"domain": "roomba",
"hostname": "roomba-*",
"macaddress": "DCF505*"
},
{
"domain": "samsungtv",
"hostname": "tizen*"
},
{
"domain": "samsungtv",
"macaddress": "8CC8CD*"
},
{
"domain": "samsungtv",
"macaddress": "606BBD*"
},
{
"domain": "samsungtv",
"macaddress": "F47B5E*"
},
{
"domain": "samsungtv",
"macaddress": "4844F7*"
},
{
"domain": "screenlogic",
"hostname": "pentair: *",
"macaddress": "00C033*"
},
{
"domain": "sense",
"hostname": "sense-*",
"macaddress": "009D6B*"
},
{
"domain": "sense",
"hostname": "sense-*",
"macaddress": "DCEFCA*"
},
{
"domain": "sense",
"hostname": "sense-*",
"macaddress": "A4D578*"
},
{
"domain": "senseme",
"macaddress": "20F85E*"
},
{
"domain": "sensibo",
"hostname": "sensibo*"
},
{
"domain": "simplisafe",
"hostname": "simplisafe*",
"macaddress": "30AEA4*"
},
{
"domain": "smartthings",
"hostname": "st*",
"macaddress": "24FD5B*"
},
{
"domain": "smartthings",
"hostname": "smartthings*",
"macaddress": "24FD5B*"
},
{
"domain": "smartthings",
"hostname": "hub*",
"macaddress": "24FD5B*"
},
{
"domain": "smartthings",
"hostname": "hub*",
"macaddress": "D052A8*"
},
{
"domain": "smartthings",
"hostname": "hub*",
"macaddress": "286D97*"
},
{
"domain": "solaredge",
"hostname": "target",
"macaddress": "002702*"
},
{
"domain": "somfy_mylink",
"hostname": "somfy_*",
"macaddress": "B8B7F1*"
},
{
"domain": "squeezebox",
"hostname": "squeezebox*",
"macaddress": "000420*"
},
{
"domain": "steamist",
"macaddress": "001E0C*",
"hostname": "my[45]50*"
},
{
"domain": "tado",
"hostname": "tado*"
},
{
"domain": "tesla_wall_connector",
"hostname": "teslawallconnector_*",
"macaddress": "DC44271*"
},
{
"domain": "tesla_wall_connector",
"hostname": "teslawallconnector_*",
"macaddress": "98ED5C*"
},
{
"domain": "tesla_wall_connector",
"hostname": "teslawallconnector_*",
"macaddress": "4CFCAA*"
},
{
"domain": "tolo",
"hostname": "usr-tcp232-ed2"
},
{
"domain": "toon",
"hostname": "eneco-*",
"macaddress": "74C63B*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "60A4B7*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "005F67*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "1027F5*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "403F8C*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "C0C9E3*"
},
{
"domain": "tplink",
"hostname": "ep*",
"macaddress": "E848B8*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "E848B8*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "909A4A*"
},
{
"domain": "tplink",
"hostname": "hs*",
"macaddress": "1C3BF3*"
},
{
"domain": "tplink",
"hostname": "hs*",
"macaddress": "50C7BF*"
},
{
"domain": "tplink",
"hostname": "hs*",
"macaddress": "68FF7B*"
},
{
"domain": "tplink",
"hostname": "hs*",
"macaddress": "98DAC4*"
},
{
"domain": "tplink",
"hostname": "hs*",
"macaddress": "B09575*"
},
{
"domain": "tplink",
"hostname": "hs*",
"macaddress": "C006C3*"
},
{
"domain": "tplink",
"hostname": "ep*",
"macaddress": "003192*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "003192*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "1C3BF3*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "50C7BF*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "68FF7B*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "98DAC4*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "B09575*"
},
{
"domain": "tplink",
"hostname": "k[lp]*",
"macaddress": "C006C3*"
},
{
"domain": "tplink",
"hostname": "lb*",
"macaddress": "1C3BF3*"
},
{
"domain": "tplink",
"hostname": "lb*",
"macaddress": "50C7BF*"
},
{
"domain": "tplink",
"hostname": "lb*",
"macaddress": "68FF7B*"
},
{
"domain": "tplink",
"hostname": "lb*",
"macaddress": "98DAC4*"
},
{
"domain": "tplink",
"hostname": "lb*",
"macaddress": "B09575*"
},
{
"domain": "tuya",
"macaddress": "105A17*"
},
{
"domain": "tuya",
"macaddress": "10D561*"
},
{
"domain": "tuya",
"macaddress": "1869D8*"
},
{
"domain": "tuya",
"macaddress": "381F8D*"
},
{
"domain": "tuya",
"macaddress": "508A06*"
},
{
"domain": "tuya",
"macaddress": "68572D*"
},
{
"domain": "tuya",
"macaddress": "708976*"
},
{
"domain": "tuya",
"macaddress": "7CF666*"
},
{
"domain": "tuya",
"macaddress": "84E342*"
},
{
"domain": "tuya",
"macaddress": "D4A651*"
},
{
"domain": "tuya",
"macaddress": "D81F12*"
},
{
"domain": "twinkly",
"hostname": "twinkly_*"
},
{
"domain": "unifiprotect",
"macaddress": "B4FBE4*"
},
{
"domain": "unifiprotect",
"macaddress": "802AA8*"
},
{
"domain": "unifiprotect",
"macaddress": "F09FC2*"
},
{
"domain": "unifiprotect",
"macaddress": "68D79A*"
},
{
"domain": "unifiprotect",
"macaddress": "18E829*"
},
{
"domain": "unifiprotect",
"macaddress": "245A4C*"
},
{
"domain": "unifiprotect",
"macaddress": "784558*"
},
{
"domain": "unifiprotect",
"macaddress": "E063DA*"
},
{
"domain": "unifiprotect",
"macaddress": "265A4C*"
},
{
"domain": "unifiprotect",
"macaddress": "74ACB9*"
},
{
"domain": "verisure",
"macaddress": "0023C1*"
},
{
"domain": "vicare",
"macaddress": "B87424*"
},
{
"domain": "wiz",
"macaddress": "A8BB50*"
},
{
"domain": "wiz",
"hostname": "wiz_*"
},
{
"domain": "yeelight",
"hostname": "yeelink-*"
}
]
DHCP: list[dict[str, str | bool]] = [
{'domain': 'august', 'hostname': 'connect', 'macaddress': 'D86162*'},
{'domain': 'august', 'hostname': 'connect', 'macaddress': 'B8B7F1*'},
{'domain': 'august', 'hostname': 'connect', 'macaddress': '2C9FFB*'},
{'domain': 'august', 'hostname': 'august*', 'macaddress': 'E076D0*'},
{'domain': 'axis', 'hostname': 'axis-00408c*', 'macaddress': '00408C*'},
{'domain': 'axis', 'hostname': 'axis-accc8e*', 'macaddress': 'ACCC8E*'},
{'domain': 'axis', 'hostname': 'axis-b8a44f*', 'macaddress': 'B8A44F*'},
{'domain': 'blink', 'hostname': 'blink*', 'macaddress': 'B85F98*'},
{'domain': 'blink', 'hostname': 'blink*', 'macaddress': '00037F*'},
{'domain': 'blink', 'hostname': 'blink*', 'macaddress': '20A171*'},
{'domain': 'broadlink', 'macaddress': '34EA34*'},
{'domain': 'broadlink', 'macaddress': '24DFA7*'},
{'domain': 'broadlink', 'macaddress': 'A043B0*'},
{'domain': 'broadlink', 'macaddress': 'B4430D*'},
{'domain': 'elkm1', 'macaddress': '00409D*'},
{'domain': 'emonitor', 'hostname': 'emonitor*', 'macaddress': '0090C2*'},
{'domain': 'flume', 'hostname': 'flume-gw-*'},
{'domain': 'flux_led', 'hostname': '[ba][lk]*', 'macaddress': '18B905*'},
{'domain': 'flux_led', 'hostname': '[ba][lk]*', 'macaddress': '249494*'},
{'domain': 'flux_led', 'hostname': '[ba][lk]*', 'macaddress': '7CB94C*'},
{'domain': 'flux_led', 'hostname': '[hba][flk]*', 'macaddress': 'ACCF23*'},
{'domain': 'flux_led', 'hostname': '[ba][lk]*', 'macaddress': 'B4E842*'},
{'domain': 'flux_led', 'hostname': '[hba][flk]*', 'macaddress': 'F0FE6B*'},
{'domain': 'flux_led', 'hostname': 'lwip*', 'macaddress': '8CCE4E*'},
{'domain': 'flux_led', 'hostname': 'zengge_[0-9a-f][0-9a-f]_*'},
{'domain': 'flux_led', 'hostname': 'sta*', 'macaddress': 'C82E47*'},
{'domain': 'fronius', 'macaddress': '0003AC*'},
{'domain': 'goalzero', 'hostname': 'yeti*'},
{'domain': 'gogogate2', 'hostname': 'ismartgate*'},
{'domain': 'guardian', 'hostname': 'gvc*', 'macaddress': '30AEA4*'},
{'domain': 'guardian', 'hostname': 'gvc*', 'macaddress': 'B4E62D*'},
{'domain': 'guardian', 'hostname': 'guardian*', 'macaddress': '30AEA4*'},
{'domain': 'hunterdouglas_powerview',
'hostname': 'hunter*',
'macaddress': '002674*'},
{'domain': 'isy994', 'hostname': 'isy*', 'macaddress': '0021B9*'},
{'domain': 'lyric', 'hostname': 'lyric-*', 'macaddress': '48A2E6*'},
{'domain': 'lyric', 'hostname': 'lyric-*', 'macaddress': 'B82CA0*'},
{'domain': 'lyric', 'hostname': 'lyric-*', 'macaddress': '00D02D*'},
{'domain': 'myq', 'macaddress': '645299*'},
{'domain': 'nest', 'macaddress': '18B430*'},
{'domain': 'nest', 'macaddress': '641666*'},
{'domain': 'nest', 'macaddress': 'D8EB46*'},
{'domain': 'nest', 'macaddress': '1C53F9*'},
{'domain': 'nexia', 'hostname': 'xl857-*', 'macaddress': '000231*'},
{'domain': 'nuheat', 'hostname': 'nuheat', 'macaddress': '002338*'},
{'domain': 'nuki', 'hostname': 'nuki_bridge_*'},
{'domain': 'oncue', 'hostname': 'kohlergen*', 'macaddress': '00146F*'},
{'domain': 'overkiz', 'hostname': 'gateway*', 'macaddress': 'F8811A*'},
{'domain': 'powerwall', 'hostname': '1118431-*'},
{'domain': 'rachio', 'hostname': 'rachio-*', 'macaddress': '009D6B*'},
{'domain': 'rachio', 'hostname': 'rachio-*', 'macaddress': 'F0038C*'},
{'domain': 'rachio', 'hostname': 'rachio-*', 'macaddress': '74C63B*'},
{'domain': 'rainforest_eagle', 'macaddress': 'D8D5B9*'},
{'domain': 'ring', 'hostname': 'ring*', 'macaddress': '0CAE7D*'},
{'domain': 'roomba', 'hostname': 'irobot-*', 'macaddress': '501479*'},
{'domain': 'roomba', 'hostname': 'roomba-*', 'macaddress': '80A589*'},
{'domain': 'roomba', 'hostname': 'roomba-*', 'macaddress': 'DCF505*'},
{'domain': 'samsungtv', 'hostname': 'tizen*'},
{'domain': 'samsungtv', 'macaddress': '8CC8CD*'},
{'domain': 'samsungtv', 'macaddress': '606BBD*'},
{'domain': 'samsungtv', 'macaddress': 'F47B5E*'},
{'domain': 'samsungtv', 'macaddress': '4844F7*'},
{'domain': 'screenlogic', 'hostname': 'pentair: *', 'macaddress': '00C033*'},
{'domain': 'sense', 'hostname': 'sense-*', 'macaddress': '009D6B*'},
{'domain': 'sense', 'hostname': 'sense-*', 'macaddress': 'DCEFCA*'},
{'domain': 'sense', 'hostname': 'sense-*', 'macaddress': 'A4D578*'},
{'domain': 'senseme', 'macaddress': '20F85E*'},
{'domain': 'sensibo', 'hostname': 'sensibo*'},
{'domain': 'simplisafe', 'hostname': 'simplisafe*', 'macaddress': '30AEA4*'},
{'domain': 'smartthings', 'hostname': 'st*', 'macaddress': '24FD5B*'},
{'domain': 'smartthings', 'hostname': 'smartthings*', 'macaddress': '24FD5B*'},
{'domain': 'smartthings', 'hostname': 'hub*', 'macaddress': '24FD5B*'},
{'domain': 'smartthings', 'hostname': 'hub*', 'macaddress': 'D052A8*'},
{'domain': 'smartthings', 'hostname': 'hub*', 'macaddress': '286D97*'},
{'domain': 'solaredge', 'hostname': 'target', 'macaddress': '002702*'},
{'domain': 'somfy_mylink', 'hostname': 'somfy_*', 'macaddress': 'B8B7F1*'},
{'domain': 'squeezebox', 'hostname': 'squeezebox*', 'macaddress': '000420*'},
{'domain': 'steamist', 'hostname': 'my[45]50*', 'macaddress': '001E0C*'},
{'domain': 'tado', 'hostname': 'tado*'},
{'domain': 'tesla_wall_connector',
'hostname': 'teslawallconnector_*',
'macaddress': 'DC44271*'},
{'domain': 'tesla_wall_connector',
'hostname': 'teslawallconnector_*',
'macaddress': '98ED5C*'},
{'domain': 'tesla_wall_connector',
'hostname': 'teslawallconnector_*',
'macaddress': '4CFCAA*'},
{'domain': 'tolo', 'hostname': 'usr-tcp232-ed2'},
{'domain': 'toon', 'hostname': 'eneco-*', 'macaddress': '74C63B*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': '60A4B7*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': '005F67*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': '1027F5*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': '403F8C*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': 'C0C9E3*'},
{'domain': 'tplink', 'hostname': 'ep*', 'macaddress': 'E848B8*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': 'E848B8*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': '909A4A*'},
{'domain': 'tplink', 'hostname': 'hs*', 'macaddress': '1C3BF3*'},
{'domain': 'tplink', 'hostname': 'hs*', 'macaddress': '50C7BF*'},
{'domain': 'tplink', 'hostname': 'hs*', 'macaddress': '68FF7B*'},
{'domain': 'tplink', 'hostname': 'hs*', 'macaddress': '98DAC4*'},
{'domain': 'tplink', 'hostname': 'hs*', 'macaddress': 'B09575*'},
{'domain': 'tplink', 'hostname': 'hs*', 'macaddress': 'C006C3*'},
{'domain': 'tplink', 'hostname': 'ep*', 'macaddress': '003192*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': '003192*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': '1C3BF3*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': '50C7BF*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': '68FF7B*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': '98DAC4*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': 'B09575*'},
{'domain': 'tplink', 'hostname': 'k[lp]*', 'macaddress': 'C006C3*'},
{'domain': 'tplink', 'hostname': 'lb*', 'macaddress': '1C3BF3*'},
{'domain': 'tplink', 'hostname': 'lb*', 'macaddress': '50C7BF*'},
{'domain': 'tplink', 'hostname': 'lb*', 'macaddress': '68FF7B*'},
{'domain': 'tplink', 'hostname': 'lb*', 'macaddress': '98DAC4*'},
{'domain': 'tplink', 'hostname': 'lb*', 'macaddress': 'B09575*'},
{'domain': 'tuya', 'macaddress': '105A17*'},
{'domain': 'tuya', 'macaddress': '10D561*'},
{'domain': 'tuya', 'macaddress': '1869D8*'},
{'domain': 'tuya', 'macaddress': '381F8D*'},
{'domain': 'tuya', 'macaddress': '508A06*'},
{'domain': 'tuya', 'macaddress': '68572D*'},
{'domain': 'tuya', 'macaddress': '708976*'},
{'domain': 'tuya', 'macaddress': '7CF666*'},
{'domain': 'tuya', 'macaddress': '84E342*'},
{'domain': 'tuya', 'macaddress': 'D4A651*'},
{'domain': 'tuya', 'macaddress': 'D81F12*'},
{'domain': 'twinkly', 'hostname': 'twinkly_*'},
{'domain': 'unifiprotect', 'macaddress': 'B4FBE4*'},
{'domain': 'unifiprotect', 'macaddress': '802AA8*'},
{'domain': 'unifiprotect', 'macaddress': 'F09FC2*'},
{'domain': 'unifiprotect', 'macaddress': '68D79A*'},
{'domain': 'unifiprotect', 'macaddress': '18E829*'},
{'domain': 'unifiprotect', 'macaddress': '245A4C*'},
{'domain': 'unifiprotect', 'macaddress': '784558*'},
{'domain': 'unifiprotect', 'macaddress': 'E063DA*'},
{'domain': 'unifiprotect', 'macaddress': '265A4C*'},
{'domain': 'unifiprotect', 'macaddress': '74ACB9*'},
{'domain': 'verisure', 'macaddress': '0023C1*'},
{'domain': 'vicare', 'macaddress': 'B87424*'},
{'domain': 'wiz', 'macaddress': 'A8BB50*'},
{'domain': 'wiz', 'hostname': 'wiz_*'},
{'domain': 'yeelight', 'hostname': 'yeelink-*'}]

View File

@ -82,7 +82,7 @@ class Manifest(TypedDict, total=False):
mqtt: list[str]
ssdp: list[dict[str, str]]
zeroconf: list[str | dict[str, str]]
dhcp: list[dict[str, str]]
dhcp: list[dict[str, bool | str]]
usb: list[dict[str, str]]
homekit: dict[str, list[str]]
is_built_in: bool
@ -228,9 +228,9 @@ async def async_get_zeroconf(
return zeroconf
async def async_get_dhcp(hass: HomeAssistant) -> list[dict[str, str]]:
async def async_get_dhcp(hass: HomeAssistant) -> list[dict[str, str | bool]]:
"""Return cached list of dhcp types."""
dhcp: list[dict[str, str]] = DHCP.copy()
dhcp: list[dict[str, str | bool]] = DHCP.copy()
integrations = await async_get_custom_components(hass)
for integration in integrations.values():
@ -474,7 +474,7 @@ class Integration:
return self.manifest.get("zeroconf")
@property
def dhcp(self) -> list[dict[str, str]] | None:
def dhcp(self) -> list[dict[str, str | bool]] | None:
"""Return Integration dhcp entries."""
return self.manifest.get("dhcp")

View File

@ -1,7 +1,8 @@
"""Generate dhcp file."""
from __future__ import annotations
import json
import pprint
import re
from .model import Config, Integration
@ -10,10 +11,11 @@ BASE = """
To update, run python3 -m script.hassfest
\"\"\"
from __future__ import annotations
# fmt: off
DHCP = {}
DHCP: list[dict[str, str | bool]] = {}
""".strip()
@ -35,7 +37,14 @@ def generate_and_validate(integrations: list[dict[str, str]]):
for entry in match_types:
match_list.append({"domain": domain, **entry})
return BASE.format(json.dumps(match_list, indent=4))
# JSON will format `True` as `true`
# re.sub for flake8 E128
formatted = pprint.pformat(match_list)
formatted_aligned_continuation = re.sub(r"^\[\{", "[\n {", formatted)
formatted_align_indent = re.sub(
r"(?m)^ ", " ", formatted_aligned_continuation, flags=re.MULTILINE, count=0
)
return BASE.format(formatted_align_indent)
def validate(integrations: dict[str, Integration], config: Config):

View File

@ -218,6 +218,7 @@ MANIFEST_SCHEMA = vol.Schema(
str, verify_uppercase, verify_wildcard
),
vol.Optional("hostname"): vol.All(str, verify_lowercase),
vol.Optional("registered_devices"): cv.boolean,
}
)
],

View File

@ -25,10 +25,11 @@ from homeassistant.const import (
STATE_HOME,
STATE_NOT_HOME,
)
import homeassistant.helpers.device_registry as dr
from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util
from tests.common import async_fire_time_changed
from tests.common import MockConfigEntry, async_fire_time_changed
# connect b8:b7:f1:6d:b5:33 192.168.210.56
RAW_DHCP_REQUEST = (
@ -207,6 +208,52 @@ async def test_dhcp_renewal_match_hostname_and_macaddress(hass):
)
async def test_registered_devices(hass):
"""Test discovery flows are created for registered devices."""
integration_matchers = [
{"domain": "not-matching", "registered_devices": True},
{"domain": "mock-domain", "registered_devices": True},
]
packet = Ether(RAW_DHCP_RENEWAL)
registry = dr.async_get(hass)
config_entry = MockConfigEntry(domain="mock-domain", data={})
config_entry.add_to_hass(hass)
registry.async_get_or_create(
config_entry_id=config_entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, "50147903852c")},
name="name",
)
# Not enabled should not get flows
config_entry2 = MockConfigEntry(domain="mock-domain-2", data={})
config_entry2.add_to_hass(hass)
registry.async_get_or_create(
config_entry_id=config_entry2.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, "50147903852c")},
name="name",
)
async_handle_dhcp_packet = await _async_get_handle_dhcp_packet(
hass, integration_matchers
)
with patch.object(hass.config_entries.flow, "async_init") as mock_init:
await async_handle_dhcp_packet(packet)
# Ensure no change is ignored
await async_handle_dhcp_packet(packet)
assert len(mock_init.mock_calls) == 1
assert mock_init.mock_calls[0][1][0] == "mock-domain"
assert mock_init.mock_calls[0][2]["context"] == {
"source": config_entries.SOURCE_DHCP
}
assert mock_init.mock_calls[0][2]["data"] == dhcp.DhcpServiceInfo(
ip="192.168.1.120",
hostname="irobot-ae9ec12dd3b04885bcbfa36afb01e1cc",
macaddress="50147903852c",
)
async def test_dhcp_match_hostname(hass):
"""Test matching based on hostname only."""
integration_matchers = [{"domain": "mock-domain", "hostname": "connect"}]

View File

@ -203,6 +203,7 @@ def test_integration_properties(hass):
{"hostname": "tesla_*", "macaddress": "4CFCAA*"},
{"hostname": "tesla_*", "macaddress": "044EAF*"},
{"hostname": "tesla_*", "macaddress": "98ED5C*"},
{"registered_devices": True},
],
"usb": [
{"vid": "10C4", "pid": "EA60"},
@ -233,6 +234,7 @@ def test_integration_properties(hass):
{"hostname": "tesla_*", "macaddress": "4CFCAA*"},
{"hostname": "tesla_*", "macaddress": "044EAF*"},
{"hostname": "tesla_*", "macaddress": "98ED5C*"},
{"registered_devices": True},
]
assert integration.usb == [
{"vid": "10C4", "pid": "EA60"},