c76ac1023e
tests / build-and-test (push) Successful in 3m7s
tests / thread-sanitizer (push) Successful in 3m41s
tests / tshark-dissector (push) Successful in 2m25s
tests / secs4j-interop (push) Successful in 1m6s
tests / python-interop (push) Successful in 3m28s
tests / libfuzzer (push) Successful in 3m40s
The package's __pycache__/*.pyc were committed (regenerated on every build, churning diffs and risking stale bytecode). Untrack all 7, add Python cache patterns to the root .gitignore, and drop the now-redundant interop/.gitignore (the root rule covers it). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
secsgem-client
A complete GEM tool integration in plain Python. The
secs_gemd daemon owns everything SEMI —
the HSMS link to the host, the GEM state machines, formats, timers,
spooling; this client tells it about your tool and reacts to the host.
from secsgem_client import Equipment
eq = Equipment("localhost:50051")
eq.set(ChamberPressure=2.5) # host sees it on its next poll
eq.fire("ProcessStarted") # S6F11 to the host, report auto-assembled
eq.alarm("chiller_temp_high") # S5F1 (set), eq.clear(...) for clear
@eq.on("START") # host remote commands -> your function
def start(cmd):
run_recipe(cmd.params.get("PPID"))
eq.fire("ProcessStarted") # the host's real completion signal
eq.listen() # block and dispatch (background=True for a thread)
Names are the ones from your equipment.yaml; values are plain Python
(float, int, bool, str, bytes, lists). Errors raise
SecsGemError with the daemon's explanation ("no variable named ...").
No compiled extension, no SEMI knowledge, no C++ toolchain — pip install
and a running daemon is the whole setup.