-
-
Notifications
You must be signed in to change notification settings - Fork 33.4k
/
Copy pathconfig_flow.py
137 lines (118 loc) · 4.39 KB
/
config_flow.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
"""Config flow for Ituran integration."""
from __future__ import annotations
from collections.abc import Mapping
import logging
from typing import Any
from pyituran import Ituran
from pyituran.exceptions import IturanApiError, IturanAuthError
import voluptuous as vol
from homeassistant.config_entries import SOURCE_REAUTH, ConfigFlow, ConfigFlowResult
from .const import (
CONF_ID_OR_PASSPORT,
CONF_MOBILE_ID,
CONF_OTP,
CONF_PHONE_NUMBER,
DOMAIN,
)
_LOGGER = logging.getLogger(__name__)
STEP_USER_DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_ID_OR_PASSPORT): str,
vol.Required(CONF_PHONE_NUMBER): str,
}
)
STEP_OTP_DATA_SCHEMA = vol.Schema(
{
vol.Required(CONF_OTP): str,
}
)
class IturanConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Ituran."""
_user_info: dict[str, Any]
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the initial step."""
errors: dict[str, str] = {}
if user_input is not None:
await self.async_set_unique_id(user_input[CONF_ID_OR_PASSPORT])
if self.source != SOURCE_REAUTH:
self._abort_if_unique_id_configured()
ituran = Ituran(
user_input[CONF_ID_OR_PASSPORT],
user_input[CONF_PHONE_NUMBER],
)
user_input[CONF_MOBILE_ID] = ituran.mobile_id
try:
authenticated = await ituran.is_authenticated()
if not authenticated:
await ituran.request_otp()
except IturanApiError:
errors["base"] = "cannot_connect"
except IturanAuthError:
errors["base"] = "invalid_auth"
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
if authenticated:
return self.async_create_entry(
title=f"Ituran {user_input[CONF_ID_OR_PASSPORT]}",
data=user_input,
)
self._user_info = user_input
return await self.async_step_otp()
return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
)
async def async_step_otp(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle the OTP step."""
errors: dict[str, str] = {}
if user_input is not None:
ituran = Ituran(
self._user_info[CONF_ID_OR_PASSPORT],
self._user_info[CONF_PHONE_NUMBER],
self._user_info[CONF_MOBILE_ID],
)
try:
await ituran.authenticate(user_input[CONF_OTP])
except IturanApiError:
errors["base"] = "cannot_connect"
except IturanAuthError:
errors["base"] = "invalid_otp"
except Exception:
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
if self.source == SOURCE_REAUTH:
return self.async_update_reload_and_abort(
self._get_reauth_entry(), data=self._user_info
)
return self.async_create_entry(
title=f"Ituran {self._user_info[CONF_ID_OR_PASSPORT]}",
data=self._user_info,
)
return self.async_show_form(
step_id="otp", data_schema=STEP_OTP_DATA_SCHEMA, errors=errors
)
async def async_step_reauth(
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:
"""Handle configuration by re-auth."""
self._user_info = dict(entry_data)
return await self.async_step_reauth_confirm()
async def async_step_reauth_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle reauth confirmation message."""
if user_input is not None:
return await self.async_step_user(self._user_info)
return self.async_show_form(
step_id="reauth_confirm",
data_schema=vol.Schema({}),
description_placeholders={
"phone_number": self._user_info[CONF_PHONE_NUMBER]
},
)