jiangping
2025-02-14 e3067f58cce422bbd26a7729bf59f5f4f34a530f
jtt808初始化
已添加2个文件
已修改13个文件
374 ■■■■ 文件已修改
server/jtt808_parent/commons/src/main/java/org/yzh/commons/util/Byte2NumberUtils.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/commons/JT808.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/commons/transform/AttributeConverter.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/commons/transform/AttributeConverterYue.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/commons/transform/AttributeKey.java 75 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/commons/transform/attribute/Battery.java 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/t808/T0107.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/t808/T0200.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-protocol/src/test/java/org/yzh/Elucidator.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-protocol/src/test/java/org/yzh/protocol/JT808Beans.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-server/src/main/java/org/yzh/protocol/t808/T0200.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-server/src/main/java/org/yzh/web/endpoint/JT808Endpoint.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-server/src/main/java/org/yzh/web/endpoint/JTHandlerInterceptor.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-server/src/main/java/org/yzh/web/model/entity/DeviceDO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/jtt808-server/src/test/java/org/yzh/client/JTMessageAdapter.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/jtt808_parent/commons/src/main/java/org/yzh/commons/util/Byte2NumberUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
package org.yzh.commons.util;
import org.apache.commons.codec.binary.Hex;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigInteger;
import java.util.*;
/**
 * @author yezhihao
 * https://gitee.com/yezhihao/jt808-server
 */
public class Byte2NumberUtils {
    public static Integer bytesToInteger(byte[] bArray) {
        try {
            return  Integer.valueOf(Hex.encodeHexString(bArray),16) ;
        }catch (Exception e){
            return null;
        }
    }
}
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/commons/JT808.java
@@ -89,4 +89,5 @@
    int å¹³å°ä¸‹è¡Œæ¶ˆæ¯ä¿ç•™ = 0x8F00 - 0x8FFF;
    int åŽ‚å•†è‡ªå®šä¹‰ä¸Šè¡Œæ¶ˆæ¯ = 0xE000 - 0xEFFF;//2019 new
    int å•†è‡ªå®šä¹‰ä¸‹è¡Œæ¶ˆæ¯ = 0xF000 - 0xFFFF;//2019 new
    int ç»ˆç«¯æ ¡æ—¶è¯·æ±‚上行 = 0x0F01;//
}
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/commons/transform/AttributeConverter.java
@@ -49,7 +49,10 @@
                .addSchema(AttributeKey.AlarmTPMS, ProtostarUtil.getRuntimeSchema(AlarmTPMS.class, 0))
                .addSchema(AttributeKey.InstallErrorMsg, NumberSchema.DWORD_INT)
                .addSchema(AttributeKey.Battery, NumberSchema.BYTE_BYTE)
                .addSchema(AttributeKey.Battery, Battery.SCHEMA)
                .addSchema(AttributeKey.Battery0102, NumberSchema.DWORD_INT)
                .addSchema(AttributeKey.Battery0304, NumberSchema.DWORD_INT)
                .addSchema(AttributeKey.Battery0506, NumberSchema.DWORD_INT)
                .addSchema(AttributeKey.ExtendLength, NumberSchema.DWORD_INT)
                .addSchema(AttributeKey.CarDoorStatus, NumberSchema.DWORD_INT)
                .addSchema(AttributeKey.CarWindowStatus, NumberSchema.DWORD_INT)
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/commons/transform/AttributeConverterYue.java
@@ -38,6 +38,10 @@
                .addSchema(AttributeKey.DriverBehaviorAlarm, NumberSchema.WORD_INT)
                .addSchema(AttributeKey.Signal, NumberSchema.DWORD_INT)
                .addSchema(AttributeKey.Battery, Battery.SCHEMA)
                .addSchema(AttributeKey.Battery0102, NumberSchema.DWORD_INT)
                .addSchema(AttributeKey.Battery0304, NumberSchema.DWORD_INT)
                .addSchema(AttributeKey.Battery0506, NumberSchema.DWORD_INT)
                .addSchema(AttributeKey.IoState, NumberSchema.WORD_INT)
                .addSchema(AttributeKey.AnalogQuantity, NumberSchema.DWORD_INT)
                .addSchema(AttributeKey.SignalStrength, NumberSchema.BYTE_INT)
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/commons/transform/AttributeKey.java
@@ -6,42 +6,45 @@
 * https://gitee.com/yezhihao/jt808-server
 */
public interface AttributeKey {
    Long Mileage = 1L;                 // 0x01 é‡Œç¨‹,数据类型为DWORD,单位为1/10km,对应车上里程表读数
    Long Fuel = 2L;                    // 0x02 æ²¹é‡,数据类型为WORD,单位为1/10L,对应车上油量表读数
    Long Speed = 3L;                   // 0x03 è¡Œé©¶è®°å½•功能获取的速度,数据类型为WORD,单位为1/10km/h
    Long AlarmEventId = 4L;            // 0x04 éœ€è¦äººå·¥ç¡®è®¤æŠ¥è­¦äº‹ä»¶çš„ID,数据类型为WORD,从1开始计数
    Long TirePressure = 5L;            // 0x05 èƒŽåŽ‹,单位为Pa,标定轮子的顺序为从车头开始从左到右顺序排列,多余的字节为0xFF,表示无效数据
    Long CarriageTemperature = 6L;     // 0x06 è½¦åŽ¢æ¸©åº¦,单位为摄氏度,取值范围为-32767~+32767,最高位为1表示负数
    Long OverSpeedAlarm = 17L;         // 0x11 è¶…速报警附加信息见表28
    Long InOutAreaAlarm = 18L;         // 0x12 è¿›å‡ºåŒºåŸŸ/路线报警附加信息见表29
    Long RouteDriveTimeAlarm = 19L;    // 0x13 è·¯æ®µè¡Œé©¶æ—¶é—´ä¸è¶³/过长报警附加信息见表30
    Integer Mileage = 1;                 // 0x01 é‡Œç¨‹,数据类型为DWORD,单位为1/10km,对应车上里程表读数
    Integer Fuel = 2;                    // 0x02 æ²¹é‡,数据类型为WORD,单位为1/10L,对应车上油量表读数
    Integer Speed = 3;                   // 0x03 è¡Œé©¶è®°å½•功能获取的速度,数据类型为WORD,单位为1/10km/h
    Integer AlarmEventId = 4;            // 0x04 éœ€è¦äººå·¥ç¡®è®¤æŠ¥è­¦äº‹ä»¶çš„ID,数据类型为WORD,从1开始计数
    Integer TirePressure = 5;            // 0x05 èƒŽåŽ‹,单位为Pa,标定轮子的顺序为从车头开始从左到右顺序排列,多余的字节为0xFF,表示无效数据
    Integer CarriageTemperature = 6;     // 0x06 è½¦åŽ¢æ¸©åº¦,单位为摄氏度,取值范围为-32767~+32767,最高位为1表示负数
    Integer OverSpeedAlarm = 17;         // 0x11 è¶…速报警附加信息见表28
    Integer InOutAreaAlarm = 18;         // 0x12 è¿›å‡ºåŒºåŸŸ/路线报警附加信息见表29
    Integer RouteDriveTimeAlarm = 19;    // 0x13 è·¯æ®µè¡Œé©¶æ—¶é—´ä¸è¶³/过长报警附加信息见表30
    Long VideoRelatedAlarm = 20L;      // 0x14 è§†é¢‘相关报警,DWORD,按位设置,标志位定义见表14
    Long VideoMissingStatus = 21L;     // 0x15 è§†é¢‘信号丢失报警状态,DWORD,按位设置,bit0~bit31分别表示第1~32个逻辑通道,相应位为1则表示该逻辑通道发生视频信号丢失
    Long VideoObscuredStatus = 22L;    // 0x16 è§†é¢‘信号遮挡报警状态,DWORD,按位设置,bit0~bit31分别表示第1~32个逻辑通道,相应位为1则表示该逻辑通道发生视频信号遮挡
    Long StorageFailureStatus = 23L;   // 0x17 å­˜å‚¨å™¨æ•…障报警状态,WORD,按位设置.bit0~bit11分别表示第1~12个主存储器.bit12~bit15分别表示第1~4个灾备存储装置,相应位为1则表示该存储器发生故障
    Long DriverBehaviorAlarm = 24L;    // 0x18 å¼‚常驾驶行为报警详细描述,WORD,定义见表15
    Integer VideoRelatedAlarm = 20;      // 0x14 è§†é¢‘相关报警,DWORD,按位设置,标志位定义见表14
    Integer VideoMissingStatus = 21;     // 0x15 è§†é¢‘信号丢失报警状态,DWORD,按位设置,bit0~bit31分别表示第1~32个逻辑通道,相应位为1则表示该逻辑通道发生视频信号丢失
    Integer VideoObscuredStatus = 22;    // 0x16 è§†é¢‘信号遮挡报警状态,DWORD,按位设置,bit0~bit31分别表示第1~32个逻辑通道,相应位为1则表示该逻辑通道发生视频信号遮挡
    Integer StorageFailureStatus = 23;   // 0x17 å­˜å‚¨å™¨æ•…障报警状态,WORD,按位设置.bit0~bit11分别表示第1~12个主存储器.bit12~bit15分别表示第1~4个灾备存储装置,相应位为1则表示该存储器发生故障
    Integer DriverBehaviorAlarm = 24;    // 0x18 å¼‚常驾驶行为报警详细描述,WORD,定义见表15
    Long Signal = 37L;                 // 0x25 æ‰©å±•车辆信号状态位,参数项格式和定义见表31
    Long IoState = 42L;                // 0x2a I0状态位,参数项格式和定义见表32
    Long AnalogQuantity = 43L;         // 0x2b æ¨¡æ‹Ÿé‡,bit[0~15],AD0L;bit[l6~31],ADl
    Long SignalStrength = 48L;         // 0x30 æ•°æ®ç±»åž‹ä¸ºBYTE,无线通信网络信号强度
    Long GnssCount = 49L;              // 0x31 æ•°æ®ç±»åž‹ä¸ºBYTE,GNSS定位卫星数
    Long AlarmADAS = 100L;             // 0x64 é«˜çº§é©¾é©¶è¾…助系统报警
    Long AlarmDSM = 101L;              // 0x65 é©¾é©¶å‘˜çŠ¶æ€ç›‘æµ‹
    Long AlarmTPMS = 102L;             // 0x66 è½®èƒŽæ°”压监测系统
    Long AlarmBSD = 103L;              // 0x67 ç›²ç‚¹ç›‘测
    Long InstallErrorMsg = 241L;       // 0xF1 å®‰è£…异常信息,由厂家自定义(粤标)
    Long AlgorithmErrorMsg = 242L;     // 0xF2 ç®—法异常信息,由厂家自定义(粤标)
    Long Battery = 0Xe3L;     // 0Xe3 data={0x01,0x02,0x03,0x04,0x05,0x06} ç”µæ± ç”µé‡æ˜¯ 0x0102,电池电压是0x0304,充电电压是 0x0506,电压单位是0.001v,上传 1000表示 1v。
    Long ExtendLength = 0Xf3L;     // 0Xf3 n è¡¨ç¤ºåŽç»­æ‰©å±•数据总长度。为 OBD行车数据项定义。后续定义的数据项见表 8-32定义(注意该定义的数据项构成包括但不一定全有)。
    Long CarDoorStatus = 0xD0L;     // 0xD0 è½¦é—¨é”çŠ¶æ€ä½ï¼Œè§è¡¨ 8-24车门锁状态位
    Long CarWindowStatus = 0xD1L;     // 0xD1 è½¦çª—状态位,见表 8-25车窗状态位。
    Long SafetyBelt = 0xD2L;     // 0xD2安全带状态位,见表 8-26安全带状态位。
    Long CarAlermStatus = 0xD3L;     // 0xD3车辆警情状态位,见表 8-27车辆警情状态位。
    Long CarFaultStatus = 0xD4L;     // 0xD4车辆故障状态位,见表 8-28车辆故障状态位。 ã€‚
    Long CarGearStatus = 0xD5L;     // 0xD5车辆档位状态,见表 8-29车辆档位状态。
    Long CarTireStatus = 0xD6L;     // 0xD6车辆胎压状态。(每个车胎信息占用 5个字节)见表 8-30车辆胎压状态。
    Long Temprature = 0xC0L;     // 0xC0;有符号数,单位 0.1度。
    Long BaseStationExtend = 0xEFL;     // 0xEF åŸºç«™é™„加数据
    Integer Signal = 37;                 // 0x25 æ‰©å±•车辆信号状态位,参数项格式和定义见表31
    Integer IoState = 42;                // 0x2a I0状态位,参数项格式和定义见表32
    Integer AnalogQuantity = 43;         // 0x2b æ¨¡æ‹Ÿé‡,bit[0~15],AD0;bit[l6~31],ADl
    Integer SignalStrength = 48;         // 0x30 æ•°æ®ç±»åž‹ä¸ºBYTE,无线通信网络信号强度
    Integer GnssCount = 49;              // 0x31 æ•°æ®ç±»åž‹ä¸ºBYTE,GNSS定位卫星数
    Integer AlarmADAS = 100;             // 0x64 é«˜çº§é©¾é©¶è¾…助系统报警
    Integer AlarmDSM = 101;              // 0x65 é©¾é©¶å‘˜çŠ¶æ€ç›‘æµ‹
    Integer AlarmTPMS = 102;             // 0x66 è½®èƒŽæ°”压监测系统
    Integer AlarmBSD = 103;              // 0x67 ç›²ç‚¹ç›‘测
    Integer InstallErrorMsg = 241;       // 0xF1 å®‰è£…异常信息,由厂家自定义(粤标)
    Integer AlgorithmErrorMsg = 242;     // 0xF2 ç®—法异常信息,由厂家自定义(粤标)
    Integer Battery = 0Xe3;     // 0Xe3 data={0x01,0x02,0x03,0x04,0x05,0x06} ç”µæ± ç”µé‡æ˜¯ 0x0102,电池电压是0x0304,充电电压是 0x0506,电压单位是0.001v,上传 1000表示 1v。
    Integer Battery0102 = 0x0102;     // 0Xe3 data={0x01,0x02,0x03,0x04,0x05,0x06} ç”µæ± ç”µé‡æ˜¯ 0x0102,电池电压是0x0304,充电电压是 0x0506,电压单位是0.001v,上传 1000表示 1v。
    Integer Battery0304 = 0x0304;     // 0Xe3 data={0x01,0x02,0x03,0x04,0x05,0x06} ç”µæ± ç”µé‡æ˜¯ 0x0102,电池电压是0x0304,充电电压是 0x0506,电压单位是0.001v,上传 1000表示 1v。
    Integer Battery0506 = 0x0506;     // 0Xe3 data={0x01,0x02,0x03,0x04,0x05,0x06} ç”µæ± ç”µé‡æ˜¯ 0x0102,电池电压是0x0304,充电电压是 0x0506,电压单位是0.001v,上传 1000表示 1v。
    Integer ExtendLength = 0Xf3;     // 0Xf3 n è¡¨ç¤ºåŽç»­æ‰©å±•数据总长度。为 OBD行车数据项定义。后续定义的数据项见表 8-32定义(注意该定义的数据项构成包括但不一定全有)。
    Integer CarDoorStatus = 0xD0;     // 0xD0 è½¦é—¨é”çŠ¶æ€ä½ï¼Œè§è¡¨ 8-24车门锁状态位
    Integer CarWindowStatus = 0xD1;     // 0xD1 è½¦çª—状态位,见表 8-25车窗状态位。
    Integer SafetyBelt = 0xD2;     // 0xD2安全带状态位,见表 8-26安全带状态位。
    Integer CarAlermStatus = 0xD3;     // 0xD3车辆警情状态位,见表 8-27车辆警情状态位。
    Integer CarFaultStatus = 0xD4;     // 0xD4车辆故障状态位,见表 8-28车辆故障状态位。 ã€‚
    Integer CarGearStatus = 0xD5;     // 0xD5车辆档位状态,见表 8-29车辆档位状态。
    Integer CarTireStatus = 0xD6;     // 0xD6车辆胎压状态。(每个车胎信息占用 5个字节)见表 8-30车辆胎压状态。
    Integer Temprature = 0xC0;     // 0xC0;有符号数,单位 0.1度。
    Integer BaseStationExtend = 0xEF;     // 0xEF åŸºç«™é™„加数据
}
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/commons/transform/attribute/Battery.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,119 @@
package org.yzh.protocol.commons.transform.attribute;
import io.github.yezhihao.protostar.Schema;
import io.github.yezhihao.protostar.util.ByteBufUtils;
import io.netty.buffer.ByteBuf;
import org.yzh.commons.util.Byte2NumberUtils;
import java.util.Arrays;
/**
 * èƒŽåŽ‹ 0x05
 * length 30
 */
public class Battery {
    public static final Integer key = 0Xe3;
    public static final Schema<Battery> SCHEMA = new TirePressureSchema();
    private byte[] value;
    private Integer capacity;//电池电量
    private Float voltage;//电池电压
    private Float chargeVoltage;//充电电压
    public Integer getCapacity() {
        return capacity;
    }
    public void setCapacity(Integer capacity) {
        this.capacity = capacity;
    }
    public Float getVoltage() {
        return voltage;
    }
    public void setVoltage(Float voltage) {
        this.voltage = voltage;
    }
    public Float getChargeVoltage() {
        return chargeVoltage;
    }
    public void setChargeVoltage(Float chargeVoltage) {
        this.chargeVoltage = chargeVoltage;
    }
    public Battery() {
    }
    /**
     * byte[] data={0x01,0x02,0x03,0x04,0x05,0x06}
     * ç”µæ± ç”µé‡æ˜¯ 0x0102,
     * ç”µæ± ç”µåŽ‹æ˜¯0x0304,
     * å……电电压是 0x0506,
     * ç”µåŽ‹å•ä½æ˜¯0.001v,
     * ä¸Šä¼  1000表示 1v。
     * @param value
     */
    public Battery(byte[] value) {
        this.value = value;
        if(value!=null && value.length>2){
            this.setCapacity(Byte2NumberUtils.bytesToInteger(new byte[]{value[0],value[1]}));
        }
        if(value!=null && value.length>4){
            try {
                this.setVoltage((float) (Byte2NumberUtils.bytesToInteger(new byte[]{value[2],value[3]}) * 0.001));
            }catch (Exception e){
            }
        }
        if(value!=null && value.length>6){
            try {
                this.setChargeVoltage((float) (Byte2NumberUtils.bytesToInteger(new byte[]{value[4],value[4]}) * 0.001));
            }catch (Exception e){
            }
        }
    }
    public byte[] getValue() {
        return value;
    }
    public void setValue(byte[] value) {
        this.value = value;
    }
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder(32);
        sb.append("Battery{value=").append(Arrays.toString(value));
        sb.append('}');
        return sb.toString();
    }
    private static class TirePressureSchema implements Schema<Battery> {
        private TirePressureSchema() {
        }
        @Override
        public Battery readFrom(ByteBuf input) {
            int len = input.readableBytes();
            if (len > 30)
                len = 30;
            byte[] value = new byte[len];
            input.readBytes(value);
            return new Battery(value);
        }
        @Override
        public void writeTo(ByteBuf output, Battery message) {
            ByteBufUtils.writeFixedLength(output, 30, message.value);
        }
    }
}
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/t808/T0107.java
@@ -2,6 +2,7 @@
import io.github.yezhihao.netmc.core.model.Response;
import io.github.yezhihao.protostar.annotation.Field;
import io.github.yezhihao.protostar.annotation.MergeSuperclass;
import io.github.yezhihao.protostar.annotation.Message;
import org.yzh.protocol.basics.JTMessage;
import org.yzh.protocol.commons.JT808;
@@ -10,6 +11,7 @@
 * @author yezhihao
 * https://gitee.com/yezhihao/jt808-server
 */
@MergeSuperclass
@Message(JT808.查询终端属性应答)
public class T0107 extends JTMessage implements Response {
server/jtt808_parent/jtt808-protocol/src/main/java/org/yzh/protocol/t808/T0200.java
@@ -2,6 +2,8 @@
import io.github.yezhihao.protostar.annotation.Field;
import io.github.yezhihao.protostar.annotation.Message;
import io.swagger.models.auth.In;
import lombok.Data;
import org.yzh.protocol.basics.JTMessage;
import org.yzh.protocol.commons.JT808;
import org.yzh.protocol.commons.transform.AttributeConverter;
@@ -15,6 +17,7 @@
 * https://gitee.com/yezhihao/jt808-server
 */
@Message(JT808.位置信息汇报)
@Data
public class T0200 extends JTMessage {
    /**
@@ -39,7 +42,7 @@
    private LocalDateTime deviceTime;
    @Field(converter = AttributeConverter.class, desc = "位置附加信息", version = {-1, 0})
    @Field(converter = AttributeConverterYue.class, desc = "位置附加信息(粤标)", version = 1)
    private Map<Long, Object> attributes;
    private Map<Integer, Object> attributes;
    public int getWarnBit() {
        return warnBit;
@@ -105,13 +108,7 @@
        this.deviceTime = deviceTime;
    }
    public Map<Long, Object> getAttributes() {
        return attributes;
    }
    public void setAttributes(Map<Long, Object> attributes) {
        this.attributes = attributes;
    }
    @Override
    public String toString() {
server/jtt808_parent/jtt808-protocol/src/test/java/org/yzh/Elucidator.java
@@ -4,9 +4,20 @@
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.platform.commons.util.StringUtils;
import org.yzh.protocol.JT808Beans;
import org.yzh.protocol.basics.JTMessage;
import org.yzh.protocol.codec.JTMessageAdapter;
import org.yzh.protocol.codec.JTMessageDecoder;
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
/**
 * è§£ç åˆ†æž
@@ -18,12 +29,37 @@
    public static final JTMessageAdapter coder = new JTMessageAdapter("org.yzh.protocol");
    public static void main(String[] args) {
        String hex = "0200004c067244400211004600000000000c0400015b197c06c8362e00000000000025020610234801040000083f02020000030200002504000000002a0200002b0400000000300117310100e3060000129d0000f2020000497e";
        String hex = "0200004c06724440021104ad00000000000c000301e4c49606fcbc04003c00000000250213220412010400001a4e02020000030200002504000000002a0200002b0400000000300115310112e306000012990000f2020000ac7e";
//        String hex = "0201004e0672444002110097019100000000000c0001015b197c06c8362e00000000000025020616592601040000083f02020000030200002504000000002a0200002b0400000000300117310100e306000012990000f2020000187e";
//        String hex = "020000d40123456789017fff000004000000080006eeb6ad02633df7013800030063200707192359642f000000400101020a0a02010a1e00640001b2070003640e200707192359000100000061646173200827111111010101652f000000410202020a0000000a1e00c8000516150006c81c20070719235900020000000064736d200827111111020202662900000042031e012c00087a23000a2c2a200707192359000300000074706d732008271111110303030067290000004304041e0190000bde31000d90382007071923590004000000006273642008271111110404049d";
        JTMessage msg = H2019(T0200JSATL12());
//        JTMessage msg = H2019(T0200JSATL12());
        msg = decode(hex);
//        msg = decode(hex);
//        hex = encode(msg);
//        System.out.println(decode(hex));
        try (FileInputStream fis = new FileInputStream(new File("C:\\Users\\T14\\Desktop\\member.xlsx"));
             Workbook workbook = new XSSFWorkbook(fis)) {
            Sheet sheet = workbook.getSheetAt(0); // èŽ·å–ç¬¬ä¸€ä¸ªå·¥ä½œè¡¨
            List<String> phoneNumbers = new ArrayList<>();
            for (Row row : sheet) {
                Cell cell = row.getCell(1); // å‡è®¾æ‰‹æœºå·åœ¨ç¬¬ä¸€åˆ—
                if (cell != null) {
                    if (cell.getCellType() == CellType.NUMERIC){
                        System.out.println(cell.getCellType());
                        phoneNumbers.add( cell.getNumericCellValue()+""); // æ·»åŠ åˆ°åˆ—è¡¨ä¸­
                    }
                    cell.setCellType(CellType.STRING); // ç¡®ä¿å•元格类型为字符串
                    String phoneNumber = cell.getStringCellValue(); // èŽ·å–å•å…ƒæ ¼å€¼ä½œä¸ºå­—ç¬¦ä¸²
                    phoneNumbers.add(  phoneNumber); // æ·»åŠ åˆ°åˆ—è¡¨ä¸­
                }
            }
            // è¾“出手机号列表
            phoneNumbers.forEach(System.out::println);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static String encode(JTMessage message) {
server/jtt808_parent/jtt808-protocol/src/test/java/org/yzh/protocol/JT808Beans.java
@@ -2,6 +2,7 @@
import io.github.yezhihao.protostar.util.KeyValuePair;
import io.netty.buffer.Unpooled;
import io.swagger.models.auth.In;
import org.yzh.protocol.basics.JTMessage;
import org.yzh.protocol.commons.Action;
import org.yzh.protocol.commons.ShapeAction;
@@ -193,7 +194,7 @@
    //位置信息汇报
    public static T0200 T0200Attributes() {
        T0200 bean = T0200();
        Map<Long, Object> attributes = new TreeMap<>();
        Map<Integer, Object> attributes = new TreeMap<>();
        attributes.put(AttributeKey.Mileage, 11);
        attributes.put(AttributeKey.Fuel, 22);
        attributes.put(AttributeKey.Speed, 33);
@@ -290,11 +291,11 @@
        T0200 bean = T0200();
        Map<Long, Object> attributes = new TreeMap<>();
        attributes.put(Long.valueOf(AlarmADAS.key), alarmADAS);
        attributes.put(Long.valueOf(AlarmDSM.key), alarmDSM);
        attributes.put(Long.valueOf(AlarmTPMS.key), alarmTPMS);
        attributes.put(Long.valueOf(AlarmBSD.key), alarmBSD);
        Map<Integer, Object> attributes = new TreeMap<>();
        attributes.put( AlarmADAS.key, alarmADAS);
        attributes.put( AlarmDSM.key, alarmDSM);
        attributes.put( AlarmTPMS.key, alarmTPMS);
        attributes.put( AlarmBSD.key, alarmBSD);
        bean.setAttributes(attributes);
        return bean;
server/jtt808_parent/jtt808-server/src/main/java/org/yzh/protocol/t808/T0200.java
@@ -3,6 +3,7 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.github.yezhihao.protostar.annotation.Field;
import io.github.yezhihao.protostar.annotation.Message;
import lombok.Data;
import org.yzh.protocol.basics.JTMessage;
import org.yzh.protocol.commons.JT808;
import org.yzh.protocol.commons.transform.AttributeConverter;
@@ -15,8 +16,22 @@
 * @author yezhihao
 * https://gitee.com/yezhihao/jt808-server
 */
@JsonIgnoreProperties({"attributes", "alarmList", "dateTime", "messageId", "properties", "protocolVersion", "clientId", "serialNo", "packageTotal", "packageNo", "verified", "bodyLength", "encryption", "subpackage", "version", "reserved"})
@JsonIgnoreProperties({"attributes",
        "alarmList",
        "dateTime",
        "messageId",
        "properties",
        "protocolVersion",
        "clientId", "serialNo",
        "packageTotal", "packageNo",
        "verified",
        "bodyLength",
        "encryption",
        "subpackage",
        "version",
        "reserved"})
@Message(JT808.位置信息汇报)
@Data
public class T0200 extends JTMessage {
    @Field(length = 4, desc = "报警标志")
@@ -39,7 +54,7 @@
    private LocalDateTime deviceTime;
    @Field(converter = AttributeConverter.class, desc = "位置附加信息", version = {-1, 0})
    @Field(converter = AttributeConverterYue.class, desc = "位置附加信息(粤标)", version = 1)
    private Map<Long, Object> attributes;
    private Map<Integer, Object> attributes;
    public int getWarnBit() {
        return warnBit;
@@ -105,13 +120,6 @@
        this.deviceTime = deviceTime;
    }
    public Map<Long, Object> getAttributes() {
        return attributes;
    }
    public void setAttributes(Map<Long, Object> attributes) {
        this.attributes = attributes;
    }
    public int getAttributeInt(int key) {
        if (attributes != null) {
server/jtt808_parent/jtt808-server/src/main/java/org/yzh/web/endpoint/JT808Endpoint.java
@@ -1,10 +1,12 @@
package org.yzh.web.endpoint;
import com.alibaba.fastjson.JSONObject;
import io.github.yezhihao.netmc.core.annotation.Async;
import io.github.yezhihao.netmc.core.annotation.AsyncBatch;
import io.github.yezhihao.netmc.core.annotation.Endpoint;
import io.github.yezhihao.netmc.core.annotation.Mapping;
import io.github.yezhihao.netmc.session.Session;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -16,9 +18,14 @@
import org.yzh.web.model.enums.SessionKey;
import org.yzh.web.service.FileService;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import static org.yzh.protocol.commons.JT808.*;
@@ -39,6 +46,7 @@
    @Mapping(types = ç»ˆç«¯å¿ƒè·³, desc = "终端心跳")
    public void T0002(JTMessage message, Session session) {
        log.info("终端心跳========={}", JSONObject.toJSONString(message));
    }
    @Mapping(types = ç»ˆç«¯æ³¨é”€, desc = "终端注销")
@@ -54,6 +62,9 @@
    @Mapping(types = ç»ˆç«¯è¡¥ä¼ åˆ†åŒ…请求, desc = "终端补传分包请求")
    public void T8003(T8003 message, Session session) {
    }
    @Mapping(types = ç»ˆç«¯æ ¡æ—¶è¯·æ±‚上行, desc = "终端校时请求上行")
    public void T0F01(JTMessage message, Session session) {
    }
    @Mapping(types = ç»ˆç«¯æ³¨å†Œ, desc = "终端注册")
@@ -99,6 +110,7 @@
    @Mapping(types = æŸ¥è¯¢ç»ˆç«¯å±žæ€§åº”ç­”, desc = "查询终端属性应答")
    public void T0107(T0107 message, Session session) {
        log.info("查询终端属性应答========={}", JSONObject.toJSONString(message));
        session.response(message);
    }
@@ -115,11 +127,24 @@
    @AsyncBatch(poolSize = 2, maxElements = 4000, maxWait = 1000)
    @Mapping(types = ä½ç½®ä¿¡æ¯æ±‡æŠ¥, desc = "位置信息汇报")
    public void T0200(List<T0200> list) {
        System.out.println(JSONObject.toJSONString(list)
      );
    }
    @Mapping(types = å®šä½æ•°æ®æ‰¹é‡ä¸Šä¼ , desc = "定位数据批量上传")
    public void T0704(T0704 message) {
    }
    public static String bcd2String(byte[] bytes) {
        StringBuilder temp = new StringBuilder(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            // é«˜å››ä½
            temp.append((bytes[i] & 0xf0) >>> 4);
            // ä½Žå››ä½
            temp.append(bytes[i] & 0x0f);
        }
        return temp.toString().substring(0, 1).equalsIgnoreCase("0") ? temp.toString().substring(1) : temp.toString();
    }
    @Mapping(types = {位置信息查询应答, è½¦è¾†æŽ§åˆ¶åº”ç­”}, desc = "位置信息查询应答/车辆控制应答")
    public void T0201_0500(T0201_0500 message, Session session) {
server/jtt808_parent/jtt808-server/src/main/java/org/yzh/web/endpoint/JTHandlerInterceptor.java
@@ -1,15 +1,24 @@
package org.yzh.web.endpoint;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.github.yezhihao.netmc.core.HandlerInterceptor;
import io.github.yezhihao.netmc.session.Session;
import netscape.javascript.JSObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yzh.commons.util.Byte2NumberUtils;
import org.yzh.protocol.basics.JTMessage;
import org.yzh.protocol.commons.JT808;
import org.yzh.protocol.commons.transform.AttributeKey;
import org.yzh.protocol.commons.transform.attribute.Battery;
import org.yzh.protocol.t808.T0001;
import org.yzh.protocol.t808.T0200;
import org.yzh.web.model.entity.DeviceDO;
import org.yzh.web.model.enums.SessionKey;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class JTHandlerInterceptor implements HandlerInterceptor<JTMessage> {
@@ -73,8 +82,16 @@
        boolean transform = request.transform();
        if (messageId == JT808.位置信息汇报) {
            DeviceDO device = SessionKey.getDevice(session);
            if (device != null)
            if (device != null){
                device.setLocation((T0200) request);
                if(device.getLocation()!=null && device.getLocation().getAttributes()!=null ){
                   Battery battery= (Battery) device.getLocation().getAttributes().get(AttributeKey.Battery);
                    if(battery !=null){
                        device.setBatteryVoltage(battery.getVoltage());
                    }
                }
            }
            return transform;
        }
        if (!session.isRegistered()) {
server/jtt808_parent/jtt808-server/src/main/java/org/yzh/web/model/entity/DeviceDO.java
@@ -1,10 +1,12 @@
package org.yzh.web.model.entity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.yzh.protocol.t808.T0200;
import java.util.Objects;
@Data
public class DeviceDO {
    @Schema(description = "设备id")
@@ -19,6 +21,8 @@
    protected int driverId;
    @Schema(description = "协议版本号")
    private int protocolVersion;
    @Schema(description = "电池电压")
    private Float batteryVoltage;
    @Schema(description = "实时状态")
    private T0200 location;
server/jtt808_parent/jtt808-server/src/test/java/org/yzh/client/JTMessageAdapter.java
@@ -8,6 +8,9 @@
import org.yzh.protocol.codec.JTMessageDecoder;
import org.yzh.protocol.codec.JTMessageEncoder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
 * JT消息编解码适配器
 * @author yezhihao
@@ -34,4 +37,7 @@
        JTMessage message = messageDecoder.decode(input);
        return message;
    }
    public static void main(String[] args) {
    }
}