mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
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
@ -7,11 +7,11 @@ from aiohttp import CookieJar
|
|||||||
from pybravia import BraviaTV
|
from pybravia import BraviaTV
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
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.core import HomeAssistant
|
||||||
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
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
|
from .coordinator import BraviaTVCoordinator
|
||||||
|
|
||||||
PLATFORMS: Final[list[Platform]] = [
|
PLATFORMS: Final[list[Platform]] = [
|
||||||
@ -25,8 +25,6 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||||||
"""Set up a config entry."""
|
"""Set up a config entry."""
|
||||||
host = config_entry.data[CONF_HOST]
|
host = config_entry.data[CONF_HOST]
|
||||||
mac = config_entry.data[CONF_MAC]
|
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, [])
|
ignored_sources = config_entry.options.get(CONF_IGNORED_SOURCES, [])
|
||||||
|
|
||||||
session = async_create_clientsession(
|
session = async_create_clientsession(
|
||||||
@ -36,8 +34,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
|
|||||||
coordinator = BraviaTVCoordinator(
|
coordinator = BraviaTVCoordinator(
|
||||||
hass=hass,
|
hass=hass,
|
||||||
client=client,
|
client=client,
|
||||||
pin=pin,
|
config=config_entry.data,
|
||||||
use_psk=use_psk,
|
|
||||||
ignored_sources=ignored_sources,
|
ignored_sources=ignored_sources,
|
||||||
)
|
)
|
||||||
config_entry.async_on_unload(config_entry.add_update_listener(update_listener))
|
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.const import CONF_HOST, CONF_MAC, CONF_NAME, CONF_PIN
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
|
from homeassistant.helpers import instance_id
|
||||||
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
from homeassistant.helpers.aiohttp_client import async_create_clientsession
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.util.network import is_host_valid
|
from homeassistant.util.network import is_host_valid
|
||||||
@ -24,11 +25,12 @@ from .const import (
|
|||||||
ATTR_CID,
|
ATTR_CID,
|
||||||
ATTR_MAC,
|
ATTR_MAC,
|
||||||
ATTR_MODEL,
|
ATTR_MODEL,
|
||||||
CLIENTID_PREFIX,
|
CONF_CLIENT_ID,
|
||||||
CONF_IGNORED_SOURCES,
|
CONF_IGNORED_SOURCES,
|
||||||
|
CONF_NICKNAME,
|
||||||
CONF_USE_PSK,
|
CONF_USE_PSK,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
NICKNAME,
|
NICKNAME_PREFIX,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -42,6 +44,8 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
self.client: BraviaTV | None = None
|
self.client: BraviaTV | None = None
|
||||||
self.device_config: dict[str, Any] = {}
|
self.device_config: dict[str, Any] = {}
|
||||||
self.entry: ConfigEntry | None = None
|
self.entry: ConfigEntry | None = None
|
||||||
|
self.client_id: str = ""
|
||||||
|
self.nickname: str = ""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@callback
|
@callback
|
||||||
@ -68,8 +72,10 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
if use_psk:
|
if use_psk:
|
||||||
await self.client.connect(psk=pin)
|
await self.client.connect(psk=pin)
|
||||||
else:
|
else:
|
||||||
|
self.device_config[CONF_CLIENT_ID] = self.client_id
|
||||||
|
self.device_config[CONF_NICKNAME] = self.nickname
|
||||||
await self.client.connect(
|
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)
|
await self.client.set_wol_mode(True)
|
||||||
|
|
||||||
@ -110,6 +116,7 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Authorize Bravia TV device."""
|
"""Authorize Bravia TV device."""
|
||||||
errors: dict[str, str] = {}
|
errors: dict[str, str] = {}
|
||||||
|
self.client_id, self.nickname = await self.gen_instance_ids()
|
||||||
|
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
self.device_config[CONF_PIN] = user_input[CONF_PIN]
|
self.device_config[CONF_PIN] = user_input[CONF_PIN]
|
||||||
@ -126,7 +133,7 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
assert self.client
|
assert self.client
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await self.client.pair(CLIENTID_PREFIX, NICKNAME)
|
await self.client.pair(self.client_id, self.nickname)
|
||||||
except BraviaTVError:
|
except BraviaTVError:
|
||||||
return self.async_abort(reason="no_ip_control")
|
return self.async_abort(reason="no_ip_control")
|
||||||
|
|
||||||
@ -190,6 +197,7 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Dialog that informs the user that reauth is required."""
|
"""Dialog that informs the user that reauth is required."""
|
||||||
self.create_client()
|
self.create_client()
|
||||||
|
client_id, nickname = await self.gen_instance_ids()
|
||||||
|
|
||||||
assert self.client is not None
|
assert self.client is not None
|
||||||
assert self.entry is not None
|
assert self.entry is not None
|
||||||
@ -201,8 +209,10 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
if use_psk:
|
if use_psk:
|
||||||
await self.client.connect(psk=pin)
|
await self.client.connect(psk=pin)
|
||||||
else:
|
else:
|
||||||
|
self.device_config[CONF_CLIENT_ID] = client_id
|
||||||
|
self.device_config[CONF_NICKNAME] = nickname
|
||||||
await self.client.connect(
|
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)
|
await self.client.set_wol_mode(True)
|
||||||
except BraviaTVError:
|
except BraviaTVError:
|
||||||
@ -215,7 +225,7 @@ class BraviaTVConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
return self.async_abort(reason="reauth_successful")
|
return self.async_abort(reason="reauth_successful")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await self.client.pair(CLIENTID_PREFIX, NICKNAME)
|
await self.client.pair(client_id, nickname)
|
||||||
except BraviaTVError:
|
except BraviaTVError:
|
||||||
return self.async_abort(reason="reauth_unsuccessful")
|
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):
|
class BraviaTVOptionsFlowHandler(config_entries.OptionsFlow):
|
||||||
"""Config flow options for Bravia TV."""
|
"""Config flow options for Bravia TV."""
|
||||||
|
@ -8,9 +8,11 @@ ATTR_MAC: Final = "macAddr"
|
|||||||
ATTR_MANUFACTURER: Final = "Sony"
|
ATTR_MANUFACTURER: Final = "Sony"
|
||||||
ATTR_MODEL: Final = "model"
|
ATTR_MODEL: Final = "model"
|
||||||
|
|
||||||
|
CONF_CLIENT_ID: Final = "client_id"
|
||||||
CONF_IGNORED_SOURCES: Final = "ignored_sources"
|
CONF_IGNORED_SOURCES: Final = "ignored_sources"
|
||||||
|
CONF_NICKNAME: Final = "nickname"
|
||||||
CONF_USE_PSK: Final = "use_psk"
|
CONF_USE_PSK: Final = "use_psk"
|
||||||
|
|
||||||
CLIENTID_PREFIX: Final = "HomeAssistant"
|
|
||||||
DOMAIN: Final = "braviatv"
|
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 datetime import timedelta
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
import logging
|
import logging
|
||||||
|
from types import MappingProxyType
|
||||||
from typing import Any, Final, TypeVar
|
from typing import Any, Final, TypeVar
|
||||||
|
|
||||||
from pybravia import (
|
from pybravia import (
|
||||||
@ -19,12 +20,20 @@ from pybravia import (
|
|||||||
from typing_extensions import Concatenate, ParamSpec
|
from typing_extensions import Concatenate, ParamSpec
|
||||||
|
|
||||||
from homeassistant.components.media_player import MediaType
|
from homeassistant.components.media_player import MediaType
|
||||||
|
from homeassistant.const import CONF_PIN
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryAuthFailed
|
from homeassistant.exceptions import ConfigEntryAuthFailed
|
||||||
from homeassistant.helpers.debounce import Debouncer
|
from homeassistant.helpers.debounce import Debouncer
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
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")
|
_BraviaTVCoordinatorT = TypeVar("_BraviaTVCoordinatorT", bound="BraviaTVCoordinator")
|
||||||
_P = ParamSpec("_P")
|
_P = ParamSpec("_P")
|
||||||
@ -61,15 +70,16 @@ class BraviaTVCoordinator(DataUpdateCoordinator[None]):
|
|||||||
self,
|
self,
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
client: BraviaTV,
|
client: BraviaTV,
|
||||||
pin: str,
|
config: MappingProxyType[str, Any],
|
||||||
use_psk: bool,
|
|
||||||
ignored_sources: list[str],
|
ignored_sources: list[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize Bravia TV Client."""
|
"""Initialize Bravia TV Client."""
|
||||||
|
|
||||||
self.client = client
|
self.client = client
|
||||||
self.pin = pin
|
self.pin = config[CONF_PIN]
|
||||||
self.use_psk = use_psk
|
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.ignored_sources = ignored_sources
|
||||||
self.source: str | None = None
|
self.source: str | None = None
|
||||||
self.source_list: list[str] = []
|
self.source_list: list[str] = []
|
||||||
@ -119,7 +129,7 @@ class BraviaTVCoordinator(DataUpdateCoordinator[None]):
|
|||||||
await self.client.connect(psk=self.pin)
|
await self.client.connect(psk=self.pin)
|
||||||
else:
|
else:
|
||||||
await self.client.connect(
|
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
|
self.connected = True
|
||||||
|
|
||||||
|
@ -12,12 +12,16 @@ import pytest
|
|||||||
from homeassistant import data_entry_flow
|
from homeassistant import data_entry_flow
|
||||||
from homeassistant.components import ssdp
|
from homeassistant.components import ssdp
|
||||||
from homeassistant.components.braviatv.const import (
|
from homeassistant.components.braviatv.const import (
|
||||||
|
CONF_CLIENT_ID,
|
||||||
CONF_IGNORED_SOURCES,
|
CONF_IGNORED_SOURCES,
|
||||||
|
CONF_NICKNAME,
|
||||||
CONF_USE_PSK,
|
CONF_USE_PSK,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
NICKNAME_PREFIX,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import SOURCE_REAUTH, SOURCE_SSDP, SOURCE_USER
|
from homeassistant.config_entries import SOURCE_REAUTH, SOURCE_SSDP, SOURCE_USER
|
||||||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PIN
|
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PIN
|
||||||
|
from homeassistant.helpers import instance_id
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
@ -93,6 +97,7 @@ async def test_show_form(hass):
|
|||||||
|
|
||||||
async def test_ssdp_discovery(hass):
|
async def test_ssdp_discovery(hass):
|
||||||
"""Test that the device is discovered."""
|
"""Test that the device is discovered."""
|
||||||
|
uuid = await instance_id.async_get(hass)
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": SOURCE_SSDP},
|
context={"source": SOURCE_SSDP},
|
||||||
@ -129,6 +134,8 @@ async def test_ssdp_discovery(hass):
|
|||||||
CONF_PIN: "1234",
|
CONF_PIN: "1234",
|
||||||
CONF_USE_PSK: False,
|
CONF_USE_PSK: False,
|
||||||
CONF_MAC: "AA:BB:CC:DD:EE:FF",
|
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):
|
async def test_create_entry(hass):
|
||||||
"""Test that the user step works."""
|
"""Test that the user step works."""
|
||||||
|
uuid = await instance_id.async_get(hass)
|
||||||
|
|
||||||
with patch("pybravia.BraviaTV.connect"), patch("pybravia.BraviaTV.pair"), patch(
|
with patch("pybravia.BraviaTV.connect"), patch("pybravia.BraviaTV.pair"), patch(
|
||||||
"pybravia.BraviaTV.set_wol_mode"
|
"pybravia.BraviaTV.set_wol_mode"
|
||||||
), patch(
|
), patch(
|
||||||
@ -297,11 +306,15 @@ async def test_create_entry(hass):
|
|||||||
CONF_PIN: "1234",
|
CONF_PIN: "1234",
|
||||||
CONF_USE_PSK: False,
|
CONF_USE_PSK: False,
|
||||||
CONF_MAC: "AA:BB:CC:DD:EE:FF",
|
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):
|
async def test_create_entry_with_ipv6_address(hass):
|
||||||
"""Test that the user step works with device IPv6 address."""
|
"""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(
|
with patch("pybravia.BraviaTV.connect"), patch("pybravia.BraviaTV.pair"), patch(
|
||||||
"pybravia.BraviaTV.set_wol_mode"
|
"pybravia.BraviaTV.set_wol_mode"
|
||||||
), patch(
|
), patch(
|
||||||
@ -331,6 +344,8 @@ async def test_create_entry_with_ipv6_address(hass):
|
|||||||
CONF_PIN: "1234",
|
CONF_PIN: "1234",
|
||||||
CONF_USE_PSK: False,
|
CONF_USE_PSK: False,
|
||||||
CONF_MAC: "AA:BB:CC:DD:EE:FF",
|
CONF_MAC: "AA:BB:CC:DD:EE:FF",
|
||||||
|
CONF_CLIENT_ID: uuid,
|
||||||
|
CONF_NICKNAME: f"{NICKNAME_PREFIX} {uuid[:6]}",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user