float *ilist;
} App;
-UA_StatusCode add_float(App *app, UA_NodeId parentNode,
- const char *name, const char *displayName, UA_Float value);
-UA_StatusCode add_int32(App *app, UA_NodeId parentNode,
- const char *name, const char *displayName, UA_Int32 value);
-UA_StatusCode add_int64(App *app, UA_NodeId parentNode,
- const char *name, const char *displayName, UA_Int64 value);
-UA_StatusCode add_float_vector(App *app, UA_NodeId parentNode,
- const char *name, const char *displayName, size_t len, UA_Float *value);
+UA_StatusCode add_scalar(App *app, UA_NodeId parentNode,
+ const char *fullname, const char *displayName,
+ void *value, const UA_DataType *valueType);
UA_StatusCode add_object_node(App *app, UA_NodeId parentNode,
- const char *name, const char *displayName,
+ const char *fullname, const char *displayName,
UA_NodeId *newNodeId);
+UA_StatusCode add_vector(App *app, UA_NodeId parentNode,
+ const char *fullname, const char *displayName,
+ size_t len, UA_Float *value, const UA_DataType *valueType);
+
UA_StatusCode update_scalar(App *app, UA_NodeId nodeId, void *valuePtr, const UA_DataType *typePtr);
UA_StatusCode update_float_vector(App *app, UA_NodeId nodeId, size_t len, const float *vector);
UA_StatusCode update_xlist(App *app);
#include "opc_app.h"
#include "wdf_utils.h"
-UA_StatusCode add_float(App *app, UA_NodeId parentNode, const char *name, const char *displayName, UA_Float value)
+static UA_StatusCode addVariableNode(UA_Server *server, UA_Int16 nsIndex, UA_NodeId parentNode,
+ const char *fullname, const char *displayName, const UA_VariableAttributes attr)
{
- UA_VariableAttributes attr = UA_VariableAttributes_default;
- if (displayName != NULL)
- attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US", displayName);
- UA_Variant_setScalar(&attr.value, &value, &UA_TYPES[UA_TYPES_FLOAT]);
+ const char *name = strrchr(fullname, '.');
+ name = (name == NULL) ? fullname : name + 1;
- char id[64] = {0};
- strcat(id, "renishaw.spd.");
- strcat(id, name);
-
- UA_NodeId nodeId = UA_NODEID_STRING(app->ns, id);
+ UA_NodeId nodeId = UA_NODEID_STRING_ALLOC(nsIndex, fullname);
UA_NodeId parentRefId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
UA_NodeId varType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE);
- UA_QualifiedName browseName = UA_QUALIFIEDNAME_ALLOC(app->ns, name);
+ UA_QualifiedName browseName = UA_QUALIFIEDNAME_ALLOC(nsIndex, displayName);
return UA_Server_addVariableNode(
- app->server, nodeId, parentNode, parentRefId, browseName,
+ server, nodeId, parentNode, parentRefId, browseName,
varType, attr, NULL, NULL);
}
-UA_StatusCode add_int32(App *app, UA_NodeId parentNode, const char *name, const char *displayName, UA_Int32 value)
+UA_StatusCode add_scalar(App *app, UA_NodeId parentNode, const char *fullname, const char *displayName, void *value, const UA_DataType *valueType)
{
+ // create a variant with the data and datatype and the display name
UA_VariableAttributes attr = UA_VariableAttributes_default;
if (displayName != NULL)
attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US", displayName);
- UA_Variant_setScalar(&attr.value, &value, &UA_TYPES[UA_TYPES_INT32]);
-
- char id[64] = {0};
- strcat(id, "renishaw.spd.");
- strcat(id, name);
-
- UA_NodeId nodeId = UA_NODEID_STRING_ALLOC(app->ns, id);
- UA_NodeId parentRefId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
- UA_NodeId varType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE);
- UA_QualifiedName browseName = UA_QUALIFIEDNAME_ALLOC(app->ns, name);
-
- return UA_Server_addVariableNode(
- app->server, nodeId, parentNode, parentRefId, browseName,
- varType, attr, NULL, NULL);
+ UA_Variant_setScalar(&attr.value, value, valueType);
+ return addVariableNode(app->server, app->ns, parentNode, fullname, displayName, attr);
}
-UA_StatusCode add_int64(App *app, UA_NodeId parentNode, const char *name, const char *displayName, UA_Int64 value)
+UA_StatusCode add_vector(App *app, UA_NodeId parentNode, const char *fullname, const char *displayName, size_t len, UA_Float *value, const UA_DataType *valueType)
{
+ UA_Int32 dims = (UA_Int32)len;
UA_VariableAttributes attr = UA_VariableAttributes_default;
+ attr.valueRank = UA_VALUERANK_ONE_DIMENSION;
+ attr.arrayDimensions = &dims;
+ attr.arrayDimensionsSize = 1;
if (displayName != NULL)
attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US", displayName);
- UA_Variant_setScalar(&attr.value, &value, &UA_TYPES[UA_TYPES_INT64]);
-
- char id[64] = {0};
- strcat(id, "renishaw.spd.");
- strcat(id, name);
-
- UA_NodeId nodeId = UA_NODEID_STRING_ALLOC(app->ns, id);
- UA_NodeId parentRefId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
- UA_NodeId varType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE);
- UA_QualifiedName browseName = UA_QUALIFIEDNAME_ALLOC(app->ns, name);
-
- return UA_Server_addVariableNode(
- app->server, nodeId, parentNode, parentRefId, browseName,
- varType, attr, NULL, NULL);
+ UA_Variant_setArray(&attr.value, value, len, valueType);
+ return addVariableNode(app->server, app->ns, parentNode, fullname, displayName, attr);
}
UA_StatusCode add_object_node(App *app,
UA_NodeId parentNode,
- const char *name, const char *displayName,
+ const char *fullname, const char *displayName,
UA_NodeId *newNodeId)
{
+ const char *name = strrchr(fullname, '.');
+ name = (name == NULL) ? fullname : name + 1;
+
UA_ObjectAttributes attr = UA_ObjectAttributes_default;
+ if (displayName != NULL)
+ attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US", displayName);
return UA_Server_addObjectNode(app->server,
- UA_NODEID_STRING_ALLOC(app->ns, name),
+ UA_NODEID_STRING_ALLOC(app->ns, fullname),
parentNode,
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
UA_QUALIFIEDNAME_ALLOC(app->ns, displayName),
attr, NULL, newNodeId);
}
-UA_StatusCode add_float_vector(App *app, UA_NodeId parentNode, const char *name, const char *displayName, size_t len, UA_Float *value)
-{
- UA_Int32 dims = (UA_Int32)len;
- UA_VariableAttributes attr = UA_VariableAttributes_default;
- attr.valueRank = UA_VALUERANK_ONE_DIMENSION;
- attr.arrayDimensions = &dims;
- attr.arrayDimensionsSize = 1;
- if (displayName != NULL)
- attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en-US", displayName);
- UA_Variant_setArray(&attr.value, value, len, &UA_TYPES[UA_TYPES_FLOAT]);
-
- char id[64] = {0};
- strcat(id, "renishaw.spd.");
- strcat(id, name);
-
- UA_NodeId nodeId = UA_NODEID_STRING_ALLOC(app->ns, id);
- UA_NodeId parentRefId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
- UA_NodeId varType = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE);
- UA_QualifiedName browseName = UA_QUALIFIEDNAME_ALLOC(app->ns, name);
-
- return UA_Server_addVariableNode(
- app->server, nodeId, parentNode, parentRefId, browseName,
- varType, attr, NULL, NULL);
-}
-
UA_StatusCode update_float_vector(App *app, UA_NodeId nodeId, size_t len, const float *vector)
{
UA_Variant value;
ssize_t count = wdf_read_xlist(app->filehandle, app->hdr.npoints, app->xlist);
if (count > 0)
{
- UA_NodeId node = UA_NODEID_STRING_ALLOC(app->ns, "renishaw.spd.xlist");
+ UA_NodeId node = UA_NODEID_STRING_ALLOC(app->ns, "renishaw.spd.spectrum.xlist");
status = update_float_vector(app, node, app->hdr.npoints, app->xlist);
}
}
WdfBlock section = {0};
uint64_t pos = wdf_find_section(app->filehandle, WDF_BLOCKID_DATA, WDF_BLOCKID_ANY, §ion);
wdf_read_spectrum(app->filehandle, pos, app->hdr.npoints, app->spectrumIndex, app->ilist);
- UA_NodeId node = UA_NODEID_STRING_ALLOC(app->ns, "renishaw.spd.ilist");
+ UA_NodeId node = UA_NODEID_STRING_ALLOC(app->ns, "renishaw.spd.spectrum.ilist");
return update_float_vector(app, node, app->hdr.npoints, app->ilist);
}
static int usage(int exitCode)
{
- fprintf(stderr, "usage: opc_server ?-port NUM? ?-register? FILENAME\n");
+ fprintf(stderr, "usage: opc_server ?-port NUM? ?-register? ?-interval MS? FILENAME\n");
exit(exitCode);
}
update_xlist(app);
update_ilist(app);
- UA_NodeId node = UA_NODEID_STRING_ALLOC(app->ns, "renishaw.spd.index");
+ UA_NodeId node = UA_NODEID_STRING_ALLOC(app->ns, "renishaw.spd.spectrum.index");
update_scalar(app, node, &app->spectrumIndex, &UA_TYPES[UA_TYPES_INT64]);
++app->spectrumIndex;
app->spectrumIndex = 0;
}
+static UA_StatusCode add_nodes(App *app)
+{
+ // Add new object node for our data as Renishaw
+ UA_NodeId mainNode, spdNode;
+ UA_StatusCode status = add_object_node(app, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), "renishaw", "Renishaw", &mainNode);
+ if (UA_StatusCode_isGood(status))
+ status = add_object_node(app, mainNode, "renishaw.spd", "SPD", &spdNode);
+ if (UA_StatusCode_isGood(status))
+ status = add_scalar(app, spdNode, "renishaw.spd.nspectra", "Capacity", &app->hdr.nspectra, &UA_TYPES[UA_TYPES_INT64]);
+ if (UA_StatusCode_isGood(status))
+ status = add_scalar(app, spdNode, "renishaw.spd.ncollected", "Count", &app->hdr.ncollected, &UA_TYPES[UA_TYPES_INT64]);
+ if (UA_StatusCode_isGood(status))
+ status = add_scalar(app, spdNode, "renishaw.spd.npoints", "Points", &app->hdr.npoints, &UA_TYPES[UA_TYPES_INT32]);
+ if (UA_StatusCode_isGood(status))
+ status = add_scalar(app, spdNode, "renishaw.spd.laserwavenum", "Laser Wavenumber", &app->hdr.laserwavenum, &UA_TYPES[UA_TYPES_FLOAT]);
+ if (UA_StatusCode_isGood(status))
+ {
+ UA_NodeId spectrumNode;
+ status = add_object_node(app, spdNode, "renishaw.spd.spectrum", "Spectrum", &spectrumNode);
+ if (UA_StatusCode_isGood(status))
+ status = add_scalar(app, spectrumNode, "renishaw.spd.spectrum.index", "Index", &app->spectrumIndex, &UA_TYPES[UA_TYPES_INT64]);
+ if (UA_StatusCode_isGood(status))
+ status = add_vector(app, spectrumNode, "renishaw.spd.spectrum.xlist", "XList", app->hdr.npoints, app->xlist, &UA_TYPES[UA_TYPES_FLOAT]);
+ if (UA_StatusCode_isGood(status))
+ status = add_vector(app, spectrumNode, "renishaw.spd.spectrum.ilist", "IList", app->hdr.npoints, app->ilist, &UA_TYPES[UA_TYPES_FLOAT]);
+ }
+ return status;
+}
+
int main(int argc, char** argv)
{
App application = {0};
App *app = &application;
unsigned short port = 4840;
+ unsigned int interval = 1000;
const char *filename = argv[argc - 1];
{
{
app->regUri = DISCOVERY_SERVER_ENDPOINT;
}
+ else if (strncmp("-interval", argv[n], 9) == 0)
+ {
+ interval = strtoul(argv[n+1], NULL, 0);
+ ++n;
+ }
else
break;
}
config->mdnsConfig.mdnsServerName = UA_String_fromChars("Renishaw Demo");
#endif
- // Add new object node for our data as Renishaw
- UA_NodeId mainNode, spdNode;
- if (UA_StatusCode_isGood(status))
- status = add_object_node(app, UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), "renishaw", "Renishaw", &mainNode);
- if (UA_StatusCode_isGood(status))
- status = add_object_node(app, mainNode, "renishaw.spd", "SPD", &spdNode);
- if (UA_StatusCode_isGood(status))
- status = add_int32(app, spdNode, "nspectra", "Capacity", (int32_t)app->hdr.nspectra);
- if (UA_StatusCode_isGood(status))
- status = add_int32(app, spdNode, "ncollected", "Count", (int32_t)app->hdr.ncollected);
if (UA_StatusCode_isGood(status))
- status = add_int32(app, spdNode, "npoints", "Points", app->hdr.npoints);
- if (UA_StatusCode_isGood(status))
- status = add_float(app, spdNode, "laserwavenum", "Laser Wavenumber", app->hdr.laserwavenum);
- if (UA_StatusCode_isGood(status))
- {
- UA_NodeId spectrumNode;
- status = add_object_node(app, spdNode, "renishaw.spd.spectrum", "Spectrum", &spectrumNode);
- if (UA_StatusCode_isGood(status))
- status = add_int64(app, spectrumNode, "index", "Index", app->spectrumIndex);
- if (UA_StatusCode_isGood(status))
- status = add_float_vector(app, spectrumNode, "xlist", "XList", app->hdr.npoints, app->xlist);
- if (UA_StatusCode_isGood(status))
- status = add_float_vector(app, spectrumNode, "ilist", "IList", app->hdr.npoints, app->ilist);
- }
+ status = add_nodes(app);
+
if (UA_StatusCode_isGood(status))
{
if (app->regUri != NULL)
/* Add a repeated callback to the server */
if (UA_StatusCode_isGood(status))
- status = UA_Server_addRepeatedCallback(app->server, getSpectrumCallback, app, 1000, NULL);
+ status = UA_Server_addRepeatedCallback(app->server, getSpectrumCallback, app, interval, NULL);
if (UA_StatusCode_isGood(status))
status = UA_Server_run(app->server, &is_running);