Learning OPC UA with Mako Server
================================
This tutorial builds the OPC UA Lua API in small steps. Each example runs with
`Mako Server `_ and uses only local data, so no PLC,
sensor, external OPC UA server, or hardware setup is required.
The goal is to learn the API shape:
* create a server
* add folders, variables, and methods to the address space
* read and write values
* connect a local client to the local server
Run the tutorial examples
-------------------------
The source files are in `LSP-Examples/OPC-UA
`_. From
that directory, run:
.. code-block:: bash
mako tutorial/run_standalone.lua
The standalone runner executes the server-side examples that do not need a
long-running server process. It exits through ``mako.exit()``. A non-zero
process exit means at least one example failed.
Run the PubSub tutorial examples
--------------------------------
The PubSub examples use the optional Lua MQTT broker module. The easiest way to
test them is to use the `Mako Server mako.zip Developer Edition
`_, which includes the
broker. No external MQTT broker is required for these tutorial examples.
From the ``LSP-Examples/OPC-UA`` directory, run:
.. code-block:: bash
cd tutorial
mako run_pubsub.lua
The PubSub examples load shared tutorial code from
``tutorial/.lua/pubsub_common.lua`` using ``mako.createloader(io)`` and
``require()``. They stop immediately and print an error message if the
``mqttbroker`` module cannot be loaded. In that case, install the Developer
Edition ``mako.zip`` or copy the broker from `MQTT-Broker
`_.
1. Minimal server
-----------------
Start with the smallest useful server. The server has one ``opc.tcp`` endpoint,
allows the ``None`` security policy, starts listening, and then shuts down.
.. literalinclude:: ../examples/tutorial/01_minimal_server.lua
:language: lua
2. Add a folder
---------------
OPC UA data is organized in the address space. A common first step is to add a
folder under the standard ``Objects`` folder.
.. literalinclude:: ../examples/tutorial/02_add_folder.lua
:language: lua
3. Add variables
----------------
Variables expose values. This example adds two ``Double`` variables with stable
NodeIds so later examples can read and write them directly.
.. literalinclude:: ../examples/tutorial/03_add_variables.lua
:language: lua
4. Write a variable
-------------------
Server-side Lua can write a variable through the same service shape used by
remote clients. This is useful when application logic updates the address space.
.. literalinclude:: ../examples/tutorial/04_write_variable.lua
:language: lua
5. Use a value callback
-----------------------
A value callback lets a variable read from and write to application state instead
of storing only a fixed value in the model.
.. literalinclude:: ../examples/tutorial/05_value_callback.lua
:language: lua
6. Read with a local client
---------------------------
The client examples use a separate local learning server. Start it in one
terminal:
.. code-block:: bash
mako -l::tutorial/learning_server
Then run the client scripts from another terminal. The first client example
opens a secure channel, creates a session, activates it, and reads one value.
Stop the learning server with ``Ctrl+C`` when you are done.
.. literalinclude:: ../examples/tutorial/learning_server/.preload
:language: lua
:caption: Local learning server used by examples 6 through 8
.. literalinclude:: ../examples/tutorial/06_client_read.lua
:language: lua
7. Write with a local client
----------------------------
Writing from a client uses ``client:write()`` with one or more nodes to update.
The example verifies the result from the server side after the write completes.
.. literalinclude:: ../examples/tutorial/07_client_write.lua
:language: lua
8. Call a method
----------------
Methods are callable operations attached to objects. This example exposes
``ScaleValue`` on a local ``Controller`` object and calls it from the client.
.. literalinclude:: ../examples/tutorial/08_method_call.lua
:language: lua
9. Define a structure type
--------------------------
OPC UA models can define custom data types. This example creates a small
``MeasurementType`` structure and a variable type that uses it.
.. literalinclude:: ../examples/tutorial/09_structure_type.lua
:language: lua
.. warning::
The following PubSub examples require an `MQTT broker
`_.
The easiest test setup is the `Mako Server mako.zip Developer Edition
`_, which includes
the broker module used by these examples.
10. Publish JSON with MQTT PubSub
---------------------------------
This example creates a local MQTT broker, connects an OPC UA MQTT publisher and
subscriber through the broker's in-process client API, publishes one JSON
dataset message, and verifies that the subscriber decodes the OPC UA PubSub
payload.
.. literalinclude:: ../examples/tutorial/10_pubsub_json.lua
:language: lua
11. Publish binary UADP with MQTT PubSub
----------------------------------------
The binary example uses the same broker setup but switches the transport profile
to MQTT binary/UADP. It publishes two fields and verifies the decoded field
indexes and values.
.. literalinclude:: ../examples/tutorial/11_pubsub_binary.lua
:language: lua
12. Publish an OPC UA server node
---------------------------------
The final PubSub example connects a publisher to an OPC UA server instance. A
dataset field is bound to a server node, the server writes a new value, and the
publisher sends the updated node value through MQTT PubSub.
.. literalinclude:: ../examples/tutorial/12_pubsub_server_node.lua
:language: lua
More advanced PubSub examples
-----------------------------
After the tutorial examples, see :doc:`../pubsub/mqtt_examples` for more
compact PubSub API examples. They cover publishing server node changes, manual
publishing without an OPC UA server, and subscribing to JSON and binary/UADP
messages.
Next steps
----------
After these examples, the reference pages are easier to read:
* :doc:`../model/index` for address-space editing
* :doc:`../client/index` for client sessions and service calls
* :doc:`../server/index` for server configuration and model setup
* :doc:`../pubsub/index` for PubSub concepts and MQTT API details