docs(phase4c): cross-driver 1-D array support + isArray/arrayLength keys + coverage matrix

This commit is contained in:
Joseph Doherty
2026-06-16 22:18:55 -04:00
parent 94e8c55b5c
commit 05c7e86f0c
7 changed files with 243 additions and 0 deletions
+61
View File
@@ -169,6 +169,67 @@ behaviour, continuation-point paging, and aggregates.
> alarms](ScriptedAlarms.md#native-driver-alarms-equipment-tag-path) for
> details.
## Array tags (1-D)
A tag can be made a **1-D OPC UA array node** by setting two keys in its `TagConfig`
JSON blob. The controls are exposed as first-class UI fields in the Tag modal (an
**Is array** checkbox + an **Array length** numeric input), available for all drivers
— typed editors (Modbus, S7, etc.) and the raw-JSON textarea (Galaxy) alike.
### Canonical rule
| Condition | OPC UA node shape |
|---|---|
| `isArray: true` AND `arrayLength >= 1` | 1-D array node (`ValueRank = OneDimension`, `ArrayDimensions = [arrayLength]`) |
| `isArray: false` (any `arrayLength`) | Scalar node (default) |
| `isArray` absent | Scalar node (default) |
A single-element array (`isArray: true, arrayLength: 1`) is valid and materialises as a
`[1]` node.
### Fields
| Field | Type | Required | Description |
|---|---|---|---|
| `isArray` | bool | no | When `true` (and `arrayLength >= 1`), makes the node a 1-D array. Absent or `false` → scalar. |
| `arrayLength` | uint (≥ 1) | when `isArray: true` | The element count for the OPC UA `ArrayDimensions` declaration. Must be ≥ 1 when `isArray` is set. |
UI validation rejects `arrayLength = 0` when `isArray` is checked.
### Examples
```json
{"FullName":"PLC1.TemperatureArray","isArray":true,"arrayLength":10}
```
```json
{"Register":"HR100","DataType":"Float32","isArray":true,"arrayLength":5}
```
Combined with historization (values are arrays — history of the whole array snapshot):
```json
{"Register":"HR200","DataType":"Int16","isArray":true,"arrayLength":20,"isHistorized":true}
```
### Per-driver read mechanism and live-verify status
| Driver | Read mechanism | Live-verify |
|---|---|---|
| **Modbus** | Contiguous FC03/FC04 block (`arrayLength × registers-per-element`); String and BitInRegister array modes also supported | Mac-verifiable (sim `10.100.0.35:5020`) |
| **S7** | Contiguous `ReadBytesAsync` block over the declared address span + per-element decode loop | Unit-proven (sim fixture down) |
| **AB CIP** | libplctag native array read (atomic and UDT member arrays) | Unit-proven (sim fixture down) |
| **AB Legacy** | PCCC multi-element file read via libplctag (cap 256 elements) | Unit-proven (sim fixture down) |
| **TwinCAT** | ADS native array symbol read against the declared `SymbolPath` | Unit-proven (sim fixture down) |
### Out of scope (named deferrals)
- **Array writes** (inbound client→device write of an array value) — tagged for a follow-up phase.
- **Multi-dimensional arrays** (`ValueRank > 1`) — not supported; all arrays are 1-D.
- **Array historization** — a historized array tag materialises with the correct `Historizing` flag, but the Wonderware sidecar historian treats the value as an opaque blob; per-element history is out of scope.
See the individual driver docs under `docs/drivers/` for per-driver implementation details.
## Galaxy address picker — native-alarm pre-fill
When the Galaxy address picker selects an attribute that is itself an alarm