How to create a check-in status verification for your devices

Check-in Status

One very important thing to monitor in an IoT application is the connection of sensors/devices with TagoIO. You may want to know if a device checkin in the last X minutes or X hours; if the device didn’t send any data or a ‘heartbeat’ for a certain period of time, it may be an indication of problem – we call this process ‘Check-in status verification’.

I’ll explain how you can check devices that have been inactive for a long time in your application and deal with the cases in which this happens. In this way, you will be notified when a device has been inactive for a period longer than expected.

How can we do that?

To implement a check-in status analysis for your devices is relatively simple. We only need 2 things:

  • An analysis running at a short time interval, such as every 1 minute for example
  • The code responsible for verify the status of our devices.

So, let’s start the implementation. First, create a new internal analysis on the TagoIO platform with the Node.js language, this analysis is where we will put our code later. With the Analysis created, you need to set one environment variable that is your account_token.

After that, paste the following script in your Analysis, select a time interval like 1 minute for example and save your Analysis.

const TagoDevice = require('tago/device'); 
const TagoAccount = require('tago/account'); 
const TagoUtils = require('tago/utils'); 
const TagoAnalysis = require('tago/analysis'); 
const moment = require('moment-timezone'); 

async function checkIn(context) { 
  const env_var = TagoUtils.env_to_obj(context.environment); 
  if (!env_var.account_token) return context.log('Missing account_token environment var'); 
  const account = new TagoAccount(env_var.account_token); 

  // Here you can choose the devices you want to checkin 
  // in this case, I am checking every device with the tag key = system 
  // if you want to use other examples, remember to comment this line before 
  const devices = await account.devices.list(1, ['id', 'name'], { tags: [{ key: 'analysis' }] }, 2000); 

  // Here are some othe example of filter you can use: 
  // Get all devices with tag key = system and value = test 
  // const devices = await account.devices.list(1, ['id', 'name'], { tags: [{ key: 'system', value: 'test' }] }, 2000); 

  if (!devices.length) return; 

  const now = moment.utc().format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]'); 

  const serie = Date.now(); 

  // If min_time = 10, you will receive an alert for 
  // every device that does not send data for more than 10 minutes 
  const min_time = 10; 

  await Promise.all(devices.map(async (dev) => { 
    const token = await TagoUtils.getTokenByName(account, dev.id); 
    const deviceToBeChecked = new TagoDevice(token); 

    const [lastData] = await deviceToBeChecked.find({ variable: 'varYouWantHere', qty: 1, query: 'last_item'}); 

    const device_data = await deviceToBeChecked.find({ variable: 'alarm_errors', query: 'last_item' }); 

    const alarm_errors = device_data.find(x => x.variable === 'alarm_errors'); 

    if (!lastData) return context.log(`device ${dev.id} does not have data yet`); 

    const minutes = moment(now).diff(lastData.time, 'minutes'); 

    if (alarm_errors && alarm_errors.value === 'Offline') return context.log(`device ${dev.id} is already offline`); 

    if (minutes > Number(min_time)) { 
      await deviceToBeChecked.insert({ variable: 'alarm_errors', value: 'Offline', serie }).then(context.log); 
      context.log('Inactive device'); 
      // do something here 
    }; 
  })); 
  context.log('checkin succesfully finished'); 
} 

module.exports = new TagoAnalysis(checkIn, 'ANALYSIS TOKEN HERE'); 

So … I just need to copy and paste the code?

No, the code is based on checking for a specific variable. That is, if your devices always send the battery variable, you have to write the code for the analysis to find the battery variable.

Why can’t I just write code to the device to look for the last variable, whatever it is?

This is because the code we are using uses some reference variables like the alarm_errors variable to work correctly, if you write in your code to look for the last variable regardless of what it was, the code will never work as it will interpret that all devices are always active.

Got it, what changes should I make to the code then?

Look for line 34 of the code, which contains the following snippet:

const [lastData] = await deviceToBeChecked.find({ variable: 'varYouWantHere', qty: 1, query: 'last_item'}); 

There, you must exchange the varYouWantHere variable for the variable you want to put. Taking the battery variable as an example, the code snippet would look like this:

const [lastData] = await deviceToBeChecked.find({ variable: 'battery', qty: 1, query: 'last_item'}); 

After this change, there is just one more detail to be done. You need to choose the maximum time a device can go without sending data before it is considered inactive. To do this, just choose the number of minutes you want and write it on line 28. For example, I want a device to stay at most 30 minutes without sending data, so my line 28 will look like this:

const min_time = 30; 

Once you have done this, you can copy and paste the code into your Analysis. Remember that you can change this code and improve it. For example, you can trigger an Action to run a script when detecting that a device is offline.

If you have any questions, leave your comment here.

Thanks!

1 Like