Skip to content

Commit

Permalink
add utility functions
Browse files Browse the repository at this point in the history
  • Loading branch information
dpazj committed Oct 28, 2024
1 parent a9bf80c commit 1cf4037
Show file tree
Hide file tree
Showing 6 changed files with 263 additions and 172 deletions.
24 changes: 22 additions & 2 deletions examples/tutorial_server_alarms_conditions.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,28 @@ afterInputNodeWrite (UA_Server *server,
UA_Server_exclusiveLimitAlarmEvaluate_default(server, &conditionInstance_1, NULL, (UA_Double*) data->value.data);
}

static UA_StatusCode
getInputNodeValue (UA_Server *server, UA_NodeId conditionId, UA_Variant *out)
{
UA_QualifiedName inputNodeQN = UA_QUALIFIEDNAME(0, "InputNode");
UA_BrowsePathResult bpr = UA_Server_browseSimplifiedBrowsePath(server, conditionId, 1, &inputNodeQN);
if (bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize != 1) return bpr.statusCode;
UA_Variant sourceNodeId;
UA_StatusCode status = UA_Server_readValue(server, bpr.targets[0].targetId.nodeId, &sourceNodeId);
UA_BrowsePathResult_clear(&bpr);
if (status != UA_STATUSCODE_GOOD || sourceNodeId.type != &UA_TYPES[UA_TYPES_NODEID]) return status;
status = UA_Server_readValue(server, *(UA_NodeId*) sourceNodeId.data, out);
UA_Variant_clear(&sourceNodeId);
return status;
}


static void *
sourceNodeGetInputDouble (UA_Server *server, const UA_NodeId *conditionId, void *conditionCtx)
{
UA_Variant val;
UA_Variant_init (&val);
UA_StatusCode ret = UA_Server_Condition_getInputNodeValue(server, *conditionId, &val);
UA_StatusCode ret = getInputNodeValue(server, *conditionId, &val);
if (ret != UA_STATUSCODE_GOOD || val.type != &UA_TYPES[UA_TYPES_DOUBLE])
{
UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
Expand All @@ -101,7 +117,11 @@ static UA_StatusCode onCondition1Active (
void *context
)
{
return UA_Server_Condition_setAcknowledgeRequired(server, *conditionId);
UA_NodeId ackedId;
UA_Server_getNodeIdWithBrowseName(server, conditionId, UA_QUALIFIEDNAME(0, "AckedState"), &ackedId);
UA_Server_writeTwoStateVariable(server, ackedId, UA_LOCALIZEDTEXT("en", "Unacknowledged"), false);
UA_NodeId_clear (&ackedId);
return UA_STATUSCODE_GOOD;
}

UA_ConditionCallbacks condition1Impl = {
Expand Down
75 changes: 55 additions & 20 deletions include/open62541/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -1265,6 +1265,59 @@ UA_StatusCode UA_EXPORT UA_THREADSAFE
UA_Server_readObjectProperty(UA_Server *server, const UA_NodeId objectId,
const UA_QualifiedName propertyName,
UA_Variant *value);

/**
* Write a value to a node via a simplified browsepath
* @param server
* @param objectId
* @param value
* @param pathSize
* @param path
* @return
*/
UA_StatusCode
UA_Server_writeValueSimplifiedBrowsePath (
UA_Server *server,
const UA_NodeId objectId,
const UA_Variant value,
size_t pathSize,
const UA_QualifiedName *path
);

/**
* read a value from a node via a simplified browsepath
* @param server
* @param objectId
* @param pathSize
* @param path
* @param value
* @return
*/
UA_StatusCode
UA_Server_readValueSimplifiedBrowsePath (
UA_Server *server,
const UA_NodeId objectId,
size_t pathSize,
const UA_QualifiedName *path,
UA_Variant *value
);

/**
* write the values to a two state variable node
* @param server
* @param twoStateVariableId
* @param value
* @param idValue
* @return
*/
UA_StatusCode
UA_Server_writeTwoStateVariable (
UA_Server *server,
const UA_NodeId twoStateVariableId,
UA_LocalizedText value,
UA_Boolean idValue
);

/*
* Get the nodeId of a node from an origin node and a browse name
*
Expand Down Expand Up @@ -1758,28 +1811,10 @@ UA_StatusCode UA_EXPORT
UA_Server_Condition_placeInService(UA_Server *server, UA_NodeId conditionId, const UA_LocalizedText *comment);

/*
Condition direct State Maniputation
Condition Evaluation and Event Generation
*/

/*
* Set the condition confirmed state where a confirmation is required. The logic for setting this is Server specific, so
* the only time a conditions ConfirmedState will be set to false is when a server implementation uses this function .
*/
UA_StatusCode UA_EXPORT
UA_Server_Condition_setConfirmRequired(UA_Server *server, UA_NodeId conditionId);

UA_StatusCode UA_EXPORT
UA_Server_Condition_setAcknowledgeRequired(UA_Server *server, UA_NodeId conditionId);

UA_StatusCode UA_EXPORT
UA_Server_Condition_getInputNodeValue (UA_Server *server, UA_NodeId conditionId, UA_Variant *out);

UA_StatusCode UA_EXPORT
UA_Server_Condition_setActiveState (UA_Server *server, UA_NodeId conditionId, UA_Boolean active);

/*
Condition Event Generation
*/
UA_Server_Condition_evaluateRetainState (UA_Server *server, UA_NodeId conditionId);

UA_StatusCode UA_EXPORT
UA_Server_Condition_notifyStateChange(UA_Server *server, UA_NodeId condition, const UA_ConditionEventInfo *info);
Expand Down
24 changes: 24 additions & 0 deletions src/server/ua_server_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,30 @@ readObjectProperty(UA_Server *server, const UA_NodeId objectId,
const UA_QualifiedName propertyName,
UA_Variant *value);

UA_StatusCode writeValueSimplifiedBrowsePath (
UA_Server *server,
const UA_NodeId object_id,
const UA_Variant value,
size_t path_size,
const UA_QualifiedName *path
);

UA_StatusCode readValueSimplifiedBrowsePath (
UA_Server *server,
const UA_NodeId object_id,
size_t path_size,
const UA_QualifiedName *path,
UA_Variant *value
);

UA_StatusCode
writeTwoStateVariable (
UA_Server *server,
const UA_NodeId twoStateVariableId,
UA_LocalizedText value,
UA_Boolean idValue
);

UA_StatusCode
getNodeIdWithBrowseName(UA_Server *server, const UA_NodeId *origin,
UA_QualifiedName browseName, UA_NodeId *outNodeId);
Expand Down
102 changes: 101 additions & 1 deletion src/server/ua_services_attribute.c
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,6 @@ readObjectProperty(UA_Server *server, const UA_NodeId objectId,
return retval;
}


UA_StatusCode
UA_Server_readObjectProperty(UA_Server *server, const UA_NodeId objectId,
const UA_QualifiedName propertyName,
Expand All @@ -799,6 +798,107 @@ UA_Server_readObjectProperty(UA_Server *server, const UA_NodeId objectId,
return retval;
}

UA_StatusCode writeValueSimplifiedBrowsePath (
UA_Server *server,
const UA_NodeId object_id,
const UA_Variant value,
size_t path_size,
const UA_QualifiedName *path
)
{
UA_StatusCode retval;
UA_BrowsePathResult bpr = browseSimplifiedBrowsePath (server, object_id, path_size, path);
if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) {
retval = bpr.statusCode;
UA_BrowsePathResult_clear(&bpr);
return retval;
}
UA_StatusCode ret = writeValueAttribute(server, bpr.targets[0].targetId.nodeId, &value);
UA_BrowsePathResult_clear (&bpr);
return ret;
}

UA_StatusCode readValueSimplifiedBrowsePath (
UA_Server *server,
const UA_NodeId object_id,
size_t path_size,
const UA_QualifiedName *path,
UA_Variant *value
)
{
UA_StatusCode retval;
UA_BrowsePathResult bpr = browseSimplifiedBrowsePath (server, object_id, path_size, path);
if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) {
retval = bpr.statusCode;
UA_BrowsePathResult_clear(&bpr);
return retval;
}
UA_StatusCode ret = readWithReadValue(server, &bpr.targets[0].targetId.nodeId, UA_ATTRIBUTEID_VALUE, value);
UA_BrowsePathResult_clear (&bpr);
return ret;
}

inline UA_StatusCode
UA_Server_writeValueSimplifiedBrowsePath (
UA_Server *server,
const UA_NodeId objectId,
const UA_Variant value,
size_t pathSize,
const UA_QualifiedName *path
)
{
UA_LOCK(&server->serviceMutex);
UA_StatusCode retval = writeValueSimplifiedBrowsePath (server, objectId, value, pathSize, path);
UA_UNLOCK(&server->serviceMutex);
return retval;
}

inline UA_StatusCode
UA_Server_readValueSimplifiedBrowsePath (
UA_Server *server,
const UA_NodeId objectId,
size_t pathSize,
const UA_QualifiedName *path,
UA_Variant *value
)
{
UA_LOCK(&server->serviceMutex);
UA_StatusCode retval = readValueSimplifiedBrowsePath (server, objectId, pathSize, path, value);
UA_UNLOCK(&server->serviceMutex);
return retval;
}

inline UA_StatusCode
writeTwoStateVariable (
UA_Server *server,
const UA_NodeId twoStateVariableId,
UA_LocalizedText value,
UA_Boolean idValue
)
{
UA_Variant val;
UA_Variant_setScalar(&val, &value, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);
UA_StatusCode ret = writeValueAttribute (server, twoStateVariableId, &val);
if (ret != UA_STATUSCODE_GOOD) return ret;
UA_Variant_setScalar(&val, &idValue, &UA_TYPES[UA_TYPES_BOOLEAN]);
UA_QualifiedName idPath = UA_QUALIFIEDNAME(0, "Id");
return writeValueSimplifiedBrowsePath (server, twoStateVariableId, val, 1, &idPath);
}

inline UA_StatusCode
UA_Server_writeTwoStateVariable (
UA_Server *server,
const UA_NodeId twoStateVariableId,
UA_LocalizedText value,
UA_Boolean idValue
)
{
UA_LOCK(&server->serviceMutex);
UA_StatusCode retval = writeTwoStateVariable (server, twoStateVariableId, value, idValue);
UA_UNLOCK(&server->serviceMutex);
return retval;
}

UA_StatusCode
getNodeIdWithBrowseName(UA_Server *server, const UA_NodeId *origin,
UA_QualifiedName browseName, UA_NodeId *outNodeId)
Expand Down
Loading

0 comments on commit 1cf4037

Please sign in to comment.