mirror of
https://github.com/open62541/open62541.git
synced 2025-06-03 04:00:21 +00:00
Merge pull request #1197 from open62541/feature/custom_types
Create examples for custom datatypes
This commit is contained in:
commit
de446d6d4a
@ -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")
|
||||
|
41
examples/custom_datatype/client_types_custom.c
Normal file
41
examples/custom_datatype/client_types_custom.c
Normal 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;
|
||||
}
|
51
examples/custom_datatype/custom_datatype.h
Normal file
51
examples/custom_datatype/custom_datatype.h
Normal 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
|
||||
};
|
86
examples/custom_datatype/server_types_custom.c
Normal file
86
examples/custom_datatype/server_types_custom.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user