OpenSMI-Core 0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opensmi_core-0.1/.github/workflows/python-publish.yml +70 -0
- opensmi_core-0.1/.gitignore +18 -0
- opensmi_core-0.1/.gitlab-ci.yml +49 -0
- opensmi_core-0.1/LICENSE +18 -0
- opensmi_core-0.1/LICENSES/MIT.txt +18 -0
- opensmi_core-0.1/PKG-INFO +32 -0
- opensmi_core-0.1/README.md +2 -0
- opensmi_core-0.1/pyproject.toml +180 -0
- opensmi_core-0.1/setup.cfg +4 -0
- opensmi_core-0.1/src/OpenSMI_Core.egg-info/PKG-INFO +32 -0
- opensmi_core-0.1/src/OpenSMI_Core.egg-info/SOURCES.txt +40 -0
- opensmi_core-0.1/src/OpenSMI_Core.egg-info/dependency_links.txt +1 -0
- opensmi_core-0.1/src/OpenSMI_Core.egg-info/requires.txt +12 -0
- opensmi_core-0.1/src/OpenSMI_Core.egg-info/scm_file_list.json +37 -0
- opensmi_core-0.1/src/OpenSMI_Core.egg-info/scm_version.json +8 -0
- opensmi_core-0.1/src/OpenSMI_Core.egg-info/top_level.txt +1 -0
- opensmi_core-0.1/src/opensmi/core/__init__.py +21 -0
- opensmi_core-0.1/src/opensmi/core/async_task_mixin.py +55 -0
- opensmi_core-0.1/src/opensmi/core/base_server.py +75 -0
- opensmi_core-0.1/src/opensmi/core/base_ua_object.py +120 -0
- opensmi_core-0.1/src/opensmi/core/config.py +92 -0
- opensmi_core-0.1/src/opensmi/core/enums.py +24 -0
- opensmi_core-0.1/src/opensmi/core/errors.py +67 -0
- opensmi_core-0.1/src/opensmi/core/frozen.py +26 -0
- opensmi_core-0.1/src/opensmi/core/hook.py +22 -0
- opensmi_core-0.1/src/opensmi/core/lifecycle_mixin.py +275 -0
- opensmi_core-0.1/src/opensmi/core/logging.py +161 -0
- opensmi_core-0.1/src/opensmi/core/meta.py +51 -0
- opensmi_core-0.1/src/opensmi/core/mixin_helpers.py +19 -0
- opensmi_core-0.1/src/opensmi/core/protocols.py +32 -0
- opensmi_core-0.1/src/opensmi/core/repr_mixin.py +33 -0
- opensmi_core-0.1/src/opensmi/core/signal.py +36 -0
- opensmi_core-0.1/src/opensmi/core/subscription_manager.py +190 -0
- opensmi_core-0.1/src/opensmi/core/ua.py +17 -0
- opensmi_core-0.1/src/opensmi/core/ua_enums.py +93 -0
- opensmi_core-0.1/src/opensmi/core/ua_node_util.py +239 -0
- opensmi_core-0.1/src/opensmi/core/unit_all.py +2187 -0
- opensmi_core-0.1/src/opensmi/core/unit_base.py +71 -0
- opensmi_core-0.1/src/opensmi/core/unset.py +22 -0
- opensmi_core-0.1/tests/test_signal.py +144 -0
- opensmi_core-0.1/tests/test_unit.py +62 -0
- opensmi_core-0.1/tools/auto_generate_units.py +170 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# This workflow will upload a Python Package to PyPI when a release is created
|
|
2
|
+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
|
|
3
|
+
|
|
4
|
+
# This workflow uses actions that are not certified by GitHub.
|
|
5
|
+
# They are provided by a third-party and are governed by
|
|
6
|
+
# separate terms of service, privacy policy, and support
|
|
7
|
+
# documentation.
|
|
8
|
+
|
|
9
|
+
name: Upload Python Package
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
release:
|
|
13
|
+
types: [published]
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
release-build:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.11"
|
|
28
|
+
|
|
29
|
+
- name: Build release distributions
|
|
30
|
+
run: |
|
|
31
|
+
# NOTE: put your own distribution build steps here.
|
|
32
|
+
python -m pip install build
|
|
33
|
+
python -m build
|
|
34
|
+
|
|
35
|
+
- name: Upload distributions
|
|
36
|
+
uses: actions/upload-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: release-dists
|
|
39
|
+
path: dist/
|
|
40
|
+
|
|
41
|
+
pypi-publish:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
needs:
|
|
44
|
+
- release-build
|
|
45
|
+
permissions:
|
|
46
|
+
# IMPORTANT: this permission is mandatory for trusted publishing
|
|
47
|
+
id-token: write
|
|
48
|
+
|
|
49
|
+
# Dedicated environments with protections for publishing are strongly recommended.
|
|
50
|
+
# For more information, see: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#deployment-protection-rules
|
|
51
|
+
environment:
|
|
52
|
+
name: pypi
|
|
53
|
+
# OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status:
|
|
54
|
+
# url: https://pypi.org/p/YOURPROJECT
|
|
55
|
+
#
|
|
56
|
+
# ALTERNATIVE: if your GitHub Release name is the PyPI project version string
|
|
57
|
+
# ALTERNATIVE: exactly, uncomment the following line instead:
|
|
58
|
+
# url: https://pypi.org/project/YOURPROJECT/${{ github.event.release.name }}
|
|
59
|
+
|
|
60
|
+
steps:
|
|
61
|
+
- name: Retrieve release distributions
|
|
62
|
+
uses: actions/download-artifact@v4
|
|
63
|
+
with:
|
|
64
|
+
name: release-dists
|
|
65
|
+
path: dist/
|
|
66
|
+
|
|
67
|
+
- name: Publish release distributions to PyPI
|
|
68
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
69
|
+
with:
|
|
70
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
default:
|
|
2
|
+
image: python:3.14-alpine
|
|
3
|
+
cache:
|
|
4
|
+
key: "$CI_COMMIT_REF_SLUG"
|
|
5
|
+
paths:
|
|
6
|
+
- .cache/pip
|
|
7
|
+
tags:
|
|
8
|
+
- k8s
|
|
9
|
+
|
|
10
|
+
test:
|
|
11
|
+
stage: test
|
|
12
|
+
parallel:
|
|
13
|
+
matrix:
|
|
14
|
+
- PYTHON_VERSION: [ "3.11", "3.14" ]
|
|
15
|
+
image: python:${PYTHON_VERSION}-alpine
|
|
16
|
+
before_script:
|
|
17
|
+
- apk add --no-cache git
|
|
18
|
+
- python --version
|
|
19
|
+
- python -m pip install --cache-dir .cache/pip --upgrade pip setuptools wheel
|
|
20
|
+
- python -m pip install --cache-dir .cache/pip . --group dev
|
|
21
|
+
script:
|
|
22
|
+
- python -m pytest --timeout=120 --html=report.html --self-contained-html --junitxml=result.xml --cov=open_smi --cov-report term --cov-report xml:coverage.xml -v -n 8
|
|
23
|
+
coverage: '/TOTAL.+ ([0-9]{1,3}%)/'
|
|
24
|
+
artifacts:
|
|
25
|
+
when: always
|
|
26
|
+
paths:
|
|
27
|
+
- report.html
|
|
28
|
+
- result.xml
|
|
29
|
+
- coverage.xml
|
|
30
|
+
- .coverage
|
|
31
|
+
reports:
|
|
32
|
+
junit: result.xml
|
|
33
|
+
coverage_report:
|
|
34
|
+
coverage_format: cobertura
|
|
35
|
+
path: coverage.xml
|
|
36
|
+
|
|
37
|
+
package:
|
|
38
|
+
stage: deploy
|
|
39
|
+
variables:
|
|
40
|
+
TWINE_USERNAME: __token__
|
|
41
|
+
TWINE_PASSWORD: ${TEST_PYPI_PASSWORD}
|
|
42
|
+
TWINE_REPOSITORY_URL: https://test.pypi.org/legacy/
|
|
43
|
+
script:
|
|
44
|
+
- apk add --no-cache git
|
|
45
|
+
- pip install build twine
|
|
46
|
+
- python -m build
|
|
47
|
+
- python -m twine upload dist/* --verbose
|
|
48
|
+
rules:
|
|
49
|
+
- if: $CI_COMMIT_TAG
|
opensmi_core-0.1/LICENSE
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OpenSMI Contributors.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
6
|
+
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
|
9
|
+
following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
12
|
+
portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
|
15
|
+
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
|
16
|
+
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
18
|
+
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OpenSMI Contributors.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
6
|
+
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
|
9
|
+
following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
12
|
+
portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
|
15
|
+
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
|
16
|
+
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
18
|
+
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: OpenSMI-Core
|
|
3
|
+
Version: 0.1
|
|
4
|
+
Summary: Smart Machine Interface core functionality for server and client applications.
|
|
5
|
+
Author-email: Carsten Harms <Carsten.Harms@dfki.de>, Simon Jungbluth <Simon.Jungbluth@smartfactory.de>
|
|
6
|
+
Classifier: Development Status :: 4 - Beta
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: Intended Audience :: Information Technology
|
|
9
|
+
Classifier: Intended Audience :: Manufacturing
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Topic :: Communications
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
|
|
19
|
+
Classifier: Topic :: Software Development :: Embedded Systems
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: asyncua<3,>=2.0.1
|
|
25
|
+
Requires-Dist: structlog>=26
|
|
26
|
+
Requires-Dist: typing-extensions>=4.16.0
|
|
27
|
+
Provides-Extra: rich
|
|
28
|
+
Requires-Dist: rich>=15.0.0; extra == "rich"
|
|
29
|
+
Requires-Dist: colorama>=0.4; sys_platform == "win32" and extra == "rich"
|
|
30
|
+
Provides-Extra: json
|
|
31
|
+
Requires-Dist: orjson<4,>=3; extra == "json"
|
|
32
|
+
Dynamic: license-file
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=80", "setuptools-scm[simple]>=9.2"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "OpenSMI-Core"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
|
|
9
|
+
description = "Smart Machine Interface core functionality for server and client applications."
|
|
10
|
+
authors = [
|
|
11
|
+
{ name = "Carsten Harms", email = "Carsten.Harms@dfki.de" },
|
|
12
|
+
{ name = "Simon Jungbluth", email = "Simon.Jungbluth@smartfactory.de" },
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
# see https://pypi.org/classifiers/
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Intended Audience :: Information Technology",
|
|
20
|
+
"Intended Audience :: Manufacturing",
|
|
21
|
+
"Intended Audience :: Science/Research",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Programming Language :: Python :: 3.14",
|
|
27
|
+
"Topic :: Communications",
|
|
28
|
+
"Topic :: Scientific/Engineering",
|
|
29
|
+
"Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator",
|
|
30
|
+
"Topic :: Software Development :: Embedded Systems",
|
|
31
|
+
"Topic :: Software Development :: Libraries",
|
|
32
|
+
"Typing :: Typed"
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
requires-python = ">=3.11"
|
|
36
|
+
|
|
37
|
+
dependencies = [
|
|
38
|
+
"asyncua>=2.0.1,<3", # OPC UA, main dep; has quite a few deps
|
|
39
|
+
"structlog>=26", # structured logging; has no deps
|
|
40
|
+
"typing-extensions>=4.16.0", # backported type hints; already a dep of asyncua
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.optional-dependencies]
|
|
44
|
+
rich = [
|
|
45
|
+
"rich>=15.0.0", # colorful logging; transitive deps: markdown-it-py, mdurl & pygments
|
|
46
|
+
"colorama>=0.4; sys_platform == 'win32'", # colors in terminal on Windows; has no deps
|
|
47
|
+
]
|
|
48
|
+
json = [
|
|
49
|
+
"orjson>=3, <4", # faster JSON logging; has no deps
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[dependency-groups]
|
|
53
|
+
dev = [
|
|
54
|
+
"basedpyright>=1.39.9",
|
|
55
|
+
"ruff>=0.15",
|
|
56
|
+
"pytest>=9",
|
|
57
|
+
"pytest-asyncio>=1",
|
|
58
|
+
"pytest-cov>=7",
|
|
59
|
+
"pytest-xdist>=3",
|
|
60
|
+
"pytest-html>=4",
|
|
61
|
+
"pytest-timeout>=2",
|
|
62
|
+
"openpyxl" # to load UNECE Excel to autogenerate units
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
[tool.setuptools]
|
|
66
|
+
include-package-data = true
|
|
67
|
+
|
|
68
|
+
[tool.setuptools.packages.find]
|
|
69
|
+
where = ["src"]
|
|
70
|
+
namespaces = true
|
|
71
|
+
# exclude = ["tests", "doc*", "examples"]
|
|
72
|
+
|
|
73
|
+
[tool.ruff]
|
|
74
|
+
# Exclude a variety of commonly ignored directories.
|
|
75
|
+
exclude = [
|
|
76
|
+
".bzr",
|
|
77
|
+
".direnv",
|
|
78
|
+
".eggs",
|
|
79
|
+
".git",
|
|
80
|
+
".git-rewrite",
|
|
81
|
+
".hg",
|
|
82
|
+
".ipynb_checkpoints",
|
|
83
|
+
".mypy_cache",
|
|
84
|
+
".nox",
|
|
85
|
+
".pants.d",
|
|
86
|
+
".pyenv",
|
|
87
|
+
".pytest_cache",
|
|
88
|
+
".pytype",
|
|
89
|
+
".ruff_cache",
|
|
90
|
+
".svn",
|
|
91
|
+
".tox",
|
|
92
|
+
".venv",
|
|
93
|
+
".vscode",
|
|
94
|
+
"__pypackages__",
|
|
95
|
+
"_build",
|
|
96
|
+
"buck-out",
|
|
97
|
+
"build",
|
|
98
|
+
"dist",
|
|
99
|
+
"node_modules",
|
|
100
|
+
"site-packages",
|
|
101
|
+
"venv",
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
line-length = 120
|
|
105
|
+
indent-width = 4
|
|
106
|
+
fix = true
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
[tool.ruff.lint]
|
|
110
|
+
select = ["A", "ANN001", "ANN201", "ANN205", "ANN206",
|
|
111
|
+
"ASYNC", "B", "C4", "CPY", "D", "DTZ", "E", "EM",
|
|
112
|
+
"EXE", "F", "FA", "ICN", "I", "LOG", "T20", "PT",
|
|
113
|
+
"SLF", "SIM", "C901", "N", "PIE", "PLE", "PYI", "PT",
|
|
114
|
+
"Q", "RSE", "RET", "TD", "PERF", "UP", "FURB", "RUF",
|
|
115
|
+
"TRY"]
|
|
116
|
+
ignore = ["D203", "D213"]
|
|
117
|
+
|
|
118
|
+
# Allow fix for all enabled rules (when `--fix`) is provided.
|
|
119
|
+
fixable = ["ALL"]
|
|
120
|
+
unfixable = []
|
|
121
|
+
|
|
122
|
+
# Allow unused variables when underscore-prefixed.
|
|
123
|
+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
124
|
+
|
|
125
|
+
[tool.ruff.lint.flake8-annotations]
|
|
126
|
+
allow-star-arg-any = true
|
|
127
|
+
|
|
128
|
+
[tool.ruff.lint.flake8-copyright]
|
|
129
|
+
notice-rgx = "SPDX-FileCopyrightText: \\d{4}"
|
|
130
|
+
author = "OpenSMI Contributors"
|
|
131
|
+
|
|
132
|
+
[tool.ruff.lint.per-file-ignores]
|
|
133
|
+
"tests/**" = ["ANN", "D", "T", "SLF001"]
|
|
134
|
+
"src/opensmi/core/unit_all.py" = [ # auto-generated
|
|
135
|
+
"E501", # line too long
|
|
136
|
+
"RUF001", # String contains ambiguous ~
|
|
137
|
+
"CPY", # copyright
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
[tool.ruff.format]
|
|
141
|
+
quote-style = "double"
|
|
142
|
+
indent-style = "space"
|
|
143
|
+
skip-magic-trailing-comma = false
|
|
144
|
+
line-ending = "auto"
|
|
145
|
+
|
|
146
|
+
# Enable auto-formatting of code examples in docstrings. Markdown,
|
|
147
|
+
# reStructuredText code/literal blocks and doctests are all supported.
|
|
148
|
+
#
|
|
149
|
+
# This is currently disabled by default, but it is planned for this
|
|
150
|
+
# to be opt-out in the future.
|
|
151
|
+
docstring-code-format = true
|
|
152
|
+
|
|
153
|
+
# Set the line length limit used when formatting code snippets in
|
|
154
|
+
# docstrings.
|
|
155
|
+
#
|
|
156
|
+
# This only has an effect when the `docstring-code-format` setting is
|
|
157
|
+
# enabled.
|
|
158
|
+
docstring-code-line-length = "dynamic"
|
|
159
|
+
|
|
160
|
+
[tool.mypy]
|
|
161
|
+
packages = "src/opensmi/core"
|
|
162
|
+
|
|
163
|
+
warn_unused_configs = true
|
|
164
|
+
pretty = true
|
|
165
|
+
|
|
166
|
+
strict = true
|
|
167
|
+
|
|
168
|
+
[tool.basedpyright]
|
|
169
|
+
include = ["src"]
|
|
170
|
+
typeCheckingMode = "standard"
|
|
171
|
+
executionEnvironments = [{ root = "src" }]
|
|
172
|
+
|
|
173
|
+
[tool.pydoctor]
|
|
174
|
+
project-name = "OpenSMI-Core"
|
|
175
|
+
add-package = ["src/opensmi/core"]
|
|
176
|
+
docformat = "restructuredtext"
|
|
177
|
+
theme = "readthedocs"
|
|
178
|
+
# verbose = 1
|
|
179
|
+
warnings-as-errors = true
|
|
180
|
+
intersphinx = ["https://opcua-asyncio.readthedocs.io/en/latest/objects.inv"] # TODO(CaHa): does not work
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: OpenSMI-Core
|
|
3
|
+
Version: 0.1
|
|
4
|
+
Summary: Smart Machine Interface core functionality for server and client applications.
|
|
5
|
+
Author-email: Carsten Harms <Carsten.Harms@dfki.de>, Simon Jungbluth <Simon.Jungbluth@smartfactory.de>
|
|
6
|
+
Classifier: Development Status :: 4 - Beta
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: Intended Audience :: Information Technology
|
|
9
|
+
Classifier: Intended Audience :: Manufacturing
|
|
10
|
+
Classifier: Intended Audience :: Science/Research
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Topic :: Communications
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
|
|
19
|
+
Classifier: Topic :: Software Development :: Embedded Systems
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: asyncua<3,>=2.0.1
|
|
25
|
+
Requires-Dist: structlog>=26
|
|
26
|
+
Requires-Dist: typing-extensions>=4.16.0
|
|
27
|
+
Provides-Extra: rich
|
|
28
|
+
Requires-Dist: rich>=15.0.0; extra == "rich"
|
|
29
|
+
Requires-Dist: colorama>=0.4; sys_platform == "win32" and extra == "rich"
|
|
30
|
+
Provides-Extra: json
|
|
31
|
+
Requires-Dist: orjson<4,>=3; extra == "json"
|
|
32
|
+
Dynamic: license-file
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
.gitignore
|
|
2
|
+
.gitlab-ci.yml
|
|
3
|
+
LICENSE
|
|
4
|
+
README.md
|
|
5
|
+
pyproject.toml
|
|
6
|
+
.github/workflows/python-publish.yml
|
|
7
|
+
LICENSES/MIT.txt
|
|
8
|
+
src/OpenSMI_Core.egg-info/PKG-INFO
|
|
9
|
+
src/OpenSMI_Core.egg-info/SOURCES.txt
|
|
10
|
+
src/OpenSMI_Core.egg-info/dependency_links.txt
|
|
11
|
+
src/OpenSMI_Core.egg-info/requires.txt
|
|
12
|
+
src/OpenSMI_Core.egg-info/scm_file_list.json
|
|
13
|
+
src/OpenSMI_Core.egg-info/scm_version.json
|
|
14
|
+
src/OpenSMI_Core.egg-info/top_level.txt
|
|
15
|
+
src/opensmi/core/__init__.py
|
|
16
|
+
src/opensmi/core/async_task_mixin.py
|
|
17
|
+
src/opensmi/core/base_server.py
|
|
18
|
+
src/opensmi/core/base_ua_object.py
|
|
19
|
+
src/opensmi/core/config.py
|
|
20
|
+
src/opensmi/core/enums.py
|
|
21
|
+
src/opensmi/core/errors.py
|
|
22
|
+
src/opensmi/core/frozen.py
|
|
23
|
+
src/opensmi/core/hook.py
|
|
24
|
+
src/opensmi/core/lifecycle_mixin.py
|
|
25
|
+
src/opensmi/core/logging.py
|
|
26
|
+
src/opensmi/core/meta.py
|
|
27
|
+
src/opensmi/core/mixin_helpers.py
|
|
28
|
+
src/opensmi/core/protocols.py
|
|
29
|
+
src/opensmi/core/repr_mixin.py
|
|
30
|
+
src/opensmi/core/signal.py
|
|
31
|
+
src/opensmi/core/subscription_manager.py
|
|
32
|
+
src/opensmi/core/ua.py
|
|
33
|
+
src/opensmi/core/ua_enums.py
|
|
34
|
+
src/opensmi/core/ua_node_util.py
|
|
35
|
+
src/opensmi/core/unit_all.py
|
|
36
|
+
src/opensmi/core/unit_base.py
|
|
37
|
+
src/opensmi/core/unset.py
|
|
38
|
+
tests/test_signal.py
|
|
39
|
+
tests/test_unit.py
|
|
40
|
+
tools/auto_generate_units.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"files": [
|
|
3
|
+
".github/workflows/python-publish.yml",
|
|
4
|
+
".gitignore",
|
|
5
|
+
".gitlab-ci.yml",
|
|
6
|
+
"LICENSE",
|
|
7
|
+
"LICENSES/MIT.txt",
|
|
8
|
+
"README.md",
|
|
9
|
+
"pyproject.toml",
|
|
10
|
+
"src/opensmi/core/__init__.py",
|
|
11
|
+
"src/opensmi/core/async_task_mixin.py",
|
|
12
|
+
"src/opensmi/core/base_server.py",
|
|
13
|
+
"src/opensmi/core/base_ua_object.py",
|
|
14
|
+
"src/opensmi/core/config.py",
|
|
15
|
+
"src/opensmi/core/enums.py",
|
|
16
|
+
"src/opensmi/core/errors.py",
|
|
17
|
+
"src/opensmi/core/frozen.py",
|
|
18
|
+
"src/opensmi/core/hook.py",
|
|
19
|
+
"src/opensmi/core/lifecycle_mixin.py",
|
|
20
|
+
"src/opensmi/core/logging.py",
|
|
21
|
+
"src/opensmi/core/meta.py",
|
|
22
|
+
"src/opensmi/core/mixin_helpers.py",
|
|
23
|
+
"src/opensmi/core/protocols.py",
|
|
24
|
+
"src/opensmi/core/repr_mixin.py",
|
|
25
|
+
"src/opensmi/core/signal.py",
|
|
26
|
+
"src/opensmi/core/subscription_manager.py",
|
|
27
|
+
"src/opensmi/core/ua.py",
|
|
28
|
+
"src/opensmi/core/ua_enums.py",
|
|
29
|
+
"src/opensmi/core/ua_node_util.py",
|
|
30
|
+
"src/opensmi/core/unit_all.py",
|
|
31
|
+
"src/opensmi/core/unit_base.py",
|
|
32
|
+
"src/opensmi/core/unset.py",
|
|
33
|
+
"tests/test_signal.py",
|
|
34
|
+
"tests/test_unit.py",
|
|
35
|
+
"tools/auto_generate_units.py"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
opensmi
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 OpenSMI Contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
"""Common functionality for both server and client."""
|
|
6
|
+
|
|
7
|
+
from importlib import metadata
|
|
8
|
+
|
|
9
|
+
from .async_task_mixin import AsyncTaskMixin as AsyncTaskMixin
|
|
10
|
+
from .enums import LifecycleState as LifecycleState
|
|
11
|
+
from .lifecycle_mixin import LifecycleMixin as LifecycleMixin
|
|
12
|
+
from .lifecycle_mixin import lifecycle as lifecycle
|
|
13
|
+
from .logging import LogFormat as LogFormat
|
|
14
|
+
from .logging import setup_logging as setup_logging
|
|
15
|
+
from .signal import Signal as Signal
|
|
16
|
+
from .ua_enums import MachineryItemState as MachineryItemState
|
|
17
|
+
from .ua_enums import MachineryOperationMode as MachineryOperationMode
|
|
18
|
+
from .ua_enums import SkillState as SkillState
|
|
19
|
+
from .unit_all import Unit as Unit
|
|
20
|
+
|
|
21
|
+
__version__ = metadata.version("OpenSMI-Core")
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2026 OpenSMI Contributors
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
|
|
5
|
+
"""Mixin for reliable tracking of fire-and-forget asyncio tasks."""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
from collections.abc import Coroutine
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class AsyncTaskMixin:
|
|
13
|
+
"""Mixin for reliable tracking of fire-and-forget asyncio tasks.
|
|
14
|
+
|
|
15
|
+
Avoids such tasks disappearing while executing when garbage collected
|
|
16
|
+
(https://docs.python.org/3/library/asyncio-task.html#creating-tasks).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
__tasks: set[asyncio.Task[None]] | None = None
|
|
20
|
+
|
|
21
|
+
def _create_task(
|
|
22
|
+
self,
|
|
23
|
+
coro: Coroutine[Any, Any, None], # pyright: ignore[reportExplicitAny]
|
|
24
|
+
*,
|
|
25
|
+
name: str,
|
|
26
|
+
) -> None:
|
|
27
|
+
"""Schedule and track a background coroutine.
|
|
28
|
+
|
|
29
|
+
The coroutine must return ``None``.
|
|
30
|
+
"""
|
|
31
|
+
if self.__tasks is None:
|
|
32
|
+
self.__tasks = set()
|
|
33
|
+
|
|
34
|
+
task = asyncio.create_task(coro, name=name)
|
|
35
|
+
self.__tasks.add(task)
|
|
36
|
+
task.add_done_callback(self.__tasks.discard)
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def _pending_tasks(self) -> set[asyncio.Task[None]]:
|
|
40
|
+
"""Return currently running tracked tasks."""
|
|
41
|
+
if self.__tasks is None:
|
|
42
|
+
return set()
|
|
43
|
+
return self.__tasks.copy()
|
|
44
|
+
|
|
45
|
+
async def _cancel_tasks(self) -> None:
|
|
46
|
+
"""Cancel and await all tracked tasks."""
|
|
47
|
+
if self.__tasks is None:
|
|
48
|
+
return # nothing to cancel
|
|
49
|
+
tasks = self.__tasks.copy()
|
|
50
|
+
|
|
51
|
+
for task in tasks:
|
|
52
|
+
_ = task.cancel()
|
|
53
|
+
|
|
54
|
+
if tasks:
|
|
55
|
+
_ = await asyncio.gather(*tasks, return_exceptions=True)
|