跳到主要内容

添加 MonitoredItem (C)

前置阅读

DarraUa_Subscription_AddNode (单个 MI)

DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL DarraUa_Subscription_AddNode(
DarraUa_SubscriptionHandle sub,
const char* node_id_str,
DarraUa_AttributeId attr,
double sampling_interval_ms, /* -1 = 跟订阅, 0 = 尽快 */
DarraUa_OnDataChange cb,
void* user_context,
DarraUa_MonitoredItemHandle* out_mi);
参数默认说明
node_id_str监控的 NodeId 字符串
attrDARRA_UA_ATTR_VALUE监控的 Attribute
sampling_interval_ms-1-1 = 跟订阅, 0 = 尽快, 其他 = 服务端实际采样间隔 (ms)
cb数据变化回调
user_contextNULL透传给 cb 的上下文
out_mi出参, MI 本地句柄
DarraUa_MonitoredItemHandle mi = DARRA_UA_INVALID_MONITORED_ITEM_HANDLE;
DarraUa_Status st = DarraUa_Subscription_AddNode(
sub, "ns=2;s=Temperature", DARRA_UA_ATTR_VALUE,
-1.0, on_change, /*ctx*/ NULL, &mi);
if (!DARRA_UA_STATUS_IS_GOOD(st))
fprintf(stderr, "AddNode failed: %s\n", DarraUa_StatusName(st));

DarraUa_Subscription_AddNodes (批量)

DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL DarraUa_Subscription_AddNodes(
DarraUa_SubscriptionHandle sub,
const char* const* node_id_strs,
const int32_t* attribute_ids, /* NULL = 全部 Value(13) */
uint32_t count,
DarraUa_OnDataChange single_cb, /* 共用一个回调 */
DarraUa_MonitoredItemHandle* out_mi, /* 调用方分配 count 个 */
DarraUa_Status* out_item_status); /* 调用方分配 count 个 */

一次 RPC 加 N 个 MI, 比循环 _AddNode 快得多. 所有 MI 共用一个回调 (用户可在 cb 里按 mi 分发).

const char* nodes[100];
DarraUa_MonitoredItemHandle mis[100] = { 0 };
DarraUa_Status results[100] = { 0 };

for (int i = 0; i < 100; ++i) {
static char buf[100][64];
snprintf(buf[i], sizeof(buf[i]), "ns=2;s=T%d", i + 1);
nodes[i] = buf[i];
}

DarraUa_Subscription_AddNodes(sub, nodes, /*attrs*/ NULL, 100,
on_change, mis, results);

for (int i = 0; i < 100; ++i) {
if (DARRA_UA_STATUS_IS_GOOD(results[i]))
printf(" %s -> mi=%u\n", nodes[i], (unsigned)mis[i]);
else
printf(" %s FAILED: %s\n", nodes[i], DarraUa_StatusName(results[i]));
}

性能: 100 个 MI 用 _AddNodes 约 1 次 RPC (~10 ms), 用循环 _AddNode 约 100 次 RPC (~500-1000 ms).


DataChange 回调签名

typedef void (*DarraUa_OnDataChange)(
DarraUa_SubscriptionHandle sub,
DarraUa_MonitoredItemHandle mi,
const DarraUa_DataValue* value, /* 生命周期 = 回调内 */
void* user_context);
字段含义
sub触发的订阅句柄
mi触发的 MI 本地句柄
valueDataValue, 仅在回调返回前有效, 不要持久保存指针
user_context注册时传入

完整字段访问见 DataChange 事件.


高级 MonitoredItem 配置

AddNode 是简化便捷, 内部用默认参数. 如需 queue_size / discardOldest / Deadband, 用 MonitoredItem_Create:

DarraUa_MonitoredItemConfig mc;
DarraUa_MonitoredItemConfig_Init(&mc);
/* 填 mc.node_id, mc.attribute_id, mc.sampling_interval_ms, mc.queue_size, ... */
mc.queue_size = 10;
mc.discard_oldest = 1;
mc.deadband_type = DARRA_UA_DEADBAND_ABSOLUTE;
mc.deadband_value = 0.5; /* 至少变化 0.5 才报 */

DarraUa_MonitoredItemHandle mi = 0;
DarraUa_Status item_status = 0;
DarraUa_MonitoredItem_Create(sub, &mc, &mi, &item_status);

/* 注册回调 (Create 不带回调参数, 单独设) */
DarraUa_MonitoredItem_SetCallback(sub, mi, on_change, NULL);

移除 MI

DarraUa_MonitoredItem_Delete(sub, mi);

只删一个 MI, 订阅本身保留.


DeadbandType / MonitoringMode 枚举

typedef enum {
DARRA_UA_DEADBAND_NONE = 0,
DARRA_UA_DEADBAND_ABSOLUTE = 1,
DARRA_UA_DEADBAND_PERCENT = 2
} DarraUa_DeadbandType;

typedef enum {
DARRA_UA_MI_MODE_DISABLED = 0,
DARRA_UA_MI_MODE_SAMPLING = 1,
DARRA_UA_MI_MODE_REPORTING = 2
} DarraUa_MonitoringMode;

监控模式切换见 SetMonitoringMode.

下一步