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.
To implement a check-in status analysis for your devices is relatively simple. We only need 2 things:
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');
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.
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.
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!