diff --git a/apps/secs_server.cpp b/apps/secs_server.cpp index c5cb37c..b884397 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/e116_constants.hpp" #include "secsgem/gem/e90_constants.hpp" #include "secsgem/gem/messages.hpp" #include "secsgem/gem/router.hpp" @@ -340,6 +341,30 @@ int main(int argc, char** argv) { } }); + // ---- E116 EPT state-change emitter ----------------------------------- + model->ept.set_state_change_handler( + [logfn, emit_event](gem::EptState from, gem::EptState to, + gem::EptEvent ev, std::chrono::milliseconds dwell) { + logfn(std::string("EPT: ") + gem::ept_state_name(from) + " -> " + + gem::ept_state_name(to) + " (" + gem::ept_event_name(ev) + + ", dwelt " + std::to_string(dwell.count()) + "ms)"); + switch (to) { + case gem::EptState::NonScheduledTime: + emit_event(gem::e116::kCeidNonScheduledTime); break; + case gem::EptState::ScheduledDowntime: + emit_event(gem::e116::kCeidScheduledDowntime); break; + case gem::EptState::UnscheduledDowntime: + emit_event(gem::e116::kCeidUnscheduledDowntime); break; + case gem::EptState::Engineering: + emit_event(gem::e116::kCeidEngineering); break; + case gem::EptState::Standby: + emit_event(gem::e116::kCeidStandby); break; + case gem::EptState::Productive: + emit_event(gem::e116::kCeidProductive); break; + case gem::EptState::NoState: break; + } + }); + // ---- Build the SECS dispatch table once ------------------------------- gem::Router router; diff --git a/include/secsgem/gem/data_model.hpp b/include/secsgem/gem/data_model.hpp index 9dac587..e5f3c1b 100644 --- a/include/secsgem/gem/data_model.hpp +++ b/include/secsgem/gem/data_model.hpp @@ -3,6 +3,7 @@ #include "secsgem/gem/store/alarms.hpp" #include "secsgem/gem/store/carriers.hpp" #include "secsgem/gem/store/clock.hpp" +#include "secsgem/gem/ept_state.hpp" #include "secsgem/gem/store/control_jobs.hpp" #include "secsgem/gem/store/equipment_constants.hpp" #include "secsgem/gem/store/event_reports.hpp" @@ -41,6 +42,7 @@ struct EquipmentDataModel { CarrierStore carriers; LoadPortStore load_ports; SubstrateStore substrates; + EptStateMachine ept; // Convenience: VID -> value lookup spanning SVIDs and DVIDs. std::optional vid_value(uint32_t vid) const { diff --git a/include/secsgem/gem/e116_constants.hpp b/include/secsgem/gem/e116_constants.hpp new file mode 100644 index 0000000..61af06c --- /dev/null +++ b/include/secsgem/gem/e116_constants.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include + +// E116 ยง6 standard collection-event identifiers, one per top-level +// state. Equipment fires the matching CEID on transition into that +// state; hosts subscribe via the existing S2F33 / S2F35 / S2F37 flow. +namespace secsgem::gem::e116 { + +inline constexpr uint32_t kCeidNonScheduledTime = 1100; +inline constexpr uint32_t kCeidScheduledDowntime = 1101; +inline constexpr uint32_t kCeidUnscheduledDowntime = 1102; +inline constexpr uint32_t kCeidEngineering = 1103; +inline constexpr uint32_t kCeidStandby = 1104; +inline constexpr uint32_t kCeidProductive = 1105; + +} // namespace secsgem::gem::e116