Part 6 AlarmSet.Base implementation summary¶
Purpose and result¶
This document summarizes the first MTPPy2.0 alarm increment. The change adds a
deliberately limited, static subset of ModuleTypePackage:AlarmSet.Base. It
provides a code-based Alarm model, PEA registration, and CAEX export for
POL-evaluated equality alarms.
The implemented feature belongs exclusively to Part 6. Existing PEA and
MTPGenerator files are touched only as integration points. The change does not
implement or change Part 1, Part 3, or Part 5 functionality, an external OPC UA
device connection, or a PEA-side alarm runtime. The Part 1, Part 3, and Part 5
documentation is updated only to record inherited problems, test findings, and
decisions that gate or were observed while verifying the Part 6 work.
The implementation was designed after reviewing the MIT-licensed MTPPy1.0
feature/asyncua-migration work around commit 4b7a192. It was reimplemented
for the MTPPy2.0 object model and existing TU Dresden manifest template rather
than cherry-picked. Managed-alarm runtime code and incompatible serializer paths
from the source branch were not ported.
Implemented vertical slice¶
| Layer | Result |
|---|---|
| Public Part 6 API | Immutable Alarm description with explicit validation |
| PEA integration | Typed PEA.alarms registry and PEA.add_alarm() |
| Trigger contract | One direct Boolean, integer, or string DataItem plus one equality value |
| CAEX grouping | One generated AlarmGroup per referenced DataAssembly object |
| CAEX alarm | AckRequired, Severity, Trigger, TriggerValue, empty Classification, and MessageRef |
| Text export | One generated AlarmMessage containing one static AlarmText |
| Reference safety | Registered-target checks, UUID links, revalidation, and alarm-link consistency when one DataAssembly is serialized repeatedly |
| Runtime | No condition evaluation, callbacks, alarm state, or acknowledgement behavior |
| OPC UA | Part 6 adds and uses no client or external-device connection; an existing PEA-hosted node link is preserved if present, and the unrelated standalone node-check helper remains unchanged |
The exact field contracts, generated class paths, reference types, and open items are documented in the Part 6 description.
TDD sequence (development snapshot, 2026-08-19)¶
The implementation was developed test-first.
- The Part 6 model, PEA registry, generator, and example tests were added before their implementation.
- The first focused collection produced three errors because
mtppy.part6.alarmdid not yet exist. - The example smoke test separately failed because
examples/pea_alarm_base.pydid not yet exist. - The minimum model, registration, generator, and example code was added until the focused tests passed.
- Review-driven tests then covered concrete W3C integer limits, generator-time revalidation, Boolean/integer/string XML typing, shared groups, complete reference targets, and the PEA-hosted server-link representation.
- A final regression test reproduced a mismatch between AlarmGroup and Trigger targets when one DataAssembly object was serialized through two existing PEA paths. It failed before the mapping retained the first DataAssembly reference and passed afterwards.
The local commit sequence at the time of this snapshot preserves the main red-to-green boundary:
| Commit | Purpose |
|---|---|
5f09041 |
Tests and GitLab Part 6 job; intentionally red without implementation |
b1a756e |
Static AlarmSet.Base model, integration, serialization, and example |
6af18a0 |
Initial specification, API, architecture, and navigation documentation |
55ba207 |
New-file whitespace correction found by the overall diff check |
Verification evidence (2026-08-19)¶
| Check | Result |
|---|---|
| Dedicated Part 6 CI command | 45 tests passed; 95% directory coverage |
| Final targeted selection covering Part 6, PEA, generator, and example | 57 tests passed |
| Final full repository suite | 1160 tests passed; one existing Part 3 timing test failed |
| Existing failure | MonBinVlv.test_dynamic_error_reset[op-man-set_reset_op]; one isolated rerun reproduced it, with no Part 3 file changed by this work |
| Final duplicate-DataAssembly regression | Failed before the one-line mapping fix, then passed |
| Ruff on every completely new Python file | Passed |
| Zensical documentation build | No issues found |
| Git diff whitespace check | Passed |
| Complete CAEX-XSD validation | Not claimed; an alarm-free baseline already fails the existing root-child order |
| GitLab pipeline | Pending at the time of writing; the dedicated Part 6 and targeted local commands passed, while the full suite has the separately documented Part 3 failure |
No unrelated existing Ruff finding or test failure was changed. The final alarm-focused suite was rerun after the last alarm code correction. An earlier full-suite run before the final alarm-only regression had passed all 1160 tests; the later Part 3 result is timing-sensitive and outside this change scope.
Created files (8)¶
| File | Purpose |
|---|---|
docs/developer/API/part6.md |
Mkdocstrings entry point and public API boundary |
docs/developer/alarming_implementation.md |
This implementation, verification, and file inventory |
docs/specification/part6.md |
Detailed Part 6 scope, mapping, runtime boundary, and open TODOs |
examples/pea_alarm_base.py |
Executable static alarm registration example |
src/mtppy/part6/__init__.py |
Part 6 package |
src/mtppy/part6/alarm_set/alarm.py |
Static Alarm model and validation rules |
src/mtppy/part6/alarm_set/alarm_test.py |
Model, type, range, ownership, and callback tests |
src/mtppy/pea/pea_test.py |
PEA alarm registration and duplicate-name tests |
Modified files (13)¶
| File | Part 6 reason for the change |
|---|---|
.gitlab-ci.yml |
Adds the dedicated Part 6 unit-test/coverage job and combines its artifact |
README.md |
Reports the initial static Part 6 subset and Managed limitation |
docs/architecture.md |
Adds Alarm fields, PEA ownership, generated-object relationships, and runtime boundary |
docs/index.md |
Changes Part 6 from out of scope to partially implemented and distinguishes its OPC UA boundary from the existing standalone client helper |
docs/specification/part1.md |
Records existing manifest and generic DataItem serializer TODOs that gate stronger Part 6 export claims; no Part 1 code changes |
docs/specification/part3.md |
Records the MonBinVlv timing/reset failure observed in the full suite and one isolated rerun; no Part 3 code changes |
docs/specification/part5.md |
Records the existing standalone client helper and communication decisions required only for future Managed alarms; no Part 5 code changes |
docs/specification/index.md |
Links the Part 6 status page, distinguishes Base from Managed alarms, and clarifies the Part 6 OPC UA boundary |
src/mtppy/pea/mtp_generator/mtp_generator.py |
Adds only the Part 6 trigger IDs, grouping, alarm/text objects, and reference serialization |
src/mtppy/pea/mtp_generator/mtp_generator_test.py |
Adds Part 6 CAEX integration and regression tests |
src/mtppy/pea/pea.py |
Adds the typed Part 6 registry and add_alarm() integration method |
tests/test_examples.py |
Adds the Part 6 example smoke test |
zensical.toml |
Adds Part 6 specification, API, and implementation-summary navigation |
Intentionally unchanged functionality¶
- No PEA-side alarm condition evaluator or alarm state.
- No acknowledge, reset, delay, shelving, suppression, history, or persistence.
- No public AlarmSet or AlarmGroup Python model.
- No multilingual text or populated classification model.
- No Part 6 event model.
- No OPC UA Alarms & Conditions implementation.
- No OPC UA client or external-device connection was added to or used by the Part 6/PEA alarm path; the existing standalone node-check helper is unchanged.
- No global rewrite of the existing DataAssembly serializer.
- No Managed-alarm instance elements, roles, or references.
- No import, factory, or round-trip support.
Open work and inherited dependencies¶
The TODOs are maintained in the part description that owns the work: direct alarm features under Part 6.
Part 5. The unrelated full-suite failure is tracked under Part 3.
The most important boundaries are:
- The shared manifest template already declares
ModuleTypePackage:AlarmSet.Managed, despite the absence of Managed content. Profile declarations should become feature-dependent after their normative identifiers are confirmed. - Complete generated manifests already violate the bundled CAEX 3.0 root-child order because InstanceHierarchies are appended after the class libraries. This also occurs without alarms and must be repaired before enabling a full XSD gate.
- The generic generator checks a non-existent public
data_itemsattribute. The Part 6 code contains only a scoped fallback for required alarm trigger DataItems; it does not change unrelated serialization behavior. - Full AlarmSet.Base conformance needs a normative review, reference MTPs, populated classifications, multilingual texts, and decisions about explicit groups and additional trigger forms.
- Managed alarms require a separate target-native runtime design before any source-branch behavior is ported.
These inherited dependencies are documented to prevent the tested static subset from being mistaken for complete Part 6 or profile conformance.