From 23bb0016ba18c93c8f7b7104a0e382e227d87ce8 Mon Sep 17 00:00:00 2001 From: HuangHuiKang Date: Wed, 4 Feb 2026 16:02:32 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E4=BF=AE=E6=94=B9=E9=87=87=E9=9B=86?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1-?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=BF=9E=E6=8E=A5=E4=B8=AD=E7=A6=BB=E7=BA=BF?= =?UTF-8?q?=E5=A4=84=E7=90=86=EF=BC=8C=E6=B7=BB=E5=8A=A0=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E9=BB=98=E8=AE=A4=E4=B8=BA=E5=BE=85=E6=9C=BA?= =?UTF-8?q?=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../framework/common/util/opc/OpcUtils.java | 8 ++- .../device/scheduled/coretask/DeviceTask.java | 62 +++++++++++++++++-- 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/opc/OpcUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/opc/OpcUtils.java index a9e6d816d..ed7871103 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/opc/OpcUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/opc/OpcUtils.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.framework.common.util.opc; +import lombok.extern.slf4j.Slf4j; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfig; import org.eclipse.milo.opcua.sdk.client.api.config.OpcUaClientConfigBuilder; @@ -24,6 +25,7 @@ import java.util.function.Predicate; * OPC UA连接静态工具类 - 适用于Eclipse Milo 0.6.9 * 提供OPC UA服务器的连接、断开、数据读写等功能(静态方法版本) */ +@Slf4j public class OpcUtils { // 静态成员变量,所有实例共享 @@ -46,14 +48,15 @@ public class OpcUtils { public static boolean connect(String url, String username, String password, int timeoutSeconds) { if (isConnected) { - System.out.println(LOG_PREFIX + "客户端已连接,无需重复连接"); + log.info(" {} 客户端已连接,无需重复连接",LOG_PREFIX); return true; } serverUrl = url; try { - System.out.println(LOG_PREFIX + "正在连接到OPC UA服务器: " + url); + + log.info(" {} 正在连接到OPC UA服务器 {}",LOG_PREFIX,url); // 提取主机和端口 final String targetHost = extractHostFromUrl(url); @@ -62,6 +65,7 @@ public class OpcUtils { System.out.println(LOG_PREFIX + "目标主机: " + targetHost + ", 端口: " + targetPort + ", 路径: " + path); + // 将主机名解析为IP地址 final String ipAddress = resolveToIpAddress(targetHost); System.out.println(LOG_PREFIX + "解析为IP地址: " + ipAddress); diff --git a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/scheduled/coretask/DeviceTask.java b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/scheduled/coretask/DeviceTask.java index 55e235b1d..39295bccf 100644 --- a/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/scheduled/coretask/DeviceTask.java +++ b/yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/controller/admin/device/scheduled/coretask/DeviceTask.java @@ -1,11 +1,13 @@ // DeviceTask.java - 原有设备任务 package cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.coretask; +import cn.iocoder.yudao.framework.common.enums.DeviceConnectionStatusEnum; import cn.iocoder.yudao.framework.common.util.opc.OpcUtils; import cn.iocoder.yudao.module.iot.controller.admin.device.enums.DeviceBasicStatusEnum; import cn.iocoder.yudao.module.iot.controller.admin.device.enums.DeviceStatusEnum; import cn.iocoder.yudao.module.iot.controller.admin.device.enums.TaskTypeEnum; import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.core.Task; +import cn.iocoder.yudao.module.iot.controller.admin.device.scheduled.scheduler.TaskSchedulerManager; import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceSaveReqVO; import cn.iocoder.yudao.module.iot.controller.admin.devicemodelrules.vo.PointRulesRespVO; import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; @@ -28,6 +30,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import javax.annotation.Resource; @@ -51,6 +54,7 @@ public class DeviceTask implements Task { private TDengineService tDengineService; @Resource + @Lazy private DeviceService deviceService; @Resource @@ -62,6 +66,10 @@ public class DeviceTask implements Task { @Resource private DeviceWarinningRecordMapper deviceWarinningRecordMapper; + @Resource + @Lazy + private TaskSchedulerManager taskSchedulerManager; + @Override public String getTaskType() { return TaskTypeEnum.DEVICE.getCode(); @@ -171,29 +179,72 @@ public class DeviceTask implements Task { String username = StringUtils.defaultString(device.getUsername()); String password = StringUtils.defaultString(device.getPassword()); - boolean connected = OpcUtils.connect(device.getUrl(), username, password, 10); - if (!connected) { - //停止任务 - deviceService.connectDevice(new DeviceSaveReqVO().setId(device.getId()).setIsConnect(2)); - throw new RuntimeException("连接OPC服务器失败,URL: " + device.getUrl()); + boolean connected = false; + + + try { + connected = OpcUtils.connect(device.getUrl(), username, password, 10); + if (!connected) { + + log.error("设备 {} 连接OPC服务器失败,URL: {}", device.getId(), device.getUrl()); + device.setStatus(String.valueOf(DeviceConnectionStatusEnum.DISCONNECTED.getStatus())); + deviceMapper.updateById(device); + taskSchedulerManager.stopDeviceTask(device.getId()); + DeviceOperationRecordDO deviceOperationRecordDO = new DeviceOperationRecordDO(); + deviceOperationRecordDO.setDeviceId(device.getId()); + deviceOperationRecordDO.setRule(DeviceStatusEnum.OFFLINE.getCode()); + //TODO 默认内置管理员 + deviceOperationRecordDO.setCreator("1"); + deviceOperationRecordDO.setUpdater("1"); + deviceOperationRecordMapper.insert(deviceOperationRecordDO); + //抛出异常终止任务 + throw new RuntimeException("连接opcuv服务器异常"); + + } + + log.info("设备 {} 成功连接OPC服务器,URL: {}", device.getId(), device.getUrl()); + + } catch (Exception e) { + log.error("设备 {} 连接OPC服务器异常,URL: {}", device.getId(), device.getUrl(), e); + device.setStatus(String.valueOf(DeviceConnectionStatusEnum.DISCONNECTED.getStatus())); + deviceMapper.updateById(device); + taskSchedulerManager.stopDeviceTask(device.getId()); + DeviceOperationRecordDO deviceOperationRecordDO = new DeviceOperationRecordDO(); + deviceOperationRecordDO.setDeviceId(device.getId()); + deviceOperationRecordDO.setRule(DeviceStatusEnum.OFFLINE.getCode()); + //TODO 默认内置管理员 + deviceOperationRecordDO.setCreator("1"); + deviceOperationRecordDO.setUpdater("1"); + deviceOperationRecordMapper.insert(deviceOperationRecordDO); + //抛出异常终止任务 + throw new RuntimeException(e); } + + } /** * 处理设备数据 */ private void processDeviceData(Long deviceId, DeviceDO device) { + DeviceDO deviceDO = deviceMapper.selectById(deviceId); // 1. 查询点位配置 List points = getDevicePoints(deviceId); if (CollectionUtils.isEmpty(points)) { + + + logger.warn("设备 {} 未配置点位", deviceId); //更新状态为待机中 DeviceOperationRecordDO record = new DeviceOperationRecordDO(); record.setDeviceId(device.getId()); record.setRule(DeviceStatusEnum.STANDBY.getCode()); + record.setTotalStandbyTime(deviceDO.getSampleCycle()); //TODO 创建人和更新人为内置默认管理员 record.setCreator("1"); record.setUpdater("1"); + + deviceOperationRecordMapper.insert(record); return; } @@ -209,6 +260,7 @@ public class DeviceTask implements Task { DeviceOperationRecordDO record = new DeviceOperationRecordDO(); record.setDeviceId(device.getId()); record.setRule(DeviceStatusEnum.STANDBY.getCode()); + record.setTotalStandbyTime(deviceDO.getSampleCycle()); //TODO 创建人和更新人为内置默认管理员 record.setCreator("1"); record.setUpdater("1");