1 """Config flow for Nmap Tracker integration."""
3 from __future__
import annotations
5 from ipaddress
import ip_address, ip_network, summarize_address_range
8 import voluptuous
as vol
14 DEFAULT_CONSIDER_HOME,
33 TRACKER_SCAN_INTERVAL,
36 MAX_SCAN_INTERVAL = 3600
37 MAX_CONSIDER_HOME = MAX_SCAN_INTERVAL * 6
38 DEFAULT_NETWORK_PREFIX = 24
42 """Search adapters for the network."""
45 local_ip = await network.async_get_source_ip(hass, MDNS_TARGET_IP)
46 network_prefix = DEFAULT_NETWORK_PREFIX
47 for adapter
in await network.async_get_adapters(hass):
48 for ipv4
in adapter[
"ipv4"]:
49 if ipv4[
"address"] == local_ip:
50 network_prefix = ipv4[
"network_prefix"]
52 return str(ip_network(f
"{local_ip}/{network_prefix}",
False))
56 """Check if a list of hosts are all ips or ip networks."""
59 hosts = [host
for host
in cv.ensure_list_csv(hosts_str)
if host !=
""]
61 for host
in sorted(hosts):
63 start, end = host.split(
"-", 1)
65 ip_1, ip_2, ip_3, _ = start.split(
".", 3)
66 end = f
"{ip_1}.{ip_2}.{ip_3}.{end}"
67 summarize_address_range(ip_address(start), ip_address(end))
71 normalized_hosts.append(host)
75 normalized_hosts.append(
str(ip_address(host)))
82 normalized_hosts.append(
str(ip_network(host)))
86 return normalized_hosts
90 """Validate hosts and exclude are valid."""
93 if not normalized_hosts:
94 errors[CONF_HOSTS] =
"invalid_hosts"
96 user_input[CONF_HOSTS] =
",".join(normalized_hosts)
99 if normalized_exclude
is None:
100 errors[CONF_EXCLUDE] =
"invalid_hosts"
102 user_input[CONF_EXCLUDE] =
",".join(normalized_exclude)
108 hass: HomeAssistant, user_input: dict[str, Any], include_options: bool
111 exclude = user_input.get(
112 CONF_EXCLUDE, await network.async_get_source_ip(hass, MDNS_TARGET_IP)
114 schema: VolDictType = {
115 vol.Required(CONF_HOSTS, default=hosts): str,
117 CONF_HOME_INTERVAL, default=user_input.get(CONF_HOME_INTERVAL, 0)
119 vol.Optional(CONF_EXCLUDE, default=exclude): str,
121 CONF_OPTIONS, default=user_input.get(CONF_OPTIONS, DEFAULT_OPTIONS)
129 default=user_input.get(CONF_SCAN_INTERVAL, TRACKER_SCAN_INTERVAL),
130 ): vol.All(vol.Coerce(int), vol.Range(min=10, max=MAX_SCAN_INTERVAL)),
133 default=user_input.get(CONF_CONSIDER_HOME)
134 or DEFAULT_CONSIDER_HOME.total_seconds(),
135 ): vol.All(vol.Coerce(int), vol.Range(min=1, max=MAX_CONSIDER_HOME)),
138 return vol.Schema(schema)
142 """Handle a option flow for homekit."""
144 def __init__(self, config_entry: ConfigEntry) ->
None:
145 """Initialize options flow."""
149 self, user_input: dict[str, Any] |
None =
None
150 ) -> ConfigFlowResult:
151 """Handle options flow."""
153 if user_input
is not None:
159 title=f
"Nmap Tracker {self.options[CONF_HOSTS]}", data=self.
optionsoptions
165 self.hass, self.
optionsoptions,
True
172 """Handle a config flow for Nmap Tracker."""
177 """Initialize config flow."""
178 self.options: dict[str, Any] = {}
181 self, user_input: dict[str, Any] |
None =
None
182 ) -> ConfigFlowResult:
183 """Handle the initial step."""
185 if user_input
is not None:
190 self.options.
update(user_input)
194 title=f
"Nmap Tracker {user_input[CONF_HOSTS]}",
202 self.hass, self.options,
False
217 """Get the options flow for this handler."""
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
OptionsFlowHandler async_get_options_flow(ConfigEntry config_entry)
bool _async_is_unique_host_list(self, dict[str, Any] user_input)
None __init__(self, ConfigEntry config_entry)
ConfigFlowResult async_step_init(self, dict[str, Any]|None user_input=None)
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)
ConfigFlowResult async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=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)
IssData update(pyiss.ISS iss)
dict[str, str] normalize_input(dict[str, Any] user_input)
str async_get_network(HomeAssistant hass)
vol.Schema _async_build_schema_with_user_input(HomeAssistant hass, dict[str, Any] user_input, bool include_options)
list[str]|None _normalize_ips_and_network(str hosts_str)