cancel
Showing results for 
Search instead for 
Did you mean: 

Locating AP's after a Location map is removed.

Locating AP's after a Location map is removed.

JasonC2
New Contributor
A bit of a unique situation my team and I have. We work for a school district with approx 16k real devices, mixed between models AP121, AP330, AP130, AP230, AP460S12C, AP1130, AP305C. How can you locate a working and connected AP that does not have an assigned location? Can a filter be created to list any devices that are connected but not assigned a location? In specific situations, we do have access to the SN and MAC of the affected AP's but for situations that we don't have that information without physically rolling out and reading the SN on the physical AP. These AP's are already provisioned but the map was removed.
1 ACCEPTED SOLUTION

Hi @Jason Cadenhead,

I was just aware of another method that is more easy to use. You can just click the download button at the upper left corner of the Manage > Devices page to export the devices list. It should download all devices if you don't have any filter applied. Once the csv file is downloaded, you can use Excel's "Sort & Filter" function to get the data you need.​

View solution in original post

3 REPLIES 3

Paul_Wang
Extreme Employee
Hi @Jason Cadenhead - I came up with a python (python 3) script like below, which should get what you need.

Note:
+ Some external modules are used in the script. Check the import list at the top of the script. Install them by using commands like "pip install MODULE-NAME" if needed.
+ The script was only tested against a VIQ with a few devices only.
+ It's possible that you may run into issues when running this script because some exceptions are not handled.
+ This script is for your reference only. I take no responsibility of maintaining it.  

import os
import requests
import json
import pprint
import pandas as pd
import time
import getpass

# Page size for each API request
limit = 1000
# Sleep time in seconds between each API call when mutiple API calls are needed for paginaation
sleep_time_seconds = 1

# Do not change any variables below
# URL of the API gateway
base_url = "https://api.extremecloudiq.com"
# Initialization of global variables
data = []
data_connected_only = []
device_without_locations = []
headers = {}
payload = {}
access_token = ''


def print_error_and_exit(desc, error):
    print("*** Error description:", desc)
    print("*** Error content:", error)
    print("*** Exiting ...")
    exit()


def display_usage():
    print('''
    This script will list all devices that are connected and without location assigned. 
    When the script runs, it will ask for the login credential of the the VIQ default admin.
    The result will be exported to a csv file named "result.csv" placed under the same directory where this script runs.
    The script uses the New API offered by XIQ. 
    See linked pages below for more details about the New API usage:
    https://api.extremecloudiq.com/swagger-ui/index.html?configUrl=/openapi/swagger-config#/
    https://extremecloudiq.com/api-docs/api-docs.html
    ''')


def get_access_token():
    username = input("Login email address of the default admin of the VIQ: ").strip()
    password = getpass.getpass()
    url = base_url + "/login"
    payload = json.dumps({
        'username': username,
        'password': password
    })
    headers['Content-Type'] = 'application/json'
    response = requests.request("POST", url, headers=headers, data=payload)
    if response.status_code != 200:
        print_error_and_exit("Status code is not 200", response.text)
    global access_token
    access_token = json.loads(response.text)["access_token"]
    print(access_token)


def list_devices(connected_only=None):
    # Page ID of the first API reqeust. Do not change this.
    page = 1

    # API request to get all devices
    url = base_url + "/devices?page=" + str(page) + "&limit=" + str(limit)

    payload = {}
    headers['Authorization'] = 'Bearer ' + access_token
    response = requests.request("GET", url, headers=headers, data=payload)
    if response.status_code != 200:
        print_error_and_exit("Status code is not 200", response.text)

    # Parse the API resposne as the json data
    response_json = json.loads(response.text)
    curent_page = response_json["page"]
    print("Current page:", curent_page)
    total_pages = response_json["total_pages"]
    print("Total number of pages:", total_pages)
    # Save the devices data to the global variable "data"
    global data
    data = (response_json["data"])

    # Make API calls pages other the the first page and aggregte the results
    print("Looping trhough to get the data")
    while curent_page < total_pages:
        time.sleep(sleep_time_seconds)
        curent_page += 1
        print("currrent_page:", curent_page)
        url = base_url + "/devices?page=" + str(curent_page) + "&limit=" + str(limit)
        response = requests.request("GET", url, headers=headers, data=payload)
        if response.status_code != 200:
            print_error_and_exit("Status code is not 200", response.text)
        response_json = json.loads(response.text)
        data.extend(response_json["data"])
    print("Data of all devices:")
    pprint.pprint(data)
    print("Number of items in data before filtered:", len(data))

    if connected_only:
        print("*** Find the devcies in connected status only")
        global data_connected_only
        for i in data:
            if i["connected"] == True:
                data_connected_only.append(i)
    print("Devices with connected status:")
    pprint.pprint(data_connected_only)
    print("Number of devices with connected status:", len(data_connected_only))


def get_devices_without_locations(connected_only=None):
    if connected_only == True:
        print("*** Get devices wth connected status only. ")
        data_devices = data_connected_only
        msg_connection_status = '(connected)'
    else:
        print("*** Get devices regardless of the connection status")
        data_devices = data
        msg_connection_status = '(regardless of connection status)'

    print("*** Get the device IDs list")
    # List of the IDs of all devices
    device_ids = []
    for i in data_devices:
        device_ids.append(str(i["id"]))
    print("*** IDs of all devices:", device_ids, msg_connection_status)
    print("*** Number of IDs of all devices:", len(device_ids), msg_connection_status)

    url = base_url + "/devices/location/:query"
    payload = json.dumps({
        "ids": device_ids
    })
    response = requests.request("POST", url, headers=headers, data=payload)
    if response.status_code != 200:
        print_error_and_exit("Status code is not 200", response.text)

    # Parse the API resposne as the json data
    response_json = json.loads(response.text)
    print("Devices with locations:")
    pprint.pprint(response_json)
    print("*** Numbe of devices with locations:", len(response_json), msg_connection_status)

    device_ids_with_locations = list(response_json.keys())
    print(device_ids_with_locations)

    device_ids_without_locations = list(set(device_ids) - set(device_ids_with_locations))
    print("*** IDs of devices without locations:", device_ids_without_locations, msg_connection_status)
    print("*** Number of devices without locations:", len(device_ids_without_locations), msg_connection_status)

    global device_without_locations
    for i in data_devices:
        if str(i["id"]) in device_ids_without_locations:
            device_without_locations.append(i)
    print("*** Devices without locations:",  msg_connection_status)
    pprint.pprint(device_without_locations)
    print("*** Number of devices without locations:", len(device_without_locations), msg_connection_status)


def export_csv():
    df = pd.json_normalize(device_without_locations)
    df.to_csv("result.csv", index=False)
    if os.name == "nt":
        os.system("type result.csv")
    else:
        print("Print the firt 3 lines of result.csv")
        os.system("cat result.csv")
    print("*** Location of the exported file: " + os.getcwd() + "/result.csv")


# main
display_usage()
get_access_token()
list_devices(connected_only=True)
get_devices_without_locations(connected_only=True)
export_csv()
​

Hi @Jason Cadenhead,

I was just aware of another method that is more easy to use. You can just click the download button at the upper left corner of the Manage > Devices page to export the devices list. It should download all devices if you don't have any filter applied. Once the csv file is downloaded, you can use Excel's "Sort & Filter" function to get the data you need.​

Thank you so much, Paul. This is exactly what my team and I were looking for. The python script is very interesting as well, it just gives me more curiosity to create my own scripts.​
GTM-P2G8KFN