24#include "csa_config.h"
30#include "open62541/plugin/log_stdout.h"
38 boost::shared_ptr<ControlSystemPVManager>
csManager,
const UA_Logger* logger,
string overwriteNodeString)
40 nodeStringIdOverwrite(std::move(overwriteNodeString)), array(false),
ua_mapped_class(server, basenodeid) {
41 this->mapSelfToNamespace(logger);
47 UA_NodeId_clear(&this->ownNodeId);
51 const UA_NodeId* ,
void* ,
const UA_NodeId* ,
void* nodeContext,
52 UA_Boolean includeSourceTimeStamp,
const UA_NumericRange* , UA_DataValue* value) {
55 UA_String ua_val = UA_String_fromChars((
char*)thisObj->getName().c_str());
56 UA_Variant_setScalarCopy(&value->value, &ua_val, &UA_TYPES[UA_TYPES_STRING]);
57 UA_String_clear(&ua_val);
58 value->hasValue =
true;
59 if(includeSourceTimeStamp) {
60 value->sourceTimestamp = thisObj->getSourceTimeStamp();
61 value->hasSourceTimestamp =
true;
63 return UA_STATUSCODE_GOOD;
72 const UA_NodeId* ,
void* ,
const UA_NodeId* ,
void* nodeContext,
73 const UA_NumericRange* ,
const UA_DataValue* value) {
77 s = (
char*)malloc(((UA_String) * ((UA_String*)value->value.data)).length + 1);
78 memset(s, 0, ((UA_String) * ((UA_String*)value->value.data)).length + 1);
79 memcpy(s, ((UA_String) * ((UA_String*)value->value.data)).data,
80 ((UA_String) * ((UA_String*)value->value.data)).length);
81 cpps.assign(s, ((UA_String) * ((UA_String*)value->value.data)).length);
83 theClass->setEngineeringUnit(cpps);
84 return UA_STATUSCODE_GOOD;
88 this->engineeringUnit = std::move(engineeringUnit);
92 const UA_NodeId* ,
void* ,
const UA_NodeId* ,
void* nodeContext,
93 UA_Boolean includeSourceTimeStamp,
const UA_NumericRange* , UA_DataValue* value) {
96 UA_String ua_val = UA_String_fromChars((
char*)thisObj->getEngineeringUnit().c_str());
97 UA_Variant_setScalarCopy(&value->value, &ua_val, &UA_TYPES[UA_TYPES_STRING]);
98 UA_String_clear(&ua_val);
99 value->hasValue =
true;
100 if(includeSourceTimeStamp) {
101 value->sourceTimestamp = thisObj->getSourceTimeStamp();
102 value->hasSourceTimestamp =
true;
104 return UA_STATUSCODE_GOOD;
108 if(!this->engineeringUnit.empty()) {
109 return this->engineeringUnit;
112 this->engineeringUnit = this->csManager->getProcessVariable(this->namePV)->getUnit();
113 return this->engineeringUnit;
119 const UA_NodeId* ,
void* ,
const UA_NodeId* ,
void* nodeContext,
120 const UA_NumericRange* ,
const UA_DataValue* value) {
124 s = (
char*)malloc(((UA_String) * ((UA_String*)value->value.data)).length + 1);
125 memset(s, 0, ((UA_String) * ((UA_String*)value->value.data)).length + 1);
126 memcpy(s, ((UA_String) * ((UA_String*)value->value.data)).data,
127 ((UA_String) * ((UA_String*)value->value.data)).length);
128 cpps.assign(s, ((UA_String) * ((UA_String*)value->value.data)).length);
130 theClass->setDescription(cpps);
131 return UA_STATUSCODE_GOOD;
135 this->description = std::move(description);
139 const UA_NodeId* ,
void* ,
const UA_NodeId* ,
void* nodeContext,
140 UA_Boolean includeSourceTimeStamp,
const UA_NumericRange* , UA_DataValue* value) {
143 UA_String ua_val = UA_String_fromChars((
char*)thisObj->getDescription().c_str());
144 UA_Variant_setScalarCopy(&value->value, &ua_val, &UA_TYPES[UA_TYPES_STRING]);
145 UA_String_clear(&ua_val);
146 value->hasValue =
true;
147 if(includeSourceTimeStamp) {
148 value->sourceTimestamp = thisObj->getSourceTimeStamp();
149 value->hasSourceTimestamp =
true;
151 return UA_STATUSCODE_GOOD;
155 const UA_NodeId* ,
void* ,
const UA_NodeId* ,
void* nodeContext,
156 UA_Boolean includeSourceTimeStamp,
const UA_NumericRange* , UA_DataValue* value) {
158 DataValidity dv = thisObj->csManager->getProcessVariable(thisObj->namePV)->dataValidity();
161 case DataValidity::ok:
164 case DataValidity::faulty:
170 UA_Variant_setScalarCopy(&value->value, &validity, &UA_TYPES[UA_TYPES_INT32]);
171 value->hasValue =
true;
172 if(includeSourceTimeStamp) {
173 value->sourceTimestamp = thisObj->getSourceTimeStamp();
174 value->hasSourceTimestamp =
true;
176 return UA_STATUSCODE_GOOD;
180 if(!this->description.empty()) {
181 return this->description;
184 this->description = this->csManager->getProcessVariable(this->namePV)->getDescription();
185 return this->description;
191 const UA_NodeId* ,
void* ,
const UA_NodeId* ,
void* nodeContext,
192 UA_Boolean includeSourceTimeStamp,
const UA_NumericRange* , UA_DataValue* value) {
195 UA_String ua_val = UA_String_fromChars((
char*)thisObj->getType().c_str());
196 UA_Variant_setScalarCopy(&value->value, &ua_val, &UA_TYPES[UA_TYPES_STRING]);
197 UA_String_clear(&ua_val);
198 value->hasValue =
true;
199 if(includeSourceTimeStamp) {
200 value->sourceTimestamp = thisObj->getSourceTimeStamp();
201 value->hasSourceTimestamp =
true;
203 return UA_STATUSCODE_GOOD;
208 std::type_info
const& valueType = this->csManager->getProcessVariable(this->namePV)->getValueType();
209 if(valueType ==
typeid(int8_t))
211 else if(valueType ==
typeid(uint8_t))
213 else if(valueType ==
typeid(int16_t))
215 else if(valueType ==
typeid(uint16_t))
217 else if(valueType ==
typeid(int32_t))
219 else if(valueType ==
typeid(uint32_t))
221 else if(valueType ==
typeid(int64_t))
223 else if(valueType ==
typeid(uint64_t))
225 else if(valueType ==
typeid(
float))
227 else if(valueType ==
typeid(
double))
229 else if(valueType ==
typeid(
string))
231 else if(valueType ==
typeid(Boolean))
233 else if(valueType ==
typeid(Void))
236 return "Unsupported type";
239 UA_StatusCode ua_processvariable::mapSelfToNamespace(
const UA_Logger* logger) {
240 UA_StatusCode retval = UA_STATUSCODE_GOOD;
241 UA_NodeId createdNodeId = UA_NODEID_NULL;
242 if(!nodeStringIdOverwrite.empty()) this->nameNew = nodeStringIdOverwrite;
244 if(UA_NodeId_equal(&this->
baseNodeId, &createdNodeId))
245 return UA_STATUSCODE_GOOD;
247 UA_LocalizedText description;
248 description = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
249 const_cast<char*
>(this->csManager->getProcessVariable(this->namePV)->getDescription().c_str()));
252 UA_VariableAttributes attr;
253 UA_VariableAttributes_init(&attr);
254 attr = UA_VariableAttributes_default;
256 attr.minimumSamplingInterval = -1.;
257 attr.displayName = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(this->nameNew.c_str()));
258 attr.description = description;
259 attr.dataType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATATYPE);
261 if(this->csManager->getProcessVariable(this->namePV)->isWriteable()) {
262 attr.writeMask = UA_ACCESSLEVELMASK_READ ^ UA_ACCESSLEVELMASK_WRITE;
263 attr.accessLevel = UA_ACCESSLEVELMASK_READ ^ UA_ACCESSLEVELMASK_WRITE;
268 string baseNodeIdName;
269 if(this->
baseNodeId.identifierType == UA_NODEIDTYPE_STRING) {
272 if(!baseNodeIdName.empty()) {
273 baseNodeIdName.resize(baseNodeIdName.size() - 3);
279 UA_NODEID_STRING(1,
const_cast<char*
>((baseNodeIdName +
"/" + this->nameNew).c_str())),
280 &result) == UA_STATUSCODE_GOOD) {
281 return UA_STATUSCODE_BADNODEIDEXISTS;
284 UA_NODEID_STRING(1,
const_cast<char*
>((baseNodeIdName +
"/" + this->nameNew).c_str())), this->
baseNodeId,
285 UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1,
const_cast<char*
>(this->nameNew.c_str())),
286 UA_NODEID_NUMERIC(CSA_NSID, 1001), attr, (
void*)
this, &createdNodeId);
287 UA_NodeId_copy(&createdNodeId, &this->ownNodeId);
292 this->addPVChildNodes(createdNodeId, baseNodeIdName, mapDs);
294 UA_Variant arrayDimensions;
295 UA_Variant_init(&arrayDimensions);
297 std::type_info
const& valueType = this->csManager->getProcessVariable(this->namePV)->getValueType();
300 mapElem.
typeTemplateId = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE);
301 mapElem.description = description;
303 UA_Variant uaArrayDimensions;
304 UA_UInt32 arrayDims[1];
306 if(valueType ==
typeid(int8_t)) {
307 arrayDims[0] = typeSpecificSetup<int8_t>(mapElem, createdNodeId);
309 else if(valueType ==
typeid(uint8_t)) {
310 arrayDims[0] = typeSpecificSetup<uint8_t>(mapElem, createdNodeId);
312 else if(valueType ==
typeid(int16_t)) {
313 arrayDims[0] = typeSpecificSetup<int16_t>(mapElem, createdNodeId);
315 else if(valueType ==
typeid(uint16_t)) {
316 arrayDims[0] = typeSpecificSetup<uint16_t>(mapElem, createdNodeId);
318 else if(valueType ==
typeid(int32_t)) {
319 arrayDims[0] = typeSpecificSetup<int32_t>(mapElem, createdNodeId);
321 else if(valueType ==
typeid(uint32_t)) {
322 arrayDims[0] = typeSpecificSetup<uint32_t>(mapElem, createdNodeId);
324 else if(valueType ==
typeid(int64_t)) {
325 arrayDims[0] = typeSpecificSetup<int64_t>(mapElem, createdNodeId);
327 else if(valueType ==
typeid(uint64_t)) {
328 arrayDims[0] = typeSpecificSetup<uint64_t>(mapElem, createdNodeId);
330 else if(valueType ==
typeid(
float)) {
331 arrayDims[0] = typeSpecificSetup<float>(mapElem, createdNodeId);
333 else if(valueType ==
typeid(
double)) {
334 arrayDims[0] = typeSpecificSetup<double>(mapElem, createdNodeId);
336 else if(valueType ==
typeid(
string)) {
337 arrayDims[0] = typeSpecificSetup<std::string>(mapElem, createdNodeId);
339 else if(valueType ==
typeid(Boolean)) {
340 arrayDims[0] = typeSpecificSetup<Boolean>(mapElem, createdNodeId);
342 else if(valueType !=
typeid(Void)) {
344 auto* demangledName = abi::__cxa_demangle(valueType.name(),
nullptr,
nullptr, &status);
347 UA_LOG_WARNING(logger, UA_LOGCATEGORY_USERLAND,
"Cannot proxy unknown type %s for variable %s", demangledName,
348 this->namePV.c_str());
352 UA_LOG_WARNING(logger, UA_LOGCATEGORY_USERLAND,
353 "Cannot proxy unknown type %s (demangling failed) for variable %s", valueType.name(), this->namePV.c_str());
357 if(!this->csManager->getProcessVariable(this->namePV)->isWriteable()) {
358 mapElem.dataSource.write =
nullptr;
361 UA_Server_writeValueRank(this->
mappedServer, createdNodeId, UA_VALUERANK_ONE_DIMENSION);
362 UA_Variant_setArray(&uaArrayDimensions, arrayDims, 1, &UA_TYPES[UA_TYPES_UINT32]);
363 UA_Server_writeArrayDimensions(this->
mappedServer, createdNodeId, uaArrayDimensions);
366 UA_Server_writeValueRank(this->
mappedServer, createdNodeId, UA_VALUERANK_SCALAR);
370 UA_NodeId_copy(&createdNodeId, &mapElem.concreteNodeId);
371 mapDs.push_back(mapElem);
373 UA_NodeId nodeIdVariableType = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE);
376 for(
auto i : mapDs) {
377 retval |= UA_Server_setVariableNode_dataSource(this->
mappedServer, i.concreteNodeId, i.dataSource);
378 UA_NodeId_clear(&i.concreteNodeId);
379 UA_NodeId_clear(&i.typeTemplateId);
381 UA_NodeId_clear(&createdNodeId);
385 UA_StatusCode ua_processvariable::addPVChildNodes(
387 UA_NodeId createdNodeId = UA_NODEID_NULL;
388 UA_VariableAttributes attr;
389 UA_StatusCode addResult;
393 mapElemName.
typeTemplateId = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE_NAME);
394 mapElemName.description = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
""));
396 mapElemName.dataSource.write =
nullptr;
398 UA_VariableAttributes_init(&attr);
399 attr = UA_VariableAttributes_default;
400 attr.displayName = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
"Name"));
401 attr.description = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
""));
402 attr.valueRank = UA_VALUERANK_SCALAR;
403 attr.dataType = UA_TYPES[UA_TYPES_STRING].typeId;
404 UA_String opcua_node_variable_t_ns_2_i_6004_variant_DataContents = UA_STRING_ALLOC(
const_cast<char*
>(
""));
405 UA_Variant_setScalar(
406 &attr.value, &opcua_node_variable_t_ns_2_i_6004_variant_DataContents, &UA_TYPES[UA_TYPES_STRING]);
407 addResult = UA_Server_addVariableNode(this->
mappedServer,
408 UA_NODEID_STRING(1,
const_cast<char*
>((baseNodePath +
"/" + this->nameNew +
"/Name").c_str())), pvNodeId,
409 UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), UA_QUALIFIEDNAME(1,
const_cast<char*
>(
"Name")),
410 UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), attr,
this, &createdNodeId);
411 if(addResult == UA_STATUSCODE_GOOD) {
412 UA_NodeId nameVariable = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE_NAME);
414 UA_NodeId_copy(&createdNodeId, &mapElemName.concreteNodeId);
415 map.push_back(mapElemName);
418 UA_NodeId_clear(&createdNodeId);
421 UA_NodeId_clear(&createdNodeId);
422 createdNodeId = UA_NODEID_NULL;
426 mapElemDesc.
typeTemplateId = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE_DESC);
427 mapElemDesc.description = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
""));
429 mapElemDesc.dataSource.write =
nullptr;
431 UA_VariableAttributes_init(&attr);
432 attr = UA_VariableAttributes_default;
433 attr.displayName = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
"Description"));
434 attr.description = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
""));
435 attr.accessLevel = UA_ACCESSLEVELMASK_READ;
436 attr.userAccessLevel = UA_ACCESSLEVELMASK_READ;
437 attr.valueRank = UA_VALUERANK_SCALAR;
438 attr.dataType = UA_TYPES[UA_TYPES_STRING].typeId;
439 UA_String opcua_node_variable_t_ns_2_i_6001_variant_DataContents = UA_STRING(
const_cast<char*
>(
""));
440 UA_Variant_setScalar(
441 &attr.value, &opcua_node_variable_t_ns_2_i_6001_variant_DataContents, &UA_TYPES[UA_TYPES_STRING]);
442 addResult = UA_Server_addVariableNode(this->
mappedServer,
443 UA_NODEID_STRING(1,
const_cast<char*
>((baseNodePath +
"/" + this->nameNew +
"/Description").c_str())), pvNodeId,
444 UA_NODEID_NUMERIC(0, 47), UA_QUALIFIEDNAME(1,
const_cast<char*
>(
"Description")), UA_NODEID_NUMERIC(0, 63), attr,
445 this, &createdNodeId);
446 if(addResult == UA_STATUSCODE_GOOD) {
447 UA_NodeId descVariable = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE_DESC);
449 UA_NodeId_copy(&createdNodeId, &mapElemDesc.concreteNodeId);
450 map.push_back(mapElemDesc);
453 UA_NodeId_clear(&createdNodeId);
457 UA_NodeId_clear(&createdNodeId);
458 createdNodeId = UA_NODEID_NULL;
462 mapElemEU.
typeTemplateId = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE_UNIT);
463 mapElemEU.description = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
""));
465 mapElemEU.dataSource.write =
nullptr;
466 UA_VariableAttributes_init(&attr);
467 attr = UA_VariableAttributes_default;
468 attr.displayName = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
"EngineeringUnit"));
469 attr.description = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
""));
470 attr.accessLevel = UA_ACCESSLEVELMASK_READ;
471 attr.userAccessLevel = UA_ACCESSLEVELMASK_READ;
472 attr.valueRank = UA_VALUERANK_SCALAR;
473 attr.dataType = UA_TYPES[UA_TYPES_STRING].typeId;
474 UA_String defaultEngineeringUnit = UA_STRING(
const_cast<char*
>(
""));
475 UA_Variant_setScalar(&attr.value, &defaultEngineeringUnit, &UA_TYPES[UA_TYPES_STRING]);
476 addResult = UA_Server_addVariableNode(this->
mappedServer,
477 UA_NODEID_STRING(1,
const_cast<char*
>((baseNodePath +
"/" + this->nameNew +
"/EngineeringUnit").c_str())),
478 pvNodeId, UA_NODEID_NUMERIC(0, 47), UA_QUALIFIEDNAME(1,
const_cast<char*
>(
"EngineeringUnit")),
479 UA_NODEID_NUMERIC(0, 63), attr,
this, &createdNodeId);
480 if(addResult == UA_STATUSCODE_GOOD) {
481 UA_NodeId engineeringunitVariable = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE_UNIT);
483 UA_NodeId_copy(&createdNodeId, &mapElemEU.concreteNodeId);
484 map.push_back(mapElemEU);
487 UA_NodeId_clear(&createdNodeId);
491 UA_NodeId_clear(&createdNodeId);
492 createdNodeId = UA_NODEID_NULL;
496 mapElemType.
typeTemplateId = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE_TYPE);
497 mapElemType.description = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
""));
499 mapElemType.dataSource.write =
nullptr;
500 UA_VariableAttributes_init(&attr);
501 attr = UA_VariableAttributes_default;
502 attr.displayName = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
"Type"));
503 attr.description = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
"Data type used in ChimeraTK"));
504 attr.accessLevel = UA_ACCESSLEVELMASK_READ;
505 attr.userAccessLevel = UA_ACCESSLEVELMASK_READ;
506 attr.valueRank = UA_VALUERANK_SCALAR;
507 attr.dataType = UA_TYPES[UA_TYPES_STRING].typeId;
508 UA_String opcua_node_variable_t_ns_2_i_6012_variant_DataContents = UA_STRING(
const_cast<char*
>(
""));
509 UA_Variant_setScalar(
510 &attr.value, &opcua_node_variable_t_ns_2_i_6012_variant_DataContents, &UA_TYPES[UA_TYPES_STRING]);
511 UA_NodeId nodeId = UA_NODEID_NUMERIC(2, 6012);
512 UA_NodeId typeDefinition = UA_NODEID_NUMERIC(0, 63);
513 UA_NodeId parentNodeId = UA_NODEID_NUMERIC(2, 1001);
514 addResult = UA_Server_addVariableNode(this->
mappedServer,
515 UA_NODEID_STRING(1,
const_cast<char*
>((baseNodePath +
"/" + this->nameNew +
"/Type").c_str())), pvNodeId,
516 UA_NODEID_NUMERIC(0, 47), UA_QUALIFIEDNAME(1,
const_cast<char*
>(
"Type")), UA_NODEID_NUMERIC(0, 63), attr,
this,
518 if(addResult == UA_STATUSCODE_GOOD) {
519 UA_NodeId typeVariable = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE_TYPE);
521 UA_NodeId_copy(&createdNodeId, &mapElemType.concreteNodeId);
522 map.push_back(mapElemType);
525 UA_NodeId_clear(&createdNodeId);
529 UA_NodeId_clear(&createdNodeId);
530 createdNodeId = UA_NODEID_NULL;
534 mapElemValidity.
typeTemplateId = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE_VALIDITY);
535 mapElemValidity.description = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
""));
537 mapElemValidity.dataSource.write =
nullptr;
538 UA_VariableAttributes_init(&attr);
539 attr = UA_VariableAttributes_default;
540 attr.displayName = UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
"Validity"));
542 UA_LOCALIZEDTEXT(
const_cast<char*
>(
"en_US"),
const_cast<char*
>(
"Data validity. 0: faulty, 1: ok"));
543 attr.accessLevel = UA_ACCESSLEVELMASK_READ;
544 attr.userAccessLevel = UA_ACCESSLEVELMASK_READ;
545 attr.valueRank = UA_VALUERANK_SCALAR;
546 attr.dataType = UA_TYPES[UA_TYPES_INT32].typeId;
547 UA_Int32 defaultValidity = -1;
548 UA_Variant_setScalar(&attr.value, &defaultValidity, &UA_TYPES[UA_TYPES_INT32]);
549 addResult = UA_Server_addVariableNode(this->
mappedServer,
550 UA_NODEID_STRING(1,
const_cast<char*
>((baseNodePath +
"/" + this->nameNew +
"/Validity").c_str())), pvNodeId,
551 UA_NODEID_NUMERIC(0, 47), UA_QUALIFIEDNAME(1,
const_cast<char*
>(
"Validity")), UA_NODEID_NUMERIC(0, 63), attr,
552 this, &createdNodeId);
553 if(addResult == UA_STATUSCODE_GOOD) {
554 UA_NodeId vadilityVariable = UA_NODEID_NUMERIC(CSA_NSID, CSA_NSID_VARIABLE_VALIDITY);
556 UA_NodeId_copy(&createdNodeId, &mapElemValidity.concreteNodeId);
557 map.push_back(mapElemValidity);
560 UA_NodeId_clear(&createdNodeId);
564 UA_NodeId_clear(&createdNodeId);
573 auto t = this->csManager->getProcessVariable(this->namePV)->getVersionNumber().getTime();
574 auto microseconds = std::chrono::time_point_cast<std::chrono::microseconds>(t).time_since_epoch().count();
576 if(microseconds == 0) {
577 microseconds = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now())
581 return (microseconds * UA_DATETIME_USEC) + UA_DATETIME_UNIX_EPOCH;
585 UA_NodeId outputNode;
586 UA_NodeId_copy(&this->ownNodeId, &outputNode);
This class mapped all inforamtion into the opca server.
This class represent a processvariable of the controlsystemadapter in the information model of a OPC ...
static UA_StatusCode ua_readproxy_ua_processvariable_getDescription(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *nodeId, void *nodeContext, UA_Boolean includeSourceTimeStamp, const UA_NumericRange *range, UA_DataValue *value)
static UA_StatusCode ua_writeproxy_ua_processvariable_setDescription(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *nodeId, void *nodeContext, const UA_NumericRange *range, const UA_DataValue *value)
void setEngineeringUnit(string engineeringUnit)
Set engineering unit of processvariable.
string getName()
Get name of processvariable.
string getType()
Get type of processvariable.
UA_DateTime getSourceTimeStamp()
Reimplement the sourcetimestamp for every processvariable.
~ua_processvariable()
Destructor for ua_processvariable.
static UA_StatusCode ua_readproxy_ua_processvariable_getEngineeringUnit(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *nodeId, void *nodeContext, UA_Boolean includeSourceTimeStamp, const UA_NumericRange *range, UA_DataValue *value)
UA_NodeId getOwnNodeId()
Get node id of this processvariable instance.
string getEngineeringUnit()
Get engineering unit of processvariable.
static UA_StatusCode ua_readproxy_ua_processvariable_getType(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *nodeId, void *nodeContext, UA_Boolean includeSourceTimeStamp, const UA_NumericRange *range, UA_DataValue *value)
static UA_StatusCode ua_readproxy_ua_processvariable_getValidity(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *nodeId, void *nodeContext, UA_Boolean includeSourceTimeStamp, const UA_NumericRange *range, UA_DataValue *value)
Get vadility of processvariable.
void setDescription(string description)
Get description unit of processvariable.
ua_processvariable(UA_Server *server, UA_NodeId basenodeid, const string &namePV, boost::shared_ptr< ControlSystemPVManager > csManager, const UA_Logger *logger, string overwriteNodeString="")
Constructor from ua_processvaribale for generic creation.
static UA_StatusCode ua_writeproxy_ua_processvariable_setEngineeringUnit(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *nodeId, void *nodeContext, const UA_NumericRange *range, const UA_DataValue *value)
static UA_StatusCode ua_readproxy_ua_processvariable_getName(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *nodeId, void *nodeContext, UA_Boolean includeSourceTimeStamp, const UA_NumericRange *range, UA_DataValue *value)
string getDescription()
Get description unit of processvariable.
boost::shared_ptr< ChimeraTK::ControlSystemPVManager > csManager
std::list< UA_DataSource_Map_Element > UA_DataSource_Map
struct ChimeraTK::UA_DataSource_Map_Element_t UA_DataSource_Map_Element
UA_StatusCode ua_mapInstantiatedNodes(UA_NodeId objectId, UA_NodeId definitionId, void *handle)
Node function and proxy mapping for new nodes.
#define NODE_PAIR_PUSH(_p_listname, _p_srcId, _p_targetId)
#define UA_STRING_TO_CPPSTRING_COPY(_p_uastring, _p_cppstring)