1 """Config flow for Modem Caller ID integration."""
3 from __future__
import annotations
7 from phone_modem
import PhoneModem
8 import serial.tools.list_ports
9 from serial.tools.list_ports_common
import ListPortInfo
10 import voluptuous
as vol
16 from .const
import DEFAULT_NAME, DOMAIN, EXCEPTIONS
18 DATA_SCHEMA = vol.Schema({
"name": str,
"device": str})
22 """Generate unique id from usb attributes."""
23 return f
"{port.vid}:{port.pid}_{port.serial_number}_{port.manufacturer}_{port.description}"
27 """Handle a config flow for Phone Modem."""
30 """Set up flow instance."""
31 self.
_device_device: str |
None =
None
34 self, discovery_info: usb.UsbServiceInfo
35 ) -> ConfigFlowResult:
36 """Handle USB Discovery."""
37 dev_path = discovery_info.device
38 unique_id = f
"{discovery_info.vid}:{discovery_info.pid}_{discovery_info.serial_number}_{discovery_info.manufacturer}_{discovery_info.description}"
48 self, user_input: dict[str, Any] |
None =
None
49 ) -> ConfigFlowResult:
50 """Handle USB Discovery confirmation."""
51 if user_input
is not None:
53 title=user_input.get(CONF_NAME, DEFAULT_NAME),
54 data={CONF_DEVICE: self.
_device_device},
60 self, user_input: dict[str, Any] |
None =
None
61 ) -> ConfigFlowResult:
62 """Handle a flow initiated by the user."""
63 errors: dict[str, str] |
None = {}
66 ports = await self.hass.async_add_executor_job(serial.tools.list_ports.comports)
71 usb.human_readable_device_name(
80 if port.device
not in existing_devices
85 if user_input
is not None:
86 port = ports[unused_ports.index(
str(user_input.get(CONF_DEVICE)))]
87 dev_path = await self.hass.async_add_executor_job(
88 usb.get_serial_by_id, port.device
95 title=user_input.get(CONF_NAME, DEFAULT_NAME),
96 data={CONF_DEVICE: dev_path},
98 user_input = user_input
or {}
99 schema = vol.Schema({vol.Required(CONF_DEVICE): vol.In(unused_ports)})
103 self, dev_path: str, unique_id: str
104 ) -> dict[str, str] |
None:
105 """Handle common flow input validation."""
111 await api.test(dev_path)
113 return {
"base":
"cannot_connect"}
ConfigFlowResult async_step_usb(self, usb.UsbServiceInfo discovery_info)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_usb_confirm(self, dict[str, Any]|None user_input=None)
dict[str, str]|None validate_device_errors(self, str dev_path, str unique_id)
None _abort_if_unique_id_configured(self, dict[str, Any]|None updates=None, bool reload_on_update=True, *str error="already_configured")
None _set_confirm_only(self)
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)
list[ConfigEntry] _async_current_entries(self, bool|None include_ignore=None)
list[ConfigFlowResult] _async_in_progress(self, bool include_uninitialized=False, dict[str, Any]|None match_context=None)
ConfigFlowResult async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=None)
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)
_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)
_FlowResultT async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=None)
str _generate_unique_id(ListPortInfo port)