core/homeassistant/components/bang_olufsen/config_flow.py

185 lines
5.9 KiB
Python
Raw Normal View History

Add bang_olufsen integration (#93462) * Add bangolufsen integration * add untested files to .coveragerc * Simplify integration to media_player platform * Remove missing files from .coveragerc * Add beolink_set_relative_volume custom service Tweaks * Remove custom services Remove grouping as it was dependent on custom services * Update API to 3.2.1.150.0 Reduce and optimize code with feedback from joostlek Tweaks * Updated testing * Remove unused options schema * Fix bugfix setting wrong state * Fix wrong initial state * Bump API * Fix Beosound Level not reconnecting properly * Remove unused constant * Fix wrong variable checked to determine source * Update integration with feedback from emontnemery * Update integration with feedback from emontnemery * Remove unused code * Move API client into dataclass Fix not all config_flow exceptions caught Tweaks * Add Bang & Olufsen brand * Revert "Add Bang & Olufsen brand" This reverts commit 57b2722078ae0b563880306c6457d2cf3f528070. * Remove volume options from setup Simplify device checks rename integration to bang_olufsen update tests to pass Update API * Remove _device from base Add _device to websocket * Move SW version device update to websocket Sort websocket variables * Add WebSocket connection test * Remove unused constants * Remove confirmation form Make discovered devices get added to Home Assistant immediately Fix device not being available on mdns discovery Change config flow aborts to forms with error * Update tests for new config_flow Add missing api_exception test * Restrict manual and discovered IP addresses to IPv4 * Re-add confirmation step for zeroconf discovery Improve error messages Move exception mapping dict to module level * Enable remote control WebSocket listener * Update tests
2024-01-24 11:00:51 +00:00
"""Config flow for the Bang & Olufsen integration."""
Add bang_olufsen integration (#93462) * Add bangolufsen integration * add untested files to .coveragerc * Simplify integration to media_player platform * Remove missing files from .coveragerc * Add beolink_set_relative_volume custom service Tweaks * Remove custom services Remove grouping as it was dependent on custom services * Update API to 3.2.1.150.0 Reduce and optimize code with feedback from joostlek Tweaks * Updated testing * Remove unused options schema * Fix bugfix setting wrong state * Fix wrong initial state * Bump API * Fix Beosound Level not reconnecting properly * Remove unused constant * Fix wrong variable checked to determine source * Update integration with feedback from emontnemery * Update integration with feedback from emontnemery * Remove unused code * Move API client into dataclass Fix not all config_flow exceptions caught Tweaks * Add Bang & Olufsen brand * Revert "Add Bang & Olufsen brand" This reverts commit 57b2722078ae0b563880306c6457d2cf3f528070. * Remove volume options from setup Simplify device checks rename integration to bang_olufsen update tests to pass Update API * Remove _device from base Add _device to websocket * Move SW version device update to websocket Sort websocket variables * Add WebSocket connection test * Remove unused constants * Remove confirmation form Make discovered devices get added to Home Assistant immediately Fix device not being available on mdns discovery Change config flow aborts to forms with error * Update tests for new config_flow Add missing api_exception test * Restrict manual and discovered IP addresses to IPv4 * Re-add confirmation step for zeroconf discovery Improve error messages Move exception mapping dict to module level * Enable remote control WebSocket listener * Update tests
2024-01-24 11:00:51 +00:00
from __future__ import annotations
from ipaddress import AddressValueError, IPv4Address
from typing import Any, TypedDict
from aiohttp.client_exceptions import ClientConnectorError
from mozart_api.exceptions import ApiException
from mozart_api.mozart_client import MozartClient
import voluptuous as vol
from homeassistant.components.zeroconf import ZeroconfServiceInfo
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
Add bang_olufsen integration (#93462) * Add bangolufsen integration * add untested files to .coveragerc * Simplify integration to media_player platform * Remove missing files from .coveragerc * Add beolink_set_relative_volume custom service Tweaks * Remove custom services Remove grouping as it was dependent on custom services * Update API to 3.2.1.150.0 Reduce and optimize code with feedback from joostlek Tweaks * Updated testing * Remove unused options schema * Fix bugfix setting wrong state * Fix wrong initial state * Bump API * Fix Beosound Level not reconnecting properly * Remove unused constant * Fix wrong variable checked to determine source * Update integration with feedback from emontnemery * Update integration with feedback from emontnemery * Remove unused code * Move API client into dataclass Fix not all config_flow exceptions caught Tweaks * Add Bang & Olufsen brand * Revert "Add Bang & Olufsen brand" This reverts commit 57b2722078ae0b563880306c6457d2cf3f528070. * Remove volume options from setup Simplify device checks rename integration to bang_olufsen update tests to pass Update API * Remove _device from base Add _device to websocket * Move SW version device update to websocket Sort websocket variables * Add WebSocket connection test * Remove unused constants * Remove confirmation form Make discovered devices get added to Home Assistant immediately Fix device not being available on mdns discovery Change config flow aborts to forms with error * Update tests for new config_flow Add missing api_exception test * Restrict manual and discovered IP addresses to IPv4 * Re-add confirmation step for zeroconf discovery Improve error messages Move exception mapping dict to module level * Enable remote control WebSocket listener * Update tests
2024-01-24 11:00:51 +00:00
from homeassistant.const import CONF_HOST, CONF_MODEL
from homeassistant.helpers.selector import SelectSelector, SelectSelectorConfig
from .const import (
ATTR_FRIENDLY_NAME,
ATTR_ITEM_NUMBER,
ATTR_SERIAL_NUMBER,
ATTR_TYPE_NUMBER,
COMPATIBLE_MODELS,
CONF_SERIAL_NUMBER,
DEFAULT_MODEL,
DOMAIN,
)
class EntryData(TypedDict, total=False):
"""TypedDict for config_entry data."""
host: str
jid: str
model: str
name: str
# Map exception types to strings
_exception_map = {
ApiException: "api_exception",
ClientConnectorError: "client_connector_error",
TimeoutError: "timeout_error",
AddressValueError: "invalid_ip",
}
class BangOlufsenConfigFlowHandler(ConfigFlow, domain=DOMAIN):
"""Handle a config flow."""
_beolink_jid = ""
_client: MozartClient
_host = ""
_model = ""
_name = ""
_serial_number = ""
def __init__(self) -> None:
"""Init the config flow."""
VERSION = 1
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
Add bang_olufsen integration (#93462) * Add bangolufsen integration * add untested files to .coveragerc * Simplify integration to media_player platform * Remove missing files from .coveragerc * Add beolink_set_relative_volume custom service Tweaks * Remove custom services Remove grouping as it was dependent on custom services * Update API to 3.2.1.150.0 Reduce and optimize code with feedback from joostlek Tweaks * Updated testing * Remove unused options schema * Fix bugfix setting wrong state * Fix wrong initial state * Bump API * Fix Beosound Level not reconnecting properly * Remove unused constant * Fix wrong variable checked to determine source * Update integration with feedback from emontnemery * Update integration with feedback from emontnemery * Remove unused code * Move API client into dataclass Fix not all config_flow exceptions caught Tweaks * Add Bang & Olufsen brand * Revert "Add Bang & Olufsen brand" This reverts commit 57b2722078ae0b563880306c6457d2cf3f528070. * Remove volume options from setup Simplify device checks rename integration to bang_olufsen update tests to pass Update API * Remove _device from base Add _device to websocket * Move SW version device update to websocket Sort websocket variables * Add WebSocket connection test * Remove unused constants * Remove confirmation form Make discovered devices get added to Home Assistant immediately Fix device not being available on mdns discovery Change config flow aborts to forms with error * Update tests for new config_flow Add missing api_exception test * Restrict manual and discovered IP addresses to IPv4 * Re-add confirmation step for zeroconf discovery Improve error messages Move exception mapping dict to module level * Enable remote control WebSocket listener * Update tests
2024-01-24 11:00:51 +00:00
"""Handle the initial step."""
data_schema = vol.Schema(
{
vol.Required(CONF_HOST): str,
vol.Required(CONF_MODEL, default=DEFAULT_MODEL): SelectSelector(
SelectSelectorConfig(options=COMPATIBLE_MODELS)
),
}
)
if user_input is not None:
self._host = user_input[CONF_HOST]
self._model = user_input[CONF_MODEL]
# Check if the IP address is a valid IPv4 address.
try:
IPv4Address(self._host)
except AddressValueError as error:
return self.async_show_form(
step_id="user",
data_schema=data_schema,
errors={"base": _exception_map[type(error)]},
)
self._client = MozartClient(self._host)
# Try to get information from Beolink self method.
async with self._client:
try:
beolink_self = await self._client.get_beolink_self(
_request_timeout=3
)
except (
ApiException,
ClientConnectorError,
TimeoutError,
) as error:
return self.async_show_form(
step_id="user",
data_schema=data_schema,
errors={"base": _exception_map[type(error)]},
)
self._beolink_jid = beolink_self.jid
self._serial_number = beolink_self.jid.split(".")[2].split("@")[0]
await self.async_set_unique_id(self._serial_number)
self._abort_if_unique_id_configured()
return await self._create_entry()
return self.async_show_form(
step_id="user",
data_schema=data_schema,
)
async def async_step_zeroconf(
self, discovery_info: ZeroconfServiceInfo
) -> ConfigFlowResult:
Add bang_olufsen integration (#93462) * Add bangolufsen integration * add untested files to .coveragerc * Simplify integration to media_player platform * Remove missing files from .coveragerc * Add beolink_set_relative_volume custom service Tweaks * Remove custom services Remove grouping as it was dependent on custom services * Update API to 3.2.1.150.0 Reduce and optimize code with feedback from joostlek Tweaks * Updated testing * Remove unused options schema * Fix bugfix setting wrong state * Fix wrong initial state * Bump API * Fix Beosound Level not reconnecting properly * Remove unused constant * Fix wrong variable checked to determine source * Update integration with feedback from emontnemery * Update integration with feedback from emontnemery * Remove unused code * Move API client into dataclass Fix not all config_flow exceptions caught Tweaks * Add Bang & Olufsen brand * Revert "Add Bang & Olufsen brand" This reverts commit 57b2722078ae0b563880306c6457d2cf3f528070. * Remove volume options from setup Simplify device checks rename integration to bang_olufsen update tests to pass Update API * Remove _device from base Add _device to websocket * Move SW version device update to websocket Sort websocket variables * Add WebSocket connection test * Remove unused constants * Remove confirmation form Make discovered devices get added to Home Assistant immediately Fix device not being available on mdns discovery Change config flow aborts to forms with error * Update tests for new config_flow Add missing api_exception test * Restrict manual and discovered IP addresses to IPv4 * Re-add confirmation step for zeroconf discovery Improve error messages Move exception mapping dict to module level * Enable remote control WebSocket listener * Update tests
2024-01-24 11:00:51 +00:00
"""Handle discovery using Zeroconf."""
# Check if the discovered device is a Mozart device
if ATTR_FRIENDLY_NAME not in discovery_info.properties:
return self.async_abort(reason="not_mozart_device")
# Ensure that an IPv4 address is received
self._host = discovery_info.host
try:
IPv4Address(self._host)
except AddressValueError:
return self.async_abort(reason="ipv6_address")
self._model = discovery_info.hostname[:-16].replace("-", " ")
self._serial_number = discovery_info.properties[ATTR_SERIAL_NUMBER]
self._beolink_jid = f"{discovery_info.properties[ATTR_TYPE_NUMBER]}.{discovery_info.properties[ATTR_ITEM_NUMBER]}.{self._serial_number}@products.bang-olufsen.com"
await self.async_set_unique_id(self._serial_number)
self._abort_if_unique_id_configured(updates={CONF_HOST: self._host})
# Set the discovered device title
self.context["title_placeholders"] = {
"name": discovery_info.properties[ATTR_FRIENDLY_NAME]
}
return await self.async_step_zeroconf_confirm()
async def _create_entry(self) -> ConfigFlowResult:
Add bang_olufsen integration (#93462) * Add bangolufsen integration * add untested files to .coveragerc * Simplify integration to media_player platform * Remove missing files from .coveragerc * Add beolink_set_relative_volume custom service Tweaks * Remove custom services Remove grouping as it was dependent on custom services * Update API to 3.2.1.150.0 Reduce and optimize code with feedback from joostlek Tweaks * Updated testing * Remove unused options schema * Fix bugfix setting wrong state * Fix wrong initial state * Bump API * Fix Beosound Level not reconnecting properly * Remove unused constant * Fix wrong variable checked to determine source * Update integration with feedback from emontnemery * Update integration with feedback from emontnemery * Remove unused code * Move API client into dataclass Fix not all config_flow exceptions caught Tweaks * Add Bang & Olufsen brand * Revert "Add Bang & Olufsen brand" This reverts commit 57b2722078ae0b563880306c6457d2cf3f528070. * Remove volume options from setup Simplify device checks rename integration to bang_olufsen update tests to pass Update API * Remove _device from base Add _device to websocket * Move SW version device update to websocket Sort websocket variables * Add WebSocket connection test * Remove unused constants * Remove confirmation form Make discovered devices get added to Home Assistant immediately Fix device not being available on mdns discovery Change config flow aborts to forms with error * Update tests for new config_flow Add missing api_exception test * Restrict manual and discovered IP addresses to IPv4 * Re-add confirmation step for zeroconf discovery Improve error messages Move exception mapping dict to module level * Enable remote control WebSocket listener * Update tests
2024-01-24 11:00:51 +00:00
"""Create the config entry for a discovered or manually configured Bang & Olufsen device."""
# Ensure that created entities have a unique and easily identifiable id and not a "friendly name"
self._name = f"{self._model}-{self._serial_number}"
return self.async_create_entry(
title=self._name,
data=EntryData(
host=self._host,
jid=self._beolink_jid,
model=self._model,
name=self._name,
),
)
async def async_step_zeroconf_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
Add bang_olufsen integration (#93462) * Add bangolufsen integration * add untested files to .coveragerc * Simplify integration to media_player platform * Remove missing files from .coveragerc * Add beolink_set_relative_volume custom service Tweaks * Remove custom services Remove grouping as it was dependent on custom services * Update API to 3.2.1.150.0 Reduce and optimize code with feedback from joostlek Tweaks * Updated testing * Remove unused options schema * Fix bugfix setting wrong state * Fix wrong initial state * Bump API * Fix Beosound Level not reconnecting properly * Remove unused constant * Fix wrong variable checked to determine source * Update integration with feedback from emontnemery * Update integration with feedback from emontnemery * Remove unused code * Move API client into dataclass Fix not all config_flow exceptions caught Tweaks * Add Bang & Olufsen brand * Revert "Add Bang & Olufsen brand" This reverts commit 57b2722078ae0b563880306c6457d2cf3f528070. * Remove volume options from setup Simplify device checks rename integration to bang_olufsen update tests to pass Update API * Remove _device from base Add _device to websocket * Move SW version device update to websocket Sort websocket variables * Add WebSocket connection test * Remove unused constants * Remove confirmation form Make discovered devices get added to Home Assistant immediately Fix device not being available on mdns discovery Change config flow aborts to forms with error * Update tests for new config_flow Add missing api_exception test * Restrict manual and discovered IP addresses to IPv4 * Re-add confirmation step for zeroconf discovery Improve error messages Move exception mapping dict to module level * Enable remote control WebSocket listener * Update tests
2024-01-24 11:00:51 +00:00
"""Confirm the configuration of the device."""
if user_input is not None:
return await self._create_entry()
self._set_confirm_only()
return self.async_show_form(
step_id="zeroconf_confirm",
description_placeholders={
CONF_HOST: self._host,
CONF_MODEL: self._model,
CONF_SERIAL_NUMBER: self._serial_number,
},
last_step=True,
)