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");