GPS microservice API Reference


Developers can chose any programming language to develop gps app. All that app needs to do is to invoke well know GPS service API's to configure and retrieve gps data. This document talks in detail the steps to do that.Most of the code snaphots are here in python.

The GPS Microservice is available as a IOx installable and appears as below in the Microservice name-space.

 [{id: "urn:cisco:system:service:protocolHandler:gps", api-version: 1,version: "1.5.0"}]

An application should declare dependency on GPS service in its package.yaml.Once the dependency is declared, IOx hosting framework would ensure that GPS service is deployed before the application can be deployed on the IOx enabled device.Also the App package.yaml needs to be an oauth client.This required to get access token which is provided as part of any request to NBI.

App can have any other logic/functionality apart from the steps mentioned here. Please tune the cpu, memory and disk requirements based on testing and profiling.Below snapshot is just an example.

Below is snapshot of package.yaml section which highlights the above mentioned requirements


``` depends-on: packages: - name: "IOxGPS" version: "1.5.0"

resources: profile: custom cpu: "100" disk: "10" memory: "30" oauth: [OauthClient]

<br>


### Steps in App development 

- Get Oauth access token.IOx will provide well defined env variables which app can access.
- Use this token for any communication with NBI like setting the GPS config, getting GPS data
- Configure GPS service via REST API and verify it is successful
- If configured for streaming, subscribe over websocket for streaming data
- If streaming is disabled, you can invoke REST API of gps service to get the data
- Parse the payload response and check for return codes before parsing gps data
- If success , parse the gps data using the JSON schema mentioned below
- Check for right error codes explained below

Below section talks in details with code snippets on which environment variables to use , which APIs to invoke, sample GPS config payload format



**Get Oauth access token from IOx CAF**



API to get access token from IOx
Form the Url using env variables as mentioned below for requesting access token
<br>

client_id = os.environ["OAUTH_CLIENT_ID"] client_secret = os.environ["OAUTH_CLIENT_SECRET"] server_ip = os.environ["OAUTH_TOKEN_SERVER_IPV4"] server_port = os.environ["OAUTH_TOKEN_SERVER_PORT"] api_path = os.environ["OAUTH_TOKEN_API_PATH"] token_url = "https://"+server_ip+":"+server_port+api_path

Do a POST call on the url derived above

print "client_id: "+client_id print "client_secret: "+client_secret print "token_url: "+token_url

tokens = urlparse.urlparse(token_url) if tokens.scheme == 'https': con = httplib.HTTPSConnection(tokens.netloc) else: con = httplib.HTTPConnection(tokens.netloc)

con.request( "POST", tokens.path, urlencode({'grant_type': 'client_credentials'}), { "Content-Type": "application/x-www-form-urlencoded", "Authorization": "Basic " + base64.b64encode("%s:%s" % (client_id, client_secret)) } )

Parse the access token from the JSON response. response = con.getresponse() if response.status / 100 != 2: raise Exception("oauth token url returned %s" % response.status)

access_token = json.loads(response.read())['access_token'] con.close()

<br>

### IOxGPS service API's



**Configuring the  IOxGPS service**

GPS micro service enquires the platform feature for GPS co-ordinates refresh, every time the REST invocation happens.

GPS microservice provides below REST API to enable GPS data streaming. The REST API supports POST method for configuration of streaming interval and the topic on which to subscribe to the GPS Stream.

POST on **https://nbi_IP_ADDRESS:nbi_TCP_9999_PORT/api/v1/mw/gps/config**

POST on https://nbi_IP_ADDRESS:nbi_TCP_9999_PORT/api/v1/mw/gps/config Sample JSON payload for above API

{
"gps-interval-seconds": 5,
"streaming-enabled": true,
"topic" : "gps" }

nbi_IP_ADDRESS is the env variable exposed to the app.It provides NBI IP to communicate to. nbi_TCP_9999_PORT is env variable exposed to the app.It provides NBI Port


- **gps-interval-seconds** value specifies the interval at which GPS data should be
  streamed when streaming is set to "true"
- **streaming-enabled** option specifies if websocket streaming needs to enabled or
  disabled.If disabled, app can invoke rest api to get the GPS data
- **topic** specifies the topic on which gps data should be streamed.App should use
  the same topic name while subscribing for gps data

Sample python code to configure the GPS service

<br>
nbi_label = "nbi"
nbi_host = os.environ[nbi_label+"_IP_ADDRESS"]
nbi_port = os.environ[nbi_label+"_TCP_9999_PORT"]

with open ("resources/"+fileName, "r") as myfile:
    payload=myfile.read()
print("payload %s" % (payload)) 
send = {}
headers = {"Content-Type": "application/json",
           "Authorization": "Bearer "+oauth.access_token,
           "Accept": "text/plain"}

con = httplib.HTTPSConnection("%s:%s" % (nbi_host, nbi_port))
con.request(
    "POST", 
    "/api/v1/mw/gps/config",
    payload,
    headers
)
response = con.getresponse()
print("%s %s %s" % (response.status, response.reason, response.read())) 
if response.status != 200 :
    print ("Failed")
    con.close()
    return -1
print ("Success")

<br>



**Rest API to get the GPS configuration**

API to get the configuration applied.

GET on  **https://nbi_IP_ADDRESS:nbi_TCP_9999_PORT/api/v1/mw/gps/config**

Sample response payload

{ "value": { "gps-interval-seconds": 5, "streaming-enabled": true, "topic": "gps" } }




Sample python code to get the GPS config
<br>
nbi_label = "nbi"
nbi_host = os.environ[nbi_label+"_IP_ADDRESS"]
nbi_port = os.environ[nbi_label+"_TCP_9999_PORT"]

print("%s %s" % (nbi_host, nbi_port)) 
headers = {
    "Authorization": "Bearer "+oauth.access_token
}

con = httplib.HTTPSConnection("%s:%s" % (nbi_host, nbi_port))
con.request(
    "GET", 
    "/api/v1/mw/gps/config",
None,
    headers
)

<br>



**REST API to get  the  GPS data**

GET on **https://nbi_IP_ADDRESS:nbi_TCP_9999_PORT/api/v1/mw/gps/location**

Sample response payload
{
  "message": {
    "altitude": "5454.000000",
    "latitude": "42.915249",
    "longitude": "75.041801",
    "return-code": "200",
    "timestamp": "Sun Dec 17 23:13:05 2017"
  },
  "topic": "gps"
}





**API to get streaming data**

To get streaming data , IOxGPS service needs to be configured with "streaming-enabled" set as "true" as explained above.

**Websocket URL**

**wss://nbi_IP_ADDRESS:nbi_TCP_9999_PORT/api/v1/mw/topics/gps**



Sample python code to create websocket connection to get the streaming data

<br>
print "Started thread"
nbi_label = "nbi"
nbi_host = os.environ[nbi_label+"_IP_ADDRESS"]
nbi_port = os.environ[nbi_label+"_TCP_9999_PORT"]
topic = topicName
url = "wss://%s:%s/api/v1/mw/topics/%s" % (nbi_host, nbi_port, topic)

websocket.enableTrace(True)
try:
    ws = websocket.create_connection(                            
               url,                                                  
               header = ["Authorization: Bearer " + oauth.access_token],
               sslopt= {"cert_reqs": ssl.CERT_NONE}
             ) 
except Exception, err:                                                              
    print Exception, err
    time.sleep(2)
<br>



**GPS data Payload Message format and schema**

*GPS data JSON payload*
e.g

{ "message": { "altitude": "5454.000000", "latitude": "42.915249", "longitude": "75.041801", "return-code": "200", "timestamp": "Sun Dec 17 23:13:05 2017" }, "topic": "gps" }


JSON schema for above gps data payload 

<br>

{ "definitions": {}, "$schema": "http://json-schema.org/draft-06/schema#", "$id": "http://example.com/example.json", "type": "object", "properties": { "message": { "$id": "/properties/message", "type": "object", "properties": { "altitude": { "$id": "/properties/message/properties/altitude", "type": "string", "title": "The Altitude Schema.", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "5454.000000" ] }, "latitude": { "$id": "/properties/message/properties/latitude", "type": "string", "title": "The Latitude Schema.", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "42.915249" ] }, "longitude": { "$id": "/properties/message/properties/longitude", "type": "string", "title": "The Longitude Schema.", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "75.041801" ] }, "return-code": { "$id": "/properties/message/properties/return-code", "type": "string", "title": "The Return-code Schema.", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "200" ] }, "timestamp": { "$id": "/properties/message/properties/timestamp", "type": "string", "title": "The Timestamp Schema.", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "Sun Dec 17 23:15:05 2017" ] } } }, "topic": { "$id": "/properties/topic", "type": "string", "title": "The Topic Schema.", "description": "An explanation about the purpose of this instance.", "default": "", "examples": [ "gps" ] } } }

<br>

**Error codes**

Applications should check the return-code value.Some of the common error conditions are,
1.Antenna is not is line of sight, or not connected
2.IOS configuration is not done properly

{ "message": { "description": "GPS data not available. Check the IOS configuration", "return-code": "404" }, "topic": "gps" }




### **Next steps**

**[Next Chapter](gps-verify.md)** - Verifying gps data stream


To learn more about how to develop GPS App use below link:

- **[GPS App development](../../../../overview/iox-gps-app-tutorial.md)** - An example on how to develop and package GPS App using IOx gps service 
- **[Reference GPS App](https://github.com/CiscoIOx/iox-services-samples/tree/master/gpsApp)**  - Sample GPS App on github

- **[IOx Services developer guide](../../../services-developer-guide/index.md)** - IOx Services developer guide