diff --git a/apps/secs_server.cpp b/apps/secs_server.cpp index 3d982fe..c5cb37c 100644 --- a/apps/secs_server.cpp +++ b/apps/secs_server.cpp @@ -16,6 +16,7 @@ #include "secsgem/endpoint.hpp" #include "secsgem/gem/control_state.hpp" #include "secsgem/gem/data_model.hpp" +#include "secsgem/gem/e90_constants.hpp" #include "secsgem/gem/messages.hpp" #include "secsgem/gem/router.hpp" #include "secsgem/secs2/message.hpp" @@ -284,6 +285,61 @@ int main(int argc, char** argv) { } }); + // ---- E90 substrate state-change emitters ----------------------------- + // Map SubstrateState / SubstrateProcessingState transitions to the + // standard E90 CEIDs. Only the post-transition state matters; the + // event-report machinery already gates on enabled CEIDs so emitting + // for every transition is safe and gives the host a complete trace. + model->substrates.set_location_handler( + [logfn, emit_event](const std::string& substid, + gem::SubstrateState from, + gem::SubstrateState to, + gem::SubstrateEvent ev) { + logfn(std::string("SUB ") + substid + ": " + + gem::substrate_state_name(from) + " -> " + + gem::substrate_state_name(to) + " (" + + gem::substrate_event_name(ev) + ")"); + switch (to) { + case gem::SubstrateState::AtSource: + emit_event(gem::e90::kCeidSubstrateAtSource); break; + case gem::SubstrateState::AtWork: + emit_event(gem::e90::kCeidSubstrateAtWork); break; + case gem::SubstrateState::AtDestination: + emit_event(gem::e90::kCeidSubstrateAtDestination); break; + case gem::SubstrateState::NoState: break; + } + }); + + model->substrates.set_processing_handler( + [logfn, emit_event](const std::string& substid, + gem::SubstrateProcessingState from, + gem::SubstrateProcessingState to, + gem::SubstrateProcessingEvent ev) { + logfn(std::string("SUB ") + substid + " proc: " + + gem::substrate_processing_state_name(from) + " -> " + + gem::substrate_processing_state_name(to) + " (" + + gem::substrate_processing_event_name(ev) + ")"); + switch (to) { + case gem::SubstrateProcessingState::NeedsProcessing: + emit_event(gem::e90::kCeidSubstrateNeedsProcessing); break; + case gem::SubstrateProcessingState::InProcess: + emit_event(gem::e90::kCeidSubstrateInProcess); break; + case gem::SubstrateProcessingState::Processed: + emit_event(gem::e90::kCeidSubstrateProcessed); break; + case gem::SubstrateProcessingState::Aborted: + emit_event(gem::e90::kCeidSubstrateAborted); break; + case gem::SubstrateProcessingState::Stopped: + emit_event(gem::e90::kCeidSubstrateStopped); break; + case gem::SubstrateProcessingState::Rejected: + emit_event(gem::e90::kCeidSubstrateRejected); break; + case gem::SubstrateProcessingState::Lost: + emit_event(gem::e90::kCeidSubstrateLost); break; + case gem::SubstrateProcessingState::Skipped: + emit_event(gem::e90::kCeidSubstrateSkipped); break; + case gem::SubstrateProcessingState::NoState: break; + } + }); + // ---- Build the SECS dispatch table once ------------------------------- gem::Router router; diff --git a/include/secsgem/gem/e90_constants.hpp b/include/secsgem/gem/e90_constants.hpp new file mode 100644 index 0000000..541e79a --- /dev/null +++ b/include/secsgem/gem/e90_constants.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include + +// E90 §6 standard collection event identifiers. Equipment vendors +// frequently register additional CEIDs around the base set; the +// constants below are the canonical ones called out by E90-0716 §6.5, +// keyed off the SubstrateState transitions so application code can +// emit them directly from a SubstrateStore change handler. +// +// Values use a high block (901+) to avoid collisions with the demo +// CEIDs in data/equipment.yaml (which uses 100s/200s/400s). +namespace secsgem::gem::e90 { + +inline constexpr uint32_t kCeidSubstrateAtSource = 901; +inline constexpr uint32_t kCeidSubstrateAtWork = 902; +inline constexpr uint32_t kCeidSubstrateAtDestination = 903; +inline constexpr uint32_t kCeidSubstrateNeedsProcessing = 910; +inline constexpr uint32_t kCeidSubstrateInProcess = 911; +inline constexpr uint32_t kCeidSubstrateProcessed = 912; +inline constexpr uint32_t kCeidSubstrateAborted = 913; +inline constexpr uint32_t kCeidSubstrateStopped = 914; +inline constexpr uint32_t kCeidSubstrateRejected = 915; +inline constexpr uint32_t kCeidSubstrateLost = 916; +inline constexpr uint32_t kCeidSubstrateSkipped = 917; + +} // namespace secsgem::gem::e90