OpenSMI Server
Open Smart Machine Interface (SMI) provides an abstract, standardized, vendor-neutral way to interact safely with real (or simulated) machines. OpenSMI is an asynchronous Python framework, built on top of asyncua for building SMI-compliant OPC UA servers.
It gives you the building blocks for exposing manufacturing capabilities — axes, grippers, robots, conveyors, whole machines — over a standardized, hierarchical OPC UA information model, without having to hand-roll everything yourself.
Why OpenSMI
A common real-world use case is as an adapter in front of a Programmable Logic Controller (PLC): many PLCs can speak OPC UA but don't natively expose SMI's richer skill model — suspendable/resumable skills, composite orchestration, feasibility/precondition checks, standardized locking. OpenSMI lets you sit in front of such a PLC and:
- Adapt what the PLC already exposes into proper SMI skills/methods, so any SMI-aware client can talk to it uniformly regardless of vendor or PLC platform.
- Extend it: if the PLC only implements simple atomic skills (e.g.
MoveTo,Open,Close), compose them into higher-level composite skills (e.g.PickAndPlace) in Python — where orchestration logic is faster to write, test, and iterate on than in PLC ladder/structured text.
This keeps low-level, safety-critical motion on the PLC where it belongs, while higher-level sequencing and coordination logic lives in a language better suited for rapid development.
Requirements
- Python 3.11+
Installation
pip install opensmi-server
Quick Start
Define a skill, add it to a machine, and start the OPC UA server:
import asyncio
from asyncua import ua
from opensmi.core import Unit
from opensmi.server import BaseMachine, BaseSkillFinalResultData, BaseSkillFinite, ParameterSet, Server, UaVariable
from opensmi.server.mixins import FinalResultDataMixin, ParameterSetMixin, ParentMixin
class ExampleSkillParameterSet(ParameterSet):
"""Parameters of the example skill."""
x = UaVariable(0, unit=Unit.NANOAMPERE, range=(0, 10))
y = UaVariable(0, unit="nA", range=(0, 10))
class ExampleSkillSimpleFinalResultData(BaseSkillFinalResultData):
"""Final result data of the example skill."""
ComputationResult = UaVariable(0, unit="nA", range=(0, 20))
class ExampleSkill(
ParentMixin["ExampleMachine"], # provides type-checkable parent type
ParameterSetMixin[ExampleSkillParameterSet], # provides type-checkable parameters
FinalResultDataMixin[ExampleSkillSimpleFinalResultData], # provides type-checkable results
BaseSkillFinite, # provides finite skill logic etc.
):
async def _handle_running(self) -> None:
# define logic that is executed in the RUNNING state
# read our parameters
x = await self.parameter_set.x.read()
y = await self.parameter_set.y.read()
# simulate long-running calculation etc.
await asyncio.sleep(1)
# we are done, write return variables
await self.final_result_data.ComputationResult.write(x + y)
class ExampleMachine(BaseMachine):
async def _init(self) -> None:
await super()._init()
await self.add_skill(ExampleSkill())
async def _write_identification(self) -> None:
# These identification variables must be set for machines
await self.identification.SerialNumber.write("1234-56789-abc")
await self.identification.ProductInstanceUri.write(
"urn:smartfactory.de-model:snr-1234-56789-abc"
)
await self.identification.Manufacturer.write(
ua.LocalizedText("Technologie-Initiative SmartFactory-KL e. V.", "de-DE")
)
async def main() -> None:
async with Server() as server: # will properly shut down the server
await server.add_machine(ExampleMachine()) # add machine(s)
await server.start(blocking=True) # start the server and block while it is running
if __name__ == "__main__":
asyncio.run(main())
Usage
- Connect to the server with any OPC UA client
(e.g. UaExpert)
at
opc.tcp://localhost:4841, authenticating as useroperatorwith passwordoperator. - Navigate to
Objects/Machines/ExampleMachine. - Under
ExampleMachine/Lock, call theInitLock()method to acquire exclusive access — required before you can write parameters or call skill methods. - Navigate to
ExampleMachine/SkillSet/ExampleSkill/SkillExecution. This is where the skill'sParameterSet,StateMachine, andFinalResultDataetc. live. - Under
ParameterSet, write values forxandy. - Under
StateMachine, callReset(). Skills start in theHaltedstate and must be reset toReadybefore they can run. - Call
Start(). The skill moves throughStarting→Running→Completing→Completed. - Once
StateMachine'sCurrentStatereadsCompleted, read the result fromComputationResultunderFinalResultData.
Or simply use our OpenSMI-Client.
Explore the safety features:
- Try writing parameters or calling skill methods without holding the Lock — it will be rejected.
- Try writing
xoryoutside their allowed range — it will be rejected. - Try acquiring the Lock while authenticated as user
visitorwith passwordvisitor— it will be rejected.
See here for more OpenSMI server examples.
Core Concepts
| Concept | What it is |
|---|---|
| Machinery Items | Common base for Machines and Components: attributes, identification, parameters, monitoring, sub-components, skills, methods, etc. |
| Components | One piece of a machine's hierarchy, e.g. an axis or a gripper. May nest further sub-components. |
| Machines | The top-level unit a client addresses as "the machine," e.g. a robot + storage + transport port. A single server can expose several machines. |
| Skills | Asynchronous, stateful capabilities — finite (run once, complete) or continuous (run indefinitely), atomic or composite. |
| Methods | Synchronous, quick operations — no state machine, just call() in, result out. |
Project Status
OpenSMI began as a closed-source project at SmartFactory-KL, in active use in our model factory since 2020. Its OPC UA information model has been refined across many iterations of research and demonstrator use. The framework was open-sourced in 2026 following substantial refactoring and cleanup.
Most of the framework is stable and well-tested, but it remains pre-1.0 — expect minor API changes before the 1.0 release.
Publications
Get more information of OpenSMI by reading our publications:
Scientific Publications
| Title | Content |
|---|---|
| Seamless Machine Integration in Smart Manufacturing: Utilizing OPC UA for Machinery with Skill-Based Engineering of Varying Granularity | Application of skills in robotics and an introduction to OpenSMI's OPC UA modeling |
| Developing a skill-based flexible transport system using OPC UA | Application of skills in intralogistic |
| Interaction between FeasibilityCheck, PreconditionCheck and SkillExecution in skill-based machining | Application of skills in machining |
Joint Publications
| Title | Content |
|---|---|
| Capabilities and Skills in Production Automation | Guidline for capabilities and skills with a focus on OPC UA |
| Information Model for Capabilities, Skills & Services | Presenting an information model for flexible manufacturing in Industry 4.0 based on capabilities, skills and services |
| Capabilities, Skills and Services CSS Model Extensions and Engineering Methodology | Refinement of the information model for capabilities, skills and services |
License
The library itself is licensed under the MIT License.
Example code contained in the examples directory is dedicated to the public domain under the CC0 1.0 Universal license.
This text was drafted with AI assistance (Claude, Anthropic) and reviewed/edited by the author before publication.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file opensmi_server-0.1.tar.gz.
File metadata
- Download URL: opensmi_server-0.1.tar.gz
- Upload date:
- Size: 138.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
15f109e79f6fc3772911bf05e019aa520565bbe956f8108e9cdd2a912bcb6510
|
|
| MD5 |
a49685a763c01a2a51486bbf6b00ebeb
|
|
| BLAKE2b-256 |
5feaa877c5391200a4156c3eaef0f111405ae08daf7a72727c7a9773ae4b9098
|
Provenance
The following attestation bundles were made for opensmi_server-0.1.tar.gz:
Publisher:
python-publish.yml on SmartFactory-KL/opensmi-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
opensmi_server-0.1.tar.gz -
Subject digest:
15f109e79f6fc3772911bf05e019aa520565bbe956f8108e9cdd2a912bcb6510 - Sigstore transparency entry: 2842508553
- Sigstore integration time:
-
Permalink:
SmartFactory-KL/opensmi-server@5daae2a15854372e311d4a95aaa4fd24c6f7073c -
Branch / Tag:
refs/tags/v0.1 - Owner: https://github.com/SmartFactory-KL
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@5daae2a15854372e311d4a95aaa4fd24c6f7073c -
Trigger Event:
release
-
Statement type:
File details
Details for the file opensmi_server-0.1-py3-none-any.whl.
File metadata
- Download URL: opensmi_server-0.1-py3-none-any.whl
- Upload date:
- Size: 137.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
da4e6c36f14458dc46dd8b59c420c79c342a6285362962e0f4dee2c089e96c8d
|
|
| MD5 |
50699efe1c4f1cbdf745c9be9a3ad53f
|
|
| BLAKE2b-256 |
0c36d29f4fe82f40d5b5357943e192386a3d654ea9358a1f686c26311657411c
|
Provenance
The following attestation bundles were made for opensmi_server-0.1-py3-none-any.whl:
Publisher:
python-publish.yml on SmartFactory-KL/opensmi-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
opensmi_server-0.1-py3-none-any.whl -
Subject digest:
da4e6c36f14458dc46dd8b59c420c79c342a6285362962e0f4dee2c089e96c8d - Sigstore transparency entry: 2842508624
- Sigstore integration time:
-
Permalink:
SmartFactory-KL/opensmi-server@5daae2a15854372e311d4a95aaa4fd24c6f7073c -
Branch / Tag:
refs/tags/v0.1 - Owner: https://github.com/SmartFactory-KL
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@5daae2a15854372e311d4a95aaa4fd24c6f7073c -
Trigger Event:
release
-
Statement type: