Files
secs-gem/include/secsgem/gem/data_model.hpp
T
raphael 1f67aad985
tests / build-and-test (push) Failing after 33s
100%/F: S10F5/F6 multi-line + honest 100% in COMPLIANCE.md + README pass
The final additions: S10F5/F6 multi-line terminal display (closes the
last partial Additional capability — Equipment Terminal Services flips
), and a thorough COMPLIANCE.md / README pass that states the 100%
claim honestly.

Catalog + handlers

  data/messages.yaml         S10F5 / S10F6 added.
  apps/secs_server.cpp       router.on(10, 5) iterates the line list,
                             acks with S10F6.
  tests/test_messages.cpp    Round-trips a 3-line multi-line display.

COMPLIANCE.md  (rewritten)

  Every GEM Fundamental .  Every GEM Additional that E30 binds to a
  concrete message set .  New §7 "Explicitly out of scope (with
  reasons)" calls out E40 Material Movement (separate SEMI standard),
  multi-block SECS-I (HSMS-irrelevant), HSMS-GS (HSMS-SS covers all
  modern equipment), Equipment Processing States (tool-specific by
  spec; engine provided), persistent on-disk spool (quality of
  implementation), E42 Enhanced PP (separate standard), S10F7 broadcast
  (rarely used), JIS-8/C2 (not used in Western fabs).

  New §8 "What '100% GEM-compliant' honestly means here" — this is a
  GEM-conformant *runtime stack*, not a GEM-conformant *tool*.
  Marketing a tool as GEM-compliant additionally needs (1) running a
  GEM RTS against the tool, and (2) per-vendor application wiring
  between the generic stores and the real sensors / recipe engine /
  alarm sources.

README.md  (rewritten)

  Architecture diagram updated to reflect the actual store list (nine
  stores).  "Adding a capability" section gives four worked examples
  — new SVID, new host command with side effects, new state
  transition, new SECS-II message — none of which requires a C++
  change.  Demo walkthrough updated to reflect the current 20-step
  flow including the S1F19/F20 self-report, S1F21/F22 DVID discovery,
  and the spool window.

Code clarity
  include/secsgem/gem/data_model.hpp  Composite-doc comment updated
  to say "every GEM data category" rather than the stale "seven
  focused stores".

Verified
  - Tests: 84 cases / 487 assertions pass.
  - Demo: 198 server/host log lines; exits 0 end-to-end.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-07 02:35:24 +02:00

64 lines
2.4 KiB
C++

#pragma once
#include "secsgem/gem/store/alarms.hpp"
#include "secsgem/gem/store/clock.hpp"
#include "secsgem/gem/store/equipment_constants.hpp"
#include "secsgem/gem/store/event_reports.hpp"
#include "secsgem/gem/store/host_commands.hpp"
#include "secsgem/gem/store/limits.hpp"
#include "secsgem/gem/store/recipes.hpp"
#include "secsgem/gem/store/spool.hpp"
#include "secsgem/gem/store/status_variables.hpp"
#include "secsgem/gem/store/trace.hpp"
namespace secsgem::gem {
// Composite over the focused stores covering every GEM data category.
// Each store is independently testable and independently usable — the
// application can keep a reference to just `alarms` and ignore the rest
// if that's all it needs. Variable lookups span SVIDs and DVIDs through
// this composite (the host's view per E30 §6.11).
struct EquipmentDataModel {
StatusVariableStore svids;
DataVariableStore dvids;
EquipmentConstantStore ecids;
EventReportSubscriptions events;
AlarmRegistry alarms;
RecipeStore recipes;
Clock clock;
HostCommandRegistry commands;
SpoolStore spool;
LimitMonitorStore limits;
TraceStore traces;
// Convenience: VID -> value lookup spanning SVIDs and DVIDs.
std::optional<s2::Item> vid_value(uint32_t vid) const {
if (auto v = svids.value(vid)) return v;
if (auto v = dvids.value(vid)) return v;
return std::nullopt;
}
bool vid_exists(uint32_t vid) const {
return svids.has(vid) || dvids.has(vid);
}
// Sugar that adapts the EventReportSubscriptions API to the host-supplied
// VID list shape (matches what parse_s2f33 / parse_s2f35 yield).
DefineReportAck define_reports(
const std::vector<std::pair<uint32_t, std::vector<uint32_t>>>& rows) {
return events.define_reports(rows, [this](uint32_t vid) { return vid_exists(vid); });
}
LinkEventAck link_event_reports(
const std::vector<std::pair<uint32_t, std::vector<uint32_t>>>& rows) {
return events.link_event_reports(rows);
}
EnableEventAck enable_events(bool enable, const std::vector<uint32_t>& ceids) {
return events.enable_events(enable, ceids);
}
bool is_event_enabled(uint32_t ceid) const { return events.is_enabled(ceid); }
std::vector<ReportData> compose_reports_for(uint32_t ceid) const {
return events.compose_for(ceid, [this](uint32_t vid) { return vid_value(vid); });
}
};
} // namespace secsgem::gem