Add support for discovery via DHCP (#45087)

* Add support for discovery via DHCP

* additional tesla ouis

* merge tests

* dhcp test

* merge requirements test

* dhcp test

* dhcp discovery

* dhcp discovery

* pylint

* pylint

* pylint

* fix

* Add matching tests

* 100% cover

* cleanup

* fix codespell

* Update exception handling

* remove unneeded comment

* fix options handling exception

* fix options handling exception
This commit is contained in:
J. Nick Koston
2021-01-13 22:09:08 -10:00
committed by GitHub
parent 402a0ea7da
commit da677f7d5a
38 changed files with 843 additions and 17 deletions
+2
View File
@@ -9,6 +9,7 @@ from . import (
config_flow,
coverage,
dependencies,
dhcp,
json,
manifest,
mqtt,
@@ -31,6 +32,7 @@ INTEGRATION_PLUGINS = [
ssdp,
translations,
zeroconf,
dhcp,
]
HASS_PLUGINS = [
coverage,
+7
View File
@@ -48,6 +48,11 @@ def validate_integration(config: Config, integration: Integration):
"config_flow",
"Zeroconf information in a manifest requires a config flow to exist",
)
if integration.manifest.get("dhcp"):
integration.add_error(
"config_flow",
"DHCP information in a manifest requires a config flow to exist",
)
return
config_flow = config_flow_file.read_text()
@@ -59,6 +64,7 @@ def validate_integration(config: Config, integration: Integration):
or "async_step_mqtt" in config_flow
or "async_step_ssdp" in config_flow
or "async_step_zeroconf" in config_flow
or "async_step_dhcp" in config_flow
)
if not needs_unique_id:
@@ -100,6 +106,7 @@ def generate_and_validate(integrations: Dict[str, Integration], config: Config):
or integration.manifest.get("mqtt")
or integration.manifest.get("ssdp")
or integration.manifest.get("zeroconf")
or integration.manifest.get("dhcp")
):
continue
+63
View File
@@ -0,0 +1,63 @@
"""Generate dhcp file."""
import json
from typing import Dict, List
from .model import Config, Integration
BASE = """
\"\"\"Automatically generated by hassfest.
To update, run python3 -m script.hassfest
\"\"\"
# fmt: off
DHCP = {}
""".strip()
def generate_and_validate(integrations: List[Dict[str, str]]):
"""Validate and generate dhcp data."""
match_list = []
for domain in sorted(integrations):
integration = integrations[domain]
if not integration.manifest:
continue
match_types = integration.manifest.get("dhcp", [])
if not match_types:
continue
for entry in match_types:
match_list.append({"domain": domain, **entry})
return BASE.format(json.dumps(match_list, indent=4))
def validate(integrations: Dict[str, Integration], config: Config):
"""Validate dhcp file."""
dhcp_path = config.root / "homeassistant/generated/dhcp.py"
config.cache["dhcp"] = content = generate_and_validate(integrations)
if config.specific_integrations:
return
with open(str(dhcp_path)) as fp:
current = fp.read().strip()
if current != content:
config.add_error(
"dhcp",
"File dhcp.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)
return
def generate(integrations: Dict[str, Integration], config: Config):
"""Generate dhcp file."""
dhcp_path = config.root / "homeassistant/generated/dhcp.py"
with open(str(dhcp_path), "w") as fp:
fp.write(f"{config.cache['dhcp']}\n")
+8
View File
@@ -71,6 +71,14 @@ MANIFEST_SCHEMA = vol.Schema(
vol.All([vol.All(vol.Schema({}, extra=vol.ALLOW_EXTRA), vol.Length(min=1))])
),
vol.Optional("homekit"): vol.Schema({vol.Optional("models"): [str]}),
vol.Optional("dhcp"): [
vol.Schema(
{
vol.Optional("macaddress"): vol.All(str, verify_uppercase),
vol.Optional("hostname"): vol.All(str, verify_lowercase),
}
)
],
vol.Required("documentation"): vol.All(
vol.Url(), documentation_url # pylint: disable=no-value-for-parameter
),