fix(daemon)+fix(client): close four fool-proofing gaps
C++ (equipment_service.hpp): - ReportSubstrate ARRIVED: check CreateResult and return INVALID_OBJECT when the substrate ID already exists, instead of silently doing nothing - ReportSubstrate/ReportModule default switch branches: return false (→ CANNOT_DO_NOW) for unknown enum values instead of silently accepting Python (_client.py): - @eq.command: raise NameError (client-side name validation) instead of SecsGemError (which means "daemon declined a request") — wrong type - Module docstring: update example to show @eq.command / eq.names API Test (test_daemon_service.cpp): - Add duplicate-ARRIVED check (expects INVALID_OBJECT) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,11 +10,12 @@ equipment.yaml; values are plain Python.
|
||||
|
||||
eq = Equipment("localhost:50051")
|
||||
eq.set(ChamberPressure=2.5)
|
||||
eq.fire("ProcessStarted")
|
||||
eq.fire(eq.names.event.ProcessStarted) # typo-safe; plain strings also work
|
||||
|
||||
@eq.on("START")
|
||||
def start(cmd):
|
||||
@eq.command # function name IS the RCMD name,
|
||||
def START(cmd): # validated against equipment at import
|
||||
run_recipe(cmd.params.get("PPID"))
|
||||
eq.fire(eq.names.event.ProcessStarted)
|
||||
|
||||
eq.listen() # blocks, dispatching host commands to your handlers
|
||||
"""
|
||||
@@ -238,9 +239,7 @@ class Equipment:
|
||||
if name not in self.names.command:
|
||||
close = difflib.get_close_matches(name, dir(self.names.command), n=3)
|
||||
hint = f" Did you mean {', '.join(close)}?" if close else ""
|
||||
raise SecsGemError(
|
||||
pb.Ack.PARAMETER_INVALID,
|
||||
f"no host command '{name}' to bind @eq.command to.{hint}")
|
||||
raise NameError(f"no host command '{name}' to bind @eq.command to.{hint}")
|
||||
self._handlers[name] = fn
|
||||
return fn
|
||||
|
||||
|
||||
Reference in New Issue
Block a user