Merge pull request #1197 from open62541/feature/custom_types

Create examples for custom datatypes
This commit is contained in:
Stefan Profanter 2017-09-07 11:08:31 +02:00 committed by GitHub
commit de446d6d4a
4 changed files with 181 additions and 0 deletions

View File

@ -70,6 +70,9 @@ add_example(server_repeated_job server_repeated_job.c)
add_example(server_inheritance server_inheritance.c)
add_example(custom_datatype_client custom_datatype/client_types_custom.c)
add_example(custom_datatype_server custom_datatype/server_types_custom.c)
if(UA_BUILD_EXAMPLES_NODESET_COMPILER)
if(BUILD_SHARED_LIBS)
message(FATAL_ERROR "The nodeset compiler currently requires static linking to access internal API")

View File

@ -0,0 +1,41 @@
/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
* See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
#include <stdio.h>
#include "open62541.h"
#include "custom_datatype.h"
int main(void) {
UA_ClientConfig config = UA_ClientConfig_default;
/* Make your custom datatype known to the stack */
UA_DataType types[1];
types[0] = PointType;
config.customDataTypes = types;
config.customDataTypesSize = 1;
UA_Client *client = UA_Client_new(config);
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");
if (retval != UA_STATUSCODE_GOOD) {
UA_Client_delete(client);
return (int)retval;
}
UA_Variant value; /* Variants can hold scalar values and arrays of any type */
UA_Variant_init(&value);
UA_NodeId nodeId =
UA_NODEID_STRING(1, "3D.Point");
retval = UA_Client_readValueAttribute(client, nodeId, &value);
if (retval == UA_STATUSCODE_GOOD) {
Point *p = (Point *)value.data;
printf("Point = %f, %f, %f \n", p->x, p->y, p->z);
}
/* Clean up */
UA_Variant_deleteMembers(&value);
UA_Client_delete(client); /* Disconnects the client internally */
return UA_STATUSCODE_GOOD;
}

View File

@ -0,0 +1,51 @@
/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
* See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
typedef struct {
UA_Float x;
UA_Float y;
UA_Float z;
} Point;
/* The datatype description for the Point datatype */
#define Point_padding_y offsetof(Point,y) - offsetof(Point,x) - sizeof(UA_Float)
#define Point_padding_z offsetof(Point,z) - offsetof(Point,y) - sizeof(UA_Float)
static UA_DataTypeMember Point_members[3] = {
/* x */
{
"x", /* .memberName */
UA_TYPES_FLOAT, /* .memberTypeIndex, points into UA_TYPES since namespaceZero is true */
0, /* .padding */
true, /* .namespaceZero, see .memberTypeIndex */
false /* .isArray */
},
/* y */
{
"y",
UA_TYPES_FLOAT, Point_padding_y, true, false
},
/* z */
{
"y",
UA_TYPES_FLOAT, Point_padding_z, true, false
}
};
static const UA_DataType PointType = {
"Point", /* .typeName */
{1, UA_NODEIDTYPE_NUMERIC, {4242}}, /* .typeId */
sizeof(Point), /* .memSize */
0, /* .typeIndex, in the array of custom types */
3, /* .membersSize */
false, /* .builtin */
true, /* .pointerFree */
false, /* .overlayable (depends on endianness and
the absence of padding) */
0, /* .binaryEncodingId, the numeric
identifier used on the wire (the
namespaceindex is from .typeId) */
Point_members
};

View File

@ -0,0 +1,86 @@
/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
* See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
#include <signal.h>
#include <open62541.h>
#include "custom_datatype.h"
UA_Boolean running = true;
static void stopHandler(int sig) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "received ctrl-c");
running = false;
}
static void
add3PointDataType(UA_Server *server) {
UA_VariableTypeAttributes dattr = UA_VariableTypeAttributes_default;
dattr.description = UA_LOCALIZEDTEXT("en_US", "3D Point");
dattr.displayName = UA_LOCALIZEDTEXT("en_US", "3D Point");
dattr.dataType = PointType.typeId;
dattr.valueRank = -1;
Point p;
p.x = 0.0;
p.y = 0.0;
p.z = 0.0;
UA_Variant_setScalar(&dattr.value, &p, &PointType);
UA_Server_addVariableTypeNode(server, PointType.typeId,
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
UA_QUALIFIEDNAME(1, "3D.Point"),
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
dattr,
NULL, NULL
);
}
static void
add3DPointVariable(UA_Server *server) {
Point p;
p.x = 3.0;
p.y = 4.0;
p.z = 5.0;
UA_VariableAttributes vattr = UA_VariableAttributes_default;
vattr.description = UA_LOCALIZEDTEXT("en_US", "3D Point");
vattr.displayName = UA_LOCALIZEDTEXT("en_US", "3D Point");
vattr.dataType = PointType.typeId;
vattr.valueRank = -1;
UA_Variant_setScalar(&vattr.value, &p, &PointType);
UA_Server_addVariableNode(server, UA_NODEID_STRING(1, "3D.Point"),
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
UA_QUALIFIEDNAME(1, "3D.Point"),
PointType.typeId,
vattr,
NULL,
NULL
);
}
int main(void) {
signal(SIGINT, stopHandler);
signal(SIGTERM, stopHandler);
UA_ServerConfig *config = UA_ServerConfig_new_default();
/* Make your custom datatype known to the stack */
UA_DataType types[1];
types[0] = PointType;
config->customDataTypes = types;
config->customDataTypesSize = 1;
UA_Server *server = UA_Server_new(config);
add3PointDataType(server);
add3DPointVariable(server);
UA_Server_run(server, &running);
UA_Server_delete(server);
UA_ServerConfig_delete(config);
return 0;
}