SiLA 2 Introduction

SiLA stands for Standardization in Lab Automation. The mission of SiLA is to create an international, open connectivity standard in lab automation. It is is a communication standard for laboratory instruments, such as readers, liquid handling robots, chromatography and other analytical equipment. You can find more information about SiLA on the official SiLA website or in this interesting blog post about SiLA.

The CETONI SiLA 2 drivers can be found in the sila directory of this SDK. These SiLA 2 drivers are based on the CETONI SDK for Python in order to control the devices.

The following types of devices are currently supported by the CETONI SiLA2 drivers:

CETONI Nemesys Syringe Pumps
CETONI Nemesys Tubing Pumps
CETONI Stirring Systems
CETONI Reaction Modules
CETONI I/O Modules
CETONI Sample Handlers
CETONI Positioning Systsms


These SiLA 2 drivers were developed and tested under Windows and Linux (Ubuntu 19.04 and Raspbian Buster on a Raspi 3B+) and are therefore expected to work on these systems. Other operating system should work as well, but have not been tested yet!

Installing Python dependencies

Install the requirements for the CETONI SiLA drivers from PyPI with

1 $ pip install -r requirements.txt

It is recommended to install these things in a virtual environment to not interfere with anything in your system's environment. This will install all Python dependencies for CETONI SiLA drivers most notably sila_python and its codegenerator (sila2codegenerator).

The current stable version of sila_python contains a few bugs that unfortunately result in SiLA 2 servers which can't be used with a Dynamic SiLA Client like CETONI Elements or the SiLA Browser.
There is a new release on the way that fixes these issues. Currently, development is done in the feature/silacodegenerator-0.3 branch in the sila_python repository that already contains the necessary fixes.
You can clone the repository from there and install it manually. Be aware, however, that this is a rapidly changing development version and it might have other bugs that have not been found yet.
To install the development version manually, follow these steps:
1 # 1. Clone the repo using the correct branch
2 $ git clone -b feature/silacodegenerator-0.3 https://gitlab.com/SiLA2/sila_python.git
3 # 2. Install sila_python
4 $ cd sila_python/sila_library
5 $ pip install --upgrade .
6 # 3. (optional) Install the code generator (if you plan on adding/modifying SiLA 2 features)
7 $ cd ../sila_tools/sila2codegenerator
8 $ pip install --upgrade .

Installing CETONI SDK

Additionally you'll of course need the CETONI SDK with the Python Integration.

For instructions on how to install the CETONI SDK for Python on your system and get a valid device configuration for your devices see the CETONI SDK Documentation. On Linux be sure to also install the correct SocketCAN driver (either SysTec or IXXAT depending on your CETONI base module).

Running SiLA 2 servers

You always need a valid device configuration created with the CETONI Elements software in order to use SiLA driver. Read the Getting Started section of the CETONI SDK documentation to learn how to create a device configuration.

Running any valid device configuration to get the corresponding SiLA 2 servers is always done through the sila_cetoni.py wrapper script located in the root of this repository.


On Windows you can simply run the script through Python giving it the path to the Qmix configuration folder as its argument:

1 > python .\sila_cetoni.py <path\to\your\device_config>
By default the script will look into the directory C:\CETONI_SDK\lib\python for the CETONI Python SDK. If you've installed the SDK elsewhere you need to adjust the path to point to your installation directory. Simply set the PYTHONPATH environment variable to C:\your\path\to\CETONI_SDK\lib\python.
See the Python documentation for more info.


On Linux this is not as easy, unfortunately. This is due to how Python loads shared object files. You need to specify the dynamic library search path before running the python executable in order for the CETONI SDK to find all necessary libraries. This can be done by manually specifying the PATH, PYTHONPATH and LD_LIBRARY_PATH environment variables before running sila_cetoni.py. To make this a bit easier you can use the provided shell script sila_cetoni.sh. You only need to edit the path to the CETONI SDK installation folder in this file as described in the Windows section. After that you can run this script giving it only the path to your configuration folder as its argument:

1 $ ./sila_qmix.sh <path/to/your/device_config>

The script will set the necessary variables and run the python script for you.

You can play around with the servers and their features by using the freely available SiLA Browser, for example. Or you can also write your own SiLA Client software using the Python or any other of the reference implementations of SiLA 2.

Modifying the drivers

You are of course free to play around with the code inside this repository. Especially when modifying the feature definitions you need to bear in mind a few things. The following is meant to be some kind of guidance for your first steps modifying the code.

Repository layout

The repository is structured in the following way:

1 sila_qmix
2 |- features/de/cetoni/ # folder structure according to SiLA 2 Part A
3 | |- controllers/ # contains all feature definitions grouped by category
4 | | `- ControlLoopService.sila.xml
5 | |- core/
6 | `- ...
7 |- impl/
8 | |- common/ # common functionality required by all feature implementations
9 | `- de/cetoni/ # folder structure as in features/ (above)
10 | |- controllers/ # contains all feature implementations grouped by category
11 | | |- gRPC/ # contains the gRPC generated code (must not be edited!)
12 | | |- ControlLoopService_servicer.py # serves as a bridge between the server and the actual implementations
13 | | |- ControlLoopService_real.py # the real implementation of this feature
14 | | |- ControlLoopService_simulation.py # the simulated implementation of this feature
15 | | `- ...
16 | |- core/
17 | `- ...
18 |- serv/ # contains server and client implementations of all services
19 | |- controllers/
20 | | |- QmixControl_server.py # server implementation of the QmixControl service
21 | | |- QmixControl_client.py # client implementation of the QmixControl service
22 | | `- service_description.json # service description defines the features to use for this service
23 | |- io/
24 | `- ...
25 |- templates/ # template files for developing new features
26 | |- Feature.sila.xml # FDL template file
27 | `- service_description.json # service description template
28 |- sila_qmix.py # standalone python wrapper script to run arbitrary servers
29 `- sila_qmix.sh # standalone shell wrapper script for Linux

Generate the prototype code from the FDL

If you modify a feature definition (.sila.xml file) you need to regenerate the gRPC Python code and the SiLA implementation prototypes. This is done using the sila2codegenerator from the sila_python reference implementation. The code generator has been automatically installed if you followed the step in Installation.

To show you the code generation process we're going to use the PumpFluidDosingService syringe pump feature as an example. In this case the feature definition resides in the file sila_qmix/features/de/cetoni/pumps/syringepumps/PumpFluidDosingService.sila.xml. Let's say you've added anew command to this feature. The code regeneration process is now as follows:

  1. Our target directory is the serv/pumps/syringepumps/ folder. This folder already contains the service_description.json file that tells the code generator which feature we want our syringe pump server to have. If you added a new feature you need to add it to the SiLA_feature_list in the service description.
  2. Then run the code generator from the root directory (i.e. sila_qmix/) with the following command

    1 $ silacodegenerator -b -o <target_dir> --service-description ../<target_dir>/service_description features/

    E.g. to generate the code for the 'pumps/syringepumps' category you'd need to run

    1 $ silacodegenerator -b -o serv/pumps/syringepumps --service-description ../serv/pumps/syringepumps/service_description features/
  3. This will create the folders with prototype implementations for each feature. You'll also be asked if you want to overwrite the existing _server.py and _client.py files. Answer this with n.
  4. After that delete all directories you don't need and only move the gRPC/ directory of th current feature into the correct directory in impl/de/cetoni/ (i.e. in our case into impl/de/cetoni/pumps/syringepumps/PumpFluidDosingService/).
  5. Finally, inspect each of the _servicer.py, _real.py and _simulation.py files of te feature to find the prototype definition(s) of the functions for your new command and copy them into the correct file in the impl/ folder. Then simply add your implementation in the _real.py file (the _simulation.py files have not been implemented because Qmix configurations support simulated devices already hence we don't need to use the simulation functionality of sila_python).