fix(address-space): numeric array writes convert (checked) to the node element type; array-to-scalar refusal only for Modbus/S7 (#610 review R6)
MAJOR-1: R4's exact element-type match refused ScadaBridge's CLR-list writes (its element types are only Boolean/Int32/Float/Double/String/ DateTime) to every Int16/UInt16/Byte/UInt32/Int64/UInt64 array node and a Double list to a Float array. EvaluateEquipmentWriteStructure now converts a numeric array of another numeric element type element-wise, CHECKED, into the node's element type and hands the converted array back through OnEquipmentTagWrite's ref value, so the node stores and the driver receives the node's own type. Any out-of-range, fractional-to-integer, NaN/Inf-to- integer or Float-overflowing element refuses the whole write BadTypeMismatch (nothing dispatched) - so the UInt32 -> Int32 bit reinterpretation stays closed. Non-numeric mismatches stay refused. The wrong 'no client relies on a looser rule' comment is corrected. MINOR-1: the array-value-to-scalar-node refusal broke writes back to browse-committed array tags (committed scalar, isArray never set) on pass-through drivers. It now applies only when the owning driver's scalar encoder cannot take an array (DriverArrayWriteSupport. RefusesArrayValueOnScalarTag: Modbus, S7), carried RawTagPlan. ScalarRefusesArrayValue / UnsReferenceVariable.BackingScalarRefusesArrayValue -> EnsureVariable(refuseArrayOnScalar) -> a per-node set in the node manager. OpcUaClient/Galaxy/others keep pre-#610 dispatch. Not on the classifier whitelist (driver-type edit rebuilds); a mirror whose flag changes is recreated, not updated in place. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -116,4 +116,4 @@ The session-less alarm feed (`GatewayGalaxyAlarmFeed`) and alarm acknowledger (`
|
||||
- **Duplicate `attributeRef` (#605 / 06-S-13)**: two authored RawPaths dialling the same Galaxy attribute are both dialled, but the reverse map is first-wins, so value fan-out and alarm `ConditionId` surface under the first RawPath only. The loser is logged at Warning and recorded in the skipped-tag ledger with the winner path in the reason.
|
||||
- **Subscribe-once reads are bounded (#605 / 06-S-3)**: `ReadAsync` on the production path (SubscribeBulk, first event, Unsubscribe) carries an internal 30 s deadline in addition to the caller token; slots that never publish come back `BadTimeout`, so `CancellationToken.None` can no longer hang on a silent tag.
|
||||
- **Supervisory advise is retried after a thrown failure (#605 / 06-S-12)**: the writer marks an item handle advised before the call; a thrown advise (not just a non-OK status) now unmarks it, fails the write closed and re-advises on the next write.
|
||||
- **Array writes (#610)**: a Galaxy array tag is client-writable only for the `MxValueEncoder` array types (OPC UA `Boolean`/`Int32`/`Int64`/`Float`/`Double`/`String`/`DateTime`) **and only with a declared `arrayLength`** — with none the node is unbounded, and a short whole-array write would *resize* the attribute. The element type must match the node exactly (`BadTypeMismatch` inline otherwise), and `MxValueEncoder` itself refuses `uint[]`/`ulong[]`: CLR array covariance let them match the `int[]`/`long[]` arms and be written bit-reinterpreted. Encoder-level only — Galaxy array writes have **no live gate** yet. See [Uns.md §Array writes](../Uns.md#array-writes-610), including the upgrade note.
|
||||
- **Array writes (#610)**: a Galaxy array tag is client-writable only for the `MxValueEncoder` array types (OPC UA `Boolean`/`Int32`/`Int64`/`Float`/`Double`/`String`/`DateTime`) **and only with a declared `arrayLength`** — with none the node is unbounded, and a short whole-array write would *resize* the attribute. The element type must match the node or be a numeric type that converts to it exactly — a numeric array of another element type is converted, checked, to the node's type in the node manager (an `Int32` list to an `Int64` array arrives as `long[]`), and any unrepresentable element refuses the write `BadTypeMismatch` inline. An array written to a **scalar** Galaxy node (a browse-committed array attribute without `isArray`) is still dispatched, as before #610. Separately, `MxValueEncoder` itself refuses `uint[]`/`ulong[]`: CLR array covariance let them match the `int[]`/`long[]` arms and be written bit-reinterpreted. Encoder-level only — Galaxy array writes have **no live gate** yet. See [Uns.md §Array writes](../Uns.md#array-writes-610), including the upgrade note.
|
||||
|
||||
Reference in New Issue
Block a user