Commit 3a545fd4 authored by Dimitris Lampridis's avatar Dimitris Lampridis

[doc] wip

parent cf5b1594
......@@ -7,7 +7,7 @@ Installation
.. todo::
Decide on installation and document it
.. _res_names:
.. _node_id:
Resource Names
==============
Node Identification
===================
......@@ -6,8 +6,8 @@ Usage
.. _clib:
WRTD Library
============
C Library
=========
.. _api_error:
......@@ -35,6 +35,19 @@ Initialisation API
.. doxygenfunction:: wrtd_init
.. doxygenfunction:: wrtd_close
.. doxygenfunction:: wrtd_reset
.. code-block:: c
#include <libwrtd.h>
int main(void) {
struct wrtd_dev *wrtd;
status = wrtd_init("MT01", false, NULL, &wrtd);
wrtd_reset(wrtd);
wrtd_close(wrtd);
}
.. _api_attr:
......@@ -107,10 +120,293 @@ Applications API
.. _pywrap:
Python Library
Python Wrapper
==============
.. autoclass:: PyWrtd.PyWrtd
:members:
.. module:: PyWrtd
The WRTD Python wrapper provides a thin wrapper around the :ref:`clib`, using the `Python ctypes
package <https://pypi.org/project/ctypes/>`_.
The wrapper is provided as a Python package with a single class that encapsulates the complete WRTD
:ref:`clib`:
.. autoclass:: PyWrtd
All the provided class methods have exactly the same names (and function) as their C counterparts,
without the "wrtd\_" prefix.
To start using it, simply import the PyWrtd package and instantiate a :py:class:`PyWrtd` object,
passing to it the :ref:`identifier of the Node<node_id>` you wish to access.
If the identifier is wrong or if the user does not have the correct permissions to access it, WRTD
will return :cpp:enumerator:`WRTD_ERROR_RESOURCE_UNKNOWN`.
.. code-block:: python
>>> from PyWrtd import PyWrtd
>>> wrtd = PyWrtd("bad id")
Error 0xbffa0060: WRTD_ERROR_RESOURCE_UNKNOWN
>>> wrtd = PyWrtd("MT01")
>>> wrtd
<PyWrtd.PyWrtd object at 0x7fa9aeeaee48>
Error Handling API
------------------
.. automethod:: PyWrtd.get_error
.. code-block:: python
>>> wrtd.get_error()
(0, 'WRTD_SUCCESS ')
.. automethod:: PyWrtd.error_message
.. code-block:: python
>>> wrtd.error_message(PyWrtd.WRTD_SUCCESS)
'WRTD_SUCCESS'
.. _pyapi_init:
Initialisation API
------------------
Compared to the :ref:`clib` :ref:`api_init`, the Python version lacks the :cpp:func:`wrtd_init` and
:cpp:func:`wrtd_close` functions, because the Python wrapper performs these tasks internally.
.. automethod:: PyWrtd.reset
.. code-block:: python
>>> wrtd.reset()
>>> wrtd.add_rule('rule1')
>>> # Query number of declared rules
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_RULE_COUNT)
1
>>> # After reset, 'rule1' should be gone
>>> wrtd.reset()
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_RULE_COUNT)
0
.. _pyapi_attr:
Attribute Handling API
----------------------
Getting and setting boolean, integer and string :ref:`Attributes <attribute>` is straight-forward.
.. automethod:: PyWrtd.set_attr_bool
.. automethod:: PyWrtd.get_attr_bool
.. code-block:: python
>>> wrtd.add_alarm('alarm1')
>>> wrtd.get_attr_bool('alarm1', PyWrtd.WRTD_ATTR_ALARM_ENABLED)
False
>>> wrtd.set_attr_bool('alarm1', PyWrtd.WRTD_ATTR_ALARM_ENABLED, True)
>>> wrtd.get_attr_bool('alarm1', PyWrtd.WRTD_ATTR_ALARM_ENABLED)
True
.. automethod:: PyWrtd.set_attr_int32
.. automethod:: PyWrtd.get_attr_int32
.. code-block:: python
>>> wrtd.add_alarm('alarm1')
>>> wrtd.get_attr_int32('alarm1', PyWrtd.WRTD_ATTR_ALARM_REPEAT_COUNT)
0
>>> wrtd.set_attr_int32('alarm1', PyWrtd.WRTD_ATTR_ALARM_REPEAT_COUNT, 5)
>>> wrtd.get_attr_int32('alarm1', PyWrtd.WRTD_ATTR_ALARM_REPEAT_COUNT)
5
.. automethod:: PyWrtd.set_attr_string
.. automethod:: PyWrtd.get_attr_string
.. code-block:: python
>>> wrtd.add_rule('rule1')
>>> wrtd.set_attr_string('rule1', PyWrtd.WRTD_ATTR_RULE_SOURCE, 'event0')
>>> wrtd.get_attr_string('rule1', PyWrtd.WRTD_ATTR_RULE_SOURCE)
'event0'
Getting and setting :ref:`timestamp` :ref:`Attributes <attribute>` is slightly different than in the
:ref:`clib`.
The *set* method takes the ``seconds``, ``ns`` and ``frac`` fields of the :ref:`timestamp` as separate
parameters.
.. automethod:: PyWrtd.set_attr_tstamp
The *get* method returns a Python dictionary with the ``seconds``, ``ns`` and ``frac`` fields of the
:ref:`timestamp`.
.. automethod:: PyWrtd.get_attr_tstamp
.. code-block:: python
>>> wrtd.add_alarm('alarm1')
>>> wrtd.get_attr_tstamp('alarm1', PyWrtd.WRTD_ATTR_ALARM_TIME)
{'frac': 0, 'ns': 0, 'seconds': 0}
>>> wrtd.set_attr_tstamp('alarm1', PyWrtd.WRTD_ATTR_ALARM_TIME, seconds = 5, ns = 40e3)
>>> wrtd.get_attr_tstamp('alarm1', PyWrtd.WRTD_ATTR_ALARM_TIME)
{'frac': 0, 'seconds': 5, 'ns': 40000}
.. _pyapi_log:
Event Logging API
-----------------
.. automethod:: PyWrtd.clear_event_log_entries
.. automethod:: PyWrtd.get_next_event_log_entry
.. code-block:: python
>>> # First, enable logging
>>> wrtd.set_attr_bool(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_EVENT_LOG_ENABLED, True)
>>> wrtd.get_next_event_log_entry()
'Id:LC-I1 |Seq:0000|2019-07-05,12:08:03.491.231.296+000|2019-07-05,12:08:03.491.226.827+412|GENERATED|DEVICE_0'
.. _pyapi_alarm:
Alarms API
----------
.. automethod:: PyWrtd.add_alarm
.. code-block:: python
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_ALARM_COUNT)
0
>>> wrtd.add_alarm('alarm1')
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_ALARM_COUNT)
1
.. automethod:: PyWrtd.disable_all_alarms
.. code-block:: python
>>> wrtd.add_alarm('alarm1')
>>> wrtd.get_attr_bool('alarm1', PyWrtd.WRTD_ATTR_ALARM_ENABLED)
False
>>> wrtd.set_attr_bool('alarm1', PyWrtd.WRTD_ATTR_ALARM_ENABLED, True)
>>> wrtd.get_attr_bool('alarm1', PyWrtd.WRTD_ATTR_ALARM_ENABLED)
True
>>> wrtd.disable_all_rules()
>>> wrtd.get_attr_bool('alarm1', PyWrtd.WRTD_ATTR_ALARM_ENABLED)
False
.. automethod:: PyWrtd.remove_alarm
.. code-block:: python
>>> wrtd.add_alarm('alarm1')
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_ALARM_COUNT)
1
>>> wrtd.remove_alarm('alarm1')
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_ALARM_COUNT)
0
.. automethod:: PyWrtd.remove_all_alarms
.. code-block:: python
>>> wrtd.add_alarm('alarm1')
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_ALARM_COUNT)
1
>>> wrtd.remove_all_alarms()
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_ALARM_COUNT)
0
.. automethod:: PyWrtd.get_alarm_name
.. code-block:: python
>>> wrtd.add_rule('alarm1')
>>> count = wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_ALARM_COUNT)
>>> print(count)
1
>>> for i in range(count):
... wrtd.get_alarm_name(i)
'alarm1'
.. _pyapi_rule:
Rules API
---------
.. automethod:: PyWrtd.add_rule
.. code-block:: python
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_RULE_COUNT)
0
>>> wrtd.add_rule('rule1')
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_RULE_COUNT)
1
.. automethod:: PyWrtd.disable_all_rules
.. code-block:: python
>>> wrtd.add_rule('rule1')
>>> wrtd.get_attr_bool('rule1', PyWrtd.WRTD_ATTR_RULE_ENABLED)
False
>>> wrtd.set_attr_bool('rule1', PyWrtd.WRTD_ATTR_RULE_ENABLED, True)
>>> wrtd.get_attr_bool('rule1', PyWrtd.WRTD_ATTR_RULE_ENABLED)
True
>>> wrtd.disable_all_rules()
>>> wrtd.get_attr_bool('rule1', PyWrtd.WRTD_ATTR_RULE_ENABLED)
False
.. automethod:: PyWrtd.remove_rule
.. code-block:: python
>>> wrtd.add_rule('rule1')
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_RULE_COUNT)
1
>>> wrtd.remove_rule('rule1')
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_RULE_COUNT)
0
.. automethod:: PyWrtd.remove_all_rules
.. code-block:: python
>>> wrtd.add_rule('rule1')
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_RULE_COUNT)
1
>>> wrtd.remove_all_rules()
>>> wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_RULE_COUNT)
0
.. automethod:: PyWrtd.get_rule_name
.. code-block:: python
>>> wrtd.add_rule('rule1')
>>> wrtd.add_rule('rule2')
>>> count = wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_RULE_COUNT)
>>> print(count)
2
>>> for i in range(count):
... wrtd.get_rule_name(i)
'rule1'
'rule2'
.. automethod:: PyWrtd.reset_rule_stats
.. code-block:: python
>>> # Assuming a rule 'rule1' exists and already has some statistics
>>> wrtd.get_attr_int32('rule1', PyWrtd.WRTD_ATTR_STAT_RULE_RX_EVENTS)
532
>>> # First disable the rule
>>> wrtd.set_attr_bool('rule1', PyWrtd.WRTD_ATTR_RULE_ENABLED, False)
>>> wrtd.reset_rule_stats('rule1')
>>> wrtd.get_attr_int32('rule1', PyWrtd.WRTD_ATTR_STAT_RULE_RX_EVENTS)
0
.. _pyapi_app:
Applications API
----------------
.. automethod:: PyWrtd.get_fw_name
.. code-block:: python
# From the SVEC-based TDC+FDELAY reference Node
>>> count = wrtd.get_attr_int32(PyWrtd.WRTD_GLOBAL_REP_CAP_ID, PyWrtd.WRTD_ATTR_FW_COUNT)
>>> print(count)
2
>>> for i in range(count):
... wrtd.get_fw_name(i)
'wrtd-tdc'
'wrtd-fd'
.. _tools:
......
......@@ -50,10 +50,8 @@ def encode_arguments(func):
class PyWrtd():
"""Top-level Python wrapper class for WRTD library.
:ref:`api_error_codes` and :ref:`api_attr_id` are the same as in the WRTD library.
:param resource_name: Underlying MockTurtle device ID in the form of ``MTxxx`` or\
``trtl-xxxx``. See also :ref:`res_names`.
``trtl-xxxx``. See also :ref:`node_id`.
"""
......@@ -285,6 +283,8 @@ class PyWrtd():
def get_error(self):
"""
Corresponds to C library :cpp:func:`wrtd_get_error`.
:return: a tuple with the :ref:`Error Code <api_error_codes>` and the error message.
"""
buf_size = self.wrtd_lib.wrtd_get_error(self.wrtd_p, None, 0, None)
error_description = create_string_buffer(buf_size)
......
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