E3: Host-side E90 substrate event observer

Adds a typed substrate-event callback to HostHandler that decodes the
canonical E90 CEIDs from incoming S6F11 messages into the matching
SubstrateState / SubstrateProcessingState enum values.  Host
applications now get strongly-typed substrate observability without
having to maintain their own CEID-to-state lookup.

  using SubstrateEventHandler =
      std::function<void(uint32_t ceid, SubstrateState location,
                         SubstrateProcessingState processing)>;

  void set_substrate_event_handler(SubstrateEventHandler);

Axes not addressed by a given CEID stay at NoState — the handler
distinguishes "this CEID updates the location axis" from "this CEID
updates the processing axis" so the host can keep its own per-
substrate FSM in sync.

Closes Tranche E — E90 Substrate Tracking end-to-end (FSM + Store +
CEIDs + server emission + host observer).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-08 01:23:11 +02:00
parent 511950aa4a
commit 777fa5e9f9
2 changed files with 38 additions and 5 deletions
+21
View File
@@ -30,6 +30,27 @@ std::optional<s2::Message> HostHandler::handle_inbound(const s2::Message& msg) {
if (msg.stream == 6 && msg.function == 11) {
if (auto parsed = parse_s6f11(msg)) {
if (on_event_) on_event_(parsed->dataid, parsed->ceid, parsed->reports);
// E90 substrate event decode: map CEID to typed state callback.
if (on_substrate_) {
const auto c = parsed->ceid;
SubstrateState loc = SubstrateState::NoState;
SubstrateProcessingState proc = SubstrateProcessingState::NoState;
if (c == e90::kCeidSubstrateAtSource) loc = SubstrateState::AtSource;
else if (c == e90::kCeidSubstrateAtWork) loc = SubstrateState::AtWork;
else if (c == e90::kCeidSubstrateAtDestination) loc = SubstrateState::AtDestination;
else if (c == e90::kCeidSubstrateNeedsProcessing) proc = SubstrateProcessingState::NeedsProcessing;
else if (c == e90::kCeidSubstrateInProcess) proc = SubstrateProcessingState::InProcess;
else if (c == e90::kCeidSubstrateProcessed) proc = SubstrateProcessingState::Processed;
else if (c == e90::kCeidSubstrateAborted) proc = SubstrateProcessingState::Aborted;
else if (c == e90::kCeidSubstrateStopped) proc = SubstrateProcessingState::Stopped;
else if (c == e90::kCeidSubstrateRejected) proc = SubstrateProcessingState::Rejected;
else if (c == e90::kCeidSubstrateLost) proc = SubstrateProcessingState::Lost;
else if (c == e90::kCeidSubstrateSkipped) proc = SubstrateProcessingState::Skipped;
if (loc != SubstrateState::NoState ||
proc != SubstrateProcessingState::NoState) {
on_substrate_(c, loc, proc);
}
}
}
return s6f12_event_report_ack(EventReportAck::Accept);
}