UniFi - Make POE control switches configurable (#32781)
* Allow control whether POE switches are to be created or not * Fix options flow and test
This commit is contained in:
parent
23e091696e
commit
314bc07cee
7 changed files with 76 additions and 45 deletions
|
@ -32,7 +32,8 @@
|
|||
"client_control": {
|
||||
"data": {
|
||||
"block_client": "Network access controlled clients",
|
||||
"new_client": "Add new client for network access control"
|
||||
"new_client": "Add new client (MAC) for network access control",
|
||||
"poe_clients": "Allow POE control of clients"
|
||||
},
|
||||
"description": "Configure client controls\n\nCreate switches for serial numbers you want to control network access for.",
|
||||
"title": "UniFi options 2/3"
|
||||
|
|
|
@ -19,12 +19,14 @@ from .const import (
|
|||
CONF_BLOCK_CLIENT,
|
||||
CONF_CONTROLLER,
|
||||
CONF_DETECTION_TIME,
|
||||
CONF_POE_CLIENTS,
|
||||
CONF_SITE_ID,
|
||||
CONF_SSID_FILTER,
|
||||
CONF_TRACK_CLIENTS,
|
||||
CONF_TRACK_DEVICES,
|
||||
CONF_TRACK_WIRED_CLIENTS,
|
||||
CONTROLLER_ID,
|
||||
DEFAULT_POE_CLIENTS,
|
||||
DOMAIN,
|
||||
LOGGER,
|
||||
)
|
||||
|
@ -262,6 +264,10 @@ class UnifiOptionsFlowHandler(config_entries.OptionsFlow):
|
|||
step_id="client_control",
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Optional(
|
||||
CONF_POE_CLIENTS,
|
||||
default=self.options.get(CONF_POE_CLIENTS, DEFAULT_POE_CLIENTS),
|
||||
): bool,
|
||||
vol.Optional(
|
||||
CONF_BLOCK_CLIENT, default=self.options[CONF_BLOCK_CLIENT]
|
||||
): cv.multi_select(clients_to_block),
|
||||
|
|
|
@ -14,12 +14,14 @@ UNIFI_WIRELESS_CLIENTS = "unifi_wireless_clients"
|
|||
CONF_ALLOW_BANDWIDTH_SENSORS = "allow_bandwidth_sensors"
|
||||
CONF_BLOCK_CLIENT = "block_client"
|
||||
CONF_DETECTION_TIME = "detection_time"
|
||||
CONF_POE_CLIENTS = "poe_clients"
|
||||
CONF_TRACK_CLIENTS = "track_clients"
|
||||
CONF_TRACK_DEVICES = "track_devices"
|
||||
CONF_TRACK_WIRED_CLIENTS = "track_wired_clients"
|
||||
CONF_SSID_FILTER = "ssid_filter"
|
||||
|
||||
DEFAULT_ALLOW_BANDWIDTH_SENSORS = False
|
||||
DEFAULT_POE_CLIENTS = True
|
||||
DEFAULT_TRACK_CLIENTS = True
|
||||
DEFAULT_TRACK_DEVICES = True
|
||||
DEFAULT_TRACK_WIRED_CLIENTS = True
|
||||
|
|
|
@ -24,6 +24,7 @@ from .const import (
|
|||
CONF_BLOCK_CLIENT,
|
||||
CONF_CONTROLLER,
|
||||
CONF_DETECTION_TIME,
|
||||
CONF_POE_CLIENTS,
|
||||
CONF_SITE_ID,
|
||||
CONF_SSID_FILTER,
|
||||
CONF_TRACK_CLIENTS,
|
||||
|
@ -32,6 +33,7 @@ from .const import (
|
|||
CONTROLLER_ID,
|
||||
DEFAULT_ALLOW_BANDWIDTH_SENSORS,
|
||||
DEFAULT_DETECTION_TIME,
|
||||
DEFAULT_POE_CLIENTS,
|
||||
DEFAULT_TRACK_CLIENTS,
|
||||
DEFAULT_TRACK_DEVICES,
|
||||
DEFAULT_TRACK_WIRED_CLIENTS,
|
||||
|
@ -98,6 +100,11 @@ class UniFiController:
|
|||
"""Config entry option with list of clients to control network access."""
|
||||
return self.config_entry.options.get(CONF_BLOCK_CLIENT, [])
|
||||
|
||||
@property
|
||||
def option_poe_clients(self):
|
||||
"""Config entry option to control poe clients."""
|
||||
return self.config_entry.options.get(CONF_POE_CLIENTS, DEFAULT_POE_CLIENTS)
|
||||
|
||||
@property
|
||||
def option_track_clients(self):
|
||||
"""Config entry option to not track clients."""
|
||||
|
|
|
@ -43,7 +43,8 @@
|
|||
"client_control": {
|
||||
"data": {
|
||||
"block_client": "Network access controlled clients",
|
||||
"new_client": "Add new client for network access control"
|
||||
"new_client": "Add new client for network access control",
|
||||
"poe_clients": "Allow POE control of clients"
|
||||
},
|
||||
"description": "Configure client controls\n\nCreate switches for serial numbers you want to control network access for.",
|
||||
"title": "UniFi options 2/3"
|
||||
|
|
|
@ -30,6 +30,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
switches_off = []
|
||||
|
||||
option_block_clients = controller.option_block_clients
|
||||
option_poe_clients = controller.option_poe_clients
|
||||
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
|
@ -66,6 +67,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
def options_updated():
|
||||
"""Manage entities affected by config entry options."""
|
||||
nonlocal option_block_clients
|
||||
nonlocal option_poe_clients
|
||||
|
||||
update = set()
|
||||
remove = set()
|
||||
|
@ -82,16 +84,26 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
else:
|
||||
remove.add(block_client_id)
|
||||
|
||||
for block_client_id in remove:
|
||||
entity = switches.pop(block_client_id)
|
||||
if option_poe_clients != controller.option_poe_clients:
|
||||
option_poe_clients = controller.option_poe_clients
|
||||
|
||||
if entity_registry.async_is_registered(entity.entity_id):
|
||||
entity_registry.async_remove(entity.entity_id)
|
||||
if option_poe_clients:
|
||||
update.add("poe_clients_enabled")
|
||||
else:
|
||||
for poe_client_id, entity in switches.items():
|
||||
if isinstance(entity, UniFiPOEClientSwitch):
|
||||
remove.add(poe_client_id)
|
||||
|
||||
hass.async_create_task(entity.async_remove())
|
||||
for client_id in remove:
|
||||
entity = switches.pop(client_id)
|
||||
|
||||
if len(update) != len(option_block_clients):
|
||||
update_controller()
|
||||
if entity_registry.async_is_registered(entity.entity_id):
|
||||
entity_registry.async_remove(entity.entity_id)
|
||||
|
||||
hass.async_create_task(entity.async_remove())
|
||||
|
||||
if len(update) != len(option_block_clients):
|
||||
update_controller()
|
||||
|
||||
controller.listeners.append(
|
||||
async_dispatcher_connect(
|
||||
|
@ -109,7 +121,6 @@ def add_entities(controller, async_add_entities, switches, switches_off):
|
|||
new_switches = []
|
||||
devices = controller.api.devices
|
||||
|
||||
# block client
|
||||
for client_id in controller.option_block_clients:
|
||||
|
||||
client = None
|
||||
|
@ -130,49 +141,49 @@ def add_entities(controller, async_add_entities, switches, switches_off):
|
|||
switches[block_client_id] = UniFiBlockClientSwitch(client, controller)
|
||||
new_switches.append(switches[block_client_id])
|
||||
|
||||
# control POE
|
||||
for client_id in controller.api.clients:
|
||||
if controller.option_poe_clients:
|
||||
for client_id in controller.api.clients:
|
||||
|
||||
poe_client_id = f"poe-{client_id}"
|
||||
poe_client_id = f"poe-{client_id}"
|
||||
|
||||
if poe_client_id in switches:
|
||||
continue
|
||||
if poe_client_id in switches:
|
||||
continue
|
||||
|
||||
client = controller.api.clients[client_id]
|
||||
|
||||
if poe_client_id in switches_off:
|
||||
pass
|
||||
# Network device with active POE
|
||||
elif (
|
||||
client_id in controller.wireless_clients
|
||||
or client.sw_mac not in devices
|
||||
or not devices[client.sw_mac].ports[client.sw_port].port_poe
|
||||
or not devices[client.sw_mac].ports[client.sw_port].poe_enable
|
||||
or controller.mac == client.mac
|
||||
):
|
||||
continue
|
||||
|
||||
# Multiple POE-devices on same port means non UniFi POE driven switch
|
||||
multi_clients_on_port = False
|
||||
for client2 in controller.api.clients.values():
|
||||
client = controller.api.clients[client_id]
|
||||
|
||||
if poe_client_id in switches_off:
|
||||
break
|
||||
|
||||
if (
|
||||
client2.is_wired
|
||||
and client.mac != client2.mac
|
||||
and client.sw_mac == client2.sw_mac
|
||||
and client.sw_port == client2.sw_port
|
||||
pass
|
||||
# Network device with active POE
|
||||
elif (
|
||||
client_id in controller.wireless_clients
|
||||
or client.sw_mac not in devices
|
||||
or not devices[client.sw_mac].ports[client.sw_port].port_poe
|
||||
or not devices[client.sw_mac].ports[client.sw_port].poe_enable
|
||||
or controller.mac == client.mac
|
||||
):
|
||||
multi_clients_on_port = True
|
||||
break
|
||||
continue
|
||||
|
||||
if multi_clients_on_port:
|
||||
continue
|
||||
# Multiple POE-devices on same port means non UniFi POE driven switch
|
||||
multi_clients_on_port = False
|
||||
for client2 in controller.api.clients.values():
|
||||
|
||||
switches[poe_client_id] = UniFiPOEClientSwitch(client, controller)
|
||||
new_switches.append(switches[poe_client_id])
|
||||
if poe_client_id in switches_off:
|
||||
break
|
||||
|
||||
if (
|
||||
client2.is_wired
|
||||
and client.mac != client2.mac
|
||||
and client.sw_mac == client2.sw_mac
|
||||
and client.sw_port == client2.sw_port
|
||||
):
|
||||
multi_clients_on_port = True
|
||||
break
|
||||
|
||||
if multi_clients_on_port:
|
||||
continue
|
||||
|
||||
switches[poe_client_id] = UniFiPOEClientSwitch(client, controller)
|
||||
new_switches.append(switches[poe_client_id])
|
||||
|
||||
if new_switches:
|
||||
async_add_entities(new_switches)
|
||||
|
|
|
@ -11,6 +11,7 @@ from homeassistant.components.unifi.const import (
|
|||
CONF_BLOCK_CLIENT,
|
||||
CONF_CONTROLLER,
|
||||
CONF_DETECTION_TIME,
|
||||
CONF_POE_CLIENTS,
|
||||
CONF_SITE_ID,
|
||||
CONF_SSID_FILTER,
|
||||
CONF_TRACK_CLIENTS,
|
||||
|
@ -287,6 +288,7 @@ async def test_option_flow(hass):
|
|||
user_input={
|
||||
CONF_BLOCK_CLIENT: clients_to_block,
|
||||
CONF_NEW_CLIENT: "00:00:00:00:00:01",
|
||||
CONF_POE_CLIENTS: False,
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -327,5 +329,6 @@ async def test_option_flow(hass):
|
|||
CONF_DETECTION_TIME: 100,
|
||||
CONF_SSID_FILTER: ["SSID 1"],
|
||||
CONF_BLOCK_CLIENT: ["00:00:00:00:00:01"],
|
||||
CONF_POE_CLIENTS: False,
|
||||
CONF_ALLOW_BANDWIDTH_SENSORS: True,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue