@@ -29,6 +29,8 @@ command ids (and their request/response payloads) don't drift between the
|
||||
| `0x0010` | `pmc_rdpmcrng` | reads PMC byte ranges |
|
||||
| `0x0020` | `cnc_modal` | reads cached modal MSTB per profile |
|
||||
| ... | ... | ... |
|
||||
| **`0x0102`** | **`cnc_wrparam`** | **mutates per-profile parameter map; returns `EW_PASSWD` (`11`) when the profile's `unlock_state` is off (sets up F4-d's unlock workflow) — issue #269, plan PR F4-b** |
|
||||
| **`0x0103`** | **`cnc_wrmacro`** | **mutates per-profile macro map; integer-only writes for now (decimalPointCount=0) — issue #269, plan PR F4-b** |
|
||||
| **`0x0F1A`** | **`cnc_rdalmhistry`** | **dumps the per-profile alarm-history ring buffer (issue #267, plan PR F3-a)** |
|
||||
|
||||
## `cnc_rdalmhistry` mock behaviour
|
||||
@@ -100,3 +102,94 @@ Integration test `Series/AlarmHistoryProjectionTests.cs` will assert:
|
||||
These tests are blocked on the focas-mock + integration-test project
|
||||
landing; the unit-test coverage in `FocasAlarmProjectionTests` already
|
||||
exercises every same-process invariant.
|
||||
|
||||
## `cnc_wrparam` / `cnc_wrmacro` mock behaviour — issue #269, plan PR F4-b
|
||||
|
||||
When the focas-mock fixture lands, it MUST implement the contract below.
|
||||
The .NET side already ships against this contract (`FwlibFocasClient.cs`
|
||||
write helpers, `FakeFocasClient` round-trip support); writing the simulator
|
||||
to the same shape lets the existing integration-test scaffolds at
|
||||
`tests/.../IntegrationTests/Series/ParameterWriteTests.cs` and
|
||||
`MacroWriteTests.cs` (when they materialise) light up without driver
|
||||
changes.
|
||||
|
||||
### Per-profile state
|
||||
|
||||
Each profile owns:
|
||||
|
||||
- `parameters: Dict[int, int]` — map from parameter number to current value.
|
||||
- `macros: Dict[int, int]` — map from macro number to current scaled-int
|
||||
value (decimal-point count fixed at 0 for F4-b).
|
||||
- `unlock_state: bool` — defaults `False`. When `False`, every
|
||||
`cnc_wrparam` returns `EW_PASSWD` (numeric `11`) regardless of
|
||||
parameter. Macro writes are NOT gated by `unlock_state`.
|
||||
- `last_write: Optional[LastWrite]` — most-recent successful
|
||||
`(kind, number, value, ts)` tuple, surfaced via the admin endpoint
|
||||
below for audit-log assertions.
|
||||
|
||||
### `cnc_wrparam` request decode
|
||||
|
||||
```
|
||||
[int16 LE datano][int16 LE axis][int8|int16|int32 LE value]
|
||||
```
|
||||
|
||||
Width of the value field is determined by the request frame trailer
|
||||
length per the table in
|
||||
[`focas-wire-protocol.md`](./focas-wire-protocol.md). On
|
||||
`unlock_state == False` short-circuit to `[int16 LE 11]` (`EW_PASSWD`).
|
||||
Otherwise mutate `parameters[datano] = value`, set `last_write`, return
|
||||
`[int16 LE 0]`.
|
||||
|
||||
### `cnc_wrmacro` request decode
|
||||
|
||||
```
|
||||
[int16 LE number][int16 LE length=8][int32 LE mcr_val][int16 LE dec_val]
|
||||
```
|
||||
|
||||
Always accept (no `unlock_state` gate). Mutate
|
||||
`macros[number] = mcr_val` (we ignore `dec_val` for F4-b — integer-only).
|
||||
Return `[int16 LE 0]`. Round-trip: a subsequent `cnc_rdmacro(number)`
|
||||
returns `(mcr_val, 0)`.
|
||||
|
||||
### Admin endpoint — `POST /admin/mock_set_unlock_state`
|
||||
|
||||
Toggles `unlock_state` for the F4-d unlock workflow tests. Without this,
|
||||
F4-b parameter-write integration tests can't reproduce the
|
||||
`EW_PASSWD` → `BadUserAccessDenied` mapping.
|
||||
|
||||
```
|
||||
POST /admin/mock_set_unlock_state
|
||||
{ "profile": "Series30i", "unlocked": true }
|
||||
```
|
||||
|
||||
### Admin endpoint — `GET /admin/mock_get_last_write`
|
||||
|
||||
Returns the simulator's view of the most-recent successful write, used by
|
||||
F4-b audit-log integration assertions ("did the write actually reach the
|
||||
fixture, and is the audit log capturing the right kind/number/value?").
|
||||
|
||||
```
|
||||
GET /admin/mock_get_last_write?profile=Series30i
|
||||
->
|
||||
{
|
||||
"kind": "param", // "param" | "macro"
|
||||
"number": 1815,
|
||||
"value": 100,
|
||||
"writtenAt": "2026-04-25T13:30:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
When no write has happened the endpoint returns `null` rather than 404 so
|
||||
the test helper can assert "no writes since fixture reset" without
|
||||
exception handling.
|
||||
|
||||
### Status
|
||||
|
||||
focas-mock simulator has not landed yet (tracked separately from F4-b).
|
||||
F4-b lands the .NET-side wire encoders + dispatch + status mapping
|
||||
unconditionally; the integration-test scaffolds at
|
||||
`tests/.../IntegrationTests/Series/ParameterWriteTests.cs` and
|
||||
`MacroWriteTests.cs` are deferred until the simulator + integration-test
|
||||
project land. Until then unit-test coverage in
|
||||
`FocasWriteParameterTests` / `FocasWriteMacroTests` exercises every
|
||||
same-process invariant against the in-memory `FakeFocasClient`.
|
||||
|
||||
Reference in New Issue
Block a user