OpenSMI-Core 0.2__tar.gz → 0.2.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.
Files changed (45) hide show
  1. {opensmi_core-0.2 → opensmi_core-0.2.1}/PKG-INFO +1 -1
  2. opensmi_core-0.2.1/README.md +49 -0
  3. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/OpenSMI_Core.egg-info/PKG-INFO +1 -1
  4. opensmi_core-0.2.1/src/OpenSMI_Core.egg-info/scm_version.json +8 -0
  5. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/ua_node_util.py +22 -9
  6. opensmi_core-0.2/README.md +0 -2
  7. opensmi_core-0.2/src/OpenSMI_Core.egg-info/scm_version.json +0 -8
  8. {opensmi_core-0.2 → opensmi_core-0.2.1}/.github/workflows/api-docs.yml +0 -0
  9. {opensmi_core-0.2 → opensmi_core-0.2.1}/.github/workflows/python-publish.yml +0 -0
  10. {opensmi_core-0.2 → opensmi_core-0.2.1}/.gitignore +0 -0
  11. {opensmi_core-0.2 → opensmi_core-0.2.1}/.gitlab-ci.yml +0 -0
  12. {opensmi_core-0.2 → opensmi_core-0.2.1}/LICENSE +0 -0
  13. {opensmi_core-0.2 → opensmi_core-0.2.1}/LICENSES/MIT.txt +0 -0
  14. {opensmi_core-0.2 → opensmi_core-0.2.1}/pyproject.toml +0 -0
  15. {opensmi_core-0.2 → opensmi_core-0.2.1}/setup.cfg +0 -0
  16. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/OpenSMI_Core.egg-info/SOURCES.txt +0 -0
  17. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/OpenSMI_Core.egg-info/dependency_links.txt +0 -0
  18. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/OpenSMI_Core.egg-info/requires.txt +0 -0
  19. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/OpenSMI_Core.egg-info/scm_file_list.json +0 -0
  20. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/OpenSMI_Core.egg-info/top_level.txt +0 -0
  21. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/__init__.py +0 -0
  22. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/async_task_mixin.py +0 -0
  23. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/base_server.py +0 -0
  24. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/base_ua_object.py +0 -0
  25. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/config.py +0 -0
  26. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/enums.py +0 -0
  27. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/errors.py +0 -0
  28. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/frozen.py +0 -0
  29. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/hook.py +0 -0
  30. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/lifecycle_mixin.py +0 -0
  31. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/logging.py +0 -0
  32. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/meta.py +0 -0
  33. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/mixin_helpers.py +0 -0
  34. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/protocols.py +0 -0
  35. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/repr_mixin.py +0 -0
  36. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/signal.py +0 -0
  37. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/subscription_manager.py +0 -0
  38. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/ua.py +0 -0
  39. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/ua_enums.py +0 -0
  40. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/unit_all.py +0 -0
  41. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/unit_base.py +0 -0
  42. {opensmi_core-0.2 → opensmi_core-0.2.1}/src/opensmi/core/unset.py +0 -0
  43. {opensmi_core-0.2 → opensmi_core-0.2.1}/tests/test_signal.py +0 -0
  44. {opensmi_core-0.2 → opensmi_core-0.2.1}/tests/test_unit.py +0 -0
  45. {opensmi_core-0.2 → opensmi_core-0.2.1}/tools/auto_generate_units.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenSMI-Core
3
- Version: 0.2
3
+ Version: 0.2.1
4
4
  Summary: Smart Machine Interface core functionality for server and client applications.
5
5
  Author-email: Carsten Harms <Carsten.Harms@dfki.de>, Simon Jungbluth <Simon.Jungbluth@smartfactory.de>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -0,0 +1,49 @@
1
+ ![OpenSMI Logo](https://smartfactory.de/wp-content/uploads/2026/09/Logo_OpenSMI.png)
2
+
3
+ [![Docs](https://img.shields.io/badge/docs-online-blue)](https://smartfactory-kl.github.io/opensmi-core/)
4
+ [![PyPI version](https://img.shields.io/pypi/v/opensmi-core.svg)](https://pypi.org/project/opensmi-core/)
5
+ [![Python versions](https://img.shields.io/pypi/pyversions/opensmi-core.svg)](https://pypi.org/project/opensmi-core/)
6
+ [![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
7
+
8
+ # OpenSMI Core
9
+
10
+ Core functionality for other OpenSMI packages such as:
11
+
12
+ - [OpenSMI Client](https://github.com/SmartFactory-KL/opensmi-client)
13
+ - [OpenSMI Server](https://github.com/SmartFactory-KL/opensmi-server)
14
+
15
+ ## Features
16
+
17
+ - (Nested) Configuration parsing into dataclasses from TOML files (See [config.py](src/opensmi/core/config.py))
18
+ - Lifecycle management via mixin and `@lifecycle` decorators, allowing explicit ordering
19
+ (See [lifecycle_mixin.py](src/opensmi/core/lifecycle_mixin.py))
20
+ - Simple callbacks via `Signal` (similar to [aiosignal](https://pypi.org/project/aiosignal/), but without freezing)
21
+ (See [signal.py](src/opensmi/core/signal.py))
22
+ - [asyncua](https://pypi.org/project/asyncua/) (OPC UA) helpers
23
+ - Node helper functions (See [ua_node_util.py](src/opensmi/core/ua_node_util.py))
24
+ - SubscriptionManager (See [subscription_manager.py](src/opensmi/core/subscription_manager.py))
25
+ - Enums for OpenSMI machine, component and skill states
26
+ - All [UN/CEFACT-Rec20](https://unece.org/trade/documents/2021/06/uncefact-rec20-0) units as a type-checkable enum.
27
+ (See [unit_all.py](src/opensmi/core/unit_all.py))
28
+ - [Structured Logging](https://pypi.org/project/structlog/) configuration (See [logging.py](src/opensmi/core/logging.py))
29
+
30
+ > [!warning]
31
+ > This library is currently pre-1.0 — expect refactoring outside above-mentioned functionality.
32
+
33
+ ## Installation
34
+
35
+ Requires Python 3.11+.
36
+
37
+ ```bash
38
+ pip install opensmi-core
39
+ ```
40
+
41
+ ## Project Status
42
+
43
+ OpenSMI began as a closed-source project at [SmartFactory-KL](https://smartfactory.de/), in active use in our model
44
+ factory since 2020. Its OPC UA information model has been refined across many iterations of research and
45
+ demonstrator use. The framework was open-sourced in 2026 following substantial refactoring and cleanup.
46
+
47
+ ## License
48
+
49
+ [MIT License](LICENSE)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: OpenSMI-Core
3
- Version: 0.2
3
+ Version: 0.2.1
4
4
  Summary: Smart Machine Interface core functionality for server and client applications.
5
5
  Author-email: Carsten Harms <Carsten.Harms@dfki.de>, Simon Jungbluth <Simon.Jungbluth@smartfactory.de>
6
6
  Classifier: Development Status :: 4 - Beta
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "0.2.1",
3
+ "distance": 0,
4
+ "node": "ga8edabe8cc0987a9434f135a0b149bc312ad6458",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-10-06"
8
+ }
@@ -65,7 +65,7 @@ async def write_value(node: Node, value: Any, *, variant_type: ua.VariantType |
65
65
  try:
66
66
  if isinstance(value, ua.Variant):
67
67
  await _write_value(node, value, variant_type=value.VariantType)
68
- if variant_type is not None:
68
+ elif variant_type is not None:
69
69
  await _write_value(node, value, variant_type=variant_type)
70
70
  else:
71
71
  # we need to figure out the correct variant type to use ourselves
@@ -178,16 +178,29 @@ def get_node_id(
178
178
  return ua.NodeId(Identifier=identifier, NamespaceIndex=ua.Int16(ns_idx))
179
179
 
180
180
 
181
- async def get_child_without_ns(parent: Node, *, display_name: str) -> Node:
182
- """Return the first child node with given display name while ignoring the namespace index.
181
+ async def get_child_without_ns(parent: Node, *, browse_name: str | None = None, display_name: str | None = None) -> Node:
182
+ """Return the first child node with given ``browse_name`` or ``display_name`` while ignoring namespaces.
183
183
 
184
- :raises BadNoMatch: If no child with given display name exists.
184
+ For each child, ``BrowseName`` is matched first, ``DisplayName`` afterward. If both are given, a child matching
185
+ either one is returned.
186
+
187
+ :param parent: OPC UA parent node.
188
+ :param browse_name: OPC UA ``BrowseName.Name`` content to compare against. ``NamespaceIndex`` is ignored.
189
+ :param display_name: OPC UA ``DisplayName.Text`` content to compare against. ``Locale`` is ignored.
190
+
191
+ :raises ValueError: If neither ``browse_name`` nor ``display_name`` is given.
192
+ :raises BadNoMatch: If no child with given browse name or display name was found.
185
193
  """
186
- for child in await parent.get_children():
187
- child_display_name = (await child.read_display_name()).Text
188
- # print(parent.nodeid.to_string(), display_name, child_display_name)
189
- if child_display_name == display_name:
190
- return child
194
+ if browse_name is None and display_name is None:
195
+ msg = "Either browse_name or display_name must be set"
196
+ raise ValueError(msg)
197
+
198
+ for ref in await parent.get_children_descriptions():
199
+ if browse_name is not None and ref.BrowseName.Name == browse_name:
200
+ return Node(session=parent.session, nodeid=ref.NodeId)
201
+ if display_name is not None and ref.DisplayName.Text == display_name:
202
+ return Node(session=parent.session, nodeid=ref.NodeId)
203
+
191
204
  raise ua.uaerrors.BadNoMatch
192
205
 
193
206
 
@@ -1,2 +0,0 @@
1
- # OpenSMI Common
2
-
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "0.2",
3
- "distance": 0,
4
- "node": "g90c7c0325f86ebe6f93c7c832b29f4672c03faa6",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-09-23"
8
- }
File without changes
File without changes
File without changes
File without changes
File without changes