From 97829ad0d5765b46ab60897f887ec61378021db2 Mon Sep 17 00:00:00 2001 From: liyongde <1419499670@qq.com> Date: Fri, 6 Mar 2026 16:21:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20opcua=E8=AF=BB=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nl-web-app/src/test/java/org/nl/ApiTest.java | 423 ++++++++++++++++++- 1 file changed, 421 insertions(+), 2 deletions(-) diff --git a/nl-web-app/src/test/java/org/nl/ApiTest.java b/nl-web-app/src/test/java/org/nl/ApiTest.java index 871dae4..a415dcc 100644 --- a/nl-web-app/src/test/java/org/nl/ApiTest.java +++ b/nl-web-app/src/test/java/org/nl/ApiTest.java @@ -4,7 +4,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.nl.iot.core.driver.bo.AttributeBO; import org.nl.iot.core.driver.entity.RValue; +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; @@ -77,7 +80,7 @@ public class ApiTest { } catch (Exception e) { System.err.println("测试失败: " + e.getMessage()); - e.printStackTrace(); +// e.printStackTrace(); } } @@ -149,7 +152,7 @@ public class ApiTest { } catch (Exception e) { System.err.println("测试失败: " + e.getMessage()); - e.printStackTrace(); +// e.printStackTrace(); } } @@ -227,6 +230,422 @@ public class ApiTest { } catch (Exception e) { System.err.println("\n✗ 测试异常: " + e.getMessage()); +// e.printStackTrace(); + } + } + + + @Test + public void plcS7TestWrite() { + // 初始化驱动 + plcS7ProtocolDriver.initial(); + + // 构建驱动配置(连接配置) + Map driverConfig = new HashMap<>(); + driverConfig.put("host", AttributeBO.builder().value("192.168.10.33").build()); + driverConfig.put("port", AttributeBO.builder().value("102").build()); + + // 构建点位配置 + Map 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") + .readonly(false) + .enabled(true) + .description("测试PLC S7数据写入") + .build(); + + try { + System.out.println("=== PLC S7写入测试开始 ==="); + + // 先读取当前值 + 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); + + 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("写入后读取失败,无法验证写入结果"); + } + + System.out.println("\n=== 测试完成 ==="); + + } catch (Exception e) { + System.err.println("\n✗ 测试异常: " + e.getMessage()); +// e.printStackTrace(); + } + } + + @Autowired + private OpcUaProtocolDriverImpl opcUaProtocolDriver; + + @Test + public void opcUaTestRead() { + // 初始化驱动 +// opcUaProtocolDriver.initial(); + + // 构建驱动配置(连接配置) + Map 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 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) + .connectId(1) + .alias("temperature") + .aliasName("温度传感器") + .registerAddress("ns=3;s=Temperature") // 与模拟器配置一致 + .dataType("float") // 模拟器中是Float类型 + .readonly(true) + .enabled(true) + .description("测试OPC UA数据读取") + .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 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 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) + .connectId(1) + .alias("temperature") + .aliasName("温度传感器") + .registerAddress("ns=3;s=Temperature") // 与模拟器配置一致 + .dataType("float") // 模拟器中是Float类型 + .readonly(true) + .enabled(true) + .description("测试OPC UA数据读取") + .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(); + + // 构建驱动配置(连接配置) + Map 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 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(true) + .enabled(true) + .description("测试OPC DA数据读取") + .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()); + + // 调用read方法进行测试 + RValue result = opcDaProtocolDriver.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 DA服务器未启动或主机地址不正确"); + System.err.println("2. CLSID配置错误或服务器未注册"); + System.err.println("3. 用户名或密码错误"); + System.err.println("4. 组名或标签名不存在"); + System.err.println("5. DCOM配置不正确"); + } + + System.out.println("\n=== 测试完成 ==="); + + } catch (Exception e) { + System.err.println("\n✗ 测试异常: " + e.getMessage()); + e.printStackTrace(); + } + } + + @Test + public void opcDaTestWrite() { + // 初始化驱动 + opcDaProtocolDriver.initial(); + + // 构建驱动配置(连接配置) + Map 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 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(); } }