pdcom5 5.3.2
Library for process data exchange
Requires Python: >=3.6

[![pipeline status](https://gitlab.com/etherlab.org/pdcom/badges/master/pipeline.svg)](https://gitlab.com/etherlab.org/pdcom/-/commits/master)
[![coverage report](https://gitlab.com/etherlab.org/pdcom/badges/master/coverage.svg)](https://docs.etherlab.org/pdcom/5/coverage/index.html)
[![online c++ documentation](https://img.shields.io/badge/Documentation-C++-informational)](https://docs.etherlab.org/pdcom/5/doxygen/index.html)
[![online python documentation](https://img.shields.io/badge/Documentation-Python-informational)](https://docs.etherlab.org/pdcom/5/sphinx/index.html)

This is the README file of the PdCom library, that is part of the EtherLab
project (http://etherlab.org/en). The home of PdCom is
http://etherlab.org/en/pdcom. The Library is released under the terms and
conditions of the GNU Lesser General Public License (LGPL), version 3 or (at
your option) any later version.

## Documentation

You can find the documentation online [here
(C++)](https://docs.etherlab.org/pdcom/5/doxygen/index.html) and [here
(Python)](https://docs.etherlab.org/pdcom/5/sphinx/index.html).

The library documentation resides in the header files and can be brought to
HTML, LaTeX and man format with the doxygen tool. To generate the
documentation, make sure that doxygen is installed and then call:

```sh
    git submodule update --init
    mkdir build
    cd build
    cmake ..
    make doc
```

Then point your favourite browser to doc/html/index.html.

## Building and Installing

To just build and install the library, call:

```sh
    mkdir build
    cd build
    cmake -DCMAKE_BUILD_TYPE=Release ..
    make
    make install
```

You'll need the following packages:
 - libexpat-devel
 - libgnutls-devel
 - cyrus-sasl-devel

For running the unit tests, the GTest library is required.

## Python API

In the python subdirectory, an [asyncio](https://docs.python.org/3/library/asyncio.html) based Python API is provided.
It requires Python >= 3.6, numpy and pybind11 >= 2.6.0.
Please note that `make install` does not install this Python module.
Instead, please navigate to the python subdirectory after installing the C++ library
and install the pdcom5 python module using `pip3 install .`.

There are also some pre-built wheel packages available.
Use `pip3 install pdcom5`
to install pdcom5 from PyPI.

The starting point for almost everything is the `Process` class
which is in charge of handling the communication.
You can use it to find variables, to set parameters and to subscribe to signals.
Most of the functions in this API are coroutines,
which have to be `await`ed.

In this snippet, a connection is made to the oscillator example in PdServ.
Its cosine output is polled twice,
then the `enable` Parameter is set to False.
After that, the cosine output is again polled twice.
Then, the cosine is enabled again.
Finally, a periodic subscription is established,
with a period of two Hz.
Note that for the interactive asyncio REPL (`python3 -m asyncio`), Python >= 3.8 is required.

```py
>>> import pdcom5
>>> process = pdcom5.Process()
>>> await process.connect("msr://localhost:2345")
>>> variable = await process.find("/osc/cos")
>>> variable.shape
(1,)
>>> await variable.poll()
(-6.698516364546891, datetime.timedelta(days=19831, seconds=52590, microseconds=757770))
>>> await variable.poll()
(-0.6620524859141752, datetime.timedelta(days=19831, seconds=52592, microseconds=717771))
>>> await process.setVariableValue("/osc/enable", False)
>>> await variable.poll()
(-1.336504969688323, datetime.timedelta(days=19831, seconds=52606, microseconds=527782))
>>> await variable.poll()
(-1.336504969688323, datetime.timedelta(days=19831, seconds=52607, microseconds=547806))
>>> await process.setVariableValue("/osc/enable", True)
>>> subscription = await process.subscribe(0.5, "/osc/cos")
>>> async for timestamp in subscription.newValues():
...    print((subscription.value, timestamp))
...
(7.271824824350419, datetime.timedelta(days=19831, seconds=52679, microseconds=597804))
(2.033658184944072, datetime.timedelta(days=19831, seconds=52680, microseconds=97877))
(-3.914956840413724, datetime.timedelta(days=19831, seconds=52680, microseconds=597896))
(-8.495901138737317, datetime.timedelta(days=19831, seconds=52681, microseconds=97879))
(-10.108844572458873, datetime.timedelta(days=19831, seconds=52681, microseconds=597802))
(-8.190313364322167, datetime.timedelta(days=19831, seconds=52682, microseconds=97916))
(-3.4105368627541592, datetime.timedelta(days=19831, seconds=52682, microseconds=597804))
(2.5606937520517863, datetime.timedelta(days=19831, seconds=52683, microseconds=97826))
(7.637358723265475, datetime.timedelta(days=19831, seconds=52683, microseconds=597976))
(10.045950358435528, datetime.timedelta(days=19831, seconds=52684, microseconds=97870))
```

There is also `Transmission.event_mode` and
`Transmission.poll_mode` for creating non-periodical subscriptions

## Further Information

For questions of any kind, subscribe to the etherlab-users mailing list at
http://etherlab.org/en.

Have fun with PdCom!