From fbb9b4374821b43d0b85aa569977415fd8d77cd9 Mon Sep 17 00:00:00 2001
From: ‘liusuyi’ <1951119284@qq.com>
Date: Mon, 03 Jul 2023 16:01:39 +0800
Subject: [PATCH] 增加雷达抽油机停机推送mqtt

---
 /dev/null                                                   |  197 ------------
 src/main/java/com/ard/utils/DateUtils.java                  |  201 ++++++++++++
 src/main/java/com/ard/utils/SpringTool.java                 |   19 -
 src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java  |  282 +++++++----------
 src/main/java/com/ard/utils/GisUtils.java                   |   29 +
 src/main/java/com/ard/utils/LonlatConver.java               |    7 
 src/main/java/com/ard/utils/mqtt/MqttConsumer.java          |    2 
 src/main/java/com/ard/utils/tcp/MessageParsing.java         |   96 ++++++
 src/main/java/com/ard/hiksdk/service/impl/FMSGCallBack.java |    2 
 src/main/java/com/ard/utils/ByteUtils.java                  |   82 +++++
 src/main/resources/application.yml                          |   12 
 11 files changed, 537 insertions(+), 392 deletions(-)

diff --git a/src/main/java/com/ard/hiksdk/service/impl/FMSGCallBack.java b/src/main/java/com/ard/hiksdk/service/impl/FMSGCallBack.java
index b345927..2803831 100644
--- a/src/main/java/com/ard/hiksdk/service/impl/FMSGCallBack.java
+++ b/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;
diff --git a/src/main/java/com/ard/hiksdk/util/DateUtils.java b/src/main/java/com/ard/hiksdk/util/DateUtils.java
deleted file mode 100644
index 2bb715f..0000000
--- a/src/main/java/com/ard/hiksdk/util/DateUtils.java
+++ /dev/null
@@ -1,197 +0,0 @@
-package com.ard.hiksdk.util;
-import org.apache.commons.lang3.time.DateFormatUtils;
-
-import java.lang.management.ManagementFactory;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.time.*;
-import java.util.Date;
-/**
- * @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;
-    }
-}
diff --git a/src/main/java/com/ard/utils/ByteUtils.java b/src/main/java/com/ard/utils/ByteUtils.java
new file mode 100644
index 0000000..507ddcc
--- /dev/null
+++ b/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;
+    }
+
+}
diff --git a/src/main/java/com/ard/utils/DateUtils.java b/src/main/java/com/ard/utils/DateUtils.java
index 41b20ed..00c25d9 100644
--- a/src/main/java/com/ard/utils/DateUtils.java
+++ b/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;
+    }
 
     /**
      * 日期字符串的月日时分秒自动补零,并将/替换成-
diff --git a/src/main/java/com/ard/utils/GisUtils.java b/src/main/java/com/ard/utils/GisUtils.java
new file mode 100644
index 0000000..df21a12
--- /dev/null
+++ b/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()};
+    }
+}
diff --git a/src/main/java/com/ard/utils/LonlatConver.java b/src/main/java/com/ard/utils/LonlatConver.java
index ff02333..cd8c092 100644
--- a/src/main/java/com/ard/utils/LonlatConver.java
+++ b/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
 	 */
diff --git a/src/main/java/com/ard/utils/SpringTool.java b/src/main/java/com/ard/utils/SpringTool.java
index e152dde..0a7acfb 100644
--- a/src/main/java/com/ard/utils/SpringTool.java
+++ b/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();
-    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/ard/utils/mqtt/MqttConsumer.java b/src/main/java/com/ard/utils/mqtt/MqttConsumer.java
index 1c07850..ea2b31a 100644
--- a/src/main/java/com/ard/utils/mqtt/MqttConsumer.java
+++ b/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;
     }
diff --git a/src/main/java/com/ard/utils/tcp/MessageParsing.java b/src/main/java/com/ard/utils/tcp/MessageParsing.java
new file mode 100644
index 0000000..14aa3c5
--- /dev/null
+++ b/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;
+    }
+}
diff --git a/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java b/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java
index bb05e68..fa6016c 100644
--- a/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java
+++ b/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()};
     }
 
 }
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 2e6ddc4..50a9b71 100644
--- a/src/main/resources/application.yml
+++ b/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

--
Gitblit v1.9.3