From 9aa66699aaa610be66f5bd0c22e90cae114311f9 Mon Sep 17 00:00:00 2001
From: ‘liusuyi’ <1951119284@qq.com>
Date: 星期五, 07 七月 2023 17:15:16 +0800
Subject: [PATCH] 优化外联设备报警解析并上传mqtt

---
 src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java |  346 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 333 insertions(+), 13 deletions(-)

diff --git a/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java b/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java
index 5770cdc..82d9685 100644
--- a/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java
+++ b/src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java
@@ -1,43 +1,363 @@
 package com.ard.utils.tcp;
 
+import com.alibaba.fastjson2.JSON;
+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.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.apache.commons.lang3.StringUtils;
 import javax.xml.bind.DatatypeConverter;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
 
 /**
- * @Description: tcp瀹㈡埛绔鐞�
+ * @Description: tcp瀹㈡埛绔鐞�-寮冪敤
  * @ClassName: NettyTcpClientHandler
  * @Author: 鍒樿嫃涔�
  * @Date: 2023骞�06鏈�25鏃�17:02
  * @Version: 1.0
  **/
-@Slf4j
+@Slf4j(topic = "netty")
 public class NettyTcpClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
+
+    private String host;
+    private Integer port;
+    private Double longitude;
+    private Double lagitude;
+    private Double altitude;
+    private String name;
+    private String id;
+
+    public NettyTcpClientHandler(ArdEquipRadar ardEquipRadar) {
+        this.host = ardEquipRadar.getIp();
+        this.port = ardEquipRadar.getPort();
+        this.longitude = ardEquipRadar.getLongitude();
+        this.lagitude = ardEquipRadar.getLatitude();
+        this.name = ardEquipRadar.getName();
+        this.id = ardEquipRadar.getId();
+        this.altitude = ardEquipRadar.getAltitude();
+    }
+
+    private ChannelHandlerContext context;
+    private ScheduledFuture<?> heartbeatTask;
+
     @Override
-    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg){
+    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
         // 澶勭悊鎺ユ敹鍒扮殑娑堟伅
         byte[] byteArray = new byte[msg.readableBytes()];
         msg.getBytes(msg.readerIndex(), byteArray);
-        String hexString = DatatypeConverter.printHexBinary(byteArray);
-
-        log.info("Received: " + hexString);
+        byte[] bytes = MessageParsing.receiveCompletePacket(byteArray);
+        if (bytes != null) {
+            processData(bytes);
+        }
     }
 
     @Override
-    public void channelActive(ChannelHandlerContext ctx) throws Exception {
-        // 褰撳鎴风杩炴帴鎴愬姛鍚庯紝鍙戦�佹秷鎭粰鏈嶅姟鍣�
-        ByteBuf message = ctx.alloc().buffer();
-        message.writeBytes("Hello, Server!".getBytes());
-        ctx.writeAndFlush(message);
+    public void channelActive(ChannelHandlerContext ctx) {
+        context = ctx;
+        startHeartbeatTask();//寮�濮嬪彂閫佸績璺�
+    }
+
+    /**
+     * 寮�濮嬪績璺充换鍔�
+     */
+    private void startHeartbeatTask() {
+        heartbeatTask = context.executor().scheduleAtFixedRate(() -> {
+            // 鍙戦�佸績璺虫秷鎭�
+            ByteBuf message = context.alloc().buffer();
+            byte[] header = {0x01, 0x02, 0x01};
+            byte[] payload = {0x10, 0x00, 0x00, 0x00};
+            byte[] payloadCrc32 = ByteUtils.parseCrc32(payload);
+            byte[] footer = {0x01, 0x02, 0x00};
+            byte[] heart = ByteUtils.appendArrays(header, payload, payloadCrc32, footer);
+//            byte[] heart = {0x01, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00, (byte) 0x83, (byte) 0x88, 0x5d, 0x71, 0x01, 0x02, 0x00};
+            String hexString = DatatypeConverter.printHexBinary(heart);
+            log.info("鍙戦�佸績璺�:" + hexString);
+            message.writeBytes(heart);
+            context.writeAndFlush(message);
+
+        }, 0, 5, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 鍋滄蹇冭烦浠诲姟
+     */
+    private void stopHeartbeatTask() {
+        if (heartbeatTask != null) {
+            heartbeatTask.cancel(false);
+            heartbeatTask = null;
+        }
     }
 
     @Override
-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+        log.info("tcp瀹㈡埛绔繛鎺ュ紓甯�");
         // 鍙戠敓寮傚父鏃剁殑澶勭悊
         cause.printStackTrace();
         ctx.close();
+        stopHeartbeatTask();//鍋滄蹇冭烦鍙戦��
     }
+
+    /**
+     * 瑙f瀽鎶ヨ鏁版嵁
+     */
+    public void processData(byte[] data) {
+        try {
+            //region crc鏍¢獙-鐩墠浠呯敤浜庢樉绀烘牎楠岀粨鏋�
+            Boolean crc32Check = MessageParsing.CRC32Check(data);
+            if (!crc32Check) {
+                log.info("CRC32鏍¢獙涓嶉�氳繃");
+            } else {
+                log.info("CRC32鏍¢獙閫氳繃");
+            }
+            //endregion
+            //log.info("鍘熷鏁版嵁:" + DatatypeConverter.printHexBinary(data));
+            //log.info("闆疯揪淇℃伅锛�" + host + "銆恜ort銆�" + port + "銆怷銆�" + longitude + "銆怸銆�" + lagitude + "銆怹銆�" + altitude);
+            data = MessageParsing.transferData(data);//鍘绘帀鍖呭ご鍜屽寘灏俱�佹牎楠屽強杞箟
+            //region 璐熻浇澶磋В鏋�
+            byte[] type = Arrays.copyOfRange(data, 0, 1);//鍛戒护绫诲瀷
+            //  log.info("鍛戒护绫诲瀷:" + DatatypeConverter.printHexBinary(type));
+            byte[] cmdId = Arrays.copyOfRange(data, 1, 2);//鍛戒护ID
+            //  log.info("鍛戒护ID:" + DatatypeConverter.printHexBinary(cmdId));
+            byte[] payloadSize = Arrays.copyOfRange(data, 2, 4);//鏈夋晥璐熻浇澶у皬
+            payloadSize = ByteUtils.toLittleEndian(payloadSize);
+            int payloadSizeToDecimal = ByteUtils.bytesToDecimal(payloadSize);
+            // log.info("鏈夋晥璐熻浇澶у皬(杞暣鍨�):" + payloadSizeToDecimal);
+            //endregion
+            List<ArdAlarmRadar> radarAlarmInfos = new ArrayList<>();
+            String alarmTime = "";
+            Integer targetNum = 0;
+            if (Arrays.equals(cmdId, new byte[]{0x01})) {
+                //region 鍛婅淇℃伅鍙嶉
+                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("鍛ㄨ鍥惧儚鐨勫嚭鐜版椂闂�(杞琩ate):" + alarmTime);
+
+                byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
+                wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
+                targetNum = ByteUtils.bytesToDecimal(wTargetNum);
+                if (targetNum == 0) {
+                    return;
+                }
+                log.info("鐩爣鎬荤偣鏁�(杞暣鍨�):" + targetNum);
+
+                //瑙f瀽NET_TARGET_UNIT(64鏄疦ET_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(cmdId));
+                    dwID = ByteUtils.toLittleEndian(dwID);
+                    int id = ByteUtils.bytesToDecimal(dwID);
+
+                    // log.info("鐩爣ID鍙凤細" + id);
+
+                    byte[] iDistance = Arrays.copyOfRange(data, index + 8, index + 12);
+                    iDistance = ByteUtils.toLittleEndian(iDistance);
+                    Double Distance = ByteUtils.bytesToDouble(iDistance);
+                    // log.info("鐩爣褰撳墠璺濈(m):" + Distance);
+                    //region 涓嶉渶瑕佺殑瀛楁
+//                    byte[] dwGSum = Arrays.copyOfRange(data, index + 4, index + 8);
+//                    dwGSum = toLittleEndian(dwGSum);
+//                    int GSum = byteArrayToDecimal(dwGSum);
+//                    log.info("鐩爣褰撳墠鍍忕礌鐏板害鍜岋細" + GSum);
+//                    byte[] iTw = Arrays.copyOfRange(data, index + 12, index + 16);
+//                    iTw = toLittleEndian(iTw);
+//                    int Tw = byteArrayToDecimal(iTw);
+//                    log.info("鐩爣褰撳墠鐨勫儚绱犲搴�:" + Tw);
+//
+//                    byte[] iTh = Arrays.copyOfRange(data, index + 16, index + 20);
+//                    iTh = toLittleEndian(iTh);
+//                    int Th = byteArrayToDecimal(iTh);
+//                    log.info("鐩爣褰撳墠鐨勫儚绱犻珮搴�:" + Th);
+//
+//                    byte[] wPxlArea = Arrays.copyOfRange(data, index + 20, index + 22);
+//                    wPxlArea = toLittleEndian(wPxlArea);
+//                    int PxlArea = byteArrayToDecimal(wPxlArea);
+//                    log.info("鐩爣褰撳墠鍍忕礌闈㈢Н:" + PxlArea);
+//
+//                    byte[] cTrkNum = Arrays.copyOfRange(data, index + 22, index + 23);
+//                    cTrkNum = toLittleEndian(cTrkNum);
+//                    int TrkNum = byteArrayToDecimal(cTrkNum);
+//                    log.info("杞ㄨ抗鐐规暟:" + TrkNum);
+
+//                    byte[] sVx = Arrays.copyOfRange(data, index + 24, index + 26);
+//                    sVx = toLittleEndian(sVx);
+//                    int Vx = byteArrayToDecimal(sVx);
+//                    log.info("鐩爣褰撳墠閫熷害鐭㈤噺(鍍忕礌璺濈)X:" + Vx);
+//
+//                    byte[] sVy = Arrays.copyOfRange(data, index + 26, index + 28);
+//                    sVy = toLittleEndian(sVy);
+//                    int Vy = byteArrayToDecimal(sVy);
+//                    log.info("鐩爣褰撳墠閫熷害鐭㈤噺(鍍忕礌璺濈)Y:" + Vy);
+//
+//                    byte[] sAreaNo = Arrays.copyOfRange(data, index + 28, index + 30);
+//                    sAreaNo = toLittleEndian(sAreaNo);
+//                    int AreaNo = byteArrayToDecimal(sAreaNo);
+//                    log.info("鐩爣褰掑睘鐨勫憡璀﹀尯鍩熷彿:" + AreaNo);
+//
+//                    byte[] cGrp = Arrays.copyOfRange(data, index + 30, index + 31);
+//                    cGrp = toLittleEndian(cGrp);
+//                    int Grp = byteArrayToDecimal(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);
+                    // 鎻愬彇绗�4浣嶈嚦绗�6浣嶇殑鍊�
+                    int extractedValue = (cStat[0] >> 4) & 0b00001111;
+                    // 鍒ゆ柇鎻愬彇鐨勫��
+                    if (extractedValue == 0b0000) {
+                        alarmType = "杩愬姩鐩爣妫�娴�";
+                    } else if (extractedValue == 0b0001) {
+                        alarmType = "鐑簮妫�娴�";
+                    }
+                    // log.info("鎶ヨ绫诲瀷:" + alarmType);
+
+                    byte[] szName = Arrays.copyOfRange(data, index + 64, index + 96);
+                    String alarmPointName = ByteUtils.bytesToStringZh(szName);
+                    // log.info("鎵�灞炲憡璀﹀尯鍩熷悕绉�:" + alarmPointName);
+                    byte[] afTx = Arrays.copyOfRange(data, index + 96, index + 100);
+                    afTx = ByteUtils.toLittleEndian(afTx);
+                    float fTx = ByteUtils.bytesToFloat(afTx);
+                    //  log.info("姘村钩瑙掑害:" + fTx);
+                    byte[] afTy = Arrays.copyOfRange(data, index + 112, index + 116);
+                    afTy = ByteUtils.toLittleEndian(afTy);
+                    float fTy = ByteUtils.bytesToFloat(afTy);
+                    //  log.info("鍨傜洿瑙掑害:" + fTy);
+                    Double[] radarXY = {longitude, lagitude};
+                    Double[] alarmXY = GisUtils.CalculateCoordinates(radarXY, Distance, (double) fTx);
+                    //  log.info("鎶ヨ淇℃伅锛�" + "銆恑d銆�" + id + "銆恘ame銆�" + alarmPointName + "銆恆larmType銆�" + alarmType + "銆恆larmTime銆�" + alarmTime + "銆恉istance銆�" + Distance + "銆怭銆�" + fTx + "銆怲銆�" + fTy + "銆怷銆�" + alarmXY[0] + "銆怸銆�" + alarmXY[1]);
+                    ArdAlarmRadar ardAlarmRadar = new ArdAlarmRadar();
+                    ardAlarmRadar.setTargetId(id);
+                    ardAlarmRadar.setName(alarmPointName);
+                    ardAlarmRadar.setLongitude(alarmXY[0]);
+                    ardAlarmRadar.setLatitude(alarmXY[1]);
+                    ardAlarmRadar.setAlarmType(alarmType);
+                    radarAlarmInfos.add(ardAlarmRadar);
+                }
+                //endregion
+            }
+            if (Arrays.equals(cmdId, new byte[]{0x04})) {
+                //region鎶芥补鏈篈I鐘舵�佸弽棣�
+                String hexString = DatatypeConverter.printHexBinary(data);
+                //log.info(hexString);
+
+                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("鍛ㄨ鍥惧儚鐨勫嚭鐜版椂闂�(杞琩ate):" + alarmTime);
+
+                byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
+                wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
+                targetNum = ByteUtils.bytesToDecimal(wTargetNum);
+                log.info("鐩爣鎬荤偣鏁�(杞暣鍨�):" + targetNum);
+                if (targetNum == 0) {
+                    return;
+                }
+                //瑙f瀽NET_TARGET_UNIT(64鏄疦ET_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);
+
+                    byte[] iTh = Arrays.copyOfRange(data, index + 8, index + 12);
+                    iTh = ByteUtils.toLittleEndian(iTh);
+                    int Th = ByteUtils.bytesToDecimal(iTh);
+                    //log.info("鐩爣褰撳墠鐨勫儚绱犻珮搴�:" + Th);
+
+                    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);
+
+                    byte[] sAreaNo = Arrays.copyOfRange(data, index + 20, index + 22);
+                    sAreaNo = ByteUtils.toLittleEndian(sAreaNo);
+                    int AreaNo = ByteUtils.bytesToDecimal(sAreaNo);
+                    //log.info("鐩爣褰掑睘鐨勫憡璀﹀尯鍩熷彿:" + AreaNo);
+
+                    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 isB0 = (cStat[0] & 0x01) == 0x00;
+                    // 鍒ゆ柇鎻愬彇鐨勫��
+                    if (isB0) {
+                        alarmType = "闆疯揪鎶芥补鏈哄仠鏈�";
+                    } else {
+                        continue;
+                    }
+                    //log.info("鎶ヨ绫诲瀷:" + alarmType);
+
+                    byte[] szName = Arrays.copyOfRange(data, index + 32, index + 64);
+                    //log.info("鎵�灞炲憡璀﹀尯鍩熷悕绉�:" + DatatypeConverter.printHexBinary(szName));
+                    String alarmPointName = ByteUtils.bytesToStringZh(szName);
+                    // log.info("鎵�灞炲憡璀﹀尯鍩熷悕绉�:" + alarmPointName);
+                    //log.info("鎶ヨ淇℃伅锛�" + "銆恑d銆�" + id + "銆恘ame銆�" + alarmPointName + "銆恆larmType銆�" + alarmType + "銆恆larmTime銆�" + alarmTime);
+                    ArdAlarmRadar ardAlarmRadar = new ArdAlarmRadar();
+                    ardAlarmRadar.setTargetId(id);
+                    ardAlarmRadar.setName(alarmPointName);
+                    ardAlarmRadar.setAlarmType(alarmType);
+                    radarAlarmInfos.add(ardAlarmRadar);
+                }
+                //endregion
+            }
+            if (StringUtils.isEmpty(alarmTime)) {
+                return;
+            }
+            if (targetNum == 0) {
+                return;
+            }
+            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("闆疯揪鎶ユ枃瑙f瀽寮傚父:" + ex.getMessage());
+        }
+    }
+
 }

--
Gitblit v1.9.3