feat(client)+feat(daemon): eq.names, @eq.command, E90/E157 RPCs
Python client:
- eq.names.event.* / .alarm.* / .command.* / .var.* / .constant.* —
autocomplete-able, typo-safe name lookup backed by the Describe RPC
(lazy, cached; AttributeError on bad name with close-match hints)
- @eq.command decorator — binds a handler by function name, validated
against the equipment's real command set at decoration time
- eq.report_substrate() — E90 wafer milestone reporting
- eq.report_module() — E157 module state reporting (auto-create)
Daemon (C++ service):
- ReportSubstrate RPC — drives E90 location + processing FSMs
- ReportModule RPC — drives E157 module FSM (auto-create on first report)
- ack_from_outcome() helper — consistent Ack mapping for read_sync results
Proto: SubstrateReport, ModuleReport, EquipmentDescription,
SpoolFlushRequest, TerminalMessage; Describe, FlushSpool,
SendTerminalMessage RPCs
Tests: C++ FSM test (journey + ghost rejection + E157 illegal jump);
interop coverage for names API and E90/E157 round-trip
Docs: ch42 RPC table + Python example updated; ch16 daemon-path section added
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -201,6 +201,37 @@ wafer was at every moment.
|
||||
|
||||
---
|
||||
|
||||
## Daemon path (Python client)
|
||||
|
||||
If your tool uses the daemon (`secs_gemd`) and the Python client, the
|
||||
E90 and E157 RPCs are wrapped as two methods:
|
||||
|
||||
```python
|
||||
from secsgem_client import Equipment
|
||||
eq = Equipment("localhost:50051")
|
||||
|
||||
# E90 — substrate journey (daemon drives FSMs, fires CEIDs automatically)
|
||||
eq.report_substrate("WFR-001", "ARRIVED", carrier_id="FOUP-7", slot=3)
|
||||
eq.report_substrate("WFR-001", "AT_WORK")
|
||||
eq.report_substrate("WFR-001", "PROCESSING")
|
||||
eq.report_substrate("WFR-001", "PROCESSED")
|
||||
eq.report_substrate("WFR-001", "AT_DESTINATION")
|
||||
|
||||
# E157 — module state (module is auto-created on first report)
|
||||
eq.report_module("CHAMBER-A", "GENERAL_EXECUTING")
|
||||
eq.report_module("CHAMBER-A", "STEP_EXECUTING")
|
||||
eq.report_module("CHAMBER-A", "STEP_COMPLETED")
|
||||
eq.report_module("CHAMBER-A", "NOT_EXECUTING")
|
||||
```
|
||||
|
||||
Milestones map to the `SubstrateReport.Milestone` protobuf enum;
|
||||
module states to `ModuleReport.State`. The daemon's `ReportSubstrate`
|
||||
handler validates FSM transitions and returns `INVALID_OBJECT` if the
|
||||
substrate was never `ARRIVED` (which guarantees the daemon owns the
|
||||
substrate record).
|
||||
|
||||
---
|
||||
|
||||
## Where to go next
|
||||
|
||||
You now know how every component of in-flight material is
|
||||
|
||||
Reference in New Issue
Block a user