Use zeroconf attributes (A-D) (#58835)

Co-authored-by: epenet <epenet@users.noreply.github.com>
This commit is contained in:
epenet 2021-11-02 18:27:06 +01:00 committed by GitHub
parent 26055e1f14
commit e983370c27
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 78 additions and 50 deletions

View file

@ -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")

View file

@ -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],
}
)

View file

@ -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():

View file

@ -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,
)

View file

@ -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)

View file

@ -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")

View file

@ -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()

View file

@ -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.")

View file

@ -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()

View file

@ -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)]

View file

@ -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(