I have created a small Python script to in a simple way (according to myself) make a plan in Ekahau Site Survey and convert it to someting i can paste in to Cisco Wireless Lan Controler (WLC). The script is created after my specific needs, i have for example only AP2700 and AP2600 in the network and live in Sweden. If you have a other accesspoint look at the code to update the powerlevels for the specific AP and region. I have also made the decision to only have 20MHz channels in the network to lower the risk of CCI.
In Ekahau Site Survey make a plan of your network, add Access Points to the map and set ther name exacly as the name in the controller. Set channel and power level, i have changed the settings in Ekahau to show the power level as dBm to reflect the way Cisco has done it in the configuration. If you whant to disable a radio, set the power level to -100dBm. If you just set it to ‘off’ it will still get configured with 1dBm power.
Today the way to export the information from Ekahau is a bit tedious. They have on there ‘to do list’ to make a simpler way but right now you have to go to File -> Export to Cisco Prime.. -> Export plan (someting simular on Mac). Open the .zip file and find the project.xml in the catalog /xmlDir/ copy the file to the same catalog as the Python script.
The script uses one package to help with the parsing of the xml-file. If it’s not allredy installed you might have to ”pip install xmltodict”
import xmltodict # To disable a radio set the power level of the radio to -100 for the specific channel in Ekahau Site Survey Planning mode. filename = 'project.xml' chan_width = 20 # 5GHz Channel width [20, 40, 80, 160] # This part of the code has to be update based on your AP-model and regulatory domain. # The easy way is to look in the WLC to get your power-levels. # For 5GHz # grep include APNAME "show advanced 802.11a txpower" # # For 2.4GHz # grep include APNAME "show advanced 802.11b txpower" # # The model value is from Ekahau-xml-export-file for the AP you have chosen there def calculate_power(model, ifType, power): if model.startswith('AP2700'): if ifType.startswith('802.11a'): s = [17, 14, 11, 8, 5, 2, 2, 2] # 5GHz else: s = [16, 13, 10, 7, 4, 1, 1, 1] # 2.4GHz elif model.startswith('AP2600'): if ifType.startswith('802.11a'): s = [17, 14, 11, 8, 5, 5, 5, 5] # 5GHz else: s = [16, 13, 10, 7, 4, 4, 4, 4] # 2.4GHz elif model.startswith('AP1140'): s = [17, 14, 11, 8, 5, 2, -1, 0] # 5GHz and 2.4GHz else: print 'I dont recognice the AP Type: %s' % model exit() ciscoPower = 1 for i in s: if i <= int(power): return ciscoPower ciscoPower += 1 return 8 # If the power is not recognized, return the lowest value. def main(): with open(filename) as fd: doc = xmltodict.parse(fd.read()) floor = doc['CiscoUnifiedInterchange']['Maps']['Site']['Building']['Floor'] floor = floor if type(floor) is list else [floor] for i in floor: for ap in i['PlannedAp']: name = ap['@name'] model = ap['@apModel'] for radio in ap['Radio']: ifType = radio['@ifType'] power = radio['@txPowerLevel'] channel = radio['ChannelDefinition']['@channelNumber'] if ifType.startswith('802.11 a/n'): ifType = '802.11a' width = chan_width # Global config from above else: ifType = '802.11b' width = 20 # 40 should not be used for 2.4GHz # Disable Radio print 'config %s disable %s' % (ifType, name) # If power level is N/A then just disable the radio. if not power.startswith('N/A'): # Set AP channel print 'config %s channel ap %s %s' % (ifType, name, channel) # Set Channel Width print 'config %s chan_width %s %i' % (ifType, name, width) # Set AP power level ciscopower = calculate_power(model, ifType, power) print 'config %s txPower ap %s %s' % (ifType, name, ciscopower) # Enable AP print 'config %s enable %s' % (ifType, name) print if __name__ == '__main__': main()