Downlink payload formatter (JavaScript) - V3

Hello all,

I’m using the following function to encode my downlink:

function encodeDownlink(input) {
  var bytes = [];
  
  if (input.data.state1 == "false"){
      bytes[0] = 0;
    }
    else if (input.data.state1 == "true"){
      bytes[0] = 1;
    }
    else{
      bytes[0] = 2;
    }
  
// Try something slightly different.....
  if (input.data.state2 && input.data.state2 === "false"){
      bytes[1] = 0;
    }
    else if (input.data.state2 &&  input.data.state2 === "true"){
      bytes[1] = 1;
    }
    else{
      bytes[1] = 2;
    }
  
  return {
    bytes: bytes,
    fPort: input.fPort,
  };
}

& testing using the following:

   curl --location \
  --header 'Authorization: Bearer NNSXS.BD...............CQ.NZCY2ECBWDW72D6VCPT446EIKZ4T3QMSFNELZSFY6EZPYFXVRBFQ' \
  --header 'Content-Type: application/json' \
  --header 'User-Agent: my-integration/my-integration-version' \
  --request POST \
  --data '{
    "downlinks": [{
      "decoded_payload": {"data": {"state1":"false", "state2":"true"}},
      "f_port": 1,
      "priority":"NORMAL"
    }]
  }' \
 'https://eu1.cloud.thethings.network/api/v3/as/applications/heltec-es-led1/webhooks/testhook2/devices/heltec-esp32-lora-2/down/push'

And the end device is receiving:

0202

Whereas I expected:

0001

Can anyone shed some light on where I’m going wrong??

Thanks

1 Like

Looks like I’ve found the reason. Changing the formatters to (note input.data.data.state1):

function encodeDownlink(input) {
  // Input is a string true or false
  var bytes = [];
  
  if (input.data.data.state1 == "false"){
      bytes[0] = 0;
    }
    else if (input.data.data.state1 == "true"){
      bytes[0] = 1;
    }
    else{
      bytes[0] = 2;
    }
  
  if (input.data.data.state2 && input.data.data.state2 === "false"){
      bytes[1] = 0;
    }
    else if (input.data.data.state2 &&  input.data.data.state2 === "true"){
      bytes[1] = 1;
    }
    else{
      bytes[1] = 2;
    }
  
  return {
    bytes: bytes,
    fPort: input.fPort,
  };
}

function decodeDownlink(input) {
  return {
    data: {
      state1: ["false", "true", "other"][input.bytes[0]],
      state2: ["false", "true", "other"][input.bytes[1]]
    }
  };
}

Yields the expected result when using:

curl --location \
  --header 'Authorization: Bearer NNSXS.BD7U....G5QFZQV6CQ.NZCY2ECBWDW72D6VCPT446EIKZ4T3QMSFNELZSFY6EZPYFXVRBFQ' \
  --header 'Content-Type: application/json' \
  --header 'User-Agent: my-integration/my-integration-version' \
  --request POST \
  --data '{"downlinks": [{"f_port":1,"decoded_payload": {"data": {"state1":"false", "state2":"true"}}}]}' \
 'https://eu1.cloud.thethings.network/api/v3/as/applications/heltec-e2-otaa-led1/webhooks/testhook2/devices/heltec-esp32-lora-2/down/push'

Interesting this format is rejected:

curl --location \
  --header 'Authorization: Bearer NNSXS.BD7U....FZQV6CQ.NZCY2ECBWDW72D6VCPT446EIKZ4T3QMSFNELZSFY6EZPYFXVRBFQ' \
  --header 'Content-Type: application/json' \
  --header 'User-Agent: my-integration/my-integration-version' \
  --request POST \
  --data '{"downlinks": [{"f_port":1,"decoded_payload": { {"state1":"false", "state2":"true"}}}]}' \
 'https://eu1.cloud.thethings.network/api/v3/as/applications/heltec-e2-otaa-led1/webhooks/testhook2/devices/heltec-esp32-lora-2/down/push'

Hope this saves someone some pain!

1 Like

Hi @leo73745
Just an observation: seems strange (to me) to use strings “true” and “false” for json values when a boolean might be more appropriate (i.e., true and false respectively)
Anyway, glad you found a solution!

Ok, I know it’s been 6 months since this topic has been updated, but honestly I would like to thank you. I’ve spent the past two and a half days trying to figure out why my testing downlink encoder didn’t work and finally I found this hidden gem. Hats off.

Thank, glad to help!

1 Like