@@ -19,6 +19,8 @@ Each FOCAS-equivalent call gets a stable wire-protocol command id. Ids are
|
||||
| `0x0003` | `cnc_rdmacro` | macro variable value |
|
||||
| `0x0004` | `cnc_rddiag` | diagnostic value |
|
||||
| ... | ... | ... |
|
||||
| **`0x0102`** | **`cnc_wrparam`** | **IODBPSD parameter-write packet (issue #269, plan PR F4-b)** |
|
||||
| **`0x0103`** | **`cnc_wrmacro`** | **ODBM macro-write packet (issue #269, plan PR F4-b)** |
|
||||
| `0x0F1A` | **`cnc_rdalmhistry`** | **ODBALMHIS alarm-history ring-buffer dump (issue #267, plan PR F3-a)** |
|
||||
|
||||
## ODBALMHIS — alarm history (`cnc_rdalmhistry`, command `0x0F1A`)
|
||||
@@ -74,3 +76,81 @@ DST transitions. The .NET decoder
|
||||
unstable anyway.
|
||||
- `msg_len` overrunning the payload truncates the entry list at the
|
||||
malformed entry rather than throwing.
|
||||
|
||||
## IODBPSD — parameter write (`cnc_wrparam`, command `0x0102`)
|
||||
|
||||
Issue #269, plan PR F4-b. The write-side payload is the **byte-symmetric
|
||||
inverse of the `cnc_rdparam` read** — the same `IODBPSD` struct shape, and
|
||||
the .NET wire client uses the read-side decoder reversed (`EncodeParamValue`
|
||||
in `FwlibFocasClient.cs`) so the encoder/decoder are guaranteed to stay in
|
||||
lock-step.
|
||||
|
||||
### Request
|
||||
|
||||
| Offset | Width | Field |
|
||||
| --- | --- | --- |
|
||||
| 0 | `int16 LE` | `datano` — parameter number (e.g. `1815`) |
|
||||
| 2 | `int16 LE` | `type` — axis index (1-based; `0` = whole-CNC parameter) |
|
||||
| 4 | `length` | `data` payload — width depends on parameter type |
|
||||
|
||||
`length` (request frame trailer, drives `data` width):
|
||||
|
||||
| FocasDataType | `length` | Payload encoding |
|
||||
| --- | --- | --- |
|
||||
| `Byte` | `4 + 1` | one signed byte at offset 4 |
|
||||
| `Int16` | `4 + 2` | int16 LE at offset 4 |
|
||||
| `Int32` | `4 + 4` | int32 LE at offset 4 |
|
||||
|
||||
Bit-addressed parameters (`PARAM:1815/0` form) are not supported by F4-b
|
||||
and surface as `BadNotSupported`; F4-c will land the read-modify-write
|
||||
helper alongside the PMC bit RMW path.
|
||||
|
||||
### Response
|
||||
|
||||
Single `int16 LE` return code per the standard FWLIB convention:
|
||||
|
||||
- `0` → `Good`
|
||||
- `11` (`EW_PASSWD`) → **`BadUserAccessDenied`** (was `BadNotWritable`
|
||||
pre-F4-b — see `FocasStatusMapper`). Means the parameter-write switch is
|
||||
off or the CNC isn't in MDI mode; the F4-d unlock workflow will close
|
||||
the loop on this from the OPC UA side.
|
||||
- Other `EW_*` codes map per
|
||||
[`FocasStatusMapper.MapFocasReturn`](../../src/ZB.MOM.WW.OtOpcUa.Driver.FOCAS/FocasStatusMapper.cs).
|
||||
|
||||
## ODBM — macro write (`cnc_wrmacro`, command `0x0103`)
|
||||
|
||||
Issue #269, plan PR F4-b. The write-side payload mirrors the
|
||||
`cnc_rdmacro` read shape: the same `(mcr_val, dec_val)` (integer +
|
||||
decimal-point count) split, but emitted from the .NET side rather than
|
||||
decoded.
|
||||
|
||||
### Request
|
||||
|
||||
| Offset | Width | Field |
|
||||
| --- | --- | --- |
|
||||
| 0 | `int16 LE` | `number` — macro variable number (e.g. `500`) |
|
||||
| 2 | `int16 LE` | `length` — fixed at `8` for ODBM |
|
||||
| 4 | `int32 LE` | `mcr_val` — scaled integer value |
|
||||
| 8 | `int16 LE` | `dec_val` — decimal-point count |
|
||||
|
||||
F4-b ships **integer-only writes** (`dec_val = 0`) to match the most
|
||||
common HMI pattern; a future `WriteMacroScaled` overload will land if the
|
||||
field calls for fractional macro setpoints. Read-side decoders apply
|
||||
`mcr_val / 10^dec_val`, so a `dec_val = 0` write surfaces back as the
|
||||
integer it was emitted as.
|
||||
|
||||
### Response
|
||||
|
||||
Same single-int16 envelope as `cnc_wrparam`. `EW_PASSWD` is rare on macro
|
||||
writes (the gate-switch protection is parameter-specific) but the mapper
|
||||
treats both kinds identically.
|
||||
|
||||
### Symmetry note
|
||||
|
||||
The plan carries a "byte layout symmetry" requirement — the encoder for
|
||||
each kind is the read-side decoder reversed. Adding a new parameter type
|
||||
(e.g. `Int64` parameters, when they ship) means extending both sides in
|
||||
the same PR; the unit test
|
||||
`FocasWriteParameterTests.ParameterWrite_round_trip_stores_value_visible_to_subsequent_read`
|
||||
exercises encode → store → decode with the fake wire client and is the
|
||||
canary for symmetry regressions.
|
||||
|
||||
Reference in New Issue
Block a user