Commit e7d811f7 authored by Alexander Travov's avatar Alexander Travov Committed by oroulet

Few doc edits.

parent 3e63ceaa
......@@ -9,11 +9,11 @@ The NodeId Class
and are therefore used on the server and client side to access specific nodes. The two classes
:class:`~asyncua.ua.uatypes.NodeId` and :class:`~asyncua.common.node.Node` should not
be confused: The NodeId is the unique identiefier of an actual Node. While the NodeId is used to identify
a specific node, the Node object can be used to access the underlaying data.
a specific node, the Node object can be used to access the underlying data.
To learn more about the Node class, head over to :ref:`usage/common/node-nodeid:the node class`.
A NodeId contains two main informations which allow a unique mapping in the opc-ua address space:
A NodeId contains two main pieces of information that allow a unique mapping in the opc-ua address space:
The :attr:`~asyncua.ua.uatypes.NodeId.Identifier` and the :attr:`~asyncua.ua.uatypes.NodeId.NamespaceIndex`.
In addition there is the :attr:`~asyncua.ua.uatypes.NodeId.NodeIdType` attribute which is used
to specify which opc-ua type is used for the Identifier. In addition to the :class:`~asyncua.ua.uatypes.NodeId`
......@@ -67,8 +67,13 @@ What else?
The :class:`~asyncua.ua.uatypes.NodeId` class is actually just a normal UA data-type like
other objects as :class:`~asyncua.ua.uatypes.QualifiedName` or :class:`~asyncua.ua.uatypes.Variant`
are. The asyncua package models all datatypes as :mod:`dataclasses`, for some types, like
the NodeId some additional logic is implemented to make it easier to work with them.
are, with some additional logic to make it easier to work with.
..
The asyncua package models all datatypes as :mod:`dataclasses`.
The info about dataclasses is an internal detail of a package implementation,
that may change in future. Maybe users should not know about it to avoid dependency on it.
The Node Class
......@@ -76,9 +81,9 @@ The Node Class
The :class:`~asyncua.common.node.Node` class is a central part used on the server and client.
On the server side nodes are created and configured as well as read and written. On the client
side we can browser through the nodes and access and manipulate their values. Nodes should not
be confused with :class:`~asyncua.ua.uatypes.NodeId`: Each node has a NodeId an can be access
by it, so the NodeId is a unique identiefier within the server to reference a Node.
side we can browse through the nodes, access and manipulate their values. Nodes should not
be confused with :class:`~asyncua.ua.uatypes.NodeId`: Each node has a NodeId an can be accessed
through it. NodeId uniquely identifies the Node within the server.
The Node class exposes a wide range of the OPC-UA protocol for easy access, however, to fully
optimize your code you will need to use lower level functions. Beside that, for many usecases
......@@ -116,7 +121,7 @@ The node now can be used to read / write / ... data from the server:
>>> await node.write_value(5.0) # Must use 5.0, see note below
>>> value = (await node.read_value())
>>> print(f"{name} = {value}")
MyVariable = 5.1
MyVariable = 5.0
Writing values using :meth:`~asyncua.common.node.Node.write_value` can be tricky in some cases
as the method converts the python type to a OPC-UA datatype. In the example above we explicitly
......@@ -157,4 +162,4 @@ Here we start at the objects node an traverse via MyObject to MyVariable. Allway
mind that browsing through the nodes will create network traffic and server load. If
you allready know the NodeId using :meth:`~asyncua.client.client.Client.get_node` should
be prefered. You might also consider caching NodeIds which you found through browsing
to reduce the traffic.
\ No newline at end of file
to reduce the traffic.
......@@ -42,7 +42,7 @@ Alongside the package some utility command line tools are installed:
Call method of a node
:code:`uaclient`:
Connect to server and start python shell. root and objects nodes are available.Node specificed in command line is available as mynode variable.
Connect to server and start python shell. root and objects nodes are available. Node specificed in command line is available as mynode variable.
:code:`uadiscover`:
Performs OPC UA discovery and prints information on servers and endpoints.
......@@ -57,7 +57,7 @@ Alongside the package some utility command line tools are installed:
Browse OPC-UA node and print result.
:code:`uaread` / :code:`uawrite`:
Read / Write attribute of a node, per default reads value of a node.
Read / Write attribute of a node, by default reads value of a node.
:code:`uaserver`:
Run an example OPC-UA server. By importing xml definition and using uawrite command line, it is even possible to expose real data using this server.
......@@ -81,4 +81,4 @@ More Tools for Development
Possible Tools:
- opcua-client (https://github.com/FreeOpcUa/opcua-client-gui)
- UaModeler (https://www.unified-automation.com/products/development-tools/uamodeler.html)
\ No newline at end of file
- UaModeler (https://www.unified-automation.com/products/development-tools/uamodeler.html)
......@@ -4,7 +4,7 @@ A Minimal OPC-UA Client
In this section we will build a client which reads / writes data from the server
created in the last section and calls the method which the server provides.
Running the client code will require a running server of course, so open a new
Running the client code requires a running server of course, so open a new
terminal and run :code:`python server-minimal.py` to start the server.
Like in the server section, we will first look at the complete code of the client
......@@ -24,11 +24,10 @@ the server, which can be used to handle the opening / closing of the connection
Getting the namespace
=====================
As all our custom objects life in a custom namespace, we need to get the namespace
As all our custom objects live in a custom namespace, we need to get the namespace
index to address our objects. This is done with the :meth:`~asyncua.client.client.Client.get_namespace_index`
method. If you are connecting to a unknown server and want to find out which namespaces
are available the :meth:`~asyncua.client.client.Client.get_namespace_array` method can be used to
fetch a list of all namespaces of the server.
method. You can find out the list of all namespaces available on the server with :meth:`~asyncua.client.client.Client.get_namespace_array`.
Read / Write Variables
======================
......@@ -43,9 +42,9 @@ of the variable. The :meth:`~asyncua.common.node.Node.get_child` method of the r
If you know the node id it's better to use the :meth:`~asyncua.client.client.Client.get_node`
method of the client. For example :code:`client.get_node("ns=2;i=2")` or
:code:`client.get_node(ua.NodeId(2, 2))` could be used in the example.
Note that the call is not :code:`async`!
Note that the latter call is not :code:`async`!
Once we have our node object, the variable value can directly be read or written using
Once we have our node object, the variable value can be read or written directly using
the :meth:`~asyncua.common.node.Node.read_value` and :meth:`~asyncua.common.node.Node.write_value`
methods. The read method automatically transforms the opc-ua type to a python type but the
:meth:`~asyncua.common.node.Node.read_data_value` method can be used if the original type of
......@@ -56,6 +55,6 @@ Calling Methods
===============
The method interface is similar to the interface of variables. In the example the special
node :code:`client.nodes.objects`, wich is in fact just a shortcut to the :code:`0:Objects`
node :code:`client.nodes.objects`, which is in fact just a shortcut to the :code:`0:Objects`
node, is used to call the `2:ServerMethod` on it. The :meth:`~asyncua.common.node.Node.call_method`
must be called on the parent node of the actuall method node.
\ No newline at end of file
must be called on the parent node of the actuall method node.
......@@ -22,7 +22,6 @@ the server. The following session gives you an idea how the tools can be used.
$ uals --url=opc.tcp://127.0.0.1:4840 # List root node
Browsing node i=84 at opc.tcp://127.0.0.1:4840
DisplayName NodeId BrowseName Value
LocalizedText(Locale=None, Text='Objects') i=85 0:Objects
......@@ -51,6 +50,7 @@ So let's start working through the code!
Imports, Basic Setup & Configuration
====================================
In the first few lines the relevant packages, classes and methods are imported.
While the :mod:`logging` module is optional (just remove all calls to the logging module),
:mod:`asyncio` is required to actually run our main function. From the :mod:`asyncua`
......@@ -70,8 +70,8 @@ Ignore the :code:`@uamethod ...` part for the moment and jump straight into the
Here the server is created and initialized (:meth:`~asyncua.server.server.Server.init`).
The endpoint is configured (:meth:`~asyncua.server.server.Server.set_endpoint`) and a custom namespace
is registered (:meth:`~asyncua.server.server.Server.register_namespace`). It's recommended (:emphasis:`required??`)
that all custom objects, variables and methods life in a separate namespace. As we later need the
namespace index to our objects to it, the index is stored as :code:`idx`.
that all custom objects, variables and methods live in a separate namespace. We store its index as :code:`idx`.
We'll need it later to add our custom objects to the namespace.
Creating Objects and Variables
==============================
......@@ -82,7 +82,7 @@ Creating Objects and Variables
In the next lines, the custom object "MyObject" is created and a variable is added to this object.
Note that by default all variables are read-only, so we need to be explicit and make it writable.
The :meth:`~asyncua.common.node.Node.add_object` / :meth:`~asyncua.common.node.Node.add_object` calls
The :meth:`~asyncua.common.node.Node.add_object` / :meth:`~asyncua.common.node.Node.add_variable` calls
are actually just calling :meth:`~asyncua.common.manage_nodes.create_object`, respectively
:meth:`~asyncua.common.manage_nodes.create_variable` internally. You can find more information on
how nodes and variables are created in the API docs of these methods.
......@@ -116,7 +116,7 @@ Starting the Server
Using the server as a context manager with :code:`async with server: ...` allows us to
hide starting and shutting down the server nicely. In order to keep the server alive
a endless loop must be present. In the this example the loop is also used to periodically
update the variable on our custom object.
a endless loop must be present. In this example the loop is also used to periodically
update the variable in our custom object.
Now that we have a working server, let's go on and write :ref:`usage/get-started/minimal-client:a minimal opc-ua client`!
\ No newline at end of file
Now that we have a working server, let's go on and write :ref:`usage/get-started/minimal-client:a minimal opc-ua client`!
......@@ -7,7 +7,7 @@ OPC-UA Basics
Are we only going to link to external references and skip explaining the OPC-UA basics?
The `open62541 documentation <http://www.open62541.org/doc/master/>`_ for example
contains a lot of information about how OPC-UA works but in many chapters it also
assumes the reader is interested how the library works. Where do we need to start
assumes the reader is interested in how the library works. Where do we need to start
such that new users can later understand how the concepts of OPC-UA are represented
by this library?
......@@ -16,7 +16,7 @@ OPC-UA Basics
External References
===================
.. note:: We are open to sugguestions for this section!
.. note:: We are open to suggestions for this section!
You know good tutorials, help pages, blogs or other resources? Share them with us!
......@@ -32,5 +32,5 @@ https://www.open62541.org
https://www.unified-automation.com
Unified Automation provides different products for the OPC-UA ecosystem. Most of the
tools are avialable as a free download with a evaluation license (non commercial use).
tools are available as a free download with an evaluation license (non commercial use).
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment