UniFi config option SSID filter (#31842)
* Draft * Use new multi_select config validation * Bump dependency to v13 * Improve options flow * Add title to config options * Add config option descriptions * Fix martins comment
This commit is contained in:
parent
60ae85564e
commit
774c892ee6
10 changed files with 84 additions and 62 deletions
|
@ -25,18 +25,26 @@
|
|||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"init": {
|
||||
"data": {}
|
||||
},
|
||||
"device_tracker": {
|
||||
"data": {
|
||||
"detection_time": "Time in seconds from last seen until considered away",
|
||||
"ssid_filter": "Select SSIDs to track wireless clients on",
|
||||
"track_clients": "Track network clients",
|
||||
"track_devices": "Track network devices (Ubiquiti devices)",
|
||||
"track_wired_clients": "Include wired network clients"
|
||||
}
|
||||
},
|
||||
"description": "Configure device tracking",
|
||||
"title": "UniFi options"
|
||||
},
|
||||
"statistics_sensors": {
|
||||
"data": {
|
||||
"allow_bandwidth_sensors": "Create bandwidth usage sensors for network clients"
|
||||
}
|
||||
"allow_bandwidth_sensors": "Bandwidth usage sensors for network clients"
|
||||
},
|
||||
"description": "Configure statistics sensors",
|
||||
"title": "UniFi options"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,21 +12,18 @@ from homeassistant.const import (
|
|||
CONF_VERIFY_SSL,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from .const import (
|
||||
CONF_ALLOW_BANDWIDTH_SENSORS,
|
||||
CONF_CONTROLLER,
|
||||
CONF_DETECTION_TIME,
|
||||
CONF_SITE_ID,
|
||||
CONF_SSID_FILTER,
|
||||
CONF_TRACK_CLIENTS,
|
||||
CONF_TRACK_DEVICES,
|
||||
CONF_TRACK_WIRED_CLIENTS,
|
||||
CONTROLLER_ID,
|
||||
DEFAULT_ALLOW_BANDWIDTH_SENSORS,
|
||||
DEFAULT_DETECTION_TIME,
|
||||
DEFAULT_TRACK_CLIENTS,
|
||||
DEFAULT_TRACK_DEVICES,
|
||||
DEFAULT_TRACK_WIRED_CLIENTS,
|
||||
DOMAIN,
|
||||
LOGGER,
|
||||
)
|
||||
|
@ -185,33 +182,30 @@ class UnifiOptionsFlowHandler(config_entries.OptionsFlow):
|
|||
self.options.update(user_input)
|
||||
return await self.async_step_statistics_sensors()
|
||||
|
||||
controller = get_controller_from_config_entry(self.hass, self.config_entry)
|
||||
|
||||
ssid_filter = {wlan: wlan for wlan in controller.api.wlans}
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="device_tracker",
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Optional(
|
||||
CONF_TRACK_CLIENTS,
|
||||
default=self.config_entry.options.get(
|
||||
CONF_TRACK_CLIENTS, DEFAULT_TRACK_CLIENTS
|
||||
),
|
||||
CONF_TRACK_CLIENTS, default=controller.option_track_clients,
|
||||
): bool,
|
||||
vol.Optional(
|
||||
CONF_TRACK_WIRED_CLIENTS,
|
||||
default=self.config_entry.options.get(
|
||||
CONF_TRACK_WIRED_CLIENTS, DEFAULT_TRACK_WIRED_CLIENTS
|
||||
),
|
||||
default=controller.option_track_wired_clients,
|
||||
): bool,
|
||||
vol.Optional(
|
||||
CONF_TRACK_DEVICES,
|
||||
default=self.config_entry.options.get(
|
||||
CONF_TRACK_DEVICES, DEFAULT_TRACK_DEVICES
|
||||
),
|
||||
CONF_TRACK_DEVICES, default=controller.option_track_devices,
|
||||
): bool,
|
||||
vol.Optional(
|
||||
CONF_SSID_FILTER, default=controller.option_ssid_filter
|
||||
): cv.multi_select(ssid_filter),
|
||||
vol.Optional(
|
||||
CONF_DETECTION_TIME,
|
||||
default=self.config_entry.options.get(
|
||||
CONF_DETECTION_TIME, DEFAULT_DETECTION_TIME
|
||||
),
|
||||
default=int(controller.option_detection_time.total_seconds()),
|
||||
): int,
|
||||
}
|
||||
),
|
||||
|
@ -223,16 +217,15 @@ class UnifiOptionsFlowHandler(config_entries.OptionsFlow):
|
|||
self.options.update(user_input)
|
||||
return await self._update_options()
|
||||
|
||||
controller = get_controller_from_config_entry(self.hass, self.config_entry)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="statistics_sensors",
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Optional(
|
||||
CONF_ALLOW_BANDWIDTH_SENSORS,
|
||||
default=self.config_entry.options.get(
|
||||
CONF_ALLOW_BANDWIDTH_SENSORS,
|
||||
DEFAULT_ALLOW_BANDWIDTH_SENSORS,
|
||||
),
|
||||
default=controller.option_allow_bandwidth_sensors,
|
||||
): bool
|
||||
}
|
||||
),
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/unifi",
|
||||
"requirements": [
|
||||
"aiounifi==12"
|
||||
"aiounifi==13"
|
||||
],
|
||||
"dependencies": [],
|
||||
"codeowners": [
|
||||
|
|
|
@ -31,15 +31,20 @@
|
|||
"device_tracker": {
|
||||
"data": {
|
||||
"detection_time": "Time in seconds from last seen until considered away",
|
||||
"ssid_filter": "Select SSIDs to track wireless clients on",
|
||||
"track_clients": "Track network clients",
|
||||
"track_devices": "Track network devices (Ubiquiti devices)",
|
||||
"track_wired_clients": "Include wired network clients"
|
||||
}
|
||||
},
|
||||
"description": "Configure device tracking",
|
||||
"title": "UniFi options"
|
||||
},
|
||||
"statistics_sensors": {
|
||||
"data": {
|
||||
"allow_bandwidth_sensors": "Create bandwidth usage sensors for network clients"
|
||||
}
|
||||
"allow_bandwidth_sensors": "Bandwidth usage sensors for network clients"
|
||||
},
|
||||
"description": "Configure statistics sensors",
|
||||
"title": "UniFi options"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -199,7 +199,7 @@ aiopylgtv==0.3.3
|
|||
aioswitcher==2019.4.26
|
||||
|
||||
# homeassistant.components.unifi
|
||||
aiounifi==12
|
||||
aiounifi==13
|
||||
|
||||
# homeassistant.components.wwlln
|
||||
aiowwlln==2.0.2
|
||||
|
|
|
@ -78,7 +78,7 @@ aiopylgtv==0.3.3
|
|||
aioswitcher==2019.4.26
|
||||
|
||||
# homeassistant.components.unifi
|
||||
aiounifi==12
|
||||
aiounifi==13
|
||||
|
||||
# homeassistant.components.wwlln
|
||||
aiowwlln==2.0.2
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import aiounifi
|
||||
from asynctest import patch
|
||||
|
||||
from homeassistant import data_entry_flow
|
||||
from homeassistant.components import unifi
|
||||
from homeassistant.components.unifi import config_flow
|
||||
from homeassistant.components.unifi.const import CONF_CONTROLLER, CONF_SITE_ID
|
||||
|
@ -13,8 +14,12 @@ from homeassistant.const import (
|
|||
CONF_VERIFY_SSL,
|
||||
)
|
||||
|
||||
from .test_controller import setup_unifi_integration
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
WLANS = [{"name": "SSID 1"}, {"name": "SSID 2"}]
|
||||
|
||||
|
||||
async def test_flow_works(hass, aioclient_mock, mock_discovery):
|
||||
"""Test config flow."""
|
||||
|
@ -236,36 +241,39 @@ async def test_flow_fails_unknown_problem(hass, aioclient_mock):
|
|||
|
||||
async def test_option_flow(hass):
|
||||
"""Test config flow options."""
|
||||
entry = MockConfigEntry(domain=config_flow.DOMAIN, data={}, options=None)
|
||||
hass.config_entries._entries.append(entry)
|
||||
controller = await setup_unifi_integration(hass, wlans_response=WLANS)
|
||||
|
||||
flow = await hass.config_entries.options.async_create_flow(
|
||||
entry.entry_id, context={"source": "test"}, data=None
|
||||
result = await hass.config_entries.options.async_init(
|
||||
controller.config_entry.entry_id
|
||||
)
|
||||
|
||||
result = await flow.async_step_init()
|
||||
assert result["type"] == "form"
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "device_tracker"
|
||||
|
||||
result = await flow.async_step_device_tracker(
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
config_flow.CONF_TRACK_CLIENTS: False,
|
||||
config_flow.CONF_TRACK_WIRED_CLIENTS: False,
|
||||
config_flow.CONF_TRACK_DEVICES: False,
|
||||
config_flow.CONF_SSID_FILTER: ["SSID 1"],
|
||||
config_flow.CONF_DETECTION_TIME: 100,
|
||||
}
|
||||
},
|
||||
)
|
||||
assert result["type"] == "form"
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "statistics_sensors"
|
||||
|
||||
result = await flow.async_step_statistics_sensors(
|
||||
user_input={config_flow.CONF_ALLOW_BANDWIDTH_SENSORS: True}
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"], user_input={config_flow.CONF_ALLOW_BANDWIDTH_SENSORS: True}
|
||||
)
|
||||
assert result["type"] == "create_entry"
|
||||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["data"] == {
|
||||
config_flow.CONF_TRACK_CLIENTS: False,
|
||||
config_flow.CONF_TRACK_WIRED_CLIENTS: False,
|
||||
config_flow.CONF_TRACK_DEVICES: False,
|
||||
config_flow.CONF_DETECTION_TIME: 100,
|
||||
config_flow.CONF_SSID_FILTER: ["SSID 1"],
|
||||
config_flow.CONF_ALLOW_BANDWIDTH_SENSORS: True,
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ async def setup_unifi_integration(
|
|||
clients_response=None,
|
||||
devices_response=None,
|
||||
clients_all_response=None,
|
||||
wlans_response=None,
|
||||
known_wireless_clients=None,
|
||||
controllers=None,
|
||||
):
|
||||
|
@ -98,6 +99,10 @@ async def setup_unifi_integration(
|
|||
if clients_all_response:
|
||||
mock_client_all_responses.append(clients_all_response)
|
||||
|
||||
mock_wlans_responses = deque()
|
||||
if wlans_response:
|
||||
mock_wlans_responses.append(wlans_response)
|
||||
|
||||
mock_requests = []
|
||||
|
||||
async def mock_request(self, method, path, json=None):
|
||||
|
@ -109,6 +114,8 @@ async def setup_unifi_integration(
|
|||
return mock_device_responses.popleft()
|
||||
if path == "s/{site}/rest/user" and mock_client_all_responses:
|
||||
return mock_client_all_responses.popleft()
|
||||
if path == "s/{site}/rest/wlanconf" and mock_wlans_responses:
|
||||
return mock_wlans_responses.popleft()
|
||||
return {}
|
||||
|
||||
# "aiounifi.Controller.start_websocket", return_value=True
|
||||
|
@ -128,6 +135,7 @@ async def setup_unifi_integration(
|
|||
controller.mock_client_responses = mock_client_responses
|
||||
controller.mock_device_responses = mock_device_responses
|
||||
controller.mock_client_all_responses = mock_client_all_responses
|
||||
controller.mock_wlans_responses = mock_wlans_responses
|
||||
controller.mock_requests = mock_requests
|
||||
|
||||
return controller
|
||||
|
|
|
@ -54,7 +54,7 @@ async def test_no_clients(hass):
|
|||
hass, options={unifi.const.CONF_ALLOW_BANDWIDTH_SENSORS: True},
|
||||
)
|
||||
|
||||
assert len(controller.mock_requests) == 3
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(hass.states.async_all()) == 1
|
||||
|
||||
|
||||
|
@ -70,7 +70,7 @@ async def test_sensors(hass):
|
|||
clients_response=CLIENTS,
|
||||
)
|
||||
|
||||
assert len(controller.mock_requests) == 3
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(hass.states.async_all()) == 5
|
||||
|
||||
wired_client_rx = hass.states.get("sensor.wired_client_name_rx")
|
||||
|
|
|
@ -207,7 +207,7 @@ async def test_no_clients(hass):
|
|||
},
|
||||
)
|
||||
|
||||
assert len(controller.mock_requests) == 3
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(hass.states.async_all()) == 1
|
||||
|
||||
|
||||
|
@ -223,7 +223,7 @@ async def test_controller_not_client(hass):
|
|||
devices_response=[DEVICE_1],
|
||||
)
|
||||
|
||||
assert len(controller.mock_requests) == 3
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(hass.states.async_all()) == 1
|
||||
cloudkey = hass.states.get("switch.cloud_key")
|
||||
assert cloudkey is None
|
||||
|
@ -244,7 +244,7 @@ async def test_not_admin(hass):
|
|||
devices_response=[DEVICE_1],
|
||||
)
|
||||
|
||||
assert len(controller.mock_requests) == 3
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(hass.states.async_all()) == 1
|
||||
|
||||
|
||||
|
@ -262,7 +262,7 @@ async def test_switches(hass):
|
|||
clients_all_response=[BLOCKED, UNBLOCKED, CLIENT_1],
|
||||
)
|
||||
|
||||
assert len(controller.mock_requests) == 3
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(hass.states.async_all()) == 4
|
||||
|
||||
switch_1 = hass.states.get("switch.poe_client_1")
|
||||
|
@ -297,7 +297,7 @@ async def test_new_client_discovered_on_block_control(hass):
|
|||
clients_all_response=[BLOCKED],
|
||||
)
|
||||
|
||||
assert len(controller.mock_requests) == 3
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(hass.states.async_all()) == 2
|
||||
|
||||
controller.api.websocket._data = {
|
||||
|
@ -310,9 +310,9 @@ async def test_new_client_discovered_on_block_control(hass):
|
|||
await hass.services.async_call(
|
||||
"switch", "turn_off", {"entity_id": "switch.block_client_1"}, blocking=True
|
||||
)
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(controller.mock_requests) == 5
|
||||
assert len(hass.states.async_all()) == 2
|
||||
assert controller.mock_requests[3] == {
|
||||
assert controller.mock_requests[4] == {
|
||||
"json": {"mac": "00:00:00:00:01:01", "cmd": "block-sta"},
|
||||
"method": "post",
|
||||
"path": "s/{site}/cmd/stamgr/",
|
||||
|
@ -321,8 +321,8 @@ async def test_new_client_discovered_on_block_control(hass):
|
|||
await hass.services.async_call(
|
||||
"switch", "turn_on", {"entity_id": "switch.block_client_1"}, blocking=True
|
||||
)
|
||||
assert len(controller.mock_requests) == 5
|
||||
assert controller.mock_requests[4] == {
|
||||
assert len(controller.mock_requests) == 6
|
||||
assert controller.mock_requests[5] == {
|
||||
"json": {"mac": "00:00:00:00:01:01", "cmd": "unblock-sta"},
|
||||
"method": "post",
|
||||
"path": "s/{site}/cmd/stamgr/",
|
||||
|
@ -341,7 +341,7 @@ async def test_new_client_discovered_on_poe_control(hass):
|
|||
devices_response=[DEVICE_1],
|
||||
)
|
||||
|
||||
assert len(controller.mock_requests) == 3
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(hass.states.async_all()) == 2
|
||||
|
||||
controller.api.websocket._data = {
|
||||
|
@ -354,9 +354,9 @@ async def test_new_client_discovered_on_poe_control(hass):
|
|||
await hass.services.async_call(
|
||||
"switch", "turn_off", {"entity_id": "switch.poe_client_1"}, blocking=True
|
||||
)
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(controller.mock_requests) == 5
|
||||
assert len(hass.states.async_all()) == 3
|
||||
assert controller.mock_requests[3] == {
|
||||
assert controller.mock_requests[4] == {
|
||||
"json": {
|
||||
"port_overrides": [{"port_idx": 1, "portconf_id": "1a1", "poe_mode": "off"}]
|
||||
},
|
||||
|
@ -367,8 +367,8 @@ async def test_new_client_discovered_on_poe_control(hass):
|
|||
await hass.services.async_call(
|
||||
"switch", "turn_on", {"entity_id": "switch.poe_client_1"}, blocking=True
|
||||
)
|
||||
assert len(controller.mock_requests) == 5
|
||||
assert controller.mock_requests[3] == {
|
||||
assert len(controller.mock_requests) == 6
|
||||
assert controller.mock_requests[4] == {
|
||||
"json": {
|
||||
"port_overrides": [
|
||||
{"port_idx": 1, "portconf_id": "1a1", "poe_mode": "auto"}
|
||||
|
@ -393,7 +393,7 @@ async def test_ignore_multiple_poe_clients_on_same_port(hass):
|
|||
hass, clients_response=POE_SWITCH_CLIENTS, devices_response=[DEVICE_1],
|
||||
)
|
||||
|
||||
assert len(controller.mock_requests) == 3
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(hass.states.async_all()) == 4
|
||||
|
||||
switch_1 = hass.states.get("switch.poe_client_1")
|
||||
|
@ -444,7 +444,7 @@ async def test_restoring_client(hass):
|
|||
clients_all_response=[CLIENT_1],
|
||||
)
|
||||
|
||||
assert len(controller.mock_requests) == 3
|
||||
assert len(controller.mock_requests) == 4
|
||||
assert len(hass.states.async_all()) == 3
|
||||
|
||||
device_1 = hass.states.get("switch.client_1")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue