VSIKnowledge

Building a Twin

Python components

A component can be Python instead of C++. vsiBuild generates a Python skeleton with the same five user regions, compiles a small gateway extension for it, and the generated Makefile runs it with the system python. A Python block talks to C++ blocks over the same fabric; nothing on the other side knows or cares.

Declaring one (VENDOR, Builder and Simulator Guide 2-25 and 2-26)

add component -type Python -name Logger
add port -componentName Logger -name log_p -gateway python2DtGenericPayload

Gateways for Python components: python2DtEthernet, python2DtGenericPayload, python2DtCan (with -canVersion can or canFd), python2DtLin (with -nodeType master or slave) and python2DtGpio. Install setuptools in the Python that python resolves to; the extension is built with setup.py --compiler=mingw32 against it, and on this machine that is CPython 3.13.

Getting one from the pipelines

  • From a Teamcenter ICD: icd_to_vsi.py --python-blocks REGEX; matching blocks become Python, everything else stays C++. Blocks that carry an Ethernet port are kept C++ and the demotion is printed and written to the assumptions file (reason below).
  • From SysML v2: specialise PythonComponent instead of CppComponent in the part def.
  • By hand: the two lines above.

Generate to a short workspace root such as D:\wfpy. The Python gateway nests a build folder under the twin and past about 260 characters the link fails with a message naming a missing .def file; from the repository path it fails, from D:\wfpy it builds.

What the skeleton looks like (EXERCISED)

src\Logger\Logger.py: imports the gateway module from vsi.build\_objs\pythonGatewaysN, a MySignals class with one attribute per signal, the module-level region "Global Variables and Definitions", a class with __init__ (region "Constructor"), run() (connects, waits for reset, loops over steps), executeMainThreadStep() with the regions "Before sending the packet" and "After sending the packet" around the generated send calls and print block, a mainThread() iteration region, and the receive callbacks that unpack into self.mySignals before the region "Protocol's callback function". Region markers are # comments with the same names as the C++ // ones, so the glue patches both with one script. A CAN consumer's send is muted by rebinding the gateway alias to a wrapper that swallows sendCanPacket (the Python form of the C++ macro mute).

Two differences from C++ to remember:

  • A Python client runs from the twin root (python src\Logger\Logger.py), a C++ client from vsi.sim\_logs. Anything written relative to the working directory lands in a different place per language. The glue's Python trace writer redirects into vsi.sim\_logs when it can see it.
  • Keep per-component state in one module-level object and advance the step through it. A global statement placed after the same name has already been read in that method is a Python syntax error, and the "Before" and "After" regions share one method.

A vendor defect and how the generator fences it (EXERCISED, with controls)

vsiBuild 2026.2 generates a Python component whose Ethernet socket carries no connected signals with an empty def establishTcpUdpConnection(self):, an indentation error before any user code runs. Reproduced with three two-component variants: a socket with connected signals gets a real body; one with signals defined but none connected gets the empty method (the Wildfire Gimbal_Video_Aggregator shape); a component with no signals at all is refused at generate and cannot show the defect. In the Teamcenter pipeline every Ethernet socket carries no signals, because Teamcenter records none, so --python-blocks keeps such blocks C++ and says so. The rule reads the one tuple in icd_to_vsi.py that decides which protocols get signal wiring, so it stops firing the day Ethernet joins it. The glue also compiles every Python file it touches, so a broken skeleton is reported at apply time. The as-generated broken files are kept under innexis-vsi\runs\evidence.

Proof (EXERCISED 2026-09-08)

Wildfire with Navigation_Unit (CAN consumer plus a GenericPayload consumer), Landing_Gear_System and Flight_Termination_System (producers) and Safety_Interlock_Unit__siuWow (consumer of a Python producer) as Python among 59 C++ blocks: built (59 client executables plus four gateway extensions), ran in 145 s, 63 traces, checker 177 pass, 0 fail, 18 of 18 producer rates. Python to C++, C++ to Python and Python to Python all carried the counters, and the muted Python CAN consumer read the C++ producer's frame. Evidence in runs\20260908-2130-wildfire-python4-177pass, including one glued Python skeleton to read as an example.

Source: InnexisVsiBuilderSimulatorGuide.pdf pages 31, 41, 42 (VENDOR); innexis-vsi/icd_to_vsi.py --python-blocks, twin_glue/generic_stim.py, runs/20260908-2130-wildfire-python4-177pass, runs/evidence (EXERCISED 2026-09-08) · retrieved Tue Sep 08 2026 00:00:00 GMT+0000 (Coordinated Universal Time)