Package to interface with TwinCAT (incl. Simulink models)
Project description
TwinPy
This repository contains a GUI made in Python to interface with Simulink models in TwinCAT.
It has two main functions: maps to Simulink models can be created, and linked to TwinCAT, and GUI widgets that read and write from those.
Interfacing with TwinCAT is done through ADS, the variable sharing service.
API documentation can be found here: https://twinpy.readthedocs.io/en/latest/
A complete example of a TwinPy GUI can be found here: https://bitbucket.org/ctw-bw/twinpy-gui-demo. This example does not use Simulink, and instead uses a very simple PLC script, which variables end up in the ADS pool.
Your own custom GUI
TwinPy is designed as a library. So your own application should incorporate it instead of modifying it.
To customize a GUI for your application, you can extend the BaseGUI
or TcMainWindow
class with your own. To maintain clean version control, create your own repository and load this base repo as a git submodule.
Starting your own GUI
A repository has been cloned or initialized.
- Add TwinPy as a submodule by running:
git submodule add https://bitbucket.org/ctw-bw/twinpy.git
- Create and activate a virtual environment if none exists yet:
python -m venv venv
venv\Scripts\activate
- Now install the TwinPy submodule in the virtual environment:
pip install -e twinpy
- This will create a link from the TwinPy source, so it is available everywhere (inside that venv)
- To install other dependencies, copy
./twinpy/requirements.txt
to./requirements.txt
and runpip install -r requirements.txt
- Now create your own application, extending
twinpy.ui.BaseGUI
ortwinpy.ui.TcMainWindow
- You can also copy the source of
BaseGUI
and__main__.py
to your own application to get you started.
- You can also copy the source of
Install package
Install TwinPy via pip:
pip install twinpy
From source
After cloning this repository (stand-alone or as a submodule), run the following in a command window (from the virtual environment):
pip install -e ./twinpy
This will install the package from local source. The -e
flag keeps the original source editable, which is convenient during development.
It is recommended to install a local package like twinpy only in a virtual environment.
Getting started
This explains how to run the given TwinPy example with the WE2 Simulink models. This is not applicable to a custom GUI or custom models. Use this getting-started as a check to see if your system is ready.
- To run from a virtual environment (recommended), open a terminal in this directory and run:
python -m venv venv
(use a full path to select a different Python version). A virtual environment is now created. - Run
venv/Scripts/Activate.ps1
for PowerShell orvenv/Scripts/activate.bat
for CMD. Your terminal should now show a '(venv)' prefix, the environment has been activated. - Install the regular packages with
python -m pip install -r requirements.txt
- You can now run
python -m twinpy
In case you do not want to use a virtual environment, just skip steps 1 and 2.
Run with active terminal
By default app.exec()
is a hanging command that fires up the main event loop of the GUI. It will prevent the script from exiting when the application is still open. When running the GUI from a terminal, you cannot interact with the active objects untill the GUI was closed.
Pyzo has a way around this. If you run the script from a shell with 'gui' set to "PyQt5" you can disable the app.exec()
line. The interpreter will handle the QT event loop elsewhere, freeing up the Python console for you to use.
TwinCAT Interface
Interfacing with TwinCAT starts with the SimulinkModel object. It points to a Simulink object running in TwinCAT. You can address parts of the model in a hierarchical way, based on the hierarchy in the original Simulink model:
model = SimulinkModel(...)
const_block = model.MySubSystem.OtherSubSystem.MyConstBlock
Parameters are listed as properties of blocks. Use get()
and set()
to read and write those parameters:
val = model.MySubSystem.OtherSubSystem.MyConstBlock.Value.get()
# A Constant block only has one parameter, named `Value`
If a block only has a single parameter or signal, you can also use get()
and set()
directly on the block:
val = model.MySubSystem.OtherSubSystem.MyConstBlock.get() # Same result as above
Signals are named si{n}
and so{n}
for input and output signals, numbered in the order determined by Simulink. Parameters are named after their Simulink name.
Docs
Documentation from the source can be compiled using sphinx:
cd docs
make html
Note: if you get an error about e.g. missing the pyads package because you use a virtual environment, install sphinx inside the virtual environment too.
Documentation is automatically built and hosted on readthedocs.io:
Tests
See the tests/
directory for unit tests and some run scripts. The tests are made with the unittest
framework. Run all tests with:
python -m unittest
Some tests rely on the pyads test server. This test server unfortunately does not work with Windows. When on a Windows system, use Linux subsystem for Windows, a virtual machine or Docker. Look for the pyads documentation or the pyads Contributing.md for more info.
PyQt
When running the tests without an actual screen (like SSH terminal or in a pipeline) PyQt will throw a fatal error. The widgets cannot be created without a screen. There a couple of workarounds for this:
- Include the Qt option
-platform minimal
option: runpython -m unittest -platform minimal
- Set a debug environment variable:
export QT_QPA_PLATFORM=offscreen
- Use a virtual X server:
xvfb-run python -m unittest
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file twinpy-1.1.3.tar.gz
.
File metadata
- Download URL: twinpy-1.1.3.tar.gz
- Upload date:
- Size: 33.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.0 CPython/3.8.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c3fb614680d1bcbcc283a7875144ad6bfc1a4af5025930ccbdd18a8c703843ef |
|
MD5 | 059f7230e295350b8f6782826c93e249 |
|
BLAKE2b-256 | 80a51783b28c498ff7e87a25029a37c19765366d8d28e1c3715a1852b6a4466b |