wwh vor 2 Wochen
Ursprung
Commit
6084bc657d

+ 6 - 4
app-common/src/main/java/com/ruoyi/common/server/EnvInputServer.java

@@ -1,21 +1,23 @@
 package com.ruoyi.common.server;
 
 import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.EventLoopGroup;
+import io.netty.channel.*;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.SocketChannel;
 import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.codec.string.StringDecoder;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
+import java.nio.charset.StandardCharsets;
+
 @Component
 public class EnvInputServer {
     @Autowired
     private EnvInputServerHandler serverHandler;
     //监听端口
-    private int port = 3729;
+//    private int port = 3729;
+    private int port = 3726;
     //创建构造方法
     public EnvInputServer(){
     }

+ 73 - 30
app-common/src/main/java/com/ruoyi/common/server/EnvInputServerHandler.java

@@ -4,17 +4,19 @@ package com.ruoyi.common.server;
 import cn.hutool.core.util.ObjectUtil;
 import com.ruoyi.common.utils.ModBusUtils;
 import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
 import io.netty.buffer.Unpooled;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInboundHandlerAdapter;
+import io.netty.channel.*;
+import io.netty.util.CharsetUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.ZoneId;
@@ -23,6 +25,8 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
 
+import static ch.qos.logback.core.encoder.ByteArrayUtil.hexStringToByteArray;
+
 
 /**
  * @Project : huimv.shiwan
@@ -64,15 +68,73 @@ public class EnvInputServerHandler extends ChannelInboundHandlerAdapter {
         }
         askTextSb.append(text);
     }
-    @Override
-    public  void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
 
-        System.out.println("收到的数据:"+msg);
+@Override
+public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+    System.out.println("收到的数据:" + msg);
+
+    if (msg instanceof ByteBuf) {
+        ByteBuf byteBuf = (ByteBuf) msg;
+
+        try {
+            // 1. 打印原始十六进制数据(用于调试)
+            String hexData = ByteBufUtil.hexDump(byteBuf);
+            System.out.println("十六进制数据: " + hexData);
+
+            // 2. 检查数据长度是否足够(假设每个参数占4字节,状态码占2字节)
+            if (byteBuf.readableBytes() < 22) { // 5个浮点数(4*5=20) + 1个状态码(2) = 22字节
+                System.err.println("数据长度不足!");
+                return;
+            }
+
+            // 3. 读取数据到字节数组(方便解析)
+
+            byte[] bytes = hexStringToByteArray(hexData.substring(14));
+
+            // 4. 解析浮点数参数(IEEE 754,大端序)
+            float cod = bytesToFloat(bytes, 0);       // 寄存器 0-1
+            float ph = bytesToFloat(bytes, 4);        // 寄存器 2-3
+            float flow = bytesToFloat(bytes, 8);      // 寄存器 4-5
+            float ammonia = bytesToFloat(bytes, 12);   // 寄存器 6-7
+            float phosphorus = bytesToFloat(bytes, 16);// 寄存器 8-9
+
+            // 5. 解析状态码(16位有符号整数)
+            int status = bytesToInt16(bytes, 20);     // 寄存器 10
+
+            // 6. 打印解析结果
+            System.out.println("解析结果:");
+            System.out.println("COD: " + cod + " mg/L");
+            System.out.println("pH: " + ph);
+            System.out.println("流量: " + flow + " m³/h");
+            System.out.println("氨氮: " + ammonia + " mg/L");
+            System.out.println("总磷: " + phosphorus + " mg/L");
+
+        } finally {
+            // 7. 释放 ByteBuf
+            byteBuf.release();
+        }
+    }
+}
+
 
-        super.channelRead(ctx, msg);
+
+    // 解析 IEEE 754 浮点数(4字节)
+    private  float bytesToFloat(byte[] bytes, int offset) {
+        return ByteBuffer.wrap(bytes, offset, 4)
+                .order(ByteOrder.BIG_ENDIAN)
+                .getFloat();
     }
 
-    public   static boolean isStartOfToday(Date date) {
+    // 解析 16位有符号整数(2字节)
+    private  int bytesToInt16(byte[] bytes, int offset) {
+        return ByteBuffer.wrap(bytes, offset, 2)
+                .order(ByteOrder.BIG_ENDIAN)
+                .getShort();
+    }
+
+
+
+    public    boolean isStartOfToday(Date date) {
         // 创建一个示例的LocalDateTime对象
         LocalDateTime exampleTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
         // 获取今天的开始时间
@@ -87,27 +149,7 @@ public class EnvInputServerHandler extends ChannelInboundHandlerAdapter {
             return false;
         }
     }
-    public  boolean isTimeBetween(LocalTime startTime, LocalTime endTime) {
-        LocalDateTime now = LocalDateTime.now();
-
-        // 获取当前日期的00:00和23:59:59
-        LocalDateTime startOfDay = now.withHour(0).withMinute(0).withSecond(0).withNano(0);
-        LocalDateTime endOfDay = startOfDay.plusDays(1).minusSeconds(1);
-
-        // 创建表示时间段的开始和结束时间的LocalDateTime对象
-        LocalDateTime startDateTime = LocalDateTime.of(now.toLocalDate(), startTime);
-        LocalDateTime endDateTime = LocalDateTime.of(now.toLocalDate(), endTime);
-
-        // 判断当前时间是否在两个时间段之一内
-        if (endDateTime.isBefore(startDateTime)) {
-            // 时间段跨越午夜,分两部分判断
-            return (now.isAfter(startDateTime) && now.isBefore(endOfDay)) ||
-                    (now.isAfter(startOfDay) && now.isBefore(endDateTime));
-        } else {
-            // 时间段在同一天内,直接判断
-            return now.isAfter(startDateTime) && now.isBefore(endDateTime);
-        }
-    }
+
     @Override
     public void channelInactive(ChannelHandlerContext ctx) throws Exception {
         Channel channel = ctx.channel();
@@ -155,6 +197,7 @@ public class EnvInputServerHandler extends ChannelInboundHandlerAdapter {
 
     @Override
     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        System.err.println("发生异常: " + cause.getMessage());
         if (cause.getMessage().indexOf("Connection reset") != -1) {
             log.info("相关采集器设备正在重启:" + cause.toString());
         }