Problem / motivation
The detected-event store carries a complete ISA-18.2 alarm-state model, but offers no way to query events by that state.
Each Event knows its alarm state:
IsOpen (libs/EventDetection/Event.m:38) — true while the violating condition still persists (EndTime = NaN).
- ack-status — derived from
AckedAt (Event.m:43); the canonical predicate is at Event.m:137.
computeDisplayState() (Event.m:125-148) — returns the four-state product 'unacked-active' | 'acked-active' | 'acked-cleared' | 'unacked-cleared'.
EventStore already has a growing query family — getEvents() (EventStore.m:97), getEventsForTag() (:156), plus the filed getEventsInRange(t0,t1) (#225) and getEventsBySeverity/getEventsByCategory (#228) — and a full acknowledgement subsystem (acknowledgeEvent() :337, getAckRecords() :322). But there is no query that filters by alarm state. Verified: grep -rniE "getUnack|getOpenEvent|getActiveAlarm|getEventsByState" libs/ --include="*.m" returns nothing.
So the two most common alarm-management questions have no store-level primitive:
- "What alarms are currently active?" (still in violation —
IsOpen)
- "What's still unacknowledged?" (the operator hasn't seen it yet)
Today a caller must pull getEvents() and hand-filter on IsOpen / AckedAt, re-deriving the exact predicate Event.computeDisplayState already encapsulates — error-prone and duplicated at every call site (the active-alarm board, the Companion NotificationCenterPane, any report).
Proposed feature
Add read-only state-filter getters to EventStore, mirroring the primitive-per-query style of #225/#228:
events = getActiveEvents(obj) — events with IsOpen == true (condition still violating).
events = getUnacknowledgedEvents(obj) — events where isAcked is false.
- (optional third)
events = getEventsByDisplayState(obj, state) — general selector over the existing four-state vocabulary ('unacked-active', 'acked-active', 'acked-cleared', 'unacked-cleared'), accepting a single state or a cellstr of states. This subsumes the two focused getters but is lower priority; the active-alarm board ('unacked-active') is the high-frequency case.
Rough sketch
- Lib / class:
libs/EventDetection/EventStore.m (single file).
- Public API:
active = es.getActiveEvents(); % IsOpen == true
open = es.getUnacknowledgedEvents(); % not yet acknowledged
board = es.getEventsByDisplayState('unacked-active'); % optional general form
- Implementation: a pure in-memory filter over
obj.events_, reusing the existing getEventsForTag iterate pattern and the in-repo predicates (ev.IsOpen; the isAcked test from Event.m:137; ev.computeDisplayState() for the general form). Return an Event array (empty [] when none), matching the shape of the existing getters. No new state, no schema change.
Value
High. Alarm/threshold ergonomics is an explicitly named sensor-analysis domain gap. "Show me the active alarms" and "show me everything not yet acknowledged" are the primary alarm-management queries for a MATLAB engineer running live monitoring — and the data model already classifies every event, so the only thing missing is the selector. Composes directly with the filed query/summary family (#225/#228/#245) and feeds any active-alarm board view.
Constraints check
- Toolbox-free: yes — plain array filtering, no toolbox calls.
- Backward-compatible: yes — purely additive; no existing method changes, serialized stores untouched, no
Event/DashboardWidget/Tag contract change.
- Pure MATLAB/Octave: yes.
Effort estimate
S — one file, reuses an existing iterate pattern and an in-repo predicate.
AI-proposed via /feature-scout — needs a human product decision before implementation.
Problem / motivation
The detected-event store carries a complete ISA-18.2 alarm-state model, but offers no way to query events by that state.
Each
Eventknows its alarm state:IsOpen(libs/EventDetection/Event.m:38) —truewhile the violating condition still persists (EndTime = NaN).AckedAt(Event.m:43); the canonical predicate is atEvent.m:137.computeDisplayState()(Event.m:125-148) — returns the four-state product'unacked-active' | 'acked-active' | 'acked-cleared' | 'unacked-cleared'.EventStorealready has a growing query family —getEvents()(EventStore.m:97),getEventsForTag()(:156), plus the filedgetEventsInRange(t0,t1)(#225) andgetEventsBySeverity/getEventsByCategory(#228) — and a full acknowledgement subsystem (acknowledgeEvent():337,getAckRecords():322). But there is no query that filters by alarm state. Verified:grep -rniE "getUnack|getOpenEvent|getActiveAlarm|getEventsByState" libs/ --include="*.m"returns nothing.So the two most common alarm-management questions have no store-level primitive:
IsOpen)Today a caller must pull
getEvents()and hand-filter onIsOpen/AckedAt, re-deriving the exact predicateEvent.computeDisplayStatealready encapsulates — error-prone and duplicated at every call site (the active-alarm board, the Companion NotificationCenterPane, any report).Proposed feature
Add read-only state-filter getters to
EventStore, mirroring the primitive-per-query style of #225/#228:events = getActiveEvents(obj)— events withIsOpen == true(condition still violating).events = getUnacknowledgedEvents(obj)— events whereisAckedis false.events = getEventsByDisplayState(obj, state)— general selector over the existing four-state vocabulary ('unacked-active','acked-active','acked-cleared','unacked-cleared'), accepting a single state or a cellstr of states. This subsumes the two focused getters but is lower priority; the active-alarm board ('unacked-active') is the high-frequency case.Rough sketch
libs/EventDetection/EventStore.m(single file).obj.events_, reusing the existinggetEventsForTagiterate pattern and the in-repo predicates (ev.IsOpen; theisAckedtest fromEvent.m:137;ev.computeDisplayState()for the general form). Return anEventarray (empty[]when none), matching the shape of the existing getters. No new state, no schema change.Value
High. Alarm/threshold ergonomics is an explicitly named sensor-analysis domain gap. "Show me the active alarms" and "show me everything not yet acknowledged" are the primary alarm-management queries for a MATLAB engineer running live monitoring — and the data model already classifies every event, so the only thing missing is the selector. Composes directly with the filed query/summary family (#225/#228/#245) and feeds any active-alarm board view.
Constraints check
Event/DashboardWidget/Tagcontract change.Effort estimate
S — one file, reuses an existing iterate pattern and an in-repo predicate.
AI-proposed via /feature-scout — needs a human product decision before implementation.