How to create your own Network to integrate with TagoIO

@Ricardo Stoklosa

This is a quick tutorial that shows how to create a Network for your devices using TagoIO. By creating your own network you will be able to push data to TagoIO in the correct device based on it’s serial number, using your own protocol. There are several Networks available for you to use (learn about current Networks here), if you need something that is not in the list you can build yours.

By following all the steps in this article you will end up with:

  • An network capable of integrate your sensors to TagoIO, using your own protocol.
  • A connector that makes use of the network you created.
  • A middleware server in TCP/IP protocol, that you can use as example to build your own.

Creating the network

First you need to access the Integrations menu in the top right corner. Now go to Network > Add network and create the Network.

The edit page should show up, here you can personalize your Network as you like. We’re going to set the serial option on the right as required and set also the format to our serial to be like “000-000-000”.

Now create and copy the token in the token menu, we’ll need that later.

Setting up a connector

For the network to work properly a connector is needed. To create a connector go back to Integrations menu and create a connector instead. In the Add connector form, select the created network.

Having done that, you will be able to see your Network in the add new device menu.
Create a device with a serial so we can proceed to the next step.

Setting up a TCP/IP server

For this example we will create a TCP/IP nodejs server to be our network. This code can be found at https://github.com/tago-io/middleware-example.

const { Device, Network } = require("@tago-io/sdk");
const net =  require("net");
const PORT = 3338;

const network = new Network({ token: "" }); /* Your Network token here */

// Parse all data, this process can be on connector parser
function parsePayload(payload) {

  const data = [
    {
      variable: "serial",
      value: payload.readUInt32LE(1),
    },
    {
      variable: "timestamp",
      value: payload.readUInt32LE(5),
    },
    {
      variable: "external_supply_voltage",
      value: payload.readUInt8(9) + payload.readUInt8(10) * 0.01,
    },
    {
      variable: "supply_voltage",
      value: payload.readUInt8(11) + payload.readUInt8(12) * 0.01,
    },
    {
      variable: "battery_voltage",
      value: payload.readUInt8(13) + payload.readUInt8(14) * 0.01,
    },
    {
      variable: "temperature",
      value: payload.readInt8(15) + payload.readUInt8(16) * 0.01,
    },
    {
      variable: "gsm_level",
      value: payload.readInt8(17),
    },
  ];

  return data;
}

async function dataReceived(msg) {
  // parse data
  const data = parsePayload(msg);
  console.info("data ", data);
  // get serial variable
  const serial = data.find((e) => e.variable == "serial").value.toString();

  /**
   * Resolve the network token received by the device
   * The token dont need hyphen symbols as a divisor
   * In this method you can use a authentication token if needed
   */
  const token = await network.resolveToken(serial);
  if (!token) {
    return console.log(`Token not found, serie: ${serial}`);
  }

  // send data to the device
  const device = new Device({ token });
  device.sendData(data).then(console.log, console.log);
}
// Input example: 6d3930000088dd5a5c0b5e075c013d190300410120f14742ae4749414300
const server = net
  .createServer((socket) => {
    socket.on("data", dataReceived);
  })
  .on("error", (err) => {
    throw err;
  });

server.listen(PORT);
console.info("Started Server at PORT", PORT);

That is it! :grinning_face: Now you have a Network for your connectors and devices.

Hi Ricardo,

A very good tutorial. I create my own Network to integrate with TagoIO. I followed your tutorial step by step.

In TagoIO I created two devices:

serial 00012345

serial 00012346

I launched the TCP server application in the Nodejs environment. Then I started sending payload to the server. As long as payload applied to devices 00012345 or 00012346, the variables were transferred to TagoIO.

Unfortunately, when the paylod contained another “serial” an error occurred in the TCP server application, after which the application stopped working and the system shell was returned.

See the log below in the attached file (and below)

What do I have to do to make the TCP server application work without error when payload applies to a device that is not in TagoIO?



node-js>node tcp-server-1
Started Server at PORT 3338

payload  <Buffer 30 30 30 31 32 33 34 35 36 0b 5e 07 5c 78 01 5c 5c 78 30 33 00 41 01 20 f1 47 42 ae 47 49 41 43 00>
data  [
  { variable: 'serial', value: '00012345' },
  { variable: 'timestamp', value: 909456435 },
  { variable: 'external_supply_voltage', value: 11.94 },
  { variable: 'supply_voltage', value: 7.92 },
  { variable: 'battery_voltage', value: 120.01 },
  { variable: 'temperature', value: 92.92 },
  { variable: 'gsm_level', value: 120 }
]
serial  00012345
> TagoIO-SDK: No region or env defined, using fallback as usa-1.
token  1d0b1eb0-37f0-4136-9635-4ae582ecc452
device  Device {
  params: { token: '1d0b1eb0-37f0-4136-9635-4ae582ecc452' },
  batch: Batch { params: { token: '1d0b1eb0-37f0-4136-9635-4ae582ecc452' } }
}
7 Data Added


payload  <Buffer 30 30 30 31 32 33 34 36 36 0b 5e 07 5c 78 01 5c 5c 78 30 33 00 41 01 20 f1 47 42 ae 47 49 41 43 00>
data  [
  { variable: 'serial', value: '00012346' },
  { variable: 'timestamp', value: 909521971 },
  { variable: 'external_supply_voltage', value: 11.94 },
  { variable: 'supply_voltage', value: 7.92 },
  { variable: 'battery_voltage', value: 120.01 },
  { variable: 'temperature', value: 92.92 },
  { variable: 'gsm_level', value: 120 }
]
serial  00012346
token  dc3ab6ab-ece8-499b-a828-f616a66a2ed1
device  Device {
  params: { token: 'dc3ab6ab-ece8-499b-a828-f616a66a2ed1' },
  batch: Batch { params: { token: 'dc3ab6ab-ece8-499b-a828-f616a66a2ed1' } }
}
7 Data Added



payload  <Buffer 30 30 30 31 32 33 34 37 36 0b 5e 07 5c 78 01 5c 5c 78 30 33 00 41 01 20 f1 47 42 ae 47 49 41 43 00>
data  [
  { variable: 'serial', value: '00012347' },
  { variable: 'timestamp', value: 909587507 },
  { variable: 'external_supply_voltage', value: 11.94 },
  { variable: 'supply_voltage', value: 7.92 },
  { variable: 'battery_voltage', value: 120.01 },
  { variable: 'temperature', value: 92.92 },
  { variable: 'gsm_level', value: 120 }
]
serial  00012347
node:internal/process/promises:279
            triggerUncaughtException(err, true /* fromPromise */);
            ^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Token can't be found".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

node-js>_

Hi Jacek,

I’m happy that this tutorial was useful to you!

This script its outdated, now the network.resolveToken function throws an error when the serial is not found. To fix that you can use try/catch or promise .catch.

I updated the repository with my solution: GitHub - tago-io/middleware-example: Example for connector middlewares for TagoIO.

Hi Ricardo,

Very good tutorial indeed. The example works w/o a problem.

I have a question though, and I realize this is much more a JS question than a Tago question.

The network we are communicating with seems to drop/loose the connections every now and again. As a result the server socket is closed and the app quits.

I know in Java the ServerSocket.accept() method returns a new Socket, which can be closed at the end of the communication w/o impacting the serverSocket. I looked through the net.ServerSocket documentation and I did notice an ‘connect’ event but I am not clear on how to use that in this context.

Again, I do realize this is not a real Tago question. Just hoping you have the expertise to point me in the right direction.

Cheers,

Erwin