1 """Adds config flow for Trafikverket Train integration."""
3 from __future__
import annotations
5 from collections.abc
import Mapping
6 from datetime
import datetime
10 from pytrafikverket
import TrafikverketTrain
11 from pytrafikverket.exceptions
import (
12 InvalidAuthentication,
13 MultipleTrainStationsFound,
14 NoTrainAnnouncementFound,
18 import voluptuous
as vol
39 from .const
import CONF_FILTER_PRODUCT, CONF_FROM, CONF_TIME, CONF_TO, DOMAIN
40 from .util
import next_departuredate
42 _LOGGER = logging.getLogger(__name__)
45 vol.Optional(CONF_FILTER_PRODUCT, default=
""):
TextSelector(),
48 DATA_SCHEMA = vol.Schema(
58 mode=SelectSelectorMode.DROPDOWN,
59 translation_key=CONF_WEEKDAY,
63 ).extend(OPTION_SCHEMA)
64 DATA_SCHEMA_REAUTH = vol.Schema(
66 vol.Required(CONF_API_KEY): cv.string,
76 train_time: str |
None,
78 product_filter: str |
None,
80 """Validate input from user input."""
81 errors: dict[str, str] = {}
86 if _time := dt_util.parse_time(train_time):
87 when = datetime.combine(
90 dt_util.get_default_time_zone(),
95 train_api = TrafikverketTrain(web_session, api_key)
96 from_station = await train_api.async_search_train_station(train_from)
97 to_station = await train_api.async_search_train_station(train_to)
99 await train_api.async_get_train_stop(
100 from_station, to_station, when, product_filter
103 await train_api.async_get_next_train_stop(
104 from_station, to_station, when, product_filter
106 except InvalidAuthentication:
107 errors[
"base"] =
"invalid_auth"
108 except NoTrainStationFound:
109 errors[
"base"] =
"invalid_station"
110 except MultipleTrainStationsFound:
111 errors[
"base"] =
"more_stations"
112 except NoTrainAnnouncementFound:
113 errors[
"base"] =
"no_trains"
114 except UnknownError
as error:
115 _LOGGER.error(
"Unknown error occurred during validation %s",
str(error))
116 errors[
"base"] =
"cannot_connect"
117 except Exception
as error:
118 _LOGGER.error(
"Unknown exception occurred during validation %s",
str(error))
119 errors[
"base"] =
"cannot_connect"
125 """Handle a config flow for Trafikverket Train integration."""
133 config_entry: ConfigEntry,
134 ) -> TVTrainOptionsFlowHandler:
135 """Get the options flow for this handler."""
139 self, entry_data: Mapping[str, Any]
140 ) -> ConfigFlowResult:
141 """Handle re-authentication with Trafikverket."""
145 self, user_input: dict[str, Any] |
None =
None
146 ) -> ConfigFlowResult:
147 """Confirm re-authentication with Trafikverket."""
148 errors: dict[str, str] = {}
151 api_key = user_input[CONF_API_KEY]
157 reauth_entry.data[CONF_FROM],
158 reauth_entry.data[CONF_TO],
159 reauth_entry.data.get(CONF_TIME),
160 reauth_entry.data[CONF_WEEKDAY],
161 reauth_entry.options.get(CONF_FILTER_PRODUCT),
166 data_updates={CONF_API_KEY: api_key},
170 step_id=
"reauth_confirm",
171 data_schema=DATA_SCHEMA_REAUTH,
176 self, user_input: dict[str, Any] |
None =
None
177 ) -> ConfigFlowResult:
178 """Handle the user step."""
179 errors: dict[str, str] = {}
181 if user_input
is not None:
182 api_key: str = user_input[CONF_API_KEY]
183 train_from: str = user_input[CONF_FROM]
184 train_to: str = user_input[CONF_TO]
185 train_time: str |
None = user_input.get(CONF_TIME)
186 train_days: list = user_input[CONF_WEEKDAY]
187 filter_product: str |
None = user_input[CONF_FILTER_PRODUCT]
189 if filter_product ==
"":
190 filter_product =
None
192 name = f
"{train_from} to {train_to}"
194 name = f
"{train_from} to {train_to} at {train_time}"
208 CONF_API_KEY: api_key,
209 CONF_FROM: train_from,
211 CONF_TIME: train_time,
212 CONF_WEEKDAY: train_days,
213 CONF_FILTER_PRODUCT: filter_product,
219 CONF_API_KEY: api_key,
221 CONF_FROM: train_from,
223 CONF_TIME: train_time,
224 CONF_WEEKDAY: train_days,
226 options={CONF_FILTER_PRODUCT: filter_product},
232 DATA_SCHEMA, user_input
or {}
239 """Handle Trafikverket Train options."""
242 self, user_input: dict[str, Any] |
None =
None
243 ) -> ConfigFlowResult:
244 """Manage Trafikverket Train options."""
245 errors: dict[str, Any] = {}
248 if not (_filter := user_input.get(CONF_FILTER_PRODUCT))
or _filter ==
"":
249 user_input[CONF_FILTER_PRODUCT] =
None
255 vol.Schema(OPTION_SCHEMA),
ConfigFlowResult async_step_reauth_confirm(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_reauth(self, Mapping[str, Any] entry_data)
TVTrainOptionsFlowHandler async_get_options_flow(ConfigEntry config_entry)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_init(self, dict[str, Any]|None user_input=None)
ConfigEntry _get_reauth_entry(self)
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_update_reload_and_abort(self, ConfigEntry entry, *str|None|UndefinedType unique_id=UNDEFINED, str|UndefinedType title=UNDEFINED, Mapping[str, Any]|UndefinedType data=UNDEFINED, Mapping[str, Any]|UndefinedType data_updates=UNDEFINED, Mapping[str, Any]|UndefinedType options=UNDEFINED, str|UndefinedType reason=UNDEFINED, bool reload_even_if_entry_is_unchanged=True)
None _async_abort_entries_match(self, dict[str, Any]|None match_dict=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)
ConfigEntry config_entry(self)
None config_entry(self, ConfigEntry value)
vol.Schema add_suggested_values_to_schema(self, vol.Schema data_schema, Mapping[str, Any]|None suggested_values)
_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)
date next_departuredate(list[str] departure)
dict[str, str] validate_input(HomeAssistant hass, str api_key, str train_from, str train_to, str|None train_time, list[str] weekdays, str|None product_filter)
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)