添加 MonitoredItem (C)
前置阅读
- 先创建 Subscription, 见 Create.
- DataChange 回调字段请看 DataChange 事件.
- 改采样参数请看 Modify.
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 字符串 |
attr | DARRA_UA_ATTR_VALUE | 监控的 Attribute |
sampling_interval_ms | -1 | -1 = 跟订阅, 0 = 尽快, 其他 = 服务端实际采样间隔 (ms) |
cb | — | 数据变化回调 |
user_context | NULL | 透传给 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 本地句柄 |
value | DataValue, 仅在回调返回前有效, 不要持久保存指针 |
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.