From: Pat Thoyts Date: Wed, 28 Jun 2023 05:55:11 +0000 (+0100) Subject: Refactored the node adding and added an interval option. X-Git-Url: http://privyetmir.co.uk/gitweb.cgi?a=commitdiff_plain;h=54569e43481b39773aecddde1189b41b6550e788;p=spd%2Fwdf_opc_demo.git Refactored the node adding and added an interval option. --- diff --git a/opc_app.h b/opc_app.h index 65a4600..bc40944 100644 --- a/opc_app.h +++ b/opc_app.h @@ -21,17 +21,16 @@ typedef struct { 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); diff --git a/opc_util.c b/opc_util.c index c70f3c5..43083bd 100644 --- a/opc_util.c +++ b/opc_util.c @@ -4,77 +4,58 @@ #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), @@ -82,31 +63,6 @@ UA_StatusCode add_object_node(App *app, 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; @@ -131,7 +87,7 @@ UA_StatusCode update_xlist(App *app) 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); } } @@ -143,7 +99,7 @@ UA_StatusCode update_ilist(App *app) 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); } diff --git a/server.c b/server.c index 7f73ac3..e5648b9 100644 --- a/server.c +++ b/server.c @@ -36,7 +36,7 @@ static void on_interrupt(int signo) 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); } @@ -62,7 +62,7 @@ static void getSpectrumCallback(UA_Server *server, void *clientData) 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; @@ -70,11 +70,41 @@ static void getSpectrumCallback(UA_Server *server, void *clientData) 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]; { @@ -90,6 +120,11 @@ int main(int argc, char** argv) { app->regUri = DISCOVERY_SERVER_ENDPOINT; } + else if (strncmp("-interval", argv[n], 9) == 0) + { + interval = strtoul(argv[n+1], NULL, 0); + ++n; + } else break; } @@ -133,31 +168,9 @@ int main(int argc, char** argv) 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) @@ -176,7 +189,7 @@ int main(int argc, char** argv) /* 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);