Downlink to TTN-v2

Dear Team,

I downloaded the analysis from the TagoIO website for sending the DL to the TTN-V2 using widget.

When i run the analysis i am not getting the output, the console is showing as follows:

[2021-04-22 13:52:14] Downlink analysis started
[2021-04-22 13:52:14] {}
[2021-04-22 13:52:14] Starting analysis 60810b154d63290018c72b7c

Here is my script and the Environment variables i use.

    const { Analysis, Account, Utils } = require('@tago-io/sdk');
    const axios        = require('axios');
    async function init(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');
      // Instance the Account class
      const account = new Account({ token: env.account_token });
      // Get the variables form_payload and form_port sent by the widget/dashboard.    //const payload = scope.find(x => x.variable === 'form_payload') || { value: env.payload, origin: env.device_id };
      const port = scope.find(x => x.variable === 'form_port') || { value: env.default_PORT };
      const unit1 = scope.find(x => x.variable === 'unit1') || {value: env.unit1};
      const unit2 = scope.find(x => x.variable === 'unit2') || {value: env.unit2};
      const time1 = scope.find(x => x.variable === 'time1') || {value: env.time1};
      const time2 = scope.find(x => x.variable === 'time2') || {value: env.time2};
  if (!payload || !payload.value || !payload.origin) return context.log('Missing "form_payload" in the data scope.');
      else if (!port || !port.value) return context.log('Missing "form_port" in the data scope.');
  const device_id = env.device_id; // All variables that trigger the analysis have the "origin" parameter, with the TagoIO Device ID.
  if (!device_id) return context.log('Device ID <origin> not found in the variables sent by the widget/dashboard.');
      // 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,
        port: port.value,
        payload_fields:{
        unit1: parseInt(unit1.value),
        time1: parseInt(time1.value),
        unit2: parseInt(unit2.value), 
        time2: parseInt(time2.value),}
      };
      context.log(data);
      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));
       });
    }
    module.exports = new Analysis(init); 

Environment varibales:

account_token:  xxxx
default_PORT: 11
device_id: xxxx
unit1: unit1
time1: time1
unit2: 0
time2: 0 

can any one help me on this? My downlink is not arriving in the TTN.

Don’t know a lot about this but finally got mine working to TTI (TTNv3).
You may want to troubleshoot by trying to send a payload to start with. ie constant payload = … instead of unit 1, …
Not sure if this is the issue, but have found TTI a bit picky with a few things on downlink.

// Get the variables form_payload and form_port sent by the widget/dashboard.
const payload = scope.find(x => x.variable === ‘payload’) || { value: env.payload, origin: env.device_id };
const port = scope.find(x => x.variable === ‘port’) || { value: env.default_PORT };
if (!payload || !payload.value || !payload.origin) return context.log(‘Missing “payload” in the data scope.’);
else if (!port || !port.value) return context.log(‘Missing “port” in the data scope.’);

Thank you Dayne kells.

Now the data file is getting executed, but i am getting the following error.

**Cannot read property 'data' of undefined**
[2021-04-24 15:57:03] Downlink failed with status 500
[2021-04-24 15:57:03] {"device":"xxx","authorization":"xxx","port":"11","payload_fields":{"payload":0}}

Any idea about this error?