You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何过滤OPC UA Milo中UaMonitoredItem的初始事件?

问题解决方案

一、过滤初始化阶段的推送数据

你遇到的是UA服务器在监控模式从Sampling切换到Reporting时,会主动推送当前的采样值(也就是初始化时已存在的数据)。要过滤这些初始值,最可靠的方式是给每个UaMonitoredItem添加首次接收标记,跳过第一次触发的回调:

实现步骤

  1. 在类中维护一个线程安全的映射,记录每个监控项是否已经处理过首次推送:
private final Map<UaMonitoredItem, Boolean> firstValueReceived = new ConcurrentHashMap<>();
  1. 在订阅监控项时初始化标记,并在setValueConsumer中判断过滤:
public void subscribeOnComponentsEvent(List list) {
    //....
    //Created in MonitoringMode.Sampling to avoid race condition
    for (UaMonitoredItem item : monitoredItems) {
        allMonitoredItems.add(item);
        firstValueReceived.put(item, false);
        item.setValueConsumer((e, vs) -> {
            Boolean isFirst = firstValueReceived.get(e);
            if (Boolean.TRUE.equals(isFirst)) {
                // 非首次推送,记录日志
                logger.info("Received from {}", e.getReadValueId().getNodeId());
            } else {
                // 首次推送,更新标记,跳过日志
                firstValueReceived.put(e, true);
            }
        });
    }
}

另外也可以尝试通过UA的DataChangeFilter设置仅当值发生变化时推送,但部分服务器仍会在模式切换时推送初始值,因此标记法的兼容性更强。

二、关于ManagedDataItem/ManagedEventItem的最佳实践

在Eclipse Milo客户端开发中,使用ManagedDataItem和ManagedEventItem确实属于最佳实践:

  • 它们封装了底层UaMonitoredItem的管理逻辑,包括初始化、状态跟踪、模式切换等,减少手动代码的编写量;
  • 提供了更简洁的API(如setValueChangeListener),并且可以更方便地配置值变化的过滤规则;
  • 内置了线程安全的状态管理,降低了手动维护监控项时出现竞态条件的概率。

如果你的应用场景允许,建议替换为Managed系列的API,能大幅提升代码的可维护性。

内容的提问来源于stack exchange,提问作者Killpop3770

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:36:38