Data Format Document
Click here for the decoding code: JavaScript decoding example code
The following is a detailed description of the data format.
1. LoRaWAN Node Data Upload Format
1.1 Overall Data Packet Format
| Sensor-1 ID | Total Length(bytes) | Sensor Data Packet 1-1 | Sensor Data Packet 1-2 | ... | Sensor Data Packet 1-n | ... | Sensor-2 ID | Total Length(bytes) | Sensor Data Packet 1-1 | ... |
|---|---|---|---|---|---|---|---|---|---|---|
| 2 bytes | 1 byte | 2 bytes | 1 byte |
Each LoRaWAN packet can contain data from multiple sensors.
Each sensor can contain multiple types of sub-data.
1.2 Sensor Data Packet Format
| Sensor Data Packet | ID Data Type Inside the Packet | Total Valid Data Length (bytes) | Valid Data of This Sensor Packet |
|---|---|---|---|
| 4 bits | 4 bits | 1 byte | ... |
Total Valid Data Length (bytes): This field is only present for arrays, omitted for other data types.
| Data Type | Value | Bytes Occupied |
|---|---|---|
| array | 0b0000 | max 64 |
| double | 0b0001 | 8 |
| float | 0b0010 | 4 |
| bool | 0b0011 | 1 |
| int8_t | 0b0100 | 1 |
| uint8_t | 0b0101 | 1 |
| int16_t | 0b0110 | 2 |
| uint16_t | 0b0111 | 2 |
| int32_t | 0b1000 | 4 |
| uint32_t | 0b1001 | 4 |
1.3 Sensor Raw Data Conversion Instructions
All data types (except for arrays) are split in the same way as floats.
When packing, the low byte comes first.
typedef union {
union bits_32_raw_data {
uint32_t uint32_t_raw_data;
int32_t int32_t_raw_data;
float float_raw_data;
};
uint8_t bits_32_convert_data[4];
} bits_32_type_convert_t;
data[0] = bits_32_convert_data[0];
data[1] = bits_32_convert_data[1];
data[2] = bits_32_convert_data[2];
data[3] = bits_32_convert_data[3];
1.4 Data Packet Decoding Example
This is an example of a complete LoRaWAN data packet upload. (The data below is in hexadecimal):
04 00 0A 02 2B 34 BB 41 12 88 C5 B3 41 00 00 02 05 07
| Data (Hex) | Description |
|---|---|
| 0x04 0x00 | Parent ID. According to the sensor table, this identifies the GXHTC temperature and humidity sensor. |
| 0x0A | GXHTC data length is 10 bytes. |
| 0x02 (0b0000 0010) | High 4 bits: Sub ID, represents GXHTC temperature. Low 4 bits: Data type is float. |
| 0x2B 0x34 0xBB 0x41 | Temperature value, converted to 23.40047264099121. |
| 0x12 (0b0001 0010) | High 4 bits: Sub ID, represents GXHTC humidity. Low 4 bits: Data type is float. |
| 0x88 0xC5 0xB3 0x41 | Humidity value, converted to 22.471450805664062. |
| 0x00 0x00 | Parent ID. According to the sensor table, this identifies battery power. |
| 0x02 | Battery data length is 2 bytes. |
| 0x05 (0b0000 0101) | High 4 bits: Sub ID, represents battery percentage. Low 4 bits: Data type is uint8_t. |
| 0x07 | Battery remaining: 7%. |
2. Special Circumstances
2.1 Sensor Data Reading Error
When a sensor reading error occurs, the data length field is set to 0, and no data for this sensor is filled afterward. However, if there are multiple sensors and one sensor encounters an error, it does not affect the data transmission of other sensors.
This is an example of a complete LoRaWAN data packet upload. (The data below is in hexadecimal):
04 00 00 00 00 02 05 07
The GXHTC sensor reading error, so the length field is set to 0. However, the battery data transmission is not affected.
3. Sensors
3.1 Sensor ID Summary Table
| Sensor Name | Parent ID | Data Name | Sub ID | Data Type | Decimal Places | Measurement Range | Unit | Description |
|---|---|---|---|---|---|---|---|---|
| Battery Power | 0x0000 | Battery Percentage | 0x00 | uint8_t | 0~100 | |||
| Charging State | 0x01 | uint8_t | 0: uncharged; 1: charging | |||||
| RS485 | 0x0001 | — | — | uint8_t | RS485 uploads array data | |||
| BMP280 | 0x0002 | Atmospheric Pressure | 0x00 | float | 2 | 300~1100 | hPa | |
| Temperature | 0x01 | float | 2 | -40~85 | °C | |||
| BH1750 | 0x0003 | Light Intensity | 0x00 | float | 1 | 1~65535 | lx | |
| GXHTC | 0x0004 | Temperature | 0x00 | float | 2 | -40~125 | °C | |
| Humidity | 0x01 | float | 2 | 0~100 | %RH | |||
| DA217 | 0x0005 | X-axis Acceleration | 0x00 | float | 2 | ±16 | g | |
| Y-axis Acceleration | 0x01 | float | 2 | ±16 | g | |||
| Z-axis Acceleration | 0x02 | float | 2 | ±16 | g | |||
| OUTDOOR_VALVE | 0x0006 | VALVE_0_STATUS | 0x00 | bool | ||||
| VALVE_1_STATUS | 0x01 | bool | ||||||
| PULSE_COUNTER_0 | 0x02 | uint32_t | ||||||
| PULSE_COUNTER_1 | 0x03 | uint32_t | ||||||
| IO | 0x0007 | IO_NUMBER | 0x00 | uint8_t | Number of IOs | |||
| IO_EDIT | 0x01 | int16_t | Each bit represents an IO; 0: non-adjustable, 1: adjustable | |||||
| IO_MODE | 0x02 | int16_t | Each bit represents an IO; 0: input, 1: output | |||||
| IO_STATUS | 0x03 | uint16_t | Each bit represents an IO; 0: low, 1: high | |||||
| PT100 | 0x0008 | Temperature | 0x00 | float | 1 | °C | ||
| DOOR_MONITOR | 0x0009 | DOOR_MONITOR | 0x00 | bool | true: door open; false: door closed | |||
| BODY_DETECTOR | 0x000A | BODY_DETECTOR | 0x00 | bool | true: presence; false: no presence | |||
| SEN0563_HCHO | 0x000B | HCHO | 0x00 | uint16_t | 0~3 | ppm | Qualitative sensor | |
| SEN0564_CO | 0x000C | CO | 0x00 | uint16_t | 5~5000 | ppm | Qualitative sensor | |
| SEN0565_CH4 | 0x000D | CH4 | 0x00 | uint16_t | 1~10000 | ppm(C3H8) | Qualitative sensor | |
| SEN0566_VOC | 0x000E | VOC | 0x00 | uint16_t | 1~500 | ppm | Qualitative sensor | |
| SEN0567_NH3 | 0x000F | NH3 | 0x00 | uint16_t | 1~300 | ppm | Qualitative sensor | |
| SEN0568_H2S | 0x0010 | H2S | 0x00 | uint16_t | 0.5~50 | ppm | Qualitative sensor | |
| SEN0569_EtOH | 0x0011 | EtOH | 0x00 | uint16_t | 1~500 | ppm | Qualitative sensor | |
| SEN0570_SMOKE | 0x0012 | SMOKE | 0x00 | uint16_t | 10~1000 | ppm | Qualitative sensor | |
| SEN0571_ODOR | 0x0013 | ODOR | 0x00 | uint16_t | 0.5~50 | ppm | Qualitative sensor | |
| SEN0572_H2 | 0x0014 | H2 | 0x00 | uint16_t | 0.1~1000 | ppm | Qualitative sensor | |
| SEN0574_NO2 | 0x0015 | NO2 | 0x00 | uint16_t | 0.1~10 | ppm | Qualitative sensor |