> For the complete documentation index, see [llms.txt](https://docs.dnt.de/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dnt.de/dnt-lw-wsci/payload-decoder.md).

# Payload Decoder

| Firmware Version | Payload Decoder Version |
| :--------------: | :---------------------: |
|      < 1.5.0     |          2.0.2          |
|      ≥ 1.5.0     |          2.1.1          |

<details>

<summary>Payload Decoder 2.0.2</summary>

```javascript
/*
 * dnt-LW-WSCI-Payload-Parser
 * 
 * */

var payload_parser_version = [2,0,2];
const ERROR_CODE =
{
  0: "DEVICE_READY"
};
const SABOTAGE_CONTACT_STATE =
{
  0: "IDLE",
  1: "TRIGGERED",
  2: "DISABLED"
};
const INPUT_STATE =
{
  0: "LOW",
  1: "HIGH",
  2: "DISABLED"
};
const WEEKDAY = 
{
  0: "SUNDAY",
  1: "MONDAY",
  2: "TUESDAY",
  3: "WEDNESDAY",
  4: "THURSDAY",
  5: "FRIDAY",
  6: "SATURDAY"
};
const MONTH = 
{
  0: "JANUARY",
  1: "FEBRUARY",
  2: "MARCH",
  3: "APRIL",
  4: "MAY",
  5: "JUNE",
  6: "JULY",
  7: "AUGUST",
  8: "SEPTEMBER",
  9: "OCTOBER",
  10: "NOVEMBER",
  11: "DECEMBER"
};
const WEEK_OF_MONTH =
{
  1: "1st",
  2: "2nd",
  3: "3rd",
  4: "4th",
  5: "last"
};
const DATA_RATE = 
{
  0: "Adaptive Data Rate",
  1: "DR 0",
  2: "DR 1",
  3: "DR 2",
  4: "DR 3",
  5: "DR 4",
  6: "DR 5",
};
const REJOIN_BEHAVIOR = 
{
  true: "Cyclic Rejoin",
  false: "Single Rejoin",
};
const INPUT_CLAMP_SENSOR_TYPE = 
{
  0: "Magnetic contact",
  1: "Glass break detector",
  2: "Reserved",
};
const COMMAND_ID =
{
  0: "COMMAND_ID_GET_STATUS_INTERVAL",
  1: "COMMAND_ID_SET_STATUS_INTERVAL",
  2: "COMMAND_ID_GET_STATUS_PARAMETER_TX_ENABLE_REGISTER",
  3: "COMMAND_ID_SET_STATUS_PARAMETER_TX_ENABLE_REGISTER",
  4: "COMMAND_ID_GET_STATUS",
  5: "COMMAND_ID_GET_BATTERY_VOLTAGE",
  6: "COMMAND_ID_GET_SABOTAGE_CONTACT_STATE",
  7: "COMMAND_ID_GET_ERROR_CODE",
  8: "COMMAND_ID_GET_DEVICE_TIME",
  9: "COMMAND_ID_SET_DEVICE_TIME",
  10: "COMMAND_ID_GET_DEVICE_TIME_CONFIG",
  11: "COMMAND_ID_SET_DEVICE_TIME_CONFIG",
  12: "COMMAND_ID_SET_SABOTAGE_CONTACT_CONFIG",
  13: "COMMAND_ID_GET_SABOTAGE_CONTACT_CONFIG",
  14: "COMMAND_ID_GET_HALL_SENSOR_STATE",
  15: "COMMAND_ID_SET_HALL_SENSOR_CONFIG",
  16: "COMMAND_ID_GET_HALL_SENSOR_CONFIG",
  17: "COMMAND_ID_GET_INPUT_CLAMP_STATE",
  18: "COMMAND_ID_SET_INPUT_CLAMP_CONFIG",
  19: "COMMAND_ID_GET_INPUT_CLAMP_CONFIG",
  20: "COMMAND_ID_SET_INPUT_CLAMP_SENSOR_TYPE",
  21: "COMMAND_ID_GET_INPUT_CLAMP_SENSOR_TYPE",
  22: "COMMAND_ID_SET_INPUT_CLAMP_SENSOR_FILTER_TIME",
  23: "COMMAND_ID_GET_INPUT_CLAMP_SENSOR_FILTER_TIME",
  54: "COMMAND_ID_COMMAND_FAILED",
  57: "COMMAND_ID_GET_HARDWARE_FACTORY_RESET_LOCK",
  58: "COMMAND_ID_SET_HARDWARE_FACTORY_RESET_LOCK",
  247: "COMMAND_ID_GET_REMAINING_TIME_UNTIL_REJOIN",
  248: "COMMAND_ID_GET_DATA_RATE",
  249: "COMMAND_ID_SET_DATA_RATE",
  250: "COMMAND_ID_GET_REJOIN_BEHAVIOR",
  251: "COMMAND_ID_SET_REJOIN_BEHAVIOR",
  252: "COMMAND_ID_GET_ALL_CONFIG",
  253: "COMMAND_ID_PERFORM_FACTORY_RESET",
  254: "COMMAND_ID_PERFORM_SOFTWARE_RESET",
  255: "COMMAND_ID_GET_VERSION"
};

function decodeUplink(input) {
  
  var size = input.bytes.length;

  const data = {};
  
  var bufferSize = input.bytes.length;
  var idx = 0;
  commandId = -1;

  while(idx < bufferSize)
  {
    commandId = input.bytes[idx++];
    
    switch(COMMAND_ID[commandId])
    {
      case "COMMAND_ID_GET_STATUS_INTERVAL":
        data.status_report = data.status_report || {};
        data.status_report.interval = data.status_report.interval || {};
        data.status_report.interval.value = input.bytes[idx++] * 360 + 30;
        data.status_report.interval.unit ="s";
      break;
      case "COMMAND_ID_GET_STATUS_PARAMETER_TX_ENABLE_REGISTER":
        data.radio = data.radio || {};
        data.radio.status_report = data.radio.status_report || {};  
        data.radio.status_report.parameter_tx_enable_reg = data.radio.status_report.parameter_tx_enable_reg || {};
        
        var status_param_tx_enable_reg = input.bytes[idx++];
        
        data.radio.status_report.parameter_tx_enable_reg.battery_voltage_enabled = !!(status_param_tx_enable_reg & (1 << 7));
        data.radio.status_report.parameter_tx_enable_reg.sabotage_contact_states_enabled = !!(status_param_tx_enable_reg & (1 << 6));
        data.radio.status_report.parameter_tx_enable_reg.hall_sensore_states_enabled = !!(status_param_tx_enable_reg & (1 << 5));
        data.radio.status_report.parameter_tx_enable_reg.input_clamp_states_enabled = !!(status_param_tx_enable_reg & (1 << 4));
        data.radio.status_report.parameter_tx_enable_reg.unit = "bool";
      break;
      case "COMMAND_ID_GET_STATUS":
        var status_param_tx_enable_reg = input.bytes[idx++];

        if( !!(status_param_tx_enable_reg & (1 << 7)) )
        {
          data.battery_voltage = data.battery_voltage || {};
          data.battery_voltage.value = ( input.bytes[idx++] * 10 + 1500).toFixed(0);
          data.battery_voltage.unit = "mV";
        }

        if( !!(status_param_tx_enable_reg & (1 << 6)) )
        {
          data.sabotage_contact_state = {};
          data.sabotage_contact_state.value = SABOTAGE_CONTACT_STATE[input.bytes[idx++]& 0x03];
          data.sabotage_contact_state.unit = "string";
        }

        if( !!(status_param_tx_enable_reg & (1 << 5)) )
        {
          data.hall_sensor_state = {};
          data.hall_sensor_state.value = INPUT_STATE[input.bytes[idx++]& 0x03];
          data.hall_sensor_state.unit = "string";
        }

        if( !!(status_param_tx_enable_reg & (1 << 4)) )
        {
          data.input_clamp_state = {};
          data.input_clamp_state.value = INPUT_STATE[input.bytes[idx++]& 0x03];
          data.input_clamp_state.unit = "string";
        }
      break;
      case "COMMAND_ID_GET_BATTERY_VOLTAGE":
        data.battery_voltage = {};
        data.battery_voltage.value = ( input.bytes[idx++] * 10 + 1500).toFixed(0);
        data.battery_voltage.unit = "mV";
      break;
      case "COMMAND_ID_GET_SABOTAGE_CONTACT_STATE":
        data.sabotage_contact_state = {};
        data.sabotage_contact_state.value = SABOTAGE_CONTACT_STATE[input.bytes[idx++]& 0x03];
        data.sabotage_contact_state.unit = "string";
      break;
      case "COMMAND_ID_GET_SABOTAGE_CONTACT_CONFIG":
        data.sabotage_contact_config = {};
        data.sabotage_contact_config.value = !!(input.bytes[idx++] & 0x01);
        data.sabotage_contact_config.unit = "bool";
      break;
      case "COMMAND_ID_GET_HALL_SENSOR_STATE":
        data.hall_sensor_state = {};
        data.hall_sensor_state.value = INPUT_STATE[input.bytes[idx++]& 0x03];
        data.hall_sensor_state.unit = "string";
      break;     
      case "COMMAND_ID_GET_HALL_SENSOR_CONFIG":
        data.hall_sensor_config = {};
        data.hall_sensor_config.value = !!(input.bytes[idx++] & 0x01);
        data.hall_sensor_config.unit = "bool";
      break;
      case "COMMAND_ID_GET_INPUT_CLAMP_STATE":
        data.input_clamp_state = {};
        data.input_clamp_state.value = INPUT_STATE[input.bytes[idx++]& 0x03];
        data.input_clamp_state.unit = "string";
      break;     
      case "COMMAND_ID_GET_INPUT_CLAMP_CONFIG":
        data.input_clamp_config = {};
        data.input_clamp_config.value = !!(input.bytes[idx++] & 0x01);
        data.input_clamp_config.unit = "bool";
      break;
      case "COMMAND_ID_GET_INPUT_CLAMP_SENSOR_TYPE":
        data.input_clamp_sensor_type = {};
        data.input_clamp_sensor_type.value = INPUT_CLAMP_SENSOR_TYPE[input.bytes[idx++]& 0x03];
        data.input_clamp_sensor_type.unit = "string";
      break;
      case "COMMAND_ID_GET_INPUT_CLAMP_SENSOR_FILTER_TIME":
        data.input_clamp_filter_time = {};
        data.input_clamp_filter_time.value = input.bytes[idx++] * 30;
        data.input_clamp_filter_time.unit ="s";
      break;
      case "COMMAND_ID_GET_ERROR_CODE":
        data.error_code = {};
        data.error_code.value = ERROR_CODE[input.bytes[idx++]];
        data.error_code.unit = "string";
      break;
      case "COMMAND_ID_GET_DEVICE_TIME":
        data.device_time = data.device_time || {};
        data.device_time.local = data.device_time.local || {};
        data.device_time.local.second = {};
        data.device_time.local.minute = {};
        data.device_time.local.hour = {};
        data.device_time.local.day = {};
        data.device_time.local.weekday = {};
        data.device_time.local.month = {};
        data.device_time.local.year = {};
        data.device_time.local.is_dst = {};
        data.device_time.local.utc_offset = {};

        data.device_time.local.second.value = input.bytes[idx++] & 0x1F;
        data.device_time.local.second.unit = "s";

        data.device_time.local.minute.value = (input.bytes[idx] >> 2) & 0x3F;
        data.device_time.local.minute.unit = "min";

        data.device_time.local.hour.value = ((input.bytes[idx++] & 0x03) << 3) + (input.bytes[idx] >> 5);
        data.device_time.local.hour.unit = "h";

        data.device_time.local.day.value = input.bytes[idx++] & 0x1F;
        data.device_time.local.day.unit = "d";

        data.device_time.local.is_dst.value = !!(input.bytes[idx] & 0x80);
        data.device_time.local.is_dst.unit = "bool";

        data.device_time.local.weekday.value = WEEKDAY[(input.bytes[idx] >> 4) & 0x07];
        data.device_time.local.weekday.unit = "string";

        data.device_time.local.month.value = MONTH[input.bytes[idx++] & 0x0F];
        data.device_time.local.month.unit = "string";

        data.device_time.local.year.value = input.bytes[idx++] + 2000;
        data.device_time.local.year.unit = "a";

        data.device_time.local.utc_offset.value = (input.bytes[idx++] * 0.25 - 12).toFixed(2);
        data.device_time.local.utc_offset.unit = "h";
      break;
      case "COMMAND_ID_GET_DEVICE_TIME_CONFIG":
        data.device_time = data.device_time || {};
        data.device_time.config = data.device_time.config || {};
        data.device_time.config.auto_time_sync_en = {};
        data.device_time.config.utc_offset = {};
        data.device_time.config.utc_dst_offset = {};
        data.device_time.config.utc_dst_begin = {};
        data.device_time.config.utc_dst_end = {};
        data.device_time.config.utc_dst_begin.week_of_month = {};
        data.device_time.config.utc_dst_end.week_of_month = {};
        data.device_time.config.utc_dst_begin.month = {};
        data.device_time.config.utc_dst_end.month = {};
        data.device_time.config.utc_dst_begin.weekday = {};
        data.device_time.config.utc_dst_end.weekday = {};
        data.device_time.config.utc_dst_begin.hour = {};
        data.device_time.config.utc_dst_end.hour = {};
        data.device_time.config.utc_dst_begin.minute = {};
        data.device_time.config.utc_dst_end.minute = {};

        data.device_time.config.auto_time_sync_en.value = !!(input.bytes[idx] >> 7);
        data.device_time.config.auto_time_sync_en.unit = "bool";
        
        data.device_time.config.utc_offset.value = ((input.bytes[idx++] & 0x7F) * 0.25 - 12).toFixed(2);
        data.device_time.config.utc_offset.unit = "h";

        data.device_time.config.utc_dst_begin.week_of_month.value = WEEK_OF_MONTH[ (input.bytes[idx] >> 4) & 0x0F ];
        data.device_time.config.utc_dst_begin.week_of_month.unit = "string";

        data.device_time.config.utc_dst_begin.month.value = MONTH[input.bytes[idx++] & 0x0F];
        data.device_time.config.utc_dst_begin.month.unit = "string";

        data.device_time.config.utc_dst_begin.weekday.value = WEEKDAY[input.bytes[idx] >> 5];
        data.device_time.config.utc_dst_begin.weekday.unit = "string";

        data.device_time.config.utc_dst_begin.hour.value = (input.bytes[idx++] & 0x0F);
        data.device_time.config.utc_dst_begin.hour.unit = "h";

        data.device_time.config.utc_dst_offset.value = ((input.bytes[idx++] & 0x7F) * 0.25 - 12).toFixed(2);
        data.device_time.config.utc_dst_offset.unit = "h";

        data.device_time.config.utc_dst_end.week_of_month.value = WEEK_OF_MONTH[ (input.bytes[idx] >> 4) & 0x0F ];
        data.device_time.config.utc_dst_end.week_of_month.unit = "string";

        data.device_time.config.utc_dst_end.month.value = MONTH[input.bytes[idx++] & 0x0F];
        data.device_time.config.utc_dst_end.month.unit = "string";

        data.device_time.config.utc_dst_end.weekday.value = WEEKDAY[input.bytes[idx] >> 5];
        data.device_time.config.utc_dst_end.weekday.unit = "string";

        data.device_time.config.utc_dst_end.hour.value = (input.bytes[idx++] & 0x0F);
        data.device_time.config.utc_dst_end.hour.unit = "h";

        data.device_time.config.utc_dst_begin.minute.value = (input.bytes[idx] >> 4) * 5;
        data.device_time.config.utc_dst_begin.minute.unit = "min";

        data.device_time.config.utc_dst_end.minute.value = (input.bytes[idx++] & 0x0F) * 5;
        data.device_time.config.utc_dst_end.minute.unit = "min";
      break;
      case "COMMAND_ID_COMMAND_FAILED":
        data.radio = data.radio || {};
        data.radio.failed_commands = {};

        var nbr_failed_commands = input.bytes[idx++];

        data.radio.failed_commands.value = {};

        for(let i = 0; i < nbr_failed_commands; i++)
        {
          data.radio.failed_commands.value[i] = COMMAND_ID[input.bytes[idx++]];
        }

        data.radio.failed_commands.unit = "COMMAND_ID";
      break;
      case "COMMAND_ID_GET_HARDWARE_FACTORY_RESET_LOCK":
        data.button_action = data.button_action || {};
        data.button_action.hw_factory_reset_locked = data.button_action.hw_factory_reset_locked || {};

        data.button_action.hw_factory_reset_locked.value = !!(input.bytes[idx++] & (0x01));
        data.button_action.hw_factory_reset_locked.unit = "bool";
      break;
      case "COMMAND_ID_GET_REMAINING_TIME_UNTIL_REJOIN":
        data.radio = data.radio || {};
        data.radio.cyclic_rejoin = data.radio.cyclic_rejoin || {};
        data.radio.cyclic_rejoin.remaining_time_until_rejoin = data.radio.cyclic_rejoin.remaining_time_until_rejoin || {};

        data.radio.cyclic_rejoin.remaining_time_until_rejoin.value = ((input.bytes[idx++] & 0x1F) << 16) + (input.bytes[idx++] << 8) + input.bytes[idx++];
        data.radio.cyclic_rejoin.remaining_time_until_rejoin.unit = "min";
      break;
      case "COMMAND_ID_GET_DATA_RATE":
        data.radio = data.radio || {};
        data.radio.data_rate = {};
        data.radio.data_rate.value = DATA_RATE[(input.bytes[idx++] & 0x0F)];
        data.radio.data_rate.unit = "string";
      break;
      case "COMMAND_ID_GET_REJOIN_BEHAVIOR":
        data.radio = data.radio || {};
        data.radio.cyclic_rejoin = data.radio.cyclic_rejoin || {};
        data.radio.cyclic_rejoin.conf = data.radio.cyclic_rejoin.conf || {};
        data.radio.cyclic_rejoin.interval = data.radio.cyclic_rejoin.interval || {};

        data.radio.cyclic_rejoin.conf.value = REJOIN_BEHAVIOR[!(input.bytes[idx] >> 7)];
        data.radio.cyclic_rejoin.conf.unit = "string"; 

        data.radio.cyclic_rejoin.interval.value = (((input.bytes[idx++] & 0x7F) * (255)) + input.bytes[idx++]);
        data.radio.cyclic_rejoin.interval.unit = "h";
      break;
      case "COMMAND_ID_GET_VERSION":
        data.version = data.version || {};
        data.version.hw_revision = {};
        data.version.application = {};
        data.version.bootloader = {};
        data.version.lorawan_l2 = {};
        data.version.payload_parser = {};

        data.version.hw_revision.value = input.bytes[idx++];
        data.version.hw_revision.unit = "uint";

        data.version.application.value = {};
        data.version.application.value[0] = input.bytes[idx++];
        data.version.application.value[1] = input.bytes[idx++];
        data.version.application.value[2] = input.bytes[idx++];
        data.version.application.unit = "uint";

        data.version.bootloader.value = {};
        data.version.bootloader.value[0] = input.bytes[idx++];
        data.version.bootloader.value[1] = input.bytes[idx++];
        data.version.bootloader.value[2] = input.bytes[idx++];
        data.version.bootloader.unit = "uint";

        data.version.lorawan_l2.value = {};
        data.version.lorawan_l2.value[0] = input.bytes[idx++];
        data.version.lorawan_l2.value[1] = input.bytes[idx++];
        data.version.lorawan_l2.value[2] = input.bytes[idx++];
        data.version.lorawan_l2.unit = "uint";

        data.version.payload_parser.value = {};
        data.version.payload_parser.value[0] = payload_parser_version[0];
        data.version.payload_parser.value[1] = payload_parser_version[1];
        data.version.payload_parser.value[2] = payload_parser_version[2];
        data.version.payload_parser.unit = "uint";
      break;
      default:
      break;     
    }
  }

  return {
    data: data,
    warnings: [],
    errors: []
  };
}

```

</details>

<details>

<summary>Payload Decoder 2.1.1</summary>

```javascript
/*
 * dnt-LW-WSCI-Payload-Parser
 * 
 * */

var payload_parser_version = [2,1,1];
const ERROR_CODE =
{
  0: "DEVICE_READY"
};
const SABOTAGE_CONTACT_STATE =
{
  0: "IDLE",
  1: "TRIGGERED",
  2: "DISABLED"
};
const INPUT_STATE =
{
  0: "LOW",
  1: "HIGH",
  2: "DISABLED"
};
const WEEKDAY = 
{
  0: "SUNDAY",
  1: "MONDAY",
  2: "TUESDAY",
  3: "WEDNESDAY",
  4: "THURSDAY",
  5: "FRIDAY",
  6: "SATURDAY"
};
const MONTH = 
{
  0: "JANUARY",
  1: "FEBRUARY",
  2: "MARCH",
  3: "APRIL",
  4: "MAY",
  5: "JUNE",
  6: "JULY",
  7: "AUGUST",
  8: "SEPTEMBER",
  9: "OCTOBER",
  10: "NOVEMBER",
  11: "DECEMBER"
};
const WEEK_OF_MONTH =
{
  1: "1st",
  2: "2nd",
  3: "3rd",
  4: "4th",
  5: "last"
};
const DATA_RATE = 
{
  0: "Adaptive Data Rate",
  1: "DR 0",
  2: "DR 1",
  3: "DR 2",
  4: "DR 3",
  5: "DR 4",
  6: "DR 5",
};
const REJOIN_BEHAVIOR = 
{
  true: "Cyclic Rejoin",
  false: "Single Rejoin",
};
const INPUT_CLAMP_SENSOR_TYPE = 
{
  0: "Magnetic contact",
  1: "Glass break detector",
  2: "Reserved",
};
const UPDATE_IMAGE_TYPE =
{
  0: "UPDATE_IMAGE_NOT_VALID",
  1: "UPDATE_IMAGE_APPLICATION",
  2: "UPDATE_IMAGE_BOOTLOADER",
  3: "UPDATE_IMAGE_COPROCESSOR",
};
const COMMAND_ID =
{
  0: "COMMAND_ID_GET_STATUS_INTERVAL",
  1: "COMMAND_ID_SET_STATUS_INTERVAL",
  2: "COMMAND_ID_GET_STATUS_PARAMETER_TX_ENABLE_REGISTER",
  3: "COMMAND_ID_SET_STATUS_PARAMETER_TX_ENABLE_REGISTER",
  4: "COMMAND_ID_GET_STATUS",
  5: "COMMAND_ID_GET_BATTERY_VOLTAGE",
  6: "COMMAND_ID_GET_SABOTAGE_CONTACT_STATE",
  7: "COMMAND_ID_GET_ERROR_CODE",
  8: "COMMAND_ID_GET_DEVICE_TIME",
  9: "COMMAND_ID_SET_DEVICE_TIME",
  10: "COMMAND_ID_GET_DEVICE_TIME_CONFIG",
  11: "COMMAND_ID_SET_DEVICE_TIME_CONFIG",
  12: "COMMAND_ID_SET_SABOTAGE_CONTACT_CONFIG",
  13: "COMMAND_ID_GET_SABOTAGE_CONTACT_CONFIG",
  14: "COMMAND_ID_GET_HALL_SENSOR_STATE",
  15: "COMMAND_ID_SET_HALL_SENSOR_CONFIG",
  16: "COMMAND_ID_GET_HALL_SENSOR_CONFIG",
  17: "COMMAND_ID_GET_INPUT_CLAMP_STATE",
  18: "COMMAND_ID_SET_INPUT_CLAMP_CONFIG",
  19: "COMMAND_ID_GET_INPUT_CLAMP_CONFIG",
  20: "COMMAND_ID_SET_INPUT_CLAMP_SENSOR_TYPE",
  21: "COMMAND_ID_GET_INPUT_CLAMP_SENSOR_TYPE",
  22: "COMMAND_ID_GET_INPUT_CLAMP_SENSOR_FILTER_TIME",
  23: "COMMAND_ID_SET_INPUT_CLAMP_SENSOR_FILTER_TIME",
  54: "COMMAND_ID_COMMAND_FAILED",
  57: "COMMAND_ID_SET_HARDWARE_FACTORY_RESET_LOCK",
  58: "COMMAND_ID_GET_HARDWARE_FACTORY_RESET_LOCK",
  240: "COMMAND_ID_GET_AUTO_UPDATE_INSTALLATION",
  243: "COMMAND_ID_GET_PENDING_UPDATE_INFO",
  247: "COMMAND_ID_GET_REMAINING_TIME_UNTIL_REJOIN",
  248: "COMMAND_ID_GET_DATA_RATE",
  249: "COMMAND_ID_SET_DATA_RATE",
  250: "COMMAND_ID_GET_REJOIN_BEHAVIOR",
  251: "COMMAND_ID_SET_REJOIN_BEHAVIOR",
  252: "COMMAND_ID_GET_ALL_CONFIG",
  253: "COMMAND_ID_PERFORM_FACTORY_RESET",
  254: "COMMAND_ID_PERFORM_SOFTWARE_RESET",
  255: "COMMAND_ID_GET_VERSION"
};

function decodeUplink(input) {
  
  var size = input.bytes.length;

  const data = {};
  
  var bufferSize = input.bytes.length;
  var idx = 0;
  commandId = -1;

  while(idx < bufferSize)
  {
    commandId = input.bytes[idx++];
    
    switch(COMMAND_ID[commandId])
    {
      case "COMMAND_ID_GET_STATUS_INTERVAL":
        data.status_report = data.status_report || {};
        data.status_report.interval = data.status_report.interval || {};
        data.status_report.interval.value = input.bytes[idx++] * 360 + 30;
        data.status_report.interval.unit ="s";
      break;
      case "COMMAND_ID_GET_STATUS_PARAMETER_TX_ENABLE_REGISTER":
        data.radio = data.radio || {};
        data.radio.status_report = data.radio.status_report || {};  
        data.radio.status_report.parameter_tx_enable_reg = data.radio.status_report.parameter_tx_enable_reg || {};
        
        var status_param_tx_enable_reg = input.bytes[idx++];
        
        data.radio.status_report.parameter_tx_enable_reg.battery_voltage_enabled = !!(status_param_tx_enable_reg & (1 << 7));
        data.radio.status_report.parameter_tx_enable_reg.sabotage_contact_states_enabled = !!(status_param_tx_enable_reg & (1 << 6));
        data.radio.status_report.parameter_tx_enable_reg.hall_sensore_states_enabled = !!(status_param_tx_enable_reg & (1 << 5));
        data.radio.status_report.parameter_tx_enable_reg.input_clamp_states_enabled = !!(status_param_tx_enable_reg & (1 << 4));
        data.radio.status_report.parameter_tx_enable_reg.unit = "bool";
      break;
      case "COMMAND_ID_GET_STATUS":
        var status_param_tx_enable_reg = input.bytes[idx++];

        if( !!(status_param_tx_enable_reg & (1 << 7)) )
        {
          data.battery_voltage = data.battery_voltage || {};
          data.battery_voltage.value = ( input.bytes[idx++] * 10 + 1500).toFixed(0);
          data.battery_voltage.unit = "mV";
        }

        if( !!(status_param_tx_enable_reg & (1 << 6)) )
        {
          data.sabotage_contact_state = {};
          data.sabotage_contact_state.value = SABOTAGE_CONTACT_STATE[input.bytes[idx++]& 0x03];
          data.sabotage_contact_state.unit = "string";
        }

        if( !!(status_param_tx_enable_reg & (1 << 5)) )
        {
          data.hall_sensor_state = {};
          data.hall_sensor_state.value = INPUT_STATE[input.bytes[idx++]& 0x03];
          data.hall_sensor_state.unit = "string";
        }

        if( !!(status_param_tx_enable_reg & (1 << 4)) )
        {
          data.input_clamp_state = {};
          data.input_clamp_state.value = INPUT_STATE[input.bytes[idx++]& 0x03];
          data.input_clamp_state.unit = "string";
        }
      break;
      case "COMMAND_ID_GET_BATTERY_VOLTAGE":
        data.battery_voltage = {};
        data.battery_voltage.value = ( input.bytes[idx++] * 10 + 1500).toFixed(0);
        data.battery_voltage.unit = "mV";
      break;
      case "COMMAND_ID_GET_SABOTAGE_CONTACT_STATE":
        data.sabotage_contact_state = {};
        data.sabotage_contact_state.value = SABOTAGE_CONTACT_STATE[input.bytes[idx++]& 0x03];
        data.sabotage_contact_state.unit = "string";
      break;
      case "COMMAND_ID_GET_SABOTAGE_CONTACT_CONFIG":
        data.sabotage_contact_config = {};
        data.sabotage_contact_config.value = !!(input.bytes[idx++] & 0x01);
        data.sabotage_contact_config.unit = "bool";
      break;
      case "COMMAND_ID_GET_HALL_SENSOR_STATE":
        data.hall_sensor_state = {};
        data.hall_sensor_state.value = INPUT_STATE[input.bytes[idx++]& 0x03];
        data.hall_sensor_state.unit = "string";
      break;     
      case "COMMAND_ID_GET_HALL_SENSOR_CONFIG":
        data.hall_sensor_config = {};
        data.hall_sensor_config.value = !!(input.bytes[idx++] & 0x01);
        data.hall_sensor_config.unit = "bool";
      break;
      case "COMMAND_ID_GET_INPUT_CLAMP_STATE":
        data.input_clamp_state = {};
        data.input_clamp_state.value = INPUT_STATE[input.bytes[idx++]& 0x03];
        data.input_clamp_state.unit = "string";
      break;     
      case "COMMAND_ID_GET_INPUT_CLAMP_CONFIG":
        data.input_clamp_config = {};
        data.input_clamp_config.value = !!(input.bytes[idx++] & 0x01);
        data.input_clamp_config.unit = "bool";
      break;
      case "COMMAND_ID_GET_INPUT_CLAMP_SENSOR_TYPE":
        data.input_clamp_sensor_type = {};
        data.input_clamp_sensor_type.value = INPUT_CLAMP_SENSOR_TYPE[input.bytes[idx++]& 0x03];
        data.input_clamp_sensor_type.unit = "string";
      break;
      case "COMMAND_ID_GET_INPUT_CLAMP_SENSOR_FILTER_TIME":
        data.input_clamp_filter_time = {};
        data.input_clamp_filter_time.value = input.bytes[idx++] * 30;
        data.input_clamp_filter_time.unit ="s";
      break;
      case "COMMAND_ID_GET_ERROR_CODE":
        data.error_code = {};
        data.error_code.value = ERROR_CODE[input.bytes[idx++]];
        data.error_code.unit = "string";
      break;
      case "COMMAND_ID_GET_DEVICE_TIME":
        data.device_time = data.device_time || {};
        data.device_time.local = data.device_time.local || {};
        data.device_time.local.second = {};
        data.device_time.local.minute = {};
        data.device_time.local.hour = {};
        data.device_time.local.day = {};
        data.device_time.local.weekday = {};
        data.device_time.local.month = {};
        data.device_time.local.year = {};
        data.device_time.local.is_dst = {};
        data.device_time.local.utc_offset = {};

        data.device_time.local.second.value = input.bytes[idx++] & 0x1F;
        data.device_time.local.second.unit = "s";

        data.device_time.local.minute.value = (input.bytes[idx] >> 2) & 0x3F;
        data.device_time.local.minute.unit = "min";

        data.device_time.local.hour.value = ((input.bytes[idx++] & 0x03) << 3) + (input.bytes[idx] >> 5);
        data.device_time.local.hour.unit = "h";

        data.device_time.local.day.value = input.bytes[idx++] & 0x1F;
        data.device_time.local.day.unit = "d";

        data.device_time.local.is_dst.value = !!(input.bytes[idx] & 0x80);
        data.device_time.local.is_dst.unit = "bool";

        data.device_time.local.weekday.value = WEEKDAY[(input.bytes[idx] >> 4) & 0x07];
        data.device_time.local.weekday.unit = "string";

        data.device_time.local.month.value = MONTH[input.bytes[idx++] & 0x0F];
        data.device_time.local.month.unit = "string";

        data.device_time.local.year.value = input.bytes[idx++] + 2000;
        data.device_time.local.year.unit = "a";

        data.device_time.local.utc_offset.value = (input.bytes[idx++] * 0.25 - 12).toFixed(2);
        data.device_time.local.utc_offset.unit = "h";
      break;
      case "COMMAND_ID_GET_DEVICE_TIME_CONFIG":
        data.device_time = data.device_time || {};
        data.device_time.config = data.device_time.config || {};
        data.device_time.config.auto_time_sync_en = {};
        data.device_time.config.utc_offset = {};
        data.device_time.config.utc_dst_offset = {};
        data.device_time.config.utc_dst_begin = {};
        data.device_time.config.utc_dst_end = {};
        data.device_time.config.utc_dst_begin.week_of_month = {};
        data.device_time.config.utc_dst_end.week_of_month = {};
        data.device_time.config.utc_dst_begin.month = {};
        data.device_time.config.utc_dst_end.month = {};
        data.device_time.config.utc_dst_begin.weekday = {};
        data.device_time.config.utc_dst_end.weekday = {};
        data.device_time.config.utc_dst_begin.hour = {};
        data.device_time.config.utc_dst_end.hour = {};
        data.device_time.config.utc_dst_begin.minute = {};
        data.device_time.config.utc_dst_end.minute = {};

        data.device_time.config.auto_time_sync_en.value = !!(input.bytes[idx] >> 7);
        data.device_time.config.auto_time_sync_en.unit = "bool";
        
        data.device_time.config.utc_offset.value = ((input.bytes[idx++] & 0x7F) * 0.25 - 12).toFixed(2);
        data.device_time.config.utc_offset.unit = "h";

        data.device_time.config.utc_dst_begin.week_of_month.value = WEEK_OF_MONTH[ (input.bytes[idx] >> 4) & 0x0F ];
        data.device_time.config.utc_dst_begin.week_of_month.unit = "string";

        data.device_time.config.utc_dst_begin.month.value = MONTH[input.bytes[idx++] & 0x0F];
        data.device_time.config.utc_dst_begin.month.unit = "string";

        data.device_time.config.utc_dst_begin.weekday.value = WEEKDAY[input.bytes[idx] >> 5];
        data.device_time.config.utc_dst_begin.weekday.unit = "string";

        data.device_time.config.utc_dst_begin.hour.value = (input.bytes[idx++] & 0x0F);
        data.device_time.config.utc_dst_begin.hour.unit = "h";

        data.device_time.config.utc_dst_offset.value = ((input.bytes[idx++] & 0x7F) * 0.25 - 12).toFixed(2);
        data.device_time.config.utc_dst_offset.unit = "h";

        data.device_time.config.utc_dst_end.week_of_month.value = WEEK_OF_MONTH[ (input.bytes[idx] >> 4) & 0x0F ];
        data.device_time.config.utc_dst_end.week_of_month.unit = "string";

        data.device_time.config.utc_dst_end.month.value = MONTH[input.bytes[idx++] & 0x0F];
        data.device_time.config.utc_dst_end.month.unit = "string";

        data.device_time.config.utc_dst_end.weekday.value = WEEKDAY[input.bytes[idx] >> 5];
        data.device_time.config.utc_dst_end.weekday.unit = "string";

        data.device_time.config.utc_dst_end.hour.value = (input.bytes[idx++] & 0x0F);
        data.device_time.config.utc_dst_end.hour.unit = "h";

        data.device_time.config.utc_dst_begin.minute.value = (input.bytes[idx] >> 4) * 5;
        data.device_time.config.utc_dst_begin.minute.unit = "min";

        data.device_time.config.utc_dst_end.minute.value = (input.bytes[idx++] & 0x0F) * 5;
        data.device_time.config.utc_dst_end.minute.unit = "min";
      break;
      case "COMMAND_ID_COMMAND_FAILED":
        data.radio = data.radio || {};
        data.radio.failed_commands = {};

        var nbr_failed_commands = input.bytes[idx++];

        data.radio.failed_commands.value = {};

        for(let i = 0; i < nbr_failed_commands; i++)
        {
          data.radio.failed_commands.value[i] = COMMAND_ID[input.bytes[idx++]];
        }

        data.radio.failed_commands.unit = "COMMAND_ID";
      break;
      case "COMMAND_ID_GET_HARDWARE_FACTORY_RESET_LOCK":
        data.button_action = data.button_action || {};
        data.button_action.hw_factory_reset_locked = data.button_action.hw_factory_reset_locked || {};

        data.button_action.hw_factory_reset_locked.value = !!(input.bytes[idx++] & (0x01));
        data.button_action.hw_factory_reset_locked.unit = "bool";
      break;
      case "COMMAND_ID_GET_REMAINING_TIME_UNTIL_REJOIN":
        data.radio = data.radio || {};
        data.radio.cyclic_rejoin = data.radio.cyclic_rejoin || {};
        data.radio.cyclic_rejoin.remaining_time_until_rejoin = data.radio.cyclic_rejoin.remaining_time_until_rejoin || {};

        data.radio.cyclic_rejoin.remaining_time_until_rejoin.value = ((input.bytes[idx++] & 0x1F) << 16) + (input.bytes[idx++] << 8) + input.bytes[idx++];
        data.radio.cyclic_rejoin.remaining_time_until_rejoin.unit = "min";
      break;
      case "COMMAND_ID_GET_DATA_RATE":
        data.radio = data.radio || {};
        data.radio.data_rate = {};
        data.radio.data_rate.value = DATA_RATE[(input.bytes[idx++] & 0x0F)];
        data.radio.data_rate.unit = "string";
      break;

            case "COMMAND_ID_GET_AUTO_UPDATE_INSTALLATION":
        data.update_info = data.update_info || {};
        data.update_info.auto_update_installation_en = {};

        data.update_info.auto_update_installation_en.value = {};
        data.update_info.auto_update_installation_en.value = !!(input.bytes[idx++]);
        data.update_info.auto_update_installation_en.unit = "bool";
      break;

      case "COMMAND_ID_GET_PENDING_UPDATE_INFO":
        data.update_info = data.update_info || {};
        data.update_info.update_image = data.update_info.update_image || {};
        data.update_info.update_image.type = {};
        data.update_info.update_image.version = {};

        data.update_info.update_image.type.value = UPDATE_IMAGE_TYPE[input.bytes[idx++]];
        data.update_info.update_image.type.unit = "string";
        data.update_info.update_image.version.value = {};
        data.update_info.update_image.version.value[0] = input.bytes[idx++];
        data.update_info.update_image.version.value[1] = input.bytes[idx++];
        data.update_info.update_image.version.value[2] = input.bytes[idx++];
        data.update_info.update_image.version.unit = "uint";
      break;
      
      case "COMMAND_ID_GET_REJOIN_BEHAVIOR":
        data.radio = data.radio || {};
        data.radio.cyclic_rejoin = data.radio.cyclic_rejoin || {};
        data.radio.cyclic_rejoin.conf = data.radio.cyclic_rejoin.conf || {};
        data.radio.cyclic_rejoin.interval = data.radio.cyclic_rejoin.interval || {};

        data.radio.cyclic_rejoin.conf.value = REJOIN_BEHAVIOR[!(input.bytes[idx] >> 7)];
        data.radio.cyclic_rejoin.conf.unit = "string"; 

        data.radio.cyclic_rejoin.interval.value = (((input.bytes[idx++] & 0x7F) * (255)) + input.bytes[idx++]);
        data.radio.cyclic_rejoin.interval.unit = "h";
      break;
      case "COMMAND_ID_GET_VERSION":
        data.version = data.version || {};
        data.version.hw_revision = {};
        data.version.application = {};
        data.version.bootloader = {};
        data.version.lorawan_l2 = {};
        data.version.payload_parser = {};

        data.version.hw_revision.value = input.bytes[idx++];
        data.version.hw_revision.unit = "uint";

        data.version.application.value = {};
        data.version.application.value[0] = input.bytes[idx++];
        data.version.application.value[1] = input.bytes[idx++];
        data.version.application.value[2] = input.bytes[idx++];
        data.version.application.unit = "uint";

        data.version.bootloader.value = {};
        data.version.bootloader.value[0] = input.bytes[idx++];
        data.version.bootloader.value[1] = input.bytes[idx++];
        data.version.bootloader.value[2] = input.bytes[idx++];
        data.version.bootloader.unit = "uint";

        data.version.lorawan_l2.value = {};
        data.version.lorawan_l2.value[0] = input.bytes[idx++];
        data.version.lorawan_l2.value[1] = input.bytes[idx++];
        data.version.lorawan_l2.value[2] = input.bytes[idx++];
        data.version.lorawan_l2.unit = "uint";

        data.version.payload_parser.value = {};
        data.version.payload_parser.value[0] = payload_parser_version[0];
        data.version.payload_parser.value[1] = payload_parser_version[1];
        data.version.payload_parser.value[2] = payload_parser_version[2];
        data.version.payload_parser.unit = "uint";
      break;
      default:
      break;     
    }
  }

  return {
    data: data,
    warnings: [],
    errors: []
  };
}
```

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.dnt.de/dnt-lw-wsci/payload-decoder.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
