#pragma once #include #include #include #include #include #include #include #include #include #include "secsgem/secs2/item.hpp" namespace secsgem::gem { namespace s2 = secsgem::secs2; // ---- Status / data / equipment-constant variables ------------------------ struct StatusVariable { uint32_t id; std::string name; std::string units; s2::Item value; }; struct DataVariable { uint32_t id; std::string name; std::string units; s2::Item value; }; struct EquipmentConstant { uint32_t id; std::string name; std::string units; s2::Item value; s2::Item def_value; std::string min_str; // optional, ASCII for S2F30 ECMIN/ECMAX std::string max_str; }; // ---- Event reports ------------------------------------------------------- struct CollectionEvent { uint32_t id; std::string name; }; struct Report { uint32_t id; std::vector vids; }; // One report's worth of data at emission time: the RPTID and the values for // each VID, in declaration order. struct ReportData { uint32_t rptid; std::vector values; }; // ---- Alarms -------------------------------------------------------------- struct Alarm { uint32_t id; std::string text; // Lower 7 bits of ALCD: alarm severity category (1=personal safety, // 2=equipment safety, 4=parameter control error, ...). Bit 7 is the // set/cleared flag, applied at emit time. uint8_t severity_category; }; // ---- Ack codes for the new SxFy ------------------------------------------ // S2F30 carries no ack; S2F34 / S2F36 / S2F38 do. enum class DefineReportAck : uint8_t { Accept = 0, InsufficientSpace = 1, InvalidFormat = 2, RptidAlreadyDefined = 3, InvalidVid = 5, }; enum class LinkEventAck : uint8_t { Accept = 0, InsufficientSpace = 1, InvalidFormat = 2, UnknownCeid = 3, UnknownRptid = 4, CeidAlreadyLinked = 5, }; enum class EnableEventAck : uint8_t { Accept = 0, UnknownCeid = 1, }; // S5F2 / S5F4 alarm ack. enum class AlarmAck : uint8_t { Accept = 0, Error = 1, }; // S6F12 event-report ack. enum class EventReportAck : uint8_t { Accept = 0, Denied = 1, }; // S7F4 process-program ack. enum class ProcessProgramAck : uint8_t { Accept = 0, PermissionNotGranted = 1, LengthError = 2, MatrixOverflow = 3, PpidNotFound = 4, ModeUnsupported = 5, PerformanceError = 6, }; // ---- Existing ack enums from earlier batches ----------------------------- enum class EquipmentAck : uint8_t { Accept = 0, Denied_UnknownEcid = 1, Denied_Busy = 3, Denied_OutOfRange = 4, }; enum class TimeAck : uint8_t { Accept = 0, Error = 1, NotDoneNotEmpty = 2, }; enum class HostCmdAck : uint8_t { Accept = 0, InvalidCommand = 1, CannotDoNow = 2, ParameterInvalid = 3, AcceptedWillFinishLater = 4, Rejected = 5, InvalidObject = 6, }; enum class TerminalAck : uint8_t { Accepted = 0, WillNotDisplay = 1, TerminalNotAvailable = 2, }; // The in-memory equipment data dictionary. Owns SVIDs, DVIDs, ECIDs, the // dynamic event-report subscription state (reports + links + enabled set), // the alarm table, and a small process-program registry. Single-threaded; // all access happens on the Asio executor. class EquipmentDataModel { public: struct CommandParam { std::string name; s2::Item value; }; using HostCommandHandler = std::function&)>; // --- SVID --------------------------------------------------------------- void add_status_variable(StatusVariable sv); std::optional status_variable(uint32_t id) const; std::vector all_status_variables() const; void set_status_value(uint32_t id, s2::Item value); // --- DVID --------------------------------------------------------------- void add_data_variable(DataVariable dv); std::optional data_variable(uint32_t id) const; std::vector all_data_variables() const; void set_data_value(uint32_t id, s2::Item value); // VID lookup that searches SVIDs then DVIDs (E30 §6.5 — VIDs share a // namespace from the host's point of view). std::optional vid_value(uint32_t vid) const; bool vid_exists(uint32_t vid) const; // --- ECID --------------------------------------------------------------- void add_equipment_constant(EquipmentConstant ec); std::optional equipment_constant(uint32_t id) const; std::vector all_equipment_constants() const; EquipmentAck set_equipment_constant_value(uint32_t id, s2::Item value); // --- Clock -------------------------------------------------------------- std::string current_time_string() const; TimeAck set_time_string(const std::string& time_str); // --- Host commands ------------------------------------------------------ void register_command(const std::string& rcmd, HostCommandHandler handler); HostCmdAck dispatch_command(const std::string& rcmd, const std::vector& params) const; bool has_command(const std::string& rcmd) const; // --- Collection events -------------------------------------------------- void register_event(CollectionEvent ce); bool has_event(uint32_t ceid) const; std::vector all_events() const; // S2F33: define reports. `reports` maps RPTID -> VID list. An empty // vector deletes all reports (and clears all links). An empty VID list // for a given RPTID deletes that report. DefineReportAck define_reports( const std::vector>>& reports); // S2F35: link CEIDs to RPTID lists. `links` maps CEID -> RPTID list. // An empty RPTID list for a CEID clears its links. An empty outer list // clears all links. LinkEventAck link_event_reports( const std::vector>>& links); // S2F37: enable/disable events. Empty CEID list applies to *all* // registered events. EnableEventAck enable_events(bool enable, const std::vector& ceids); bool is_event_enabled(uint32_t ceid) const; // Compose the report data for a CEID emission (S6F11 body's report list). std::vector compose_reports_for(uint32_t ceid) const; std::vector all_reports() const; // --- Alarms ------------------------------------------------------------- void add_alarm(Alarm a); std::optional alarm(uint32_t alid) const; std::vector all_alarms() const; AlarmAck set_alarm_enabled(uint32_t alid, bool enable); bool alarm_enabled(uint32_t alid) const; // Returns the ALCD byte to put on the wire (bit 7 indicates set/cleared). // Returns nullopt for unknown alarms. std::optional alarm_set(uint32_t alid); std::optional alarm_clear(uint32_t alid); bool alarm_active(uint32_t alid) const; // --- Process programs --------------------------------------------------- void add_process_program(std::string ppid, std::string ppbody); std::optional process_program(const std::string& ppid) const; std::vector process_program_list() const; ProcessProgramAck delete_process_program(const std::string& ppid); private: std::map svids_; std::map dvids_; std::map ecids_; std::int64_t time_offset_seconds_ = 0; std::map commands_; std::map ceids_; std::map reports_; std::map> ce_links_; // CEID -> RPTID list std::set events_enabled_; std::map alarms_; std::set alarms_enabled_; std::set alarms_active_; std::map process_programs_; }; } // namespace secsgem::gem