Dragino Device Parse

I need a code to parse the data coming from my Dragino SN50v3-CB device – NB-IoT/LTE-M Sensor Node. The payload received is as follows:

{

"IMEI": "860751074067197",

"IMSI": "724068042540503",

"Model": "DTN-300-FSN7-DC",

"mod": 8,

"battery": 3.60,

"signal": 24,

"time": "2025/03/15 16:55:01",

"adc2": 2,

"DS18B20\_Temp": -409.5,

"interrupt": 0,

"interrupt\_level": 0,

"interrupt\_pa4": 0,

"interrupt\_level\_pa4": 0,

"interrupt\_pa8": 0,

"interrupt\_level\_pa8": 0

}

Obviously this data is not saved in the device's Bucket because it needs to be in the following format:

\[

 { "variable": "imei", "value": "860751074067197" },

 { "variable": "imsi", "value": "724068042540503" },

 { "variable": "model", "value": "DTN-300-FSN7-DC" },

 { "variable": "mod", "value": 8 },

 { "variable": "battery", "value": 3.60, "unit": "V" },

 { "variable": "signal", "value": 24, "unit": "dBm" },

 { "variable": "time", "value": "2025/03/15 16:55:01" },

 { "variable": "adc2", "value": 2 },

 { "variable": "ds18b20\_temp", "value": -409.5, "unit": "C" },

 { "variable": "interrupt", "value": 0 },

 { "variable": "interrupt\_level", "value": 0 },

 { "variable": "interrupt\_pa4", "value": 0 },

 { "variable": "interrupt\_level\_pa4", "value": 0 },

 { "variable": "interrupt\_pa8", "value": 0 },

 { "variable": "interrupt\_level\_pa8", "value": 0 }

\]

Can anyone help me with a valid code for parse?

Hi Leandro,

I’ve created the following parser to help you decode the data you’re receiving:

/**
 * Parses device telemetry data and converts it to TagoIO format
 *
 * @param {Object} deviceData - The device telemetry object
 * @param {string} group - Group identifier for related data
 * @param {string} receivedTime - Time when data was received
 * @returns {Array} Array of TagoIO data objects
 */
function parseDeviceTelemetry(deviceData, group, receivedTime) {
  const data = [];
  const time = receivedTime || new Date().toISOString();

  // Device identification information
  if (deviceData.IMEI) {
    data.push({
      variable: "imei",
      value: deviceData.IMEI,
      group,
      time,
      metadata: {
        device_model: deviceData.Model || "Unknown"
      }
    });
  }

  if (deviceData.IMSI) {
    data.push({
      variable: "imsi",
      value: deviceData.IMSI,
      group,
      time
    });
  }

  if (deviceData.Model) {
    data.push({
      variable: "device_model",
      value: deviceData.Model,
      group,
      time
    });
  }

  // Battery level
  if (deviceData.battery !== undefined) {
    data.push({
      variable: "battery",
      value: deviceData.battery,
      unit: "V",
      group,
      time,
      metadata: {
        battery_status:
          deviceData.battery > 3.5
            ? "Good"
            : deviceData.battery > 3.2
            ? "Low"
            : "Critical"
      }
    });
  }

  // Signal strength
  if (deviceData.signal !== undefined) {
    data.push({
      variable: "signal_strength",
      value: deviceData.signal,
      unit: "dBm",
      group,
      time,
      metadata: {
        signal_quality:
          deviceData.signal > 20
            ? "Excellent"
            : deviceData.signal > 15
            ? "Good"
            : deviceData.signal > 10
            ? "Fair"
            : "Poor"
      }
    });
  }

  // Module information
  if (deviceData.mod !== undefined) {
    data.push({
      variable: "module_id",
      value: deviceData.mod,
      group,
      time
    });
  }

  // ADC reading
  if (deviceData.adc2 !== undefined) {
    data.push({
      variable: "adc2",
      value: deviceData.adc2,
      unit: "V",
      group,
      time
    });
  }

  // Temperature sensor (DS18B20)
  if (deviceData.DS18B20_Temp !== undefined) {
    // Check if temperature reading is valid (not error value like -409.5)
    const isValidTemp =
      deviceData.DS18B20_Temp > -200 && deviceData.DS18B20_Temp < 200;
    data.push({
      variable: "temperature",
      value: isValidTemp ? deviceData.DS18B20_Temp : null,
      unit: "°C",
      group,
      time,
      metadata: {
        sensor_type: "DS18B20",
        sensor_status: isValidTemp ? "OK" : "Error",
        raw_value: deviceData.DS18B20_Temp
      }
    });

    // Add sensor status as separate variable for monitoring
    data.push({
      variable: "temperature_sensor_status",
      value: isValidTemp ? "OK" : "Error",
      group,
      time,
      metadata: {
        error_code: isValidTemp ? null : "TEMP_SENSOR_ERROR",
        raw_reading: deviceData.DS18B20_Temp
      }
    });
  }

  // Interrupt monitoring
  if (deviceData.interrupt !== undefined) {
    data.push({
      variable: "interrupt",
      value: deviceData.interrupt,
      group,
      time,
      metadata: {
        interrupt_level: deviceData.interrupt_level || 0
      }
    });
  }

  if (deviceData.interrupt_level !== undefined) {
    data.push({
      variable: "interrupt_level",
      value: deviceData.interrupt_level,
      group,
      time
    });
  }

  // PA4 interrupt monitoring
  if (deviceData.interrupt_pa4 !== undefined) {
    data.push({
      variable: "interrupt_pa4",
      value: deviceData.interrupt_pa4,
      group,
      time,
      metadata: {
        interrupt_level_pa4: deviceData.interrupt_level_pa4 || 0
      }
    });
  }

  if (deviceData.interrupt_level_pa4 !== undefined) {
    data.push({
      variable: "interrupt_level_pa4",
      value: deviceData.interrupt_level_pa4,
      group,
      time
    });
  }

  // PA8 interrupt monitoring
  if (deviceData.interrupt_pa8 !== undefined) {
    data.push({
      variable: "interrupt_pa8",
      value: deviceData.interrupt_pa8,
      group,
      time,
      metadata: {
        interrupt_level_pa8: deviceData.interrupt_level_pa8 || 0
      }
    });
  }

  if (deviceData.interrupt_level_pa8 !== undefined) {
    data.push({
      variable: "interrupt_level_pa8",
      value: deviceData.interrupt_level_pa8,
      group,
      time
    });
  }

  // Device timestamp (if different from received time)
  if (deviceData.time) {
    // Convert device time format to ISO string if needed
    let deviceTime;
    try {
      // Handle the format "2025/03/15 16:55:01"
      const timeStr = deviceData.time.replace(/\//g, "-");
      deviceTime = new Date(timeStr).toISOString();
    } catch (error) {
      deviceTime = time; // Fallback to received time
    }

    data.push({
      variable: "device_timestamp",
      value: deviceData.time,
      group,
      time: deviceTime,
      metadata: {
        original_format: deviceData.time,
        parsed_time: deviceTime
      }
    });
  }

  return data;
}

// Main decoder logic
try {
  // Check if payload contains the device data
  const deviceDataItem = payload.find(
    (item) =>
      item.variable === "payload" ||
      item.variable === "data" ||
      (item.value && typeof item.value === "object")
  );

  if (deviceDataItem) {
    let deviceData;
    // Parse JSON if the value is a string
    if (typeof deviceDataItem.value === "string") {
      try {
        deviceData = JSON.parse(deviceDataItem.value);
      } catch (error) {
        console.error("Failed to parse JSON payload:", error.message);
        payload = [
          { variable: "parser_error", value: "Invalid JSON format", time: new Date().toISOString() }
        ];
      }
    } else if (typeof deviceDataItem.value === "object") {
      deviceData = deviceDataItem.value;
    }

    if (deviceData) {
      // Generate group ID for related data
      const group = deviceDataItem.group || `${Date.now()}-${Math.random().toString(36).substring(2, 5)}`;
      // Parse the device data
      const parsedData = parseDeviceTelemetry(deviceData, group, deviceDataItem.time);
      // Replace payload with parsed data
      payload = parsedData;
    }
  } else {
    // If no structured payload found, try to parse the entire payload as device data
    if (payload.length > 0 && payload[0].value && typeof payload[0].value === "object") {
      const group = `${Date.now()}-${Math.random().toString(36).substring(2, 5)}`;
      const parsedData = parseDeviceTelemetry(payload[0].value, group, payload[0].time);
      payload = parsedData;
    }
  }
} catch (error) {
  console.error("Payload parsing error:", error.message);
  payload = [
    {
      variable: "parser_error",
      value: `Parsing failed: ${error.message}`,
      time: new Date().toISOString()
    }
  ];
}

Please note that the code is expecting that json to be inside the payload variable’s value property, if its not, you’ll need to slightly modify the decoder.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.