‘liusuyi’
2023-07-05 1fd64b07ddb99c2d9cc8a358b71aceb6a2c81492
src/main/java/com/ard/utils/tcp/NettyTcpClientHandler.java
@@ -11,20 +11,22 @@
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(topic = "radar")
@Slf4j(topic = "netty")
public class NettyTcpClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
    private String host;
@@ -72,7 +74,12 @@
        heartbeatTask = context.executor().scheduleAtFixedRate(() -> {
            // 发送心跳消息
            ByteBuf message = context.alloc().buffer();
            byte[] heart = {0x01, 0x02, 0x01, 0x10, 0x00, 0x00, 0x00, (byte) 0x83, (byte) 0x88, 0x5d, 0x71, 0x01, 0x02, 0x00};
            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);
@@ -105,23 +112,32 @@
     */
    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 + "【port】" + port + "【X】" + longitude + "【Y】" + lagitude + "【Z】" + altitude);
            //log.info("雷达信息:" + host + "【port】" + port + "【X】" + longitude + "【Y】" + lagitude + "【Z】" + 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="";
            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");
@@ -131,8 +147,11 @@
                byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
                wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
                int targetNum = ByteUtils.bytesToDecimal(wTargetNum);
                //log.info("目标总点数(转整型):" + targetNum);
                targetNum = ByteUtils.bytesToDecimal(wTargetNum);
                if (targetNum == 0) {
                    return;
                }
                log.info("目标总点数(转整型):" + targetNum);
                //解析NET_TARGET_UNIT(64是NET_TARGET_HEAD的字节数)
                int uintSize = (payloadSizeToDecimal - 64) / targetNum;
@@ -213,7 +232,7 @@
                    // log.info("报警类型:" + alarmType);
                    byte[] szName = Arrays.copyOfRange(data, index + 64, index + 96);
                    int position = findIndexOfDoubleZero(szName);
                    int position = ByteUtils.findIndexOfDoubleZero(szName);
                    String alarmPointName;
                    if (position != -1) {
                        byte[] result = new byte[position];
@@ -242,10 +261,11 @@
                    ardAlarmRadar.setAlarmType(alarmType);
                    radarAlarmInfos.add(ardAlarmRadar);
                }
                //endregion
            }
            if (Arrays.equals(cmdId, new byte[]{0x04})) {
                //String hexString = DatatypeConverter.printHexBinary(data);
                //region抽油机AI状态反馈
                String hexString = DatatypeConverter.printHexBinary(data);
                //log.info(hexString);
                byte[] dwTim = Arrays.copyOfRange(data, 4, 8);
@@ -257,9 +277,11 @@
                byte[] wTargetNum = Arrays.copyOfRange(data, 8, 10);
                wTargetNum = ByteUtils.toLittleEndian(wTargetNum);
                int targetNum = ByteUtils.bytesToDecimal(wTargetNum);
                //log.info("目标总点数(转整型):" + targetNum);
                targetNum = ByteUtils.bytesToDecimal(wTargetNum);
                log.info("目标总点数(转整型):" + targetNum);
                if (targetNum == 0) {
                    return;
                }
                //解析NET_TARGET_UNIT(64是NET_TARGET_HEAD的字节数)
                int uintSize = (payloadSizeToDecimal - 64) / targetNum;
                //log.info("单条报警大小:" + uintSize);
@@ -307,9 +329,9 @@
                    //log.info("目标当前状态:" + binaryString);
                    // 提取第0位值
                    // 使用位运算操作判断第0位是否为1
                    boolean isBitSet = (cStat[0] & 0x01) == 0x00;
                    boolean isB0 = (cStat[0] & 0x01) == 0x00;
                    // 判断提取的值
                    if (isBitSet) {
                    if (isB0) {
                        alarmType = "雷达抽油机停机";
                    } else {
                        continue;
@@ -318,7 +340,7 @@
                    byte[] szName = Arrays.copyOfRange(data, index + 32, index + 64);
                    //log.info("所属告警区域名称:" + DatatypeConverter.printHexBinary(szName));
                    int position = findIndexOfDoubleZero(szName);
                    int position = ByteUtils.findIndexOfDoubleZero(szName);
                    String alarmPointName;
                    if (position != -1) {
                        byte[] result = new byte[position];
@@ -335,6 +357,13 @@
                    ardAlarmRadar.setAlarmType(alarmType);
                    radarAlarmInfos.add(ardAlarmRadar);
                }
                //endregion
            }
            if (StringUtils.isEmpty(alarmTime)) {
                return;
            }
            if (targetNum == 0) {
                return;
            }
            RadarAlarmData radarAlarmData = new RadarAlarmData();
            radarAlarmData.setRadarId(id);
@@ -345,18 +374,6 @@
        } catch (Exception ex) {
            log.error("雷达报文解析异常:" + ex.getMessage());
        }
    }
    /**
     * 找到00的索引位置
     */
    private int findIndexOfDoubleZero(byte[] bytes) {
        for (int i = 0; i < bytes.length - 1; i++) {
            if (bytes[i] == 0x00) {
                return i;
            }
        }
        return -1;
    }
}