‘liusuyi’
2023-07-03 fbb9b4374821b43d0b85aa569977415fd8d77cd9
增加雷达抽油机停机推送mqtt
已添加3个文件
已修改7个文件
已删除1个文件
929 ■■■■■ 文件已修改
src/main/java/com/ard/hiksdk/service/impl/FMSGCallBack.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/util/DateUtils.java 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/ByteUtils.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/DateUtils.java 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/GisUtils.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/LonlatConver.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/SpringTool.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/mqtt/MqttConsumer.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/tcp/MessageParsing.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java 282 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/hiksdk/service/impl/FMSGCallBack.java
@@ -7,9 +7,9 @@
import com.ard.config.MinioClientSingleton;
import com.ard.hiksdk.common.GlobalVariable;
import com.ard.hiksdk.domain.alarmEventInfo;
import com.ard.hiksdk.util.DateUtils;
import com.ard.hiksdk.util.hikSdkUtil.HCNetSDK;
import com.ard.hiksdk.util.minio.MinioUtils;
import com.ard.utils.DateUtils;
import com.ard.utils.SpringTool;
import com.ard.utils.mqtt.MqttConsumer;
import com.sun.jna.Pointer;
src/main/java/com/ard/hiksdk/util/DateUtils.java
ÎļþÒÑɾ³ý
src/main/java/com/ard/utils/ByteUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,82 @@
package com.ard.utils;
import javax.xml.bind.DatatypeConverter;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * @Description: å­—节工具类
 * @ClassName: byteUtils
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´07月03日15:18
 * @Version: 1.0
 **/
public class ByteUtils {
    /**
     * Byte字节转Hex
     * @param b å­—节
     * @return Hex
     */
    public static String byteToHex(byte b)
    {
        String hexString = Integer.toHexString(b & 0xFF);
        //由于十六进制是由0~9、A~F来表示1~16,所以如果Byte转换成Hex后如果是<16,就会是一个字符(比如A=10),通常是使用两个字符来表示16进制位的,
        //假如一个字符的话,遇到字符串11,这到底是1个字节,还是1和1两个字节,容易混淆,如果是补0,那么1和1补充后就是0101,11就表示纯粹的11
        if (hexString.length() < 2)
        {
            hexString = new StringBuilder(String.valueOf(0)).append(hexString).toString();
        }
        return hexString.toUpperCase();
    }
    /**
     * byte数组转float
     */
    public static float bytesToFloat(byte[] bytes) {
        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        return buffer.getFloat();
    }
    /**
     * byte数组转整型
     */
    public static int bytesToDecimal(byte[] byteArray) {
        int decimalValue = 0;
        for (int i = 0; i < byteArray.length; i++) {
            decimalValue = (decimalValue << 8) | (byteArray[i] & 0xFF);
        }
        return decimalValue;
    }
    /**
     * byte数组转Double
     */
    public static double bytesToDouble(byte[] byteArray) {
        long longBits = 0;
        // æ ¹æ®å­—节数组的长度和字节顺序,将字节数组转换为长整型
        for (int i = 0; i < byteArray.length; i++) {
            longBits |= (long) (byteArray[i] & 0xFF) << (8 * (byteArray.length - 1 - i));
        }
        // ä½¿ç”¨Double.longBitsToDouble方法将长整型转换为Double类型
        return Double.longBitsToDouble(longBits);
    }
    /**
     * å¤§ç«¯è½¬å°ç«¯
     */
    public static byte[] toLittleEndian(byte[] bigEndianBytes) {
        byte[] littleEndianBytes = new byte[bigEndianBytes.length];
        for (int i = 0; i < bigEndianBytes.length; i++) {
            int j = bigEndianBytes.length - i - 1;
            littleEndianBytes[i] = bigEndianBytes[j];
        }
        return littleEndianBytes;
    }
}
src/main/java/com/ard/utils/DateUtils.java
@@ -1,16 +1,201 @@
package com.ard.utils;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.time.LocalDateTime;
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Date;
/**
 * @Description: æ—¶é—´å¤„理工具
 * @ClassName: DateUtils
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´06月06日10:04
 * @Version: 1.0
 **/
public class DateUtils {
 * @ClassName DateUtils
 * @Description: è¿™æ˜¯ä¸€ä¸ªæ—¶é—´å·¥å…·ç±»
 * @Author åˆ˜è‹ä¹‰
 * @Date 2023/2/16 21:58
 * @Version 1.0
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{
    public static String YYYY = "yyyy";
    public static String YYYY_MM = "yyyy-MM";
    public static String YYYY_MM_DD = "yyyy-MM-dd";
    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
    /**
     * èŽ·å–å½“å‰Date型日期
     *
     * @return Date() å½“前日期
     */
    public static Date getNowDate()
    {
        return new Date();
    }
    /**
     * èŽ·å–å½“å‰æ—¥æœŸ, é»˜è®¤æ ¼å¼ä¸ºyyyy-MM-dd
     *
     * @return String
     */
    public static String getDate()
    {
        return dateTimeNow(YYYY_MM_DD);
    }
    public static final String getTime()
    {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }
    public static final String dateTimeNow()
    {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }
    public static final String dateTimeNow(final String format)
    {
        return parseDateToStr(format, new Date());
    }
    public static final String dateTime(final Date date)
    {
        return parseDateToStr(YYYY_MM_DD, date);
    }
    public static final String parseDateToStr(final String format, final Date date)
    {
        return new SimpleDateFormat(format).format(date);
    }
    public static final Date dateTime(final String format, final String ts)
    {
        try
        {
            return new SimpleDateFormat(format).parse(ts);
        }
        catch (ParseException e)
        {
            throw new RuntimeException(e);
        }
    }
    /**
     * æ—¥æœŸè·¯å¾„ å³å¹´/月/日 å¦‚2018/08/08
     */
    public static final String datePath()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }
    /**
     * æ—¥æœŸè·¯å¾„ å³å¹´/月/日 å¦‚20180808
     */
    public static final String dateTime()
    {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }
    /**
     * æ—¥æœŸåž‹å­—符串转化为日期 æ ¼å¼
     */
    public static Date parseDate(Object str)
    {
        if (str == null)
        {
            return null;
        }
        try
        {
            return parseDate(str.toString(), parsePatterns);
        }
        catch (ParseException e)
        {
            return null;
        }
    }
    /**
     * èŽ·å–æœåŠ¡å™¨å¯åŠ¨æ—¶é—´
     */
    public static Date getServerStartDate()
    {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }
    /**
     * è®¡ç®—相差天数
     */
    public static int differentDaysByMillisecond(Date date1, Date date2)
    {
        return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
    }
    /**
     * è®¡ç®—两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate)
    {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // èŽ·å¾—ä¸¤ä¸ªæ—¶é—´çš„æ¯«ç§’æ—¶é—´å·®å¼‚
        long diff = endDate.getTime() - nowDate.getTime();
        // è®¡ç®—差多少天
        long day = diff / nd;
        // è®¡ç®—差多少小时
        long hour = diff % nd / nh;
        // è®¡ç®—差多少分钟
        long min = diff % nd % nh / nm;
        // è®¡ç®—差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }
    /**
     * å¢žåŠ  LocalDateTime ==> Date
     */
    public static Date toDate(LocalDateTime temporalAccessor)
    {
        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }
    /**
     * å¢žåŠ  LocalDate ==> Date
     */
    public static Date toDate(LocalDate temporalAccessor)
    {
        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }
    //SDK时间解析
    public static String parseTime(int time)
    {
        int year=(time>>26)+2000;
        int month=(time>>22)&15;
        int day=(time>>17)&31;
        int hour=(time>>12)&31;
        int min=(time>>6)&63;
        int second=(time>>0)&63;
        String sTime=String.format("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, min, second);
        return sTime;
    }
    /**
     * æ—¥æœŸå­—符串的月日时分秒自动补零,并将/替换成-
src/main/java/com/ard/utils/GisUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.ard.utils;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GlobalCoordinates;
/**
 * @Description: gis工具类
 * @ClassName: GisUtils
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´07月03日15:23
 * @Version: 1.0
 **/
public class GisUtils {
    /**
     * é€šè¿‡A点坐标,长度和Y轴角度计算B点坐标
     */
    public static Double[] CalculateCoordinates(Double[] radarCoordinates, Double distance, Double angle) {
        double[] to_wgs84 = LonlatConver.gcj02_To_Wgs84(radarCoordinates[0], radarCoordinates[1]);
        double Ax = to_wgs84[0]; // A ç‚¹çš„ X åæ ‡
        double Ay = to_wgs84[1]; // A ç‚¹çš„ Y åæ ‡
        double AB = distance; // AB çš„长度
        double angleWithYAxisDegrees = angle; // AB ä¸Ž Y è½´çš„角度(以度数表示)
        GeodeticCalculator calculator = new GeodeticCalculator();
        GlobalCoordinates globalCoordinates = new GlobalCoordinates(Ay, Ax);
        GlobalCoordinates globalCoordinates1 = calculator.calculateEndingGlobalCoordinates(Ellipsoid.WGS84, globalCoordinates, angleWithYAxisDegrees, AB);
        return new Double[]{globalCoordinates1.getLongitude(), globalCoordinates1.getLatitude()};
    }
}
src/main/java/com/ard/utils/LonlatConver.java
@@ -1,6 +1,11 @@
package com.ard.utils;
/**
 * ç»çº¬åº¦è½¬æ¢å·¥å…·
 * åˆ˜è‹ä¹‰
 * 2023/7/3 15:15
 */
public class LonlatConver {
    /**
     * a
     */
src/main/java/com/ard/utils/SpringTool.java
@@ -4,6 +4,9 @@
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.nio.ByteBuffer;
/**
 * @Description:
 * @ClassName: SpringTool
@@ -33,20 +36,4 @@
        return getApplicationContext().getBean(name);
    }
    /**
     * Byte字节转Hex
     * @param b å­—节
     * @return Hex
     */
    public static String byteToHex(byte b)
    {
        String hexString = Integer.toHexString(b & 0xFF);
        //由于十六进制是由0~9、A~F来表示1~16,所以如果Byte转换成Hex后如果是<16,就会是一个字符(比如A=10),通常是使用两个字符来表示16进制位的,
        //假如一个字符的话,遇到字符串11,这到底是1个字节,还是1和1两个字节,容易混淆,如果是补0,那么1和1补充后就是0101,11就表示纯粹的11
        if (hexString.length() < 2)
        {
            hexString = new StringBuilder(String.valueOf(0)).append(hexString).toString();
        }
        return hexString.toUpperCase();
    }
}
src/main/java/com/ard/utils/mqtt/MqttConsumer.java
@@ -75,7 +75,7 @@
        // è®¾ç½®ä¼šè¯å¿ƒè·³æ—¶é—´
        options.setKeepAliveInterval(PropertiesUtil.MQTT_KEEP_ALIVE);
        // æ˜¯å¦æ¸…除session
        options.setCleanSession(false);
        options.setCleanSession(true);
        log.info("--生成mqtt配置对象");
        return options;
    }
src/main/java/com/ard/utils/tcp/MessageParsing.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,96 @@
package com.ard.utils.tcp;
import javax.xml.bind.DatatypeConverter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * @Description: æŠ¥æ–‡è§£æž
 * @ClassName: MessageParsing
 * @Author: åˆ˜è‹ä¹‰
 * @Date: 2023å¹´07月03日15:30
 * @Version: 1.0
 **/
public class MessageParsing {
    // åˆ›å»ºç¼“冲区列表
    private static List<Byte> buffer = new ArrayList<>();
    /**
     * æŽ¥æ”¶å®Œæ•´åŒ…
     */
    public static byte[] receiveCompletePacket(byte[] receivedData) {
        // å®šä¹‰åŒ…尾字节序列
        byte[] packetEnd = {0x01, 0x02, 0x00};
        // æ·»åŠ å·²æŽ¥æ”¶çš„æ•°æ®åˆ°ç¼“å†²åŒº
        for (byte data : receivedData) {
            buffer.add(data);
        }
        // æ£€æŸ¥ç¼“冲区中的数据是否包含完整的包
        while (buffer.size() >= packetEnd.length) {
            int endIndex = findPacketEndIndex(buffer, packetEnd);
            if (endIndex != -1) {
                // æ‰¾åˆ°å®Œæ•´çš„包
                byte[] packet = extractPacketFromBuffer(buffer, endIndex + packetEnd.length);
                return packet;
            } else {
                // æœªæ‰¾åˆ°åŒ…尾,继续接收数据
                break;
            }
        }
        // æœªæ‰¾åˆ°å®Œæ•´çš„包
        return null;
    }
    /**
     * èŽ·å–åŒ…ç»“æŸç´¢å¼•
     */
    public static int findPacketEndIndex(List<Byte> buffer, byte[] packetEnd) {
        for (int i = 0; i <= buffer.size() - packetEnd.length; i++) {
            boolean isMatch = true;
            for (int j = 0; j < packetEnd.length; j++) {
                if (buffer.get(i + j) != packetEnd[j]) {
                    isMatch = false;
                    break;
                }
            }
            if (isMatch) {
                return i;
            }
        }
        return -1;
    }
    /**
     * ä»Žç¼“冲区提取数据包
     */
    public static byte[] extractPacketFromBuffer(List<Byte> buffer, int endIndex) {
        byte[] packet = new byte[endIndex];
        for (int i = 0; i < endIndex; i++) {
            packet[i] = buffer.get(i);
        }
        buffer.subList(0, endIndex).clear();
        return packet;
    }
    /**
     * åŽ»æŽ‰åŒ…å¤´å’ŒåŒ…å°¾æ ¡éªŒåŠè½¬ä¹‰
     */
    public static byte[] transferData(byte[] data) {
        data = Arrays.copyOfRange(data, 3, data.length);
        data = Arrays.copyOfRange(data, 0, data.length - 7);
        String dataStr = DatatypeConverter.printHexBinary(data);
        if (dataStr.contains("01020201")) {//转义01020201
            dataStr = dataStr.replaceAll("01020201", "010201");
        }
        if (dataStr.contains("01020200")) {//转义01020200
            dataStr = dataStr.replaceAll("01020200", "010200");
        }
        if (dataStr.contains("01020202")) {//转义01020202
            dataStr = dataStr.replaceAll("01020202", "010202");
        }
        data = DatatypeConverter.parseHexBinary(dataStr);
        return data;
    }
}
src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java
@@ -4,18 +4,14 @@
import com.ard.alarm.radar.domain.ArdEquipRadar;
import com.ard.alarm.radar.domain.RadarAlarmData;
import com.ard.alarm.radar.domain.ArdAlarmRadar;
import com.ard.utils.LonlatConver;
import com.ard.utils.ByteUtils;
import com.ard.utils.GisUtils;
import com.ard.utils.mqtt.MqttConsumer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GlobalCoordinates;
import javax.xml.bind.DatatypeConverter;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ScheduledFuture;
@@ -35,6 +31,7 @@
    private Integer port;
    private Double longitude;
    private Double lagitude;
    private Double altitude;
    private String name;
    private String id;
@@ -45,6 +42,7 @@
        this.lagitude = ardEquipRadar.getLatitude();
        this.name = ardEquipRadar.getName();
        this.id = ardEquipRadar.getId();
        this.altitude = ardEquipRadar.getAltitude();
    }
    private ChannelHandlerContext context;
@@ -55,10 +53,8 @@
        // å¤„理接收到的消息
        byte[] byteArray = new byte[msg.readableBytes()];
        msg.getBytes(msg.readerIndex(), byteArray);
        byte[] bytes = receiveCompletePacket(byteArray);
        byte[] bytes = MessageParsing.receiveCompletePacket(byteArray);
        if (bytes != null) {
            //  String hexString = DatatypeConverter.printHexBinary(bytes);
            //  log.info(hexString);
            processData(bytes);
        }
    }
@@ -109,7 +105,9 @@
     */
    public void processData(byte[] data) {
        try {
            data = transferData(data);//去掉包头和包尾、校验及转义
            //log.info("原始数据:" + DatatypeConverter.printHexBinary(data));
            log.info("雷达信息:" + host + "【port】" + port + "【X】" + longitude + "【Y】" + lagitude + "【Z】" + altitude);
            data = MessageParsing.transferData(data);//去掉包头和包尾、校验及转义
            byte[] type = Arrays.copyOfRange(data, 0, 1);//命令类型
            //  log.info("命令类型:" + DatatypeConverter.printHexBinary(type));
@@ -118,40 +116,41 @@
            //  log.info("命令ID:" + DatatypeConverter.printHexBinary(cmdId));
            byte[] payloadSize = Arrays.copyOfRange(data, 2, 4);//有效负载大小
            payloadSize = toLittleEndian(payloadSize);
            int payloadSizeToDecimal = byteArrayToDecimal(payloadSize);
            payloadSize = ByteUtils.toLittleEndian(payloadSize);
            int payloadSizeToDecimal = ByteUtils.bytesToDecimal(payloadSize);
            // log.info("有效负载大小(转整型):" + payloadSizeToDecimal);
            List<ArdAlarmRadar> radarAlarmInfos = new ArrayList<>();
            String alarmTime="";
            if (Arrays.equals(cmdId, new byte[]{0x01})) {
                byte[] dwTim = Arrays.copyOfRange(data, 4, 8);
                dwTim = toLittleEndian(dwTim);
                dwTim = ByteUtils.toLittleEndian(dwTim);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                long l = byteArrayToDecimal(dwTim);
                String alarmTime = sdf.format(l * 1000);
                long l = ByteUtils.bytesToDecimal(dwTim);
                alarmTime = sdf.format(l * 1000);
                // log.info("周视图像的出现时间(转date):" + alarmTime);
                byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
                wTargetNum = toLittleEndian(wTargetNum);
                int targetNum = byteArrayToDecimal(wTargetNum);
                wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
                int targetNum = ByteUtils.bytesToDecimal(wTargetNum);
                //log.info("目标总点数(转整型):" + targetNum);
                //解析NET_TARGET_UNIT(64是NET_TARGET_HEAD的字节数)
                int uintSize = (payloadSizeToDecimal - 64) / targetNum;
                // log.info("单条报警大小:" + uintSize);
                List<ArdAlarmRadar> radarAlarmInfos = new ArrayList<>();
                for (int i = 0; i < targetNum; i++) {
                    Integer index = 68 + uintSize * i;
                    byte[] dwID = Arrays.copyOfRange(data, index, index + 4);
                    // log.info("目标ID:" + DatatypeConverter.printHexBinary(cmdId));
                    dwID = toLittleEndian(dwID);
                    int id = byteArrayToDecimal(dwID);
                    dwID = ByteUtils.toLittleEndian(dwID);
                    int id = ByteUtils.bytesToDecimal(dwID);
                    // log.info("目标ID号:" + id);
                    byte[] iDistance = Arrays.copyOfRange(data, index + 8, index + 12);
                    iDistance = toLittleEndian(iDistance);
                    int Distance = byteArrayToDecimal(iDistance);
                    iDistance = ByteUtils.toLittleEndian(iDistance);
                    Double Distance = ByteUtils.bytesToDouble(iDistance);
                    // log.info("目标当前距离(m):" + Distance);
                    //region ä¸éœ€è¦çš„字段
//                    byte[] dwGSum = Arrays.copyOfRange(data, index + 4, index + 8);
@@ -200,7 +199,7 @@
                    //endregion
                    String alarmType = "";
                    byte[] cStat = Arrays.copyOfRange(data, index + 23, index + 24);
                    cStat = toLittleEndian(cStat);
                    cStat = ByteUtils.toLittleEndian(cStat);
                    String binaryString = String.format("%8s", Integer.toBinaryString(cStat[0] & 0xFF)).replace(' ', '0');
                    // log.info("目标当前状态:" + binaryString);
                    // æå–第4位至第6位的值
@@ -215,7 +214,7 @@
                    byte[] szName = Arrays.copyOfRange(data, index + 64, index + 96);
                    int position = findIndexOfDoubleZero(szName);
                    String alarmPointName = "";
                    String alarmPointName;
                    if (position != -1) {
                        byte[] result = new byte[position];
                        System.arraycopy(szName, 0, result, 0, position);
@@ -225,16 +224,15 @@
                    }
                    // log.info("所属告警区域名称:" + alarmPointName);
                    byte[] afTx = Arrays.copyOfRange(data, index + 96, index + 100);
                    afTx = toLittleEndian(afTx);
                    float fTx = bytesToFloat(afTx);
                    afTx = ByteUtils.toLittleEndian(afTx);
                    float fTx = ByteUtils.bytesToFloat(afTx);
                    //  log.info("水平角度:" + fTx);
                    byte[] afTy = Arrays.copyOfRange(data, index + 112, index + 116);
                    afTy = toLittleEndian(afTy);
                    float fTy = bytesToFloat(afTy);
                    afTy = ByteUtils.toLittleEndian(afTy);
                    float fTy = ByteUtils.bytesToFloat(afTy);
                    //  log.info("垂直角度:" + fTy);
                    //  log.info("雷达信息:" + host + "【port】" + port + "【X】" + longitude + "【Y】" + lagitude);
                    Double[] radarXY = {longitude, lagitude};
                    Double[] alarmXY = CalculateCoordinates(radarXY, Distance, (double) fTx);
                    Double[] alarmXY = GisUtils.CalculateCoordinates(radarXY, Distance, (double) fTx);
                    //  log.info("报警信息:" + "【id】" + id + "【name】" + alarmPointName + "【alarmType】" + alarmType + "【alarmTime】" + alarmTime + "【distance】" + Distance + "【P】" + fTx + "【T】" + fTy + "【X】" + alarmXY[0] + "【Y】" + alarmXY[1]);
                    ArdAlarmRadar ardAlarmRadar = new ArdAlarmRadar();
                    ardAlarmRadar.setTargetId(id);
@@ -244,134 +242,109 @@
                    ardAlarmRadar.setAlarmType(alarmType);
                    radarAlarmInfos.add(ardAlarmRadar);
                }
                RadarAlarmData radarAlarmData = new RadarAlarmData();
                radarAlarmData.setRadarId(id);
                radarAlarmData.setRadarName(name);
                radarAlarmData.setAlarmTime(alarmTime);
                radarAlarmData.setArdAlarmRadars(radarAlarmInfos);
                MqttConsumer.publish(2, false, "radar", JSON.toJSONString(radarAlarmData));
            }
        } catch (Exception ex) {
            log.error(ex.getMessage());
        }
    }
            if (Arrays.equals(cmdId, new byte[]{0x04})) {
                //String hexString = DatatypeConverter.printHexBinary(data);
                //log.info(hexString);
    /**
     * byte数组转float
     */
    private float bytesToFloat(byte[] bytes) {
        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        return buffer.getFloat();
    }
                byte[] dwTim = Arrays.copyOfRange(data, 4, 8);
                dwTim = ByteUtils.toLittleEndian(dwTim);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                long l = ByteUtils.bytesToDecimal(dwTim);
                alarmTime = sdf.format(l * 1000);
                //log.info("周视图像的出现时间(转date):" + alarmTime);
                byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
                wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
                int targetNum = ByteUtils.bytesToDecimal(wTargetNum);
                //log.info("目标总点数(转整型):" + targetNum);
    /**
     * byte数组转整型
     */
    public int byteArrayToDecimal(byte[] byteArray) {
        int decimalValue = 0;
                //解析NET_TARGET_UNIT(64是NET_TARGET_HEAD的字节数)
                int uintSize = (payloadSizeToDecimal - 64) / targetNum;
                //log.info("单条报警大小:" + uintSize);
                for (int i = 0; i < targetNum; i++) {
                    Integer index = 68 + uintSize * i;
                    byte[] dwID = Arrays.copyOfRange(data, index, index + 4);
                    //log.info("目标ID:" + DatatypeConverter.printHexBinary(dwID));
                    dwID = ByteUtils.toLittleEndian(dwID);
                    int id = ByteUtils.bytesToDecimal(dwID);
                    //log.info("目标ID号:" + id);
                    //region ä¸éœ€è¦çš„字段
                    byte[] iTw = Arrays.copyOfRange(data, index + 4, index + 8);
                    iTw = ByteUtils.toLittleEndian(iTw);
                    int Tw = ByteUtils.bytesToDecimal(iTw);
                    // log.info("目标当前的像素宽度:" + Tw);
        for (int i = 0; i < byteArray.length; i++) {
            decimalValue = (decimalValue << 8) | (byteArray[i] & 0xFF);
        }
                    byte[] iTh = Arrays.copyOfRange(data, index + 8, index + 12);
                    iTh = ByteUtils.toLittleEndian(iTh);
                    int Th = ByteUtils.bytesToDecimal(iTh);
                    //log.info("目标当前的像素高度:" + Th);
        return decimalValue;
    }
                    byte[] fTx = Arrays.copyOfRange(data, index + 12, index + 16);
                    fTx = ByteUtils.toLittleEndian(fTx);
                    float fTxAngle = ByteUtils.bytesToFloat(fTx);
                    //log.info("p角度:" + fTxAngle);
                    byte[] fTy = Arrays.copyOfRange(data, index + 16, index + 20);
                    fTy = ByteUtils.toLittleEndian(fTy);
                    float fTyAngle = ByteUtils.bytesToFloat(fTy);
                    //log.info("t角度:" + fTyAngle);
    /**
     * å¤§ç«¯è½¬å°ç«¯
     */
    public byte[] toLittleEndian(byte[] bigEndianBytes) {
        byte[] littleEndianBytes = new byte[bigEndianBytes.length];
                    byte[] sAreaNo = Arrays.copyOfRange(data, index + 20, index + 22);
                    sAreaNo = ByteUtils.toLittleEndian(sAreaNo);
                    int AreaNo = ByteUtils.bytesToDecimal(sAreaNo);
                    //log.info("目标归属的告警区域号:" + AreaNo);
        for (int i = 0; i < bigEndianBytes.length; i++) {
            int j = bigEndianBytes.length - i - 1;
            littleEndianBytes[i] = bigEndianBytes[j];
        }
                    byte[] cGrp = Arrays.copyOfRange(data, index + 22, index + 23);
                    cGrp = ByteUtils.toLittleEndian(cGrp);
                    int Grp = ByteUtils.bytesToDecimal(cGrp);
                    //log.info("所属组:" + Grp);
                    //endregion
                    String alarmType;
                    byte[] cStat = Arrays.copyOfRange(data, index + 23, index + 24);
                    cStat = ByteUtils.toLittleEndian(cStat);
                    //String binaryString = String.format("%8s", Integer.toBinaryString(cStat[0] & 0xFF)).replace(' ', '0');
                    //log.info("目标当前状态:" + binaryString);
                    // æå–第0位值
                    // ä½¿ç”¨ä½è¿ç®—操作判断第0位是否为1
                    boolean isBitSet = (cStat[0] & 0x01) == 0x00;
                    // åˆ¤æ–­æå–的值
                    if (isBitSet) {
                        alarmType = "雷达抽油机停机";
                    } else {
                        continue;
                    }
                    //log.info("报警类型:" + alarmType);
        return littleEndianBytes;
    }
    // åˆ›å»ºç¼“冲区列表
    List<Byte> buffer = new ArrayList<>();
    /**
     * æŽ¥æ”¶å®Œæ•´åŒ…
     */
    public byte[] receiveCompletePacket(byte[] receivedData) {
        // å®šä¹‰åŒ…尾字节序列
        byte[] packetEnd = {0x01, 0x02, 0x00};
        // æ·»åŠ å·²æŽ¥æ”¶çš„æ•°æ®åˆ°ç¼“å†²åŒº
        for (byte data : receivedData) {
            buffer.add(data);
        }
        // æ£€æŸ¥ç¼“冲区中的数据是否包含完整的包
        while (buffer.size() >= packetEnd.length) {
            int endIndex = findPacketEndIndex(buffer, packetEnd);
            if (endIndex != -1) {
                // æ‰¾åˆ°å®Œæ•´çš„包
                byte[] packet = extractPacketFromBuffer(buffer, endIndex + packetEnd.length);
                return packet;
            } else {
                // æœªæ‰¾åˆ°åŒ…尾,继续接收数据
                break;
            }
        }
        // æœªæ‰¾åˆ°å®Œæ•´çš„包
        return null;
    }
    /**
     * èŽ·å–åŒ…ç»“æŸç´¢å¼•
     */
    public int findPacketEndIndex(List<Byte> buffer, byte[] packetEnd) {
        for (int i = 0; i <= buffer.size() - packetEnd.length; i++) {
            boolean isMatch = true;
            for (int j = 0; j < packetEnd.length; j++) {
                if (buffer.get(i + j) != packetEnd[j]) {
                    isMatch = false;
                    break;
                    byte[] szName = Arrays.copyOfRange(data, index + 32, index + 64);
                    //log.info("所属告警区域名称:" + DatatypeConverter.printHexBinary(szName));
                    int position = findIndexOfDoubleZero(szName);
                    String alarmPointName;
                    if (position != -1) {
                        byte[] result = new byte[position];
                        System.arraycopy(szName, 0, result, 0, position);
                        alarmPointName = new String(result, "GBK");
                    } else {
                        alarmPointName = new String(szName, "GBK");
                    }
                    // log.info("所属告警区域名称:" + alarmPointName);
                    //log.info("报警信息:" + "【id】" + id + "【name】" + alarmPointName + "【alarmType】" + alarmType + "【alarmTime】" + alarmTime);
                    ArdAlarmRadar ardAlarmRadar = new ArdAlarmRadar();
                    ardAlarmRadar.setTargetId(id);
                    ardAlarmRadar.setName(alarmPointName);
                    ardAlarmRadar.setAlarmType(alarmType);
                    radarAlarmInfos.add(ardAlarmRadar);
                }
            }
            if (isMatch) {
                return i;
            }
            RadarAlarmData radarAlarmData = new RadarAlarmData();
            radarAlarmData.setRadarId(id);
            radarAlarmData.setRadarName(name);
            radarAlarmData.setAlarmTime(alarmTime);
            radarAlarmData.setArdAlarmRadars(radarAlarmInfos);
            MqttConsumer.publish(2, false, "radar", JSON.toJSONString(radarAlarmData));
        } catch (Exception ex) {
            log.error("雷达报文解析异常:" + ex.getMessage());
        }
        return -1;
    }
    /**
     * ä»Žç¼“冲区提取数据包
     */
    public byte[] extractPacketFromBuffer(List<Byte> buffer, int endIndex) {
        byte[] packet = new byte[endIndex];
        for (int i = 0; i < endIndex; i++) {
            packet[i] = buffer.get(i);
        }
        buffer.subList(0, endIndex).clear();
        return packet;
    }
    /**
     * åŽ»æŽ‰åŒ…å¤´å’ŒåŒ…å°¾æ ¡éªŒåŠè½¬ä¹‰
     */
    public byte[] transferData(byte[] data) {
        data = Arrays.copyOfRange(data, 3, data.length);
        data = Arrays.copyOfRange(data, 0, data.length - 7);
        String dataStr = DatatypeConverter.printHexBinary(data);
        if (dataStr.contains("01020201")) {//转义01020201
            dataStr = dataStr.replaceAll("01020201", "010201");
        }
        if (dataStr.contains("01020200")) {//转义01020200
            dataStr = dataStr.replaceAll("01020200", "010200");
        }
        if (dataStr.contains("01020202")) {//转义01020202
            dataStr = dataStr.replaceAll("01020202", "010202");
        }
        data = DatatypeConverter.parseHexBinary(dataStr);
        return data;
    }
    /**
@@ -384,21 +357,6 @@
            }
        }
        return -1;
    }
    /**
     * é€šè¿‡A点坐标,长度和Y轴角度计算B点坐标
     */
    public Double[] CalculateCoordinates(Double[] radarCoordinates, Integer distance, Double angle) {
        double[] to_wgs84 = LonlatConver.gcj02_To_Wgs84(radarCoordinates[0], radarCoordinates[1]);
        double Ax = to_wgs84[0]; // A ç‚¹çš„ X åæ ‡
        double Ay = to_wgs84[1]; // A ç‚¹çš„ Y åæ ‡
        double AB = distance; // AB çš„长度
        double angleWithYAxisDegrees = angle; // AB ä¸Ž Y è½´çš„角度(以度数表示)
        GeodeticCalculator calculator = new GeodeticCalculator();
        GlobalCoordinates globalCoordinates = new GlobalCoordinates(Ay, Ax);
        GlobalCoordinates globalCoordinates1 = calculator.calculateEndingGlobalCoordinates(Ellipsoid.WGS84, globalCoordinates, angleWithYAxisDegrees, AB);
        return new Double[]{globalCoordinates1.getLongitude(), globalCoordinates1.getLatitude()};
    }
}
src/main/resources/application.yml
@@ -9,7 +9,7 @@
      enabled: true
  mqtt:
    host: tcp://192.168.1.15:1883
    clientId: c3
    clientId: cc3
    username: admin
    password: xzx12345
    topic: tube
@@ -20,12 +20,12 @@
    url: http://iot.zhdk.net:8090/Warning/GetWarning?userName=cy4oil
  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://111.40.46.199:15432/ry-vue?stringtype=unspecified
    username: postgres
    password: Yykj.2021
#    url: jdbc:postgresql://192.168.1.15:5432/ry-vue?stringtype=unspecified
#    url: jdbc:postgresql://111.40.46.199:15432/ry-vue?stringtype=unspecified
#    username: postgres
#    password: postgres
#    password: Yykj.2021
    url: jdbc:postgresql://192.168.1.15:5432/ry-vue?stringtype=unspecified
    username: postgres
    password: postgres
mybatis:
  typeAliasesPackage: com.ard.alarm.**.domain
  mapperLocations: classpath:/mapper/*.xml