1.SDK下载

JT709SDK(JT709SDK_V2.rar) 下载地址
JT709SDK测试工具(JT709SDK_Test.rar) 下载地址
如果需要测试工具及SDK开发源码,请与商务申请


2.集成开发说明

2.1.集成开发语言及框架说明

JT709SDK(Jt709DataParser.dll)及测试工具(Test.exe)是基于C#语言,.NET Framework 4.6.1目标框架开发的。该SDK的集成开发环境也是需要依赖于C#语言以及.NET Framework 4.6.1目标框架。

2.2.集成说明

(1)将Jt709DataParser.dll引入到自己的网关程序中,引入方法如下:
鼠标右键项目下的”引用”,选择”添加引用(R)…”

选择下图中”浏览(B)…”,找到你解压JT709SDK_V2.rar后的文件夹,选中Jt709DataParser.dll与对应的Json字符串序列化/反序列化包Newtonsoft.Json.dll即可完成对SDK的引用
(2)调用Jt709DataParser.dll中的解析方法receiveData
receiveData()是一个重载方法,你可以传入16进制字符串或者byte[],一般我们网关程序接收到的设备数据是以二进制流进行传输的,所以我们这里建议使用此重载方法receiveData(byte[] bytes);
当然如果你想通过16进制字符串进行测试,也可以使用receiveData(string strData);
strData:就是我们接收到的设备数据转成16进制后的字符串

2.3.核心代码

Jt709DataParser.dll
(1)解析类DataParser.cs

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Jt709DataParser
{
    public class DataParser
    {
        private static byte[] endbytes = null;// 上一次未处理的剩余字节

        /// <summary>
        /// 解析16进制原始数据
        /// </summary>
        /// <param name="strData"></param>
        /// <returns></returns>
        public static string receiveData(string strData)
        {
            byte[] bytes = Common.HexStringToBytes(strData);
            return receiveData(bytes);
        }

        /// <summary>
        /// 解析2进制原始数据
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string receiveData(byte[] bytes)
        {
            byte[] newBytes = null;
            if (endbytes != null && endbytes.Length > 0)
            {
                newBytes = new byte[endbytes.Length + bytes.Length];
                bytes = Common.CombineBytes(endbytes, bytes);
            }
            else
            {
                newBytes = new byte[bytes.Length];
                newBytes = bytes;
            }
            int i = 0;//初始化byte[]下标
            byte[] parserBytes = null;//去除正确包头之前的数据后的数据
            foreach (var item in newBytes)
            {
                if (item == 0x7E)
                {
                    parserBytes = new byte[newBytes.Length - i];
                    parserBytes = newBytes.Skip(i).Take(newBytes.Length - i).ToArray();
                    return parserLocation(parserBytes);
                }
                else if (item == '(')
                {
                    parserBytes = new byte[newBytes.Length - i];
                    parserBytes = newBytes.Skip(i).Take(newBytes.Length - i).ToArray();
                    return parserCommand(parserBytes);
                }
                i++;
            }
            return null;
        }

        private static string parserLocation(byte[] bytes)
        {
            byte[] frame = PacketUtil.decodePacket(bytes);
            if (frame == null)
            {
                endbytes = bytes;
                return null;
            }
            //定义定位数据实体类
            Result model = new Result();
            //消息ID
            int msgId = Common.SwapUInt16(BitConverter.ToUInt16(frame, 1));
            //消息体属性
            int msgBodyAttr = Common.SwapUInt16(BitConverter.ToUInt16(frame, 3));
            //消息体长度
            int msgBodyLen = msgBodyAttr & 0x03FF;
            byte[] terminalNumArr = frame.Skip(5).Take(6).ToArray();
            model.DeviceID = Common.ByteToHexStr(terminalNumArr).TrimStart('0');
            //消息流水号
            int msgFlowId = Common.SwapUInt16(BitConverter.ToUInt16(frame, 11));
            //消息体
            byte[] msgBodyArr = frame.Skip(13).Take(msgBodyLen).ToArray();
            if (msgId == 0x0200)
            {
                //解析消息体
                LocationData locationData = PacketUtil.parseLocationBody(msgBodyArr);
                locationData.Index = msgFlowId;
                locationData.DataLength = msgBodyLen;
                model.MsgType = "Location";
                model.DataBody = locationData;
                string replyMsg = PacketUtil.replyBinaryMessage(terminalNumArr, msgFlowId);
                model.ReplyMsg = replyMsg;
            }
            else
            {
                model.MsgType = "heartbeat";
            }
            return JsonConvert.SerializeObject(model);
        }

        /// <summary>
        /// 解析指令数据
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        private static string parserCommand(byte[] bytes)
        {
            Result result = new Result();
            byte[] newBytes = null;
            int tailIndex = Common.BytesIndexOf(bytes, 0x29) + 1;
            if (tailIndex > 0)
            {
                if (bytes.Length > tailIndex)
                {
                    endbytes = bytes.Skip(tailIndex).Take(bytes.Length - tailIndex).ToArray();
                }
                newBytes = bytes.Skip(0).Take(tailIndex).ToArray();
            }
            else
            {
                endbytes = new byte[bytes.Length];
                endbytes = bytes;
            }
            if (newBytes != null && newBytes.Length > 0)
            {
                //转换成()带括号的数据
                string msgAscii = Common.ByteToASCII(newBytes);
                //按逗号拆分字符串
                char[] p = new char[] { ',' };
                //返回的数组中,包含空字符串
                string[] msgArrays = msgAscii.Replace("(", "").Replace(")", "").Split(p, StringSplitOptions.None);
                result.DeviceID = msgArrays[0];
                string msgType = string.Empty;
                if (msgArrays.Length > 5)
                {
                    msgType = msgArrays[3] + msgArrays[4];
                }
                else
                {
                    return null;
                }
                result.MsgType = msgType;
                result.DataBody = msgAscii;
                string replyMsg = string.Empty;
                if (msgType.Equals("BASE2") && msgArrays[5].ToUpper().Equals("TIME"))
                {
                    replyMsg = PacketUtil.replyBASE2Message(msgArrays);
                }
                result.ReplyMsg = replyMsg;
                return JsonConvert.SerializeObject(result);
            }
            else
            {
                return null;
            }
        }
    }
}

(2)公共方法类:Common.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Jt709DataParser
{
    public class Common
    {

        /// <summary>
        /// 16进制格式字符串转字节数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        public static byte[] HexStringToBytes(string hexString)
        {
            hexString = Regex.Replace(hexString, @".{2}", "$0 ");
            //以 ' ' 分割字符串,并去掉空字符
            string[] chars = hexString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            byte[] returnBytes = new byte[chars.Length];
            //逐个字符变为16进制字节数据
            for (int i = 0; i < chars.Length; i++)
            {
                returnBytes[i] = Convert.ToByte(chars[i], 16);
            }
            return returnBytes;
        }

        /// <summary>
        /// 合并数组
        /// </summary>
        /// <param name="bytes1"></param>
        /// <param name="bytes2"></param>
        /// <returns></returns>
        public static byte[] CombineBytes(byte[] bytes1, byte[] bytes2)
        {
            List<byte> tmp = new List<byte>(bytes1.Length + bytes2.Length);
            tmp.AddRange(bytes1);
            tmp.AddRange(bytes2);
            byte[] merged = tmp.ToArray();
            return merged;
        }

        /// <summary>
        /// 报告指定的 System.Byte[] 在此实例中的第一个匹配项的索引。
        /// </summary>
        /// <param name="srcBytes">被执行查找的 System.Byte[]。</param>
        /// <param name="searchBytes">要查找的 System.Byte[]。</param>
        /// <returns>如果找到该字节数组,则为 searchBytes 的索引位置;如果未找到该字节数组,则为 -1。如果 searchBytes 为 null 或者长度为0,则返回值为 -1。</returns>
        public static int BytesIndexOf(byte[] srcBytes, byte searchBytes)
        {
            if (srcBytes == null) { return -1; }
            if (srcBytes.Length == 0) { return -1; }
            for (int i = 0; i < srcBytes.Length; i++)
            {
                if (srcBytes[i] == searchBytes)
                {
                    return i;
                }
            }
            return -1;
        }

        /// <summary>
        /// 16进制字符串转ASCII
        /// </summary>
        /// <param name="Data"></param>
        /// <param name="istrans"></param>
        /// <returns></returns>
        public static string HexStrToAsciiString(string Data, bool istrans)
        {
            if (istrans)
            {
                Data = Regex.Replace(Data, @"(?is)(?<=^([0-9a-f]{2})+)(?!$)", " ");
                Data = Data.Replace("3D 00", "3D ").Replace("3D 11", "2C ").Replace("3D 14", "28 ").Replace("3D 15", "29 ").Replace(" ", "");
            }
            int count = Data.Length / 2;
            string strContent = "";
            char[] num = new char[count];
            for (int i = 0; i < count; i++)
            {
                string str = Data.Substring(i * 2, 2);
                byte by = Convert.ToByte(Convert.ToInt32(str, 16));
                num[i] = Convert.ToChar(by);
                strContent += num[i].ToString();
            }
            return strContent;
        }

        /// <summary>
        /// 二进制转ASCII
        /// </summary>
        /// <param name="bt"></param>
        /// <returns></returns>
        public static string ByteToASCII(byte[] bt)
        {
            string lin = "";
            for (int i = 0; i < bt.Length; i++)
            {
                lin = lin + bt[i] + " ";
            }
            string[] ss = lin.Trim().Split(new char[] { ' ' });
            char[] c = new char[ss.Length];
            int a;
            for (int i = 0; i < c.Length; i++)
            {
                a = Convert.ToInt32(ss[i]);
                c[i] = Convert.ToChar(a);
            }

            string b = new string(c);
            return b;
        }

        /// <summary>
        /// 时间格式转换
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static DateTime GetDataTime(byte[] bytes)
        {
            return DateTime.ParseExact(ByteToHexStr(bytes), "yyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
        }

        public static DateTime GetDataTime(string strdate)
        {
            return DateTime.ParseExact(strdate, "yyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
        }

        /// <summary>
        /// 获取二进制第index位的值
        /// </summary>
        /// <param name="number"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static int getBitValue(long number, int index)
        {
            return (number & (1 << index)) > 0 ? 1 : 0;
        }

        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="byteDatas"></param>
        /// <returns></returns>
        public static string ByteToHexStr(byte[] byteDatas)
        {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < byteDatas.Length; i++)
            {
                builder.Append(string.Format("{0:X2}", byteDatas[i]));
            }
            return builder.ToString().Trim();
        }

        public static ushort SwapUInt16(ushort v)
        {
            return (ushort)(((v & 0xff) << 8) | ((v >> 8) & 0xff));
        }

        public static uint SwapUInt32(uint v)
        {
            return (uint)(((SwapUInt16((ushort)v) & 0xffff) << 0x10) |
                           (SwapUInt16((ushort)(v >> 0x10)) & 0xffff));
        }

        /// <summary>
        /// Short转Bytes
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public static byte[] ShortToBytes(short number)
        {
            byte byte2 = (byte)(number >> 8);
            byte byte1 = (byte)(number & 255);
            byte[] bytes = new byte[2];
            bytes[0] = byte1;
            bytes[1] = byte2;
            return bytes.Reverse().ToArray();
        }

        /// <summary>
        /// 随机short
        /// </summary>
        /// <returns></returns>
        public static short RandomNumber(int min, int max)
        {
            Random rd = new Random();
            return (short)rd.Next(min, max);
        }

        /// <summary>
        /// 计算校验码
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static byte xor(List<byte> bytes)
        {
            int checksum = 0;
            foreach (byte b in bytes)
            {
                checksum ^= b;
            }
            return (byte)(checksum & 0xff);
        }

        /// <summary>
        /// 转义
        /// </summary>
        /// <param name="inBytes"></param>
        /// <returns></returns>
        public static byte[] escape(List<byte> inBytes)
        {
            List<byte> outBytes = new List<byte>();
            foreach (byte b in inBytes)
            {
                if (b == 0x7E)
                {
                    outBytes.AddRange(HexStringToBytes("7D02"));
                }
                else if (b == 0x7D)
                {
                    outBytes.AddRange(HexStringToBytes("7D01"));
                }
                else
                {
                    outBytes.Add(b);
                }
            }
            return outBytes.ToArray();
        }
    }
}

(3)解包工具类PacketUtil.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Jt709DataParser
{
    public class PacketUtil
    {

        public static byte[] decodePacket(byte[] bytes)
        {
            //查找消息尾
            byte[] msgBodyNoHeader = bytes.Skip(1).Take(bytes.Length - 1).ToArray();
            int tailIndex = Common.BytesIndexOf(msgBodyNoHeader, 0x7E);
            if (tailIndex <= 0)
            {
                return null;
            }
            return unescape(bytes, tailIndex).ToArray();
        }
        /// <summary>
        /// 反转义
        /// </summary>
        /// <param name="bytes"></param>
        /// <param name="bodyLen"></param>
        /// <returns></returns>
        public static List<byte> unescape(byte[] bytes, int bodyLen)
        {
            int i = 0;
            List<byte> frame = new List<byte>();
            while (i < bodyLen)
            {
                byte b = bytes[i];
                if (b == 0x7D)
                {
                    byte nextByte = bytes[i + 1];
                    if (nextByte == 0x01)
                    {
                        frame.Add(0x7D);
                    }
                    else if (nextByte == 0x02)
                    {
                        frame.Add(0x7E);
                    }
                    else
                    {
                        //异常数据
                        frame.Add(b);
                        frame.Add(nextByte);
                    }
                    i += 2;
                }
                else
                {
                    frame.Add(b);
                    i++;
                }
            }
            return frame;
        }

        /// <summary>
        /// 解析定位消息体
        /// </summary>
        /// <param name="msgBodyBuf"></param>
        /// <returns></returns>
        public static LocationData parseLocationBody(byte[] msgBodyBuf)
        {
            //报警标志
            long alarmFlag = Common.SwapUInt32(BitConverter.ToUInt32(msgBodyBuf, 0));
            //状态
            long status = Common.SwapUInt32(BitConverter.ToUInt32(msgBodyBuf, 4));
            //纬度
            double lat = Common.SwapUInt32(BitConverter.ToUInt32(msgBodyBuf, 8)) * 0.000001;
            //经度
            double lon = Common.SwapUInt32(BitConverter.ToUInt32(msgBodyBuf, 12)) * 0.000001;
            //海拔高度,单位为米
            int altitude = Common.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 16));
            //速度
            double speed = Common.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 18)) * 0.1;
            //方向
            int direction = Common.SwapUInt16(BitConverter.ToUInt16(msgBodyBuf, 20));
            //定位时间
            DateTime gpsZonedDateTime = Common.GetDataTime(msgBodyBuf.Skip(22).Take(6).ToArray());
            //根据状态位的值判断是否南纬和西经
            if (Common.getBitValue(status, 2) == 1)
            {
                lat = -lat;
            }
            if (Common.getBitValue(status, 3) == 1)
            {
                lon = -lon;
            }
            //定位状态
            int locationType = Common.getBitValue(status, 18);
            if (locationType == 0)
            {
                locationType = Common.getBitValue(status, 1);
            }
            if (locationType == 0)
            {
                locationType = Common.getBitValue(status, 6) > 0 ? 2 : 0;
            }
            //锁绳状态
            int lockRope = Common.getBitValue(status, 20);
            //锁电机状态
            int lockMotor = Common.getBitValue(status, 21);
            //锁状态(由锁绳/按钮+电机来组合判断,当锁绳/按钮为开(1)则锁状态必然为开(1);或者电机状态为开(1)则锁状态也为开(1);其他的则为关(0))
            int lockStatus = 0;
            if (lockRope == 1 || lockMotor == 1)
            {
                lockStatus = 1;
            }
            //后盖状态
            int backCover = Common.getBitValue(status, 7);
            //唤醒源
            long awaken = (status >> 24) & 0x0f;
            int alarm = parseAlarm(alarmFlag);
            LocationData locationData = new LocationData();
            locationData.GpsTime = gpsZonedDateTime;
            locationData.Latitude = lat;
            locationData.Longitude = lon;
            locationData.LocationType = locationType;
            locationData.Speed = (int)speed;
            locationData.Direction = direction;
            locationData.Altitude = altitude;
            locationData.LockStatus = lockStatus;
            locationData.LockRope = lockRope;
            locationData.Alarm = alarm;
            locationData.BackCover = backCover;
            locationData.Awaken = (int)awaken;
            //处理附加信息
            if (msgBodyBuf.Length > 28)
            {
                byte[] extraBytes = msgBodyBuf.Skip(28).Take(msgBodyBuf.Length - 28).ToArray();
                parseExtraInfo(extraBytes, locationData);
            }
            return locationData;
        }

        /// <summary>
        /// 解析附加信息
        /// </summary>
        /// <param name="msgBody"></param>
        /// <param name="location"></param>
        private static void parseExtraInfo(byte[] msgBody, LocationData location)
        {
            byte[] extraInfoBuf = null;
            while (msgBody.Length > 1)
            {
                int extraInfoId = msgBody[0];
                int extraInfoLen = msgBody[1];
                if (msgBody.Length - 2 < extraInfoLen)
                {
                    break;
                }
                extraInfoBuf = msgBody.Skip(2).Take(extraInfoLen).ToArray();
                msgBody = msgBody.Skip(2 + extraInfoLen).Take(msgBody.Length - (2 + extraInfoLen)).ToArray();
                switch (extraInfoId)
                {
                    //锁事件
                    case 0x0B:
                        LockEvent lockEvent = new LockEvent();
                        //锁事件
                        int type = extraInfoBuf[0];
                        lockEvent.Type = type;
                        if (type == 0x01 || type == 0x02 || type == 0x03 || type == 0x05 || type == 0x1E || type == 0x1F)
                        {
                            byte[] passwordBytes = extraInfoBuf.Skip(1).Take(6).ToArray();
                            string password = Common.ByteToASCII(passwordBytes);
                            lockEvent.Password = password;
                            int unlockStatus = extraInfoBuf[7];
                            if (unlockStatus == 0xff)
                            {
                                lockEvent.UnLockStatus = 0;
                            }
                            else
                            {
                                if (unlockStatus > 0 && unlockStatus < 100)
                                {
                                    lockEvent.FenceId = unlockStatus;
                                }
                                lockEvent.UnLockStatus = 1;
                            }
                        }
                        else if (type == 0x06 || type == 0x07 || type == 0x08 || type == 0x10 || type == 0x11 || type == 0x18 || type == 0x19 || type == 0x20 || type == 0x28 || type == 0x29)
                        {
                            byte[] passwordBytes = extraInfoBuf.Skip(0).Take(6).ToArray();
                            string password = Common.ByteToASCII(passwordBytes);
                            lockEvent.Password = password;
                            lockEvent.UnLockStatus = 0;
                        }
                        else if (type == 0x22)
                        {
                            long cardId = Common.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 0));
                            if (cardId != 0)
                            {
                                lockEvent.CardNo = cardId.ToString().PadLeft(10, '0');
                            }
                            if (extraInfoBuf.Length > 4)
                            {
                                int unlockStatus = extraInfoBuf[4];
                                if (unlockStatus == 0xff)
                                {
                                    lockEvent.UnLockStatus = 0;
                                }
                                else
                                {
                                    if (unlockStatus > 0 && unlockStatus < 100)
                                    {
                                        lockEvent.FenceId = unlockStatus;
                                    }
                                    lockEvent.UnLockStatus = 1;
                                }
                            }
                        }
                        else if (type == 0x23 || type == 0x2A || type == 0x2B)
                        {
                            long cardId = Common.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 0));
                            if (cardId != 0)
                            {
                                lockEvent.CardNo = cardId.ToString().PadLeft(10, '0');
                            }
                        }
                        location.LockEvent = lockEvent;
                        break;
                    //无线通信网络信号强度
                    case 0x30:
                        int fCellSignal = extraInfoBuf[0];
                        location.GSMSignal = fCellSignal;
                        break;
                    //卫星数
                    case 0x31:
                        int fGPSSignal = extraInfoBuf[0];
                        location.GpsSignal = fGPSSignal;
                        break;
                    //电池电量百分比
                    case 0xD4:
                        int fBattery = extraInfoBuf[0];
                        location.Battery = fBattery;
                        break;
                    //电池电压
                    case 0xD5:
                        int fVoltage = Common.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                        location.Voltage = fVoltage * 0.01;
                        break;
                    case 0xF9:
                        //版本号
                        int version = Common.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                        location.ProtocolVersion = version;
                        break;
                    case 0xFD:
                        //小区码信息
                        int mcc = Common.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 0));
                        location.MCC = mcc;
                        int mnc = extraInfoBuf[2];
                        location.MNC = mnc;
                        long cellId = Common.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 3));
                        location.CELLID = cellId;
                        int lac = Common.SwapUInt16(BitConverter.ToUInt16(extraInfoBuf, 7));
                        location.LAC = lac;
                        break;
                    case 0xFC:
                        int fenceId = extraInfoBuf[0];
                        location.FenceId = fenceId;
                        break;
                    case 0xFE:
                        long mileage = Common.SwapUInt32(BitConverter.ToUInt32(extraInfoBuf, 0));
                        location.Mileage = mileage;
                        break;
                    default:
                        break;
                }
            }
        }

        /// <summary>
        /// 温度解析
        /// </summary>
        /// <param name="temperatureInt"></param>
        /// <returns></returns>
        private static double parseTemperature(int temperatureInt)
        {
            if (temperatureInt == 0xFFFF)
            {
                return -1000;
            }
            double temperature = ((short)(temperatureInt << 4) >> 4) * 0.1;
            if ((temperatureInt >> 12) > 0)
            {
                temperature = -temperature;
            }
            return temperature;
        }

        /// <summary>
        /// 回复内容
        /// </summary>
        /// <param name="terminalNumArr"></param>
        /// <param name="msgFlowId"></param>
        /// <returns></returns>
        public static string replyBinaryMessage(byte[] terminalNumArr, int msgFlowId)
        {
            List<byte> byteList = new List<byte>();
            byteList.AddRange(Common.HexStringToBytes("8001"));
            byteList.AddRange(Common.HexStringToBytes("0005"));
            byteList.AddRange(terminalNumArr);
            byteList.AddRange(Common.ShortToBytes(Common.RandomNumber(0, 65534)));
            byteList.AddRange(Common.ShortToBytes((short)msgFlowId));
            byteList.AddRange(Common.HexStringToBytes("0200"));
            byteList.Add(0x00);
            byteList.Add(Common.xor(byteList));
            byte[] bytes = Common.escape(byteList);
            List<byte> replyList = new List<byte>();
            replyList.Add(0x7E);
            replyList.AddRange(bytes);
            replyList.Add(0x7E);
            return Common.ByteToHexStr(replyList.ToArray());
        }

        /// <summary>
        /// 授时
        /// </summary>
        /// <param name="itemList"></param>
        /// <returns></returns>
        public static string replyBASE2Message(string[] itemList)
        {
            try
            {
                string strBase2Reply = string.Format("({0},{1},{2},{3},{4},{5})", itemList[0], itemList[1]
                        , itemList[2], itemList[3], itemList[4], DateTime.UtcNow.ToString("yyyyMMddHHmmss"));
                return strBase2Reply;
            }
            catch (Exception e)
            {
                return "";
            }
        }

        /// <summary>
        /// 报警解析
        /// </summary>
        /// <param name="alarmFlag"></param>
        /// <returns></returns>
        private static int parseAlarm(long alarmFlag)
        {
            int alarm = -1;
            //单次触发报警
            if (Common.getBitValue(alarmFlag, 1) == 1)
            {
                alarm = (int)AlarmTypeEnum.ALARM_1;
            }
            else if (Common.getBitValue(alarmFlag, 7) == 1)
            {
                alarm = (int)AlarmTypeEnum.ALARM_2;
            }
            else if (Common.getBitValue(alarmFlag, 16) == 1)
            {
                alarm = (int)AlarmTypeEnum.ALARM_3;
            }
            else if (Common.getBitValue(alarmFlag, 17) == 1)
            {
                alarm = (int)AlarmTypeEnum.ALARM_4;
            }
            else if (Common.getBitValue(alarmFlag, 18) == 1)
            {
                alarm = (int)AlarmTypeEnum.ALARM_5;
            }
            return alarm;
        }
    }
}

2.4.返回消息及说明

(1)心跳数据
原始数据:

7E000200007501804283100001267E

返回消息:

{"DeviceID":"750180428310","MsgType":"heartbeat"}

返回消息描述

{"DeviceID":设备ID,"MsgType":消息类型(heartbeat:心跳)}

(2)定位数据
原始数据(不带锁事件):

7E0200003A790011000094180C000000000234000201E807C80713B76A007800000000210804150651D4014AD502018C30011A310108FE0400000BCCFD0901CC000000308D51D0F27E

返回消息:

{
    "DeviceID": "790011000094",
    "DataBody": {
        "GpsTime": "2021-08-04T15:06:51Z",
        "MNC": 0,
        "FenceId": 0,
        "BackCover": 0,
        "Index": 6156,
        "Latitude": 31.98356,
        "Awaken": 2,
        "ProtocolVersion": 0,
        "Direction": 0,
        "Battery": 74,
        "GpsSignal": 8,
        "Voltage": 3.96,
        "Speed": 0,
        "LockStatus": 1,
        "Mileage": 3020,
        "MCC": 460,
        "Longitude": 118.73265,
        "LAC": 20944,
        "Alarm": -1,
        "DataLength": 58,
        "CELLID": 12429,
        "LockRope": 1,
        "LocationType": 1,
        "Altitude": 120,
        "GSMSignal": 26
    },
    "ReplyMsg": "7e80010005790011000094dae5180c020000517e",
    "MsgType": "Location"
}

返回消息描述

{
    "DeviceID": "790011000094",
    "DataBody": {
        "GpsTime": 定位时间(UTC时间),
        "Latitude": 纬度(WGS84),
        "Longitude": 经度(WGS84),
        "MCC": 小区码信息MCC,
        "MNC": 小区码信息MNC,
        "LAC": 小区码信息LAC,
        "CELLID": 小区码信息CI,
        "FenceId": 电子围栏Id,
        "BackCover": 后盖状态(1:开;0:关),
        "Index": 流水号,
        "Awaken": 唤醒源 (1:RTC闹钟唤醒,2:Gsens震动唤醒 3:开盖唤醒 4:剪绳唤醒 5:充电唤醒 6:刷卡唤醒7:Lora唤醒8:VIP号码唤醒9:非VIP唤醒10:蓝牙唤醒)
        "ProtocolVersion":协议版本号,
        "Direction": 正北为0,顺时针0-360,
        "Battery": 电量值(0~100%,255 表示电池充电中),
        "GpsSignal": GPS当前接收到的卫星颗数,
        "Voltage": 电压值,单位V,
        "Speed": 速度,单位km/h,
        "LockStatus": 锁状态(0:关;1:开),
        "LockRope": 锁绳状态(0:插入;1:拔出),
        "Mileage": 里程值,单位km,
        "Alarm": 报警类型(1:超速报警;2:低电报警;3:主机开盖报警;4:进围栏报警;5:出围栏报警),
        "DataLength": 数据长度(字节数),
        "LocationType": 定位方式(0:不定位;1:GPS定位;2:基站定位),
        "Altitude": 海拔高度km,
        "GSMSignal": GSM信号值
    },
    "ReplyMsg": 需要回复终端的内容(为空则表示不需要回复),
    "MsgType": 数据类型(Location:定位数据)
}

原始数据(带锁事件):

7E020000477900110000941808000000000224000201E807AA0713B7EC009100000000210804150506D4014AD502018C30011E310108FE0400000BCCFD0901CC00000038CB51D0EF014A0B0801383838383838654B7E

返回消息:

{
    "DeviceID": "790011000094",
    "DataBody": {
        "GpsTime": "2021-08-04T15:05:06Z",
        "MNC": 0,
        "FenceId": 0,
        "BackCover": 0,
        "Index": 6152,
        "Latitude": 31.98353,
        "Awaken": 2,
        "ProtocolVersion": 0,
        "Direction": 0,
        "Battery": 74,
        "GpsSignal": 8,
        "Voltage": 3.96,
        "LockEvent": {
            "Type": 1,
            "FenceId": -1,
            "UnLockStatus": 1,
            "Password": "888888"
        },
        "Speed": 0,
        "LockStatus": 1,
        "Mileage": 3020,
        "MCC": 460,
        "Longitude": 118.73278,
        "LAC": 20944,
        "Alarm": -1,
        "DataLength": 71,
        "CELLID": 14539,
        "LockRope": 0,
        "LocationType": 1,
        "Altitude": 145,
        "GSMSignal": 30
    },
    "ReplyMsg": "7e80010005790011000094a8251808020000e77e",
    "MsgType": "Location"
}

返回消息描述

{
    "DeviceID": "790011000094",
    "DataBody": {
        "GpsTime": 定位时间(UTC时间),
        "Latitude": 纬度(WGS84),
        "Longitude": 经度(WGS84),
        "MCC": 小区码信息MCC,
        "MNC": 小区码信息MNC,
        "LAC": 小区码信息LAC,
        "CELLID": 小区码信息CI,
        "FenceId": 电子围栏Id,
        "BackCover": 后盖状态(1:开;0:关),
        "Index": 流水号,
        "Awaken": 唤醒源 (1:RTC闹钟唤醒,2:Gsens震动唤醒 3:开盖唤醒 4:剪绳唤醒 5:充电唤醒 6:刷卡唤醒7:Lora唤醒8:VIP号码唤醒9:非VIP唤醒10:蓝牙唤醒)
        "ProtocolVersion":协议版本号,
        "Direction": 正北为0,顺时针0-360,
        "Battery": 电量值(0~100%,255表示电池充电中),
        "GpsSignal": GPS当前接收到的卫星颗数,
        "Voltage": 电压值,单位V,
        "Speed": 速度,单位km/h,
        "LockStatus": 锁状态(0:关;1:开),
        "LockRope": 锁绳状态(0:插入;1:拔出),
        "Mileage": 里程值,单位km,
        "Alarm": 报警类型(1:超速报警;2:低电报警;3:主机开盖报警;4:进围栏报警;5:出围栏报警),
        "LockEvent": {
            "Type": 事件类型(参见附件1),
            "FenceId": 事件关联的围栏ID(-1:与围栏无关),
            "UnLockStatus": 开锁状态(1:开锁成功;0:开锁失败),
            "Password": 开锁密码
            "CardNo":如果事件类型为刷卡开锁,这里表示的是卡号
        },
        "DataLength": 数据长度(字节数),
        "LocationType": 定位方式(0:不定位;1:GPS定位;2:基站定位),
        "Altitude": 海拔高度km,
        "GSMSignal": GSM信号值
    },
    "ReplyMsg": 需要回复终端的内容(为空则表示不需要回复),
    "MsgType": 数据类型(Location:定位数据)
}

(3)指令数据解析
原始数据:

283739313030353030303030332c312c3030312c424153452c312c4a54373039415f32303230303932325f48572d56312e305f4e6f524649445f53494d434f4d373630305f56325f312c302c4c45313142303353494d373630304d31315f412c38393836303431323130313843303733383535342c3836373538343033343631313131362c3436302c302c3138303535343736342c313033343229

返回消息:

{
    "DeviceID": "791005000003",
    "DataBody": "(791005000003,1,001,BASE,1,JT709A_20200922_HW-V1.0_NoRFID_SIMCOM7600_V2_1,0,LE11B03SIM7600M11_A,898604121018C0738554,867584034611116,460,0,180554764,10342)",
    "ReplyMsg": "",
    "MsgType": "BASE1"
}

返回消息描述

{
    "DeviceID": 设备ID,
    "DataBody": 消息体内容,
    "ReplyMsg": 回复设备的消息(为空则表示不需要回复),
    "MsgType": 指令类型
}

3.指令消息

3.1.查询终端基本信息

消息体内容(DataBody):

(791005000003,1,001,BASE,1,JT709A_20200922_HW-V1.0_NoRFID_SIMCOM7600_V2_1,0,LE11B03SIM7600M11_A,898604121018C0738554,867584034611116,460,0,180554764,10342)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,1 指令类型(BASE1)
3 JT709A_20200922_HW-V1.0_NoRFID_SIMCOM7600_V2_1 当前设备的版本号。
4 0 前面的0表示英文,1表示其它语言的Unicode码
5 LE11B03SIM7600M11_A GSM模块版本。
6 898604121018C0738554 SIM卡的ICCID。
7 867584034611116 GSM模块的IMEI号。
8 460,00,4243,6877 网络信息:460 移动国家代码,即MCC信息,此处表示中国;00电信运营商网络号码,MNC信息(中国移动为00,中国联通为01);4243 基站编号CELL ID信息;6877 位置区域码LAC信息。CELL ID与LAC为十六进制,即4243转为十进制为16963。

3.2.授时(同步GMT时间)

消息体内容(DataBody):

(700160818000,1,001,BASE,2,20111018123820)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,2 指令类型(BASE2)
3 20111018123820 设置的时间(yyyyMMddHHmmss)

3.3.远程重启终端

消息体内容(DataBody):

(700160818000,1,001,BASE,3)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,3 指令类型(BASE3)

3.4.恢复出厂设置

消息体内容(DataBody):

(700160818000,1,001,BASE,4)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,4 指令类型(BASE4)

3.5.设置报警开关指令

消息体内容(DataBody):

(700160818000,1,001,BASE,5, 1,1,1,1,1,1,1,1,1,1,1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,5 指令类型(BASE5)
3 1,1,1,1,1,1,1,1,1,1,1 从左至右依次为(1)锁挂绳剪断报警、(2)刷非法卡报警、(3)开锁状态保持一段时间报警、(4)指令开锁密码连续输错5次报警、(5)震动报警、(6)进区域报警、(7)出区域报警的开关、(8)低电报警(电量低于满电的30%)、(9)开后盖报警、(10)卡锁报警、(11)超速报警;(每个报警开关参数可以取值为0,1,2,3,并且可以任意组合,0表示GPRS和SMS报警都关闭,1表示只开启GPRS报警,2表示只开启SMS报警,3表示GPRS和SMS报警都开启.)

3.6.查询/设置上传间隔和休眠定时唤醒间隔

消息体内容(DataBody):

(700160818000,1,001,BASE,6,60,30)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,6 指令类型(BASE6)
3 60 上传间隔,以秒为单位,默认60。最长1小时,最短5秒
4 30 设备正常工作间隔,单位分钟,默认60分钟. 当该值为0时,启用持续追踪模式,设备不休眠。最长24小时,最短5分钟

3.7.查询/设置终端休眠模式

消息体内容(DataBody):

(700160818000,1,001,BASE,7,1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,7 指令类型(BASE7)
3 1 0正常休眠模式任一中断、RTC可以唤醒,1表示在0模式上增加短信电话可以唤醒

3.8.查询/设置终端本地时差

消息体内容(DataBody):

(2310915002,1,001,BASE,8, 480)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,8 指令类型(BASE8)
3 480 时差值,此处单位为分钟

3.9.查询/设置终端本地时差

消息体内容(DataBody):

(700160818000,1,001,BASE,9,8613998765432,0,0,0,0)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,9 指令类型(BASE9)
3 8613998765432,0,0,0,0 5个监控手机号码,0表示没有设置

3.10.查询/设置主从IP地址与端口号、APN及用户名与密码等参数

消息体内容(DataBody):

(700160818000,1,001,BASE,10,211.154.112.98,1088,211.154.112.98,1088,CMNET,abc,123456)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,10 指令类型(BASE10)
3 211.154.112.98 主IP(域名)
4 1088 主端口
5 211.154.112.98 从IP(域名)
6 1088 从端口
7 CMNET APN名称
8 abc 用户名
9 123456 密码

3.11.查询/设置/删除设备工作闹钟

消息体内容(DataBody):

(700160818000,1,001,BASE,32,1,480)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,32 指令类型(BASE32)
3 1 则表明当前有效闹钟个数;返回0表示当前没有有效闹钟
4 480 设置一个设备闹钟的时间,以分钟为单位(范围为:0~1439)

3.12.查询/设置仅支持VIP号码

消息体内容(DataBody):

(700160818000,1,001,BASE,40,1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,40 指令类型(BASE40)
3 1 1表示仅支持VIP号码进行设备配置和查询,0表示非vip号码也可以配置和查询。默认0

3.13.查询/设置里程统计相关参数

消息体内容(DataBody):

(700160818000,1,001,BASE,43,10,10)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,43 指令类型(BASE43)
3 10 表示里程统计的速度限制值操作(即速度小于改值不统计里程,默认10km/h, 参数0-100)
4 10 表示设置里程同步值为10公里

3.14.查询/设置静态飘移处理功能

消息体内容(DataBody):

(700160818000,1,001,BASE,44,1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,44 指令类型(BASE44)
3 1 1打开这个静态漂移处理功能,0表示关闭静态漂移处理功能

3.15.查询/设置GPS追踪定位模式功能

消息体内容(DataBody):

(700160818000,1,001,BASE,45,1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,45 指令类型(BASE45)
3 1 1表示节能定时追踪,0 表示节能定位追踪,2表示全速追踪

3.16.查询/设置GPS定位判定门限参数(防GPS定位漂移)

消息体内容(DataBody):

(700160818000,1,001,BASE,46,5,25,6)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,46 指令类型(BASE46)
3 5 HDOP门限值
4 25 单颗卫星信噪比门限值
5 6 联合定位卫星个数门限值

3.17.查询/设置GPS定位判定门限参数(防GPS定位漂移)

消息体内容(DataBody):

(700160818000,1,001,BASE,47,1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,47 指令类型(BASE47)
3 1 1: 启用监控IP服务器,0关闭监控IP服务器

3.18.设置报警开关指令

消息体内容(DataBody):

(700160818000,1,001,BASE,48, 1,1,1,1,1,1,1,1,1,1,1,1,1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 BASE,47 指令类型(BASE47)
3 1,1,1,1, 1,1,1,1, 1,1,1,1,1 从左至右依次为(1) 锁绳剪断报警、(2)刷非法卡报警、(3)长时间开锁报警、(4)开锁密码错误、(5)震动报警、(6)进区域报警、(7)出区域报警、(8)低电报警、(9)开后盖报警、(10)卡锁报警、(11)GSM信号低报警、(12)超速报警 (每个报警开关参数可以取值为0,1,2,3,并且可以任意组合,0表示GPRS和SMS报警都关闭,1表示只开启GPRS报警,2表示只开启SMS报警,3表示GPRS和SMS报警都开启.),(13)倾斜报警,其中红色的没有相应报警

3.19.查询/设置震动检测阈值

消息体内容(DataBody):

(700160818000,1,001,GSENS,1, 500)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 GSENS,1 指令类型(GSENS1)
3 500 500:单位是mg(gsensor芯片63mg为阶梯配置,实际芯片配置值为500/63取整=7),最小63,最大值8000,默认500。当震动达到这个值,会检测到一次震动。如果值等于0,关闭该功能

3.20.电池产品入库前进入休眠

消息体内容(DataBody):

(700160818000,1,001,DEBUG,7)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 DEBUG,7 指令类型(DEBUG7)

3.20.电池产品入库前进入休眠

消息体内容(DataBody):

(700160818000,1,001,DEBUG,15, 10)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 DEBUG,15 指令类型(DEBUG15)
3 10 0表示马上进入睡眠,设置大于0的数表示相应时间后进入休眠

3.21.查询物联卡信息

消息体内容(DataBody):

(700160818000,1,001,DEBUG,27, ICCID, IMSI)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 DEBUG,27 指令类型(DEBUG27)
3 ICCID ICCID号码
4 IMSI IMSI号码

3.22.查询/清除历史(盲区)数据

消息体内容(DataBody):

(700160818000,1,001,DEBUG,29, 0)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 DEBUG,29 指令类型(DEBUG29)
3 0 返回0则表明当前历史数据条数

3.23.查询/设置超速报警速度

消息体内容(DataBody):

(700160818000,1,001,DEBUG,30,120,10)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 DEBUG,30 指令类型(DEBUG30)
3 120 报警的速度临界值(默认值120),单位为:公里
4 10 超速此时间后报警(默认值10),单位:秒

3.24.查询/设置低电报警数值

消息体内容(DataBody):

(700160818000,1,001,DEBUG,31,5)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 DEBUG,31 指令类型(DEBUG31)
3 5 报警的电量临界值;5表明当前电量百分比

3.25.查询/设置关闭看门狗作用

消息体内容(DataBody):

(700160818000,1,001,DEBUG,38,0)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 DEBUG,38 指令类型(DEBUG38)
3 0 返回0表明已接收该指令,并生效。

3.26.设置/查询区域详细节点信息

消息体内容(DataBody):

(700160818000,1,001,GFCE,7,8,15,1,10,11323.1234…)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 GFCE,7 指令类型(GFCE7)
3 8 8表示第八个区域
4 15 15表示总点数
5 1 1表示当前页
6 10 10表示当前页的点数
7 11323.1234… 各个点的经度与纬度

3.27.清除设置的全部区域点信息

消息体内容(DataBody):

(700160818000,1,001,GFCE,8,1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 GFCE,8 指令类型(GFCE8)
3 1 1表示删除围栏的ID

3.28.查询/设置没有关锁报警提醒时间间隔

消息体内容(DataBody):

(700160818000,1,001,ELOCK,2, 1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,2 指令类型(ELOCK2)
3 1 提醒时间,单位(分钟)。当开锁后没有关锁,如果此值不为0(为0无效)时间到就上报开锁提醒消息,最小值为1分钟,最大值为10分钟 。默认为1分钟

3.29.终端上报动态密码

消息体内容(DataBody):

(700160818000,1,001,ELOCK,3,123456)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,3 指令类型(ELOCK3)
3 123456 上报的动态密码

3.30.设置/修改远程开锁静态密码

消息体内容(DataBody):

(700160818000,1,001,ELOCK,4,666666)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,4 指令类型(ELOCK4)
3 666666 666666: 表示修改成功的密码。

3.31.凭静态或动态密码开锁

消息体内容(DataBody):

(700160818000,1,001,ELOCK,5,1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,5 指令类型(ELOCK5)
3 1 0: 表示密码正确,大于0表示密码错误开锁失败

3.32.查询/设置围栏外禁止开锁

消息体内容(DataBody):

(700160818000,1,001,ELOCK,7,1,2,3,4)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,7 指令类型(ELOCK7)
3 1 1表示设置了栏外禁止开锁,必须在定位状下围栏内才能开锁。2表示设置了栏外禁止开锁,有定位必须在围栏内开锁,没有定位可以通过远程静态密码或动态密码开锁,如果设置了围栏外禁止开锁没有定位不能通过现场按键或蓝牙APP开锁。0表示没有开启围栏外禁止开锁功能,默认没有开启。
4 2 围栏ID个数:1~10有效,只支持区域围栏。其它类型的围栏不支持
5 3,4 围栏ID: 1~10有效,3,4表示只能在区域围栏ID为3,4的围栏可以开锁,1~10的ID存在对应的位置

3.33.动态密码权限处理(不对外公开)

消息体内容(DataBody):

(700160818000,1,001,ELOCK,7,1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,7 指令类型(ELOCK7)
3 1 1表示使能产生动态密码;0表示关闭产生动态密码

3.34.查询/增删/开锁授权号

消息体内容(DataBody)实例1:

(700160818000,1,001, ELOCK,15,0,2,20,2,1,0013953759, 0013953758, 0013953757,,,,,,,,,,,,,)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,15 指令类型(ELOCK15)
3 0 操作模式, 0表示查询终端已存所有授权号,1表示要增加开锁授权号操作,2表示删除授权号,3表示删除所有的授权号。
4 2 2为查询第2组数据,一共分3组,分别为1~3
5 20 20表示有20个ID号
6 2 2表示总共有2应答包
7 1 1表示当前是第1个应答包
8 0013953759, 0013953758, 0013953757,,,,, 表示该组存储的授权号列表

消息体内容(DataBody)实例2:

(700160818000,1,001,ELOCK,15,1,3,200)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,15 指令类型(ELOCK15)
3 1 操作模式, 0表示查询终端已存所有授权号,1表示要增加开锁授权号操作,2表示删除授权号,3表示删除所有的授权号。
4 3 增加3个授权卡号成功
5 200 当前总共有200个卡

消息体内容(DataBody)实例3:

(700160818000,1,001,ELOCK,15,2,3)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,15 指令类型(ELOCK15)
3 2 操作模式, 0表示查询终端已存所有授权号,1表示要增加开锁授权号操作,2表示删除授权号,3表示删除所有的授权号。
4 3 表示删除3个授权卡号成功。(每次最多一次性删除20)

消息体内容(DataBody)实例4:

(700160818000,1,001, ELOCK,15,3,0)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,15 指令类型(ELOCK15)
3 3 操作模式, 0表示查询终端已存所有授权号,1表示要增加开锁授权号操作,2表示删除授权号,3表示删除所有的授权号。
4 0 表示删除全部授权卡号成功,目前剩余0个授权卡

3.35.现场刷卡授权模式配置指令

消息体内容(DataBody)实例1:

(700160818000,1,001, ELOCK,16,2,0013953759,0013953751)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,16 指令类型(ELOCK16)
3 2 授权的卡个数
4 0013953759,0013953751 授权的卡号

消息体内容(DataBody)实例2:

(700160818000,1,001, ELOCK,16,0)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 ELOCK,16 指令类型(ELOCK16)
3 0 1表示打开批量增加终端开锁授权号功能, 0表示关闭批量增加终端开锁授权号功能。

3.36.通知设备MCU升级

消息体内容(DataBody):

(700160818000,1,001,OTA,1,1,20120102)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 OTA,1 指令类型(OTA1)
3 1 1:表示同意升级,只有当设备的当前版本号低于要升级的版本号的时候才返回1.若设备返回0表示拒绝升级,即设备当前的Firmware版本和升级的Firmware版本相同或者更高。服务器只有在收到同意升级以后才发送第一个Firmware数据包.
4 20120102 当前设备的Firmware版本号.

3.37.发送Firmware数据包

消息体内容(DataBody):

(700160818000,1,001,OTA,2,0,200,100)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 OTA,2 指令类型(OTA2)
3 0 1表示保存成功,0表示保存失败,如果失败重发.
4 200 接收到的Firmware数据包序号.
5 100 下一条需要发送的数据包序号.

3.38.取消Firmware升级

消息体内容(DataBody):

(700160818000,1,001,OTA,3,1,20120222)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 OTA,3 指令类型(OTA3)
3 1 1表示取消成功,0表示取消失败。如果该指令的版本号和正在升级的固件版本号不符的话就可能取消失败.
4 20120222 设备正在升级的版本号

3.39.完成Firmware传输

消息体内容(DataBody):

(700160818000,1,001,OTA,4,1)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 OTA,4 指令类型(OTA4)
3 1 该参数可以为1或者为0,1表示接受该指令,并根据指令执行。0表示:接受的数据不完全,拒绝升级.

3.40.查询发送下条Firmware数据包序号

消息体内容(DataBody):

(700160818000,1,001,OTA,5,1,200)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 OTA,5 指令类型(OTA5)
3 1 1:代表目前正在接收的固件和查询的相同,0表示目前接收的固件和查询的不同.
4 200 如果查询的固件版本号比设备的版本号新的话,该参数表示下一条需要发送的序号。如果查询的版本号和正在升级的版本号不同的话,则该参数为1.即代表需要重新下载现在查询的固件.

3.41.查询当前stm32固件的版本号

消息体内容(DataBody):

(700160818000,1,001,OTA,6,JT709A_V103R001)

消息体内容描述:

序号 示例 说明
1 700160818000 设备ID
2 OTA,6 指令类型(OTA6)
3 JT709A_V103R001 固件版本号

附件1

事件ID(16进制) 事件ID 事件描述
0x01 1 静态密码远程开锁
0x02 2 动态密码远程开锁
0x03 3 动态密码现场(蓝牙或WIFI)APP开锁
0x05 5 表示静态密码现场(蓝牙或WIFI)APP开锁
0x06 6 错误的静态密码远程开锁
0x07 7 错误的动态密码远程开锁
0x08 8 错误的动态密码现场(蓝牙或WIFI)APP开锁
0x0B 11 长时间开锁事件
0x0C 12 锁绳剪断事件
0x0D 13 关锁事件(包括自动关锁和远程关锁)
0x10 16 远程执行开锁异常,没有定位不执行开锁
0x11 17 远程执行开锁异常,有定位在围栏外不执行开锁
0x12 18 电机异常
0x18 24 蓝牙执行开锁异常,没有定位不执行开锁
0x19 25 蓝牙执行开锁异常,有定位在围栏外不执行开锁
0x1C 28 开锁并拔出锁绳
0x1E 30 短信静态密码远程开锁
0x1F 31 短信动态密码远程开锁
0x20 32 表示错误的短信动态密码
0x22 34 刷授权卡开锁事件
0x23 35 刷非法卡开锁事件
0x28 40 错误的静态密码现场(蓝牙或WIFI)APP开锁
0x29 41 错误的短信静态密码开锁
0x2A 42 RFID执行开锁异常,没有定位不执行开锁
0x2B 43 RFID执行开锁异常,有定位在围栏外不执行开锁
文档更新时间: 2024-10-15 18:07   作者:admin