utils : Utility functions¶
MTP File¶
mtppy.utils.mtp_file_handling.mtp_reader.mtp_reader.MtpReader(mtp_path=None)
¶
A class to read and parse MTP files.
This class provides functionality to read MTP files, extract their manifest, and create mappings between aliases and OPC UA node IDs.
Initialize the MtpReader with an optional MTP file path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mtp_path
|
str | Path | None
|
Path to the MTP file to read. If None, no file is read initially but all the public data structured are initialized |
None
|
create_alias_opcua_node_map(data_assemblies, node_ids)
¶
read_mtp(mtp_path)
¶
Read and parse an MTP file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mtp_path
|
str | Path
|
Path to the MTP file to read. |
required |
Returns:
| Type | Description |
|---|---|
ElementTree
|
Parsed XML tree of the manifest |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If file does not exist |
ValueError
|
If file is not readable |
mtppy.utils.mtp_file_handling.mtp_writer.mtp_writer.MtpWriter()
¶
Writer for MTP files.
mtppy.utils.mtp_file_handling.mtp_reader.mtp_xml
¶
Utilities for XML file handling.
get_all_child_attribute_text(elem, node_ids=None)
¶
Get all child attribute texts from an element.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
elem
|
Element
|
The XML element to process. |
required |
node_ids
|
dict[str, str] | None
|
Optional mapping of node IDs to their replacement values. |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict[str, dict[str, str]]
|
Dictionary containing attribute names and values. |
get_child_default_value_text(elem)
¶
get_child_value_text(elem)
¶
get_data_assemblies(root)
¶
get_named_childs_recursive(parent, xpath)
¶
Recursively get named children from an XML element.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parent
|
Element
|
The parent XML element. |
required |
xpath
|
str
|
The XPath expression to find child elements. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict[str, Any]
|
A dictionary of named children and their attributes. |
get_opcua_node_id(root, identifier)
¶
Get OPC UA node ID from an ExternalInterface element.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
root
|
Element
|
The root ElementTree to search. |
required |
identifier
|
str
|
The ID of the ExternalInterface element. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The OPC UA node ID in the format "ns= |
get_opcua_node_ids(root)
¶
get_services(root)
¶
DataItem and DataItemCollection: Data Storage, Access and Callbacks¶
mtppy.utils.data_item.DataItem(name, w3c_xml_data_type, access, init_value=0, description='', external_write_cb=None, internal_write_cb=None)
¶
Represent a scalar typed value hosted by a data-item collection.
A DataItem validates and stores its value according to a W3C XML data type. It can notify an internal callback and any number of external communication observers when its value is written.
The class is hosted by a DataItemCollection, the base class for DataAssembly.
A DataItem is associated with an Attribute of a DataAssembly definition within MTP 2.0.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
DataItem name. |
w3c_xml_data_type |
W3cXmlDataTypes
|
DataItem value type. |
access |
MTPAccess
|
DataItem access mode. |
init_value |
ANY_TYPE
|
Initial, type-corrected value. |
description |
str
|
Human-readable description. |
ext_wrt_cb |
Callable[[ANY_TYPE], None] | None
|
Callback invoked for external writes. |
int_wrt_cb |
Callable[[ANY_TYPE], None] | None
|
Callback invoked for internal writes. |
communication_objects |
list[CommunicationObject]
|
External communication observers notified on value writes. |
comm_obj |
CommunicationObject | None
|
Backwards-compatible alias for the first communication observer. |
_value |
ANY_TYPE
|
Current type-corrected value. |
_is_notifying |
bool
|
Whether an internal notification is in progress. |
Initialize a DataItem.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Name of the data item. |
required |
w3c_xml_data_type
|
W3cXmlDataTypes
|
W3C XML type used to convert assigned values. |
required |
access
|
MTPAccess
|
Access mode for the data item. |
required |
init_value
|
ANY_TYPE | None
|
Initial value. |
0
|
description
|
str
|
Human-readable description. |
''
|
external_write_cb
|
Callable[[ANY_TYPE], None] | None
|
Callback for external writes received through the data item. |
None
|
internal_write_cb
|
Callable[[ANY_TYPE], None] | None
|
Callback for internal writes to the data item. |
None
|
Raises:
| Type | Description |
|---|---|
TypeError
|
If |
comm_obj
property
writable
¶
Return the first communication object, if one is attached.
Returns:
| Type | Description |
|---|---|
CommunicationObject | None
|
The first attached observer, or |
attach_communication_object(communication_object)
¶
Attach an external communication observer.
Duplicate observers are ignored. Observers are notified in attachment order whenever the DataItem is written.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
communication_object
|
CommunicationObject
|
Communication object that exposes this DataItem to an external client. |
required |
get_value()
¶
Return the current value of the DataItem.
Returns:
| Type | Description |
|---|---|
ANY_TYPE
|
The current value, already converted to the DataItem's |
ANY_TYPE
|
pythonic |
get_value_str()
¶
Return a human-readable string representation of the DataItem.
Returns:
| Type | Description |
|---|---|
str
|
A string of the form |
set_value(value, notify_external=True, source_observer=None)
¶
Set the value and notify external subscribers except its source.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
ANY_TYPE
|
Value to convert, store, and publish. |
required |
notify_external
|
bool
|
Whether to notify attached communication observers. |
True
|
source_observer
|
CommunicationObject | None
|
Observer that supplied |
None
|
write_value(value)
¶
Set the local value and publish it to the communication nodes, without invoking the external write callback.
This is the server-side half of an external handshake: it stores
value locally (most often a reset to 0) and pushes it to the
attached communication nodes so that external clients observe the
change, but it does NOT call :attr:ext_wrt_cb. That callback is the
entry point for writes coming from an external client, so invoking
it here would make the PEA react to its own handshake. On OPC UA the
communication object additionally suppresses the datachange event that
the server's own self-subscription would otherwise fire, which would
call :attr:ext_wrt_cb with the new value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
ANY_TYPE
|
Value to store locally and publish to the nodes. |
required |
mtppy.utils.data_item.DataItemCollection()
¶
Bases: MutableMapping[str, DataItem]
Key-immutable, dict-like container of DataItem instances.
The collection is populated at construction time from the ClassVar
CLASS_DATA_ITEMS mapping declared statically on the owning class
(and all of its bases in MRO order). Each entry is deep-copied so that two
collections derived from the same class do not share DataItems.
The collection supports both mapping-style (da["WQC"]) and
attribute-style (da.WQC) access to the current value of
a DataItem.
Both the dict-keys and the attributes of the class are immutable, that is
a lhs da["NEW"] does not add a new entry with key "NDW" to the
DataItemCollection. The same is true for lhs da.new or self.new - this
hardens the class against typos.
Note
In cases where the SNAKE_CASE string holding constant is not distinguishable from the CamelCase PNO MTP 2.0 name, our best practice is to have the constant name end with an , e.g. WQC, P_, PV_
Attention
The collection is key-immutable and attribute-immutable. Setting an unknown
key or attribute raises KeyError, while reading an unknown
attribute raises AttributeError. Consequently,
hasattr(collection, name) returns False for missing attributes,
as it does for normal Python objects.
Initialize the collection from the class-level CLASS_DATA_ITEMS.
Walks the class MRO in reverse order so that base-class entries are inserted first and subclass entries take precedence on duplicate keys. Each declared data item is deep-copied to avoid shared state between instances.
attach_loop(loop)
¶
Bind this collection to the run-task event loop of its service.
Once bound, every write made from a foreign thread is scheduled onto that loop so that all mutations happen on the single run task (the single-writer principle). Writes made from the run task itself execute inline. Collections that are never bound keep the legacy synchronous, inline behaviour.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loop
|
AbstractEventLoop
|
The running event loop owned by the service's run task. |
required |
attach_wake(wake_fn)
¶
Register the run-task wake callable for this collection.
When a guarded write (e.g. a service op-mode or command change) is
scheduled onto the bound loop from a foreign thread, the owning
service's run task may be parked in the offline undefined state.
Registering its wake callable lets such a write release that wait
immediately instead of waiting out the next poll interval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
wake_fn
|
Callable[[], None]
|
Zero-argument callable that signals the run task to wake. |
required |
get_item(key)
¶
Access the underlying DataItem for introspection.
Unlike __getitem__, this returns the full DataItem object
instead of only its current value, allowing callers to inspect or
modify attributes such as the data type, access mode or
subscription callback.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The data item name. |
required |
Returns:
| Type | Description |
|---|---|
DataItem
|
The DataItem instance registered |
DataItem
|
under |
items()
¶
keys()
¶
run_on_loop(fn)
¶
Run fn on the bound loop, deferring from foreign threads.
This is the single-writer primitive. Three cases:
- No bound loop -> run
fninline (unbound / test / offline). - Caller already on the bound loop -> run
fninline (avoids a re-post loop for nested / cascade writes fired inside a posted operation). - Caller on a foreign thread -> schedule
fnvialoop.call_soon_threadsafeso it runs on the run task.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fn
|
Callable[[], None]
|
Zero-argument callable that mutates this collection. |
required |
logging¶
mtppy.utils.logging
¶
predefined logging levels for the MTPPy2.0 framework.
setLogLevel(log_level)
¶
Set the root logger level from a numeric value or level name.
testing¶
mtppy.utils.testing
¶
testing provides repeated pieces of codes used in testing.
data_object_set_modes(instance, init_op_mode, init_src_mode)
¶
Set initial mode of ActiveElement instance to a certain state.
General utility functions¶
The utils module delivers some general helper functions that have their own use independent of the MTP application.
Conversion of Automation Types¶
utils.type_conversion
¶
type_conversion collects utility functions that cast values to basic types used in automation.
OPC UA, MTP, IEC 61131 and other automation standards have quite specialized data types, which are not always directly supported by Python, for instance signed/unsigned integer types of different sizes (UNSIGNED SHORT != SHORT, INT != SHORT), or strings with a maximum length.
The collected functions help to convert/cast values to the appropriate python types, ensuring compatibility with these standards.
cast_to_bool(value)
¶
Casts canonical boolean values without treating arbitrary strings as true.
cast_to_byte(value)
¶
Casts value to byte, ensuring it falls within the range of INT8_MIN to INT8_MAX (-128 to 127).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
SupportsInt
|
The value to be cast to a byte. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The byte representation of the value, clamped to the valid range. |
cast_to_int(value)
¶
Casts a value to an integer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
SupportsInt
|
The value to be cast to an integer. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The integer representation of the value. |
cast_to_long(value)
¶
Casts value to long integer, ensuring it falls within the range of INT64_MIN to INT64_MAX (-9223372036854775808 to 9223372036854775807).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
SupportsInt
|
The value to be cast to a long integer. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The signed integer representation of the value, clamped to the valid range. |
cast_to_short(value)
¶
Casts a value to a short integer, ensuring it falls within the range of -32768 to 32767.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
SupportsInt
|
The value to be cast to a short integer. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The signed short integer representation of the value, clamped to the valid |
int
|
range. |
cast_to_string(value, max_len=None)
¶
Casts a value to a string, optionally truncating it to a maximum length.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
object
|
The value to be cast to a string. |
required |
max_len
|
SupportsIndex | None
|
The maximum length of the resulting string. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The string representation of the value, optionally truncated. |
cast_to_ubyte(value)
¶
Casts value to unsigned byte, ensuring it falls within the range of 0 to UINT8_MAX (255).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
SupportsInt
|
The value to be cast to an unsigned byte. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The unsigned byte representation of the value, clamped to the valid range. |
cast_to_uint(value)
¶
Casts a value to an unsigned integer, ensuring it falls within the range of 0 to 4294967295.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
SupportsInt
|
The value to be cast to an unsigned integer. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The unsigned integer representation, clamped to the valid range. |
cast_to_ulong(value)
¶
Casts value to unsigned long integer, ensuring it falls within the range of 0 to UINT64_MAX (18446744073709551615).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
SupportsInt
|
The value to be cast to an unsigned long integer. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The unsigned long integer representation, clamped to the valid range. |
cast_to_ushort(value)
¶
Casts value to unsigned short integer, ensuring it falls within the range of 0 to 65535.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
SupportsInt
|
The value to be cast to an unsigned short integer. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The unsigned short integer representation, clamped to the valid range. |
clamp(value, limit, reset=None)
¶
Clamp a value between a lower and an upper bound.
When value is below the lower bound or above the upper bound, it is
replaced by the corresponding element of reset. If reset is not
provided, the bounds themselves are used as the replacement values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
float
|
The value to clamp. |
required |
limit
|
tuple[float, float]
|
A |
required |
reset
|
tuple[float, float] | None
|
An optional |
None
|
Returns:
| Type | Description |
|---|---|
float
|
The clamped value, or the matching fallback bound. |
Example
clamp(value,[0,100],[0,0]) - generates a saw-tooth when fed with a ramp clamp(value,[0,0]) - clamps the value between upper and lower bound
logging¶
utils.logging.CustomLogger(name, level=logging.NOTSET)
¶
Bases: Logger
Custom logger class that allows adding custom logging levels.
The levels are between the standard logging levels INFO and WARNING. The logger is configured to display the timestamp, log level, thread, module, function name, and message in the log output.
Example
Initialize a logger with the standard logging constructor.
add_custom_level(level_name, level_value)
¶
Register one custom level name without modifying the logger API.
add_custom_levels(custom_levels)
¶
Register level names using offsets from logging.INFO.
The logger methods are explicit and are not generated dynamically. This keeps the framework API visible to static type checkers.
app(msg, *args, **kwargs)
¶
Log a message at the application level.
mtp(msg, *args, **kwargs)
¶
Log a message at the MTP level.
opcua(msg, *args, **kwargs)
¶
Log a message at the OPC UA level.
pol(msg, *args, **kwargs)
¶
Log a message at the POL level.