Package: twinpy
TwinPyThis 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 GUITwinPy 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 theBaseGUIorTcMainWindowclass with your own. To maintain clean version control, create your own repository and load this base repo as a git submodule.Starting your own GUIA repository has been cloned or initialized.Add TwinPy as a submodule by running:git submodule add https://bitbucket.org/ctw-bw/twinpy.gitCreate and activate a virtual environment if none exists yet:python -m venv venvvenv\Scripts\activateNow install the TwinPy submodule in the virtual environment:pip install -e twinpyThis will create a link from the TwinPy source, so it is available everywhere (inside that venv)To install other dependencies, copy./twinpy/requirements.txtto./requirements.txtand runpip install -r requirements.txtNow create your own application, extendingtwinpy.ui.BaseGUIortwinpy.ui.TcMainWindowYou can also copy the source ofBaseGUIand__main__.pyto your own application to get you started.Install packageInstall TwinPy via pip:pip install twinpyFrom sourceAfter cloning this repository (stand-alone or as a submodule), run the following in a command window (from the virtual environment):pip install -e ./twinpyThis will install the package from local source. The-eflag 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 startedThis 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.Runvenv/Scripts/Activate.ps1for PowerShell orvenv/Scripts/activate.batfor CMD. Your terminal should now show a '(venv)' prefix, the environment has been activated.Install the regular packages withpython -m pip install -r requirements.txtYou can now runpython -m twinpyIn case you do not want to use a virtual environment, just skip steps 1 and 2.Run with active terminalBy defaultapp.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 theapp.exec()line. The interpreter will handle the QT event loop elsewhere, freeing up the Python console for you to use.TwinCAT InterfaceInterfacing 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.MyConstBlockParameters are listed as properties of blocks. Useget()andset()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 useget()andset()directly on the block:val = model.MySubSystem.OtherSubSystem.MyConstBlock.get()  # Same result as aboveSignals are namedsi{n}andso{n}for input and output signals, numbered in the order determined by Simulink. Parameters are named after their Simulink name.DocsDocumentation from the source can be compiled using sphinx:cd docs
make htmlNote: 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:https://twinpy.readthedocs.ioTestsSee thetests/directory for unit tests and some run scripts. The tests are made with theunittestframework. Run all tests with:python-munittestSome 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 thepyads Contributing.mdfor more info.PyQtWhen 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 minimaloption: runpython -m unittest -platform minimalSet a debug environment variable:export QT_QPA_PLATFORM=offscreenUse a virtual X server:xvfb-run python -m unittest