Skill Level: Intermediate

Requires basic Linux skills

Skyhook’s (www.skyhook.com) Precision Location system provides a simple, lightweight geolocation API for IoT devices. Our Wi-Fi based location solution can locate any connected device that is able to perform a Wi-Fi scan and communicate with the cloud.


  1. Wi-Fi capable IoT Device
  2. Cloud application using the Skyhook Precision Location API
  3. Skyhook Precision Location URL and API Key


  1. What is demonstrated in this recipe?

    This recipe includes detailed steps to locate Watson IoT devices using Wi-Fi scans (see our video for an illustration). The recipe includes an example of how to locate a Raspberry PI device. Similar steps can be utilized to locate any other Watson-connected device that can scan nearby Wi-Fi Access Points (APs).

    After following the recipe steps, location data (latitude, longitude and uncertainty radius) will be available for each device. The data can be utilized to locate, track and manage devices or resources or perform geofencing and other geolocation use cases.

    Location Process:

    • The device collects information from all of the APs, cellular, and GPS sources within range
    • Wi-Fi information collected includes: SSID, MAC Address and Signal Strength
      • Communication with the Wi-Fi APs is not required
      • Devices in urban areas typically receive information from greater than 40 Wi-Fi APs
      • Using Skyhooks Precision Location API, the requesting application (such as IBM BlueMix), sends the Wi-Fi information collected by the device to the Skyhook cloud servers via XML over HTTPs.
    • The device location is calculated by comparing the observed power level of various Wi-Fi APs with the location of APs contained in the Skyhook database. Correlation between the APs observed by the device and those contained in the Skyhook database is accomplished using the SSID associated with each AP.

    NOTE: Skyhook currently supports GPS and Cellular location methods if those capabilities are available from the device. 


    For more information, see our video illustrating this recipe, or click over to Skyhook.com

  2. Connect your Device to Watson

    Connect your device to Watson using one of the recipes found on the IBM Developer Works site such as:


    The Precision Location API supports any IoT device with the ability to perform and send a Wi-Fi scan.

  3. Add an Event to Send a Wi-Fi Scan

    After the device is connected and sending events to the Watson IoT client, insert the following sample code into your device application to allow it to include the Wi-Fi scan in the events (Note: the examples shown assume the use of Python, but the same results can be obtained with a variety of other languages):

    • Perform a Wi-Fi scan. If running on a Linux device use the following command:
    proc = subprocess.Popen(["/sbin/wpa_cli", "scan_results"], stdout=subprocess.PIPE, universal_newlines=True)  
    • Parse the scanned result and format into a JSON event including the array of APs in the following format:
    [[mac, rssi, ssid], [mac, rssi, ssid]]EG: [['001a1ee99745', '-47', 'tp-wpa2'], ['ee99744', '-47', 'tp-wpa']]  
    • Where:
      • mac (access point mac address identifier, 48bit string with no colons)
      • rssi (signal strength in dbm)
      • ssid (optional string including Wi-Fi network name)
    • Send the event with JSON Wi-Fi scan to the Watson IoT Cloud see the example below:
    aps = wifi_scan();
    data={'wifiscan' : str(aps) }
    client.publishEvent("status", "json", data)

    Sample Python device code for a Raspberrry Pi to establish a connection with Watson, perform a Wi-Fi Scan and send it to the Cloud can be found here:


  4. Obtain a Location API Key from Skyhook

    A Location API key and URL may be obtained from Skyhook by creating a user account and a Precision Location project at: https://my.skyhookwireless.com/


    Skyhook offers temporary demonstration keys and URLs at no charge.

  5. Integrate the Skyhook Precision Location API into your Application

    Create an application to process the device data (events).

    To locate your device based on the reported Wi-Fi scan events you must first configure your application to subscribe to device-reported events including JSON formatted Wi-Fi scans.

    Configure your application via the following steps:

    1. Use the API key assigned by Bluemix for the device (Raspberry Pi for example) to receive and send (or subscribe). This can be done on a Python, Node-RED or Java application. Follow one of the IBM recipes to subscribe to device-reported events (example for a Node-RED application: https://developer.ibm.com/recipes/tutorials/creating-a-nodered-application-on-bluemix/)
    2. When your application has subscribed and received events with a JSON formatted Wi-Fi scan from your device, use the Skyhook Precision Location API to position the device. The API is based on the Python function available at: https://github.com/SkyhookWireless/ibm-bluemix/tree/master/skyhook-app
    3. To integrate the function into your application, you must first initialize it by providing the Skyhook Precision Location API Key and URL obtained in the previous step.


    skyhook_sdk_key = '1234567893858358385skjfhsdhjfsdfkjfhsdkwu238389839834738758sZdRL' # example key obtained from Skyhook
    skyhook_url = 'https://api.skyhookwireless.com/wps2/location' # example url obtained from Skyhook
    # instantiate Skyhook class
    skyhook = Skyhook(skyhook_sdk_key, skyhook_url)

    When the event with a Wi-Fi scan is available use the skyhook.getlocation() API as shown below to locate the device:

     def event_callback(event):
    print("%-33s%-32s%s: %s" % (event.timestamp.isoformat(), event.device, event.event, json.dumps(event.data)))
    device_type, device_id = event.device.split(':')
    if 'wifiscan' in event.data:
    aps = eval(event.data['wifiscan'])
    if len(aps) == 0: return
    fix = skyhook.get_location(device_id, aps)
    if fix is None: return

    except Exception, ex:
    print 'exception in event_callback:', ex

    The skyhook.getlocation() API includes two parameters:

    • device_id: id of the device.This can be the device mac address or Watson allocated ID or any other unqiue ID.
    • aps: array of Wi-Fi access-points in the following format: [[mac, rssi, ssid], [mac, rssi, ssid]] Example: [[001a1ee99745, -47, tp-wpa2], [001a1ee99744, -47, tp-wpa]]


    The function returns device location in the following format: {latitude’: 40.064514, longitude’: -75.46025, accuracy’: 13}

  6. Utilize IoT Device Location

    Utilize the locations for your own application. The location can be:

    Some third party recipes that display device locations on a map require the device itself to report the location (latitude/longitude). In that case, your application can mimic the device to send events on its behalf. This can be done in a Node-RED application as well using the “ibmiot” output node.

4 comments on"Skyhook Precision Location for IoT"

  1. StanfordDad June 28, 2016

    I am getting
    HTTP Error 401: Unauthorized

  2. Hello,
    I’ve been trying to start up this app https://github.com/SkyhookWireless/ibm-bluemix/tree/master/skyhook-app for a few days and it’s been impossible. Does anybody have more info. about it? thanks

Join The Discussion