How to timesync with MCF88

In this article, we’ll learn how to set up an analysis to do timesync with MCF88 devices.

By following all the steps in this article, you’ll end up with:

  • An analysis that will handle timesync for MCF88 devices.
  • An action to trigger the analysis when MCF88 devices send payloads.

Setting up the analysis

For this article, we’ll need to setup an analysis to send the timesync for the MCF88 devices.

  1. Go to your account settings by clicking here: Account Settings (tago.io)
  2. Then go to your profile.
  3. Then go to the Tokens tab.
  4. Create a new token with expire set to Never.
  5. Copy the new token generated.
  6. Get the analysis template by clicking here: http://admin.tago.io/template/602d7bfda62d88001ae05e01
  7. Go to the Environment Variables tab.
  8. Replace the value for account_token with the token you just copied on sstep 5.
  9. Press save.

Setting up the action

For this article, we’ll need to setup an action to trigger the analysis when the MCF88 device sends the payload data.

  1. Go to the Actions button on your account.
  2. Create a new action.
  3. Select Type of trigger to Variable
  4. Select Type of action to Run an Analysis
  5. Choose your analysis created previously.
  6. Click create.
  7. Choose “Multiple Devices”.
  8. Select the tag key “type” and enter the tag value “MCF88”
  9. Enter the variable payload for Trigger, and select the condition “Anything”.
  10. Press save.

You’re done!

Now your devices should start to timesync with the analysis. You can go to the analysis you created and check the console log information to know if everything’s running properly.

Good morning @vitor

How could I know if this procedure is working fine?

I think that I should receive a message like below, but I didn´t:

Blockquote
Downlink status message

`Downlink accepted with status …

Blockquote

Blockquote
Console Log

[2021-04-06 09:00:44] Downlink accepted with status 200
[2021-04-06 09:00:44] Trying to send the downlink
[2021-04-06 09:00:44] Downlink analysis started
[2021-04-06 09:00:43] Starting analysis 606c4628b659f900187071c6
[2021-04-06 09:00:39] Downlink accepted with status 200
[2021-04-06 09:00:39] Trying to send the downlink
[2021-04-06 09:00:39] Downlink analysis started
[2021-04-06 09:00:38] Starting analysis 606c4628b659f900187071c6
[2021-04-06 09:00:33] Downlink accepted with status 200
[2021-04-06 09:00:33] Trying to send the downlink
[2021-04-06 09:00:33] Downlink analysis started
[2021-04-06 09:00:32] Starting analysis 606c4628b659f900187071c6
[2021-04-06 09:00:28] Downlink accepted with status 200
[2021-04-06 09:00:27] Trying to send the downlink
[2021-04-06 09:00:27] Downlink analysis started
[2021-04-06 09:00:27] Starting analysis 606c4628b659f900187071c6
[2021-04-06 09:00:22] Downlink accepted with status 200
[2021-04-06 09:00:21] Trying to send the downlink
[2021-04-06 09:00:21] Downlink analysis started
[2021-04-06 09:00:21] Starting analysis 606c4628b659f900187071c6

Blockquote

Blockquote
TagoIO MCF88 JS

/*

** MCF88 Timesync analysis

** Do the timesync for MCf88 devices.

**

** In order to enable this analysis, follow these instructions and setup the environment variable.

** 1 - Create an action By Variable.

** 2 - Select the action to run an analysis.

** 3 - Select this analysis you created.

** 4 - Choose to run by Multiple devices.

** 5 - Enter a tag key and a tag value.

** 6 - Select the variable payload, with condition Any.

** 7 - Save the action.

** 8 - For each mCF88 device that you create, make sure to enter the same tag key and tag value for the device.

**

** Environment Variables

** In order to use this analysis, you must setup the Environment Variable table.

**

** account_token: Your account token. Check bellow how to get this.

**

** Steps to generate an account_token:

** 1 - Enter the following link: Admin

** 2 - Select your Profile.

** 3 - Enter Tokens tab.

** 4 - Generate a new Token with Expires Never.

** 5 - Press the Copy Button and place at the Environment Variables tab of this analysis.

*/

const { Utils, Analysis, Account } = require(’@tago-io/sdk’);

const moment = require(‘moment’);

const axios = require(‘axios’);

function reverse(str) {

return str.match(/[a-fA-F0-9]{2}/g).reverse().join(’’);

}

function encodeDate(date) {

const mDate = moment(date);

const year = (mDate.year() - 2000).toString(2).padStart(7, ‘0’);

const month = (mDate.month() + 1).toString(2).padStart(4, ‘0’);

const day = (mDate.date()).toString(2).padStart(5, ‘0’);

const hour = (mDate.hour()).toString(2).padStart(5, ‘0’);

const minute = (mDate.minute()).toString(2).padStart(6, ‘0’);

const second = (mDate.second() / 2).toString(2).padStart(5, ‘0’);

return reverse(parseInt(${year}${month}${day}${hour}${minute}${second}, 2).toString(16).toUpperCase());

}

async function processTimeSync(context, account, device_id, payload) {

const sync_id = payload.substring(2, 10);

const currentDate = encodeDate(moment()._d);

const payload_raw = 00${sync_id.value}${currentDate};

const payloadHex = Buffer.from(payload_raw.match(/.{1,2}/g).map(x => 0x${x})).toString(‘hex’);

console.log(currentDate, payload_raw, payloadHex);

const device_tokens = await account.devices.tokenList(device_id, { page: 1, fields: [‘name’, ‘serie_number’, ‘last_authorization’], amount: 10 });

const token = device_tokens.find(x => x.serie_number && x.last_authorization);

if (!token) return context.log(“Couldn’t find a token with serial/authorization for this device”);

// Get the connector ID from the device

const { network: network_id } = await account.devices.info(device_id);

if (!network_id) return context.log(‘Device is not using a network.’);

// Get the network information with the NS URL for the Downlink

const network = await account.integration.networks.info(network_id, [‘id’, ‘middleware_endpoint’, ‘name’]);

if (!network.middleware_endpoint) return context.log(“Couldn’t find a network middleware for this device.”);

// Set the parameters for the device. Some NS like Everynet need this.

const params = await account.devices.paramList(device_id);

let downlink_param = params.find(x => x.key === ‘downlink’);

downlink_param = {

id: downlink_param ? downlink_param.id : null, key: 'downlink', value: String(payload.value), sent: false,

};

await account.devices.paramSet(device_id, downlink_param);

context.log(‘Trying to send the downlink’);

const data = {

device: token.serie_number,

authorization: token.last_authorization,

payload: payloadHex,

port: 1,

};

await axios.post(https://${network.middleware_endpoint}/downlink, data)

.then((result) => {

  context.log(`Downlink accepted with status ${result.status}`);

})

.catch((error) => {

  context.log(`Downlink failed with status ${error.response.status}`);

  context.log(error.response.data || JSON.stringify(error));

});

}

async function myAnalysis(context, scope) {

if (!scope[0]) return context.log(‘This analysis must be triggered by a widget.’);

context.log(‘Downlink analysis started’);

// Get the environment variables.

const env = Utils.envToJson(context.environment);

if (!env.account_token) return context.log(‘Missing “account_token” environment variable’);

else if (env.account_token.length !== 36) return context.log(‘Invalid “account_token” in the environment variable’);

const account = new Account({ token: env.account_token });

const payload = scope.find(x => [‘payload_raw’, ‘data’, ‘payload’].includes(x.variable));

// const serie = payload.serie ? ${new Date().getTime()}-${payload.serie} : new Date().getTime();

if (payload) {

const uplinkId = payload.value.substring(0, 2);

if (uplinkId === '01') {

  await processTimeSync(context, account, scope[0].origin, payload.value);

}

}

}

module.exports = new Analysis(myAnalysis);

Blockquote

Hi Claudio,
If you’re receiving

Downlink accepted with status 200

In your console, it means the downlink was accepted by the networrk server. You can check the network server to see if the downlink is showing up there.

Is this message in the console log?

[2021-04-06 09:00:44] Downlink accepted with status 200
[2021-04-06 09:00:44] Trying to send the downlink
[2021-04-06 09:00:44] Downlink analysis started
[2021-04-06 09:00:43] Starting analysis 606c4628b659f900187071c6