From e5392d2c7b3b5b3d86e87ba1ff75f3fd582ab82a Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Fri, 29 May 2026 16:00:10 -0400 Subject: [PATCH] feat(templateengine): flatten native alarm sources (inherit/compose/override) --- .../Flattening/FlatteningService.cs | 139 ++++++++++++++++++ .../Flattening/FlatteningServiceTests.cs | 34 +++++ 2 files changed, 173 insertions(+) diff --git a/src/ZB.MOM.WW.ScadaBridge.TemplateEngine/Flattening/FlatteningService.cs b/src/ZB.MOM.WW.ScadaBridge.TemplateEngine/Flattening/FlatteningService.cs index de6c7f0d..20a48ee4 100644 --- a/src/ZB.MOM.WW.ScadaBridge.TemplateEngine/Flattening/FlatteningService.cs +++ b/src/ZB.MOM.WW.ScadaBridge.TemplateEngine/Flattening/FlatteningService.cs @@ -96,6 +96,13 @@ public class FlatteningService // Step 7: Resolve alarm on-trigger script references to canonical names ResolveAlarmScriptReferences(alarms, alarmScriptIds, scriptCanonicalById); + // Step 7b: Resolve native alarm source bindings (connection + source + // reference). Conditions under each source are discovered at runtime; + // flattening only resolves the binding through inherit/compose/override. + var nativeAlarmSources = ResolveInheritedNativeAlarmSources(templateChain, prefix: null); + ResolveComposedNativeAlarmSources(templateChain, compositionMap, composedTemplateChains, nativeAlarmSources); + ApplyInstanceNativeAlarmSourceOverrides(instance.NativeAlarmSourceOverrides, nativeAlarmSources); + // Step 8: Collect connection configurations for deployment packaging var connections = new Dictionary(); foreach (var attr in attributes.Values) @@ -125,6 +132,7 @@ public class FlatteningService AreaId = instance.AreaId, Attributes = attributes.Values.OrderBy(a => a.CanonicalName, StringComparer.Ordinal).ToList(), Alarms = alarms.Values.OrderBy(a => a.CanonicalName, StringComparer.Ordinal).ToList(), + NativeAlarmSources = nativeAlarmSources.Values.OrderBy(s => s.CanonicalName, StringComparer.Ordinal).ToList(), Scripts = scripts.Values.OrderBy(s => s.CanonicalName, StringComparer.Ordinal).ToList(), Connections = connections.Count > 0 ? connections : null, GeneratedAtUtc = DateTimeOffset.UtcNow @@ -649,6 +657,137 @@ public class FlatteningService } } + /// + /// Resolves native alarm source bindings from an inheritance chain. Keys of + /// the returned dictionary are bare binding names (caller path-qualifies for + /// composed modules). Derived templates win unless the base binding is + /// locked; placeholders + /// never shadow a live base binding. + /// + private static Dictionary ResolveInheritedNativeAlarmSources( + IReadOnlyList