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