|
|
@@ -0,0 +1,533 @@
|
|
|
+package com.mes.test;
|
|
|
+
|
|
|
+import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
|
|
|
+import org.eclipse.milo.opcua.sdk.client.api.identity.UsernameProvider;
|
|
|
+import org.eclipse.milo.opcua.stack.core.security.SecurityPolicy;
|
|
|
+import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue;
|
|
|
+import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId;
|
|
|
+import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode;
|
|
|
+import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
|
|
|
+import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import java.util.Scanner;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 报警信息读取测试类
|
|
|
+ * 用于测试OP040设备的报警和刀具信息读取
|
|
|
+ *
|
|
|
+ * @author MES
|
|
|
+ */
|
|
|
+public class AlarmReadTest {
|
|
|
+
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(AlarmReadTest.class);
|
|
|
+
|
|
|
+ // 所有可用设备列表
|
|
|
+ private static final String[][] DEVICES = {
|
|
|
+ // 西侧设备 (80.22.10.x)
|
|
|
+ {"OP040A", "opc.tcp://80.22.10.42:4840"},
|
|
|
+ {"OP040B", "opc.tcp://80.22.10.43:4840"},
|
|
|
+ {"OP040C", "opc.tcp://80.22.10.44:4840"},
|
|
|
+ {"OP040D", "opc.tcp://80.22.10.45:4840"},
|
|
|
+ {"OP040E", "opc.tcp://80.22.10.46:4840"},
|
|
|
+ {"OP040F", "opc.tcp://80.22.10.47:4840"},
|
|
|
+ // 东侧设备 (80.23.10.x)
|
|
|
+ {"OP040G", "opc.tcp://80.23.10.42:4840"},
|
|
|
+ {"OP040H", "opc.tcp://80.23.10.43:4840"},
|
|
|
+ {"OP040I", "opc.tcp://80.23.10.44:4840"},
|
|
|
+ {"OP040J", "opc.tcp://80.23.10.45:4840"},
|
|
|
+ {"OP040K", "opc.tcp://80.23.10.46:4840"},
|
|
|
+ {"OP040L", "opc.tcp://80.23.10.47:4840"},
|
|
|
+ };
|
|
|
+
|
|
|
+ private static final String USERNAME = "OPCUA";
|
|
|
+ private static final String PASSWORD = "OPCUA123";
|
|
|
+
|
|
|
+ // 当前选择的设备
|
|
|
+ private String deviceName;
|
|
|
+ private String endpointUrl;
|
|
|
+
|
|
|
+ // 命名空间索引
|
|
|
+ private static final int NS = 2;
|
|
|
+
|
|
|
+ private OpcUaClient client;
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ AlarmReadTest test = new AlarmReadTest();
|
|
|
+ test.run();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 主运行方法 - 交互式选择设备
|
|
|
+ */
|
|
|
+ public void run() {
|
|
|
+ Scanner scanner = new Scanner(System.in);
|
|
|
+
|
|
|
+ while (true) {
|
|
|
+ // 显示设备列表
|
|
|
+ printDeviceMenu();
|
|
|
+
|
|
|
+ System.out.print("请输入设备编号 (1-12), 输入0退出: ");
|
|
|
+ String input = scanner.nextLine().trim();
|
|
|
+
|
|
|
+ if ("0".equals(input) || "q".equalsIgnoreCase(input) || "quit".equalsIgnoreCase(input)) {
|
|
|
+ System.out.println("退出测试程序");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ int choice = Integer.parseInt(input);
|
|
|
+ if (choice < 1 || choice > 12) {
|
|
|
+ System.out.println("无效输入,请输入1-12之间的数字");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 选择设备 (用户输入1-12,数组索引0-11)
|
|
|
+ int deviceIndex = choice - 1;
|
|
|
+ deviceName = DEVICES[deviceIndex][0];
|
|
|
+ endpointUrl = DEVICES[deviceIndex][1];
|
|
|
+
|
|
|
+ System.out.println("\n选择设备: " + deviceName + " (" + endpointUrl + ")");
|
|
|
+
|
|
|
+ // 运行测试
|
|
|
+ runTest();
|
|
|
+
|
|
|
+ System.out.println("\n按回车继续选择其他设备...");
|
|
|
+ scanner.nextLine();
|
|
|
+
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ System.out.println("无效输入,请输入数字");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ scanner.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 打印设备菜单
|
|
|
+ */
|
|
|
+ private void printDeviceMenu() {
|
|
|
+ System.out.println("\n╔════════════════════════════════════════════════════════╗");
|
|
|
+ System.out.println("║ CNC设备报警/刀具信息测试工具 ║");
|
|
|
+ System.out.println("╠════════════════════════════════════════════════════════╣");
|
|
|
+ System.out.println("║ 西侧设备 (80.22.10.x) ║");
|
|
|
+ System.out.println("║ 1. OP040A (80.22.10.42) ║");
|
|
|
+ System.out.println("║ 2. OP040B (80.22.10.43) ║");
|
|
|
+ System.out.println("║ 3. OP040C (80.22.10.44) ║");
|
|
|
+ System.out.println("║ 4. OP040D (80.22.10.45) ║");
|
|
|
+ System.out.println("║ 5. OP040E (80.22.10.46) ║");
|
|
|
+ System.out.println("║ 6. OP040F (80.22.10.47) ║");
|
|
|
+ System.out.println("╠════════════════════════════════════════════════════════╣");
|
|
|
+ System.out.println("║ 东侧设备 (80.23.10.x) ║");
|
|
|
+ System.out.println("║ 7. OP040G (80.23.10.42) ║");
|
|
|
+ System.out.println("║ 8. OP040H (80.23.10.43) ║");
|
|
|
+ System.out.println("║ 9. OP040I (80.23.10.44) ║");
|
|
|
+ System.out.println("║ 10. OP040J (80.23.10.45) ║");
|
|
|
+ System.out.println("║ 11. OP040K (80.23.10.46) ║");
|
|
|
+ System.out.println("║ 12. OP040L (80.23.10.47) ║");
|
|
|
+ System.out.println("╠════════════════════════════════════════════════════════╣");
|
|
|
+ System.out.println("║ 0. 退出程序 ║");
|
|
|
+ System.out.println("╚════════════════════════════════════════════════════════╝");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 运行测试
|
|
|
+ */
|
|
|
+ public void runTest() {
|
|
|
+ try {
|
|
|
+ // 1. 连接设备
|
|
|
+ if (!connect()) {
|
|
|
+ log.error("连接设备失败,测试终止");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("========================================");
|
|
|
+ log.info("开始测试 {} ({}) 报警/刀具信息读取", deviceName, endpointUrl);
|
|
|
+ log.info("========================================");
|
|
|
+
|
|
|
+ // 2. 先读取报警数量
|
|
|
+ testAlarmCount();
|
|
|
+
|
|
|
+ // 3. 测试各种报警路径格式
|
|
|
+ testAlarmPaths();
|
|
|
+
|
|
|
+ // 4. 遍历读取报警信息(多种索引格式)
|
|
|
+ testAlarmWithDifferentIndexes();
|
|
|
+
|
|
|
+ // 5. 测试其他可能的报警相关路径
|
|
|
+ testOtherAlarmPaths();
|
|
|
+
|
|
|
+ // 6. 测试刀具信息读取
|
|
|
+ testToolInfo();
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("测试过程中发生异常", e);
|
|
|
+ } finally {
|
|
|
+ disconnect();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 连接到OPC UA服务器
|
|
|
+ */
|
|
|
+ private boolean connect() {
|
|
|
+ try {
|
|
|
+ log.info("正在连接到 {} ...", endpointUrl);
|
|
|
+ client = OpcUaClient.create(endpointUrl,
|
|
|
+ endpoints -> endpoints.stream()
|
|
|
+ .filter(e -> e.getSecurityPolicyUri().equals(SecurityPolicy.None.getUri()))
|
|
|
+ .findFirst(),
|
|
|
+ configBuilder -> configBuilder
|
|
|
+ .setIdentityProvider(new UsernameProvider(USERNAME, PASSWORD))
|
|
|
+ .setRequestTimeout(UInteger.valueOf(10000))
|
|
|
+ .build()
|
|
|
+ );
|
|
|
+ client.connect().get();
|
|
|
+ log.info("连接成功!");
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("连接失败: {}", e.getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 断开连接
|
|
|
+ */
|
|
|
+ private void disconnect() {
|
|
|
+ if (client != null) {
|
|
|
+ try {
|
|
|
+ client.disconnect().get();
|
|
|
+ log.info("已断开连接");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("断开连接异常", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 读取单个变量
|
|
|
+ */
|
|
|
+ private DataValue readValue(String path) {
|
|
|
+ try {
|
|
|
+ NodeId nodeId = new NodeId(NS, path);
|
|
|
+ return client.readValue(0.0, TimestampsToReturn.Both, nodeId).get();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.debug("读取 {} 异常: {}", path, e.getMessage());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 读取并打印结果
|
|
|
+ */
|
|
|
+ private void readAndPrint(String description, String path) {
|
|
|
+ DataValue dv = readValue(path);
|
|
|
+ if (dv != null) {
|
|
|
+ StatusCode status = dv.getStatusCode();
|
|
|
+ if (status != null && status.isGood()) {
|
|
|
+ Object value = dv.getValue().getValue();
|
|
|
+ log.info("[成功] {} - 路径: {} - 值: {} (类型: {})",
|
|
|
+ description, path, value, value != null ? value.getClass().getSimpleName() : "null");
|
|
|
+ } else {
|
|
|
+ log.warn("[失败] {} - 路径: {} - 状态: {}", description, path, status);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.warn("[失败] {} - 路径: {} - 无法读取", description, path);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试报警数量
|
|
|
+ */
|
|
|
+ private void testAlarmCount() {
|
|
|
+ log.info("\n---------- 测试报警数量 ----------");
|
|
|
+ readAndPrint("报警数量", "/Nck/State/numAlarms");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试各种报警路径格式
|
|
|
+ */
|
|
|
+ private void testAlarmPaths() {
|
|
|
+ log.info("\n---------- 测试报警路径格式 ----------");
|
|
|
+
|
|
|
+ // 报警类型 clearInfo
|
|
|
+ String[] clearInfoPaths = {
|
|
|
+ "/Nck/SequencedAlarms/clearInfo[0]",
|
|
|
+ "/Nck/SequencedAlarms/clearInfo[1]",
|
|
|
+ "/Nck/SequencedAlarms/clearInfo[u1]",
|
|
|
+ "/Nck/SequencedAlarms/clearInfo",
|
|
|
+ };
|
|
|
+
|
|
|
+ for (String path : clearInfoPaths) {
|
|
|
+ readAndPrint("报警类型 clearInfo", path);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 报警号 textIndex
|
|
|
+ String[] textIndexPaths = {
|
|
|
+ "/Nck/SequencedAlarms/textIndex[0]",
|
|
|
+ "/Nck/SequencedAlarms/textIndex[1]",
|
|
|
+ "/Nck/SequencedAlarms/textIndex[u1]",
|
|
|
+ "/Nck/SequencedAlarms/textIndex",
|
|
|
+ };
|
|
|
+
|
|
|
+ for (String path : textIndexPaths) {
|
|
|
+ readAndPrint("报警号 textIndex", path);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试不同索引格式的报警读取
|
|
|
+ */
|
|
|
+ private void testAlarmWithDifferentIndexes() {
|
|
|
+ log.info("\n---------- 遍历报警索引 (0-10) ----------");
|
|
|
+
|
|
|
+ // 遍历索引0-10,使用不同格式
|
|
|
+ for (int i = 0; i <= 10; i++) {
|
|
|
+ // 格式1: [index]
|
|
|
+ String path1 = "/Nck/SequencedAlarms/clearInfo[" + i + "]";
|
|
|
+ String path2 = "/Nck/SequencedAlarms/textIndex[" + i + "]";
|
|
|
+ readAndPrint("clearInfo[" + i + "]", path1);
|
|
|
+ readAndPrint("textIndex[" + i + "]", path2);
|
|
|
+
|
|
|
+ // 格式2: [uIndex]
|
|
|
+ String path3 = "/Nck/SequencedAlarms/clearInfo[u" + i + "]";
|
|
|
+ String path4 = "/Nck/SequencedAlarms/textIndex[u" + i + "]";
|
|
|
+ readAndPrint("clearInfo[u" + i + "]", path3);
|
|
|
+ readAndPrint("textIndex[u" + i + "]", path4);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("\n---------- 测试双索引格式 ----------");
|
|
|
+ // 尝试双索引格式 [channel, index]
|
|
|
+ for (int ch = 1; ch <= 2; ch++) {
|
|
|
+ for (int idx = 0; idx <= 3; idx++) {
|
|
|
+ String path1 = "/Nck/SequencedAlarms/clearInfo[u" + ch + "," + idx + "]";
|
|
|
+ String path2 = "/Nck/SequencedAlarms/textIndex[u" + ch + "," + idx + "]";
|
|
|
+ readAndPrint("clearInfo[u" + ch + "," + idx + "]", path1);
|
|
|
+ readAndPrint("textIndex[u" + ch + "," + idx + "]", path2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试其他可能的报警相关路径
|
|
|
+ */
|
|
|
+ private void testOtherAlarmPaths() {
|
|
|
+ log.info("\n---------- 测试其他报警相关路径 ----------");
|
|
|
+
|
|
|
+ // 可能的报警信息路径
|
|
|
+ String[] otherPaths = {
|
|
|
+ // Alarm相关
|
|
|
+ "/Nck/Alarms/numAlarms",
|
|
|
+ "/Nck/Alarm/numAlarms",
|
|
|
+ "/Nck/AlarmList/numAlarms",
|
|
|
+
|
|
|
+ // SequencedAlarms 其他属性
|
|
|
+ "/Nck/SequencedAlarms/alarmNo[0]",
|
|
|
+ "/Nck/SequencedAlarms/alarmNo[1]",
|
|
|
+ "/Nck/SequencedAlarms/alarmText[0]",
|
|
|
+ "/Nck/SequencedAlarms/alarmText[1]",
|
|
|
+ "/Nck/SequencedAlarms/alarmMsg[0]",
|
|
|
+ "/Nck/SequencedAlarms/alarmMsg[1]",
|
|
|
+ "/Nck/SequencedAlarms/message[0]",
|
|
|
+ "/Nck/SequencedAlarms/message[1]",
|
|
|
+ "/Nck/SequencedAlarms/text[0]",
|
|
|
+ "/Nck/SequencedAlarms/text[1]",
|
|
|
+ "/Nck/SequencedAlarms/description[0]",
|
|
|
+ "/Nck/SequencedAlarms/description[1]",
|
|
|
+
|
|
|
+ // 报警时间
|
|
|
+ "/Nck/SequencedAlarms/alarmTime[0]",
|
|
|
+ "/Nck/SequencedAlarms/alarmTime[1]",
|
|
|
+ "/Nck/SequencedAlarms/time[0]",
|
|
|
+ "/Nck/SequencedAlarms/time[1]",
|
|
|
+ "/Nck/SequencedAlarms/timestamp[0]",
|
|
|
+ "/Nck/SequencedAlarms/timestamp[1]",
|
|
|
+
|
|
|
+ // 报警状态
|
|
|
+ "/Nck/SequencedAlarms/state[0]",
|
|
|
+ "/Nck/SequencedAlarms/state[1]",
|
|
|
+ "/Nck/SequencedAlarms/status[0]",
|
|
|
+ "/Nck/SequencedAlarms/status[1]",
|
|
|
+ "/Nck/SequencedAlarms/active[0]",
|
|
|
+ "/Nck/SequencedAlarms/active[1]",
|
|
|
+
|
|
|
+ // 报警号/ID
|
|
|
+ "/Nck/SequencedAlarms/id[0]",
|
|
|
+ "/Nck/SequencedAlarms/id[1]",
|
|
|
+ "/Nck/SequencedAlarms/number[0]",
|
|
|
+ "/Nck/SequencedAlarms/number[1]",
|
|
|
+
|
|
|
+ // Channel级别的报警
|
|
|
+ "/Channel/State/numAlarms",
|
|
|
+ "/Channel/State/numAlarms[u1]",
|
|
|
+ "/Channel/Alarms/numAlarms",
|
|
|
+ "/Channel/Alarms/numAlarms[u1]",
|
|
|
+
|
|
|
+ // 带通道的SequencedAlarms
|
|
|
+ "/Channel/SequencedAlarms/clearInfo[u1,0]",
|
|
|
+ "/Channel/SequencedAlarms/textIndex[u1,0]",
|
|
|
+
|
|
|
+ // 活动报警
|
|
|
+ "/Nck/State/activeAlarms",
|
|
|
+ "/Nck/State/activeAlarm",
|
|
|
+ "/Nck/ActiveAlarms/numAlarms",
|
|
|
+ };
|
|
|
+
|
|
|
+ for (String path : otherPaths) {
|
|
|
+ readAndPrint("探索路径", path);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("\n---------- 测试不同命名空间 ----------");
|
|
|
+ // 尝试不同的命名空间
|
|
|
+ String[] testPathsForNs = {
|
|
|
+ "/Nck/State/numAlarms",
|
|
|
+ "/Nck/SequencedAlarms/clearInfo[0]",
|
|
|
+ "/Nck/SequencedAlarms/textIndex[0]",
|
|
|
+ };
|
|
|
+
|
|
|
+ for (int ns = 0; ns <= 4; ns++) {
|
|
|
+ log.info("--- 命名空间 ns={} ---", ns);
|
|
|
+ for (String path : testPathsForNs) {
|
|
|
+ try {
|
|
|
+ NodeId nodeId = new NodeId(ns, path);
|
|
|
+ DataValue dv = client.readValue(0.0, TimestampsToReturn.Both, nodeId).get();
|
|
|
+ if (dv != null) {
|
|
|
+ StatusCode status = dv.getStatusCode();
|
|
|
+ if (status != null && status.isGood()) {
|
|
|
+ Object value = dv.getValue().getValue();
|
|
|
+ log.info("[成功] ns={} path={} 值={}", ns, path, value);
|
|
|
+ } else {
|
|
|
+ log.debug("[失败] ns={} path={} 状态={}", ns, path, status);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.debug("[异常] ns={} path={} 错误={}", ns, path, e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 测试刀具信息读取
|
|
|
+ * 根据文档:
|
|
|
+ * - /Tool/ActiveCatalogue/toolIdent[u<Area index>, <Row index>] - 刀具名称
|
|
|
+ * - /Tool/ActiveCatalogue/toolNo[u<Area index>, <Row index>] - 刀号
|
|
|
+ *
|
|
|
+ * OP40刀具信息:
|
|
|
+ * 刀号1: HM铝用平头铣刀 D8.8x35x130xSD8.6,3T (420件)
|
|
|
+ * 刀号2: HM铝用平头铣刀 D10.0x30x75xSD10,3T (2300件)
|
|
|
+ * 刀号3: HM铝用平头铣刀 D16.0x45x100xSD16,3T (4000件)
|
|
|
+ * 刀号4: 锯片铣刀片 D150-H32-H5-Z72 (600件)
|
|
|
+ */
|
|
|
+ private void testToolInfo() {
|
|
|
+ log.info("\n========================================");
|
|
|
+ log.info("测试刀具信息读取");
|
|
|
+ log.info("========================================");
|
|
|
+
|
|
|
+ // 测试基本刀具路径
|
|
|
+ log.info("\n---------- 测试基本刀具路径 ----------");
|
|
|
+ String[] basicToolPaths = {
|
|
|
+ "/Tool/ActiveCatalogue/toolIdent",
|
|
|
+ "/Tool/ActiveCatalogue/toolNo",
|
|
|
+ "/Tool/Catalogue/toolIdent",
|
|
|
+ "/Tool/Catalogue/toolNo",
|
|
|
+ };
|
|
|
+ for (String path : basicToolPaths) {
|
|
|
+ readAndPrint("刀具基本路径", path);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试单索引格式 [index]
|
|
|
+ log.info("\n---------- 测试刀具单索引格式 [index] ----------");
|
|
|
+ for (int i = 0; i <= 5; i++) {
|
|
|
+ readAndPrint("toolIdent[" + i + "]", "/Tool/ActiveCatalogue/toolIdent[" + i + "]");
|
|
|
+ readAndPrint("toolNo[" + i + "]", "/Tool/ActiveCatalogue/toolNo[" + i + "]");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试单索引格式 [uIndex]
|
|
|
+ log.info("\n---------- 测试刀具单索引格式 [uIndex] ----------");
|
|
|
+ for (int i = 1; i <= 5; i++) {
|
|
|
+ readAndPrint("toolIdent[u" + i + "]", "/Tool/ActiveCatalogue/toolIdent[u" + i + "]");
|
|
|
+ readAndPrint("toolNo[u" + i + "]", "/Tool/ActiveCatalogue/toolNo[u" + i + "]");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试双索引格式 [uArea, Row] - 这是文档推荐的格式
|
|
|
+ log.info("\n---------- 测试刀具双索引格式 [uArea, Row] ----------");
|
|
|
+ // Area index 通常是刀具区域, Row index 是刀沿序号
|
|
|
+ for (int area = 1; area <= 2; area++) {
|
|
|
+ for (int row = 1; row <= 5; row++) {
|
|
|
+ String identPath = "/Tool/ActiveCatalogue/toolIdent[u" + area + "," + row + "]";
|
|
|
+ String noPath = "/Tool/ActiveCatalogue/toolNo[u" + area + "," + row + "]";
|
|
|
+ readAndPrint("toolIdent[u" + area + "," + row + "]", identPath);
|
|
|
+ readAndPrint("toolNo[u" + area + "," + row + "]", noPath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试从0开始的行索引
|
|
|
+ log.info("\n---------- 测试刀具双索引格式 (行索引从0开始) ----------");
|
|
|
+ for (int area = 1; area <= 2; area++) {
|
|
|
+ for (int row = 0; row <= 4; row++) {
|
|
|
+ String identPath = "/Tool/ActiveCatalogue/toolIdent[u" + area + "," + row + "]";
|
|
|
+ String noPath = "/Tool/ActiveCatalogue/toolNo[u" + area + "," + row + "]";
|
|
|
+ readAndPrint("toolIdent[u" + area + "," + row + "]", identPath);
|
|
|
+ readAndPrint("toolNo[u" + area + "," + row + "]", noPath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试其他可能的刀具相关路径
|
|
|
+ log.info("\n---------- 测试其他刀具相关路径 ----------");
|
|
|
+ String[] otherToolPaths = {
|
|
|
+ // 当前刀具
|
|
|
+ "/Channel/State/actTNumber[u1]",
|
|
|
+ "/Channel/State/actToolIdent[u1]",
|
|
|
+ "/Channel/State/curTool[u1]",
|
|
|
+ "/Channel/State/currentTool[u1]",
|
|
|
+ "/Channel/Tool/actTNumber[u1]",
|
|
|
+ "/Channel/Tool/actToolIdent[u1]",
|
|
|
+
|
|
|
+ // 刀具管理
|
|
|
+ "/Tool/Management/actTNumber",
|
|
|
+ "/Tool/Management/actToolIdent",
|
|
|
+ "/Tool/State/actTNumber",
|
|
|
+ "/Tool/State/actToolIdent",
|
|
|
+
|
|
|
+ // 刀具补偿
|
|
|
+ "/Tool/Compensation/toolIdent[u1,1]",
|
|
|
+ "/Tool/Compensation/toolNo[u1,1]",
|
|
|
+
|
|
|
+ // 刀库
|
|
|
+ "/Tool/Magazine/toolIdent[u1,1]",
|
|
|
+ "/Tool/Magazine/toolNo[u1,1]",
|
|
|
+
|
|
|
+ // 主轴上的刀具
|
|
|
+ "/Tool/Spindle/toolIdent[u1]",
|
|
|
+ "/Tool/Spindle/toolNo[u1]",
|
|
|
+ "/Spindle/Tool/toolIdent[u1]",
|
|
|
+ "/Spindle/Tool/toolNo[u1]",
|
|
|
+ };
|
|
|
+
|
|
|
+ for (String path : otherToolPaths) {
|
|
|
+ readAndPrint("其他刀具路径", path);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试刀具寿命相关路径
|
|
|
+ log.info("\n---------- 测试刀具寿命相关路径 ----------");
|
|
|
+ String[] toolLifePaths = {
|
|
|
+ "/Tool/ActiveCatalogue/toolLife[u1,1]",
|
|
|
+ "/Tool/ActiveCatalogue/toolLife[u1,2]",
|
|
|
+ "/Tool/ActiveCatalogue/toolLife[u1,3]",
|
|
|
+ "/Tool/ActiveCatalogue/toolLife[u1,4]",
|
|
|
+ "/Tool/ActiveCatalogue/usedLife[u1,1]",
|
|
|
+ "/Tool/ActiveCatalogue/remainLife[u1,1]",
|
|
|
+ "/Tool/Catalogue/toolLife[u1,1]",
|
|
|
+ "/Tool/Management/toolLife[1]",
|
|
|
+ "/Tool/Management/usedPieces[1]",
|
|
|
+ "/Tool/Management/remainPieces[1]",
|
|
|
+ };
|
|
|
+
|
|
|
+ for (String path : toolLifePaths) {
|
|
|
+ readAndPrint("刀具寿命路径", path);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|