文章目录
- 简介
- 目标
- 客户端实用功能
- 高级别的客户端功能
- 读取属性
- 历史访问
- 写属性
- 方法调用
- 节点管理
- 杂项高级功能
- 订阅
- 受监控的项目
- 最近更新
简介
目标
翻译和补充open62541v1.2的官方手册。
客户端实用功能
/* Lookup a datatype by its NodeId. Takes the custom types in the client
* configuration into account. Return NULL if none found. */
const UA_DataType *
UA_Client_findDataType(UA_Client *client, const UA_NodeId *typeId);
高级别的客户端功能
下面的定义是在后台使用标准OPC UA服务的便利函数。这是一种不太灵活的处理堆栈的方式,因为在很多地方都假定了合理的默认值;同时,使用这些函数是实现OPC UA应用的最简单的方式,因为你不必考虑OPC UA服务中的所有细节。如果需要更多的灵活性,你总是可以使用原始的OPC UA服务实现同样的功能。
读取属性
以下函数可用于检索单个节点的属性。使用常规的服务来一次读取几个属性。
/* Don't call this function, use the typed versions */
UA_StatusCode
__UA_Client_readAttribute(UA_Client *client, const UA_NodeId *nodeId,
UA_AttributeId attributeId, void *out,
const UA_DataType *outDataType);
static UA_INLINE UA_StatusCode
UA_Client_readNodeIdAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_NodeId *outNodeId) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_NODEID,
outNodeId, &UA_TYPES[UA_TYPES_NODEID]);
}
static UA_INLINE UA_StatusCode
UA_Client_readNodeClassAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_NodeClass *outNodeClass) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_NODECLASS,
outNodeClass, &UA_TYPES[UA_TYPES_NODECLASS]);
}
static UA_INLINE UA_StatusCode
UA_Client_readBrowseNameAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_QualifiedName *outBrowseName) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_BROWSENAME,
outBrowseName,
&UA_TYPES[UA_TYPES_QUALIFIEDNAME]);
}
static UA_INLINE UA_StatusCode
UA_Client_readDisplayNameAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_LocalizedText *outDisplayName) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME,
outDisplayName,
&UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
}
static UA_INLINE UA_StatusCode
UA_Client_readDescriptionAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_LocalizedText *outDescription) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_DESCRIPTION,
outDescription,
&UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
}
static UA_INLINE UA_StatusCode
UA_Client_readWriteMaskAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_UInt32 *outWriteMask) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_WRITEMASK,
outWriteMask, &UA_TYPES[UA_TYPES_UINT32]);
}
static UA_INLINE UA_StatusCode
UA_Client_readUserWriteMaskAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_UInt32 *outUserWriteMask) {
return __UA_Client_readAttribute(client, &nodeId,
UA_ATTRIBUTEID_USERWRITEMASK,
outUserWriteMask,
&UA_TYPES[UA_TYPES_UINT32]);
}
static UA_INLINE UA_StatusCode
UA_Client_readIsAbstractAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_Boolean *outIsAbstract) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_ISABSTRACT,
outIsAbstract, &UA_TYPES[UA_TYPES_BOOLEAN]);
}
static UA_INLINE UA_StatusCode
UA_Client_readSymmetricAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_Boolean *outSymmetric) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_SYMMETRIC,
outSymmetric, &UA_TYPES[UA_TYPES_BOOLEAN]);
}
static UA_INLINE UA_StatusCode
UA_Client_readInverseNameAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_LocalizedText *outInverseName) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_INVERSENAME,
outInverseName,
&UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
}
static UA_INLINE UA_StatusCode
UA_Client_readContainsNoLoopsAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_Boolean *outContainsNoLoops) {
return __UA_Client_readAttribute(client, &nodeId,
UA_ATTRIBUTEID_CONTAINSNOLOOPS,
outContainsNoLoops,
&UA_TYPES[UA_TYPES_BOOLEAN]);
}
static UA_INLINE UA_StatusCode
UA_Client_readEventNotifierAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_Byte *outEventNotifier) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_EVENTNOTIFIER,
outEventNotifier, &UA_TYPES[UA_TYPES_BYTE]);
}
static UA_INLINE UA_StatusCode
UA_Client_readValueAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_Variant *outValue) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_VALUE,
outValue, &UA_TYPES[UA_TYPES_VARIANT]);
}
static UA_INLINE UA_StatusCode
UA_Client_readDataTypeAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_NodeId *outDataType) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_DATATYPE,
outDataType, &UA_TYPES[UA_TYPES_NODEID]);
}
static UA_INLINE UA_StatusCode
UA_Client_readValueRankAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_Int32 *outValueRank) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_VALUERANK,
outValueRank, &UA_TYPES[UA_TYPES_INT32]);
}
UA_StatusCode
UA_Client_readArrayDimensionsAttribute(UA_Client *client, const UA_NodeId nodeId,
size_t *outArrayDimensionsSize,
UA_UInt32 **outArrayDimensions);
static UA_INLINE UA_StatusCode
UA_Client_readAccessLevelAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_Byte *outAccessLevel) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL,
outAccessLevel, &UA_TYPES[UA_TYPES_BYTE]);
}
static UA_INLINE UA_StatusCode
UA_Client_readUserAccessLevelAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_Byte *outUserAccessLevel) {
return __UA_Client_readAttribute(client, &nodeId,
UA_ATTRIBUTEID_USERACCESSLEVEL,
outUserAccessLevel,
&UA_TYPES[UA_TYPES_BYTE]);
}
static UA_INLINE UA_StatusCode
UA_Client_readMinimumSamplingIntervalAttribute(UA_Client *client,
const UA_NodeId nodeId,
UA_Double *outMinSamplingInterval) {
return __UA_Client_readAttribute(client, &nodeId,
UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL,
outMinSamplingInterval,
&UA_TYPES[UA_TYPES_DOUBLE]);
}
static UA_INLINE UA_StatusCode
UA_Client_readHistorizingAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_Boolean *outHistorizing) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_HISTORIZING,
outHistorizing, &UA_TYPES[UA_TYPES_BOOLEAN]);
}
static UA_INLINE UA_StatusCode
UA_Client_readExecutableAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_Boolean *outExecutable) {
return __UA_Client_readAttribute(client, &nodeId, UA_ATTRIBUTEID_EXECUTABLE,
outExecutable, &UA_TYPES[UA_TYPES_BOOLEAN]);
}
static UA_INLINE UA_StatusCode
UA_Client_readUserExecutableAttribute(UA_Client *client, const UA_NodeId nodeId,
UA_Boolean *outUserExecutable) {
return __UA_Client_readAttribute(client, &nodeId,
UA_ATTRIBUTEID_USEREXECUTABLE,
outUserExecutable,
&UA_TYPES[UA_TYPES_BOOLEAN]);
}
历史访问
以下函数可用于历史地读取单个节点。使用常规服务,可以一次读取多个节点。
#ifdef UA_ENABLE_HISTORIZING
typedef UA_Boolean
(*UA_HistoricalIteratorCallback)(UA_Client *client,
const UA_NodeId *nodeId,
UA_Boolean moreDataAvailable,
const UA_ExtensionObject *data, void *callbackContext);
#ifdef UA_ENABLE_EXPERIMENTAL_HISTORIZING
UA_StatusCode
UA_Client_HistoryRead_events(UA_Client *client, const UA_NodeId *nodeId,
const UA_HistoricalIteratorCallback callback,
UA_DateTime startTime, UA_DateTime endTime,
UA_String indexRange, const UA_EventFilter filter, UA_UInt32 numValuesPerNode,
UA_TimestampsToReturn timestampsToReturn, void *callbackContext);
#endif // UA_ENABLE_EXPERIMENTAL_HISTORIZING
UA_StatusCode
UA_Client_HistoryRead_raw(UA_Client *client, const UA_NodeId *nodeId,
const UA_HistoricalIteratorCallback callback,
UA_DateTime startTime, UA_DateTime endTime,
UA_String indexRange, UA_Boolean returnBounds, UA_UInt32 numValuesPerNode,
UA_TimestampsToReturn timestampsToReturn, void *callbackContext);
#ifdef UA_ENABLE_EXPERIMENTAL_HISTORIZING
UA_StatusCode
UA_Client_HistoryRead_modified(UA_Client *client, const UA_NodeId *nodeId,
const UA_HistoricalIteratorCallback callback,
UA_DateTime startTime, UA_DateTime endTime,
UA_String indexRange, UA_Boolean returnBounds, UA_UInt32 numValuesPerNode,
UA_TimestampsToReturn timestampsToReturn, void *callbackContext);
#endif // UA_ENABLE_EXPERIMENTAL_HISTORIZING
UA_StatusCode
UA_Client_HistoryUpdate_insert(UA_Client *client,
const UA_NodeId *nodeId,
UA_DataValue *value);
UA_StatusCode
UA_Client_HistoryUpdate_replace(UA_Client *client,
const UA_NodeId *nodeId,
UA_DataValue *value);
UA_StatusCode
UA_Client_HistoryUpdate_update(UA_Client *client,
const UA_NodeId *nodeId,
UA_DataValue *value);
UA_StatusCode
UA_Client_HistoryUpdate_deleteRaw(UA_Client *client,
const UA_NodeId *nodeId,
UA_DateTime startTimestamp,
UA_DateTime endTimestamp);
#endif // UA_ENABLE_HISTORIZING
写属性
下面的函数可以用来一次写一个节点的属性。使用常规的写入服务来一次写入几个属性。
/* Don't call this function, use the typed versions */
UA_StatusCode
__UA_Client_writeAttribute(UA_Client *client, const UA_NodeId *nodeId,
UA_AttributeId attributeId, const void *in,
const UA_DataType *inDataType);
static UA_INLINE UA_StatusCode
UA_Client_writeNodeIdAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_NodeId *newNodeId) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_NODEID,
newNodeId, &UA_TYPES[UA_TYPES_NODEID]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeNodeClassAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_NodeClass *newNodeClass) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_NODECLASS,
newNodeClass, &UA_TYPES[UA_TYPES_NODECLASS]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeBrowseNameAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_QualifiedName *newBrowseName) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_BROWSENAME,
newBrowseName,
&UA_TYPES[UA_TYPES_QUALIFIEDNAME]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeDisplayNameAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_LocalizedText *newDisplayName) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_DISPLAYNAME,
newDisplayName,
&UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeDescriptionAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_LocalizedText *newDescription) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_DESCRIPTION,
newDescription,
&UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeWriteMaskAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_UInt32 *newWriteMask) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_WRITEMASK,
newWriteMask, &UA_TYPES[UA_TYPES_UINT32]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeUserWriteMaskAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_UInt32 *newUserWriteMask) {
return __UA_Client_writeAttribute(client, &nodeId,
UA_ATTRIBUTEID_USERWRITEMASK,
newUserWriteMask,
&UA_TYPES[UA_TYPES_UINT32]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeIsAbstractAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_Boolean *newIsAbstract) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_ISABSTRACT,
newIsAbstract, &UA_TYPES[UA_TYPES_BOOLEAN]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeSymmetricAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_Boolean *newSymmetric) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_SYMMETRIC,
newSymmetric, &UA_TYPES[UA_TYPES_BOOLEAN]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeInverseNameAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_LocalizedText *newInverseName) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_INVERSENAME,
newInverseName,
&UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeContainsNoLoopsAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_Boolean *newContainsNoLoops) {
return __UA_Client_writeAttribute(client, &nodeId,
UA_ATTRIBUTEID_CONTAINSNOLOOPS,
newContainsNoLoops,
&UA_TYPES[UA_TYPES_BOOLEAN]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeEventNotifierAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_Byte *newEventNotifier) {
return __UA_Client_writeAttribute(client, &nodeId,
UA_ATTRIBUTEID_EVENTNOTIFIER,
newEventNotifier,
&UA_TYPES[UA_TYPES_BYTE]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeValueAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_Variant *newValue) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_VALUE,
newValue, &UA_TYPES[UA_TYPES_VARIANT]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeDataTypeAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_NodeId *newDataType) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_DATATYPE,
newDataType, &UA_TYPES[UA_TYPES_NODEID]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeValueRankAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_Int32 *newValueRank) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_VALUERANK,
newValueRank, &UA_TYPES[UA_TYPES_INT32]);
}
UA_StatusCode
UA_Client_writeArrayDimensionsAttribute(UA_Client *client, const UA_NodeId nodeId,
size_t newArrayDimensionsSize,
const UA_UInt32 *newArrayDimensions);
static UA_INLINE UA_StatusCode
UA_Client_writeAccessLevelAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_Byte *newAccessLevel) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_ACCESSLEVEL,
newAccessLevel, &UA_TYPES[UA_TYPES_BYTE]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeUserAccessLevelAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_Byte *newUserAccessLevel) {
return __UA_Client_writeAttribute(client, &nodeId,
UA_ATTRIBUTEID_USERACCESSLEVEL,
newUserAccessLevel,
&UA_TYPES[UA_TYPES_BYTE]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeMinimumSamplingIntervalAttribute(UA_Client *client,
const UA_NodeId nodeId,
const UA_Double *newMinInterval) {
return __UA_Client_writeAttribute(client, &nodeId,
UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL,
newMinInterval, &UA_TYPES[UA_TYPES_DOUBLE]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeHistorizingAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_Boolean *newHistorizing) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_HISTORIZING,
newHistorizing, &UA_TYPES[UA_TYPES_BOOLEAN]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeExecutableAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_Boolean *newExecutable) {
return __UA_Client_writeAttribute(client, &nodeId, UA_ATTRIBUTEID_EXECUTABLE,
newExecutable, &UA_TYPES[UA_TYPES_BOOLEAN]);
}
static UA_INLINE UA_StatusCode
UA_Client_writeUserExecutableAttribute(UA_Client *client, const UA_NodeId nodeId,
const UA_Boolean *newUserExecutable) {
return __UA_Client_writeAttribute(client, &nodeId,
UA_ATTRIBUTEID_USEREXECUTABLE,
newUserExecutable,
&UA_TYPES[UA_TYPES_BOOLEAN]);
}
方法调用
#ifdef UA_ENABLE_METHODCALLS
UA_StatusCode
UA_Client_call(UA_Client *client, const UA_NodeId objectId,
const UA_NodeId methodId, size_t inputSize, const UA_Variant *input,
size_t *outputSize, UA_Variant **output);
#endif
节点管理
参见服务器端节点管理一节。
UA_StatusCode
UA_Client_addReference(UA_Client *client, const UA_NodeId sourceNodeId,
const UA_NodeId referenceTypeId, UA_Boolean isForward,
const UA_String targetServerUri,
const UA_ExpandedNodeId targetNodeId,
UA_NodeClass targetNodeClass);
UA_StatusCode
UA_Client_deleteReference(UA_Client *client, const UA_NodeId sourceNodeId,
const UA_NodeId referenceTypeId, UA_Boolean isForward,
const UA_ExpandedNodeId targetNodeId,
UA_Boolean deleteBidirectional);
UA_StatusCode
UA_Client_deleteNode(UA_Client *client, const UA_NodeId nodeId,
UA_Boolean deleteTargetReferences);
/* Protect against redundant definitions for server/client */
#ifndef UA_DEFAULT_ATTRIBUTES_DEFINED
#define UA_DEFAULT_ATTRIBUTES_DEFINED
/* The default for variables is "BaseDataType" for the datatype, -2 for the
* valuerank and a read-accesslevel. */
extern const UA_VariableAttributes UA_VariableAttributes_default;
extern const UA_VariableTypeAttributes UA_VariableTypeAttributes_default;
/* Methods are executable by default */
extern const UA_MethodAttributes UA_MethodAttributes_default;
/* The remaining attribute definitions are currently all zeroed out */
extern const UA_ObjectAttributes UA_ObjectAttributes_default;
extern const UA_ObjectTypeAttributes UA_ObjectTypeAttributes_default;
extern const UA_ReferenceTypeAttributes UA_ReferenceTypeAttributes_default;
extern const UA_DataTypeAttributes UA_DataTypeAttributes_default;
extern const UA_ViewAttributes UA_ViewAttributes_default;
#endif
/* Don't call this function, use the typed versions */
UA_StatusCode
__UA_Client_addNode(UA_Client *client, const UA_NodeClass nodeClass,
const UA_NodeId requestedNewNodeId,
const UA_NodeId parentNodeId,
const UA_NodeId referenceTypeId,
const UA_QualifiedName browseName,
const UA_NodeId typeDefinition, const UA_NodeAttributes *attr,
const UA_DataType *attributeType, UA_NodeId *outNewNodeId);
static UA_INLINE UA_StatusCode
UA_Client_addVariableNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
const UA_NodeId parentNodeId,
const UA_NodeId referenceTypeId,
const UA_QualifiedName browseName,
const UA_NodeId typeDefinition,
const UA_VariableAttributes attr,
UA_NodeId *outNewNodeId) {
return __UA_Client_addNode(client, UA_NODECLASS_VARIABLE, requestedNewNodeId,
parentNodeId, referenceTypeId, browseName,
typeDefinition, (const UA_NodeAttributes*)&attr,
&UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
outNewNodeId);
}
static UA_INLINE UA_StatusCode
UA_Client_addVariableTypeNode(UA_Client *client,
const UA_NodeId requestedNewNodeId,
const UA_NodeId parentNodeId,
const UA_NodeId referenceTypeId,
const UA_QualifiedName browseName,
const UA_VariableTypeAttributes attr,
UA_NodeId *outNewNodeId) {
return __UA_Client_addNode(client, UA_NODECLASS_VARIABLETYPE,
requestedNewNodeId,
parentNodeId, referenceTypeId, browseName,
UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
&UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],
outNewNodeId);
}
static UA_INLINE UA_StatusCode
UA_Client_addObjectNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
const UA_NodeId parentNodeId,
const UA_NodeId referenceTypeId,
const UA_QualifiedName browseName,
const UA_NodeId typeDefinition,
const UA_ObjectAttributes attr, UA_NodeId *outNewNodeId) {
return __UA_Client_addNode(client, UA_NODECLASS_OBJECT, requestedNewNodeId,
parentNodeId, referenceTypeId, browseName,
typeDefinition, (const UA_NodeAttributes*)&attr,
&UA_TYPES[UA_TYPES_OBJECTATTRIBUTES], outNewNodeId);
}
static UA_INLINE UA_StatusCode
UA_Client_addObjectTypeNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
const UA_NodeId parentNodeId,
const UA_NodeId referenceTypeId,
const UA_QualifiedName browseName,
const UA_ObjectTypeAttributes attr,
UA_NodeId *outNewNodeId) {
return __UA_Client_addNode(client, UA_NODECLASS_OBJECTTYPE, requestedNewNodeId,
parentNodeId, referenceTypeId, browseName,
UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
&UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],
outNewNodeId);
}
static UA_INLINE UA_StatusCode
UA_Client_addViewNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
const UA_NodeId parentNodeId,
const UA_NodeId referenceTypeId,
const UA_QualifiedName browseName,
const UA_ViewAttributes attr,
UA_NodeId *outNewNodeId) {
return __UA_Client_addNode(client, UA_NODECLASS_VIEW, requestedNewNodeId,
parentNodeId, referenceTypeId, browseName,
UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
&UA_TYPES[UA_TYPES_VIEWATTRIBUTES], outNewNodeId);
}
static UA_INLINE UA_StatusCode
UA_Client_addReferenceTypeNode(UA_Client *client,
const UA_NodeId requestedNewNodeId,
const UA_NodeId parentNodeId,
const UA_NodeId referenceTypeId,
const UA_QualifiedName browseName,
const UA_ReferenceTypeAttributes attr,
UA_NodeId *outNewNodeId) {
return __UA_Client_addNode(client, UA_NODECLASS_REFERENCETYPE,
requestedNewNodeId,
parentNodeId, referenceTypeId, browseName,
UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
&UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],
outNewNodeId);
}
static UA_INLINE UA_StatusCode
UA_Client_addDataTypeNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
const UA_NodeId parentNodeId,
const UA_NodeId referenceTypeId,
const UA_QualifiedName browseName,
const UA_DataTypeAttributes attr,
UA_NodeId *outNewNodeId) {
return __UA_Client_addNode(client, UA_NODECLASS_DATATYPE, requestedNewNodeId,
parentNodeId, referenceTypeId, browseName,
UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
&UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],
outNewNodeId);
}
static UA_INLINE UA_StatusCode
UA_Client_addMethodNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
const UA_NodeId parentNodeId,
const UA_NodeId referenceTypeId,
const UA_QualifiedName browseName,
const UA_MethodAttributes attr,
UA_NodeId *outNewNodeId) {
return __UA_Client_addNode(client, UA_NODECLASS_METHOD, requestedNewNodeId,
parentNodeId, referenceTypeId, browseName,
UA_NODEID_NULL, (const UA_NodeAttributes*)&attr,
&UA_TYPES[UA_TYPES_METHODATTRIBUTES], outNewNodeId);
}
杂项高级功能
/* Get the namespace-index of a namespace-URI
*
* @param client The UA_Client struct for this connection
* @param namespaceUri The interested namespace URI
* @param namespaceIndex The namespace index of the URI. The value is unchanged
* in case of an error
* @return Indicates whether the operation succeeded or returns an error code */
UA_StatusCode
UA_Client_NamespaceGetIndex(UA_Client *client, UA_String *namespaceUri,
UA_UInt16 *namespaceIndex);
#ifndef HAVE_NODEITER_CALLBACK
#define HAVE_NODEITER_CALLBACK
/* Iterate over all nodes referenced by parentNodeId by calling the callback
function for each child node */
typedef UA_StatusCode (*UA_NodeIteratorCallback)(UA_NodeId childId, UA_Boolean isInverse,
UA_NodeId referenceTypeId, void *handle);
#endif
UA_StatusCode
UA_Client_forEachChildNodeCall(UA_Client *client, UA_NodeId parentNodeId,
UA_NodeIteratorCallback callback, void *handle);
订阅
OPC UA的订阅是异步的。也就是说,客户端向服务器发送几个PublishRequests。服务器返回带有通知的PublishResponses。但只有当通知被生成时。客户端不等待响应,继续正常操作。
注意Subscriptions和MonitoredItems之间的区别。订阅是用来报告通知的。MonitoredItems用于生成通知。每个MonitoredItem都精确地附着在一个Subscription上。而一个Subscription可以包含许多MonitoredItems。
客户端在后台自动处理PublishResponses(带有回调),并保持足够的PublishRequests在运输中。PublishResponses可以在同步服务调用或UA_Client_run_iterate
中接收。参见更多关于异步性。
/* Callbacks defined for Subscriptions */
typedef void (*UA_Client_DeleteSubscriptionCallback)
(UA_Client *client, UA_UInt32 subId, void *subContext);
typedef void (*UA_Client_StatusChangeNotificationCallback)
(UA_Client *client, UA_UInt32 subId, void *subContext,
UA_StatusChangeNotification *notification);
/* Provides default values for a new subscription.
*
* RequestedPublishingInterval: 500.0 [ms]
* RequestedLifetimeCount: 10000
* RequestedMaxKeepAliveCount: 10
* MaxNotificationsPerPublish: 0 (unlimited)
* PublishingEnabled: true
* Priority: 0 */
static UA_INLINE UA_CreateSubscriptionRequest
UA_CreateSubscriptionRequest_default(void) {
UA_CreateSubscriptionRequest request;
UA_CreateSubscriptionRequest_init(&request);
request.requestedPublishingInterval = 500.0;
request.requestedLifetimeCount = 10000;
request.requestedMaxKeepAliveCount = 10;
request.maxNotificationsPerPublish = 0;
request.publishingEnabled = true;
request.priority = 0;
return request;
}
UA_CreateSubscriptionResponse
UA_Client_Subscriptions_create(UA_Client *client,
const UA_CreateSubscriptionRequest request,
void *subscriptionContext,
UA_Client_StatusChangeNotificationCallback statusChangeCallback,
UA_Client_DeleteSubscriptionCallback deleteCallback);
UA_StatusCode
UA_Client_Subscriptions_create_async(UA_Client *client,
const UA_CreateSubscriptionRequest request,
void *subscriptionContext,
UA_Client_StatusChangeNotificationCallback statusChangeCallback,
UA_Client_DeleteSubscriptionCallback deleteCallback,
UA_ClientAsyncServiceCallback callback,
void *userdata, UA_UInt32 *requestId);
UA_ModifySubscriptionResponse
UA_Client_Subscriptions_modify(UA_Client *client,
const UA_ModifySubscriptionRequest request);
UA_StatusCode
UA_Client_Subscriptions_modify_async(UA_Client *client,
const UA_ModifySubscriptionRequest request,
UA_ClientAsyncServiceCallback callback,
void *userdata, UA_UInt32 *requestId);
UA_DeleteSubscriptionsResponse
UA_Client_Subscriptions_delete(UA_Client *client,
const UA_DeleteSubscriptionsRequest request);
UA_StatusCode
UA_Client_Subscriptions_delete_async(UA_Client *client,
const UA_DeleteSubscriptionsRequest request,
UA_ClientAsyncServiceCallback callback,
void *userdata, UA_UInt32 *requestId);
/* Delete a single subscription */
UA_StatusCode
UA_Client_Subscriptions_deleteSingle(UA_Client *client, UA_UInt32 subscriptionId);
static UA_INLINE UA_SetPublishingModeResponse
UA_Client_Subscriptions_setPublishingMode(UA_Client *client,
const UA_SetPublishingModeRequest request) {
UA_SetPublishingModeResponse response;
__UA_Client_Service(client,
&request, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODEREQUEST],
&response, &UA_TYPES[UA_TYPES_SETPUBLISHINGMODERESPONSE]);
return response;
}
受监控的项目
事件的MonitoredItems表示EventNotifier
属性。这表明服务器不监测该属性的变化,而是转发该节点的事件通知。
在创建MonitoredItem的过程中,服务器可能会返回调整过的参数。检查返回的UA_CreateMonitoredItemsResponse
以获得当前参数。
/* Provides default values for a new monitored item. */
static UA_INLINE UA_MonitoredItemCreateRequest
UA_MonitoredItemCreateRequest_default(UA_NodeId nodeId) {
UA_MonitoredItemCreateRequest request;
UA_MonitoredItemCreateRequest_init(&request);
request.itemToMonitor.nodeId = nodeId;
request.itemToMonitor.attributeId = UA_ATTRIBUTEID_VALUE;
request.monitoringMode = UA_MONITORINGMODE_REPORTING;
request.requestedParameters.samplingInterval = 250;
request.requestedParameters.discardOldest = true;
request.requestedParameters.queueSize = 1;
return request;
}
The clientHandle parameter can’t be set by the user, any value will be replaced by the client before sending the request to the server.
/* Callback for the deletion of a MonitoredItem */
typedef void (*UA_Client_DeleteMonitoredItemCallback)
(UA_Client *client, UA_UInt32 subId, void *subContext,
UA_UInt32 monId, void *monContext);
/* Callback for DataChange notifications */
typedef void (*UA_Client_DataChangeNotificationCallback)
(UA_Client *client, UA_UInt32 subId, void *subContext,
UA_UInt32 monId, void *monContext,
UA_DataValue *value);
/* Callback for Event notifications */
typedef void (*UA_Client_EventNotificationCallback)
(UA_Client *client, UA_UInt32 subId, void *subContext,
UA_UInt32 monId, void *monContext,
size_t nEventFields, UA_Variant *eventFields);
/* Don't use to monitor the EventNotifier attribute */
UA_CreateMonitoredItemsResponse
UA_Client_MonitoredItems_createDataChanges(UA_Client *client,
const UA_CreateMonitoredItemsRequest request, void **contexts,
UA_Client_DataChangeNotificationCallback *callbacks,
UA_Client_DeleteMonitoredItemCallback *deleteCallbacks);
UA_StatusCode
UA_Client_MonitoredItems_createDataChanges_async(UA_Client *client,
const UA_CreateMonitoredItemsRequest request, void **contexts,
UA_Client_DataChangeNotificationCallback *callbacks,
UA_Client_DeleteMonitoredItemCallback *deleteCallbacks,
UA_ClientAsyncServiceCallback createCallback,
void *userdata, UA_UInt32 *requestId);
UA_MonitoredItemCreateResult
UA_Client_MonitoredItems_createDataChange(UA_Client *client,
UA_UInt32 subscriptionId,
UA_TimestampsToReturn timestampsToReturn,
const UA_MonitoredItemCreateRequest item,
void *context, UA_Client_DataChangeNotificationCallback callback,
UA_Client_DeleteMonitoredItemCallback deleteCallback);
/* Monitor the EventNotifier attribute only */
UA_CreateMonitoredItemsResponse
UA_Client_MonitoredItems_createEvents(UA_Client *client,
const UA_CreateMonitoredItemsRequest request, void **contexts,
UA_Client_EventNotificationCallback *callback,
UA_Client_DeleteMonitoredItemCallback *deleteCallback);
/* Monitor the EventNotifier attribute only */
UA_StatusCode
UA_Client_MonitoredItems_createEvents_async(UA_Client *client,
const UA_CreateMonitoredItemsRequest request, void **contexts,
UA_Client_EventNotificationCallback *callbacks,
UA_Client_DeleteMonitoredItemCallback *deleteCallbacks,
UA_ClientAsyncServiceCallback createCallback,
void *userdata, UA_UInt32 *requestId);
UA_MonitoredItemCreateResult
UA_Client_MonitoredItems_createEvent(UA_Client *client,
UA_UInt32 subscriptionId,
UA_TimestampsToReturn timestampsToReturn,
const UA_MonitoredItemCreateRequest item,
void *context, UA_Client_EventNotificationCallback callback,
UA_Client_DeleteMonitoredItemCallback deleteCallback);
UA_DeleteMonitoredItemsResponse
UA_Client_MonitoredItems_delete(UA_Client *client,
const UA_DeleteMonitoredItemsRequest);
UA_StatusCode
UA_Client_MonitoredItems_delete_async(UA_Client *client,
const UA_DeleteMonitoredItemsRequest request,
UA_ClientAsyncServiceCallback callback,
void *userdata, UA_UInt32 *requestId);
UA_StatusCode
UA_Client_MonitoredItems_deleteSingle(UA_Client *client,
UA_UInt32 subscriptionId, UA_UInt32 monitoredItemId);
/* The clientHandle parameter will be filled automatically */
UA_ModifyMonitoredItemsResponse
UA_Client_MonitoredItems_modify(UA_Client *client,
const UA_ModifyMonitoredItemsRequest request);
以下服务调用直接进入服务器。MonitoredItem的设置不存储在客户端。
static UA_INLINE UA_SetMonitoringModeResponse
UA_Client_MonitoredItems_setMonitoringMode(UA_Client *client,
const UA_SetMonitoringModeRequest request) {
UA_SetMonitoringModeResponse response;
__UA_Client_Service(client,
&request, &UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST],
&response, &UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE]);
return response;
}
static UA_INLINE UA_SetTriggeringResponse
UA_Client_MonitoredItems_setTriggering(UA_Client *client,
const UA_SetTriggeringRequest request) {
UA_SetTriggeringResponse response;
__UA_Client_Service(client,
&request, &UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST],
&response, &UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE]);
return response;
}
static UA_INLINE UA_StatusCode
UA_Client_MonitoredItems_modify_async(UA_Client *client,
const UA_ModifyMonitoredItemsRequest request,
UA_ClientAsyncServiceCallback callback,
void *userdata, UA_UInt32 *requestId) {
return __UA_Client_AsyncService(client, &request,
&UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSREQUEST], callback,
&UA_TYPES[UA_TYPES_MODIFYMONITOREDITEMSRESPONSE],
userdata, requestId);
}
static UA_INLINE UA_StatusCode
UA_Client_MonitoredItems_setMonitoringMode_async(UA_Client *client,
const UA_SetMonitoringModeRequest request,
UA_ClientAsyncServiceCallback callback,
void *userdata, UA_UInt32 *requestId) {
return __UA_Client_AsyncService(client, &request,
&UA_TYPES[UA_TYPES_SETMONITORINGMODEREQUEST], callback,
&UA_TYPES[UA_TYPES_SETMONITORINGMODERESPONSE],
userdata, requestId);
}
static UA_INLINE UA_StatusCode
UA_Client_MonitoredItems_setTriggering_async(UA_Client *client,
const UA_SetTriggeringRequest request,
UA_ClientAsyncServiceCallback callback,
void *userdata, UA_UInt32 *requestId) {
return __UA_Client_AsyncService(client, &request,
&UA_TYPES[UA_TYPES_SETTRIGGERINGREQUEST], callback,
&UA_TYPES[UA_TYPES_SETTRIGGERINGRESPONSE],
userdata, requestId);
}
#endif
最近更新
查看本文最近更新请点击