1 """Config flow to configure the LG Netcast TV integration."""
3 from __future__
import annotations
6 from datetime
import datetime, timedelta
7 from typing
import TYPE_CHECKING, Any
9 from pylgnetcast
import AccessTokenError, LgNetCastClient, SessionIdError
10 import voluptuous
as vol
12 from homeassistant
import config_entries
26 from .const
import DEFAULT_NAME, DOMAIN
27 from .helpers
import LGNetCastDetailDiscoveryError, async_discover_netcast_details
29 DISPLAY_ACCESS_TOKEN_INTERVAL =
timedelta(seconds=1)
33 """Handle a config flow for LG Netcast TV integration."""
38 """Initialize config flow."""
39 self.
clientclient: LgNetCastClient |
None =
None
40 self.device_config: dict[str, Any] = {}
41 self._discovered_devices: dict[str, Any] = {}
45 """Create LG Netcast client from config."""
46 host = self.device_config[CONF_HOST]
47 access_token = self.device_config.
get(CONF_ACCESS_TOKEN)
48 self.
clientclient = LgNetCastClient(host, access_token)
51 self, user_input: dict[str, Any] |
None =
None
52 ) -> ConfigFlowResult:
53 """Handle the initial step."""
54 errors: dict[str, str] = {}
56 if user_input
is not None:
57 host = user_input[CONF_HOST]
59 self.device_config[CONF_HOST] = host
62 errors[CONF_HOST] =
"invalid_host"
66 data_schema=vol.Schema({vol.Required(CONF_HOST): str}),
71 """Handle Discovery step."""
75 assert self.
clientclient
is not None
77 if self.device_config.
get(CONF_ID):
82 except LGNetCastDetailDiscoveryError
as err:
83 raise AbortFlow(
"cannot_connect")
from err
85 if (unique_id := details[
"uuid"])
is None:
88 self.device_config[CONF_ID] = unique_id
89 self.device_config[CONF_MODEL] = details[
"model_name"]
91 if CONF_NAME
not in self.device_config:
92 self.device_config[CONF_NAME] = details[
"friendly_name"]
or DEFAULT_NAME
95 self, user_input: dict[str, Any] |
None =
None
96 ) -> ConfigFlowResult:
97 """Handle Authorize step."""
98 errors: dict[str, str] = {}
101 if user_input
is not None and user_input.get(CONF_ACCESS_TOKEN)
is not None:
102 self.device_config[CONF_ACCESS_TOKEN] = user_input[CONF_ACCESS_TOKEN]
105 assert self.
clientclient
is not None
109 updates={CONF_HOST: self.device_config[CONF_HOST]}
113 await self.hass.async_add_executor_job(
114 self.
clientclient._get_session_id
116 except AccessTokenError:
117 if user_input
is not None:
118 errors[CONF_ACCESS_TOKEN] =
"invalid_access_token"
119 except SessionIdError:
120 errors[
"base"] =
"cannot_connect"
127 DISPLAY_ACCESS_TOKEN_INTERVAL,
128 cancel_on_shutdown=
True,
133 data_schema=vol.Schema(
135 vol.Optional(CONF_ACCESS_TOKEN): vol.All(str, vol.Length(max=6)),
142 """Display access token on screen."""
143 assert self.
clientclient
is not None
144 with contextlib.suppress(AccessTokenError, SessionIdError):
145 await self.hass.async_add_executor_job(
146 self.
clientclient._get_session_id
151 """Terminate Access token display if flow is removed."""
155 """Stop Access token request if running."""
161 """Create LG Netcast TV Device from config."""
165 title=self.device_config[CONF_NAME], data=self.device_config
def async_stop_display_access_token(self)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
def async_discover_client(self)
ConfigFlowResult async_step_authorize(self, dict[str, Any]|None user_input=None)
def async_display_access_token(self, datetime|None _=None)
ConfigFlowResult async_create_device(self)
None _abort_if_unique_id_configured(self, dict[str, Any]|None updates=None, bool reload_on_update=True, *str error="already_configured")
ConfigEntry|None async_set_unique_id(self, str|None unique_id=None, *bool raise_on_progress=True)
ConfigFlowResult async_create_entry(self, *str title, Mapping[str, Any] data, str|None description=None, Mapping[str, str]|None description_placeholders=None, Mapping[str, Any]|None options=None)
ConfigFlowResult async_show_form(self, *str|None step_id=None, vol.Schema|None data_schema=None, dict[str, str]|None errors=None, Mapping[str, str]|None description_placeholders=None, bool|None last_step=None, str|None preview=None)
_FlowResultT async_show_form(self, *str|None step_id=None, vol.Schema|None data_schema=None, dict[str, str]|None errors=None, Mapping[str, str]|None description_placeholders=None, bool|None last_step=None, str|None preview=None)
_FlowResultT async_create_entry(self, *str|None title=None, Mapping[str, Any] data, str|None description=None, Mapping[str, str]|None description_placeholders=None)
web.Response get(self, web.Request request, str config_key)
NetcastDetails async_discover_netcast_details(HomeAssistant hass, LgNetCastClient client)
CALLBACK_TYPE async_track_time_interval(HomeAssistant hass, Callable[[datetime], Coroutine[Any, Any, None]|None] action, timedelta interval, *str|None name=None, bool|None cancel_on_shutdown=None)
bool is_host_valid(str host)