#include #include #include "helper_functions.h" #include // C++ includes #include using namespace std; UA_StatusCode setVariable(UA_Server* server, void *value, const UA_DataType *dataType, UA_NodeId variableNodeid) { UA_StatusCode res; UA_Variant var; UA_Variant_setScalar(&var, value, dataType); res = UA_Server_writeValue(server, variableNodeid, var); if(res != UA_STATUSCODE_GOOD) UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to init variable node NS=%d,i=%d. Error: %s\n", variableNodeid.namespaceIndex, variableNodeid.identifier.numeric, UA_StatusCode_name(res)); return res; } UA_StatusCode setEURangeVariable(UA_Server* server, UA_Double low, UA_Double high, UA_NodeId euRangeVariableNodeid) { UA_StatusCode res; UA_Range range; UA_Range_init(&range); range.low = low; range.high = high; res = setVariable(server, &range, &UA_TYPES[UA_TYPES_RANGE], euRangeVariableNodeid); if(res != UA_STATUSCODE_GOOD) UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Failed to set range for node NS=%d,i=%d. Error: %s\n", euRangeVariableNodeid.namespaceIndex, euRangeVariableNodeid.identifier.numeric, UA_StatusCode_name(res)); return res ; } // UA State-machine handling bool inState(UA_Server* server, UA_NodeId currentStateIdNodeId, UA_NodeId stateNodeId) { UA_Variant out; UA_Variant_init(&out); UA_Server_readValue(server, currentStateIdNodeId, &out); UA_NodeId *currentStateId = (UA_NodeId*)(out.data); if(UA_NodeId_equal(currentStateId, &stateNodeId)) return true; return false; } UA_StatusCode setCurrentState(UA_Server *server, UA_NodeId currentStateVariableNodeId, UA_NodeId currentStateVariableIdNodeId, UA_NodeId newStateNodeId) { // set the Id property of the CurrentState variable to newStateNodeId UA_Variant var; UA_Variant_init(&var); UA_Variant_setScalar(&var, &newStateNodeId, &UA_TYPES[UA_TYPES_NODEID]); UA_Server_writeValue(server, currentStateVariableIdNodeId, var); // set the CurrentState variable to a human-readable string UA_LocalizedText stateName; UA_LocalizedText_init(&stateName); UA_Server_readDisplayName(server, newStateNodeId, &stateName); UA_Variant_setScalar(&var, &stateName, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); UA_Server_writeValue(server, currentStateVariableNodeId, var); } // Configuration file handling bool getIntFromConfig(const config_t* cfg, const char* name, int *res) { if (!config_lookup_int(cfg, name, res)) { cerr << "No " << name << " setting in configuration file." << endl; return false; } return true; } bool getBoolFromConfig(const config_t* cfg, const char* name, bool *res) { int resInt; *res = false; if (!config_lookup_bool(cfg, name, &resInt)) { cerr << "No " << name << " setting in configuration file." << endl; return false; } if (resInt != 0) *res = true; return true; } bool getStringFromConfig(const config_t* cfg, const char* name, char **res) { if (!config_lookup_string(cfg, name, (const char **) res)) { cerr << "No " << name << " setting in configuration file." << endl; return false; } return true; } bool getStringListFromConfig(const config_t* cfg, const char* name, char **res, int *listLength) { config_setting_t *setting = config_lookup(cfg, name); *listLength = config_setting_length(setting); if (*listLength == 0) { cerr << "No " << name << " setting in configuration file or wrong format. Note that a list of strings should look like this: (\"item1\", \"item2\")." << endl; return false; } for(int i = 0; i < *listLength; i++){ const char *elem = config_setting_get_string_elem (setting, i); if (elem == NULL) { cerr << "No " << name << " setting in configuration file or wrong format. Note that a list of strings should look like this: (\"item1\", \"item2\")." << endl; return false; } res[i] = strdup(elem); } return true; } bool getDoubleFromConfig(const config_t* cfg, const char* name, double *res) { if (!config_lookup_float(cfg, name, res)) { cerr << "No " << name << " setting in configuration file." << endl; return false; } return true; }