告警保护方案轮询-初稿
This commit is contained in:
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user