From d5b46b8e3769ab240a3fb8d479a3e46cc0c1c718 Mon Sep 17 00:00:00 2001 From: wangshilong Date: Tue, 26 Nov 2024 14:25:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8C=87=E4=BB=A4=E5=8F=91=E9=80=81=E5=92=8C?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E6=B7=BB=E5=8A=A0=E5=8A=9F=E8=83=BD=E7=A0=81?= =?UTF-8?q?=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../iot/modbus_rtcp/netty/ModbusSender.java | 9 ++- .../iot/modbus_rtcp/netty/SyncHandler.java | 10 +++ .../utils/ModbusFunctionCodeEnums.java | 63 +++++++++++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/iot/modbus_rtcp/utils/ModbusFunctionCodeEnums.java diff --git a/src/main/java/com/iot/modbus_rtcp/netty/ModbusSender.java b/src/main/java/com/iot/modbus_rtcp/netty/ModbusSender.java index d4cf6c4..43e3aef 100644 --- a/src/main/java/com/iot/modbus_rtcp/netty/ModbusSender.java +++ b/src/main/java/com/iot/modbus_rtcp/netty/ModbusSender.java @@ -2,8 +2,10 @@ package com.iot.modbus_rtcp.netty; import com.iot.modbus_rtcp.config.EquipmentIPProperties; import com.iot.modbus_rtcp.dto.ModbusCommandDto; +import com.iot.modbus_rtcp.utils.ModbusFunctionCodeEnums; import com.iot.modbus_rtcp.utils.SpringUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.HashMap; @@ -40,9 +42,12 @@ public class ModbusSender { private Map> split(List modbusCommandBoList) { Map> map = new HashMap<>(); - modbusCommandBoList.stream().forEach(modbusCommandBo -> { + modbusCommandBoList.forEach(modbusCommandBo -> { if (modbusCommandBo.getIdentifier() == null) { - return; + throw new NullPointerException("Invalid gateway identifier"); + } + if (!ModbusFunctionCodeEnums.isHandlerHexCode(StringUtils.substring(modbusCommandBo.getCommand(), 2, 2))) { + throw new RuntimeException("Not support command: " + modbusCommandBo.getCommand()); } List list = map.getOrDefault(modbusCommandBo.getIdentifier(), new ArrayList<>()); diff --git a/src/main/java/com/iot/modbus_rtcp/netty/SyncHandler.java b/src/main/java/com/iot/modbus_rtcp/netty/SyncHandler.java index 1328579..aba87cd 100644 --- a/src/main/java/com/iot/modbus_rtcp/netty/SyncHandler.java +++ b/src/main/java/com/iot/modbus_rtcp/netty/SyncHandler.java @@ -2,11 +2,13 @@ package com.iot.modbus_rtcp.netty; import com.iot.modbus_rtcp.dto.CommandTypeComparable; import com.iot.modbus_rtcp.dto.ModbusCommandDto; +import com.iot.modbus_rtcp.utils.ModbusFunctionCodeEnums; import com.iot.modbus_rtcp.utils.SpringUtil; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.amqp.rabbit.core.RabbitTemplate; import java.net.InetSocketAddress; @@ -53,6 +55,14 @@ public class SyncHandler extends ChannelInboundHandlerAdapter { if (CommandTypeComparable.CommandType.CONTROL.equals(message.getType())) { return; } + + if (!ModbusFunctionCodeEnums.isHandlerHexCode(StringUtils.substring(msg.toString(), 2, 2))) { + log.warn("Gateway {} fails to send command {} to return data: {}", + channel.getIdentifier(), message.getCommand(), msg); + // TODO 可在此处添加设备告警 + return; + } + String json = message.getKey() + "/" + System.currentTimeMillis() + "/" + msg; log.info("推数据到MQ({}): {}", channel.getCollectQueue(), json); try { diff --git a/src/main/java/com/iot/modbus_rtcp/utils/ModbusFunctionCodeEnums.java b/src/main/java/com/iot/modbus_rtcp/utils/ModbusFunctionCodeEnums.java new file mode 100644 index 0000000..979e71e --- /dev/null +++ b/src/main/java/com/iot/modbus_rtcp/utils/ModbusFunctionCodeEnums.java @@ -0,0 +1,63 @@ +package com.iot.modbus_rtcp.utils; + +import com.iot.modbus_rtcp.dto.CommandTypeComparable; +import lombok.Getter; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Objects; + +/** + * @author 王仕龙 + * 2024/11/26 13:43 + */ +@Getter +public enum ModbusFunctionCodeEnums { + + READ_COILS(1, CommandTypeComparable.CommandType.COLLECTION, "读取线圈状态", "位", "读取一组逻辑线圈的当前状态(ON/OFF)"), + READ_DISCRETE_INPUTS(2, CommandTypeComparable.CommandType.COLLECTION, "读取输入状态", "位", "读取一组开关输入的当前状态(ON/OFF)"), + READ_HOLDING_REGISTERS(3, CommandTypeComparable.CommandType.COLLECTION, "读取保持寄存器", "整数,字符型,状态字,浮点型", "在一个或多个保持寄存器中取得当前的二进制值"), + READ_INPUT_REGISTERS(4, CommandTypeComparable.CommandType.COLLECTION, "读取输入寄存器", "整数,状态字,浮点型", "在一个或多个输入寄存器中取得当前的二进制值"), + WRITE_COIL(5, CommandTypeComparable.CommandType.CONTROL, "强置单线圈", "位", "强置一个逻辑线圈的通断状态"), + WRITE_REGISTER(6, CommandTypeComparable.CommandType.CONTROL, "预置单寄存器", "整数,字符型,状态字,浮点型", "把具体二进值装入一个保持寄存器"), + // READ_EXCEPTION_STATUS(7, CommandTypeComparable.CommandType.COLLECTION, "读取异常状态", "", "取得8个内部线圈的通断状态,这8个线圈的地址由控制器决定,用户逻辑可以将这些线圈定义,以说明从机状态,短报文适宜于迅速读取状态"), + // READ_EXCEPTION_STATUS(8, CommandTypeComparable.CommandType.COLLECTION, "回送诊断校验", "", "把诊断校验报文送从机,以对通信处理进行评鉴"), + WRITE_COILS(15, CommandTypeComparable.CommandType.CONTROL, "强置多线圈", "位", "强置一串连续逻辑线圈的通断"), + WRITE_REGISTERS(16, CommandTypeComparable.CommandType.CONTROL, "预置多寄存器", "整数,字符型,状态字,浮点型", "把具体的二进制值装入一串连续的保持寄存器"), +// REPORT_SLAVE_ID(17, CommandTypeComparable.CommandType.COLLECTION, "报告从机标识", "字符型", "可使主机判断编址从机的类型及该从机运行指示灯的状态"), + ; + private final int code; + private final String name; + private final String dataType; + private final String description; + private final CommandTypeComparable.CommandType commandType; + + ModbusFunctionCodeEnums(int code, CommandTypeComparable.CommandType commandType, String name, String dataType, String description) { + this.code = code; + this.name = name; + this.dataType = dataType; + this.commandType = commandType; + this.description = description; + } + + public String getHexCode() { + return Integer.toHexString(this.code); + } + + public static Collection getAllControlCode() { + return Arrays.stream(values()) + .filter(item -> Objects.equals(CommandTypeComparable.CommandType.CONTROL, item.getCommandType())) + .toList(); + } + + public static Collection getAllCollectionCode() { + return Arrays.stream(values()) + .filter(item -> Objects.equals(CommandTypeComparable.CommandType.COLLECTION, item.getCommandType())) + .toList(); + } + + public static boolean isHandlerHexCode(String hexCode) { + return Arrays.stream(values()).anyMatch(item -> Objects.equals(item.getHexCode(), hexCode)); + } + +}