fix: modbustcp读功能与测试
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package org.nl.iot.core.driver.protocol.modbustcp;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.common.exception.CommonException;
|
||||
import org.nl.iot.core.driver.bo.AttributeBO;
|
||||
@@ -20,6 +21,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* modbus-tcp通信协议的驱动自定义服务实现类
|
||||
@@ -38,8 +40,9 @@ public class ModBusProtocolDriverImpl implements DriverCustomService {
|
||||
private Map<String, ModbusMaster> connectMap;
|
||||
|
||||
@Override
|
||||
@PostConstruct
|
||||
public void initial() {
|
||||
|
||||
connectMap = new ConcurrentHashMap<>(16);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,22 +107,25 @@ public class ModBusProtocolDriverImpl implements DriverCustomService {
|
||||
int slaveId = pointConfig.get("slaveId").getValueByClass(Integer.class);
|
||||
int offset = pointConfig.get("offset").getValueByClass(Integer.class);
|
||||
int functionCode = getFunctionCode(offset);
|
||||
|
||||
// 计算实际的寄存器地址(Modbus协议地址从0开始)
|
||||
int actualAddress = getActualAddress(offset, functionCode);
|
||||
|
||||
switch (functionCode) {
|
||||
case 1:
|
||||
BaseLocator<Boolean> coilLocator = BaseLocator.coilStatus(slaveId, offset);
|
||||
BaseLocator<Boolean> coilLocator = BaseLocator.coilStatus(slaveId, actualAddress);
|
||||
Boolean coilValue = getMasterValue(modbusMaster, coilLocator);
|
||||
return String.valueOf(coilValue);
|
||||
case 2:
|
||||
BaseLocator<Boolean> inputLocator = BaseLocator.inputStatus(slaveId, offset);
|
||||
BaseLocator<Boolean> inputLocator = BaseLocator.inputStatus(slaveId, actualAddress);
|
||||
Boolean inputStatusValue = getMasterValue(modbusMaster, inputLocator);
|
||||
return String.valueOf(inputStatusValue);
|
||||
case 3:
|
||||
BaseLocator<Number> holdingLocator = BaseLocator.holdingRegister(slaveId, offset, getValueType(type));
|
||||
BaseLocator<Number> holdingLocator = BaseLocator.holdingRegister(slaveId, actualAddress, getValueType(type));
|
||||
Number holdingValue = getMasterValue(modbusMaster, holdingLocator);
|
||||
return String.valueOf(holdingValue);
|
||||
case 4:
|
||||
BaseLocator<Number> inputRegister = BaseLocator.inputRegister(slaveId, offset, getValueType(type));
|
||||
BaseLocator<Number> inputRegister = BaseLocator.inputRegister(slaveId, actualAddress, getValueType(type));
|
||||
Number inputRegisterValue = getMasterValue(modbusMaster, inputRegister);
|
||||
return String.valueOf(inputRegisterValue);
|
||||
default:
|
||||
@@ -179,26 +185,58 @@ public class ModBusProtocolDriverImpl implements DriverCustomService {
|
||||
|
||||
/**
|
||||
* 根据Modbus地址偏移量获取对应的功能码
|
||||
* 注意:不同厂商对地址范围的定义可能不同,这里采用常见的约定:
|
||||
* - 00001-09999: 功能码01 (线圈 Coil)
|
||||
* - 10001-19999: 功能码02 (离散输入 Discrete Input)
|
||||
* - 30001-39999: 功能码04 (输入寄存器 Input Register)
|
||||
* - 40001-49999: 功能码03 (保持寄存器 Holding Register)
|
||||
*
|
||||
* @param offset 地址偏移量(1-9999/10001-19999/30001-39999/40001-49999)
|
||||
* @return 对应的功能码(1-4)
|
||||
* @throws CommonException 当偏移量不在合法范围时抛出异常
|
||||
*/
|
||||
|
||||
public static int getFunctionCode(int offset) {
|
||||
int functionCode;
|
||||
|
||||
if (offset >= 1 && offset <= 9999) {
|
||||
functionCode = 1;
|
||||
functionCode = 1; // 线圈
|
||||
} else if (offset >= 10001 && offset <= 19999) {
|
||||
functionCode = 2;
|
||||
functionCode = 2; // 离散输入
|
||||
} else if (offset >= 30001 && offset <= 39999) {
|
||||
functionCode = 3;
|
||||
functionCode = 4; // 输入寄存器
|
||||
} else if (offset >= 40001 && offset <= 49999) {
|
||||
functionCode = 4;
|
||||
functionCode = 3; // 保持寄存器
|
||||
} else {
|
||||
throw new CommonException("无效的偏移量:" + offset);
|
||||
}
|
||||
|
||||
return functionCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据Modbus地址偏移量和功能码计算实际的寄存器地址
|
||||
* Modbus协议中,寄存器地址从0开始,需要减去相应的偏移量
|
||||
*
|
||||
* @param offset 地址偏移量(1-9999/10001-19999/30001-39999/40001-49999)
|
||||
* @param functionCode 功能码(1-4)
|
||||
* @return 实际的寄存器地址(从0开始)
|
||||
*/
|
||||
private int getActualAddress(int offset, int functionCode) {
|
||||
switch (functionCode) {
|
||||
case 1:
|
||||
// 线圈状态:1-9999 -> 0-9998
|
||||
return offset - 1;
|
||||
case 2:
|
||||
// 离散输入:10001-19999 -> 0-9998
|
||||
return offset - 10001;
|
||||
case 3:
|
||||
// 保持寄存器:40001-49999 -> 0-9998
|
||||
return offset - 40001;
|
||||
case 4:
|
||||
// 输入寄存器:30001-39999 -> 0-9998
|
||||
return offset - 30001;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user