From 30d07b91f4db35a1cdbd94a3814cbaa88bacce23 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Wed, 17 Jun 2026 06:07:40 -0400 Subject: [PATCH] fix(dcl): write List attributes as real MXAccess arrays (not a stringified List) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Ipsen MoveIn e2e (after the supervisory-advise fix landed scalar writes) exposed a second blocker: writes to List-typed attributes (MoveInWorkOrderNumbers / MoveInPartNumbers, List) hung at the 30s device-write timeout while scalar writes succeeded. InstanceActor.HandleSetDataAttribute already decodes a List attribute's canonical JSON into a typed List before the write (so the DCL can push a real array), but RealMxGatewayClient.ToMxValue only had scalar cases — a List fell through to Convert.ToString and wrote the garbage string "System.Collections.Generic.List`1[System.String]" to the array Galaxy node, which the gateway's COM write rejected/blocked. Add IReadOnlyList cases that call the client package's typed array encoders (VT_ARRAY|VT_BSTR etc.); List is mapped to DateTimeOffset. Covers every element type AttributeValueCodec produces. --- .../Adapters/RealMxGatewayClient.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealMxGatewayClient.cs b/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealMxGatewayClient.cs index 8435d1d6..ac7c7086 100644 --- a/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealMxGatewayClient.cs +++ b/src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/RealMxGatewayClient.cs @@ -435,6 +435,21 @@ public sealed class RealMxGatewayClient : IMxGatewayClient string s => s.ToMxValue(), DateTimeOffset dto => dto.ToMxValue(), DateTime dt => dt.ToMxValue(), + // List/array attribute values. The InstanceActor decodes a canonical JSON + // List attribute into a typed List (AttributeValueCodec produces + // List) before the write so the DCL + // can push a real MXAccess array. Map each to the client's typed array + // encoder. Without these a List would fall through to Convert.ToString + // and write a garbage scalar string to an array node — which the gateway's + // COM write then rejects/blocks (the array-write hang). + IReadOnlyList lb => lb.ToMxValue(), + IReadOnlyList li => li.ToMxValue(), + IReadOnlyList ll => ll.ToMxValue(), + IReadOnlyList lf => lf.ToMxValue(), + IReadOnlyList ld => ld.ToMxValue(), + IReadOnlyList ls => ls.ToMxValue(), + IReadOnlyList ldto => ldto.ToMxValue(), + IReadOnlyList ldt => ldt.Select(d => (DateTimeOffset)d).ToList().ToMxValue(), // Fall back to invariant string for any other CLR type. _ => Convert.ToString(value, CultureInfo.InvariantCulture)!.ToMxValue(), };