tutorial_server_variables.rst 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. .. role:: ccode(code)
  2. :language: c
  3. Adding variables to a server
  4. ----------------------------
  5. This tutorial shows how to add variable nodes to a server and how these can be
  6. connected to a physical process in the background.
  7. This is the code for a server with a single variable node holding an integer. We
  8. will take this example to explain some of the fundamental concepts of open62541.
  9. .. literalinclude:: ${PROJECT_SOURCE_DIR}/examples/server_variable.c
  10. :language: c
  11. :linenos:
  12. :lines: 4,13,15-
  13. Variants and Datatypes
  14. ^^^^^^^^^^^^^^^^^^^^^^
  15. The datatype :ref:`variant` belongs to the built-in datatypes of OPC UA and is
  16. used as a container type. A variant can hold any other datatype as a scalar
  17. (except variant) or as an array. Array variants can additionally denote the
  18. dimensionality of the data (e.g. a 2x3 matrix) in an additional integer array.
  19. The `UA_VariableAttributes` type contains a variant member `value`. The command
  20. :ccode:`UA_Variant_setScalar(&attr.value, &myInteger,
  21. &UA_TYPES[UA_TYPES_INT32])` sets the variant to point to the integer. Note that
  22. this does not make a copy of the integer (for which `UA_Variant_setScalarCopy`
  23. can be used). The variant (and its content) is then copied into the newly
  24. created node.
  25. The above code could have used allocations by making copies of all entries of
  26. the attribute variant. Then, of course, the variant content needs to be deleted
  27. to prevent memleaks.
  28. .. code-block:: c
  29. UA_VariableAttributes attr;
  30. UA_VariableAttributes_init(&attr);
  31. UA_Int32 myInteger = 42;
  32. UA_Variant_setScalarCopy(&attr.value, &myInteger, &UA_TYPES[UA_TYPES_INT32]);
  33. attr.description = UA_LOCALIZEDTEXT_ALLOC("en_US","the answer");
  34. attr.displayName = UA_LOCALIZEDTEXT_ALLOC("en_US","the answer");
  35. /* add the variable node here */
  36. UA_VariableAttributes_deleteMembers(&attr); /* free the allocated memory */
  37. Finally, one needs to tell the server where to add the new variable in the
  38. information model. For that, we state the NodeId of the parent node and the
  39. (hierarchical) reference to the parent node.
  40. NodeIds
  41. ^^^^^^^
  42. A :ref:`nodeid` is a unique identifier in server's context. It contains the
  43. number of node's namespace and either a numeric, string or GUID (Globally
  44. Unique ID) identifier. The following are some examples for their usage.
  45. .. code-block:: c
  46. UA_NodeId id1 = UA_NODEID_NUMERIC(1, 1234);
  47. UA_NodeId id2 = UA_NODEID_STRING(1, "testid"); /* points to the static string */
  48. UA_NodeId id3 = UA_NODEID_STRING_ALLOC(1, "testid"); /* copy to memory */
  49. UA_NodeId_deleteMembers(&id3); /* free the allocated string */
  50. Adding a Variable with an external Data Source
  51. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  52. In order to couple a running process to a variable, a :ref:`datasource` is used.
  53. Consider ``examples/server_datasource.c`` in the repository for an example.