Losant Brings Connected Solutions to Market - mcThings Cloud Partner


Contents  



Losant Setup



Go to https://accounts.losant.com/ to create your Losant account

After verifying our email address you will be presented with a page offering:

  1. Tutorial
  2. Instruction to build a weather station
  3. Become a developer

In this instance we can skip to “No thanks, I am ready to start building!”

On the following page we can choose various Application templates. For this lesson we will choose “Blank Application”.

Let's name our Application. Since we are using an Oyster asset tracker in the guide, we will name it Oyster and create our first Application.

Now we should land on our Losant Home Dashboard.

Let’s start by adding our device. Choose “Device” in the left side panel and then choose “Create new Device” in red.

Choose Standalone Device.

To create a new device we just need to add a name we want to use. For Key we will use EUI and for Value we will use our Device EUI as shown in the image below. 

Name: Oyster

Key: EUI

Value: put your “Device EUI” here

Next, under Device attributes add:

Attribute Name: position

Data Type: GPS

Attribute Name: battery

Data Type: Number

Then click “Update Attributes”


Now in the left panel we will choose Webhook and add a new webhook.

In this instance we will just name the webhook “Loriot webhook” and click “Create webhook”

Your new Webhook should appear in the top right corner. Copy the webhook.

LORIOT Configuration



Now to connect your Losant platform with the LORIOT network server, go to your LORIOT UI as shown below.

Choose Applications, then Manage Outputs.

Add output as HTTP Push and place the webhook from Losant in the Target URL for POSTs field.


Now we will go back to Losant to finalize the process.


Losant Workflow Configuration


Now we can create our application Workflow.

In this instance we will chose the name “Losant integration”

Now we can create a visual representation of the integration. Lets choose the following functions shown below to get started and place them as shown on the screen. The webhook will need to be given a name, in this case we used "Webhook"

Hint- If you click on the connecting threads they will be highlighted and you can press “Delete” to remove them. Then click on the box you want to create a thread from and drag it to the box you want to connect.

The "Debug" boxes can have a message assigned for monitoring each stage of the flow when doing debugging. 

We assigned the following messages:

Debug 1: Message received

Debug 2: Not rx message

Debug 3: Not working device

Debug 4: Decoded result

Debug 5: Not position message

Under "Conditional" change the expression to - {{data.body.cmd}} === 'rx' 

Now let’s add “Device: Get” and connect it to the Conditional above choosing these settings-

Find by: Match any tags query

Key Template: EUI

Value Template: {{data.body.EUI}}


Include no Attribute and click “return tags as an object map instead of an array”

Result Path: working.device

This is connected to a "Conditional" with expression: {{working.device}} !== null

Connect the previous "Conditional" to “Function” and add this expression:



var bytes = [];

var hexString = payload.data.body.data;

while (hexString.length >= 1) {

  bytes.push(parseInt(hexString.substring(0, 2), 16));

  hexString = hexString.substring(2, hexString.length);

}

const port = payload.data.body.port


var decoded = {};

decoded.deviceId = payload.working.device.deviceId


 if (port === 1)

 {

 decoded.type = "position";

 decoded.latitudeDeg = bytes[0] + bytes[1] * 256 +

 bytes[2] * 65536 + bytes[3] * 16777216;

 if (decoded.latitudeDeg >= 0x80000000) // 2^31

 decoded.latitudeDeg -= 0x100000000; // 2^32

 decoded.latitudeDeg /= 1e7;


 decoded.longitudeDeg = bytes[4] + bytes[5] * 256 +

 bytes[6] * 65536 + bytes[7] * 16777216;

 if (decoded.longitudeDeg >= 0x80000000) // 2^31

 decoded.longitudeDeg -= 0x100000000; // 2^32

 decoded.longitudeDeg /= 1e7;

 decoded.inTrip = ((bytes[8] & 0x1) !== 0) ? true : false;

 decoded.fixFailed = ((bytes[8] & 0x2) !== 0) ? true : false;

 decoded.headingDeg = (bytes[8] >> 2) * 5.625;


 decoded.speedKmph = bytes[9];

 decoded.batV = bytes[10] * 0.025;

 decoded.manDown = null;

 }

 else if (port === 4)

 {

 decoded.type = "position";

 decoded.latitudeDeg = bytes[0] + bytes[1] * 256 + bytes[2] * 65536;

 if (decoded.latitudeDeg >= 0x800000) // 2^23

 decoded.latitudeDeg -= 0x1000000; // 2^24

 decoded.latitudeDeg *= 256e-7;


 decoded.longitudeDeg = bytes[3] + bytes[4] * 256 + bytes[5] * 65536;

 if (decoded.longitudeDeg >= 0x800000) // 2^23

 decoded.longitudeDeg -= 0x1000000; // 2^24

 decoded.longitudeDeg *= 256e-7;

 decoded.headingDeg = (bytes[6] & 0x7) * 45;

 decoded.speedKmph = (bytes[6] >> 3) * 5;

 decoded.batV = bytes[7] * 0.025;

 decoded.inTrip = ((bytes[8] & 0x1) !== 0) ? true : false;

 decoded.fixFailed = ((bytes[8] & 0x2) !== 0) ? true : false;

 decoded.manDown = ((bytes[8] & 0x4) !== 0) ? true : false;

 }

 else if (port === 2)

 {

 decoded.type = "downlink ack";

 decoded.sequence = (bytes[0] & 0x7F);

 decoded.accepted = ((bytes[0] & 0x80) !== 0) ? true : false;

 decoded.fwMaj = bytes[1];

 decoded.fwMin = bytes[2];

 }

 else if (port === 3)

 {

decoded.type = "stats";

 decoded.initialBatV = 4.0 + 0.100 * (bytes[0] & 0xF);

 decoded.txCount = 32 * ((bytes[0] >> 4) + (bytes[1] & 0x7F) * 16);

 decoded.tripCount = 32 * ((bytes[1] >> 7) + (bytes[2] & 0xFF) * 2

 + (bytes[3] & 0x0F) * 512);

 decoded.gpsSuccesses = 32 * ((bytes[3] >> 4) + (bytes[4] & 0x3F) * 16);

 decoded.gpsFails = 32 * ((bytes[4] >> 6) + (bytes[5] & 0x3F) * 4);

 decoded.aveGpsFixS = 1 * ((bytes[5] >> 6) + (bytes[6] & 0x7F) * 4);

 decoded.aveGpsFailS = 1 * ((bytes[6] >> 7) + (bytes[7] & 0xFF) * 2);

 decoded.aveGpsFreshenS = 1 * ((bytes[7] >> 8) + (bytes[8] & 0xFF) * 1);

 decoded.wakeupsPerTrip = 1 * ((bytes[8] >> 8) + (bytes[9] & 0x7F) * 1);

 decoded.uptimeWeeks = 1 * ((bytes[9] >> 7) + (bytes[10] & 0xFF) * 2);

 }


 return decoded;


Connect the "Function" to a "Switch":

Switch template: {{type}}

Case template: position


Now let's add a "Devices: State"

Use a Device ID specified on the current payload: deviceId

Data method : Individual Fields

Attribute: position    Value: {{latitudeDeg}},{{longitudeDeg}}

 Attribute: battery   Value: {{batV}}

Use the time of the current payload


Now we can click the “Save and Deploy” button in the top right corner


Losant Dashboard Configuration


Now we will go and add our Dashboard to visualize the data coming in. Choose the dashboard name you want to use.

Now we will select "Add a block" to display it on the dashboard.

On the "GPS History" block choose "Customize".

Let's give our Block a name. We used "Oyster GPS."

In the "Select by Ids and tags" field choose your tracking device.

In the "Populate from attribute data" section choose "position". Everything else should be left as default settings. Now select "Add Block".

Congratulations! You should now be able to begin visualizing the GPS data in your dashboard.