CloudLocate Service-to-Service access using MQTT

Introduction

Service-to-Service access enables you to leverage the power of CloudLocate sending the GNSS measurements from your application platform, instead of directly using your IoT device.

This documentation will guide you through the process of setting up your Thingstream account for service-to-service access and using MQTT to publish device measurements to the platform .

As an alternative option, you can publish the measurements using the Thingstream Customer API as described in this guide

Prerequisites

The prerequisites to complete the procedure are:

  1. you have access to the u-blox Thingstream portal and you have already created a domain

  2. you have registered a credit card in the portal or you have a credit line active.

  3. You have a basic knowledge of the Data Flow Manager. More information is available in our Flows guide.


Procedure overview

The mains steps of this procedure are

  1. Create an IP Thing

  2. Import the desired flow from the templates list

  3. Modify the flow (only if any customization is required)

  4. Deploy the flow

  5. Send the measurement and get the position back

Create an IP Thing

The first step is to create an IP thing; this is used to inject data in the platform


  1. Click on "Things" on the left side panel, which will open up Things page

  2. Click on "Add Thing" button at the top right of the page, which will open a dialog where you can add a thing

  3. On the dialog that pops up, click "Add IP Thing"

When you click "Add IP Thing" button, a new screen (in the same dialog) will appear where you will have to enter a name for the thing, and click "Add Thing".


4. Give your "Internet Thing" a name

5. Click "Add Thing"

Once you've created a thing, you will be asked to select a plan. You need to select an MQTT Now plan in order to use service-to-service access. All pricing plans are available in the pricing section under the MQTT now panel. You can start with the developer plan or select the plan that suits your needs best, and click "Activate".

6. Select a plan that suits your needs

7. Click "Activate"

Once you've activated the device, click "View details" to see details of the Thing you just created.

8. Once you've activated the device, click "View details" to see details of the thing you just created.

9. Copy the "DeviceID" using the icon on the right side. You need this for what is to come next.

Still need help?

CloudLocate getting started guide

Service to Service access using MQTT

If you need more help or have any questions, please send an email to support@thingstream.io.

Import a Flow from the template list

The next step is to create a Flow to call the CloudLocate service. We've created a template to help you get started.

  1. Click "Flows" on the sidebar .

  2. Click "Create Flow", and then select "From Flow Library".

3. Click on "IoT Location-as-a-Service"

4. Click "CloudLocate Position"

5. Click "Copy" dropdown and select "Copy to domain & edit" which will take you to the flow editor

As last step:

  • remove the connection between Append Identity node and http request node

  • wire Append Identity node with Thingstream publish node

Flow Explanation

Let's look at what's happening in the flow, in detail, before we take it for a test drive (for that you need to "Deploy" the flow first, which we will cover in next section).

Summary of the flow

Once the flow is deployed, it will subscribe to a topic (via thingstream subscribe node), convert the incoming payload to json (via json node), save the identity in the payload (SaveIdentity node) before passing the measurement data to the CloudLoate node. The calculated position is passed to the AppendIdentity node, which will add back the identity saved earlier, and will then do two things: [1] output the response as a debug message (via the msg.payload (debug) node), and [2] send the payload in the body of an HTTP POST request (via the HTTP request node).

Now let's look at each node in detail:

thingstream subscribe node

This node acts as an input to the flow. When we deploy the flow, we associate a topic with it, and whenever something is published on that topic (via the Publish API or an MQTT publish), it gets injected into the flow using this node.

This node does not need any configuration.

json node

This node converts the incoming payload from a JSON string to a JSON object representation.

SaveIdentity (function) node

This is a JavaScript function node, which has been renamed to "SaveIdentity". The job of this node is to extract the "identity" header from the incoming payload and save it as a flow variable (to be used later). This is necessary as the CloudLocate node requires only the base64 encoded measurement as an input.

The "Identity" header is used to identify the device sending the measurement data. If you do not need this identification, you don't have to set this header.

If you "double-click" this node, it will open up function code, which will look like:

flow.set(`identity:${msg.messageId}`, msg.payload.headers.identity);

return msg;

CloudLocate node

This node calls the CloudLocate service and returns a calculated location.

AppendIdentity (function) node

The job of this function node is to put back identity header's value as part of payload. Once that is done, the flow variable is reset. The output from this node is used by the two following nodes

msg.payload (debug) node

This node outputs debug data to the "debug" tab on the right-hand side of the editor.

http request node

This node is responsible for making an HTTP(s) request which could be used to POST the calculated location together with the identity value (if provided). Details of how to use this, and all nodes, can be found in the "info" tab on the right-hand side of the editor

thingstream publish node

The thingstream publish node can be used to publish the result of the flow to another Thingstream MQTT topic.

email node

The email node can be used to send the flow results by email. Simply connect and configure email node (by looking at its info tab), and link it with the AppendIdentity function node.

sms node

You may also wish to send an SMS with the location result. Just connect the output of the AppendIdentity node to the sms node, and configure it as required.

Flow Deployment

Before you can start using the flow, it needs to be deployed.

  1. Click "Deploy" at top right corner of the screen

2. You need to setup subscription before flow can be deployed. Click "Edit" against "Subscription" to configure it.

3. In the search box, start searching for the topic that you want the flow to subscribe to.

4. If the topic already exists you can pick it from the list, otherwise click Add.

5. Click "Done"

6. Click "Deploy" to deploy the flow.

7. This flow contains premium extension nodes. The popup that shows up warns you of this, and has a link to pricing page for details. If you're OK with the cost, click "Deploy".

Once the flow is deployed, the top part of the pages changes to show you which topic the flow is subscribed to

Send Measurement using MQTT client

You can use any MQTT client to send measurement data, and receive the calculated position data back

NOTE: Maximum payload size of an MQTT 8092 bytes.

You'll find the details that you need in order to configure your MQTT client in the Thing Details page.

Get Device Level Credentials

Go to Things > Click on the name of the thing we created earlier, and it will open up "Thing Details":

  1. Make note of Hostname

  2. Make note of Client ID (this is the Device ID)

  3. Make note of Username

  4. Make note of Password

You will need all these values to configure your MQTT client.

  1. Use the thingstream publish node to receive the calculated position back using MQTT. Double click on the node and define the topic to which you want to publish the calculated location. In the picture we are using as an example, a topic named s2s/CloudLocate/position

Sample MQTT client code in Python

You can use the following MQTT client code, written in Python, to send measurement data and get the response. The following script:

  • publishes GNSS sample measurement into the MQTT topic specified above during Flow deployment

  • subscribes to a topic to receive the calculated position. It can be the same one above or a different one. It shall be the one configured in the publish node in the flow .

For testing phase we suggest you to configure in the script and in the thingstream publish node, the same topics so that you can use a unique script to send the measurement and receive back the position

The CloudLocate service endpoint expects to received a JSON formatted payload like the one below:

{

"body":"Base64 encoded measurement (String)",

"headers":{"UTCDateTime": "yyyy-mm-ddThh:mm:ss" , "identity": "my_device"}

}

where identity field is optional and is your preferred device identifier and should be different for every device. See the two sample measurement below for a real example.

The measurement in the body field shall be a Base64 encoded string:

  • if you are using u-center to obtain the GNSS measurement the output is binary file with .ubx extension. To convert the file to Base64, you can use to this online converter.

  • If you are getting the measurement directly from the receiver, without using u-center, be sure to make the conversion into Base64 in your own code

When using the sample code below to test the service you need also to escape the JSON payload so that it can be recognized as a properly formatted JSON object. You can simply do this using this online tool. Just copy the entire JSON payload in the tool to obtain the exact payload to be sent to CloudLocate service endpoint.

Note: remember that you can avoid to add the "UTCDateTime" parameter if you can send the measurements within 1 min from when it has been generated in the GNSS. If you are not in this use case you need always to add that time field.

To configure the script (as done in the Getting started guide):

  1. Set Hostname, DeviceID, username and password for the MQTT client; you can retrieve these information in the Credential tab in the Thing details section of the IP Thing created previously

  2. Set the MQTT_TOPIC variable. This is the topic where the script publish the measurement. Use the one selected during the flow deployment

  3. Set the subscription topic in MQTT_SUB_TOPIC variable, where the location result will be published by the CloudLocate node. Set it accordingly to what you have configured in the thingstream publish node. It can be the same one as in the previous step or a different one

  4. Add the measurement (JSON formatted payload) in the MQTT_MSG variable in this format

{

"body":"Base64 encoded measurement (String)",

"headers":{"UTCDateTime":"yyyy-mm-ddThh:mm:ss" , "identity": "my_device"}

}

Below the script you can find two versions with and without identity field. Whichever you plan to use remember, to escape it and configure the identity if needed.

  1. run the script; the calculated position should be now visible in the output of the script. For debug purpose you can always see the output in the debug node


import paho.mqtt.client as mqtt

import time


Hostname = "" #mqtt.thingstream.io

DeviceID = "" #find it in the IP Thing just created in the credential tab

Username = "" #find it in the IP Thing just created in the credential tab

Password = "" #find it in the IP Thing just created in the credential tab



# GNSS Sample measurement

MQTT_MSG = "" #Escaped payload

MQTT_TOPIC = "" #use the topic selected during Flow deployment

MQTT_SUB_TOPIC = "" #use the topic selected during Flow deployment


def message_handler(client, userdata, message):

print("\n\nReceived message\n" + str(message.payload.decode("utf-8")) + "\n" + message.topic + "\nQoS: " + str(message.qos))



client = mqtt.Client(DeviceID)

client.username_pw_set(username = Username, password = Password)

client.connect(Hostname)

client.on_message = message_handler

msg_counter = 0

if MQTT_SUB_TOPIC:

client.subscribe(MQTT_SUB_TOPIC)

client.loop_start()


while msg_counter < 2:

msg_counter += 1

client.publish(MQTT_TOPIC, MQTT_MSG)

print("msg #{0} published".format(msg_counter))

time.sleep(60)

client.loop_stop()

Sample measurement (unescaped) without identity

{

"body": "tWICFMQBAQAAAHjedx2oYxweyKd3HXjedx143ncdAAD//wAAAAAAABEuAAAAAAAAAAABeykB/wsAAJwMAAAkA40CZisZAAAAAAABiCgBCAwAAKUMAAAdAq4BmO8QAAAAAAAAGyIBP8T//zPB///9AKECP+8HAAAFAAAAHCUB9wsAAJQMAADuArEAQncXAAAAAAACBCgB5+P//3ji//9qA5gCB1wbAAAAAAAAEScBKEUAAK9IAABhAGgAlAkDAAAAAAAADiYBc/b///b1//8uAvoAU3YRAAAAAAACJC4BRgIAAGQCAABUCkQDObsSAAIAAAAACiMBGc7//47L//9lALEALSoDAAAAAAACBSoCakAAALNDAAAHCF4B0EoAAAIAAAACCS4BWRUAAG8WAABqCaMAIGQLAAIAAAAAIC0Bv+7//97t//8LAmoB7F4QAAAAAAAAFjABPRgAAHoZAAAoABMCeEQBAAAAAAAAFS4BwQYAABoHAACOAy4AfHccAAAAAAAACCwB7dD//4bO//9JAG0DcE8CAAAAAAAAAy0BFzoAAA49AABNAiMC5HASAAAAAAAAATABWB0AANceAAAKAUgDplgIAAAAAABDOA==",

"headers": {"UTCDateTime": "2021-05-28T17:19:37" }

}

Sample measurement (unescaped) with identity

{

"body": "tWICFMQBAQAAAHjedx2oYxweyKd3HXjedx143ncdAAD//wAAAAAAABEuAAAAAAAAAAABeykB/wsAAJwMAAAkA40CZisZAAAAAAABiCgBCAwAAKUMAAAdAq4BmO8QAAAAAAAAGyIBP8T//zPB///9AKECP+8HAAAFAAAAHCUB9wsAAJQMAADuArEAQncXAAAAAAACBCgB5+P//3ji//9qA5gCB1wbAAAAAAAAEScBKEUAAK9IAABhAGgAlAkDAAAAAAAADiYBc/b///b1//8uAvoAU3YRAAAAAAACJC4BRgIAAGQCAABUCkQDObsSAAIAAAAACiMBGc7//47L//9lALEALSoDAAAAAAACBSoCakAAALNDAAAHCF4B0EoAAAIAAAACCS4BWRUAAG8WAABqCaMAIGQLAAIAAAAAIC0Bv+7//97t//8LAmoB7F4QAAAAAAAAFjABPRgAAHoZAAAoABMCeEQBAAAAAAAAFS4BwQYAABoHAACOAy4AfHccAAAAAAAACCwB7dD//4bO//9JAG0DcE8CAAAAAAAAAy0BFzoAAA49AABNAiMC5HASAAAAAAAAATABWB0AANceAAAKAUgDplgIAAAAAABDOA==",

"headers": {"UTCDateTime": "2021-05-28T17:19:37" , "identity": "my_device" }

}

Supported hardware

To evaluate the service, you can use any of the u-blox GNSS modules that support RXM-MEASX message (i.e. M8, M9 and M10). You have at least two option

  • If you are planning to use your own cellular modem or the RXM-MEASX message is transferred over a non-celllular interface, the simplest way is to purchase one of the following kits: EVK-M8, EVK-M9 or EVK-M10 from the u-blox product selector

  • If you want to use a u-blox cellular modem with intergated GNSS you can purchase an EVK-R510M8S.