Skip to content

Add functionality to change Access Point Port VLANs #55

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions pyunifi/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,91 @@ def get_switch_port_overrides(self, target_mac):
log.debug('get_switch_port_overrides(%s)', target_mac)
return self.get_device_stat(target_mac)['port_overrides']

def get_networks(self):
"""Returns unfiltered list of all configured networks
:returns: networks known to the unifi controller
:rtype: list()
"""
log.debug('get_networks()')
return self._api_read("rest/networkconf")

def _get_portconf_id_list(self):
"""VLANs on an(y) AP port are mapped to a "portconf_id".
This helper method gets the mapping vlan id -> portconf_id
:returns: dictionary vlan_id -> portconf_id
:rtype: dict()
"""
nets = self.get_networks()
portconf_id_list = {}
for net in nets:
if 'vlan' in net:
portconf_id_list[int(net['vlan'])] = net['_id']
return portconf_id_list

def _ap_port_vlan(self, target_mac, port_idx, portconf_id):
"""Helper method to set the VLAN on the user ports of UAP-IW Devices.
Generates the json parameters including all unchanged settings.

:param target_mac: MAC address of the AP.
:type target_mac: str()
:param port_idx: Port ID to target
:type port_idx: int()
:param portconf_id: portconf_id to set.
:type portconf_id: str()
:returns: { 'port_overrides': [ { 'port_idx': int(),
'portconf': str, 'name': str } ] }
:rtype: dict( list( dict() ) )
"""
log.debug('_ap_port_vlan(%s, %s, %s)', target_mac, port_idx, portconf_id)
device_stat = self.get_device_stat(target_mac)
device_id = device_stat['_id']
overrides = device_stat['port_overrides']
found = False
for i in range(0, len(overrides)):
if overrides[i]['port_idx'] == port_idx:
# Override already exists, update..
overrides[i]['portconf_id'] = portconf_id
found = True
break
if not found:
log.error("No overrides for port %s on device %s. Are port vlans enabled/is this the right port?" % (str(port_idx), target_mac))
raise APIError(
"No overrides for port %s on device %s. Are port vlans enabled/is this the right port?" % (str(port_idx), target_mac)
)
return {"port_overrides": overrides, "device_id": device_id}

def ap_port_vlan(self, target_mac, port_idx, vlan, portconf_id_list=None):
"""Changes the VLAN on the given UAP Port

:param target_mac: MAC address of the AP.
:type target_mac: str()
:param port_idx: Port ID to change
:type port_idx: int()
:param vlan: VLAN ID to set
:type vlan: int()
:param portconf_id_list: Optional mapping vlan -> portconf_id as generated by get_portconf_id_list.
Otherwise the controller is queried for every port change
:type portconf_id_list: dict()

:returns: API Response which is either the full device info or empty if nothing was changed
:rtype: list()
"""
log.debug('ap_port_vlan(%s, %s, %s)', target_mac, port_idx, vlan)

if portconf_id_list is None:
portconf_id_list = self._get_portconf_id_list()
if vlan not in portconf_id_list:
log.error("VLAN %s unknown (no corresponding portconf_id was found)." % str(vlan))
raise APIError(
"VLAN %s unknown (no corresponding portconf_id was found)." % str(vlan)
)
# The portconf_id is the _id of the network w/ that VLAN, but + 1. !?
portconf_id = hex(int(portconf_id_list[vlan], 16)+1)[2:]
params = self._ap_port_vlan(target_mac, port_idx, portconf_id)
device_id = params['device_id']
del params['device_id']
return self._api_update('rest/device/' + device_id, params)

def _switch_port_power(self, target_mac, port_idx, mode):
"""Helper method to set the given PoE mode the port/switch.

Expand Down