client_historical.c 6.3 KB

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