GB100 LoRaWAN 智能安全帽用户手册
设备信息:型号 GB100,devEui ffffff100004e9c3,网关 IP 192.168.31.205,Modbus Slave ID 8,BACnet Device ID 107
1 协议概览
GB100 在 Fport 210 上报 GPS 位置(经纬度/海拔)、电池电压/百分比、跌倒报警、信标数据及信号质量。
1.1 上行数据协议(Fport 210)
载荷格式(Fport 210):
| 字节位置 | 字段 | 说明 |
|---|---|---|
| 0 | 保留 | 固定 0x00(协议版本) |
| 1 … N | TLV 对 | [Type(1 B)][Value(N B)] … 循环至结束 |
每个 Type 字节决定字段名称和后续 value 字节数:
| Type | Value字节数 | 字段名称 | 编码方式 | 换算 | 单位 | 说明 |
|---|---|---|---|---|---|---|
0x01 |
1 | model |
uint8 | — | — | 型号码 = 0x60 |
0x93 |
1 | batteryLevel |
uint8 | — | % | 0–100 % 电量 |
0x6D |
1 | packetType |
uint8 | — | — | 0x00=心跳 0x01=数据上报 |
0xAA |
2 | temperature |
int16 BE | ÷10 | °C | 如 0x00FD=253 → 25.3 °C |
0xA9 |
1 | temperatureAlarmStatus |
uint8 | — | — | 0=正常 1=过低 2=过高 3=无法采集 |
0x57 |
4 | atmosphericPressure |
uint32 BE | — | Pa | 如 101325 Pa |
0xD8 |
4 | altitude |
int32 BE | ÷10 | m | 有符号;如 538 → 53.8 m |
0xCB |
1 | fallAlarmStatus |
uint8 | — | — | 0=无报警 1=跌倒报警 |
0xCC |
1 | fallAlarmEvent |
uint8 | — | — | 0=无事件 1=跌倒事件 |
0xCD |
1 | helmetRemovalAlarmStatus |
uint8 | — | — | 0=无报警 1=摘帽报警 |
0xCE |
1 | helmetRemovalAlarmEvent |
uint8 | — | — | 0=无事件 1=摘帽事件 |
0xD1 |
1 | impactAlarmStatus |
uint8 | — | — | 0=无报警 1=撞击报警 |
0xD2 |
1 | impactAlarmEvent |
uint8 | — | — | 0=无事件 1=撞击事件 |
0xCF |
1 | electricityProximityAlarmStatus |
uint8 | — | — | 0=无报警 1=靠近电气报警 |
0xD0 |
1 | electricityProximityAlarmEvent |
uint8 | — | — | 0=无事件 1=靠近电气事件 |
0xB8 |
1 | batteryLowAlarm |
uint8 | — | — | 0=正常 1=低电量报警事件 |
0x14 |
1 | sosEvent |
uint8 | — | — | 0=正常 1=SOS 紧急 |
0x3E |
4 | latitude |
int32 BE | ÷10000000 | ° | 如 227439186 → 22.7439186° |
0x43 |
4 | longitude |
int32 BE | ÷10000000 | ° | 如 1139290611 → 113.9290611° |
0xC3 |
1 | positionAccuracy |
uint8 | ÷10 | — | 0–254 = 精度 ÷10;255 = 无效 |
0xDA |
1+N | gpsData |
block | — | — | 1字节长度 + GPS 轨迹块;详见下方 GPS 子表 |
0xD9 |
1+N | beaconData |
block | — | — | 1字节长度 + 信标扫描块;详见下方信标子表 |
0xDA GPS 轨迹数据块(GB100)
| 偏移 | 字节数 | 字段 | 编码 | 说明 |
|---|---|---|---|---|
| 0 | 1 | dataLength | uint8 | 块数据总字节数 N |
| 1 | 4 | gpsTimestamp | uint32 BE | 参考 Unix 时间戳 |
| 5 | 1 | pointCount | uint8 | GPS 点数量 M |
| 每个 GPS 点 (16 字节): | ||||
| 0 | 1 | flags | uint8 | Bit 0=时间有效;Bit 1=重复发送 |
| 1 | 2 | timeOffset | uint16 BE | 相对参考时间戳的偏移秒数 |
| 3 | 4 | latitude | int32 BE | ÷10,000,000 → 度 |
| 7 | 4 | longitude | int32 BE | ÷10,000,000 → 度 |
| 11 | 4 | altitude | int32 BE | ÷10 → 米 |
| 15 | 1 | positionAccuracy | uint8 | ÷10 → 精度因子;255=无效 |
点绝对时间 =gpsTimestamp − timeOffset
最新点(timeOffset=0 或最大索引)的经纬度升级为顶层字段。
0xD9 信标数据块(CM100 / GB100)
| 偏移 | 字节数 | 字段 | 编码 | 说明 |
|---|---|---|---|---|
| 0 | 1 | dataLength | uint8 | 块数据总字节数 N |
| 1 | 4 | timestamp | uint32 BE | 扫描时的 Unix 时间戳 |
| 5 | 1 | beaconCount | uint8 | 信标数量 M |
| 每个信标 (10 字节): | ||||
| 0 | 1 | flags | uint8 | Bit 0=时间戳有效;Bit 1=重复发送 |
| 1 | 4 | beaconId | uint32 BE | 信标 MAC 地址的后 4 字节 |
| 5 | 2 | timeOffset | uint16 BE | 相对扫描时间戳的偏移秒数 |
| 7 | 1 | rssi | int8 | 有符号 RSSI(dBm) |
| 8 | 1 | batteryLevel | uint8 | 0–100 %;255=无效 |
| 9 | 1 | scannedCount | uint8 | 扫描到的信标数量 |
每个信标的绝对时间 = timestamp − timeOffset
JavaScript 解码示例:
// 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;
}
脚本下载:LPP.zip
版本说明: LPP.js 基于 ChirpStack v4.17.0 开发和测试。不同版本的 ChirpStack JavaScript 编解码器 API 可能存在差异——如果您使用的是其他版本,请在部署前检查并根据需要调整脚本。
2 获取上行数据
⚠️ 以下示例中的 IP 地址(192.168.31.205/192.168.31.193)、ChirpStack API token、Slave ID、BACnet Device ID 及 devEui 均为演示示例,请替换为实际网关 IP、ChirpStack API token 及设备参数。
2.1 ChirpStack MQTT 订阅
订阅 MQTT topic 以接收实时上行数据:
应用 ID —3ef9e6b9-ec54-4eda-86b8-a5fb46899f39是网关内置的出厂默认 ChirpStack 应用。
如果您创建了其他应用,请替换为实际的应用 ID。
网关 IP —192.168.31.205为示例网关 WAN 口 IP,
请替换为您实际的网关 IP 地址。
设备 EUI —ffffff100004e9c3为示例设备 EUI,
请替换为网关设备列表中显示的实际 EUI;
也可用+通配符一次订阅所有设备的数据。
# 订阅指定设备
mosquitto_sub -h 192.168.31.205 -p 1883 \
-u gateway -P mqtt88888888 \
-t "application/3ef9e6b9-ec54-4eda-86b8-a5fb46899f39/device/ffffff100004e9c3/event/up"
# 订阅所有应用下所有设备(通配符)
mosquitto_sub -h 192.168.31.205 -p 1883 \
-u gateway -P mqtt88888888 \
-t "application/+/device/+/event/up"
上行数据载荷示例(JSON):
{
"devEui": "ffffff100004e9c3",
"fPort": 210,
"object": {
... (已解码的 LPP 字段)
}
}
2.2 IoT Hub HTTP API
发送 GET 请求获取设备最新状态:
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 脚本
脚本下载:modbus_tcp_read.py
使用 modbus_tcp_read.py 一次性读取所有寄存器:
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
工具下载:Modbus Poll 9.5.0.1507.zip
- 打开 Modbus Poll,连接
192.168.31.205:502,Slave ID8 - 菜单 Setup → Read/Write Definition,功能码选 FC03,起始地址
6,长度93 - 点击 OK — 数值实时刷新
2.5 IoT Hub BACnet BIP — Python 脚本
脚本下载:bacnet_read.py
使用 bacnet_read.py 读取所有 BACnet 对象:
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
工具下载:SetupYabe_v2.1.0.exe
- 打开 YABE,连接
192.168.31.205:47808 - 在设备树中展开设备 107
- 浏览 AI/BI/AV/BV/CV 对象,查看实时数值