GB100 LoRaWAN Smart Safety Helmet User Guide

Device Information: Model GB100, devEui ffffff100004e9c3, gateway IP 192.168.31.205, Modbus Slave ID 8, BACnet Device ID 107

1 Protocol Overview

The GB100 reports GPS location (latitude/longitude/altitude), battery voltage/percentage, fall alarm, beacon data, and signal quality on Fport 210.

Payload format (Fport 210):

Byte Field Description
0 Reserved Always 0x00 (protocol version)
1 … N TLV pairs [Type(1 B)][Value(N B)] … repeating until end

Each Type byte determines the field name and the number of following value bytes:

Type Value Bytes Field Name Encoding Scale Unit Notes
0x01 1 model uint8 Model code = 0x60
0x93 1 batteryLevel uint8 % 0–100 % battery level
0x6D 1 packetType uint8 0x00=heartbeat 0x01=data report
0xAA 2 temperature int16 BE ÷10 °C e.g. 0x00FD=253 → 25.3 °C
0xA9 1 temperatureAlarmStatus uint8 0=normal 1=too low 2=too high 3=cannot collect
0x57 4 atmosphericPressure uint32 BE Pa e.g. 101325 Pa
0xD8 4 altitude int32 BE ÷10 m Signed; e.g. 538 → 53.8 m
0xCB 1 fallAlarmStatus uint8 0=no alarm 1=fall alarm
0xCC 1 fallAlarmEvent uint8 0=no event 1=fall event
0xCD 1 helmetRemovalAlarmStatus uint8 0=no alarm 1=removal alarm
0xCE 1 helmetRemovalAlarmEvent uint8 0=no event 1=removal event
0xD1 1 impactAlarmStatus uint8 0=no alarm 1=impact alarm
0xD2 1 impactAlarmEvent uint8 0=no event 1=impact event
0xCF 1 electricityProximityAlarmStatus uint8 0=no alarm 1=electricity alarm
0xD0 1 electricityProximityAlarmEvent uint8 0=no event 1=electricity event
0xB8 1 batteryLowAlarm uint8 0=normal 1=low battery alarm event
0x14 1 sosEvent uint8 0=normal 1=SOS danger
0x3E 4 latitude int32 BE ÷10000000 ° e.g. 227439186 → 22.7439186°
0x43 4 longitude int32 BE ÷10000000 ° e.g. 1139290611 → 113.9290611°
0xC3 1 positionAccuracy uint8 ÷10 0–254 = accuracy ÷10; 255 = invalid
0xDA 1+N gpsData block 1-byte length + GPS trajectory block; see GPS sub-table below
0xD9 1+N beaconData block 1-byte length + beacon scan block; see Beacon sub-table below

0xDA GPS Trajectory Data Block (GB100)

Offset Bytes Field Encoding Notes
0 1 dataLength uint8 Total block data bytes N
1 4 gpsTimestamp uint32 BE Reference Unix timestamp
5 1 pointCount uint8 Number of GPS points M
Per GPS point (16 bytes each):
0 1 flags uint8 Bit 0=time valid; Bit 1=repeat send
1 2 timeOffset uint16 BE Seconds before reference timestamp
3 4 latitude int32 BE ÷10,000,000 → degrees
7 4 longitude int32 BE ÷10,000,000 → degrees
11 4 altitude int32 BE ÷10 → meters
15 1 positionAccuracy uint8 ÷10 → accuracy factor; 255=invalid
Point absolute time = gpsTimestamp − timeOffset
Latest point (timeOffset=0 or largest index) is promoted to top-level latitude/longitude.

0xD9 Beacon Data Block (CM100 / GB100)

Offset Bytes Field Encoding Notes
0 1 dataLength uint8 Total block data bytes N
1 4 timestamp uint32 BE Unix timestamp of scan
5 1 beaconCount uint8 Number of beacons M
Per beacon (10 bytes each):
0 1 flags uint8 Bit 0=timestamp valid; Bit 1=repeat send
1 4 beaconId uint32 BE Last 4 bytes of beacon MAC address
5 2 timeOffset uint16 BE Seconds before scan timestamp
7 1 rssi int8 Signed RSSI (dBm)
8 1 batteryLevel uint8 0–100 %; 255=invalid
9 1 scannedCount uint8 Number of beacons scanned
Absolute time of each beacon = timestamp − timeOffset

JavaScript Decoder Example:

// GB100 Smart Safety Helmet — Fport 210 uplink decoder
function decodeUplink(bytes) {
  var i = 1, r = {};
  function u16(b,o){ return (b[o]<<8)|b[o+1]; }
  function i16(b,o){ var v=u16(b,o); return v>32767?v-65536:v; }
  function u32(b,o){ return ((b[o]<<24)|(b[o+1]<<16)|(b[o+2]<<8)|b[o+3])>>>0; }
  function i32(b,o){ var v=u32(b,o); return v>0x7FFFFFFF?v-0x100000000:v; }
  while (i < bytes.length) {
    var t = bytes[i++];
    switch (t) {
      case 0x01: r.model              = bytes[i++]; break;
      case 0x14: r.sosEvent           = bytes[i++]; break;
      case 0x93: r.batteryLevel       = bytes[i++]; break; // %
      case 0x6D: r.packetType         = bytes[i++]; break;
      case 0xAA: r.temperature        = i16(bytes,i)/10; i+=2; break; // °C
      case 0xA9: r.temperatureAlarmStatus = bytes[i++]; break;
      case 0x57: r.atmosphericPressure= u32(bytes,i); i+=4; break; // Pa
      case 0xD8: r.altitude           = i32(bytes,i)/10; i+=4; break; // m
      case 0xB8: r.batteryLowAlarm    = bytes[i++]; break;
      case 0xCB: r.fallAlarmStatus    = bytes[i++]; break;
      case 0xCC: r.fallAlarmEvent     = bytes[i++]; break;
      case 0xCD: r.helmetRemovalAlarmStatus = bytes[i++]; break;
      case 0xCE: r.helmetRemovalAlarmEvent  = bytes[i++]; break;
      case 0xD1: r.impactAlarmStatus  = bytes[i++]; break;
      case 0xD2: r.impactAlarmEvent   = bytes[i++]; break;
      case 0x3E: r.latitude  = i32(bytes,i)/10000000; i+=4; break; // degrees
      case 0x43: r.longitude = i32(bytes,i)/10000000; i+=4; break; // degrees
      case 0xC3: { var a=bytes[i++]; r.positionAccuracy=a===255?null:a/10; break; }
      case 0xDA: { var len=bytes[i++]; /* parse GPS block — see sub-table */ i+=len; break; }
      case 0xD9: { var len=bytes[i++]; /* parse beacon block — see sub-table */ i+=len; break; }
      default:   i++; break;
    }
  }
  return r;
}

Script download: LPP.zip

Compatibility note: LPP.js is developed and tested against ChirpStack v4.17.0. The ChirpStack JavaScript codec API may differ across versions — if you are running a different ChirpStack version, review and adjust the script as needed before deployment.
⚠️ The IP addresses (192.168.31.205 / 192.168.31.193), ChirpStack API token, Slave ID, BACnet Device ID, and devEui in the examples below are for demonstration only. Replace them with your actual gateway IP, ChirpStack API token, and device parameters.

2.1 ChirpStack MQTT Subscription

Subscribe to the MQTT topic to receive real-time uplink frames:

Application ID3ef9e6b9-ec54-4eda-86b8-a5fb46899f39 is the factory-default ChirpStack
application built into the gateway. Replace it with your actual application
ID if you have created a different one.

Gateway IP192.168.31.205 is the gateway WAN port IP shown as an
example. Replace it with your actual gateway IP address.

Device EUIffffff100004e9c3 is the EUI of the example device.
Replace it with the EUI shown in the gateway device list, or use +
as a wildcard to subscribe to all devices at once.
# Subscribe to one specific device
mosquitto_sub -h 192.168.31.205 -p 1883 \
  -u gateway -P mqtt88888888 \
  -t "application/3ef9e6b9-ec54-4eda-86b8-a5fb46899f39/device/ffffff100004e9c3/event/up"

# Subscribe to ALL devices on ALL applications (wildcard)
mosquitto_sub -h 192.168.31.205 -p 1883 \
  -u gateway -P mqtt88888888 \
  -t "application/+/device/+/event/up"

Example uplink payload (JSON):

{
  "devEui": "ffffff100004e9c3",
  "fPort": 210,
  "object": {
    ...  (decoded LPP fields)
  }
}

2.2 IoT Hub HTTP API

Send a GET request to retrieve the latest device state:

curl -s "http://192.168.31.205:8070/api/getStatus?devEui=ffffff100004e9c3"
{
  "success": true,
  "result": {
    "batteryLevel": 18,
    "atmosphericPressure": 100682,
    "altitude": 43.4,
    "temperature": 28.3,
    "temperatureAlarmStatus": 0,
    "fallAlarmStatus": false,
    "fallAlarmEvent": false,
    "helmetRemovalAlarmStatus": false,
    "helmetRemovalAlarmEvent": false,
    "electricityProximityAlarmStatus": false,
    "electricityProximityAlarmEvent": false,
    "impactAlarmStatus": false,
    "impactAlarmEvent": false,
    "silenceAlarmStatus": false,
    "silenceAlarmEvent": false,
    "heightAccessAlarmStatus": false,
    "heightAccessAlarmEvent": false,
    "latitude": 22.743929,
    "longitude": 113.928696,
    "positionAccuracy": 2.5,
    "gpsAbsoluteTimestamp": 1774921335,
    "gpsTimeValid": true,
    "beaconBatteryValid": false,
    "batteryLowAlarm": false,
    "temperatureEvent": false,
    "sosEvent": true,
    "safetyAlarmActive": false,
    "isHeartbeat": true,
    "model": "GB100"
  }
}

2.3 IoT Hub Modbus TCP — Python Script

Script download: modbus_tcp_read.py

Use modbus_tcp_read.py to poll all registers at once:

python3 modbus_tcp_read.py --ip 192.168.31.205 --port 502 \
    --slaveId 8 --sensorType GB100
Target: 192.168.31.205:502 | Slave ID: 8 | Sensor: GB100
================================================================================================================================================================
Attribute                | Addr   | FC  | Format     | Order        | Cnt | Scale    | Raw(Hex)            | Value              | Unit
----------------------------------------------------------------------------------------------------------------------------------------------------------------
online                   | 6      | 03  | Bit/Bool   | Big(ABCD)    | 1   | x1       | 0001                | true               | none
lastOnlineTime           | 7      | 03  | UnixTime   | Big(ABCD)    | 2   | x1       | 69CC CE3D           | 1775029821         | second
batteryLevel             | 9      | 03  | Int16      | Big(ABCD)    | 1   | x1       | 0012                | 18.0               | percent
atmosphericPressure      | 10     | 03  | Int32      | Big(ABCD)    | 2   | x1       | 0001 894A           | 100682.0           | pascal
altitude                 | 12     | 03  | Float32    | Big(ABCD)    | 2   | x1       | 422D 999A           | 43.4               | meter
temperature              | 14     | 03  | Int16(S)   | Big(ABCD)    | 1   | /100     | 0B0E                | 28.3               | celsius
temperatureAlarmStatus   | 15     | 03  | Int16      | Big(ABCD)    | 1   | x1       | 0000                | 0.0                | none
fallAlarmStatus          | 16     | 03  | Bit/Bool   | Big(ABCD)    | 1   | x1       | 0000                | false              | none
fallAlarmEvent           | 17     | 03  | Bit/Bool   | Big(ABCD)    | 1   | x1       | 0000                | false              | none
helmetRemovalAlarmStatus | 18     | 03  | Bit/Bool   | Big(ABCD)    | 1   | x1       | 0000                | false              | none
helmetRemovalAlarmEvent  | 19     | 03  | Bit/Bool   | Big(ABCD)    | 1   | x1       | 0000                | false              | none
electricityProximityAlarmStatus | 20     | 03  | Bit/Bool   | Big(ABCD)    | 1   | x1       | 0000                | false              | none
... (36 fields total)

2.4 IoT Hub Modbus TCP — Modbus Poll

Tool download: Modbus Poll 9.5.0.1507.zip

  1. Open Modbus Poll, connect to 192.168.31.205:502, Slave ID 8
  2. Menu Setup → Read/Write Definition, set Function Code = FC03, Start Address = 6, Length = 93
  3. Click OK — values update in real-time

2.5 IoT Hub BACnet BIP — Python Script

Script download: bacnet_read.py

Use bacnet_read.py to read all BACnet objects:

python3 bacnet_read.py --ip 192.168.31.205 --port 47808 --id 107
Target: 192.168.31.205:47808 | BACnet ID: 107 | Scan: 10700-10799
------------------------------------------------------------
Type | Instance | Offset | Value                    | Object Name
------------------------------------------------------------
BI   | 10702    | 2      | active                   | ffffff100004e9c3.online
AI   | 10703    | 3      | 1775029760.00            | ffffff100004e9c3.lastOnlineTime
AI   | 10704    | 4      | 18.00                    | ffffff100004e9c3.batteryLevel
AI   | 10705    | 5      | 100682.00                | ffffff100004e9c3.atmosphericPressure
AI   | 10706    | 6      | 43.40                    | ffffff100004e9c3.altitude
AI   | 10707    | 7      | 28.30                    | ffffff100004e9c3.temperature
AI   | 10708    | 8      | 0.00                     | ffffff100004e9c3.temperatureAlarmStatus
BI   | 10709    | 9      | inactive                 | ffffff100004e9c3.fallAlarmStatus
BI   | 10710    | 10     | inactive                 | ffffff100004e9c3.fallAlarmEvent
BI   | 10711    | 11     | inactive                 | ffffff100004e9c3.helmetRemovalAlarmStatus
BI   | 10712    | 12     | inactive                 | ffffff100004e9c3.helmetRemovalAlarmEvent
BI   | 10713    | 13     | inactive                 | ffffff100004e9c3.electricityProximityAlarmStatus
... (36 objects total)

2.6 IoT Hub BACnet BIP — YABE

Tool download: SetupYabe_v2.1.0.exe

  1. Open YABE, connect to 192.168.31.205:47808
  2. Expand Device 107 in the device tree
  3. Browse AI/BI/AV/BV/CV objects to view real-time values