Hi,
I’m stuck at the point where I’m only able to send downlink to a specific Device ID (only if I declared the device id environment variable).
I want to know if there’s a way using script to get triggered device ID and send downlink to the specific ID without declaring any device_id environment variable. I’m currently using node.JS to try out different codes.
I’ve tried to modify the code for checkin status(to find out the device id using script) and sending downlink(send data to device id from envVar after triggered by variable). By using Action, I can run both scripts at the same time, but I want to have a script that is able to combine this two together, so that I can know which was the device ID that needed to send downlink. Is there anyone that can help me on this?
If you are triggering your script using a widget or action (by variable), you can get it form the parameter “origin” of your variables.
The following function is very useful for that, and you can add to your code:
// This function helps us get the device using just its id.
async function getDevice(account, device_id) {
const token = await Utils.getTokenByName(account, device_id);
const dev = new Device({ token: token });
return dev;
}
//
// Use as:
// const account = new Account({ token: "account-token" });
// const device = await getDevice(account, scope[0].origin);
However, currently I’m fixing my ‘Sending downlink using dashboards’ to send downlink without dashboard and this is my script:
const { Analysis, Account, Utils } = require('@tago-io/sdk');
const axios = require('axios');
async function init(context) {
context.log('Downlink analysis started');
// Get the environment variables.
const env = Utils.envToJson(context.environment);
const account = new Account({ token: env.account_token });
const payload = { value: env.payload, origin: env.device_id };
const port = { value: env.default_PORT };
const device_id = payload.origin; // All variables that trigger the analysis have the "origin" parameter, with the TagoIO Device ID.
// Find the token containing the authorization code used.
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: payload.value,
port: port.value,
};
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 with status ${error.response.status}`);
context.log(error.response.data || JSON.stringify(error));
});
}
module.exports = new Analysis(init);
Is there a way I can find the Device ID & Token without hard coding ‘device_id’ in the environment variables? As I have multiple devices so I’m trying to find out if I can get the device id from script and send the downlink, instead of hardcoding many ‘device_id’ to many analysis script.
I tried to change the above code to run without the device_id in the environment variables but I got this in the console:
Was wondering what modification need to be done to this script so I’m able to find out which Device triggered the Action to run this downlink Analysis to Loriot.
I am very clueless now as I don’t really know much about Loriot Node.JS
I would very much appreciate your help in this!
From your description, you did setup an Action By Variable to run this is script. Is that correct?
If that’s so, you need to edit the: async function init(context)toasync function init(context, scope)
Because any data regarding what triggered your analysis is available in the scope parameter of the analysis.
When you receive information in the scope, usually the information regarding which device send the data will be available in the scope[0].origin. That said, you can just edit the following line to: