forked from open62541/open62541
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client_historical.c
180 lines (154 loc) · 6.27 KB
/
client_historical.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* 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 <open62541/client_config_default.h>
#include <open62541/client_highlevel.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef UA_ENABLE_EXPERIMENTAL_HISTORIZING
static void
printUpdateType(UA_HistoryUpdateType type) {
switch (type) {
case UA_HISTORYUPDATETYPE_INSERT:
printf("Insert\n");
return;
case UA_HISTORYUPDATETYPE_REPLACE:
printf("Replace\n");
return;
case UA_HISTORYUPDATETYPE_UPDATE:
printf("Update\n");
return;
case UA_HISTORYUPDATETYPE_DELETE:
printf("Delete\n");
return;
default:
printf("Unknown\n");
return;
}
}
#endif
static void
printTimestamp(char *name, UA_DateTime date) {
UA_DateTimeStruct dts = UA_DateTime_toStruct(date);
if (name)
printf("%s: %02u-%02u-%04u %02u:%02u:%02u.%03u, ", name,
dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);
else
printf("%02u-%02u-%04u %02u:%02u:%02u.%03u, ",
dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);
}
static void
printDataValue(UA_DataValue *value) {
/* Print status and timestamps */
if (value->hasServerTimestamp)
printTimestamp("ServerTime", value->serverTimestamp);
if (value->hasSourceTimestamp)
printTimestamp("SourceTime", value->sourceTimestamp);
if (value->hasStatus)
printf("Status 0x%08x, ", value->status);
if (value->value.type == &UA_TYPES[UA_TYPES_UINT32]) {
UA_UInt32 hrValue = *(UA_UInt32 *)value->value.data;
printf("Uint32Value %u\n", hrValue);
}
if (value->value.type == &UA_TYPES[UA_TYPES_DOUBLE]) {
UA_Double hrValue = *(UA_Double *)value->value.data;
printf("DoubleValue %f\n", hrValue);
}
}
static UA_Boolean
readRaw(const UA_HistoryData *data) {
printf("readRaw Value count: %lu\n", (long unsigned)data->dataValuesSize);
/* Iterate over all values */
for (UA_UInt32 i = 0; i < data->dataValuesSize; ++i)
{
printDataValue(&data->dataValues[i]);
}
/* We want more data! */
return true;
}
#ifdef UA_ENABLE_EXPERIMENTAL_HISTORIZING
static UA_Boolean
readRawModified(const UA_HistoryModifiedData *data) {
printf("readRawModified Value count: %lu\n", (long unsigned)data->dataValuesSize);
/* Iterate over all values */
for (size_t i = 0; i < data->dataValuesSize; ++i) {
printDataValue(&data->dataValues[i]);
}
printf("Modificaton Value count: %lu\n", data->modificationInfosSize);
for (size_t j = 0; j < data->modificationInfosSize; ++j) {
if (data->modificationInfos[j].userName.data)
printf("Username: %s, ", data->modificationInfos[j].userName.data);
printTimestamp("Modtime", data->modificationInfos[j].modificationTime);
printUpdateType(data->modificationInfos[j].updateType);
}
/* We want more data! */
return true;
}
static UA_Boolean
readEvents(const UA_HistoryEvent *data) {
printf("readEvent Value count: %lu\n", (long unsigned)data->eventsSize);
for (size_t i = 0; i < data->eventsSize; ++i) {
printf("Processing event: %lu\n", (long unsigned)i);
for (size_t j = 0; j < data->events[i].eventFieldsSize; ++j) {
printf("Processing %lu: %s\n", (long unsigned)j, data->events[i].eventFields[j].type->typeName);
}
}
return true;
}
#endif
static UA_Boolean
readHist(UA_Client *client, const UA_NodeId *nodeId,
UA_Boolean moreDataAvailable,
const UA_ExtensionObject *data, void *unused) {
printf("\nRead historical callback:\n");
printf("\tHas more data:\t%d\n\n", moreDataAvailable);
if (data->content.decoded.type == &UA_TYPES[UA_TYPES_HISTORYDATA]) {
return readRaw((UA_HistoryData*)data->content.decoded.data);
}
#ifdef UA_ENABLE_EXPERIMENTAL_HISTORIZING
if (data->content.decoded.type == &UA_TYPES[UA_TYPES_HISTORYMODIFIEDDATA]) {
return readRawModified((UA_HistoryModifiedData*)data->content.decoded.data);
}
if (data->content.decoded.type == &UA_TYPES[UA_TYPES_HISTORYEVENT]) {
return readEvents((UA_HistoryEvent*)data->content.decoded.data);
}
#endif
return true;
}
int main(int argc, char *argv[]) {
UA_Client *client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(client));
/* Connect to the Unified Automation demo server */
UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:53530/OPCUA/SimulationServer");
if(retval != UA_STATUSCODE_GOOD) {
UA_Client_delete(client);
return EXIT_FAILURE;
}
/* Read historical values (uint32) */
printf("\nStart historical read (1, \"myUintValue\"):\n");
UA_NodeId node = UA_NODEID_STRING(2, "MyLevel");
retval = UA_Client_HistoryRead_raw(client, &node, readHist,
UA_DateTime_fromUnixTime(0), UA_DateTime_now(), UA_STRING_NULL, false, 10, UA_TIMESTAMPSTORETURN_BOTH, (void *)UA_FALSE);
if (retval != UA_STATUSCODE_GOOD) {
printf("Failed. %s\n", UA_StatusCode_name(retval));
}
#ifdef UA_ENABLE_EXPERIMENTAL_HISTORIZING
printf("\nStart historical modified read (1, \"myUintValue\"):\n");
retval = UA_Client_HistoryRead_modified(client, &node, readHist,
UA_DateTime_fromUnixTime(0), UA_DateTime_now(), UA_STRING_NULL, false, 10, UA_TIMESTAMPSTORETURN_BOTH, (void *)UA_FALSE);
if (retval != UA_STATUSCODE_GOOD) {
printf("Failed. %s\n", UA_StatusCode_name(retval));
}
printf("\nStart historical event read (1, \"myUintValue\"):\n");
UA_EventFilter filter;
UA_EventFilter_init(&filter);
UA_NodeId eventNode = UA_NODEID_NUMERIC(0, 2253);
retval = UA_Client_HistoryRead_events(client, &eventNode, readHist,
UA_DateTime_fromUnixTime(0), UA_DateTime_now(), UA_STRING_NULL, filter, 10, UA_TIMESTAMPSTORETURN_BOTH, (void *)UA_FALSE);
if (retval != UA_STATUSCODE_GOOD) {
printf("Failed. %s\n", UA_StatusCode_name(retval));
}
#endif
UA_Client_disconnect(client);
UA_Client_delete(client);
return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}