Browse Source

refactor(ModbusRequest): 修改为DeviceRequest适配Modbus、OPC UA、MQTT等协议

wangpx 9 months ago
parent
commit
1f1b9de9eb

+ 9 - 9
admin/src/main/java/com/dcs/equipment/controller/ModbusTcpController.java

@@ -2,7 +2,7 @@ package com.dcs.equipment.controller;
 
 import com.dcs.common.core.domain.AjaxResult;
 import com.dcs.equipment.domain.Condition;
-import com.dcs.equipment.domain.ModbusRequest;
+import com.dcs.equipment.domain.DeviceRequest;
 import com.dcs.equipment.service.ModbusTcpService;
 import com.dcs.hnyz.domain.EquipmentParam;
 import com.dcs.hnyz.domain.vo.EquipmentParamFormVO;
@@ -27,7 +27,7 @@ import static com.dcs.common.core.domain.AjaxResult.success;
  * @author: wangpx
  * @date: 2025-03-07 16:54
  */
-@Api
+@Api(tags = "ModbusTCP模块")
 @RestController
 @RequestMapping("/modbus")
 public class ModbusTcpController {
@@ -48,44 +48,44 @@ public class ModbusTcpController {
 
     @GetMapping("/getValues")
     @ApiOperation(value = "modbus tcp 获取数据")
-    public AjaxResult getValues(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+    public AjaxResult getValues(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
         List<Object> values = service.getValues(request);
         return success(values);
     }
 
     @PostMapping("/setCoils")
     @ApiOperation(value = "modbus tcp 设置多个线圈数据")
-    public void setCoils(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+    public void setCoils(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
         service.setCoils(request);
     }
 
     @PostMapping("/setCoil")
     @ApiOperation(value = "modbus tcp 设置单个线圈数据")
-    public void setCoil(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+    public void setCoil(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
         service.setCoil(request);
     }
 
     @PostMapping("/setIntRegisters")
     @ApiOperation(value = "modbus tcp 设置多个整型数据")
-    public void setInts(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+    public void setInts(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
         service.setIntRegisters(request);
     }
 
     @PostMapping("/setIntRegister")
     @ApiOperation(value = "modbus tcp 设置单个整型数据")
-    public void setInt(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+    public void setInt(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
         service.setIntRegister(request);
     }
 
     @PostMapping("/setFloatRegisters")
     @ApiOperation(value = "modbus tcp 设置多个浮点数据")
-    public void setFloats(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+    public void setFloats(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
         service.setFloatRegisters(request);
     }
 
     @PostMapping("/setFloatRegister")
     @ApiOperation(value = "modbus tcp 设置单个浮点数据")
-    public void setFloat(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+    public void setFloat(@ApiParam(name = "modbus请求参数", value = "modbus请求参数", required = true) DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
         service.setFloatRegister(request);
     }
 

+ 9 - 8
admin/src/main/java/com/dcs/equipment/service/ModbusTcpService.java

@@ -1,7 +1,7 @@
 package com.dcs.equipment.service;
 
 import com.dcs.equipment.domain.Condition;
-import com.dcs.equipment.domain.ModbusRequest;
+import com.dcs.equipment.domain.DeviceRequest;
 import com.dcs.hnyz.domain.EquipmentParam;
 import com.dcs.hnyz.domain.vo.EquipmentParamFormVO;
 import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
@@ -26,17 +26,18 @@ public interface ModbusTcpService {
     // 判断条件有一个满足
     boolean processIfAnyConditionMet(List<EquipmentParam> targets, List<Condition> conditions) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
     // modbus tcp 获取数据
-    List<Object> getValues(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
+    List<Object> getValues(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
     // 设置多个线圈数据
-    void setCoils(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
+    void setCoils(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
     // 设置单个线圈数据
-    void setCoil(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
+    void setCoil(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
     // 设置多个寄存器整型数据
-    void setIntRegisters(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
+    void setIntRegisters(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
     // 设置单个寄存器整型数据
-    void setIntRegister(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
+    void setIntRegister(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
     // 设置多个寄存器浮点数据
-    void setFloatRegisters(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
+    void setFloatRegisters(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
     // 设置单个寄存器浮点数据
-    void setFloatRegister(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
+    void setFloatRegister(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException;
+//    void getData
 }

+ 31 - 32
admin/src/main/java/com/dcs/equipment/service/impl/ModbusTcpServiceImpl.java

@@ -3,7 +3,7 @@ package com.dcs.equipment.service.impl;
 //import com.dcs.dcs.domain.vo.EquipmentParamFormVo;
 
 import com.dcs.equipment.domain.Condition;
-import com.dcs.equipment.domain.ModbusRequest;
+import com.dcs.equipment.domain.DeviceRequest;
 import com.dcs.equipment.service.ModbusTcpService;
 import com.dcs.equipment.task.ModbusTcpTask;
 import com.dcs.equipment.utils.ModbusUtil;
@@ -51,7 +51,7 @@ public class ModbusTcpServiceImpl implements ModbusTcpService {
     public void updateEquipmentCodes() {
         EquipmentParam dcsEquipment = new EquipmentParam();
         List<EquipmentParam> newEquipmentParamList = equipmentParamService.selectEquipmentParamList(dcsEquipment);
-        ModbusTcpTask.modbusRequestList = Collections.unmodifiableList(ModbusUtil.getModbusRequests(newEquipmentParamList));
+        ModbusTcpTask.modbusRequestList = Collections.unmodifiableList(ModbusUtil.getDeviceRequests(newEquipmentParamList));
         // 按照顺序存储数据
         newEquipmentParamList.sort(Comparator.comparing(EquipmentParam::getRegisterId));
         ModbusTcpTask.equipmentParamList = Collections.unmodifiableList(newEquipmentParamList);
@@ -154,11 +154,11 @@ public class ModbusTcpServiceImpl implements ModbusTcpService {
     }
     // 执行设备操作
     private void executeEquipmentOperations(List<EquipmentParam> targets) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
-        List<ModbusRequest> modbusRequests = ModbusUtil.getModbusRequests(targets);
-        for (ModbusRequest request : modbusRequests) {
-            String functionCode = request.getFunctionCode();
+        List<DeviceRequest> modbusRequests = ModbusUtil.getDeviceRequests(targets);
+        for (DeviceRequest request : modbusRequests) {
+            String resource = request.getResource();
             String dataType = request.getDataType();
-            int address = request.getStartAddress();
+            int address = request.getOffsetOrIndex();
             Object value = request.getData().get(0);
             switch (dataType) {
                 case COIL_DATA_TYPE:
@@ -176,66 +176,65 @@ public class ModbusTcpServiceImpl implements ModbusTcpService {
 
 
     @Override
-    public List<Object> getValues(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+    public List<Object> getValues(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
         return ModbusUtil.getValues(request);
     }
 
     @Override
-    public void setCoils(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
-        int slaveId = request.getSlaveId();
-        int address = request.getStartAddress();
+    public void setCoils(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+        int unitId = request.getUnitId();
+        int address = request.getOffsetOrIndex();
         List<Object> requestData = request.getData();
         boolean[] data = new boolean[requestData.size()];
         for (int i = 0; i < requestData.size(); i++) {
             data[i] =  objToBoolean(requestData.get(i));
         }
-        ModbusUtil.setCoilValues(slaveId, address, data);
+        ModbusUtil.setCoilValues(unitId, address, data);
     }
 
     @Override
-    public void setCoil(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
-        int slaveId = request.getSlaveId();
-        int address = request.getStartAddress();
-        ModbusUtil.setCoilValue(slaveId, address, objToBoolean(request.getData().get(0)));
+    public void setCoil(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+        int unitId = request.getUnitId();
+        int address = request.getOffsetOrIndex();
+        ModbusUtil.setCoilValue(unitId, address, objToBoolean(request.getData().get(0)));
     }
 
     @Override
-    public void setIntRegisters(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
-        int slaveId = request.getSlaveId();
-        int address = request.getStartAddress();
+    public void setIntRegisters(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+        int unitId = request.getUnitId();
+        int address = request.getOffsetOrIndex();
         List<Object> requestData = request.getData();
         int[] data = new int[requestData.size()];
         for (int i = 0; i < requestData.size(); i++) {
             data[i] = objToInt(requestData.get(i));
         }
-        ModbusUtil.setRegisterValues(slaveId, address, data);
+        ModbusUtil.setRegisterValues(unitId, address, data);
     }
 
     @Override
-    public void setIntRegister(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
-        int slaveId = request.getSlaveId();
-        int address = request.getStartAddress();
-        ModbusUtil.setRegisterValue(slaveId, address, objToInt(request.getData().get(0)));
+    public void setIntRegister(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+        int unitId = request.getUnitId();
+        int address = request.getOffsetOrIndex();
+        ModbusUtil.setRegisterValue(unitId, address, objToInt(request.getData().get(0)));
     }
 
     @Override
-    public void setFloatRegisters(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
-        int slaveId = request.getSlaveId();
-        int address = request.getStartAddress();
+    public void setFloatRegisters(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+        int unitId = request.getUnitId();
+        int address = request.getOffsetOrIndex();
         List<Object> requestData = request.getData();
         float[] data = new float[requestData.size()];
         for (int i = 0; i < requestData.size(); i++) {
             data[i] = objToFloat(requestData.get(i));
         }
-        ModbusUtil.setRegisterFloatValues(slaveId, address, data);
+        ModbusUtil.setRegisterFloatValues(unitId, address, data);
     }
 
     @Override
-    public void setFloatRegister(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
-        int slaveId = request.getSlaveId();
-        int address = request.getStartAddress();
-        ModbusUtil.setRegisterFloatValue(slaveId, address, objToFloat(request.getData().get(0)));
+    public void setFloatRegister(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+        int unitId = request.getUnitId();
+        int address = request.getOffsetOrIndex();
+        ModbusUtil.setRegisterFloatValue(unitId, address, objToFloat(request.getData().get(0)));
     }
 
-
 }

+ 10 - 21
admin/src/main/java/com/dcs/equipment/task/ModbusTcpTask.java

@@ -1,10 +1,9 @@
 package com.dcs.equipment.task;
 
 import com.alibaba.fastjson2.JSON;
-import com.dcs.equipment.domain.ModbusRequest;
+import com.dcs.equipment.domain.DeviceRequest;
 import com.dcs.equipment.domain.ModbusResponse;
 import com.dcs.equipment.server.EquipmentListWebSocketServer;
-import com.dcs.equipment.server.EquipmentTreeWebSocketServer;
 import com.dcs.equipment.service.InfluxDBService;
 import com.dcs.equipment.service.ModbusTcpService;
 import com.dcs.hnyz.cache.CacheCenter;
@@ -37,8 +36,6 @@ public class ModbusTcpTask {
     private static final Logger logger = LoggerFactory.getLogger("modbusTcp");
     @Resource
     private EquipmentListWebSocketServer equipmentListWebSocketServer;
-    @Resource
-    private EquipmentTreeWebSocketServer equipmentTreeWebSocketServer;
     @Autowired
     private ModbusTcpService modbusTcpService;
     @Autowired
@@ -49,7 +46,7 @@ public class ModbusTcpTask {
     private ScheduledExecutorService scheduledExecutorService;
 
     // 保存modbus请求信息
-    public static volatile List<ModbusRequest> modbusRequestList;
+    public static volatile List<DeviceRequest> modbusRequestList;
     // 保存设备寄存器信息和数据地址
     public static volatile List<EquipmentParam> equipmentParamList;
 
@@ -65,7 +62,7 @@ public class ModbusTcpTask {
     }
 
     // 保存数据到influxdb
-    private void saveDataToInfluxdb(List<EquipmentParamFormVO> equipmentParamList) {
+    private void syncsSaveDataToInfluxdb(List<EquipmentParamFormVO> equipmentParamList) {
         CompletableFuture.runAsync(() ->
             influxDBService.saveDataToInfluxDB("shanghai_dcs_bucket", equipmentParamList)
         , scheduledExecutorService);
@@ -84,22 +81,22 @@ public class ModbusTcpTask {
             int finalI = i;
             try {
                 futures[finalI] = CompletableFuture.runAsync(() -> {
-                    ModbusRequest modbusRequest = modbusRequestList.get(finalI);
+                    DeviceRequest modbusRequest = modbusRequestList.get(finalI);
                     List<Object> list = new ArrayList<>();
                     // 响应数据
                     ModbusResponse response = new ModbusResponse();
-                    response.setSlaveId(modbusRequest.getSlaveId());
-                    response.setFunctionCode(modbusRequest.getFunctionCode());
+                    response.setSlaveId(modbusRequest.getUnitId());
+                    response.setFunctionCode(modbusRequest.getResource());
                     response.setDataType(modbusRequest.getDataType());
-                    response.setStartAddress(modbusRequest.getStartAddress());
-                    response.setQuantity(modbusRequest.getQuantity());
+                    response.setStartAddress(modbusRequest.getOffsetOrIndex());
+                    response.setQuantity(modbusRequest.getLengthOrQos());
                     try {
                         list = getValues(modbusRequest);
                     } catch (Exception e) {
                         e.printStackTrace();
                     }
                     response.setData(list);
-                    modbusResponseMap.get(modbusRequest.getFunctionCode()).add(response);
+                    modbusResponseMap.get(modbusRequest.getResource()).add(response);
                 }, scheduledExecutorService);
             } catch (Exception e) {
                 e.printStackTrace();
@@ -141,7 +138,7 @@ public class ModbusTcpTask {
         }
         broadCastEquipmentParamFormVOList = Collections.unmodifiableList(deepCopyEquipmentParamFormVOList);
         CacheCenter.registerNowDataMap= EquipmentParamUtils.paramListToMap(broadCastEquipmentParamFormVOList);
-        saveDataToInfluxdb(deepCopyEquipmentParamFormVOList);
+        syncsSaveDataToInfluxdb(deepCopyEquipmentParamFormVOList);
     }
 
     // 保存并广播设备数据消息
@@ -151,12 +148,4 @@ public class ModbusTcpTask {
         equipmentListWebSocketServer.broadCastInfo(JSON.toJSONString(broadCastEquipmentParamFormVOList));
     }
 
-    public void broacastEquipmentTree() {
-        // 拷贝设备信息
-//        List<EquipmentParamFormVo> deepCopyEquipmentParamFormVOList = broadCastEquipmentParamFormVOList;
-//        for (EquipmentParamFormVo equipmentParamFormVo : broadCastEquipmentParamFormVOList) {
-//            deepCopyEquipmentParamFormVOList.add(equipmentParamFormVo.clone());
-//        }
-    }
-
 }

+ 93 - 38
admin/src/main/java/com/dcs/equipment/utils/ModbusUtil.java

@@ -1,6 +1,6 @@
 package com.dcs.equipment.utils;
 
-import com.dcs.equipment.domain.ModbusRequest;
+import com.dcs.equipment.domain.DeviceRequest;
 import com.dcs.hnyz.domain.EquipmentParam;
 import com.intelligt.modbus.jlibmodbus.Modbus;
 import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
@@ -15,9 +15,11 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import static com.dcs.equipment.constants.ModbusConstants.*;
 import static com.dcs.equipment.domain.ModbusTcpEnum.DATA_ADDRESS_LENGTH_MAP;
@@ -37,27 +39,40 @@ public class ModbusUtil {
 
     public static void main(String[] args) throws Exception {
         TcpParameters tcpParameters = new TcpParameters();
-        InetAddress address = InetAddress.getByName("200.200.200.10");
+        InetAddress address = null;
+        try {
+            address = InetAddress.getByName("200.200.200.10");
+        } catch (UnknownHostException e) {
+            // 日志记录 广播异常信息
+            e.printStackTrace();
+            MASTER = null;
+        }
         tcpParameters.setHost(address);
         tcpParameters.setPort(502);
         tcpParameters.setKeepAlive(true);
         Modbus.setAutoIncrementTransactionId(true);
         ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
         MASTER = master;
-        master.connect();// 开启连接
+//        master.connect();// 开启连接
+        try {
+            MASTER.connect();
+        } catch (ModbusIOException e) {
+            // 日志记录 广播异常信息
+            e.printStackTrace();
+            MASTER = null;
+        }
         // 从机模拟 1线圈 2输入 3保持
         int i = 1;
         float[] holdingRegistersFloatValues = getHoldingRegistersFloatValues(1, 712, 26);
         for (float f : holdingRegistersFloatValues) {
             System.out.println("第 " + i++ + " Value: " + f);
         }
-//        setCo
-        master.disconnect();
+        MASTER.disconnect();
     }
 
-    public static List<ModbusRequest> getModbusRequests(List<EquipmentParam> equipmentParamList) {
+    public static List<DeviceRequest> getDeviceRequests(List<EquipmentParam> equipmentParamList) {
         // 保存modbus请求信息
-        List<ModbusRequest> modbusRequestList = new ArrayList<>();
+        List<DeviceRequest> modbusRequestList = new ArrayList<>();
         // 根据功能码分类的设备信息
         Map<String, List<EquipmentParam>> responseMap = new HashMap<>();
         // 根据功能码分类的设备地址信息
@@ -109,12 +124,12 @@ public class ModbusUtil {
                 int readQuantityLength = MathUtil.ceil((lastAddress - firstAddress), DATA_ADDRESS_LENGTH_MAP.get(dataType));
                 // 根据读取长度分段读取 超过一次可读取的长度的地址将被分为多个请求
                 for (int i = 1; i <= MathUtil.ceil(readQuantityLength, DATA_TYPE_LENGTH_MAP.get(dataType)); i++){
-                    ModbusRequest modbusRequest = new ModbusRequest();
+                    DeviceRequest modbusRequest = new DeviceRequest();
                     // TODO 设备从机地址需要从数据库中获取
-                    modbusRequest.setSlaveId(1);
-                    modbusRequest.setFunctionCode(registerCode);
+                    modbusRequest.setUnitId(1);
+                    modbusRequest.setResource(registerCode);
                     modbusRequest.setDataType(dataType);
-                    modbusRequest.setStartAddress(addresses.get(0) + (DATA_TYPE_LENGTH_MAP.get(dataType) * (i - 1) * DATA_ADDRESS_LENGTH_MAP.get(dataType)));
+                    modbusRequest.setOffsetOrIndex(addresses.get(0) + (DATA_TYPE_LENGTH_MAP.get(dataType) * (i - 1) * DATA_ADDRESS_LENGTH_MAP.get(dataType)));
                     int quantity;
                     // 读取长度是否超过一次可读取的长度
                     if (readQuantityLength < DATA_TYPE_LENGTH_MAP.get(dataType) * i) {
@@ -124,7 +139,7 @@ public class ModbusUtil {
                         // 超过
                         quantity = (int) Math.ceil(DATA_TYPE_LENGTH_MAP.get(dataType));
                     }
-                    modbusRequest.setQuantity(quantity);
+                    modbusRequest.setLengthOrQos(quantity);
                     modbusRequestList.add(modbusRequest);
                 }
             }
@@ -132,13 +147,23 @@ public class ModbusUtil {
         return modbusRequestList;
     }
 
-    private static TcpParameters TCP_PARAMETERS;
     private static ModbusMaster MASTER;
-    private static final Object MASTER_LOCK = new Object();
+
+    private static final int reconnectingCount = 5; // 单次重连 最多尝试次数
 
     @PostConstruct // 启动时spring容器调用该方法初始化
-    public void init() throws InterruptedException {
-        TCP_PARAMETERS = new TcpParameters();
+    public void init() {
+        initMasterSetting();
+        try {
+            MASTER.connect();
+            logger.info("连接 PLC");
+        } catch (ModbusIOException e) {
+            logger.error("PLC 初始化连接失败");
+        }
+    }
+
+    private void initMasterSetting() {
+        TcpParameters TCP_PARAMETERS = new TcpParameters();
         InetAddress address = null;
         try {
             address = InetAddress.getByName(HOST);
@@ -149,30 +174,60 @@ public class ModbusUtil {
         TCP_PARAMETERS.setPort(PORT);
         MASTER = ModbusMasterFactory.createModbusMasterTCP(TCP_PARAMETERS);
         Modbus.setAutoIncrementTransactionId(true);
-        boolean flag = true;
-        int i = 0;
-        while (flag) {
+    }
+
+    @PreDestroy
+    public void destroy() {
+        if (MASTER!= null && MASTER.isConnected()) {
             try {
-                getMaster();
-                flag = false;
+                MASTER.disconnect();
+                logger.info("PLC 断开连接");
             } catch (ModbusIOException e) {
-                logger.error("与 PLC 连接失败, 一秒后尝试重连...." + i++);
-                logger.error("错误码: " + e.getMessage());
-                Thread.sleep(1000);
+                logger.error("与 PLC 断开连接失败");
             }
         }
     }
 
+    private static final AtomicBoolean reconnecting = new AtomicBoolean(false);
+
     private static ModbusMaster getMaster() throws ModbusIOException {
-            if (!MASTER.isConnected()) { // 连接断开时,重新连接
-                synchronized (MASTER_LOCK) { // 加锁 避免多线程并发连接
-                    if (!MASTER.isConnected()) {
-                        logger.error("与 PLC 连接断开,尝试重新连接...");
-                        MASTER.connect();
+        if (!MASTER.isConnected()) {
+            reconnect(); // 启动后台重连,不会重复启动
+            throw new ModbusIOException("PLC 连接断开,正在尝试自动重连...");
+        }
+        return MASTER;
+    }
+
+    private static void reconnect() {
+        if (reconnecting.get()) return; // 已在重连中,直接返回
+
+        if (reconnecting.compareAndSet(false, true)) {
+            new Thread(() -> {
+                try {
+                    for (int i = 0; i < reconnectingCount; i++) { // 单次重连 最多尝试次数
+                        try {
+                            logger.warn("PLC 连接断开,开始重连...");
+                            MASTER.connect();
+                            if (MASTER.isConnected()) {
+                                logger.info("PLC 重连成功!");
+                                break;
+                            }
+                        } catch (ModbusIOException e) {
+                            logger.error("PLC 重连失败: {}", e.getMessage());
+                        }
+
+                        try {
+                            Thread.sleep(1000); // 每次重试间隔 1 秒
+                        } catch (InterruptedException e) {
+                            Thread.currentThread().interrupt();
+                            break;
+                        }
                     }
+                } finally {
+                    reconnecting.set(false); // 重连结束,允许后续再次触发
                 }
-            }
-        return MASTER;
+            }, "PLC-Reconnect-Thread").start();
+        }
     }
 
     /**
@@ -355,23 +410,23 @@ public class ModbusUtil {
         return getCoilValues(slaveId, offset, 1)[0];
     }
 
-    public static List<Object> getValues(ModbusRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
-        switch (request.getFunctionCode()) {
+    public static List<Object> getValues(DeviceRequest request) throws ModbusProtocolException, ModbusNumberException, ModbusIOException {
+        switch (request.getResource()) {
             case COIL_FUNCTION_CODE:
-                return convertArrayToList(getCoilValues(request.getSlaveId(), request.getStartAddress(), request.getQuantity()));
+                return convertArrayToList(getCoilValues(request.getUnitId(), request.getOffsetOrIndex(), request.getLengthOrQos()));
             case INPUT_FUNCTION_CODE:
                 switch (request.getDataType()) {
                     case INT_DATA_TYPE:
-                        return convertArrayToList(getInputRegisterValues(request.getSlaveId(), request.getStartAddress(), request.getQuantity()));
+                        return convertArrayToList(getInputRegisterValues(request.getUnitId(), request.getOffsetOrIndex(), request.getLengthOrQos()));
                     case FLOAT_DATA_TYPE:
-                        return convertArrayToList(getInputRegisterFloatValues(request.getSlaveId(), request.getStartAddress(), request.getQuantity()));
+                        return convertArrayToList(getInputRegisterFloatValues(request.getUnitId(), request.getOffsetOrIndex(), request.getLengthOrQos()));
                 }
             case HOLDING_FUNCTION_CODE:
                 switch (request.getDataType()) {
                     case INT_DATA_TYPE:
-                        return convertArrayToList(getHoldingRegisterValues(request.getSlaveId(), request.getStartAddress(), request.getQuantity()));
+                        return convertArrayToList(getHoldingRegisterValues(request.getUnitId(), request.getOffsetOrIndex(), request.getLengthOrQos()));
                     case FLOAT_DATA_TYPE:
-                        return convertArrayToList(getHoldingRegistersFloatValues(request.getSlaveId(), request.getStartAddress(), request.getQuantity()));
+                        return convertArrayToList(getHoldingRegistersFloatValues(request.getUnitId(), request.getOffsetOrIndex(), request.getLengthOrQos()));
                 }
             default:
                 return Collections.emptyList();