1.Jar package download

jt704-sdk-1.0.0.jar Download
If you need Jar package development source code, please contact the business application


2.Integrated Development Instructions

2.1.Integrated development language and framework description

jt704-sdk-1.0.0.jar is based on the Java language,SpringBoot2.x frame,use netty,fastjson,lombok,commons-lang3

BaseEnum:base enumeration
Constant:custom constant
AlarmTypeEnum:Alarm enumeration
EventTypeEnum:event enumeration
LocationData:Location entity class
LockEvent:lock event entity class
Result:result entity class
SensorData:Slave data entity class
CommonUtil:public method class
NumberUtil:digital manipulation tools
ParserUtil:Parser method tool class
DataParser:Parser main method

2.2.Integration Instructions

Introduce jt704-sdk-1.0.0.jar into your gateway program as follows:
Introduce the jar package in pom.xml

        <dependency>
            <groupId>com.jointech.sdk</groupId>
            <artifactId>jt704-sdk</artifactId>
            <version>1.0.0</version>
        </dependency>

Call jt704-sdk-1.0.0.jar, the receiveData() method in the DataParser class
receiveData() method is overloaded

    /**
     * Parse Hex string raw data
     * @param strData hexadecimal string
     * @return
     */
    public static Object receiveData(String strData) {
        int length=strData.length()%2>0?strData.length()/2+1:strData.length()/2;
        ByteBuf msgBodyBuf = Unpooled.buffer(length);
        msgBodyBuf.writeBytes(CommonUtil.hexStr2Byte(strData));
        return receiveData(msgBodyBuf);
    }

    /**
     * Parse byte[] raw data
     * @param bytes
     * @return
     */
    private static Object receiveData(byte[] bytes)
    {
        ByteBuf msgBodyBuf =Unpooled.buffer(bytes.length);
        msgBodyBuf.writeBytes(bytes);
        return receiveData(msgBodyBuf);
    }

    /**
     * Parse ByteBuf raw data
     * @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.Core code

ParserUtil:Parsing method tool class ParserUtil

package com.jointech.sdk.jt704.utils;

import com.jointech.sdk.jt704.constants.Constant;
import com.jointech.sdk.jt704.model.AlarmTypeEnum;
import com.jointech.sdk.jt704.model.LocationData;
import com.jointech.sdk.jt704.model.Result;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import org.apache.commons.lang3.StringUtils;

import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>Description: Analysis method tool class</p>
 * @author HyoJung
 * @date 20210526
 */
public class ParserUtil {
    /**
     * Parse Positioning data 0x0200
     * @param in
     * @return
     */
    public static Result decodeBinaryMessage(ByteBuf in) {
        //unexcape rawdata
        ByteBuf msg = (ByteBuf) PacketUtil.decodePacket(in);
        //message length
        int msgLen = msg.readableBytes();
        //packet header
        msg.readByte();
        //message ID
        int msgId = msg.readUnsignedShort();
        //message body properties
        int msgBodyAttr = msg.readUnsignedShort();
        //message body length
        int msgBodyLen = msgBodyAttr & 0b00000011_11111111;
        //Whether to subcontract
        boolean multiPacket = (msgBodyAttr & 0b00100000_00000000) > 0;
        //Remove the base length of the message body
        int baseLen = Constant.BINARY_MSG_BASE_LENGTH;

        //The following packet length is obtained according to the length of the message body and whether it is subcontracted
        int ensureLen = multiPacket ? baseLen + msgBodyLen + 4 : baseLen + msgBodyLen;
        if (msgLen != ensureLen) {
            return null;
        }
        //array of deviceID
        byte[] terminalNumArr = new byte[6];
        msg.readBytes(terminalNumArr);
        //Device ID (remove leading 0)
        String terminalNumber = StringUtils.stripStart(ByteBufUtil.hexDump(terminalNumArr), "0");
        //message serial number
        int msgFlowId = msg.readUnsignedShort();
        //total number of message packets
        int packetTotalCount = 0;
        //package serial number
        int packetOrder = 0;
        //subcontract
        if (multiPacket) {
            packetTotalCount = msg.readShort();
            packetOrder = msg.readShort();
        }
        //message body
        byte[] msgBodyArr = new byte[msgBodyLen];
        msg.readBytes(msgBodyArr);
        if(msgId==0x0200) {
            //Parse the message body
            LocationData locationData=parseLocationBody(Unpooled.wrappedBuffer(msgBodyArr));
            locationData.setIndex(msgFlowId);
            locationData.setDataLength(msgBodyLen);
            //check code
            int checkCode = msg.readUnsignedByte();
            //packet end
            msg.readByte();
            //Get message response content
            String replyMsg= PacketUtil.replyBinaryMessage(terminalNumArr,msgFlowId);
            //Define the location data entity class
            Result model = new Result();
            model.setDeviceID(terminalNumber);
            model.setMsgType("Location");
            model.setDataBody(locationData);
            model.setReplyMsg(replyMsg);
            return model;
        }else {
            //Define the location data entity class
            Result model = new Result();
            model.setDeviceID(terminalNumber);
            model.setMsgType("heartbeat");
            model.setDataBody(null);
            return model;
        }
    }

    /**
     * Parse instruction data
     * @param in raw data 
     * @return
     */
    public static Result decodeTextMessage(ByteBuf in) {

        //The read pointer is set to the message header
        in.markReaderIndex();
        //Look for the end of the message, if not found, continue to wait for the next packet
        int tailIndex = in.bytesBefore(Constant.TEXT_MSG_TAIL);
        if (tailIndex < 0) {
            in.resetReaderIndex();
            return null;
        }
        //Define the location data entity class
        Result model = new Result();
        //packet header(
        in.readByte();
        //Field list
        List<String> itemList = new ArrayList<String>();
        while (in.readableBytes() > 0) {
            //Query the subscript of comma to intercept data
            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));
        }
        String msgType = "";
        if (itemList.size() >= 5) {
            msgType = itemList.get(3) + itemList.get(4);
        }
        Object dataBody=null;
        if(itemList.size()>0){
            dataBody="(";
            for(String item :itemList) {
                dataBody+=item+",";
            }
            dataBody=CommonUtil.trimEnd(dataBody.toString(),",");
            dataBody += ")";
        }
        String replyMsg="";
        if(msgType.equals("BASE2")&&itemList.get(5).toUpperCase().equals("TIME")) {
            replyMsg=PacketUtil.replyBASE2Message(itemList);
        }
        model.setDeviceID(itemList.get(0));
        model.setMsgType(msgType);
        model.setDataBody(dataBody);
        model.setReplyMsg(replyMsg);
        return model;
    }

    /**
     * Parse and locate message body
     * @param msgBodyBuf
     * @return
     */
    private static LocationData parseLocationBody(ByteBuf msgBodyBuf){
        //alarm sign
        long alarmFlag = msgBodyBuf.readUnsignedInt();
        //Device status
        long status = msgBodyBuf.readUnsignedInt();
        //latitude
        double lat = NumberUtil.multiply(msgBodyBuf.readUnsignedInt(), NumberUtil.COORDINATE_PRECISION);
        //longitude
        double lon = NumberUtil.multiply(msgBodyBuf.readUnsignedInt(), NumberUtil.COORDINATE_PRECISION);
        //Altitude, in meters
        int altitude = msgBodyBuf.readShort();
        //Speed
        double speed = NumberUtil.multiply(msgBodyBuf.readUnsignedShort(), NumberUtil.ONE_PRECISION);
        //directioin
        int direction = msgBodyBuf.readShort();
        //GPS time
        byte[] timeArr = new byte[6];
        msgBodyBuf.readBytes(timeArr);
        String bcdTimeStr = ByteBufUtil.hexDump(timeArr);
        ZonedDateTime gpsZonedDateTime = CommonUtil.parseBcdTime(bcdTimeStr);
        //Determine whether the south latitude and west longitude are based on the value of the status bit
        if (NumberUtil.getBitValue(status, 2) == 1) {
            lat = -lat;
        }
        if (NumberUtil.getBitValue(status, 3) == 1) {
            lon = -lon;
        }
        //Positioning status
        int locationType=NumberUtil.getBitValue(status, 18);
        if(locationType==0)
        {
            locationType = NumberUtil.getBitValue(status, 1);
        }
        if(locationType==0)
        {
            locationType = NumberUtil.getBitValue(status, 6) > 0 ? 2 : 0;
        }
        //Alarm status
        int alarm=-1;
        if(NumberUtil.getBitValue(alarmFlag, 16) == 1)
        {
            alarm=Integer.parseInt(AlarmTypeEnum.ALARM_1.getValue());
        }
        //Back cover status
        int backCover=NumberUtil.getBitValue(status, 7);
        //wake-up source
        long awaken = (status>>24)&0b00001111;

        LocationData locationData=new LocationData();
        locationData.setGpsTime(gpsZonedDateTime.toString());
        locationData.setLatitude(lat);
        locationData.setLongitude(lon);
        locationData.setLocationType(locationType);
        locationData.setSpeed((int)speed);
        locationData.setDirection(direction);
        locationData.setAlarm(alarm);
        locationData.setBackCover(backCover);
        locationData.setAwaken((int)awaken);
        //Handling additional information
        if (msgBodyBuf.readableBytes() > 0) {
            parseExtraInfo(msgBodyBuf, locationData);
        }
        return locationData;
    }

    /**
     * Parse additional information
     *
     * @param msgBody
     * @param location
     */
    private static void parseExtraInfo(ByteBuf msgBody, LocationData location) {
        ByteBuf extraInfoBuf = null;
        while (msgBody.readableBytes() > 1) {
            int extraInfoId = msgBody.readUnsignedByte();
            int extraInfoLen = msgBody.readUnsignedByte();
            if (msgBody.readableBytes() < extraInfoLen) {
                break;
            }
            extraInfoBuf = msgBody.readSlice(extraInfoLen);
            switch (extraInfoId) {
                case 0x0F:
                    //Parsing temperature data
                    double temperature = -1000.0;
                    temperature = parseTemperature(extraInfoBuf.readShort());
                    location.setTemperature((int)temperature);
                    break;
                //Wireless communication network signal strength
                case 0x30:
                    int fCellSignal=extraInfoBuf.readByte();
                    location.setGSMSignal(fCellSignal);
                    break;
                //number of satellites
                case 0x31:
                    int fGPSSignal=extraInfoBuf.readByte();
                    location.setGpsSignal(fGPSSignal);
                    break;
                //battery percentage
                case 0xD4:
                    int fBattery=extraInfoBuf.readUnsignedByte();
                    location.setBattery(fBattery);
                    break;
                //battery voltage
                case 0xD5:
                    int fVoltage=extraInfoBuf.readUnsignedShort();
                    location.setVoltage(fVoltage*0.01);
                    break;
                case 0xFD:
                    //Cell code information
                    int mcc=extraInfoBuf.readUnsignedShort();
                    location.setMCC(mcc);
                    int mnc=extraInfoBuf.readUnsignedByte();
                    location.setMNC(mnc);
                    long cellId=extraInfoBuf.readUnsignedInt();
                    location.setCELLID((int)cellId);
                    int lac=extraInfoBuf.readUnsignedShort();
                    location.setLAC(lac);
                    break;
                case 0xFE:
                    long mileage = extraInfoBuf.readUnsignedInt();
                    location.setMileage(mileage);
                    break;
                default:
                    ByteBufUtil.hexDump(extraInfoBuf);
                    break;
            }
        }
    }

    /**
     * Parse temperature
     * @param temperatureInt
     * @return
     */
    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;
    }
}

PacketUtil:Used to process preprocessed data and restore method encapsulation class

package com.jointech.sdk.jt704.utils;

import com.jointech.sdk.jt704.constants.Constant;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufUtil;
import io.netty.util.ReferenceCountUtil;

import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Random;

/**
 * Parse package preprocessing (do unescaping)
 * @author HyoJung
 */
public class PacketUtil {
    /**
     * Parse message packets
     *
     * @param in
     * @return
     */
    public static Object decodePacket(ByteBuf in) {
        //The readable length cannot be less than the base length
        if (in.readableBytes() < Constant.BINARY_MSG_BASE_LENGTH) {
            return null;
        }

        //Prevent illegal code stream attacks, the data is too large to be abnormal data
        if (in.readableBytes() > Constant.BINARY_MSG_MAX_LENGTH) {
            in.skipBytes(in.readableBytes());
            return null;
        }

        //Look for the end of the message, if not found, continue to wait for the next packet
        in.readByte();
        int tailIndex = in.bytesBefore(Constant.BINARY_MSG_HEADER);
        if (tailIndex < 0) {
            in.resetReaderIndex();
            return null;
        }

        int bodyLen = tailIndex;
        //Create a ByteBuf to store the reversed data
        ByteBuf frame = ByteBufAllocator.DEFAULT.heapBuffer(bodyLen + 2);
        frame.writeByte(Constant.BINARY_MSG_HEADER);
        //The data between the header and the end of the message is escaped
        unescape(in, frame, bodyLen);
        in.readByte();
        frame.writeByte(Constant.BINARY_MSG_HEADER);

        //The length after the reverse escape cannot be less than the base length
        if (frame.readableBytes() < Constant.BINARY_MSG_BASE_LENGTH) {
            ReferenceCountUtil.release(frame);
            return null;
        }
        return frame;
    }

    /**
     * In the message header, message body and check code, 0x7D 0x02 is reversed to 0x7E, and 0x7D 0x01 is reversed to 0x7D
     *
     * @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 == 0x7D) {
                int nextByte = in.readUnsignedByte();
                if (nextByte == 0x01) {
                    frame.writeByte(0x7D);
                } else if (nextByte == 0x02) {
                    frame.writeByte(0x7E);
                } else {
                    //abnormal data
                    frame.writeByte(b);
                    frame.writeByte(nextByte);
                }
                i += 2;
            } else {
                frame.writeByte(b);
                i++;
            }
        }
    }

    /**
     * In the message header, message body and check code, 0x7E is escaped as 0x7D 0x02, and 0x7D is escaped as 0x7D 0x01
     *
     * @param out
     * @param bodyBuf
     */
    public static void escape(ByteBuf out, ByteBuf bodyBuf) {
        while (bodyBuf.readableBytes() > 0) {
            int b = bodyBuf.readUnsignedByte();
            if (b == 0x7E) {
                out.writeShort(0x7D02);
            } else if (b == 0x7D) {
                out.writeShort(0x7D01);
            } else {
                out.writeByte(b);
            }
        }
    }

    /**
     * reply content
     * @param terminalNumArr
     * @param msgFlowId
     * @return
     */
    public static String replyBinaryMessage(byte[] terminalNumArr,int msgFlowId) {
        //Remove the length of the head and tail
        int contentLen = Constant.BINARY_MSG_BASE_LENGTH + 4;
        ByteBuf bodyBuf = ByteBufAllocator.DEFAULT.heapBuffer(contentLen-2);
        ByteBuf replyBuf = ByteBufAllocator.DEFAULT.heapBuffer(25);
        try {
            //message ID
            bodyBuf.writeShort(0x8001);
            //data length
            bodyBuf.writeShort(0x0005);
            //Device ID
            bodyBuf.writeBytes(terminalNumArr);
            Random random = new Random();
            //Generate random numbers from 1-65534
            int index = random.nextInt() * (65534 - 1 + 1) + 1;
            //current message serial number
            bodyBuf.writeShort(index);
            //response message serial number
            bodyBuf.writeShort(msgFlowId);
            //response message ID
            bodyBuf.writeShort(0x0200);
            //response result
            bodyBuf.writeByte(0x00);
            //check code
            int checkCode = CommonUtil.xor(bodyBuf);
            bodyBuf.writeByte(checkCode);
            //packet header
            replyBuf.writeByte(Constant.BINARY_MSG_HEADER);
            //The read pointer is reset to the starting position
            bodyBuf.readerIndex(0);
            //escape
            PacketUtil.escape(replyBuf, bodyBuf);
            //packet end
            replyBuf.writeByte(Constant.BINARY_MSG_HEADER);
            return ByteBufUtil.hexDump(replyBuf);
        } catch (Exception e) {
            ReferenceCountUtil.release(replyBuf);
            return "";
        }
    }

    /**
     * Timing command reply
     * @param itemList
     */
    public static String replyBASE2Message(List<String> itemList) {
        try {
            //set date format
            ZonedDateTime currentDateTime = ZonedDateTime.now(ZoneOffset.UTC);
            String strBase2Reply = String.format("(%s,%s,%s,%s,%s,%s)", itemList.get(0), itemList.get(1)
                    , itemList.get(2), itemList.get(3), itemList.get(4), DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(currentDateTime));
            return strBase2Reply;
        }catch (Exception e) {
            return "";
        }
    }
}

NumberUtil:digital manipulation tools

package com.jointech.sdk.jt704.utils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * digital tools
 * @author HyoJung
 * @date 20210526
 */
public class NumberUtil {
    /**
     * Coordinate accuracy
     */
    public static final BigDecimal COORDINATE_PRECISION = new BigDecimal("0.000001");

    /**
     * Coordinate factor
     */
    public static final BigDecimal COORDINATE_FACTOR = new BigDecimal("1000000");

    /**
     * One decimal place precision
     */
    public static final BigDecimal ONE_PRECISION = new BigDecimal("0.1");

    private NumberUtil() {
    }

    /**
     * Format message ID (convert to 0xXXXX)
     *
     * @param msgId Message ID
     * @return format string
     */
    public static String formatMessageId(int msgId) {
        return String.format("0x%04x", msgId);
    }

    /**
     * format short numbers
     *
     * @param num number
     * @return format string
     */
    public static String formatShortNum(int num) {
        return String.format("0x%02x", num);
    }

    /**
     * Convert 4-digit hexadecimal string
     *
     * @param num digits
     * @return format string
     */
    public static String hexStr(int num) {
        return String.format("%04x", num).toUpperCase();
    }

    /**
     * Parse the value of type short and get the number of digits whose value is 1
     *
     * @param number
     * @return
     */
    public static List<Integer> parseShortBits(int number) {
        List<Integer> bits = new ArrayList<>();
        for (int i = 0; i < 16; i++) {
            if (getBitValue(number, i) == 1) {
                bits.add(i);
            }
        }
        return bits;
    }

    /**
     * Parse the value of type int and get the number of digits whose value is 1
     *
     * @param number
     * @return
     */
    public static List<Integer> parseIntegerBits(long number) {
        List<Integer> bits = new ArrayList<>();
        for (int i = 0; i < 32; i++) {
            if (getBitValue(number, i) == 1) {
                bits.add(i);
            }
        }
        return bits;
    }

    /**
     * Get the value of the index-th bit in binary
     *
     * @param number
     * @param index
     * @return
     */
    public static int getBitValue(long number, int index) {
        return (number & (1 << index)) > 0 ? 1 : 0;
    }

    /**
     * bit list to int
     *
     * @param bits
     * @param len
     * @return
     */
    public static int bitsToInt(List<Integer> bits, int len) {
        if (bits == null || bits.isEmpty()) {
            return 0;
        }

        char[] chars = new char[len];
        for (int i = 0; i < len; i++) {
            char value = bits.contains(i) ? '1' : '0';
            chars[len - 1 - i] = value;
        }
        int result = Integer.parseInt(new String(chars), 2);
        return result;
    }

    /**
     * bit list to long
     *
     * @param bits
     * @param len
     * @return
     */
    public static long bitsToLong(List<Integer> bits, int len) {
        if (bits == null || bits.isEmpty()) {
            return 0L;
        }

        char[] chars = new char[len];
        for (int i = 0; i < len; i++) {
            char value = bits.contains(i) ? '1' : '0';
            chars[len - 1 - i] = value;
        }
        long result = Long.parseLong(new String(chars), 2);
        return result;
    }

    /**
     * BigDecimal Multiplication
     *
     * @param longNum
     * @param precision
     * @return
     */
    public static double multiply(long longNum, BigDecimal precision) {
        return new BigDecimal(String.valueOf(longNum)).multiply(precision).doubleValue();
    }

    /**
     * BigDecimal Multiplication
     *
     * @param longNum
     * @param precision
     * @return
     */
    public static double multiply(int longNum, BigDecimal precision) {
        return new BigDecimal(String.valueOf(longNum)).multiply(precision).doubleValue();
    }
}

CommonUtil:public method class

package com.jointech.sdk.jt704.utils;

import io.netty.buffer.ByteBuf;

import java.nio.ByteBuffer;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

/**
 * <p>Description: Used to store some public methods encountered in parsing</p>
 *
 * @author lenny
 * @version 1.0.1
 * @date 20210328
 */
public class CommonUtil {
    /**
     * remove last character from string
     * @param inStr input string
     * @param suffix characters to remove
     * @return
     */
    public static String trimEnd(String inStr, String suffix) {
        while(inStr.endsWith(suffix)){
            inStr = inStr.substring(0,inStr.length()-suffix.length());
        }
        return inStr;
    }

    /**
     * Hexadecimal to 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();
    }

    /**
     *Convert GPS time
     *
     * @param bcdTimeStr
     * @return
     */
    public static ZonedDateTime parseBcdTime(String bcdTimeStr) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmmss");
        LocalDateTime localDateTime = LocalDateTime.parse(bcdTimeStr, formatter);
        ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneOffset.UTC);
        return zonedDateTime;
    }

    /**
     * XOR evaluation of each byte
     *
     * @param buf
     * @return
     */
    public static int xor(ByteBuf buf) {
        int checksum = 0;
        while (buf.readableBytes() > 0) {
            checksum ^= buf.readUnsignedByte();
        }
        return checksum;
    }
}

LocationData:Location entity class

package com.jointech.sdk.jt704.model;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;

import java.io.Serializable;

/**
 * <p>Description: Location entity class</p>
 *
 * @author lenny
 * @version 1.0.1
 * @date 20210328
 */
@Data
public class LocationData implements Serializable {
    /**
     * Messagebody
     */
    @JSONField(name = "DataLength")
    public int DataLength;
    /**
     * positioning time
     */
    @JSONField(name = "GpsTime")
    public String GpsTime;
    /**
     * Latitude
     */
    @JSONField(name = "Latitude")
    public double Latitude;
    /**
     * Longitude
     */
    @JSONField(name = "Longitude")
    public double Longitude;
    /**
     * Positioning type
     */
    @JSONField(name = "LocationType")
    public int LocationType;
    /**
     * Speed
     */
    @JSONField(name = "Speed")
    public int Speed;
    /**
     * Direction
     */
    @JSONField(name = "Direction")
    public int Direction;
    /**
     * Mileage
     */
    @JSONField(name = "Mileage")
    public long Mileage;
    /**
     * GpsSignal
     */
    @JSONField(name = "GpsSignal")
    public int GpsSignal;
    /**
     * GSMSignal
     */
    @JSONField(name = "GSMSignal")
    public int GSMSignal;
    /**
     * Battery
     */
    @JSONField(name = "Battery")
    public int Battery;
    /**
     * Voltage
     */
    @JSONField(name = "Voltage")
    public double Voltage;
    /**
     * BackCover status
     */
    @JSONField(name = "BackCover")
    public int BackCover;
    /**
     * MCC
     */
    @JSONField(name = "MCC")
    public int MCC;
    /**
     * MNC
     */
    @JSONField(name = "MNC")
    public int MNC;
    /**
     * LAC
     */
    @JSONField(name = "LAC")
    public int LAC;
    /**
     * CELLID
     */
    @JSONField(name = "CELLID")
    public long CELLID;
    /**
     * Awaken
     */
    @JSONField(name = "Awaken")
    public int Awaken;
    /**
     * Alarm type
     */
    @JSONField(name = "Alarm")
    public int Alarm = -1;
    /**
     * Data serial number
     */
    @JSONField(name = "Index")
    public int Index;
    /**
     * Temperature
     */
    @JSONField(name = "Temperature")
    public int Temperature=-1000;
}

Result:result entity class

package com.jointech.sdk.jt704.model;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;

import java.io.Serializable;

/**
 * result entity class
 * @author HyoJung
 * @date 20210526
 */
@Data
public class Result implements Serializable {
    @JSONField(name = "DeviceID")
    private String DeviceID;
    @JSONField(name = "MsgType")
    private String MsgType;
    @JSONField(name = "DataBody")
    private Object DataBody;
    @JSONField(name = "ReplyMsg")
    private String ReplyMsg;
}

AlarmTypeEnum:Terminal alarm type enumeration

package com.jointech.sdk.jt704.model;

import com.jointech.sdk.jt704.base.BaseEnum;
import lombok.Getter;

/**
 * Terminal alarm type
 * @author HyoJung
 */
public enum AlarmTypeEnum implements BaseEnum<String> {

    ALARM_1("Main unit disassembly alarm", "1");

    @Getter
    private String desc;

    private String value;

    AlarmTypeEnum(String desc, String value) {
        this.desc = desc;
        this.value = value;
    }

    @Override
    public String getValue() {
        return value;
    }

    public static AlarmTypeEnum fromValue(Integer value) {
        String valueStr = String.valueOf(value);
        for (AlarmTypeEnum alarmTypeEnum : values()) {
            if (alarmTypeEnum.getValue().equals(valueStr)) {
                return alarmTypeEnum;
            }
        }
        return null;
    }
}

2.4.Return message and description

(1)Heartbeat data
Raw data:

7E000200007501804283100001267E

return message:

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

Return message description

{"DeviceID":DeviceID,"MsgType":messagetype(heartbeat:heartbeat)}

(2)positioning data
Rawdata:

7E0200003B7501809250040102000000000004000201588F0F06CA3C52002700000000181106123212D4015AD502015C30011431010CFD0901CC00000010922866EF014A0F0201406E7E

Return content:

{
    "DeviceID": "750180925004",
    "DataBody": {
        "Speed": 0,
        "GpsTime": "2018-11-06T12:32:12Z",
        "Temperature": 32,
        "MNC": 0,
        "Mileage": 0,
        "BackCover": 0,
        "Index": 258,
        "Latitude": 22.581007,
        "Awaken": 0,
        "MCC": 460,
        "Direction": 0,
        "Longitude": 113.91701,
        "LAC": 10342,
        "Alarm": -1,
        "Battery": 90,
        "GpsSignal": 12,
        "Voltage": 3.48,
        "DataLength": 59,
        "CELLID": 4242,
        "LocationType": 1,
        "GSMSignal": 20
    },
    "ReplyMsg": "7e800100057501809250040dbd0102020000077e",
    "MsgType": "Location"
}

Return message Description

{
    "DeviceID": DeviceID,
    "DataBody": {
        "Speed": Speed,
        "GpsTime": GPStime(UTC),
        "Temperature": Temperature,
        "MCC": MCC,
        "MNC": MNC,
        "LAC": LAC,
        "CELLID": CELLID,
        "Mileage": Mileage(km),
        "BackCover": BackCover(1:开;0:关),
        "Index": Data serial number,
        "Latitude": Latitude(WGS84),
        "Longitude": Longitude(WGS84),
        "Awaken": Wake-up source(0:RTC reporting 3:Back Cover openning reporting  4:Close Cover reporting),
        "Direction": Direction(0~360,0 means true north),
        "Alarm": Alarm type(1:Main unit disassembly alarm;-1:No alarm),
        "Battery": BattteryLevel(0~100%),
        "GpsSignal": number of satellites,
        "Voltage": Battery Voltage(unit:V),
        "DataLength": Data length,
        "LocationType": Positioning type(1:GPS positioning;0:No positioning),
        "GSMSignal": GSM signal strength
    },
    "ReplyMsg": Need to reply to the command of the device,
    "MsgType": Data type(Location:Position data)
}

(3)Command data parsing
Rawdata:

283730303136303831383030302c312c3030312c424153452c312c312c32303135303431385f473330302c302c4265694875616e2c3131333742303353494d3930304d36345f53545f4d4d532c38393836303034323139313133303237323534392c3031323230373030353632303933322c3436302c30302c343234332c3638373729

Return message:

{
    "DeviceID": "700160818000",
    "DataBody": "(700160818000,1,001,BASE,1,1,20150418_G300,0,BeiHuan,1137B03SIM900M64_ST_MMS,89860042191130272549,012207005620932,460,00,4243,6877)",
    "ReplyMsg": "",
    "MsgType": "BASE1"
}

Return message description

{
    "DeviceID": DeviceID,
    "DataBody": Message Content,
    "ReplyMsg": Reply to the device message (empty means no reply is required),
    "MsgType": command type
}
文档更新时间: 2022-11-15 17:04   作者:admin