Part 6: Alarms and Events¶
MTPPy2.0 implements an initial, code-based subset of the
ModuleTypePackage:AlarmSet.Base profile. The implementation describes static
alarm metadata in the generated MTP. Alarm condition evaluation remains the
responsibility of the Process Orchestration Layer (POL).
Scope¶
| Capability | Status |
|---|---|
Public static Alarm model |
Implemented |
Registration with PEA.add_alarm() |
Implemented |
AlarmSet.Base CAEX alarm description |
Implemented as an initial subset |
AlarmGroup |
Generated internally, one group per referenced DataAssembly instance |
AlarmMessage and AlarmText |
One static text per alarm |
| Boolean, integer, and string equality trigger | Implemented |
| Alarm condition evaluation | POL responsibility; not implemented in the PEA |
| Events | Not implemented |
| PEA-managed alarms and alarm runtime state | Not implemented |
| OPC UA Alarms & Conditions | Not implemented |
“Implemented” in this table means that the repository tests the described API
and generator behavior. It does not claim complete AlarmSet.Base or Part 6
conformance.
Public model and registration contract¶
Alarm is the only public Part 6 model. There are no
public Python AlarmSet or AlarmGroup classes in this first implementation.
The generator derives the CAEX AlarmGroup, AlarmMessage, and AlarmText
objects from each registered Alarm.
Alarm field |
Contract |
|---|---|
tag_name |
Non-empty text and unique within PEA.alarms |
data_assembly |
Existing DataAssembly instance |
trigger |
Direct DataItem member of that exact DataAssembly instance |
trigger_value |
Exact Python type and valid value range of the trigger DataItem |
message |
Non-empty static operator text |
ack_required |
Exact bool; exported as metadata only |
severity |
Exact int in the inclusive range from 1 through 1000 |
The exact DataAssembly instance must be reachable through an existing PEA
registration and serialization path, for example directly through
PEA.add_data_assembly() or as a service-owned DataAssembly through
PEA.add_service(). PEA.add_alarm() does not register it implicitly and
rejects non-Alarm objects and duplicate alarm tag names. A reference to an
unregistered DataAssembly is rejected when the MTP is generated, rather than
emitting a dangling AlarmGroup.RefID.
The alarm itself is an immutable dataclass. Its referenced DataAssembly and
DataItem remain mutable, so the generator calls Alarm.validate() again before
serialization. This prevents a DataItem type or membership change made after
alarm construction from producing invalid alarm metadata.
Supported trigger types¶
xs:booleanxs:stringxs:byte,xs:unsignedBytexs:short,xs:unsignedShortxs:int,xs:unsignedIntxs:long,xs:unsignedLong
Every integer trigger is checked against the range of its concrete W3C XML type.
Python bool is not accepted as an integer. Float, double, date/time, URI, token,
multiple-trigger expressions, and comparison operators other than equality with
TriggerValue are not supported.
Code-based example¶
The trigger DataAssembly must be registered with the PEA. Use get_item() to
pass the DataItem itself; mapping access such as level_high[BinView.V_] returns
only its current value.
from mtppy.part3.data_assembly_set.indicator_elements.views.bin_view import BinView
from mtppy.part6.alarm_set.alarm import Alarm
from mtppy.pea.pea import PEA
pea = PEA()
level_high = BinView("LevelHigh")
pea.add_data_assembly(level_high)
pea.add_alarm(
Alarm(
tag_name="LevelHigh.Alarm",
data_assembly=level_high,
trigger=level_high.get_item(BinView.V_),
trigger_value=True,
message="Level is too high.",
ack_required=True,
severity=500,
)
)
The complete executable registration example is available in
examples/pea_alarm_base.py.
The example builds the Python model and registers the alarm. It deliberately does not start runtime services or connect to an external device. Manifest generation is covered by the generator tests.
Generator behavior¶
The implementation follows this sequence:
- Revalidate every registered alarm and reserve one CAEX ID per trigger DataItem object.
- Serialize registered DataAssemblies and add that ID to each alarm trigger attribute.
- Create exactly one CAEX
AlarmGroupfor each referenced DataAssembly object. Its generated name is<DataAssembly.tag_name>_AlarmGroupand is not configurable. Multiple alarms referencing the same object share the group. - Create one
AlarmMessagecontaining oneAlarmTextfor every alarm. - Create the
Alarminside its generated group and resolveRefID,Trigger, andMessageRef. - Reject missing DataAssembly or trigger targets instead of serializing dangling links.
If the same DataAssembly object is registered through more than one existing
PEA path, the alarm mapping retains the first serialized DataAssembly reference.
This keeps AlarmGroup.RefID and Alarm.Trigger within the same serialized
object graph.
flowchart LR
Registry[PEA.alarms] --> Generator[MTPGenerator]
Generator --> Group[AlarmGroup]
Generator --> AlarmElement[Alarm]
Generator --> Message[AlarmMessage / AlarmText]
Group -- RefID --> Assembly[DataAssembly]
AlarmElement -- Trigger --> Item[DataItem attribute ID]
AlarmElement -- MessageRef --> Message
AlarmElement -- TriggerValue --> Equality[POL equality evaluation]
Generated CAEX mapping¶
| Generated object or attribute | CAEX type or reference type | Value or target |
|---|---|---|
AlarmGroup |
MTPAlarmSUCLib/AlarmGroup |
One per referenced DataAssembly object |
AlarmGroup.RefID |
MTPATLib/IDReferenceType/RefIDAttributeType |
DataAssembly RefID |
Alarm |
MTPAlarmSUCLib/Alarm |
One per registered alarm |
AckRequired |
xs:boolean |
Static alarm metadata |
Severity |
xs:short |
Integer from 1 through 1000 |
Trigger |
MTPATLib/IDReferenceType/IDLinkAttributeType, xs:string |
CAEX ID of the trigger DataItem attribute |
TriggerValue |
Concrete xs:* type of the DataItem |
Equality value evaluated by the POL |
Classification |
AutomationMLBaseAttributeTypeLib/OrderedListType |
Empty container; values are not implemented |
MessageRef |
MTPTextATLib/TextRefAttributeType, xs:string |
CAEX ID of the AlarmMessage |
AlarmMessage |
MTPTextSUCLib/TextDefinition/AlarmMessage |
Container generated per alarm |
AlarmText |
MTPTextSUCLib/TextDefinition/AlarmMessage/AlarmText |
Contains one static Text attribute |
Generic AutomationML role requirements are appended to the generated group,
alarm, message, and text objects. No AlarmMgmt, AlarmMgmtRef, IsManaged, or
other Managed-alarm instance is generated.
The generated names are <alarm.tag_name> message for AlarmMessage and
<alarm.tag_name>.Text for AlarmText.
The trigger DataItem attribute follows the existing generic serializer and
remains xs:string for both static and linked values. If a PEA-hosted OPC UA
node exists, its RefAttributeType and Value additionally form the existing
ID link. The alarm value type belongs to TriggerValue, which therefore carries
the concrete Boolean, integer, or string W3C type.
Runtime and OPC UA boundary¶
Alarm registration affects only manifest generation. It does not install
DataItem callbacks, evaluate conditions, or change the PEA runtime path.
AckRequired is metadata for the POL; it does not add an acknowledgement method
or state to the Python object.
No separate alarm OPC UA node is created, and this feature does not connect to external OPC UA devices. If the existing PEA OPC UA server is initialized, the trigger DataItem keeps its normal link to the node hosted by that PEA server. The alarm adds only the CAEX trigger reference. The alarm implementation neither starts that server nor acts as an OPC UA client, and it does not read or subscribe to nodes. Without a started PEA server, the alarm remains a static MTP description.
Verification¶
The implementation is covered at four levels:
- model tests for all fields, supported types, integer ranges, invalid values, DataItem ownership, and the absence of runtime callbacks;
- PEA tests for registration, wrong types, and duplicate names;
- generator tests for CAEX paths, reference targets, grouping, revalidation,
multiple DataAssembly serialization paths, and Boolean/integer/string
TriggerValuetypes; - a smoke test for the executable registration example.
The dedicated GitLab job runs the collocated src/mtppy/part6 tests and includes
their coverage artifact in the combined report. A complete implementation and
test inventory is available in the
Part 6 implementation summary.
Open Part 6 TODOs¶
These TODOs are deliberately documented but not implemented in the first static port.
| ID | Open work | Why it remains open |
|---|---|---|
P6-TODO-01 |
Verify and conditionally emit the Part 6 profile declarations in AdditionalInformation. |
The shared template already advertises ModuleTypePackage:AlarmSet.Managed although no Managed content is generated. Changing shared template policy was outside the focused port. |
P6-TODO-02 |
Perform a normative AlarmSet.Base review using the official specification and reference MTPs. |
Repository tests prove the implemented contract, not complete profile conformance. CAEX-XSD validity alone would also not prove MTP semantic conformance. |
P6-TODO-03 |
Introduce explicit public AlarmSet/AlarmGroup models if required. |
The minimal API derives one fixed-name group per DataAssembly and cannot express custom names or multiple groups for one assembly. |
P6-TODO-04 |
Add populated alarm classifications. | The serializer currently emits only the ordered-list container defined by the repository template; classification terminology and public ownership need a target-native model and normative confirmation. |
P6-TODO-05 |
Add multilingual alarm messages and default-language behavior. | The first port intentionally uses one static text. A shared TextSet/language API is needed before adding fallback semantics. |
P6-TODO-06 |
Support nested BaseFunction triggers, further data types, and richer conditions where the specification permits them. | The current ownership rule deliberately accepts one direct Boolean, integer, or string DataItem and one equality value. |
P6-TODO-07 |
Implement Part 6 events. | The current public package exports only Alarm; event identity, payload, lifecycle, and serialization require a separate design. |
P6-TODO-08 |
Design and implement PEA-managed alarms. | AlarmMgmt, state/command encoding, acknowledgement, reset, delays, shelving, suppression, quality, lifecycle, thread safety, and callback fan-out require new target-native runtime infrastructure. |
P6-TODO-09 |
Add Part 6 import, factory, and round-trip support if required by downstream tooling. | The first increment covers code-based construction and export only. |