From 90fdf45df5c47cdf6f9412c4c566875257268a4f Mon Sep 17 00:00:00 2001 From: Raphael Maenle Date: Mon, 8 Jun 2026 03:38:11 +0200 Subject: [PATCH] H2: E157 module CEIDs + server-side emission MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the canonical E157 collection-event identifiers in the 1570+ block: 1570 ModuleProcessStateChange (generic; fired on any transition) 1571 ModuleNotExecuting 1572 ModuleGeneralExecuting 1573 ModuleStepExecuting 1574 ModuleStepCompleted Server installs a state-change handler that fires both the generic CEID and the state-specific one for each transition. Hosts that prefer "wake me on any module change and I'll fan it out myself" can subscribe to only the generic CEID; hosts that want narrower notifications subscribe to specific states. Closes Tranche H — E157 Module Process Tracking end-to-end (FSM + Store + CEIDs + server emission). Co-Authored-By: Claude Opus 4.7 --- apps/secs_server.cpp | 27 ++++++++++++++++++++++++++ include/secsgem/gem/e157_constants.hpp | 16 +++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 include/secsgem/gem/e157_constants.hpp diff --git a/apps/secs_server.cpp b/apps/secs_server.cpp index b884397..23d8a3f 100644 --- a/apps/secs_server.cpp +++ b/apps/secs_server.cpp @@ -17,6 +17,7 @@ #include "secsgem/gem/control_state.hpp" #include "secsgem/gem/data_model.hpp" #include "secsgem/gem/e116_constants.hpp" +#include "secsgem/gem/e157_constants.hpp" #include "secsgem/gem/e90_constants.hpp" #include "secsgem/gem/messages.hpp" #include "secsgem/gem/router.hpp" @@ -365,6 +366,32 @@ int main(int argc, char** argv) { } }); + // ---- E157 module state-change emitter -------------------------------- + // Every module transition fires the generic ModuleProcessStateChange + // CEID plus the state-specific one, mirroring secsgem-py's per-module + // CEID granularity. Hosts that don't subscribe to the specific CEID + // can still listen on the generic one to drive an internal FSM. + model->modules.set_state_change_handler( + [logfn, emit_event](const std::string& mod, gem::ModuleState from, + gem::ModuleState to, gem::ModuleEvent ev) { + logfn(std::string("MOD ") + mod + ": " + + gem::module_state_name(from) + " -> " + + gem::module_state_name(to) + " (" + + gem::module_event_name(ev) + ")"); + emit_event(gem::e157::kCeidModuleProcessStateChange); + switch (to) { + case gem::ModuleState::NotExecuting: + emit_event(gem::e157::kCeidModuleNotExecuting); break; + case gem::ModuleState::GeneralExecuting: + emit_event(gem::e157::kCeidModuleGeneralExecuting); break; + case gem::ModuleState::StepExecuting: + emit_event(gem::e157::kCeidModuleStepExecuting); break; + case gem::ModuleState::StepCompleted: + emit_event(gem::e157::kCeidModuleStepCompleted); break; + case gem::ModuleState::NoState: break; + } + }); + // ---- Build the SECS dispatch table once ------------------------------- gem::Router router; diff --git a/include/secsgem/gem/e157_constants.hpp b/include/secsgem/gem/e157_constants.hpp new file mode 100644 index 0000000..01681c2 --- /dev/null +++ b/include/secsgem/gem/e157_constants.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include + +// E157 §6 standard collection-event identifiers, one per module state. +// Equipment fires the matching CEID when a module transitions; hosts +// subscribe via the standard S2F33 / S2F35 / S2F37 path. +namespace secsgem::gem::e157 { + +inline constexpr uint32_t kCeidModuleProcessStateChange = 1570; +inline constexpr uint32_t kCeidModuleNotExecuting = 1571; +inline constexpr uint32_t kCeidModuleGeneralExecuting = 1572; +inline constexpr uint32_t kCeidModuleStepExecuting = 1573; +inline constexpr uint32_t kCeidModuleStepCompleted = 1574; + +} // namespace secsgem::gem::e157