Use zeroconf attributes (A-D) (#58835)
Co-authored-by: epenet <epenet@users.noreply.github.com>
This commit is contained in:
parent
26055e1f14
commit
e983370c27
11 changed files with 78 additions and 50 deletions
|
@ -9,17 +9,13 @@ from pyatv.convert import protocol_str
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.const import (
|
||||
CONF_ADDRESS,
|
||||
CONF_NAME,
|
||||
CONF_PIN,
|
||||
CONF_PROTOCOL,
|
||||
CONF_TYPE,
|
||||
)
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.const import CONF_ADDRESS, CONF_NAME, CONF_PIN, CONF_PROTOCOL
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.data_entry_flow import AbortFlow
|
||||
from homeassistant.data_entry_flow import AbortFlow, FlowResult
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.typing import DiscoveryInfoType
|
||||
|
||||
from .const import CONF_CREDENTIALS, CONF_IDENTIFIER, CONF_START_OFF, DOMAIN
|
||||
|
||||
|
@ -148,16 +144,18 @@ class AppleTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
description_placeholders={"devices": self._devices_str()},
|
||||
)
|
||||
|
||||
async def async_step_zeroconf(self, discovery_info):
|
||||
async def async_step_zeroconf(
|
||||
self, discovery_info: DiscoveryInfoType
|
||||
) -> FlowResult:
|
||||
"""Handle device found via zeroconf."""
|
||||
service_type = discovery_info[CONF_TYPE]
|
||||
properties = discovery_info["properties"]
|
||||
service_type = discovery_info[zeroconf.ATTR_TYPE]
|
||||
properties = discovery_info[zeroconf.ATTR_PROPERTIES]
|
||||
|
||||
if service_type == "_mediaremotetv._tcp.local.":
|
||||
identifier = properties["UniqueIdentifier"]
|
||||
name = properties["Name"]
|
||||
elif service_type == "_touch-able._tcp.local.":
|
||||
identifier = discovery_info["name"].split(".")[0]
|
||||
identifier = discovery_info[zeroconf.ATTR_NAME].split(".")[0]
|
||||
name = properties["CtlN"]
|
||||
else:
|
||||
return self.async_abort(reason="unknown")
|
||||
|
|
|
@ -6,6 +6,7 @@ from urllib.parse import urlsplit
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.components.dhcp import HOSTNAME, IP_ADDRESS, MAC_ADDRESS
|
||||
from homeassistant.config_entries import SOURCE_IGNORE
|
||||
from homeassistant.const import (
|
||||
|
@ -17,7 +18,9 @@ from homeassistant.const import (
|
|||
CONF_USERNAME,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
from homeassistant.helpers.typing import DiscoveryInfoType
|
||||
from homeassistant.util.network import is_link_local
|
||||
|
||||
from .const import (
|
||||
|
@ -174,14 +177,18 @@ class AxisFlowHandler(config_entries.ConfigFlow, domain=AXIS_DOMAIN):
|
|||
}
|
||||
)
|
||||
|
||||
async def async_step_zeroconf(self, discovery_info: dict):
|
||||
async def async_step_zeroconf(
|
||||
self, discovery_info: DiscoveryInfoType
|
||||
) -> FlowResult:
|
||||
"""Prepare configuration for a Zeroconf discovered Axis device."""
|
||||
return await self._process_discovered_device(
|
||||
{
|
||||
CONF_HOST: discovery_info[CONF_HOST],
|
||||
CONF_MAC: format_mac(discovery_info["properties"]["macaddress"]),
|
||||
CONF_NAME: discovery_info["name"].split(".", 1)[0],
|
||||
CONF_PORT: discovery_info[CONF_PORT],
|
||||
CONF_HOST: discovery_info[zeroconf.ATTR_HOST],
|
||||
CONF_MAC: format_mac(
|
||||
discovery_info[zeroconf.ATTR_PROPERTIES]["macaddress"]
|
||||
),
|
||||
CONF_NAME: discovery_info[zeroconf.ATTR_NAME].split(".", 1)[0],
|
||||
CONF_PORT: discovery_info[zeroconf.ATTR_PORT],
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ from bond_api import Bond
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries, exceptions
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_HOST, CONF_NAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
@ -94,8 +95,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
self, discovery_info: DiscoveryInfoType
|
||||
) -> FlowResult:
|
||||
"""Handle a flow initialized by zeroconf discovery."""
|
||||
name: str = discovery_info[CONF_NAME]
|
||||
host: str = discovery_info[CONF_HOST]
|
||||
name: str = discovery_info[zeroconf.ATTR_NAME]
|
||||
host: str = discovery_info[zeroconf.ATTR_HOST]
|
||||
bond_id = name.partition(".")[0]
|
||||
await self.async_set_unique_id(bond_id)
|
||||
for entry in self._async_current_entries():
|
||||
|
|
|
@ -12,7 +12,7 @@ from boschshcpy.exceptions import (
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries, core
|
||||
from homeassistant.components.zeroconf import async_get_instance
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_TOKEN
|
||||
|
||||
from .const import (
|
||||
|
@ -40,7 +40,7 @@ def write_tls_asset(hass: core.HomeAssistant, filename: str, asset: bytes) -> No
|
|||
file_handle.write(asset.decode("utf-8"))
|
||||
|
||||
|
||||
def create_credentials_and_validate(hass, host, user_input, zeroconf):
|
||||
def create_credentials_and_validate(hass, host, user_input, zeroconf_instance):
|
||||
"""Create and store credentials and validate session."""
|
||||
helper = SHCRegisterClient(host, user_input[CONF_PASSWORD])
|
||||
result = helper.register(host, "HomeAssistant")
|
||||
|
@ -54,21 +54,21 @@ def create_credentials_and_validate(hass, host, user_input, zeroconf):
|
|||
hass.config.path(DOMAIN, CONF_SHC_CERT),
|
||||
hass.config.path(DOMAIN, CONF_SHC_KEY),
|
||||
True,
|
||||
zeroconf,
|
||||
zeroconf_instance,
|
||||
)
|
||||
session.authenticate()
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_info_from_host(hass, host, zeroconf):
|
||||
def get_info_from_host(hass, host, zeroconf_instance):
|
||||
"""Get information from host."""
|
||||
session = SHCSession(
|
||||
host,
|
||||
"",
|
||||
"",
|
||||
True,
|
||||
zeroconf,
|
||||
zeroconf_instance,
|
||||
)
|
||||
information = session.mdns_info()
|
||||
return {"title": information.name, "unique_id": information.unique_id}
|
||||
|
@ -123,14 +123,14 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
"""Handle the credentials step."""
|
||||
errors = {}
|
||||
if user_input is not None:
|
||||
zeroconf = await async_get_instance(self.hass)
|
||||
zeroconf_instance = await zeroconf.async_get_instance(self.hass)
|
||||
try:
|
||||
result = await self.hass.async_add_executor_job(
|
||||
create_credentials_and_validate,
|
||||
self.hass,
|
||||
self.host,
|
||||
user_input,
|
||||
zeroconf,
|
||||
zeroconf_instance,
|
||||
)
|
||||
except SHCAuthenticationError:
|
||||
errors["base"] = "invalid_auth"
|
||||
|
@ -183,14 +183,14 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
|
||||
async def async_step_zeroconf(self, discovery_info):
|
||||
"""Handle zeroconf discovery."""
|
||||
if not discovery_info.get("name", "").startswith("Bosch SHC"):
|
||||
if not discovery_info.get(zeroconf.ATTR_NAME, "").startswith("Bosch SHC"):
|
||||
return self.async_abort(reason="not_bosch_shc")
|
||||
|
||||
try:
|
||||
hosts = (
|
||||
discovery_info["host"]
|
||||
if isinstance(discovery_info["host"], list)
|
||||
else [discovery_info["host"]]
|
||||
discovery_info[zeroconf.ATTR_HOST]
|
||||
if isinstance(discovery_info[zeroconf.ATTR_HOST], list)
|
||||
else [discovery_info[zeroconf.ATTR_HOST]]
|
||||
)
|
||||
for host in hosts:
|
||||
if host.startswith("169."): # skip link local address
|
||||
|
@ -202,7 +202,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
except SHCConnectionError:
|
||||
return self.async_abort(reason="cannot_connect")
|
||||
|
||||
local_name = discovery_info["hostname"][:-1]
|
||||
local_name = discovery_info[zeroconf.ATTR_HOSTNAME][:-1]
|
||||
node_name = local_name[: -len(".local")]
|
||||
|
||||
await self.async_set_unique_id(self.info["unique_id"])
|
||||
|
@ -227,11 +227,11 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
|
||||
async def _get_info(self, host):
|
||||
"""Get additional information."""
|
||||
zeroconf = await async_get_instance(self.hass)
|
||||
zeroconf_instance = await zeroconf.async_get_instance(self.hass)
|
||||
|
||||
return await self.hass.async_add_executor_job(
|
||||
get_info_from_host,
|
||||
self.hass,
|
||||
host,
|
||||
zeroconf,
|
||||
zeroconf_instance,
|
||||
)
|
||||
|
|
|
@ -9,6 +9,7 @@ from brother import Brother, SnmpError, UnsupportedModel
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries, exceptions
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.const import CONF_HOST, CONF_TYPE
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers.typing import DiscoveryInfoType
|
||||
|
@ -84,13 +85,13 @@ class BrotherConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
) -> FlowResult:
|
||||
"""Handle zeroconf discovery."""
|
||||
# Hostname is format: brother.local.
|
||||
self.host = discovery_info["hostname"].rstrip(".")
|
||||
self.host = discovery_info[zeroconf.ATTR_HOSTNAME].rstrip(".")
|
||||
|
||||
# Do not probe the device if the host is already configured
|
||||
self._async_abort_entries_match({CONF_HOST: self.host})
|
||||
|
||||
snmp_engine = get_snmp_engine(self.hass)
|
||||
model = discovery_info.get("properties", {}).get("product")
|
||||
model = discovery_info.get(zeroconf.ATTR_PROPERTIES, {}).get("product")
|
||||
|
||||
try:
|
||||
self.brother = Brother(self.host, snmp_engine=snmp_engine, model=model)
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.typing import DiscoveryInfoType
|
||||
|
||||
from .const import CONF_IGNORE_CEC, CONF_KNOWN_HOSTS, CONF_UUID, DOMAIN
|
||||
|
||||
|
@ -49,7 +51,9 @@ class FlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
|
||||
return await self.async_step_config()
|
||||
|
||||
async def async_step_zeroconf(self, discovery_info):
|
||||
async def async_step_zeroconf(
|
||||
self, discovery_info: DiscoveryInfoType
|
||||
) -> FlowResult:
|
||||
"""Handle a flow initialized by zeroconf discovery."""
|
||||
if self._async_in_progress() or self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
|
|
@ -10,7 +10,10 @@ from pydaikin.discovery import Discovery
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.const import CONF_API_KEY, CONF_HOST, CONF_PASSWORD
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers.typing import DiscoveryInfoType
|
||||
|
||||
from .const import CONF_UUID, DOMAIN, KEY_MAC, TIMEOUT
|
||||
|
||||
|
@ -123,18 +126,20 @@ class FlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
user_input.get(CONF_PASSWORD),
|
||||
)
|
||||
|
||||
async def async_step_zeroconf(self, discovery_info):
|
||||
async def async_step_zeroconf(
|
||||
self, discovery_info: DiscoveryInfoType
|
||||
) -> FlowResult:
|
||||
"""Prepare configuration for a discovered Daikin device."""
|
||||
_LOGGER.debug("Zeroconf user_input: %s", discovery_info)
|
||||
devices = Discovery().poll(ip=discovery_info[CONF_HOST])
|
||||
devices = Discovery().poll(ip=discovery_info[zeroconf.ATTR_HOST])
|
||||
if not devices:
|
||||
_LOGGER.debug(
|
||||
"Could not find MAC-address for %s,"
|
||||
" make sure the required UDP ports are open (see integration documentation)",
|
||||
discovery_info[CONF_HOST],
|
||||
discovery_info[zeroconf.ATTR_HOST],
|
||||
)
|
||||
return self.async_abort(reason="cannot_connect")
|
||||
await self.async_set_unique_id(next(iter(devices))[KEY_MAC])
|
||||
self._abort_if_unique_id_configured()
|
||||
self.host = discovery_info[CONF_HOST]
|
||||
self.host = discovery_info[zeroconf.ATTR_HOST]
|
||||
return await self.async_step_user()
|
||||
|
|
|
@ -6,6 +6,7 @@ from typing import Any
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import callback
|
||||
|
@ -49,7 +50,10 @@ class DevoloHomeControlFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
) -> FlowResult:
|
||||
"""Handle zeroconf discovery."""
|
||||
# Check if it is a gateway
|
||||
if discovery_info.get("properties", {}).get("MT") in SUPPORTED_MODEL_TYPES:
|
||||
if (
|
||||
discovery_info.get(zeroconf.ATTR_PROPERTIES, {}).get("MT")
|
||||
in SUPPORTED_MODEL_TYPES
|
||||
):
|
||||
await self._async_handle_discovery_without_unique_id()
|
||||
return await self.async_step_zeroconf_confirm()
|
||||
return self.async_abort(reason="Not a devolo Home Control gateway.")
|
||||
|
|
|
@ -77,17 +77,17 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
self, discovery_info: DiscoveryInfoType
|
||||
) -> FlowResult:
|
||||
"""Handle zerooconf discovery."""
|
||||
if discovery_info["properties"]["MT"] in ["2600", "2601"]:
|
||||
if discovery_info[zeroconf.ATTR_PROPERTIES]["MT"] in ["2600", "2601"]:
|
||||
return self.async_abort(reason="home_control")
|
||||
|
||||
await self.async_set_unique_id(discovery_info["properties"]["SN"])
|
||||
await self.async_set_unique_id(discovery_info[zeroconf.ATTR_PROPERTIES]["SN"])
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
|
||||
self.context[CONF_HOST] = discovery_info["host"]
|
||||
self.context[CONF_HOST] = discovery_info[zeroconf.ATTR_HOST]
|
||||
self.context["title_placeholders"] = {
|
||||
PRODUCT: discovery_info["properties"]["Product"],
|
||||
CONF_NAME: discovery_info["hostname"].split(".")[0],
|
||||
PRODUCT: discovery_info[zeroconf.ATTR_PROPERTIES]["Product"],
|
||||
CONF_NAME: discovery_info[zeroconf.ATTR_HOSTNAME].split(".")[0],
|
||||
}
|
||||
|
||||
return await self.async_step_zeroconf_confirm()
|
||||
|
|
|
@ -8,8 +8,11 @@ import requests
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries, core, exceptions
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers.typing import DiscoveryInfoType
|
||||
from homeassistant.util.network import is_link_local
|
||||
|
||||
from .const import CONF_EVENTS, DOMAIN, DOORBIRD_OUI
|
||||
|
@ -90,10 +93,12 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
data = self.discovery_schema or _schema_with_defaults()
|
||||
return self.async_show_form(step_id="user", data_schema=data, errors=errors)
|
||||
|
||||
async def async_step_zeroconf(self, discovery_info):
|
||||
async def async_step_zeroconf(
|
||||
self, discovery_info: DiscoveryInfoType
|
||||
) -> FlowResult:
|
||||
"""Prepare configuration for a discovered doorbird device."""
|
||||
macaddress = discovery_info["properties"]["macaddress"]
|
||||
host = discovery_info[CONF_HOST]
|
||||
macaddress = discovery_info[zeroconf.ATTR_PROPERTIES]["macaddress"]
|
||||
host = discovery_info[zeroconf.ATTR_HOST]
|
||||
|
||||
if macaddress[:6] != DOORBIRD_OUI:
|
||||
return self.async_abort(reason="not_doorbird_device")
|
||||
|
@ -109,7 +114,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
return self.async_abort(reason="not_doorbird_device")
|
||||
|
||||
chop_ending = "._axis-video._tcp.local."
|
||||
friendly_hostname = discovery_info["name"]
|
||||
friendly_hostname = discovery_info[zeroconf.ATTR_NAME]
|
||||
if friendly_hostname.endswith(chop_ending):
|
||||
friendly_hostname = friendly_hostname[: -len(chop_ending)]
|
||||
|
||||
|
|
|
@ -63,8 +63,11 @@ MAX_NAME_LEN = 63
|
|||
|
||||
# Attributes for HaServiceInfo
|
||||
ATTR_HOST: Final = "host"
|
||||
ATTR_HOSTNAME: Final = "hostname"
|
||||
ATTR_NAME: Final = "name"
|
||||
ATTR_PORT: Final = "port"
|
||||
ATTR_PROPERTIES: Final = "properties"
|
||||
ATTR_TYPE: Final = "type"
|
||||
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
|
|
Loading…
Add table
Reference in a new issue