告警保护方案轮询-初稿

This commit is contained in:
2025-10-29 18:38:34 +08:00
parent 614cca4297
commit 82e63e28d3
9 changed files with 803 additions and 6 deletions

View File

@ -95,7 +95,7 @@ public class ModbusConnectionManager implements ApplicationRunner {
*/
private TCPMasterConnection createRawConnection(EmsDevicesSetting device) throws Exception {
try {
InetAddress addr = InetAddress.getByName("192.168.80.100");
InetAddress addr = InetAddress.getByName("10.1.0.230");
TCPMasterConnection connection = new TCPMasterConnection(addr);
connection.setPort(502);
connection.setTimeout(5000);

View File

@ -2,11 +2,16 @@ package com.xzzn.framework.web.service;
import com.ghgande.j2mod.modbus.ModbusException;
import com.ghgande.j2mod.modbus.ModbusIOException;
import com.ghgande.j2mod.modbus.io.ModbusSerialTransaction;
import com.ghgande.j2mod.modbus.io.ModbusTCPTransaction;
import com.ghgande.j2mod.modbus.msg.ReadInputRegistersRequest;
import com.ghgande.j2mod.modbus.msg.ReadInputRegistersResponse;
import com.ghgande.j2mod.modbus.msg.WriteMultipleRegistersRequest;
import com.ghgande.j2mod.modbus.msg.WriteSingleRegisterRequest;
import com.ghgande.j2mod.modbus.net.SerialConnection;
import com.ghgande.j2mod.modbus.net.TCPMasterConnection;
import com.ghgande.j2mod.modbus.procimg.Register;
import com.ghgande.j2mod.modbus.procimg.SimpleRegister;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -42,8 +47,26 @@ public class ModbusService {
}
}
private int[] readRtuRegisters(SerialConnection connection, int startAddr, int count) {
return null;
private int[] readRtuRegisters(SerialConnection connection, int startAddr, int count) throws ModbusException {
if (!connection.isOpen()) {
throw new ModbusIOException("RTU连接未建立");
}
ReadInputRegistersRequest request = new ReadInputRegistersRequest(startAddr, count);
ModbusSerialTransaction transaction = new ModbusSerialTransaction(connection);
transaction.setRequest(request);
transaction.setRetries(2);
try {
transaction.execute();
ReadInputRegistersResponse response = (ReadInputRegistersResponse) transaction.getResponse();
if (response == null) {
throw new ModbusException("RTU响应为空");
}
return parseRegisters(response);
} catch (ModbusException e) {
logger.error("读取RTU寄存器失败: {}", e.getMessage());
throw e;
}
}
private int[] readTcpRegisters(TCPMasterConnection conn, int start, int count) throws ModbusException {
@ -98,4 +121,159 @@ public class ModbusService {
return new int[0];
}
/**
* 写入单个寄存器支持TCP/RTU
* @param connection 连接对象TCPMasterConnection 或 SerialConnection
* @param registerAddr 寄存器地址
* @param value 要写入的值16位整数
*/
@Retryable(
value = {ModbusException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000, multiplier = 2)
)
@CircuitBreaker(name = "modbusOperation", fallbackMethod = "writeRegisterFallback")
public boolean writeSingleRegister(Object connection, int registerAddr, int value) throws ModbusException {
try {
if (connection instanceof TCPMasterConnection) {
return writeTcpSingleRegister((TCPMasterConnection) connection, registerAddr, value);
} else if (connection instanceof SerialConnection) {
return writeRtuSingleRegister((SerialConnection) connection, registerAddr, value);
}
throw new IllegalArgumentException("不支持的连接类型: " + connection.getClass().getName());
} catch (ModbusIOException e) {
throw new ModbusException("写入通信故障", e);
} catch (Exception e) {
throw new ModbusException("写入系统错误", e);
}
}
/**
* 写入多个寄存器支持TCP/RTU
* @param connection 连接对象
* @param startAddr 起始寄存器地址
* @param values 要写入的值数组每个值为16位整数
*/
@Retryable(
value = {ModbusException.class},
maxAttempts = 3,
backoff = @Backoff(delay = 1000, multiplier = 2)
)
@CircuitBreaker(name = "modbusOperation", fallbackMethod = "writeRegisterFallback")
public boolean writeMultipleRegisters(Object connection, int startAddr, int[] values) throws ModbusException {
try {
if (connection instanceof TCPMasterConnection) {
return writeTcpMultipleRegisters((TCPMasterConnection) connection, startAddr, values);
} else if (connection instanceof SerialConnection) {
return writeRtuMultipleRegisters((SerialConnection) connection, startAddr, values);
}
throw new IllegalArgumentException("不支持的连接类型: " + connection.getClass().getName());
} catch (ModbusIOException e) {
throw new ModbusException("写入通信故障", e);
} catch (Exception e) {
throw new ModbusException("写入系统错误", e);
}
}
// ==================== TCP写入实现 ====================
private boolean writeTcpSingleRegister(TCPMasterConnection conn, int registerAddr, int value) throws ModbusException {
if (!conn.isConnected()) {
throw new ModbusIOException("TCP连接未建立无法写入");
}
// 创建写入单个寄存器的请求功能码06
WriteSingleRegisterRequest request = new WriteSingleRegisterRequest(registerAddr, new SimpleRegister(value));
ModbusTCPTransaction transaction = new ModbusTCPTransaction(conn);
transaction.setRequest(request);
transaction.setRetries(2);
try {
transaction.execute();
logger.info("TCP写入单个寄存器成功地址:{},值:{}", registerAddr, value);
return true;
} catch (ModbusException e) {
logger.error("TCP写入单个寄存器失败地址:{},值:{}", registerAddr, value, e);
throw e;
}
}
private boolean writeTcpMultipleRegisters(TCPMasterConnection conn, int startAddr, int[] values) throws ModbusException {
if (!conn.isConnected()) {
throw new ModbusIOException("TCP连接未建立无法写入");
}
// 转换值数组为寄存器数组
Register[] registers = new Register[values.length];
for (int i = 0; i < values.length; i++) {
registers[i] = new SimpleRegister(values[i]);
}
// 创建写入多个寄存器的请求功能码16
WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest(startAddr, registers);
ModbusTCPTransaction transaction = new ModbusTCPTransaction(conn);
transaction.setRequest(request);
transaction.setRetries(2);
try {
transaction.execute();
logger.info("TCP写入多个寄存器成功起始地址:{},数量:{}", startAddr, values.length);
return true;
} catch (ModbusException e) {
logger.error("TCP写入多个寄存器失败起始地址:{}", startAddr, e);
throw e;
}
}
// ==================== RTU写入实现 ====================
private boolean writeRtuSingleRegister(SerialConnection connection, int registerAddr, int value) throws ModbusException {
if (!connection.isOpen()) {
throw new ModbusIOException("RTU串口未打开请先建立连接");
}
WriteSingleRegisterRequest request = new WriteSingleRegisterRequest(registerAddr, new SimpleRegister(value));
ModbusSerialTransaction transaction = new ModbusSerialTransaction(connection);
transaction.setRequest(request);
transaction.setRetries(2);
try {
transaction.execute();
logger.info("RTU写入单个寄存器成功地址:{},值:{}", registerAddr, value);
return true;
} catch (ModbusException e) {
logger.error("RTU写入单个寄存器失败地址:{},值:{}", registerAddr, value, e);
throw e;
}
}
private boolean writeRtuMultipleRegisters(SerialConnection connection, int startAddr, int[] values) throws ModbusException {
if (!connection.isOpen()) {
throw new ModbusIOException("RTU串口未打开请先建立连接");
}
Register[] registers = new Register[values.length];
for (int i = 0; i < values.length; i++) {
registers[i] = new SimpleRegister(values[i]);
}
WriteMultipleRegistersRequest request = new WriteMultipleRegistersRequest(startAddr, registers);
ModbusSerialTransaction transaction = new ModbusSerialTransaction(connection);
transaction.setRequest(request);
transaction.setRetries(2);
try {
transaction.execute();
logger.info("RTU写入多个寄存器成功起始地址:{},数量:{}", startAddr, values.length);
return true;
} catch (ModbusException e) {
logger.error("RTU写入多个寄存器失败起始地址:{}", startAddr, e);
throw e;
}
}
// ==================== 写入操作的降级方法 ====================
public boolean writeRegisterFallback(Object connection, int addr, int value, Exception e) {
logger.warn("写入单个寄存器降级(原因: {}),地址:{}", e.getMessage(), addr);
return false;
}
public boolean writeRegisterFallback(Object connection, int startAddr, int[] values, Exception e) {
logger.warn("写入多个寄存器降级(原因: {}),起始地址:{}", e.getMessage(), startAddr);
return false;
}
}