diff --git a/homeassistant/components/unifi/.translations/en.json b/homeassistant/components/unifi/.translations/en.json index d9b65b6d1da..abef9344987 100644 --- a/homeassistant/components/unifi/.translations/en.json +++ b/homeassistant/components/unifi/.translations/en.json @@ -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" } } } diff --git a/homeassistant/components/unifi/config_flow.py b/homeassistant/components/unifi/config_flow.py index 9dbacc7916d..36fa7489e81 100644 --- a/homeassistant/components/unifi/config_flow.py +++ b/homeassistant/components/unifi/config_flow.py @@ -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 } ), diff --git a/homeassistant/components/unifi/manifest.json b/homeassistant/components/unifi/manifest.json index b4a4a5dab16..a42b136e665 100644 --- a/homeassistant/components/unifi/manifest.json +++ b/homeassistant/components/unifi/manifest.json @@ -4,7 +4,7 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/unifi", "requirements": [ - "aiounifi==12" + "aiounifi==13" ], "dependencies": [], "codeowners": [ diff --git a/homeassistant/components/unifi/strings.json b/homeassistant/components/unifi/strings.json index ce2f2345917..e652b60ee32 100644 --- a/homeassistant/components/unifi/strings.json +++ b/homeassistant/components/unifi/strings.json @@ -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" } } } diff --git a/requirements_all.txt b/requirements_all.txt index 63861444fbd..d5c554f18c4 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -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 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 676d4e6e77f..1718d816164 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -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 diff --git a/tests/components/unifi/test_config_flow.py b/tests/components/unifi/test_config_flow.py index c2c89d2b9c0..64d1ab9775e 100644 --- a/tests/components/unifi/test_config_flow.py +++ b/tests/components/unifi/test_config_flow.py @@ -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, } diff --git a/tests/components/unifi/test_controller.py b/tests/components/unifi/test_controller.py index e1b2b2355c4..daec8cddf5d 100644 --- a/tests/components/unifi/test_controller.py +++ b/tests/components/unifi/test_controller.py @@ -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 diff --git a/tests/components/unifi/test_sensor.py b/tests/components/unifi/test_sensor.py index c726d3bb1cb..7d0600f5885 100644 --- a/tests/components/unifi/test_sensor.py +++ b/tests/components/unifi/test_sensor.py @@ -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") diff --git a/tests/components/unifi/test_switch.py b/tests/components/unifi/test_switch.py index cd3d8785399..a2b609078de 100644 --- a/tests/components/unifi/test_switch.py +++ b/tests/components/unifi/test_switch.py @@ -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")