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