From f7826170f389853424b895542cc2243b06dcde17 Mon Sep 17 00:00:00 2001 From: liyongde <1419499670@qq.com> Date: Fri, 20 Mar 2026 18:00:57 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E7=AE=80=E5=8D=95=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E4=B8=8E=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/cache/CacheRefreshController.java | 13 +++ .../iot/core/cache/MetadataCacheManager.java | 97 +++++++++++++++++++ .../schedule/AutoReadAllSignalTaskRunner.java | 18 +++- .../iot/mapper/mapping/IotConfigMapper.xml | 2 +- nl-web-app/src/test/java/org/nl/ApiTest.java | 72 ++++++++++++++ 5 files changed, 197 insertions(+), 5 deletions(-) diff --git a/nl-iot/src/main/java/org/nl/iot/core/cache/CacheRefreshController.java b/nl-iot/src/main/java/org/nl/iot/core/cache/CacheRefreshController.java index fa3b9d1..1d139f7 100644 --- a/nl-iot/src/main/java/org/nl/iot/core/cache/CacheRefreshController.java +++ b/nl-iot/src/main/java/org/nl/iot/core/cache/CacheRefreshController.java @@ -1,5 +1,6 @@ package org.nl.iot.core.cache; +import cn.dev33.satoken.annotation.SaIgnore; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; @@ -73,4 +74,16 @@ public class CacheRefreshController { return CommonResult.error("获取缓存统计失败: " + e.getMessage()); } } + @Operation(summary = "获取缓存统计信息") + @GetMapping("/datas") + @SaIgnore + public CommonResult> getAllCacheData() { + try { + Map stats = cacheManager.getAllCacheData(); + return CommonResult.data(stats); + } catch (Exception e) { + log.error("获取缓存统计失败", e); + return CommonResult.error("获取缓存统计失败: " + e.getMessage()); + } + } } diff --git a/nl-iot/src/main/java/org/nl/iot/core/cache/MetadataCacheManager.java b/nl-iot/src/main/java/org/nl/iot/core/cache/MetadataCacheManager.java index 9865984..3b432b4 100644 --- a/nl-iot/src/main/java/org/nl/iot/core/cache/MetadataCacheManager.java +++ b/nl-iot/src/main/java/org/nl/iot/core/cache/MetadataCacheManager.java @@ -5,6 +5,7 @@ import org.nl.iot.core.driver.bo.ConnectSiteDO; import org.nl.iot.core.driver.bo.DeviceConnectionBO; import org.nl.iot.core.driver.bo.DeviceInfoReadCacheDo; import org.nl.iot.core.driver.bo.SiteBO; +import org.nl.iot.core.driver.entity.RValue; import org.nl.iot.modular.iot.service.IotConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; @@ -29,6 +30,13 @@ public class MetadataCacheManager implements CommandLineRunner { private IotConfigService configService; private final Map deviceInfoCache = new ConcurrentHashMap<>(); + + /** + * 信号值缓存 + * Key: connectCode.deviceCode.alias + * Value: RValue对象 + */ + private final Map signalValueCache = new ConcurrentHashMap<>(); @Override public void run(String... args) throws Exception { @@ -149,6 +157,7 @@ public class MetadataCacheManager implements CommandLineRunner { */ public void clearAll() { deviceInfoCache.clear(); + signalValueCache.clear(); log.info("已清空所有元数据缓存"); } @@ -158,6 +167,94 @@ public class MetadataCacheManager implements CommandLineRunner { public Map getCacheStats() { Map stats = new HashMap<>(); stats.put("deviceInfoCacheCount", deviceInfoCache.size()); + stats.put("signalValueCacheCount", signalValueCache.size()); return stats; } + + /** + * 获取所有缓存信息 + */ + public Map getAllCacheData() { + Map stats = new HashMap<>(); + stats.put("deviceInfoCacheCount", deviceInfoCache); + stats.put("signalValueCacheCount", signalValueCache); + return stats; + } + + // ==================== 信号值缓存方法 ==================== + + /** + * 存储单个信号值 + * @param deviceKey connectCode.deviceCode + * @param alias 信号别名 + * @param rValue 信号值对象 + */ + public void putSignalValue(String deviceKey, String alias, RValue rValue) { + String key = deviceKey + "." + alias; + signalValueCache.put(key, rValue); + } + + /** + * 批量存储信号值 + * @param deviceKey connectCode.deviceCode + * @param rValues 信号值列表 + */ + public void putSignalValues(String deviceKey, List rValues) { + if (rValues == null || rValues.isEmpty()) { + return; + } + + for (RValue rValue : rValues) { + if (rValue != null && rValue.getSiteBO() != null) { + String alias = rValue.getSiteBO().getAlias(); + putSignalValue(deviceKey, alias, rValue); + } + } + } + + /** + * 获取单个信号值 + * @param deviceKey connectCode.deviceCode + * @param alias 信号别名 + * @return RValue对象 + */ + public RValue getSignalValue(String deviceKey, String alias) { + String key = deviceKey + "." + alias; + return signalValueCache.get(key); + } + + /** + * 获取指定设备的所有信号值 + * @param deviceKey connectCode.deviceCode + * @return 信号值Map,key为alias,value为RValue + */ + public Map getDeviceSignalValues(String deviceKey) { + String prefix = deviceKey + "."; + Map result = new HashMap<>(); + + signalValueCache.forEach((key, value) -> { + if (key.startsWith(prefix)) { + String alias = key.substring(prefix.length()); + result.put(alias, value); + } + }); + + return result; + } + + /** + * 获取所有信号值缓存 + * @return 所有信号值的副本 + */ + public Map getAllSignalValues() { + return new HashMap<>(signalValueCache); + } + + /** + * 清空信号值缓存 + */ + public void clearSignalValues() { + signalValueCache.clear(); + log.info("已清空信号值缓存"); + } } diff --git a/nl-iot/src/main/java/org/nl/iot/core/schedule/AutoReadAllSignalTaskRunner.java b/nl-iot/src/main/java/org/nl/iot/core/schedule/AutoReadAllSignalTaskRunner.java index de8dd53..ef22a36 100644 --- a/nl-iot/src/main/java/org/nl/iot/core/schedule/AutoReadAllSignalTaskRunner.java +++ b/nl-iot/src/main/java/org/nl/iot/core/schedule/AutoReadAllSignalTaskRunner.java @@ -38,7 +38,7 @@ public class AutoReadAllSignalTaskRunner implements CommonTimerTaskRunner { log.error("设备缓存为空..."); return; } - // 读取 + // 同步顺序读取 for (Map.Entry entry : allDeviceInfoCache.entrySet()) { // 获取Map的Key(这里Key是设备ID,和实体中的deviceId可能相同/不同) String key = entry.getKey(); @@ -46,9 +46,19 @@ public class AutoReadAllSignalTaskRunner implements CommonTimerTaskRunner { DeviceInfoReadCacheDo deviceInfo = entry.getValue(); DeviceConnectionBO deviceConnectionBO = deviceInfo.getDeviceConnectionBO(); List siteBOS = deviceInfo.getSiteBOS(); - DriverCustomService driver = driverCustomFactory.getDriver(deviceConnectionBO.getProtocol()); - List list = driver.batchRead(deviceConnectionBO, siteBOS); - // 组装数据 + + try { + DriverCustomService driver = driverCustomFactory.getDriver(deviceConnectionBO.getProtocol()); + List list = driver.batchRead(deviceConnectionBO, siteBOS); + + // 批量存储信号值到缓存 + if (list != null && !list.isEmpty()) { + metadataCacheManager.putSignalValues(key, list); + log.debug("设备 {} 读取并缓存了 {} 个信号值", key, list.size()); + } + } catch (Exception e) { + log.error("读取设备 {} 信号值失败", key, e); + } } } } diff --git a/nl-iot/src/main/java/org/nl/iot/modular/iot/mapper/mapping/IotConfigMapper.xml b/nl-iot/src/main/java/org/nl/iot/modular/iot/mapper/mapping/IotConfigMapper.xml index 8c30e78..6abe75b 100644 --- a/nl-iot/src/main/java/org/nl/iot/modular/iot/mapper/mapping/IotConfigMapper.xml +++ b/nl-iot/src/main/java/org/nl/iot/modular/iot/mapper/mapping/IotConfigMapper.xml @@ -21,6 +21,6 @@ `iot_config` ic LEFT JOIN iot_device id ON id.id = ic.sub_device_id LEFT JOIN iot_connect ict ON ict.id = ic.connect_id - WHERE ic.enabled = TRUE + WHERE ic.enabled = TRUE AND id.enabled = TRUE AND ict.enabled = TRUE \ No newline at end of file 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 a76b6dc..4f71f6d 100644 --- a/nl-web-app/src/test/java/org/nl/ApiTest.java +++ b/nl-web-app/src/test/java/org/nl/ApiTest.java @@ -16,13 +16,17 @@ 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.core.driver.service.DriverCustomService; +import org.nl.iot.core.cache.CacheRefreshController; +import org.nl.iot.core.schedule.AutoReadAllSignalTaskRunner; import org.nl.iot.modular.iot.entity.IotConfig; import org.nl.iot.modular.iot.entity.IotConnect; +import org.nl.common.pojo.CommonResult; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -2101,4 +2105,72 @@ public class ApiTest { System.out.println("\n========== 协议驱动工厂测试完成 =========="); } + + + @Autowired + private AutoReadAllSignalTaskRunner autoReadAllSignalTaskRunner; + + @Autowired + private CacheRefreshController cacheRefreshController; + + @Test + public void ApiTest01() { + try { + System.out.println("========== 开始测试 AutoReadAllSignalTaskRunner =========="); + + // 1. 执行 AutoReadAllSignalTaskRunner 的 action 方法 + System.out.println("执行 AutoReadAllSignalTaskRunner.action() 方法..."); + autoReadAllSignalTaskRunner.action(null); + System.out.println("action() 方法执行完成"); + + // 2. 等待一小段时间确保数据已写入缓存 + Thread.sleep(1000); + + // 3. 调用 getAllCacheData() 获取缓存数据 + System.out.println("\n调用 getAllCacheData() 获取缓存数据..."); + CommonResult> result = cacheRefreshController.getAllCacheData(); + + // 4. 输出结果 + System.out.println("\n========== 测试结果 =========="); + System.out.println("返回状态码: " + result.getCode()); + System.out.println("返回消息: " + result.getMsg()); + + if (result.getData() != null) { + Map data = result.getData(); + System.out.println("\n缓存数据内容:"); + System.out.println(" - deviceInfoCacheCount: " + + (data.get("deviceInfoCacheCount") != null ? + ((Map)data.get("deviceInfoCacheCount")).size() : 0)); + System.out.println(" - signalValueCacheCount: " + + (data.get("signalValueCacheCount") != null ? + ((Map)data.get("signalValueCacheCount")).size() : 0)); + + // 详细输出设备信息缓存 + if (data.get("deviceInfoCacheCount") != null) { + System.out.println("\n设备信息缓存详情:"); + Map deviceCache = (Map) data.get("deviceInfoCacheCount"); + deviceCache.forEach((key, value) -> { + System.out.println(" 设备Key: " + key); + }); + } + + // 详细输出信号值缓存 + if (data.get("signalValueCacheCount") != null) { + System.out.println("\n信号值缓存详情:"); + Map signalCache = (Map) data.get("signalValueCacheCount"); + signalCache.forEach((key, value) -> { + System.out.println(" 信号Key: " + key + " -> 值: " + value); + }); + } + } else { + System.out.println("返回数据为空"); + } + + System.out.println("\n========== 测试完成 =========="); + + } catch (Exception e) { + System.err.println("测试失败: " + e.getMessage()); + e.printStackTrace(); + } + } }