Skip to content

Commit

Permalink
Redesign and refactor Bravia TV config_flow (home-assistant#84832)
Browse files Browse the repository at this point in the history
fixes undefined
  • Loading branch information
Drafteed authored and frenck committed Dec 30, 2022
1 parent 0e0677b commit 80ac4c0
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 225 deletions.
158 changes: 86 additions & 72 deletions homeassistant/components/braviatv/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ def __init__(self) -> None:
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
Expand All @@ -62,8 +60,13 @@ def create_client(self) -> None:
)
self.client = BraviaTV(host=host, session=session)

async def async_create_device(self) -> FlowResult:
"""Initialize and create Bravia TV device from config."""
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]}"

async def async_connect_device(self) -> None:
"""Connect to Bravia TV device from config."""
assert self.client

pin = self.device_config[CONF_PIN]
Expand All @@ -72,13 +75,16 @@ async def async_create_device(self) -> FlowResult:
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=self.client_id, nickname=self.nickname
)
client_id = self.device_config[CONF_CLIENT_ID]
nickname = self.device_config[CONF_NICKNAME]
await self.client.connect(pin=pin, clientid=client_id, nickname=nickname)
await self.client.set_wol_mode(True)

async def async_create_device(self) -> FlowResult:
"""Create Bravia TV device from config."""
assert self.client
await self.async_connect_device()

system_info = await self.client.get_system_info()
cid = system_info[ATTR_CID].lower()
title = system_info[ATTR_MODEL]
Expand All @@ -90,6 +96,16 @@ async def async_create_device(self) -> FlowResult:

return self.async_create_entry(title=title, data=self.device_config)

async def async_reauth_device(self) -> FlowResult:
"""Reauthorize Bravia TV device from config."""
assert self.entry
assert self.client
await self.async_connect_device()

self.hass.config_entries.async_update_entry(self.entry, data=self.device_config)
await self.hass.config_entries.async_reload(self.entry.entry_id)
return self.async_abort(reason="reauth_successful")

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
Expand All @@ -100,28 +116,51 @@ async def async_step_user(
host = user_input[CONF_HOST]
if is_host_valid(host):
self.device_config[CONF_HOST] = host
self.create_client()
return await self.async_step_authorize()

errors[CONF_HOST] = "invalid_host"

return self.async_show_form(
step_id="user",
data_schema=vol.Schema({vol.Required(CONF_HOST, default=""): str}),
data_schema=vol.Schema({vol.Required(CONF_HOST): str}),
errors=errors,
)

async def async_step_authorize(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Authorize Bravia TV device."""
"""Handle authorize step."""
self.create_client()

if user_input is not None:
self.device_config[CONF_USE_PSK] = user_input[CONF_USE_PSK]
if user_input[CONF_USE_PSK]:
return await self.async_step_psk()
return await self.async_step_pin()

return self.async_show_form(
step_id="authorize",
data_schema=vol.Schema(
{
vol.Required(CONF_USE_PSK, default=False): bool,
}
),
)

async def async_step_pin(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle PIN authorize step."""
errors: dict[str, str] = {}
self.client_id, self.nickname = await self.gen_instance_ids()
client_id, nickname = await self.gen_instance_ids()

if user_input is not None:
self.device_config[CONF_PIN] = user_input[CONF_PIN]
self.device_config[CONF_USE_PSK] = user_input[CONF_USE_PSK]
self.device_config[CONF_CLIENT_ID] = client_id
self.device_config[CONF_NICKNAME] = nickname
try:
if self.entry:
return await self.async_reauth_device()
return await self.async_create_device()
except BraviaTVAuthError:
errors["base"] = "invalid_auth"
Expand All @@ -133,16 +172,44 @@ async def async_step_authorize(
assert self.client

try:
await self.client.pair(self.client_id, self.nickname)
await self.client.pair(client_id, nickname)
except BraviaTVError:
return self.async_abort(reason="no_ip_control")

return self.async_show_form(
step_id="authorize",
step_id="pin",
data_schema=vol.Schema(
{
vol.Required(CONF_PIN, default=""): str,
vol.Required(CONF_USE_PSK, default=False): bool,
vol.Required(CONF_PIN): str,
}
),
errors=errors,
)

async def async_step_psk(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle PSK authorize step."""
errors: dict[str, str] = {}

if user_input is not None:
self.device_config[CONF_PIN] = user_input[CONF_PIN]
try:
if self.entry:
return await self.async_reauth_device()
return await self.async_create_device()
except BraviaTVAuthError:
errors["base"] = "invalid_auth"
except BraviaTVNotSupported:
errors["base"] = "unsupported_model"
except BraviaTVError:
errors["base"] = "cannot_connect"

return self.async_show_form(
step_id="psk",
data_schema=vol.Schema(
{
vol.Required(CONF_PIN): str,
}
),
errors=errors,
Expand Down Expand Up @@ -181,7 +248,6 @@ async def async_step_confirm(
) -> FlowResult:
"""Allow the user to confirm adding the device."""
if user_input is not None:
self.create_client()
return await self.async_step_authorize()

return self.async_show_form(step_id="confirm")
Expand All @@ -190,59 +256,7 @@ async def async_step_reauth(self, entry_data: Mapping[str, Any]) -> FlowResult:
"""Handle configuration by re-auth."""
self.entry = self.hass.config_entries.async_get_entry(self.context["entry_id"])
self.device_config = {**entry_data}
return await self.async_step_reauth_confirm()

async def async_step_reauth_confirm(
self, user_input: dict[str, Any] | None = None
) -> 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

if user_input is not None:
pin = user_input[CONF_PIN]
use_psk = user_input[CONF_USE_PSK]
try:
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=client_id, nickname=nickname
)
await self.client.set_wol_mode(True)
except BraviaTVError:
return self.async_abort(reason="reauth_unsuccessful")
else:
self.hass.config_entries.async_update_entry(
self.entry, data={**self.device_config, **user_input}
)
await self.hass.config_entries.async_reload(self.entry.entry_id)
return self.async_abort(reason="reauth_successful")

try:
await self.client.pair(client_id, nickname)
except BraviaTVError:
return self.async_abort(reason="reauth_unsuccessful")

return self.async_show_form(
step_id="reauth_confirm",
data_schema=vol.Schema(
{
vol.Required(CONF_PIN, default=""): str,
vol.Required(CONF_USE_PSK, default=False): bool,
}
),
)

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]}"
return await self.async_step_authorize()


class BraviaTVOptionsFlowHandler(config_entries.OptionsFlowWithConfigEntry):
Expand Down
25 changes: 15 additions & 10 deletions homeassistant/components/braviatv/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,27 @@
},
"authorize": {
"title": "Authorize Sony Bravia TV",
"description": "Enter the PIN code shown on the Sony Bravia TV. \n\nIf the PIN code is not shown, you have to unregister Home Assistant on your TV, go to: Settings -> Network -> Remote device settings -> Deregister remote device. \n\nYou can use PSK (Pre-Shared-Key) instead of PIN. PSK is a user-defined secret key used for access control. This authentication method is recommended as more stable. To enable PSK on your TV, go to: Settings -> Network -> Home Network Setup -> IP Control. Then check «Use PSK authentication» box and enter your PSK instead of PIN.",
"description": "Make sure that «Control remotely» is enabled on your TV, go to: \nSettings -> Network -> Remote device settings -> Control remotely. \n\nThere are two authorization methods: PIN code or PSK (Pre-Shared Key). \nAuthorization via PSK is recommended as more stable.",
"data": {
"pin": "[%key:common::config_flow::data::pin%]",
"use_psk": "Use PSK authentication"
}
},
"confirm": {
"description": "[%key:common::config_flow::description::confirm_setup%]"
"pin": {
"title": "Authorize Sony Bravia TV",
"description": "Enter the PIN code shown on the Sony Bravia TV. \n\nIf the PIN code is not shown, you have to unregister Home Assistant on your TV, go to: Settings -> Network -> Remote device settings -> Deregister remote device.",
"data": {
"pin": "[%key:common::config_flow::data::pin%]"
}
},
"reauth_confirm": {
"description": "Enter the PIN code shown on the Sony Bravia TV. \n\nIf the PIN code is not shown, you have to unregister Home Assistant on your TV, go to: Settings -> Network -> Remote device settings -> Deregister remote device. \n\nYou can use PSK (Pre-Shared-Key) instead of PIN. PSK is a user-defined secret key used for access control. This authentication method is recommended as more stable. To enable PSK on your TV, go to: Settings -> Network -> Home Network Setup -> IP Control. Then check «Use PSK authentication» box and enter your PSK instead of PIN.",
"psk": {
"title": "Authorize Sony Bravia TV",
"description": "To set up PSK on your TV, go to: Settings -> Network -> Home Network Setup -> IP Control. Set «Authentication» to «Normal and Pre-Shared Key» or «Pre-Shared Key» and define your Pre-Shared-Key string (e.g. sony). \n\nThen enter your PSK here.",
"data": {
"pin": "[%key:common::config_flow::data::pin%]",
"use_psk": "Use PSK authentication"
"pin": "PSK"
}
},
"confirm": {
"description": "[%key:common::config_flow::description::confirm_setup%]"
}
},
"error": {
Expand All @@ -36,8 +42,7 @@
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"no_ip_control": "IP Control is disabled on your TV or the TV is not supported.",
"not_bravia_device": "The device is not a Bravia TV.",
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
"reauth_unsuccessful": "Re-authentication was unsuccessful, please remove the integration and set it up again."
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]"
}
},
"options": {
Expand Down
21 changes: 13 additions & 8 deletions homeassistant/components/braviatv/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
"already_configured": "Device is already configured",
"no_ip_control": "IP Control is disabled on your TV or the TV is not supported.",
"not_bravia_device": "The device is not a Bravia TV.",
"reauth_successful": "Re-authentication was successful",
"reauth_unsuccessful": "Re-authentication was unsuccessful, please remove the integration and set it up again."
"reauth_successful": "Re-authentication was successful"
},
"error": {
"cannot_connect": "Failed to connect",
Expand All @@ -16,21 +15,27 @@
"step": {
"authorize": {
"data": {
"pin": "PIN Code",
"use_psk": "Use PSK authentication"
},
"description": "Enter the PIN code shown on the Sony Bravia TV. \n\nIf the PIN code is not shown, you have to unregister Home Assistant on your TV, go to: Settings -> Network -> Remote device settings -> Deregister remote device. \n\nYou can use PSK (Pre-Shared-Key) instead of PIN. PSK is a user-defined secret key used for access control. This authentication method is recommended as more stable. To enable PSK on your TV, go to: Settings -> Network -> Home Network Setup -> IP Control. Then check \u00abUse PSK authentication\u00bb box and enter your PSK instead of PIN.",
"description": "Make sure that \u00abControl remotely\u00bb is enabled on your TV, go to: \nSettings -> Network -> Remote device settings -> Control remotely. \n\nThere are two authorization methods: PIN code or PSK (Pre-Shared Key). \nAuthorization via PSK is recommended as more stable.",
"title": "Authorize Sony Bravia TV"
},
"confirm": {
"description": "Do you want to start setup?"
},
"reauth_confirm": {
"pin": {
"data": {
"pin": "PIN Code",
"use_psk": "Use PSK authentication"
"pin": "PIN Code"
},
"description": "Enter the PIN code shown on the Sony Bravia TV. \n\nIf the PIN code is not shown, you have to unregister Home Assistant on your TV, go to: Settings -> Network -> Remote device settings -> Deregister remote device.",
"title": "Authorize Sony Bravia TV"
},
"psk": {
"data": {
"pin": "PSK"
},
"description": "Enter the PIN code shown on the Sony Bravia TV. \n\nIf the PIN code is not shown, you have to unregister Home Assistant on your TV, go to: Settings -> Network -> Remote device settings -> Deregister remote device. \n\nYou can use PSK (Pre-Shared-Key) instead of PIN. PSK is a user-defined secret key used for access control. This authentication method is recommended as more stable. To enable PSK on your TV, go to: Settings -> Network -> Home Network Setup -> IP Control. Then check \u00abUse PSK authentication\u00bb box and enter your PSK instead of PIN."
"description": "To set up PSK on your TV, go to: Settings -> Network -> Home Network Setup -> IP Control. Set \u00abAuthentication\u00bb to \u00abNormal and Pre-Shared Key\u00bb or \u00abPre-Shared Key\u00bb and define your Pre-Shared-Key string (e.g. sony). \n\nThen enter your PSK here.",
"title": "Authorize Sony Bravia TV"
},
"user": {
"data": {
Expand Down
Loading

0 comments on commit 80ac4c0

Please sign in to comment.