1.Jar包下载
jt701-sdk-1.0.0.jar 下载地址
如果需要Jar包开发源码,请与商务申请
2.集成开发说明
2.1.集成开发语言及框架说明
jt701-sdk-1.0.0.jar是基于Java语言,SpringBoot2.x框架,使用到了netty,fastjson,lombok
BaseEnum:基础枚举
Constant:自定义常量
AlarmTypeEnum:报警枚举
EventTypeEnum:事件枚举
LocationData:定位实体类
LockEvent:锁事件实体类
Result:结果实体类
SensorData:从机数据实体类
CommonUtil:公共方法类
NumberUtil:数字操作工具类
ParserUtil:解析方法工具类
DataParser:解析主方法
2.2.集成说明
将jt701-sdk-1.0.0.jar引入到自己的网关程序中,引入方法如下:
在pom.xml引入jar包
<dependency>
<groupId>com.jointech.sdk</groupId>
<artifactId>jt701-sdk</artifactId>
<version>1.0.0</version>
</dependency>
调用jt701-sdk-1.0.0.jar,DataParser类中receiveData()方法
receiveData()方法是重载方法
/**
* 解析Hex字符串原始数据
* @param strData 16进制字符串
* @return
*/
public static Object receiveData(String strData)
{
ByteBuf msgBodyBuf = ByteBufAllocator.DEFAULT.heapBuffer(strData.length()/2);
msgBodyBuf.writeBytes(CommonUtil.hexStr2Byte(strData));
return receiveData(msgBodyBuf);
}
/**
* 解析byte[]原始数据
* @param bytes
* @return
*/
private static Object receiveData(byte[] bytes)
{
ByteBuf msgBodyBuf =ByteBufAllocator.DEFAULT.heapBuffer(bytes.length);
msgBodyBuf.writeBytes(bytes);
return receiveData(msgBodyBuf);
}
/**
* 解析ByteBuf原始数据
* @param in
* @return
*/
private static Object receiveData(ByteBuf in)
{
Object decoded = null;
in.markReaderIndex();
int header = in.readByte();
if (header == Constant.TEXT_MSG_HEADER) {
in.resetReaderIndex();
decoded = ParserUtil.decodeTextMessage(in);
} else if (header == Constant.BINARY_MSG_HEADER) {
in.resetReaderIndex();
decoded = ParserUtil.decodeBinaryMessage(in);
} else {
return null;
}
return JSONArray.toJSON(decoded).toString();
}
2.3.核心代码
解析方法工具类ParserUtil
package com.jointech.sdk.jt701.utils;
import com.jointech.sdk.jt701.constants.Constant;
import com.jointech.sdk.jt701.model.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* <p>Description: 解析方法工具类</p>
* @author HyoJung
* @date 20210526
*/
public class ParserUtil {
private ParserUtil()
{}
/**
* 解析指令数据
* @param in 原始数据
* @return
*/
public static Result decodeTextMessage(ByteBuf in)
{
//定义定位数据实体类
Result model = new Result();
//包头(
in.readByte();
//字段列表
List<String> itemList = new ArrayList<String>();
//透传的二进制数据
ByteBuf msgBody = null;
while (in.readableBytes() > 0) {
//无线网关数据上传(WLNET5、WLNET7)第7个字段以及后面为二进制数据
if (itemList.size() >= 6 && Objects.equals("WLNET", itemList.get(3)) && Constant.WLNET_TYPE_LIST.contains(itemList.get(4))) {
//到结尾")"前的长度
int lastItemLen = in.readableBytes() - 1;
//反转义
msgBody = Unpooled.buffer(lastItemLen);
CommonUtil.unescape(in, msgBody, lastItemLen);
in.readByte();
} else {
//查询逗号的下标截取数据
int index = in.bytesBefore(Constant.TEXT_MSG_SPLITER);
int itemLen = index > 0 ? index : in.readableBytes() - 1;
byte[] byteArr = new byte[itemLen];
in.readBytes(byteArr);
in.readByte();
itemList.add(new String(byteArr));
}
}
//WLNET消息类型为组合
String msgType = itemList.get(1);
if (itemList.size() >= 5 && (Objects.equals("WLNET", itemList.get(3))||Objects.equals("OTA", itemList.get(3)))) {
msgType = itemList.get(3) + itemList.get(4);
}
Object dataBody=null;
if(msgType.equals("WLNET5")) {
SensorData sensorData=parseWlnet5(msgBody);
dataBody=sensorData;
model.setReplyMsg(replyMessage(msgType,sensorData.getIndex()));
}else if(msgType.equals("P45")) {
dataBody=parseP45(itemList);
model.setReplyMsg(replyMessage(msgType,itemList));
}else {
if(itemList.size()>0)
{
dataBody="(";
for(String item :itemList) {
dataBody+=item+",";
}
dataBody=CommonUtil.trimEnd(dataBody.toString(),",");
dataBody += ")";
}
}
model.setDeviceID(itemList.get(0));
model.setMsgType(msgType);
model.setDataBody(dataBody);
return model;
}
/**
* 解析从机数据
* @param byteBuf
* @return
*/
private static SensorData parseWlnet5(ByteBuf byteBuf) {
SensorData sensorData = new SensorData();
//定位时间
byte[] timeArr = new byte[6];
byteBuf.readBytes(timeArr);
String bcdTimeStr = ByteBufUtil.hexDump(timeArr);
ZonedDateTime gpsZonedDateTime = parseBcdTime(bcdTimeStr);
//纬度
byte[] latArr = new byte[4];
byteBuf.readBytes(latArr);
String latHexStr = ByteBufUtil.hexDump(latArr);
BigDecimal latFloat = new BigDecimal(latHexStr.substring(2, 4) + "." + latHexStr.substring(4)).divide(new BigDecimal("60"), 6, RoundingMode.HALF_UP);
double lat = new BigDecimal(latHexStr.substring(0, 2)).add(latFloat).doubleValue();
//经度
byte[] lngArr = new byte[5];
byteBuf.readBytes(lngArr);
String lngHexStr = ByteBufUtil.hexDump(lngArr);
BigDecimal lngFloat = new BigDecimal(lngHexStr.substring(3, 5) + "." + lngHexStr.substring(5, 9)).divide(new BigDecimal("60"), 6, RoundingMode.HALF_UP);
double lng = new BigDecimal(lngHexStr.substring(0, 3)).add(lngFloat).doubleValue();
//位指示
int bitFlag = Byte.parseByte(lngHexStr.substring(9, 10), 16);
//定位状态
int locationType = (bitFlag & 0x01) > 0 ? 1 : 0;
//北纬、南纬
if ((bitFlag & 0b0010) == 0) {
lat = -lat;
}
//东经、西经
if ((bitFlag & 0b0100) == 0) {
lng = -lng;
}
//速度
int speed = (int) (byteBuf.readUnsignedByte() * 1.85);
//方向
int direction = byteBuf.readUnsignedByte() * 2;
//从机时间
byte[] slaveMachineTimeArr = new byte[6];
byteBuf.readBytes(slaveMachineTimeArr);
String slaveMachineBcdTimeStr = ByteBufUtil.hexDump(slaveMachineTimeArr);
ZonedDateTime slaveMachineZonedDateTime = parseBcdTime(slaveMachineBcdTimeStr);
//从机ID
byte[] slaveMachineIdArr = new byte[5];
byteBuf.readBytes(slaveMachineIdArr);
String slaveMachineId = ByteBufUtil.hexDump(slaveMachineIdArr).toUpperCase();
//从机数据流水号
int flowId = byteBuf.readUnsignedByte();
//从机电压
String voltage = new BigDecimal(byteBuf.readUnsignedShort()).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP).toString();
//从机电量
int power = byteBuf.readUnsignedByte();
//RSSI
int rssi = byteBuf.readUnsignedByte();
//传感器类型
int sensorType = byteBuf.readUnsignedByte();
//温度值
double temperature = -1000.0;
//湿度值
int humidity = 0;
//事件类型
int eventType = -1;
//设备状态
int terminalStatus = -1;
//开关锁次数
int lockTimes = -1;
if (sensorType == 1) {
//温度
temperature = parseTemperature(byteBuf.readShort());
//湿度
humidity = byteBuf.readUnsignedByte();
//网关保存数据条数
int itemCount = byteBuf.readUnsignedShort();
//网关状态
int gatewayStatus = byteBuf.readUnsignedByte();
} else if (sensorType == 4) {
//事件
int event = byteBuf.readUnsignedShort();
//判断事件
if (NumberUtil.getBitValue(event, 0) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_0.getValue());
} else if (NumberUtil.getBitValue(event, 1) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_1.getValue());
} else if (NumberUtil.getBitValue(event, 2) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_2.getValue());
} else if (NumberUtil.getBitValue(event, 3) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_3.getValue());
} else if (NumberUtil.getBitValue(event, 4) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_4.getValue());
} else if (NumberUtil.getBitValue(event, 5) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_5.getValue());
} else if (NumberUtil.getBitValue(event, 6) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_6.getValue());
} else if (NumberUtil.getBitValue(event, 7) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_7.getValue());
} else if (NumberUtil.getBitValue(event, 8) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_8.getValue());
} else if (NumberUtil.getBitValue(event, 9) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_9.getValue());
}else if (NumberUtil.getBitValue(event, 14) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_14.getValue());
}
//设备状态
terminalStatus = byteBuf.readUnsignedShort();
//开关锁次数
lockTimes = byteBuf.readUnsignedShort();
//网关状态
int gatewayStatus = byteBuf.readUnsignedByte();
}else if (sensorType == 5||sensorType == 6)
{
//事件
int event = byteBuf.readUnsignedShort();
//判断事件
if (NumberUtil.getBitValue(event, 0) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_15.getValue());
} else if (NumberUtil.getBitValue(event, 1) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_16.getValue());
} else if (NumberUtil.getBitValue(event, 2) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_17.getValue());
} else if (NumberUtil.getBitValue(event, 3) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_6.getValue());
} else if (NumberUtil.getBitValue(event, 4) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_18.getValue());
} else if (NumberUtil.getBitValue(event, 5) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_19.getValue());
} else if (NumberUtil.getBitValue(event, 6) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_3.getValue());
} else if (NumberUtil.getBitValue(event, 7) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_0.getValue());
} else if (NumberUtil.getBitValue(event, 8) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_1.getValue());
} else if (NumberUtil.getBitValue(event, 9) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_20.getValue());
}else if (NumberUtil.getBitValue(event, 10) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_21.getValue());
}else if (NumberUtil.getBitValue(event, 11) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_22.getValue());
}else if (NumberUtil.getBitValue(event, 12) == 1) {
eventType = Integer.parseInt(EventTypeEnum.LockEvent_5.getValue());
}
//设备状态
terminalStatus = byteBuf.readUnsignedShort();
//开关锁次数
lockTimes = byteBuf.readUnsignedShort();
//网关状态
int gatewayStatus = byteBuf.readUnsignedByte();
}
sensorData.setGpsTime(gpsZonedDateTime.toString());
sensorData.setLatitude(lat);
sensorData.setLongitude(lng);
sensorData.setLocationType(locationType);
sensorData.setSpeed(speed);
sensorData.setDirection(direction);
sensorData.setSensorID(slaveMachineId);
sensorData.setLockStatus(NumberUtil.getBitValue(terminalStatus, 0));
sensorData.setLockRope(NumberUtil.getBitValue(terminalStatus, 0));
sensorData.setLockTimes(lockTimes);
sensorData.setIndex(flowId);
sensorData.setVoltage(voltage);
sensorData.setPower(power);
sensorData.setRSSI(rssi);
sensorData.setDateTime(slaveMachineZonedDateTime.toString());
sensorData.setSensorType(sensorType);
sensorData.setTemperature(temperature);
sensorData.setHumidity(humidity);
sensorData.setEvent(eventType);
return sensorData;
}
/**
* 解析P45
* @param itemList
* @return
*/
private static LockEvent parseP45(List<String> itemList)
{
LockEvent model = new LockEvent();
model.DateTime= parseBcdTime(itemList.get(2) + itemList.get(3)).toString();
model.Latitude = Double.valueOf(itemList.get(4));
if (itemList.get(5).equals("S"))
{
model.Latitude = -model.Latitude;
}
model.Longitude = Double.valueOf(itemList.get(6));
if (itemList.get(5).equals("W"))
{
model.Longitude = -model.Longitude;
}
model.LocationType= itemList.get(8).equals("V") ? 0 : 1;
model.Speed= Double.valueOf(itemList.get(9)).intValue();
model.Direction = Integer.valueOf(itemList.get(10));
model.Event = Integer.valueOf(itemList.get(11));
//开锁验证
int status= Integer.valueOf(itemList.get(12));
model.RFIDNo = itemList.get(13);
//动态密码开锁
if (model.Event == 6)
{
if (status == 0)
{
//开锁密码不正确
model.Status = 0;
}
else if (status > 0 && status <= 10)
{
//正常开锁
model.Status = 1;
//围栏内开锁时候的围栏ID
model.UnlockFenceID = status;
}
else if (status == 98)
{
//正常开锁
model.Status = 1;
}
else if (status == 99)
{
//设备开启了围栏内开锁,且当前开锁并未在围栏内,拒绝开锁
model.Status = 3;
}
}
else if (model.Event == 4)
{
if (Integer.valueOf(itemList.get(14)) == 0)
{
//开锁密码不正确
model.Status = 0;
}
else
{
//正常开锁
model.Status = 1;
}
}
model.PsdErrorTimes = Integer.valueOf(itemList.get(15));
model.Index = Integer.valueOf(itemList.get(16));
if (itemList.size() > 17)
{
model.Mileage = Integer.valueOf(itemList.get(16));
}
return model;
}
/**
* 解析从机数据温度
*
* @param temperatureInt
* @return
*/
private static double parseTemperature(int temperatureInt) {
if (temperatureInt == 0xFFFF) {
return 9999.9;
}
double temperature = ((short) (temperatureInt << 4) >> 4) * 0.1;
if ((temperatureInt >> 12) > 0) {
temperature = -temperature;
}
return temperature;
}
/**
* 转换GPS时间
*
* @param bcdTimeStr
* @return
*/
public static ZonedDateTime parseBcdTime(String bcdTimeStr) {
if(bcdTimeStr.equals("000000000000"))
{
//默认给出时间为2000年1月1日 00时00分00
bcdTimeStr="010100000000";
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyHHmmss");
LocalDateTime localDateTime = LocalDateTime.parse(bcdTimeStr, formatter);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneOffset.UTC);
return zonedDateTime;
}
/**
* 解析定位数据
* @param in
* @return
*/
public static Result decodeBinaryMessage(ByteBuf in)
{
//协议头
in.readByte();
//终端号码
byte[] terminalNumArr = new byte[5];
in.readBytes(terminalNumArr);
String terminalNum = ByteBufUtil.hexDump(terminalNumArr);
//协议版本号
int version = in.readUnsignedByte();
short tempByte = in.readUnsignedByte();
//终端类型号
int terminalType = tempByte >> 4;
//数据类型号
int dataType = tempByte & 0b00001111;
//数据长度
int dataLen = in.readUnsignedShort();
//定位时间
byte[] timeArr = new byte[6];
in.readBytes(timeArr);
String bcdTimeStr = ByteBufUtil.hexDump(timeArr);
ZonedDateTime gpsZonedDateTime = parseBcdTime(bcdTimeStr);
//纬度
byte[] latArr = new byte[4];
in.readBytes(latArr);
String latHexStr = ByteBufUtil.hexDump(latArr);
double lat = 0.0;
BigDecimal latFloat = new BigDecimal(latHexStr.substring(2, 4) + "." + latHexStr.substring(4)).divide(new BigDecimal("60"), 6, RoundingMode.HALF_UP);
lat = new BigDecimal(latHexStr.substring(0, 2)).add(latFloat).doubleValue();
//经度
byte[] lngArr = new byte[5];
in.readBytes(lngArr);
String lngHexStr = ByteBufUtil.hexDump(lngArr);
double lng=0.0;
BigDecimal lngFloat = new BigDecimal(lngHexStr.substring(3, 5) + "." + lngHexStr.substring(5, 9)).divide(new BigDecimal("60"), 6, RoundingMode.HALF_UP);
lng = new BigDecimal(lngHexStr.substring(0, 3)).add(lngFloat).doubleValue();
//位指示
int bitFlag = Byte.parseByte(lngHexStr.substring(9, 10), 16);
//定位状态
int locationType = (bitFlag & 0x01) > 0 ? 1 : 0;
//北纬、南纬
if ((bitFlag & 0b0010) == 0) {
lat = -lat;
}
//东经、西经
if ((bitFlag & 0b0100) == 0) {
lng = -lng;
}
//速度
int speed = (int) (in.readUnsignedByte() * 1.85);
//方向
int direction = in.readUnsignedByte() * 2;
//里程
long mileage = in.readUnsignedInt();
//GPS卫星个数
int gpsSignal = in.readByte();
//绑定车辆ID
long vehicleId = in.readUnsignedInt();
//终端状态
int terminalStatus = in.readUnsignedShort();
//是否基站定位
if (NumberUtil.getBitValue(terminalStatus, 0) == 1) {
locationType = 2;
}
//电量指示
int batteryPercent = in.readUnsignedByte();
//2G CELL ID
int cellId2G = in.readUnsignedShort();
//LAC
int lac = in.readUnsignedShort();
//GSM信号质量
int cellSignal = in.readUnsignedByte();
//区域报警ID
int regionAlarmId = in.readUnsignedByte();
//设备状态3
int terminalStatus3 = in.readUnsignedByte();
//唤醒源
int fWakeSource=(terminalStatus3 & 0b0000_1111);
//预留
in.readShort();
//IMEI号
byte[] imeiArr = new byte[8];
in.readBytes(imeiArr);
String imei = ByteBufUtil.hexDump(imeiArr);
//3G CELL ID 高16位
int cellId3G = in.readUnsignedShort();
int cellId=0;
if(cellId3G>0){
cellId=(cellId3G<<16)+cellId2G;
}else{
cellId=cellId2G;
}
//MCC
int mcc = in.readUnsignedShort();
//MNC
int mnc = in.readUnsignedByte();
//流水号
int flowId = in.readUnsignedByte();
//解析报警
int fAlarm=parseLocationAlarm(terminalStatus);
LocationData location=new LocationData();
location.setProtocolType(version);
location.setDeviceType(terminalType);
location.setDataType(dataType);
location.setDataLength(dataLen);
location.setGpsTime(gpsZonedDateTime.toString());
location.setLatitude(lat);
location.setLongitude(lng);
location.setLocationType(locationType);
location.setSpeed(speed);
location.setDirection(direction);
location.setMileage(mileage);
location.setGpsSignal(gpsSignal);
location.setGSMSignal(cellSignal);
location.setAlarm(fAlarm);
location.setAlarmArea(regionAlarmId);
location.setBattery(batteryPercent);
location.setLockStatus(NumberUtil.getBitValue(terminalStatus, 7) == 1 ? 0 : 1);
location.setLockRope(NumberUtil.getBitValue(terminalStatus, 6) == 1 ? 0 : 1);
location.setBackCover(NumberUtil.getBitValue(terminalStatus, 13));
location.setMCC(mcc);
location.setMNC(mnc);
location.setLAC(lac);
location.setCELLID(cellId);
location.setIMEI(imei);
location.setAlarm(fWakeSource);
location.setIndex(flowId);
//定义定位数据实体类
Result model = new Result();
model.setDeviceID(terminalNum);
model.setMsgType("Location");
model.setDataBody(location);
if (version < 0x19) {
model.setReplyMsg("(P35)");
} else {
model.setReplyMsg(String.format("(P69,0,%s)",flowId));
}
return model;
}
/**
* 解析定位报警
* @param terminalStatus
* @return
*/
private static int parseLocationAlarm(int terminalStatus)
{
//是否报警
int fAlarm = -1;
//是否应答确认
if (NumberUtil.getBitValue(terminalStatus, 5) == 1) {
//判断报警
if (NumberUtil.getBitValue(terminalStatus, 1) == 1) {
fAlarm = Integer.parseInt(AlarmTypeEnum.LOCK_ALARM_9.getValue());
} else if (NumberUtil.getBitValue(terminalStatus, 2) == 1) {
fAlarm = Integer.parseInt(AlarmTypeEnum.LOCK_ALARM_10.getValue());
} else if (NumberUtil.getBitValue(terminalStatus, 3) == 1) {
fAlarm = Integer.parseInt(AlarmTypeEnum.LOCK_ALARM_1.getValue());
} else if (NumberUtil.getBitValue(terminalStatus, 4) == 1) {
fAlarm = Integer.parseInt(AlarmTypeEnum.LOCK_ALARM_2.getValue());
} else if (NumberUtil.getBitValue(terminalStatus, 8) == 1) {
fAlarm = Integer.parseInt(AlarmTypeEnum.LOCK_ALARM_3.getValue());
} else if (NumberUtil.getBitValue(terminalStatus, 9) == 1) {
fAlarm = Integer.parseInt(AlarmTypeEnum.LOCK_ALARM_4.getValue());
} else if (NumberUtil.getBitValue(terminalStatus, 10) == 1) {
fAlarm = Integer.parseInt(AlarmTypeEnum.LOCK_ALARM_5.getValue());
} else if (NumberUtil.getBitValue(terminalStatus, 11) == 1) {
fAlarm = Integer.parseInt(AlarmTypeEnum.LOCK_ALARM_6.getValue());
} else if (NumberUtil.getBitValue(terminalStatus, 12) == 1) {
fAlarm = Integer.parseInt(AlarmTypeEnum.LOCK_ALARM_7.getValue());
} else if (NumberUtil.getBitValue(terminalStatus, 14) == 1) {
fAlarm = Integer.parseInt(AlarmTypeEnum.LOCK_ALARM_8.getValue());
} else {
fAlarm = -1;
}
}
return fAlarm;
}
/**
* 指令应答回复
* @param msgType
* @param itemList
* @return
*/
private static String replyMessage(String msgType,List<String> itemList)
{
String replyContent = null;
switch (msgType)
{
case "P22":
ZonedDateTime currentDateTime = ZonedDateTime.now(ZoneOffset.UTC);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ddMMyyHHmmss");
replyContent = String.format("(P22,%s)", currentDateTime.format(formatter));
break;
case "P43":
if (itemList.get(2).equals("0")) {
//密码重置
replyContent = String.format("(P44,1,888888)");
}
break;
case "P45":
replyContent = String.format("(P69,0,%s)", itemList.get(16));
break;
case "P52":
if (itemList.get(2).equals("2")) {
replyContent = String.format("(P52,2,%s)", itemList.get(3));
}
break;
default:
break;
}
return replyContent;
}
/**
* 指令应答回复
* @param msgType
* @param index
* @return
*/
public static String replyMessage(String msgType, int index)
{
String replyContent = null;
switch (msgType)
{
case "WLNET5":
case "WLNET7":
replyContent = String.format("(P69,0,{0})", index);
break;
default:
break;
}
return replyContent;
}
}
公共方法类CommonUtil
package com.jointech.sdk.jt701.utils;
import io.netty.buffer.ByteBuf;
import java.nio.ByteBuffer;
/**
* <p>Description: 用来存储一些解析中遇到的公共方法</p>
*
* @author lenny
* @version 1.0.1
* @date 20210328
*/
public class CommonUtil {
private CommonUtil()
{
}
/**
* 反转义文本透传数据
*
* @param in
* @param frame
* @param bodyLen
*/
public static void unescape(ByteBuf in, ByteBuf frame, int bodyLen) {
int i = 0;
while (i < bodyLen) {
int b = in.readUnsignedByte();
if (b == 0x3D) {
int nextByte = in.readUnsignedByte();
if (nextByte == 0x14) {
frame.writeByte(0x3D ^ 0x14);
} else if (nextByte == 0x15) {
frame.writeByte(0x3D ^ 0x15);
} else if (nextByte == 0x00) {
frame.writeByte(0x3D ^ 0x00);
} else if (nextByte == 0x11) {
frame.writeByte(0x3D ^ 0x11);
} else {
frame.writeByte(b);
frame.writeByte(nextByte);
}
i += 2;
} else {
frame.writeByte(b);
i++;
}
}
}
/**
* 去掉字符串最后一个字符
* @param inStr 输入的字符串
* @param suffix 需要去掉的字符
* @return
*/
public static String trimEnd(String inStr, String suffix) {
while(inStr.endsWith(suffix)){
inStr = inStr.substring(0,inStr.length()-suffix.length());
}
return inStr;
}
/**
* 16进制转byte[]
* @param hex
* @return
*/
public static byte[] hexStr2Byte(String hex) {
ByteBuffer bf = ByteBuffer.allocate(hex.length() / 2);
for (int i = 0; i < hex.length(); i++) {
String hexStr = hex.charAt(i) + "";
i++;
hexStr += hex.charAt(i);
byte b = (byte) Integer.parseInt(hexStr, 16);
bf.put(b);
}
return bf.array();
}
}
解析常量Constant
package com.jointech.sdk.jt701.constants;
import java.util.Arrays;
import java.util.List;
/**
* 常量定义
* @author HyoJung
* @date 20210526
*/
public class Constant {
private Constant(){}
/**
* 二进制消息包头
*/
public static final byte BINARY_MSG_HEADER = '$';
/**
* 文本消息包头
*/
public static final byte TEXT_MSG_HEADER = '(';
/**
* 文本消息包尾
*/
public static final byte TEXT_MSG_TAIL = ')';
/**
* 文本消息分隔符
*/
public static final byte TEXT_MSG_SPLITER = ',';
/**
* 透传二进制数据的指令
*/
public static final List<String> WLNET_TYPE_LIST = Arrays.asList("5", "7");
}
2.4.返回消息及说明
(1)定位数据
原始数据:
2480405002251911003426032118530329532416031008941d0000000018070c0000000020e04f8b0c56001f00020f0f0f0f0f0f0f0f0f0f00f2028f0157
返回消息:
{
"DeviceID": "8040500225",
"DataBody": {
"GpsTime": "2021-03-26T18:53:03Z",
"MNC": 1,
"BackCover": 1,
"Index": 87,
"Latitude": -29.88736,
"Awaken": 0,
"Direction": 0,
"Battery": 79,
"GpsSignal": 12,
"DataType": 1,
"AlarmArea": 0,
"Speed": 0,
"LockStatus": 0,
"Mileage": 6151,
"IMEI": "0f0f0f0f0f0f0f0f",
"MCC": 655,
"Longitude": 31.014902,
"LAC": 22016,
"DeviceType": 1,
"ProtocolType": 25,
"Alarm": 2,
"DataLength": 52,
"CELLID": 15895308,
"LockRope": 0,
"LocationType": 1,
"GSMSignal": 31
},
"ReplyMsg": "(P69,0,87)",
"MsgType": "Location"
}
返回消息描述
{
"DeviceID":设备ID
"MsgType":消息类型, 此处为: Location,表示定位数据,
"DataBody":消息体内容
{
"ProtocolType": 协议版本号,
"DeviceType": 终端类型号,
"DataType": 数据类型号( 1 表明最新二进制定位数据, 2 表示报警数据, 3 表示盲区常规二进制定位数据, 4 表示次新二进制定位数据),
"DataLength": 数据长度,
"GpsTime": 定位时间( GMT时间),
"Latitude": 纬度(dd.dddd格式),
"Longitude": 经度(dd.dddd格式),
"LocationType": 定位类型( 0: 不定位; 1: GPS定位; 2: 基站定位),
"Speed": 速度( 单位: km / h),
"Direction": 方向( 0~360; 0 与360表示正北方向),
"Mileage": 当前里程值(单位:km),
"GpsSignal": GPS卫星个数,
"GSMSignal": GSM信号值,
"Alarm": 报警类型( - 1: 无告警信息; 1: 锁绳剪断; 2: 震动; 3: 长时间开锁; 4: 开锁密码连续5次错误; 5: 刷非法卡; 6: 低电量; 7: 开后盖; 8: 卡锁; 9: 进区域报警; 10: 出区域报警),
"AlarmArea": 如果告警与区域有关, 则此处值为区域的ID,
"Battery": 电量值( 0~100; 255: 充电中),
"LockStatus": 锁电机状态( 1: 开; 0: 关),
"LockRope": 锁绳状态( 1: 拔出; 0: 插入),
"BackCover": 后盖状态( 1: 关闭; 0: 开启),
"MCC": 国家代码,
"MNC": 运营商代码,
"LAC": 位置区域码,
"CELLID": 基站编号,
"IMEI": IMEI号码, 全是0F无效,
"Awaken": 唤醒源( 0 重启,
1: RTC唤醒, 2: 震动, 3: 开后盖, 4: 锁绳, 5: 接外电, 6: 刷卡, 7: 门磁, 8: VIP短信, 9: 非VIP短信或垃圾短信),
"Index": 数据流水号
},
"ReplyMsg":回复内容( 如果为空字符串, 则不需要给终端回复内容)
}
(2)传感器采集数据(WLNET5)
原始数据(SensorType=1):
28383035303530303037332c312c3134312c574c4e45542c352c322c260321184709649672953949673d1408ff002603211847181020110986660133623c0100d71b00000029
返回消息(SensorType=1):
{
"DeviceID": "8050500073",
"DataBody": {
"SensorID": "1020110986",
"SensorType": 1,
"Speed": 471,
"GpsTime": "2021-03-26T18:47:09Z",
"Temperature": 21.5,
"LockStatus": 1,
"Index": 102,
"Latitude": -65.612158,
"Direction": 0,
"Longitude": -395.61215,
"DateTime": "2021-03-26T18:47:18Z",
"RSSI": 60,
"Humidity": 27,
"Voltage": "3.07",
"LockTimes": -1,
"Event": -1,
"LockRope": 1,
"LocationType": 0,
"Power": 98
},
"ReplyMsg": "(P69,0,102)",
"MsgType": "WLNET5"
}
原始数据(SensorType=4):
28373030303331333330392C312C3038312C574C4E45542C352C322C05082115430722348250113550300F0000050821154304E0171E086925018D4E690400400000002A0029
返回消息(SensorType=4):
{
"DeviceID": "7000313309",
"MsgType": "WLNET5",
"DataBody": {
"GpsTime": "2021-08-05T15:43:07",
"Latitude": 22.580416666666668,
"Longitude": 113.91716666666667,
"LocationType": 1,
"Speed": 0,
"Direction": 0,
"SensorID": "E0171E0869",
"LockStatus": 0,
"LockRope": 0,
"LockTimes": 42,
"Index": 37,
"Voltage": "3.97",
"Power": 78,
"RSSI": -105,
"DateTime": "2021-08-05T15:43:04",
"SensorType": 4,
"Temperature": 0.0,
"Humidity": 0,
"Event": 6
},
"ReplyMsg": "(P69,0,37)"
}
返回消息描述
{
"DeviceID": 设备ID,
"MsgType": 消息类型, 此处为: WLNET5,表示传感器透传数据,
"DataBody": 消息体内容
{
"GpsTime": 定位时间(GMT时间),
"Latitude": 纬度(dd.dddd格式),
"Longitude": 经度(dd.dddd格式),
"LocationType": 定位类型( 0: 不定位; 1: GPS定位; 2: 基站定位),
"Speed": 速度( 单位: km / h);0xFF表示速度无效,
"Direction": 方向( 0~360; 0 与360表示正北方向),
"SensorID": 传感器ID,
"LockStatus": 如果从机类型SensorType=4,此是才有效;1:开锁;0:关锁,
"LockRope": 如果从机类型SensorType=4,此是才有效;1:锁绳拔出;0:锁绳插入,
"LockTimes": 开锁次数(如果SensorType=4此值才有效),
"Index": 数据流水号,
"Voltage": 电压值(单位:V),
"Power": 传感器电量(0~100;255: 充电中),
"RSSI": RSSI信号强度,是负数越接近0信号越好,
"DateTime": 数据采集时间(GMT时间),
"SensorType": 传感器类型(1:温湿度传感器(JT126);4:从机JT709;),
"Temperature":温度值(如果SensorType=1此值才有效),
"Humidity": 湿度值(如果SensorType=1此值才有效),
"Event": 事件类型(-1:无从机事件;0:关锁事件;1:蓝牙开锁事件;2:NFC开锁事件;3:Lora开锁事件;4:从机锁剪断报警事件;5:按键唤醒事件;6:定时上报事件;7:充电上报事件)
},
"ReplyMsg": 回复内容(如果为空字符串,则不需要给终端回复内容)
}
(3)锁事件上报数据(P45)
原始数据:
28373839303632393238342c5034352c3236303332312c3139343933392c32362e3237323033352c4e2c35302e3632313433352c452c412c302e30352c302c342c312c303030303030303030302c312c302c3129
返回消息:
{
"DeviceID": "7890629284",
"MsgType": "P45",
"DataBody": {
"DateTime": "2021-03-26T19:49:39",
"Latitude": 26.272035,
"Longitude": 50.621435,
"LocationType": 1,
"Speed": 0,
"Direction": 0,
"Event": 4,
"Status": 1,
"UnlockFenceID": -1,
"RFIDNo": "0000000000",
"PsdErrorTimes": 0,
"Index": 1,
"Mileage": 0
},
"ReplyMsg": "(P69,0,1)"
}
返回消息描述:
{
"DeviceID": 设备ID,
"MsgType": 消息类型, 此处为: P45,表示开关锁事件数据上传,
"DataBody": 消息体内容
{
"DateTime": 事件时间(GMT时间),
"Latitude": 纬度(dd.dddd格式),
"Longitude": 经度(dd.dddd格式),
"LocationType": 定位类型( 0: 不定位; 1: GPS定位; 2: 基站定位),
"Speed": 速度( 单位: km / h),
"Direction": 方向( 0~360; 0 与360表示正北方向),
"Event": 事件类型(1:表示刷授权卡;2:表示刷非法卡;3:表示刷车辆ID卡绑定;4:表示为凭密码开锁;5:表示终端自动关锁记录;6: 动态密码围栏内开锁;7: 蓝牙开锁),
"Status": 开锁验证(0:开锁密码不正确;1:正常开锁;2:因为开启了围栏开锁,未在围栏内开锁,开锁被拒绝),
"UnlockFenceID": (-1:开锁与围栏无关;1~10:标识对应的开锁围栏ID),
"RFIDNo": 刷卡卡号;如果未“0000000000”,则无效,
"PsdErrorTimes": 开锁密码错误次数,
"Index": 数据流水号,
"Mileage": 当前里程值(单位:km)
},
"ReplyMsg": 回复内容(如果为空字符串,则不需要给终端回复内容)
}
(4)其他指令回复数据
原始数据:
28373839303632393238342c50333529
返回消息:
{
"DeviceID": "7890629284",
"MsgType": "P35",
"DataBody": "(7890629284,P35)",
"ReplyMsg": ""
}
返回消息描述:
{
"DeviceID": 设备ID,
"MsgType": 消息类型(参见更多的消息类型及其描述,请参阅3.消息类型及消息体内容描述),
"DataBody": 消息体内容(除定位数据:Location;传感器透传数据:WLNET5;锁事件上报:P45外;其他此处均直接返回指令内容的ASCII字符串),
"ReplyMsg": 回复内容(如果为空字符串,则不需要给终端回复内容)
}
3.消息类型及消息体内容描述
3.1.P01:查询终端当前的版本号
消息体内容:(示例)(7591225008,P01,JT701D_20200720_China_Jointech_SIM7600,77%)
消息体内容描述:7591225008:设备ID
P01:消息类型
JT701D_20200720_China_Jointech_SIM7600:协议版本
77%:当前设备电量
P03:低电休眠控制
消息体内容:(示例)(7560704001,P03,1,30)
消息体描述:7560704001:设备ID
P03:消息类型
1:生效;0:不生效
30:设置电量低于30的时候进入休眠,默认31%,可设定范围5%~90%
P04:设置/查询数据上传间隔和休眠自动唤醒间隔
消息体内容:(示例)(7570101998,P04,30,30)
消息体描述:7570101998:设备ID
P04:消息类型
30:数据上传间隔,单位秒钟,默认30秒,取值范围5-600
30:休眠自动唤醒间隔,单位分钟,默认30分钟,取值范围30-1440
P06:设置/查询监控中心IP与端口、APN
消息体内容:(示例)(7570101998,P06,211.162.111.225,10906,CMNET,user,password,1)
消息体描述:7570101998:设备ID
P06:消息类型
211.162.111.225:监控中心的IP地址
10906:监控中心端口地址,最大65530
CMNET:接入点名称(最长50个字节)
User:APN用户名(最长50个字节)
Password:APN密码(最长50个字节)
1:0表示卡1,1表示卡2
P10:设置/查询终端使用地点与国际标准时间的时差
消息体内容:(示例)(7570101998,P10,480)
消息体描述:7570101998:设备ID
P10:消息类型
480:时差值,以分钟为单位.如北京时间与标准时时差为8小时,即为480分钟,取值范围-12*60-13*60,默认0
P11:设置/查询VIP手机号码
消息体内容:(示例)(7570101998,P11,1,8613910102345)
消息体描述:7570101998:设备ID
P11:消息类型
1:VIP手机号码索引,取值为1-5,允许有五组VIP手机号码
8613910102345:手机号码,不能超过15位数字,前面需加国际区号,中国为86或者+86.
P12:设置/查询VIP号码是否允许报警
消息体内容:(示例)(7570101998,P12,1,1,1,1,1)
消息体描述:7570101998:设备ID
P12:消息类型
1,1,1,1,1:分别对应5个VIP号码是否允许报警;1表示允许对应的VIP号码报警,0表示不允许此VIP号码报警
P13:恢复出厂设置
消息体内容:(示例)(7570101998,P13)
消息体描述:7570101998:设备ID
P13:消息类型
P14:读取终端的IMEI号
消息体内容:(示例)(7570101998,P14,012207004451636)
消息体描述:7570101998:设备ID
P14:消息类型
012207004451636:终端的IMEI号
P15:终端重启指令
消息体内容:(示例)(7570101998,P15)
消息体描述:7570101998:设备ID
P15:消息类型
P22:GPS无效的时候,监控中心对终端授时
消息体内容:(示例)(7570101998,P22,1)
消息体描述:7570101998:设备ID
P22:消息类型
1:1表示授时成功,0表示失败,2表示主动请求授时
P22:设置/取消短信、电话可唤醒工作模式
消息体内容:(示例)(7570101998,P23,1)
消息体描述:7570101998:设备ID
P23:消息类型
1:1表示设置成功,0表示设置失败.
P24:区域是否有效,及区域名称设置指令
消息体内容:(示例)(7570101998,P24,10,1,area10)
消息体描述:7570101998:设备ID
P24:消息类型
10:表示第10个区域.
1:表示有效 ,0表示无效
area10:表示区域名称,最大长度为16个字节.
P29:设置或者查询区域的详细节点信息
消息体内容:(示例)(7570101998,P29,8,15,1,10,11323.1234…)
消息体描述:7570101998:设备ID
P29:消息类型
8:表示第八个区域
15:表示总点数
1:表示当前页
10:表示当前页的点数.余下的为各个点的经度与纬度
P30:清除相关的区域
消息体内容:(示例)(7570101998,P30,1)
消息体描述:7570101998:设备ID
P30:消息类型
1:1表示清除成功,0表示清除失败.
P31:区域信息设置完毕
消息体内容:(示例)(7570101998,P31)
消息体描述:7570101998:设备ID
P31:消息类型
P32:主动进入休眠指令
消息体内容:(示例)(7570101998,P32)
消息体描述:7570101998:设备ID
P32:消息类型
P37:查询/设置G-sensor相关参数
消息体内容:(示例)(7570101998,P37,500)
消息体描述:7570101998:设备ID
P37:消息类型
500:运动检测门限值,范围是63到500,单位是mg;如果设置为0则为关闭G-sensor相关全部功能;关闭G-sensor功能后,如需重新开启G-sensor功能只需重新设置有效的G-sensor参数即可.默认值126
P38:开锁报警时间间隔设置指令
消息体内容:(示例)(7570101998,P38,120)
消息体描述:7570101998:设备ID
P38:消息类型
120:开锁报警时间间隔设置,即从锁电机处于开锁状态时刻算起,如果该状态持续保持超过120分钟,则可触发开锁报警,范围是3到180,单位是分钟;默认为120分钟.
P40:查询/设置GPRS通道和短消息通道的报警开关
消息体内容:(示例)(7570101998,P40,1,1,1,1,1,1,1,1,1,1,1)
消息体描述:7570101998:设备ID
P40:消息类型
1,1,1,1,1,1,1,1,1,1,1:从左至右依次为锁挂绳剪断报警、刷非法卡报警、开锁状态保持一段时间报警、指令开锁密码连续输错5次报警、震动报警、进区域报警、出区域报警的开关、低电报警、开后盖报警、卡锁报警;每个报警开关参数可以取值为0,1,2,3,并且可以任意组合,0表示GPRS和SMS报警都关闭,1表示只开启GPRS报警,2表示只开启SMS报警,3表示GPRS和SMS报警都开启.
P41:增删开锁授权号指令
消息体内容:(示例1)(7570101998,P41,1,30)
消息体描述:7570101998:设备ID
P41:消息类型
1:1表示增加授权卡号操作;2表示删除授权号,3表示删除所有的授权号
30:30表示当前已存授权卡号总个数;
消息体内容:(示例2)(7570101998,P41,2,3,0013953759, 0013953758, 0013953757)
消息体描述:7570101998:设备ID
P41:消息类型
2:查询第2组数据;一共分3组,分别为1~3,查询时每次最多返回20个ID号
3:3表示有3个ID号
0013953759, 0013953758, 0013953757表示该组存储的授权号列表
P42:现场刷卡授权模式配置指令
消息体内容:(示例1)(7570101998,P42,0)
消息体描述:7570101998:设备ID
P42:消息类型
1:1表示打开批量增加终端开锁授权号功能, 0表示关闭批量增加终端开锁授权号功能。
消息体内容:(示例2)(7570101998,P41,2,0013953759,0013953751)
消息体描述:7570101998:设备ID
P42:消息类型
2:表示终端已存了2个开锁授权号.
0013953759,0013953751:授权卡号.
P44:远程开锁密码修改指令
消息体内容:(示例1)(7570101998,P44,1)
消息体描述:7570101998:设备ID
P44:消息类型
1:1:表示修改密码是否成功,1表示成功,0表示失败。
消息体内容:(示例2)(7570101998,P44,888888)
消息体描述:7570101998:设备ID
P44:消息类型
888888:当前的设备可开锁的动态密码
P50:电源开关生效控制设置
消息体内容:(示例)(7570101998,P50,1)
消息体描述:7570101998:设备ID
P44:消息类型
1:1表示开关有效,默认是1;0表示停用开关.
P52:动态密码指令
消息体内容:(示例1)(7570101998,P52,0,405935,326387)
消息体描述:7570101998:设备ID
P52:消息类型
0:指令操作;查询当前产生的动态密码和当前用来开锁的动态密码
405935:表示,还没有被系统确认的动态密码
326387:表示目前用来开锁的动态密码
消息体内容:(示例2)(7570101998,P52,1,1,0)
消息体描述:7570101998:设备ID
P52:消息类型
1:1表示设置动态密码功能
1:1查询是否开启动态密码功能;0:表示关闭动态密码功能
0:1表示动态密码开锁必须在区域内才能开锁,即表明如果想要开锁,必须设置区域,0表示动态密码开锁跟区域无关,只要符合动态密码开锁的其它条件就可以开锁
消息体内容:(示例3)(7570101998,P52,2,405935)
消息体描述:7570101998:设备ID
P52:消息类型
2:回复上传的动态密码确认指令
405935:需要被确认的动态密码
消息体内容:(示例4)(7570101998,P52,3,1,0)
消息体描述:7570101998:设备ID
P52:消息类型
3:发送动态密码开锁
1:1,代表成功,0是失败
0:代表失败次数
P54:查询/设置是否关闭休眠模式指令(设备不休眠)
消息体内容:(示例)(7570101998,P54,0,0)
消息体描述:7570101998:设备ID
P54:消息类型
0:0 查询;1 设置
0:0 需要休眠 , 1 开启不休眠
P58:查询和设置RFID卡是否关联电子围栏 (默认关联电子围栏)
消息体内容:(示例)(7570101998,P58,1,1)
消息体描述:7570101998:设备ID
P58:消息类型
1:1表示设置,0表示查询
1:1:关联电子围栏,必须在区域内才能刷卡开锁;0表示刷卡开锁跟区域无关,只要符刷卡开锁的条件就可以开锁
P61:设置或查询电量低报警提示的阀值
消息体内容:(示例)(7570101998,P61,30)
消息体描述:7570101998:设备ID
P61:消息类型
30:当前阀值
P62:设置或查询里程统计相关参数
消息体内容:(示例)(7570101998,P62,1,10)
消息体描述:7570101998:设备ID
P62:消息类型
1:操作参数类型;1:设置一个速度值,低于这个速度里程不会统计;2:同步当前设备里程值
10:当操作参数类型为1,此时为速度值,单位km/h;当操作参数类型为2,此时为里程值,单位km
P63:静态飘移处理功能设置
消息体内容:(示例)(7570101998,P63,1)
消息体描述:7570101998:设备ID
P63:消息类型
1:1开启,0关闭(默认)
P68:查询SIM卡的IMSI/ICCID号
消息体内容:(示例)(7570101998,P65,2,898600220909A0206023)
消息体描述:7570101998:设备ID
P65:消息类型
2:1:查询IMSI, 2:查询ICCID
898600220909A0206023:SIM卡的IMSI/ICCID号
P70:启用/关闭VIP号码功能
消息体内容:(示例)(7570101998,P70,1)
消息体描述:7570101998:设备ID
P70:消息类型
1:0:关闭状态;1:开启状态
WLNET1:查询/设置要监听的从机设备ID号
消息体内容:(示例)(700160818000,1,001,WLNET,1,20,0217270000,,,,,,,,,)
消息体描述:700160818000:设备ID
WLNET,1:组合消息类型WLNET1
20:表示当前配置20个从机设备ID号,如果为配置0个ID号表示清除所有配置的ID号
0217270000,,,,,,,,,:从机ID号
WLNET2:查询/设置从机工作时间间隔
消息体内容:(示例)(700160818000,1,001,WLNET,2,20)
消息体描述:700160818000:设备ID
WLNET,2:组合消息类型WLNET2
20:20:从机工作时间间隔为20分钟,单位分钟,最小1分钟,最大1440一天,默认5分钟
WLNET3:查询/设置从机发送功率
消息体内容:(示例)(700160818000,1,001,WLNET,3,2)
消息体描述:700160818000:设备ID
WLNET,3:组合消息类型WLNET3
2:从机从机发送功率,1~3分别是低中高三个发送功率模式,默认是1低功率
WLNET4:查询/设置从机发送功率
消息体内容:(示例)(700160818000,1,001,WLNET,4,170828,170829)
消息体描述:700160818000:设备ID
WLNET,4:组合消息类型WLNET4
170828:网关版本
170829:传感器的软件版本
WLNET6:查询/设置从机温度门限参数
消息体内容:(示例)(700160818000,1,001,WLNET,6,1,2,10,120,30,15,12)
消息体描述:700160818000:设备ID
WLNET,6:组合消息类型WLNET6
1:指令功能:0表示查询;1:表示设置
2:参数类型:1表示温度相关参数,2表示设置数据上传方式
10:低温门限值:默认0值无效,温度以1度为单位10~175有效,-40~125度,门限值 – 50 = 实际值,如10- 50 = -40℃。
120:高温门限值:默认0值无效,温度以1度为单位10~175有效,-40~125度,门限值 – 50 = 实际值,如120- 50 = 70℃
30:温度变化时间值:多长时间内温度变化多少的时间值,单位分钟,默认0值无效,一般20~60参考值,最大240,4小时
15:温度变化值:默认0值无效,15表示1.5度,最大250、25度,也就是如30分钟内变化1.5度就报警
12:每天定点上传多少个点:默认0值当前一个点,12表示每天12个点2小时一个点,最多24个点,一般12或24个点参考值