feat(composer): admit GalaxyMxGateway-backed equipment alias tags (+byte-parity)
This commit is contained in:
@@ -362,11 +362,16 @@ public static class Phase7Composer
|
||||
// Equipment tags = the inverse filter: a Tag bound to an Equipment (non-null EquipmentId)
|
||||
// whose driver's namespace is Equipment-kind. FullName is the driver-side wire reference
|
||||
// pulled from TagConfig — it becomes the variable's NodeId + read/write routing key.
|
||||
// A Galaxy alias is the one exception to the Equipment-kind namespace rule: a GalaxyMxGateway
|
||||
// driver lives in a SystemPlatform-kind namespace, yet an equipment-scoped alias Tag bound to
|
||||
// it must still surface as an equipment tag — so admit those by DriverType. The galaxyTags
|
||||
// producer keeps its `t.EquipmentId is null` guard, so an alias (EquipmentId set) never
|
||||
// double-counts there.
|
||||
var equipmentTags = tags
|
||||
.Where(t => t.EquipmentId is not null)
|
||||
.Where(t => driversById.TryGetValue(t.DriverInstanceId, out var di)
|
||||
&& namespacesById.TryGetValue(di.NamespaceId, out var ns)
|
||||
&& ns.Kind == NamespaceKind.Equipment)
|
||||
&& (ns.Kind == NamespaceKind.Equipment || di.DriverType == "GalaxyMxGateway"))
|
||||
.OrderBy(t => t.EquipmentId, StringComparer.Ordinal)
|
||||
.ThenBy(t => t.FolderPath ?? string.Empty, StringComparer.Ordinal) // coalesce so the sort matches the artifact-decode side exactly
|
||||
.ThenBy(t => t.Name, StringComparer.Ordinal)
|
||||
|
||||
@@ -471,8 +471,11 @@ public static class DeploymentArtifact
|
||||
if (isEquipment) equipmentNamespaces.Add(id!);
|
||||
}
|
||||
|
||||
// driverInstanceId → namespaceId
|
||||
// driverInstanceId → namespaceId, and driverInstanceId → DriverType. The DriverType map admits
|
||||
// a Galaxy alias (a GalaxyMxGateway-backed equipment-scoped tag) that lives in a SystemPlatform
|
||||
// namespace — byte-parity with the composer's `di.DriverType == "GalaxyMxGateway"` clause.
|
||||
var driverToNamespace = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
var driverToType = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
foreach (var el in diArr.EnumerateArray())
|
||||
{
|
||||
if (el.ValueKind != JsonValueKind.Object) continue;
|
||||
@@ -480,6 +483,9 @@ public static class DeploymentArtifact
|
||||
var ns = el.TryGetProperty("NamespaceId", out var nsEl) ? nsEl.GetString() : null;
|
||||
if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(ns))
|
||||
driverToNamespace[id!] = ns!;
|
||||
var dtype = el.TryGetProperty("DriverType", out var dtEl) ? dtEl.GetString() : null;
|
||||
if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(dtype))
|
||||
driverToType[id!] = dtype!;
|
||||
}
|
||||
|
||||
var result = new List<EquipmentTagPlan>(tagsArr.GetArrayLength());
|
||||
@@ -502,7 +508,10 @@ public static class DeploymentArtifact
|
||||
|
||||
if (string.IsNullOrWhiteSpace(tagId) || string.IsNullOrWhiteSpace(di) || string.IsNullOrWhiteSpace(name)) continue;
|
||||
if (!driverToNamespace.TryGetValue(di!, out var nsId)) continue;
|
||||
if (!equipmentNamespaces.Contains(nsId)) continue;
|
||||
// A GalaxyMxGateway-backed alias qualifies even though its namespace is SystemPlatform-kind
|
||||
// (not Equipment) — byte-parity with the composer's broadened equipment-tag filter.
|
||||
var isGalaxyAlias = driverToType.TryGetValue(di!, out var dtype2) && dtype2 == "GalaxyMxGateway";
|
||||
if (!equipmentNamespaces.Contains(nsId) && !isGalaxyAlias) continue;
|
||||
|
||||
result.Add(new EquipmentTagPlan(
|
||||
TagId: tagId!,
|
||||
|
||||
Reference in New Issue
Block a user