interop: secsgem-py cross-validation harness + lenient identifier parsing

Adds a Docker-based interop harness that drives the C++ server with
secsgem-py 0.3.0 as the active host and probes a secsgem-py-passive
equipment from a minimal C++ active client.  Surfaces and fixes four
interoperability bugs uncovered by cross-testing:

  * SEMI E5 identifier formatcodes are a U1|U2|U4|U8 wildcard;
    secsgem-py picks the narrowest fitting width while our parsers
    only accepted U4.  `as_uN_scalar` / `as_iN_scalar` now accept
    any unsigned/signed width and range-check the downcast.
  * PPBODY (S7F3/F6) is "ASCII | Binary | List" per the spec;
    secsgem-py defaults to ASCII.  Added BINARY_OR_ASCII codegen
    item type with `as_text_or_binary` accessor.
  * S1F23/F24 Collection Event Namelist was unimplemented; added
    schema + `vids_for(ceid)` accessor on EventReportSubscriptions
    plus the dispatch handler.
  * S10F1 was registered as a host->equipment handler, but per
    SEMI E5 §12 S10F1 is equipment->host; S10F3 is the actual
    host->equipment Terminal Display Single.  Added an S10F3
    handler alongside (we keep S10F1 too for backward compat).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-08 23:17:18 +02:00
parent 9fbab92106
commit 2d60571a9c
13 changed files with 793 additions and 10 deletions
+34 -2
View File
@@ -191,6 +191,38 @@ messages:
- {name: name, shape: {kind: scalar, item_type: ASCII}}
- {name: units, shape: {kind: scalar, item_type: ASCII}}
# S1F23 / S1F24 — Collection Event Namelist (CEID directory).
# Body of S1F23 is a list of CEIDs; an empty list means "every CEID".
# The S1F24 reply has rows of (CEID, CENAME, [VID...]) listing every
# status variable referenced by the reports linked to that CEID.
- id: S1F23
stream: 1
function: 23
w: true
builder: s1f23_collection_event_namelist_request
parser: parse_s1f23
body:
kind: list_of
element: {kind: scalar, item_type: U4}
name: ceids
- id: S1F24
stream: 1
function: 24
builder: s1f24_collection_event_namelist_data
parser: parse_s1f24
body:
kind: list_of
name: items
element:
kind: list
struct_name: CollectionEventName
fields:
- {name: ceid, shape: {kind: scalar, item_type: U4}}
- {name: cename, shape: {kind: scalar, item_type: ASCII}}
- name: vids
shape: {kind: list_of, element: {kind: scalar, item_type: U4}}
# =====================================================================
# S2 — Equipment control + reports
# =====================================================================
@@ -920,7 +952,7 @@ messages:
struct_name: ProcessProgram
fields:
- {name: ppid, shape: {kind: scalar, item_type: ASCII}}
- {name: ppbody, shape: {kind: scalar, item_type: BINARY}}
- {name: ppbody, shape: {kind: scalar, item_type: BINARY_OR_ASCII}}
- id: S7F4
stream: 7
@@ -946,7 +978,7 @@ messages:
struct_name: ProcessProgram
fields:
- {name: ppid, shape: {kind: scalar, item_type: ASCII}}
- {name: ppbody, shape: {kind: scalar, item_type: BINARY}}
- {name: ppbody, shape: {kind: scalar, item_type: BINARY_OR_ASCII}}
- id: S7F19
stream: 7