Use HA uuid
as client_id
in BraviaTV (#79618)
* Use uuid as clientid/nickname * Fixes after rebase * Move gen_instance_ids() to utils * Store client_id and nickname in config_entry * Update tests * Clean names * Rename consts
This commit is contained in:
parent
33bdc67a61
commit
9dd9147343
5 changed files with 59 additions and 20 deletions
|
@ -7,11 +7,11 @@ from aiohttp import CookieJar
|
|||
from pybravia import BraviaTV
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PIN, Platform
|
||||
from homeassistant.const import CONF_HOST, CONF_MAC, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
||||
|
||||
from .const import CONF_IGNORED_SOURCES, CONF_USE_PSK, DOMAIN
|
||||
from .const import CONF_IGNORED_SOURCES, DOMAIN
|
||||
from .coordinator import BraviaTVCoordinator
|
||||
|
||||
PLATFORMS: Final[list[Platform]] = [
|
||||
|
@ -25,8 +25,6 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||
"""Set up a config entry."""
|
||||
host = config_entry.data[CONF_HOST]
|
||||
mac = config_entry.data[CONF_MAC]
|
||||
pin = config_entry.data[CONF_PIN]
|
||||
use_psk = config_entry.data.get(CONF_USE_PSK, False)
|
||||
ignored_sources = config_entry.options.get(CONF_IGNORED_SOURCES, [])
|
||||
|
||||
session = async_create_clientsession(
|
||||
|
@ -36,8 +34,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||
coordinator = BraviaTVCoordinator(
|
||||
hass=hass,
|
||||
client=client,
|
||||
pin=pin,
|
||||
use_psk=use_psk,
|
||||
config=config_entry.data,
|
||||
ignored_sources=ignored_sources,
|
||||
)
|
||||
config_entry.async_on_unload(config_entry.add_update_listener(update_listener))
|
||||
|
|
|
@ -15,6 +15,7 @@ from homeassistant.config_entries import ConfigEntry
|
|||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME, CONF_PIN
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers import instance_id
|
||||
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.util.network import is_host_valid
|
||||
|
@ -24,11 +25,12 @@ from .const import (
|
|||
ATTR_CID,
|
||||
ATTR_MAC,
|
||||
ATTR_MODEL,
|
||||
CLIENTID_PREFIX,
|
||||
CONF_CLIENT_ID,
|
||||
CONF_IGNORED_SOURCES,
|
||||
CONF_NICKNAME,
|
||||
CONF_USE_PSK,
|
||||
DOMAIN,
|
||||
NICKNAME,
|
||||
NICKNAME_PREFIX,
|
||||
)
|
||||
|
||||
|
||||
|
@ -42,6 +44,8 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
self.client: BraviaTV | None = None
|
||||
self.device_config: dict[str, Any] = {}
|
||||
self.entry: ConfigEntry | None = None
|
||||
self.client_id: str = ""
|
||||
self.nickname: str = ""
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
|
@ -68,8 +72,10 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
if use_psk:
|
||||
await self.client.connect(psk=pin)
|
||||
else:
|
||||
self.device_config[CONF_CLIENT_ID] = self.client_id
|
||||
self.device_config[CONF_NICKNAME] = self.nickname
|
||||
await self.client.connect(
|
||||
pin=pin, clientid=CLIENTID_PREFIX, nickname=NICKNAME
|
||||
pin=pin, clientid=self.client_id, nickname=self.nickname
|
||||
)
|
||||
await self.client.set_wol_mode(True)
|
||||
|
||||
|
@ -110,6 +116,7 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
) -> FlowResult:
|
||||
"""Authorize Bravia TV device."""
|
||||
errors: dict[str, str] = {}
|
||||
self.client_id, self.nickname = await self.gen_instance_ids()
|
||||
|
||||
if user_input is not None:
|
||||
self.device_config[CONF_PIN] = user_input[CONF_PIN]
|
||||
|
@ -126,7 +133,7 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
assert self.client
|
||||
|
||||
try:
|
||||
await self.client.pair(CLIENTID_PREFIX, NICKNAME)
|
||||
await self.client.pair(self.client_id, self.nickname)
|
||||
except BraviaTVError:
|
||||
return self.async_abort(reason="no_ip_control")
|
||||
|
||||
|
@ -190,6 +197,7 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
) -> FlowResult:
|
||||
"""Dialog that informs the user that reauth is required."""
|
||||
self.create_client()
|
||||
client_id, nickname = await self.gen_instance_ids()
|
||||
|
||||
assert self.client is not None
|
||||
assert self.entry is not None
|
||||
|
@ -201,8 +209,10 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
if use_psk:
|
||||
await self.client.connect(psk=pin)
|
||||
else:
|
||||
self.device_config[CONF_CLIENT_ID] = client_id
|
||||
self.device_config[CONF_NICKNAME] = nickname
|
||||
await self.client.connect(
|
||||
pin=pin, clientid=CLIENTID_PREFIX, nickname=NICKNAME
|
||||
pin=pin, clientid=client_id, nickname=nickname
|
||||
)
|
||||
await self.client.set_wol_mode(True)
|
||||
except BraviaTVError:
|
||||
|
@ -215,7 +225,7 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
return self.async_abort(reason="reauth_successful")
|
||||
|
||||
try:
|
||||
await self.client.pair(CLIENTID_PREFIX, NICKNAME)
|
||||
await self.client.pair(client_id, nickname)
|
||||
except BraviaTVError:
|
||||
return self.async_abort(reason="reauth_unsuccessful")
|
||||
|
||||
|
@ -229,6 +239,11 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
),
|
||||
)
|
||||
|
||||
async def gen_instance_ids(self) -> tuple[str, str]:
|
||||
"""Generate client_id and nickname."""
|
||||
uuid = await instance_id.async_get(self.hass)
|
||||
return uuid, f"{NICKNAME_PREFIX} {uuid[:6]}"
|
||||
|
||||
|
||||
class BraviaTVOptionsFlowHandler(config_entries.OptionsFlow):
|
||||
"""Config flow options for Bravia TV."""
|
||||
|
|
|
@ -8,9 +8,11 @@ ATTR_MAC: Final = "macAddr"
|
|||
ATTR_MANUFACTURER: Final = "Sony"
|
||||
ATTR_MODEL: Final = "model"
|
||||
|
||||
CONF_CLIENT_ID: Final = "client_id"
|
||||
CONF_IGNORED_SOURCES: Final = "ignored_sources"
|
||||
CONF_NICKNAME: Final = "nickname"
|
||||
CONF_USE_PSK: Final = "use_psk"
|
||||
|
||||
CLIENTID_PREFIX: Final = "HomeAssistant"
|
||||
DOMAIN: Final = "braviatv"
|
||||
NICKNAME: Final = "Home Assistant"
|
||||
LEGACY_CLIENT_ID: Final = "HomeAssistant"
|
||||
NICKNAME_PREFIX: Final = "Home Assistant"
|
||||
|
|
|
@ -5,6 +5,7 @@ from collections.abc import Awaitable, Callable, Coroutine, Iterable
|
|||
from datetime import timedelta
|
||||
from functools import wraps
|
||||
import logging
|
||||
from types import MappingProxyType
|
||||
from typing import Any, Final, TypeVar
|
||||
|
||||
from pybravia import (
|
||||
|
@ -19,12 +20,20 @@ from pybravia import (
|
|||
from typing_extensions import Concatenate, ParamSpec
|
||||
|
||||
from homeassistant.components.media_player import MediaType
|
||||
from homeassistant.const import CONF_PIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed
|
||||
from homeassistant.helpers.debounce import Debouncer
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
from .const import CLIENTID_PREFIX, DOMAIN, NICKNAME
|
||||
from .const import (
|
||||
CONF_CLIENT_ID,
|
||||
CONF_NICKNAME,
|
||||
CONF_USE_PSK,
|
||||
DOMAIN,
|
||||
LEGACY_CLIENT_ID,
|
||||
NICKNAME_PREFIX,
|
||||
)
|
||||
|
||||
_BraviaTVCoordinatorT = TypeVar("_BraviaTVCoordinatorT", bound="BraviaTVCoordinator")
|
||||
_P = ParamSpec("_P")
|
||||
|
@ -61,15 +70,16 @@ class BraviaTVCoordinator(DataUpdateCoordinator[None]):
|
|||
self,
|
||||
hass: HomeAssistant,
|
||||
client: BraviaTV,
|
||||
pin: str,
|
||||
use_psk: bool,
|
||||
config: MappingProxyType[str, Any],
|
||||
ignored_sources: list[str],
|
||||
) -> None:
|
||||
"""Initialize Bravia TV Client."""
|
||||
|
||||
self.client = client
|
||||
self.pin = pin
|
||||
self.use_psk = use_psk
|
||||
self.pin = config[CONF_PIN]
|
||||
self.use_psk = config.get(CONF_USE_PSK, False)
|
||||
self.client_id = config.get(CONF_CLIENT_ID, LEGACY_CLIENT_ID)
|
||||
self.nickname = config.get(CONF_NICKNAME, NICKNAME_PREFIX)
|
||||
self.ignored_sources = ignored_sources
|
||||
self.source: str | None = None
|
||||
self.source_list: list[str] = []
|
||||
|
@ -119,7 +129,7 @@ class BraviaTVCoordinator(DataUpdateCoordinator[None]):
|
|||
await self.client.connect(psk=self.pin)
|
||||
else:
|
||||
await self.client.connect(
|
||||
pin=self.pin, clientid=CLIENTID_PREFIX, nickname=NICKNAME
|
||||
pin=self.pin, clientid=self.client_id, nickname=self.nickname
|
||||
)
|
||||
self.connected = True
|
||||
|
||||
|
|
|
@ -12,12 +12,16 @@ import pytest
|
|||
from homeassistant import data_entry_flow
|
||||
from homeassistant.components import ssdp
|
||||
from homeassistant.components.braviatv.const import (
|
||||
CONF_CLIENT_ID,
|
||||
CONF_IGNORED_SOURCES,
|
||||
CONF_NICKNAME,
|
||||
CONF_USE_PSK,
|
||||
DOMAIN,
|
||||
NICKNAME_PREFIX,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, SOURCE_SSDP, SOURCE_USER
|
||||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PIN
|
||||
from homeassistant.helpers import instance_id
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
@ -93,6 +97,7 @@ async def test_show_form(hass):
|
|||
|
||||
async def test_ssdp_discovery(hass):
|
||||
"""Test that the device is discovered."""
|
||||
uuid = await instance_id.async_get(hass)
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_SSDP},
|
||||
|
@ -129,6 +134,8 @@ async def test_ssdp_discovery(hass):
|
|||
CONF_PIN: "1234",
|
||||
CONF_USE_PSK: False,
|
||||
CONF_MAC: "AA:BB:CC:DD:EE:FF",
|
||||
CONF_CLIENT_ID: uuid,
|
||||
CONF_NICKNAME: f"{NICKNAME_PREFIX} {uuid[:6]}",
|
||||
}
|
||||
|
||||
|
||||
|
@ -270,6 +277,8 @@ async def test_duplicate_error(hass):
|
|||
|
||||
async def test_create_entry(hass):
|
||||
"""Test that the user step works."""
|
||||
uuid = await instance_id.async_get(hass)
|
||||
|
||||
with patch("pybravia.BraviaTV.connect"), patch("pybravia.BraviaTV.pair"), patch(
|
||||
"pybravia.BraviaTV.set_wol_mode"
|
||||
), patch(
|
||||
|
@ -297,11 +306,15 @@ async def test_create_entry(hass):
|
|||
CONF_PIN: "1234",
|
||||
CONF_USE_PSK: False,
|
||||
CONF_MAC: "AA:BB:CC:DD:EE:FF",
|
||||
CONF_CLIENT_ID: uuid,
|
||||
CONF_NICKNAME: f"{NICKNAME_PREFIX} {uuid[:6]}",
|
||||
}
|
||||
|
||||
|
||||
async def test_create_entry_with_ipv6_address(hass):
|
||||
"""Test that the user step works with device IPv6 address."""
|
||||
uuid = await instance_id.async_get(hass)
|
||||
|
||||
with patch("pybravia.BraviaTV.connect"), patch("pybravia.BraviaTV.pair"), patch(
|
||||
"pybravia.BraviaTV.set_wol_mode"
|
||||
), patch(
|
||||
|
@ -331,6 +344,8 @@ async def test_create_entry_with_ipv6_address(hass):
|
|||
CONF_PIN: "1234",
|
||||
CONF_USE_PSK: False,
|
||||
CONF_MAC: "AA:BB:CC:DD:EE:FF",
|
||||
CONF_CLIENT_ID: uuid,
|
||||
CONF_NICKNAME: f"{NICKNAME_PREFIX} {uuid[:6]}",
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue