fix: modbus协议读写改造
This commit is contained in:
@@ -1,21 +1,21 @@
|
||||
package org.nl;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.nl.iot.core.driver.bo.AttributeBO;
|
||||
import org.nl.iot.core.driver.bo.DeviceBO;
|
||||
import org.nl.iot.core.driver.bo.SiteBO;
|
||||
import org.nl.iot.core.driver.entity.RValue;
|
||||
import org.nl.iot.core.driver.entity.WResponse;
|
||||
import org.nl.iot.core.driver.entity.WValue;
|
||||
import org.nl.iot.core.driver.protocol.modbustcp.ModBusProtocolDriverImpl;
|
||||
import org.nl.iot.core.driver.protocol.opcda.OpcDaProtocolDriverImpl;
|
||||
import org.nl.iot.core.driver.protocol.opcua.OpcUaProtocolDriverImpl;
|
||||
import org.nl.iot.core.driver.protocol.plcs7.PlcS7ProtocolDriverImpl;
|
||||
import org.nl.iot.modular.iot.entity.IotConfig;
|
||||
import org.nl.iot.modular.iot.entity.IotConnect;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -32,23 +32,15 @@ public class ApiTest {
|
||||
|
||||
@Test
|
||||
public void modbusTest() {
|
||||
// 构建驱动配置(连接配置)
|
||||
Map<String, AttributeBO> driverConfig = new HashMap<>();
|
||||
driverConfig.put("host", AttributeBO.builder().value("192.168.81.251").build());
|
||||
driverConfig.put("port", AttributeBO.builder().value("502").build());
|
||||
|
||||
// 构建点位配置
|
||||
Map<String, AttributeBO> pointConfig = new HashMap<>();
|
||||
pointConfig.put("slaveId", AttributeBO.builder().value("1").build());
|
||||
pointConfig.put("offset", AttributeBO.builder().value("40001").build()); // 功能码3:保持寄存器
|
||||
pointConfig.put("data_type", AttributeBO.builder().value("int16").build());
|
||||
|
||||
// 构建连接对象
|
||||
JSONObject o = new JSONObject();
|
||||
o.put("slaveId", "1");
|
||||
IotConnect connect = IotConnect.builder()
|
||||
.id(1)
|
||||
.code("MODBUS_TCP_001")
|
||||
.host("192.168.81.251")
|
||||
.port(502)
|
||||
.properties(JSONObject.toJSONString(o))
|
||||
.protocol("modbus-tcp")
|
||||
.enabled(true)
|
||||
.description("测试Modbus TCP连接")
|
||||
@@ -61,614 +53,414 @@ public class ApiTest {
|
||||
.alias("temperature")
|
||||
.aliasName("温度传感器")
|
||||
.registerAddress("40001")
|
||||
.dataType("int16")
|
||||
.dataType("INT")
|
||||
.readonly(true)
|
||||
.enabled(true)
|
||||
.description("测试温度读取")
|
||||
.build();
|
||||
|
||||
// 执行读取操作
|
||||
try {
|
||||
// 调用read方法进行测试
|
||||
RValue result = modBusProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
System.out.println("========== 开始测试Modbus TCP读取 ==========");
|
||||
System.out.println("连接信息: " + connect.getHost() + ":" + connect.getPort());
|
||||
System.out.println("寄存器地址: " + config.getRegisterAddress());
|
||||
System.out.println("数据类型: " + config.getDataType());
|
||||
|
||||
// 输出测试结果
|
||||
System.out.println("=== Modbus读取测试结果 ===");
|
||||
System.out.println("连接信息: " + result.getConnect());
|
||||
System.out.println("配置信息: " + result.getConfig());
|
||||
System.out.println("读取值: " + result.getValue());
|
||||
System.out.println("测试完成!");
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
.host(connect.getHost())
|
||||
.port(connect.getPort())
|
||||
.protocol(connect.getProtocol())
|
||||
.build();
|
||||
|
||||
// 转换为SiteBO
|
||||
SiteBO siteBO = SiteBO.builder()
|
||||
.deviceCode(connect.getCode())
|
||||
.alias(config.getAlias())
|
||||
.aliasName(config.getAliasName())
|
||||
.registerAddress(config.getRegisterAddress())
|
||||
.dataType(config.getDataType())
|
||||
.readonly(config.getReadonly())
|
||||
.build();
|
||||
|
||||
// 调用驱动读取数据
|
||||
RValue result = modBusProtocolDriver.read(deviceBO, siteBO);
|
||||
|
||||
System.out.println("读取成功!");
|
||||
System.out.println("读取结果: " + result.getValue());
|
||||
System.out.println("========== 测试完成 ==========");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("测试失败: " + e.getMessage());
|
||||
// e.printStackTrace();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modbusTestWrite() {
|
||||
// 构建驱动配置(连接配置)
|
||||
Map<String, AttributeBO> driverConfig = new HashMap<>();
|
||||
driverConfig.put("host", AttributeBO.builder().value("192.168.81.251").build());
|
||||
driverConfig.put("port", AttributeBO.builder().value("502").build());
|
||||
|
||||
// 构建点位配置 - 写入保持寄存器(功能码3)
|
||||
Map<String, AttributeBO> pointConfig = new HashMap<>();
|
||||
pointConfig.put("slaveId", AttributeBO.builder().value("1").build());
|
||||
pointConfig.put("offset", AttributeBO.builder().value("40001").build()); // 功能码3:保持寄存器,地址0
|
||||
pointConfig.put("data_type", AttributeBO.builder().value("int16").build());
|
||||
|
||||
// 构建连接对象
|
||||
JSONObject o = new JSONObject();
|
||||
o.put("slaveId", "1");
|
||||
IotConnect connect = IotConnect.builder()
|
||||
.id(1)
|
||||
.code("MODBUS_TCP_001")
|
||||
.host("192.168.81.251")
|
||||
.port(502)
|
||||
.properties(JSONObject.toJSONString(o))
|
||||
.protocol("modbus-tcp")
|
||||
.enabled(true)
|
||||
.description("测试Modbus TCP写入连接")
|
||||
.description("测试Modbus TCP连接")
|
||||
.build();
|
||||
|
||||
// 构建配置对象
|
||||
// 构建配置对象 - 写入操作,设置为可写
|
||||
IotConfig config = IotConfig.builder()
|
||||
.id(2)
|
||||
.connectId(1)
|
||||
.alias("output_value")
|
||||
.aliasName("输出值")
|
||||
.registerAddress("40001")
|
||||
.dataType("LREAL")
|
||||
.readonly(false) // 设置为可写
|
||||
.enabled(true)
|
||||
.description("测试写入操作")
|
||||
.build();
|
||||
|
||||
// 执行写入操作
|
||||
try {
|
||||
System.out.println("========== 开始测试Modbus TCP写入 ==========");
|
||||
System.out.println("连接信息: " + connect.getHost() + ":" + connect.getPort());
|
||||
System.out.println("寄存器地址: " + config.getRegisterAddress());
|
||||
System.out.println("数据类型: " + config.getDataType());
|
||||
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
.host(connect.getHost())
|
||||
.port(connect.getPort())
|
||||
.protocol(connect.getProtocol())
|
||||
.build();
|
||||
|
||||
// 转换为SiteBO
|
||||
SiteBO siteBO = SiteBO.builder()
|
||||
.deviceCode(connect.getCode())
|
||||
.alias(config.getAlias())
|
||||
.aliasName(config.getAliasName())
|
||||
.registerAddress(config.getRegisterAddress())
|
||||
.dataType(config.getDataType())
|
||||
.readonly(config.getReadonly())
|
||||
.build();
|
||||
|
||||
// 构建写入值对象
|
||||
String writeValue = "25.5"; // 要写入的值
|
||||
WValue wValue = WValue.builder()
|
||||
.point(siteBO)
|
||||
.value(writeValue)
|
||||
.type(config.getDataType())
|
||||
.build();
|
||||
|
||||
System.out.println("写入值: " + writeValue);
|
||||
|
||||
// 调用驱动写入数据
|
||||
Boolean result = modBusProtocolDriver.write(deviceBO, wValue);
|
||||
|
||||
if (result != null && result) {
|
||||
System.out.println("写入成功!");
|
||||
System.out.println("写入结果: " + result);
|
||||
} else {
|
||||
System.out.println("写入失败!");
|
||||
}
|
||||
System.out.println("========== 测试完成 ==========");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("测试失败: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modbusBatchReadTest() {
|
||||
// 构建连接对象
|
||||
JSONObject o = new JSONObject();
|
||||
o.put("slaveId", "1");
|
||||
IotConnect connect = IotConnect.builder()
|
||||
.id(1)
|
||||
.code("MODBUS_TCP_001")
|
||||
.host("192.168.81.251")
|
||||
.port(502)
|
||||
.properties(JSONObject.toJSONString(o))
|
||||
.protocol("modbus-tcp")
|
||||
.enabled(true)
|
||||
.description("测试Modbus TCP连接")
|
||||
.build();
|
||||
|
||||
// 构建多个配置对象进行批量读取
|
||||
IotConfig config1 = IotConfig.builder()
|
||||
.id(1)
|
||||
.connectId(1)
|
||||
.alias("temperature")
|
||||
.aliasName("温度传感器")
|
||||
.registerAddress("40001")
|
||||
.dataType("int16")
|
||||
.readonly(false)
|
||||
.enabled(true)
|
||||
.description("测试温度写入")
|
||||
.build();
|
||||
|
||||
try {
|
||||
// 先读取当前值
|
||||
System.out.println("=== Modbus写入测试开始 ===");
|
||||
RValue beforeValue = modBusProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
System.out.println("写入前的值: " + beforeValue.getValue());
|
||||
|
||||
// 构建写入值对象 - 写入新的温度值(例如:100)
|
||||
org.nl.iot.core.driver.entity.WValue wValue = new org.nl.iot.core.driver.entity.WValue();
|
||||
wValue.setValue("100");
|
||||
wValue.setType("int16");
|
||||
|
||||
// 调用write方法进行写入测试
|
||||
Boolean writeResult = modBusProtocolDriver.write(driverConfig, pointConfig, connect, config, wValue);
|
||||
System.out.println("写入结果: " + (writeResult ? "成功" : "失败"));
|
||||
|
||||
// 等待一小段时间后再次读取,验证写入是否成功
|
||||
Thread.sleep(500);
|
||||
RValue afterValue = modBusProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
System.out.println("写入后的值: " + afterValue.getValue());
|
||||
|
||||
// 验证写入是否成功
|
||||
if (writeResult && "100".equals(afterValue.getValue())) {
|
||||
System.out.println("✓ 写入验证成功!值已更新为: " + afterValue.getValue());
|
||||
} else {
|
||||
System.out.println("✗ 写入验证失败!期望值: 100, 实际值: " + afterValue.getValue());
|
||||
}
|
||||
|
||||
System.out.println("=== 测试完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("测试失败: " + e.getMessage());
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private PlcS7ProtocolDriverImpl plcS7ProtocolDriver;
|
||||
|
||||
@Test
|
||||
public void plcS7TestRead() {
|
||||
// 初始化驱动
|
||||
plcS7ProtocolDriver.initial();
|
||||
|
||||
// 构建驱动配置(连接配置)
|
||||
Map<String, AttributeBO> driverConfig = new HashMap<>();
|
||||
driverConfig.put("host", AttributeBO.builder().value("192.168.10.33").build());
|
||||
driverConfig.put("port", AttributeBO.builder().value("102").build());
|
||||
|
||||
// 构建点位配置
|
||||
Map<String, AttributeBO> pointConfig = new HashMap<>();
|
||||
pointConfig.put("dbNum", AttributeBO.builder().value("1").build()); // 数据块编号
|
||||
pointConfig.put("byteOffset", AttributeBO.builder().value("0").build()); // 字节偏移量
|
||||
pointConfig.put("bitOffset", AttributeBO.builder().value("0").build()); // 位偏移量
|
||||
pointConfig.put("blockSize", AttributeBO.builder().value("1").build()); // 数据块大小
|
||||
pointConfig.put("data_type", AttributeBO.builder().value("int").build()); // 数据类型
|
||||
|
||||
// 构建连接对象
|
||||
IotConnect connect = IotConnect.builder()
|
||||
.id(1)
|
||||
.code("PLC_S7_001")
|
||||
.host("192.168.10.33")
|
||||
.port(102)
|
||||
.protocol("plc-s7")
|
||||
.enabled(true)
|
||||
.description("测试PLC S7连接")
|
||||
.build();
|
||||
|
||||
// 构建配置对象
|
||||
IotConfig config = IotConfig.builder()
|
||||
.id(1)
|
||||
.connectId(1)
|
||||
.alias("pressure")
|
||||
.aliasName("压力传感器")
|
||||
.registerAddress("DB1.DBW0")
|
||||
.dataType("int")
|
||||
.dataType("INT")
|
||||
.readonly(true)
|
||||
.enabled(true)
|
||||
.description("测试PLC S7数据读取")
|
||||
.description("测试温度读取")
|
||||
.build();
|
||||
|
||||
try {
|
||||
System.out.println("=== PLC S7读取测试开始 ===");
|
||||
System.out.println("连接地址: " + driverConfig.get("host").getValue() + ":" + driverConfig.get("port").getValue());
|
||||
System.out.println("数据块: DB" + pointConfig.get("dbNum").getValue() +
|
||||
", 偏移: " + pointConfig.get("byteOffset").getValue() +
|
||||
", 类型: " + pointConfig.get("data_type").getValue());
|
||||
|
||||
// 调用read方法进行测试
|
||||
RValue result = plcS7ProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
|
||||
// 检查结果是否为null
|
||||
if (result != null) {
|
||||
System.out.println("\n✓ 读取成功!");
|
||||
System.out.println("连接信息: " + result.getConnect());
|
||||
System.out.println("配置信息: " + result.getConfig());
|
||||
System.out.println("读取值: " + result.getValue());
|
||||
} else {
|
||||
System.err.println("\n✗ 读取失败:返回结果为null");
|
||||
System.err.println("可能原因:");
|
||||
System.err.println("1. PLC设备未连接或IP地址不正确");
|
||||
System.err.println("2. 端口号配置错误(S7-300/400默认102)");
|
||||
System.err.println("3. 数据块(DB)不存在或无访问权限");
|
||||
System.err.println("4. 数据类型或偏移量配置错误");
|
||||
}
|
||||
|
||||
System.out.println("\n=== 测试完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("\n✗ 测试异常: " + e.getMessage());
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void plcS7TestWrite() {
|
||||
// 初始化驱动
|
||||
plcS7ProtocolDriver.initial();
|
||||
|
||||
// 构建驱动配置(连接配置)
|
||||
Map<String, AttributeBO> driverConfig = new HashMap<>();
|
||||
driverConfig.put("host", AttributeBO.builder().value("192.168.10.33").build());
|
||||
driverConfig.put("port", AttributeBO.builder().value("102").build());
|
||||
|
||||
// 构建点位配置
|
||||
Map<String, AttributeBO> pointConfig = new HashMap<>();
|
||||
pointConfig.put("dbNum", AttributeBO.builder().value("1").build()); // 数据块编号
|
||||
pointConfig.put("byteOffset", AttributeBO.builder().value("0").build()); // 字节偏移量
|
||||
pointConfig.put("bitOffset", AttributeBO.builder().value("0").build()); // 位偏移量
|
||||
pointConfig.put("blockSize", AttributeBO.builder().value("1").build()); // 数据块大小
|
||||
pointConfig.put("data_type", AttributeBO.builder().value("int").build()); // 数据类型
|
||||
|
||||
// 构建连接对象
|
||||
IotConnect connect = IotConnect.builder()
|
||||
.id(1)
|
||||
.code("PLC_S7_001")
|
||||
.host("192.168.10.33")
|
||||
.port(102)
|
||||
.protocol("plc-s7")
|
||||
.enabled(true)
|
||||
.description("测试PLC S7写入连接")
|
||||
.build();
|
||||
|
||||
// 构建配置对象
|
||||
IotConfig config = IotConfig.builder()
|
||||
.id(1)
|
||||
IotConfig config2 = IotConfig.builder()
|
||||
.id(2)
|
||||
.connectId(1)
|
||||
.alias("pressure")
|
||||
.aliasName("压力传感器")
|
||||
.registerAddress("DB1.DBW0")
|
||||
.dataType("int")
|
||||
.readonly(false)
|
||||
.alias("humidity")
|
||||
.aliasName("湿度传感器")
|
||||
.registerAddress("40002")
|
||||
.dataType("INT")
|
||||
.readonly(true)
|
||||
.enabled(true)
|
||||
.description("测试PLC S7数据写入")
|
||||
.description("测试湿度读取")
|
||||
.build();
|
||||
|
||||
// IotConfig config3 = IotConfig.builder()
|
||||
// .id(3)
|
||||
// .connectId(1)
|
||||
// .alias("press")
|
||||
// .aliasName("压力传感器")
|
||||
// .registerAddress("40003")
|
||||
// .dataType("LREAL")
|
||||
// .readonly(true)
|
||||
// .enabled(true)
|
||||
// .description("测试状态读取")
|
||||
// .build();
|
||||
IotConfig config4 = IotConfig.builder()
|
||||
.id(4)
|
||||
.connectId(1)
|
||||
.alias("move")
|
||||
.aliasName("有无货")
|
||||
.registerAddress("40008")
|
||||
.dataType("SSSS")
|
||||
.readonly(true)
|
||||
.enabled(true)
|
||||
.description("测试状态读取")
|
||||
.build();
|
||||
|
||||
// 执行批量读取操作
|
||||
try {
|
||||
System.out.println("=== PLC S7写入测试开始 ===");
|
||||
System.out.println("========== 开始测试Modbus TCP批量读取 ==========");
|
||||
System.out.println("连接信息: " + connect.getHost() + ":" + connect.getPort());
|
||||
|
||||
// 先读取当前值
|
||||
RValue beforeValue = plcS7ProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
if (beforeValue != null) {
|
||||
System.out.println("写入前的值: " + beforeValue.getValue());
|
||||
} else {
|
||||
System.out.println("写入前读取失败,继续执行写入测试...");
|
||||
}
|
||||
|
||||
// 构建写入值对象 - 写入新的压力值(例如:200)
|
||||
WValue wValue = new WValue();
|
||||
wValue.setValue("200");
|
||||
wValue.setType("int");
|
||||
|
||||
// 调用write方法进行写入测试
|
||||
Boolean writeResult = plcS7ProtocolDriver.write(driverConfig, pointConfig, connect, config, wValue);
|
||||
System.out.println("写入结果: " + (writeResult ? "成功" : "失败"));
|
||||
|
||||
// 等待一小段时间后再次读取,验证写入是否成功
|
||||
Thread.sleep(500);
|
||||
RValue afterValue = plcS7ProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
.host(connect.getHost())
|
||||
.port(connect.getPort())
|
||||
.protocol(connect.getProtocol())
|
||||
.build();
|
||||
|
||||
if (afterValue != null) {
|
||||
System.out.println("写入后的值: " + afterValue.getValue());
|
||||
|
||||
// 验证写入是否成功
|
||||
if (writeResult && "200".equals(afterValue.getValue())) {
|
||||
System.out.println("✓ 写入验证成功!值已更新为: " + afterValue.getValue());
|
||||
} else {
|
||||
System.out.println("✗ 写入验证失败!期望值: 200, 实际值: " + afterValue.getValue());
|
||||
}
|
||||
} else {
|
||||
System.err.println("写入后读取失败,无法验证写入结果");
|
||||
// 转换为SiteBO列表
|
||||
java.util.List<SiteBO> siteBOList = java.util.Arrays.asList(
|
||||
SiteBO.builder()
|
||||
.deviceCode(connect.getCode())
|
||||
.alias(config1.getAlias())
|
||||
.aliasName(config1.getAliasName())
|
||||
.registerAddress(config1.getRegisterAddress())
|
||||
.dataType(config1.getDataType())
|
||||
.readonly(config1.getReadonly())
|
||||
.build(),
|
||||
SiteBO.builder()
|
||||
.deviceCode(connect.getCode())
|
||||
.alias(config2.getAlias())
|
||||
.aliasName(config2.getAliasName())
|
||||
.registerAddress(config2.getRegisterAddress())
|
||||
.dataType(config2.getDataType())
|
||||
.readonly(config2.getReadonly())
|
||||
.build()
|
||||
// SiteBO.builder()
|
||||
// .deviceCode(connect.getCode())
|
||||
// .alias(config3.getAlias())
|
||||
// .aliasName(config3.getAliasName())
|
||||
// .registerAddress(config3.getRegisterAddress())
|
||||
// .dataType(config3.getDataType())
|
||||
// .readonly(config3.getReadonly())
|
||||
// .build(),
|
||||
// SiteBO.builder()
|
||||
// .deviceCode(connect.getCode())
|
||||
// .alias(config4.getAlias())
|
||||
// .aliasName(config4.getAliasName())
|
||||
// .registerAddress(config4.getRegisterAddress())
|
||||
// .dataType(config4.getDataType())
|
||||
// .readonly(config4.getReadonly())
|
||||
// .build()
|
||||
);
|
||||
|
||||
System.out.println("批量读取点位数量: " + siteBOList.size());
|
||||
for (SiteBO site : siteBOList) {
|
||||
System.out.println(" - " + site.getAliasName() + " (" + site.getAlias() + "): " +
|
||||
site.getRegisterAddress() + " [" + site.getDataType() + "]");
|
||||
}
|
||||
|
||||
System.out.println("\n=== 测试完成 ===");
|
||||
|
||||
|
||||
// 调用驱动批量读取数据
|
||||
List<RValue> result = modBusProtocolDriver.batchRead(deviceBO, siteBOList);
|
||||
|
||||
System.out.println("批量读取成功!");
|
||||
System.out.println("读取结果:");
|
||||
|
||||
// 输出每个点位的读取结果
|
||||
for (RValue rValue : result) {
|
||||
SiteBO site = rValue.getSiteBO();
|
||||
String value = rValue.getValue();
|
||||
System.out.println(" - " + site.getAliasName() + " (" + site.getAlias() + "): " + value + (value == null ? "[" + rValue.getExceptionMessage() + "]" : ""));
|
||||
}
|
||||
|
||||
System.out.println("========== 批量读取测试完成 ==========");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("\n✗ 测试异常: " + e.getMessage());
|
||||
// e.printStackTrace();
|
||||
System.err.println("批量读取测试失败: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private OpcUaProtocolDriverImpl opcUaProtocolDriver;
|
||||
|
||||
@Test
|
||||
public void opcUaTestRead() {
|
||||
// 初始化驱动
|
||||
// opcUaProtocolDriver.initial();
|
||||
|
||||
// 构建驱动配置(连接配置)
|
||||
Map<String, AttributeBO> driverConfig = new HashMap<>();
|
||||
driverConfig.put("host", AttributeBO.builder().value("Lyd-ThinkBook").build());
|
||||
driverConfig.put("port", AttributeBO.builder().value("53530").build());
|
||||
driverConfig.put("path", AttributeBO.builder().value("/OPCUA/SimulationServer").build());
|
||||
|
||||
// 构建点位配置
|
||||
// 根据模拟器配置:ns=3;s=Temperature
|
||||
Map<String, AttributeBO> pointConfig = new HashMap<>();
|
||||
pointConfig.put("namespace", AttributeBO.builder().value("3").build()); // 命名空间3
|
||||
pointConfig.put("tag", AttributeBO.builder().value("Temperature").build()); // 节点标识:Temperature
|
||||
|
||||
public void modbusBatchWriteTest() {
|
||||
// 构建连接对象
|
||||
JSONObject o = new JSONObject();
|
||||
o.put("slaveId", "1");
|
||||
IotConnect connect = IotConnect.builder()
|
||||
.id(1)
|
||||
.code("OPC_UA_001")
|
||||
.host("Lyd-ThinkBook")
|
||||
.port(53530)
|
||||
.protocol("opc-ua")
|
||||
.code("MODBUS_TCP_001")
|
||||
.host("192.168.81.251")
|
||||
.port(502)
|
||||
.properties(JSONObject.toJSONString(o))
|
||||
.protocol("modbus-tcp")
|
||||
.enabled(true)
|
||||
.description("测试OPC UA连接")
|
||||
.description("测试Modbus TCP连接")
|
||||
.build();
|
||||
|
||||
// 构建配置对象
|
||||
IotConfig config = IotConfig.builder()
|
||||
// 构建多个配置对象进行批量写入
|
||||
IotConfig config1 = IotConfig.builder()
|
||||
.id(1)
|
||||
.connectId(1)
|
||||
.alias("temperature")
|
||||
.aliasName("温度传感器")
|
||||
.registerAddress("ns=3;s=Temperature") // 与模拟器配置一致
|
||||
.dataType("float") // 模拟器中是Float类型
|
||||
.readonly(true)
|
||||
.aliasName("温度")
|
||||
.registerAddress("40001")
|
||||
.dataType("INT")
|
||||
.readonly(false) // 设置为可写
|
||||
.enabled(true)
|
||||
.description("测试OPC UA数据读取")
|
||||
.description("测试批量写入1")
|
||||
.build();
|
||||
|
||||
try {
|
||||
System.out.println("=== OPC UA读取测试开始 ===");
|
||||
System.out.println("连接地址: opc.tcp://" + driverConfig.get("host").getValue() +
|
||||
":" + driverConfig.get("port").getValue() +
|
||||
driverConfig.get("path").getValue());
|
||||
System.out.println("节点信息: 命名空间=" + pointConfig.get("namespace").getValue() +
|
||||
", 标签=" + pointConfig.get("tag").getValue());
|
||||
System.out.println("完整NodeId: " + config.getRegisterAddress());
|
||||
|
||||
// 调用read方法进行测试
|
||||
RValue result = opcUaProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
|
||||
// 检查结果是否为null
|
||||
if (result != null) {
|
||||
System.out.println("\n✓ 读取成功!");
|
||||
System.out.println("连接信息: " + result.getConnect());
|
||||
System.out.println("配置信息: " + result.getConfig());
|
||||
System.out.println("读取值: " + result.getValue());
|
||||
} else {
|
||||
System.err.println("\n✗ 读取失败:返回结果为null");
|
||||
System.err.println("可能原因:");
|
||||
System.err.println("1. OPC UA服务器未启动或IP地址不正确");
|
||||
System.err.println("2. 端口号配置错误(默认4840)");
|
||||
System.err.println("3. 节点不存在或命名空间索引错误");
|
||||
System.err.println("4. 服务器需要身份验证(当前使用匿名访问)");
|
||||
}
|
||||
|
||||
System.out.println("\n=== 测试完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("\n✗ 测试异常: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void opcUaTestWrite() {
|
||||
// 初始化驱动
|
||||
opcUaProtocolDriver.initial();
|
||||
|
||||
// 构建驱动配置(连接配置)
|
||||
Map<String, AttributeBO> driverConfig = new HashMap<>();
|
||||
driverConfig.put("host", AttributeBO.builder().value("Lyd-ThinkBook").build());
|
||||
driverConfig.put("port", AttributeBO.builder().value("53530").build());
|
||||
driverConfig.put("path", AttributeBO.builder().value("/OPCUA/SimulationServer").build());
|
||||
|
||||
// 构建点位配置
|
||||
// 根据模拟器配置:ns=3;s=Temperature
|
||||
Map<String, AttributeBO> pointConfig = new HashMap<>();
|
||||
pointConfig.put("namespace", AttributeBO.builder().value("3").build()); // 命名空间3
|
||||
pointConfig.put("tag", AttributeBO.builder().value("Temperature").build()); // 节点标识:Temperature
|
||||
|
||||
// 构建连接对象
|
||||
IotConnect connect = IotConnect.builder()
|
||||
.id(1)
|
||||
.code("OPC_UA_001")
|
||||
.host("Lyd-ThinkBook")
|
||||
.port(53530)
|
||||
.protocol("opc-ua")
|
||||
.enabled(true)
|
||||
.description("测试OPC UA连接")
|
||||
.build();
|
||||
|
||||
// 构建配置对象
|
||||
IotConfig config = IotConfig.builder()
|
||||
.id(1)
|
||||
IotConfig config2 = IotConfig.builder()
|
||||
.id(2)
|
||||
.connectId(1)
|
||||
.alias("temperature")
|
||||
.aliasName("温度传感器")
|
||||
.registerAddress("ns=3;s=Temperature") // 与模拟器配置一致
|
||||
.dataType("float") // 模拟器中是Float类型
|
||||
.readonly(true)
|
||||
.alias("humidity")
|
||||
.aliasName("湿度")
|
||||
.registerAddress("40002")
|
||||
.dataType("INT")
|
||||
.readonly(false) // 设置为可写
|
||||
.enabled(true)
|
||||
.description("测试OPC UA数据读取")
|
||||
.description("测试批量写入2")
|
||||
.build();
|
||||
|
||||
try {
|
||||
System.out.println("=== OPC UA写入测试开始 ===");
|
||||
|
||||
// 先读取当前值
|
||||
RValue beforeValue = opcUaProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
if (beforeValue != null) {
|
||||
System.out.println("写入前的值: " + beforeValue.getValue());
|
||||
} else {
|
||||
System.out.println("写入前读取失败,继续执行写入测试...");
|
||||
}
|
||||
|
||||
// 构建写入值对象 - 写入新的温度值(例如:25.5)
|
||||
WValue wValue = new WValue();
|
||||
wValue.setValue("25.5");
|
||||
wValue.setType("float");
|
||||
|
||||
// 调用write方法进行写入测试
|
||||
Boolean writeResult = opcUaProtocolDriver.write(driverConfig, pointConfig, connect, config, wValue);
|
||||
System.out.println("写入结果: " + (writeResult ? "成功" : "失败"));
|
||||
|
||||
// 等待一小段时间后再次读取,验证写入是否成功
|
||||
Thread.sleep(500);
|
||||
RValue afterValue = opcUaProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
|
||||
if (afterValue != null) {
|
||||
System.out.println("写入后的值: " + afterValue.getValue());
|
||||
|
||||
// 验证写入是否成功
|
||||
if (writeResult && "25.5".equals(afterValue.getValue())) {
|
||||
System.out.println("✓ 写入验证成功!值已更新为: " + afterValue.getValue());
|
||||
} else {
|
||||
System.out.println("✗ 写入验证失败!期望值: 25.5, 实际值: " + afterValue.getValue());
|
||||
}
|
||||
} else {
|
||||
System.err.println("写入后读取失败,无法验证写入结果");
|
||||
}
|
||||
|
||||
System.out.println("\n=== 测试完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("\n✗ 测试异常: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private OpcDaProtocolDriverImpl opcDaProtocolDriver;
|
||||
|
||||
@Test
|
||||
public void opcDaTestRead() {
|
||||
// 初始化驱动
|
||||
opcDaProtocolDriver.initial();
|
||||
|
||||
// 构建驱动配置(连接配置)
|
||||
// 重要提示:
|
||||
// 1. 本地连接使用 "127.0.0.1" 或 "localhost"
|
||||
// 2. username 格式:
|
||||
// - 本地用户:直接使用用户名,如 "Administrator" 或 "YourUsername"
|
||||
// - 域用户:使用 "DOMAIN\\username" 格式
|
||||
// - 如果 OPC 服务器配置为允许匿名访问,可以尝试空字符串
|
||||
// 3. password 必须是 Windows 用户的实际密码
|
||||
// 4. 确保 Windows DCOM 配置正确(参考 Matrikon OPC 文档)
|
||||
|
||||
Map<String, AttributeBO> driverConfig = new HashMap<>();
|
||||
driverConfig.put("host", AttributeBO.builder().value("127.0.0.1").build());
|
||||
driverConfig.put("clsId", AttributeBO.builder().value("F8582CF2-88FB-11D0-B850-00C0F0104305").build());
|
||||
|
||||
// 方案1:使用当前登录用户(推荐本地测试)
|
||||
// 获取当前 Windows 用户名:在 CMD 中运行 "echo %USERNAME%"
|
||||
String currentUser = System.getProperty("user.name"); // 获取当前 Java 进程的用户名
|
||||
// driverConfig.put("username", AttributeBO.builder().value(currentUser).build());
|
||||
// driverConfig.put("password", AttributeBO.builder().value("6614").build()); // 替换为你的 Windows 密码
|
||||
|
||||
// 方案2:如果模拟器配置了特定用户,使用该用户
|
||||
driverConfig.put("username", AttributeBO.builder().value("Administrator").build());
|
||||
driverConfig.put("password", AttributeBO.builder().value("12356").build());
|
||||
|
||||
// 方案3:尝试匿名访问(某些 OPC 服务器支持)
|
||||
// driverConfig.put("username", AttributeBO.builder().value("").build());
|
||||
// driverConfig.put("password", AttributeBO.builder().value("").build());
|
||||
|
||||
// 构建点位配置
|
||||
// 根据你的模拟器截图,Item ID 是 "Random.Int1"
|
||||
Map<String, AttributeBO> pointConfig = new HashMap<>();
|
||||
pointConfig.put("group", AttributeBO.builder().value("Group0").build()); // 组名
|
||||
pointConfig.put("tag", AttributeBO.builder().value("Random.Int1").build()); // 标签名,与模拟器中的 Item ID 一致
|
||||
|
||||
// 构建连接对象
|
||||
IotConnect connect = IotConnect.builder()
|
||||
.id(1)
|
||||
.code("OPC_DA_001")
|
||||
.host("localhost")
|
||||
.protocol("opc-da")
|
||||
.enabled(true)
|
||||
.description("测试OPC DA连接")
|
||||
.build();
|
||||
|
||||
// 构建配置对象
|
||||
IotConfig config = IotConfig.builder()
|
||||
.id(1)
|
||||
IotConfig config3 = IotConfig.builder()
|
||||
.id(3)
|
||||
.connectId(1)
|
||||
.alias("sensor1")
|
||||
.aliasName("传感器1")
|
||||
.registerAddress("Random.Int1")
|
||||
.dataType("int")
|
||||
.readonly(true)
|
||||
.alias("output_value3")
|
||||
.aliasName("输出值3")
|
||||
.registerAddress("40003")
|
||||
.dataType("LREAL")
|
||||
.readonly(false) // 设置为可写
|
||||
.enabled(true)
|
||||
.description("测试OPC DA数据读取")
|
||||
.description("测试批量写入3")
|
||||
.build();
|
||||
|
||||
// 执行批量写入操作
|
||||
try {
|
||||
System.out.println("=== OPC DA读取测试开始 ===");
|
||||
System.out.println("连接地址: " + driverConfig.get("host").getValue());
|
||||
System.out.println("CLSID: " + driverConfig.get("clsId").getValue());
|
||||
System.out.println("组名: " + pointConfig.get("group").getValue());
|
||||
System.out.println("标签: " + pointConfig.get("tag").getValue());
|
||||
System.out.println("========== 开始测试Modbus TCP批量写入 ==========");
|
||||
System.out.println("连接信息: " + connect.getHost() + ":" + connect.getPort());
|
||||
|
||||
// 调用read方法进行测试
|
||||
RValue result = opcDaProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
// 转换为DeviceBO
|
||||
DeviceBO deviceBO = DeviceBO.builder()
|
||||
.id(String.valueOf(connect.getId()))
|
||||
.code(connect.getCode())
|
||||
.properties(connect.getProperties())
|
||||
.host(connect.getHost())
|
||||
.port(connect.getPort())
|
||||
.protocol(connect.getProtocol())
|
||||
.build();
|
||||
|
||||
// 检查结果是否为null
|
||||
if (result != null) {
|
||||
System.out.println("\n✓ 读取成功!");
|
||||
System.out.println("连接信息: " + result.getConnect());
|
||||
System.out.println("配置信息: " + result.getConfig());
|
||||
System.out.println("读取值: " + result.getValue());
|
||||
} else {
|
||||
System.err.println("\n✗ 读取失败:返回结果为null");
|
||||
System.err.println("可能原因:");
|
||||
System.err.println("1. OPC DA服务器未启动或主机地址不正确");
|
||||
System.err.println("2. CLSID配置错误或服务器未注册");
|
||||
System.err.println("3. 用户名或密码错误");
|
||||
System.err.println("4. 组名或标签名不存在");
|
||||
System.err.println("5. DCOM配置不正确");
|
||||
// 转换为SiteBO并构建WValue列表
|
||||
java.util.List<WValue> wValueList = java.util.Arrays.asList(
|
||||
WValue.builder()
|
||||
.point(SiteBO.builder()
|
||||
.deviceCode(connect.getCode())
|
||||
.alias(config1.getAlias())
|
||||
.aliasName(config1.getAliasName())
|
||||
.registerAddress(config1.getRegisterAddress())
|
||||
.dataType(config1.getDataType())
|
||||
.readonly(config1.getReadonly())
|
||||
.build())
|
||||
.value("100") // 写入值1
|
||||
.type(config1.getDataType())
|
||||
.build(),
|
||||
WValue.builder()
|
||||
.point(SiteBO.builder()
|
||||
.deviceCode(connect.getCode())
|
||||
.alias(config2.getAlias())
|
||||
.aliasName(config2.getAliasName())
|
||||
.registerAddress(config2.getRegisterAddress())
|
||||
.dataType(config2.getDataType())
|
||||
.readonly(config2.getReadonly())
|
||||
.build())
|
||||
.value("200") // 写入值2
|
||||
.type(config2.getDataType())
|
||||
.build()
|
||||
// WValue.builder()
|
||||
// .point(SiteBO.builder()
|
||||
// .deviceCode(connect.getCode())
|
||||
// .alias(config3.getAlias())
|
||||
// .aliasName(config3.getAliasName())
|
||||
// .registerAddress(config3.getRegisterAddress())
|
||||
// .dataType(config3.getDataType())
|
||||
// .readonly(config3.getReadonly())
|
||||
// .build())
|
||||
// .value("25.5") // 写入值3
|
||||
// .type(config3.getDataType())
|
||||
// .build()
|
||||
);
|
||||
|
||||
System.out.println("批量写入点位数量: " + wValueList.size());
|
||||
for (WValue wValue : wValueList) {
|
||||
SiteBO site = wValue.getPoint();
|
||||
System.out.println(" - " + site.getAliasName() + " (" + site.getAlias() + "): " +
|
||||
site.getRegisterAddress() + " [" + site.getDataType() + "] = " + wValue.getValue());
|
||||
}
|
||||
|
||||
System.out.println("\n=== 测试完成 ===");
|
||||
// 调用驱动批量写入数据
|
||||
List<WResponse> result = modBusProtocolDriver.batchWrite(deviceBO, wValueList);
|
||||
|
||||
System.out.println("批量写入完成!");
|
||||
System.out.println("写入结果:");
|
||||
|
||||
// 输出每个点位的写入结果
|
||||
for (WResponse wResponse : result) {
|
||||
WValue wValue = wResponse.getWValue();
|
||||
SiteBO site = wValue.getPoint();
|
||||
Boolean success = wResponse.getIsOk();
|
||||
System.out.println(" - " + site.getAliasName() + " (" + site.getAlias() + "): " +
|
||||
"写入值=" + wValue.getValue() + " 结果=" + (success ? "成功" : "失败"));
|
||||
}
|
||||
|
||||
System.out.println("========== 批量写入测试完成 ==========");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("\n✗ 测试异常: " + e.getMessage());
|
||||
System.err.println("批量写入测试失败: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void opcDaTestWrite() {
|
||||
// 初始化驱动
|
||||
opcDaProtocolDriver.initial();
|
||||
|
||||
// 构建驱动配置(连接配置)
|
||||
Map<String, AttributeBO> driverConfig = new HashMap<>();
|
||||
driverConfig.put("host", AttributeBO.builder().value("localhost").build());
|
||||
driverConfig.put("clsId", AttributeBO.builder().value("F8582CF2-88FB-11D0-B850-00C0F0104305").build()); // OPC DA Server CLSID
|
||||
driverConfig.put("username", AttributeBO.builder().value("Administrator").build());
|
||||
driverConfig.put("password", AttributeBO.builder().value("password").build());
|
||||
|
||||
// 构建点位配置
|
||||
Map<String, AttributeBO> pointConfig = new HashMap<>();
|
||||
pointConfig.put("group", AttributeBO.builder().value("Group1").build()); // 组名
|
||||
pointConfig.put("tag", AttributeBO.builder().value("Channel1.Device1.Tag1").build()); // 标签名
|
||||
|
||||
// 构建连接对象
|
||||
IotConnect connect = IotConnect.builder()
|
||||
.id(1)
|
||||
.code("OPC_DA_001")
|
||||
.host("localhost")
|
||||
.protocol("opc-da")
|
||||
.enabled(true)
|
||||
.description("测试OPC DA写入连接")
|
||||
.build();
|
||||
|
||||
// 构建配置对象
|
||||
IotConfig config = IotConfig.builder()
|
||||
.id(1)
|
||||
.connectId(1)
|
||||
.alias("sensor1")
|
||||
.aliasName("传感器1")
|
||||
.registerAddress("Channel1.Device1.Tag1")
|
||||
.dataType("int")
|
||||
.readonly(false)
|
||||
.enabled(true)
|
||||
.description("测试OPC DA数据写入")
|
||||
.build();
|
||||
|
||||
try {
|
||||
System.out.println("=== OPC DA写入测试开始 ===");
|
||||
|
||||
// 先读取当前值
|
||||
RValue beforeValue = opcDaProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
if (beforeValue != null) {
|
||||
System.out.println("写入前的值: " + beforeValue.getValue());
|
||||
} else {
|
||||
System.out.println("写入前读取失败,继续执行写入测试...");
|
||||
}
|
||||
|
||||
// 构建写入值对象 - 写入新的值(例如:100)
|
||||
WValue wValue = new WValue();
|
||||
wValue.setValue("100");
|
||||
wValue.setType("int");
|
||||
|
||||
// 调用write方法进行写入测试
|
||||
Boolean writeResult = opcDaProtocolDriver.write(driverConfig, pointConfig, connect, config, wValue);
|
||||
System.out.println("写入结果: " + (writeResult ? "成功" : "失败"));
|
||||
|
||||
// 等待一小段时间后再次读取,验证写入是否成功
|
||||
Thread.sleep(500);
|
||||
RValue afterValue = opcDaProtocolDriver.read(driverConfig, pointConfig, connect, config);
|
||||
|
||||
if (afterValue != null) {
|
||||
System.out.println("写入后的值: " + afterValue.getValue());
|
||||
|
||||
// 验证写入是否成功
|
||||
if (writeResult && "100".equals(afterValue.getValue())) {
|
||||
System.out.println("✓ 写入验证成功!值已更新为: " + afterValue.getValue());
|
||||
} else {
|
||||
System.out.println("✗ 写入验证失败!期望值: 100, 实际值: " + afterValue.getValue());
|
||||
}
|
||||
} else {
|
||||
System.err.println("写入后读取失败,无法验证写入结果");
|
||||
}
|
||||
|
||||
System.out.println("\n=== 测试完成 ===");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("\n✗ 测试异常: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user