24#include "ChimeraTK/ControlSystemAdapter/ControlSystemPVManager.h"
25#include "ChimeraTK/SupportedUserTypes.h"
28#include <boost/fusion/container/map.hpp>
32namespace fusion = boost::fusion;
36 typedef fusion::map<fusion::pair<int8_t, uint>, fusion::pair<uint8_t, uint>, fusion::pair<int16_t, uint>,
37 fusion::pair<uint16_t, uint>, fusion::pair<int32_t, uint>, fusion::pair<uint32_t, uint>,
38 fusion::pair<int64_t, uint>, fusion::pair<uint64_t, uint>, fusion::pair<float, uint>, fusion::pair<double, uint>,
39 fusion::pair<string, uint>, fusion::pair<Boolean, uint>>
53 string nodeStringIdOverwrite;
54 string engineeringUnit;
56 UA_NodeId ownNodeId = UA_NODEID_NULL;
58 TypesMap typesMap{fusion::make_pair<int8_t>(UA_TYPES_SBYTE), fusion::make_pair<uint8_t>(UA_TYPES_BYTE),
59 fusion::make_pair<int16_t>(UA_TYPES_INT16), fusion::make_pair<uint16_t>(UA_TYPES_UINT16),
60 fusion::make_pair<int32_t>(UA_TYPES_INT32), fusion::make_pair<uint32_t>(UA_TYPES_UINT32),
61 fusion::make_pair<int64_t>(UA_TYPES_INT64), fusion::make_pair<uint64_t>(UA_TYPES_UINT64),
62 fusion::make_pair<float>(UA_TYPES_FLOAT), fusion::make_pair<double>(UA_TYPES_DOUBLE),
63 fusion::make_pair<string>(UA_TYPES_STRING), fusion::make_pair<Boolean>(UA_TYPES_BOOLEAN)};
67 boost::shared_ptr<ControlSystemPVManager> csManager;
68 UA_StatusCode addPVChildNodes(UA_NodeId pvNodeId,
const string& baseNodePath,
UA_DataSource_Map& map);
74 UA_StatusCode mapSelfToNamespace(
const UA_Logger* logger);
87 boost::shared_ptr<ControlSystemPVManager>
csManager,
const UA_Logger* logger,
string overwriteNodeString =
"");
100 void* sessionContext,
const UA_NodeId* nodeId,
void* nodeContext, UA_Boolean includeSourceTimeStamp,
101 const UA_NumericRange* range, UA_DataValue* value);
110 void* sessionContext,
const UA_NodeId* nodeId,
void* nodeContext, UA_Boolean includeSourceTimeStamp,
111 const UA_NumericRange* range, UA_DataValue* value);
120 const UA_NodeId* sessionId,
void* sessionContext,
const UA_NodeId* nodeId,
void* nodeContext,
121 UA_Boolean includeSourceTimeStamp,
const UA_NumericRange* range, UA_DataValue* value);
124 const UA_NodeId* sessionId,
void* sessionContext,
const UA_NodeId* nodeId,
void* nodeContext,
125 const UA_NumericRange* range,
const UA_DataValue* value);
139 void* sessionContext,
const UA_NodeId* nodeId,
void* nodeContext,
const UA_NumericRange* range,
140 const UA_DataValue* value);
143 void* sessionContext,
const UA_NodeId* nodeId,
void* nodeContext, UA_Boolean includeSourceTimeStamp,
144 const UA_NumericRange* range, UA_DataValue* value);
148 void* sessionContext,
const UA_NodeId* nodeId,
void* nodeContext, UA_Boolean includeSourceTimeStamp,
149 const UA_NumericRange* range, UA_DataValue* value);
170 void* sessionContext,
const UA_NodeId* nodeId,
void* nodeContext, UA_Boolean includeSourceTimeStamp,
171 const UA_NumericRange* range, UA_DataValue* value);
174 UA_StatusCode
getValue(UA_Variant* v,
const UA_NumericRange* range);
178 void* sessionContext,
const UA_NodeId* nodeId,
void* nodeContext,
const UA_NumericRange* range,
179 const UA_DataValue* value);
182 UA_StatusCode
setValue(
const UA_Variant* data);
190 const UA_NodeId* ,
void* ,
const UA_NodeId* ,
void* nodeContext,
191 UA_Boolean includeSourceTimeStamp,
const UA_NumericRange* range, UA_DataValue* value) {
193 UA_StatusCode rv = UA_STATUSCODE_GOOD;
194 rv = thisObj->
getValue<T>(&value->value, range);
195 if(rv == UA_STATUSCODE_GOOD) {
196 value->hasValue =
true;
197 if(includeSourceTimeStamp) {
198 value->sourceTimestamp = thisObj->getSourceTimeStamp();
199 value->hasSourceTimestamp =
true;
207 const UA_NodeId* ,
void* ,
const UA_NodeId* ,
void* nodeContext,
208 const UA_NumericRange* ,
const UA_DataValue* value) {
209 UA_StatusCode retval = UA_STATUSCODE_BADINTERNALERROR;
211 retval = theClass->
setValue<T>(&value->value);
217 UA_StatusCode rv = UA_STATUSCODE_BADINTERNALERROR;
218 if(this->csManager->getProcessVariable(this->namePV)->isReadable()) {
219 this->csManager->getProcessArray<T>(this->namePV)->readLatest();
221 if(this->csManager->getProcessArray<T>(this->namePV)->accessChannel(0).size() == 1) {
222 T ival = this->csManager->getProcessArray<T>(this->namePV)->accessChannel(0).at(0);
223 rv = UA_Variant_setScalarCopy(v, &ival, &UA_TYPES[fusion::at_key<T>(typesMap)]);
226 std::vector<T> iarr = this->csManager->getProcessArray<T>(this->namePV)->accessChannel(0);
227 v->type = &UA_TYPES[fusion::at_key<T>(typesMap)];
228 if(range !=
nullptr) {
231 UA_Variant tmpVariant;
232 UA_Variant_setArray(&tmpVariant, iarr.data(), iarr.size(), &UA_TYPES[fusion::at_key<T>(typesMap)]);
233 rv = UA_Variant_copyRange(&tmpVariant, v, *range);
236 rv = UA_Variant_setArrayCopy(v, iarr.data(), iarr.size(), &UA_TYPES[fusion::at_key<T>(typesMap)]);
243 inline UA_StatusCode ua_processvariable::getValue<string>(UA_Variant* v,
const UA_NumericRange* ) {
244 UA_StatusCode rv = UA_STATUSCODE_BADINTERNALERROR;
245 if(this->csManager->getProcessVariable(this->namePV)->isReadable()) {
246 this->csManager->getProcessArray<
string>(this->namePV)->readLatest();
248 if(this->csManager->getProcessArray<
string>(this->namePV)->accessChannel(0).size() == 1) {
249 string sval = this->csManager->getProcessArray<
string>(this->namePV)->accessChannel(0).at(0);
250 UA_String ua_val = UA_String_fromChars((
char*)sval.c_str());
251 rv = UA_Variant_setScalarCopy(v, &ua_val, &UA_TYPES[UA_TYPES_STRING]);
252 UA_String_clear(&ua_val);
255 std::vector<string> sarr = this->csManager->getProcessArray<
string>(this->namePV)->accessChannel(0);
256 auto* sarrayval =
new UA_String[sarr.size()];
257 for(
size_t i = 0; i < sarr.size(); i++) {
258 sarrayval[i] = UA_String_fromChars((
char*)sarr[i].c_str());
260 rv = UA_Variant_setArrayCopy(v, sarrayval, sarr.size(), &UA_TYPES[UA_TYPES_STRING]);
268 UA_StatusCode retval = UA_STATUSCODE_BADINTERNALERROR;
270 if(this->csManager->getProcessVariable(this->namePV)->isWriteable()) {
271 vector<T> valueArray;
272 if(UA_Variant_isScalar(data) && (!array)) {
273 T value = *((T*)data->data);
274 valueArray.push_back(value);
276 else if((!UA_Variant_isScalar(data)) && array) {
277 auto* v = (T*)data->data;
278 valueArray.resize(data->arrayLength);
279 for(
size_t i = 0; i < valueArray.size(); i++) {
280 valueArray.at(i) = v[i];
282 if(this->csManager->getProcessArray<T>(this->namePV)->accessChannel(0).size() != data->arrayLength) {
283 return UA_STATUSCODE_BADINVALIDARGUMENT;
286 this->csManager->getProcessArray<T>(this->namePV)->accessChannel(0) = valueArray;
287 this->csManager->getProcessArray<T>(this->namePV)->write();
288 retval = UA_STATUSCODE_GOOD;
291 retval = UA_STATUSCODE_BADNOTWRITABLE;
298 inline UA_StatusCode ua_processvariable::setValue<std::string>(
const UA_Variant* data) {
299 UA_StatusCode retval = UA_STATUSCODE_BADINTERNALERROR;
301 if(this->
csManager->getProcessVariable(this->namePV)->isWriteable()) {
302 vector<string> valueArray;
303 if(UA_Variant_isScalar(data) && (!array)) {
307 valueArray.push_back(cpps);
309 else if((!UA_Variant_isScalar(data)) && array) {
311 auto* vdata = (UA_String*)data->data;
312 valueArray.resize(data->arrayLength);
313 for(uint32_t i = 0; i < valueArray.size(); i++) {
316 valueArray.at(i) = cpps;
318 if(this->
csManager->getProcessArray<
string>(this->namePV)->accessChannel(0).size() != data->arrayLength) {
319 return UA_STATUSCODE_BADINVALIDARGUMENT;
322 this->
csManager->getProcessArray<
string>(this->namePV)->accessChannel(0) = valueArray;
323 this->
csManager->getProcessArray<
string>(this->namePV)->write();
324 retval = UA_STATUSCODE_GOOD;
327 retval = UA_STATUSCODE_BADNOTWRITABLE;
336 mapElem.
dataSource.read = ua_processvariable::ua_readproxy_ua_processvariable_getValue<T>;
337 if(this->csManager->getProcessVariable(this->namePV)->isWriteable()) {
338 mapElem.
dataSource.write = ua_processvariable::ua_writeproxy_ua_processvariable_setValue<T>;
340 if(this->csManager->getProcessArray<T>(this->namePV)->accessChannel(0).size() == 1) {
345 arrayDims = this->csManager->getProcessArray<T>(this->namePV)->accessChannel(0).size();
347 UA_Server_writeDataType(this->
mappedServer, nodeId, UA_TYPES[fusion::at_key<T>(typesMap)].typeId);
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.
static UA_StatusCode ua_writeproxy_ua_processvariable_setValue(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *nodeId, void *nodeContext, const UA_NumericRange *range, const UA_DataValue *value)
string getType()
Get type of processvariable.
UA_DateTime getSourceTimeStamp()
Reimplement the sourcetimestamp for every processvariable.
~ua_processvariable()
Destructor for ua_processvariable.
UA_UInt32 typeSpecificSetup(UA_DataSource_Map_Element &mapElem, const UA_NodeId nodeId)
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.
static UA_StatusCode ua_readproxy_ua_processvariable_getValue(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 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.
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)
UA_StatusCode setValue(const UA_Variant *data)
UA_StatusCode getValue(UA_Variant *v, const UA_NumericRange *range)
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
fusion::map< fusion::pair< int8_t, uint >, fusion::pair< uint8_t, uint >, fusion::pair< int16_t, uint >, fusion::pair< uint16_t, uint >, fusion::pair< int32_t, uint >, fusion::pair< uint32_t, uint >, fusion::pair< int64_t, uint >, fusion::pair< uint64_t, uint >, fusion::pair< float, uint >, fusion::pair< double, uint >, fusion::pair< string, uint >, fusion::pair< Boolean, uint > > TypesMap
For generic callback use, this sturct contains the methode pointer and a NodeId of the model.
#define UASTRING_TO_CPPSTRING(_p_uastring, _p_cppstring)