Skip to content

MonitorTag: add Latched / manual-reset alarm mode (alarm holds until reset(), for self-clearing transients) #352

Description

@HanSur94

Problem / motivation

MonitorTag produces a 0/1 alarm signal that drops back to 0 the instant its condition clears (after any hysteresis / MinDuration debounce). There is no way to make an alarm hold.

That means a self-clearing transient — a spike above threshold that returns to normal before anyone looks — is effectively invisible on a dashboard. A StatusWidget / NumberWidget bound to the monitor just shows OK, because by the time the engineer glances at the tile the signal is already back to 0. For the target user (a MATLAB sensor engineer watching a dashboard rather than the live sample stream) this is a real blind spot.

Latching / manual-reset alarms are a bedrock alarm-management pattern (ISA-18.2): an alarm, once tripped, stays asserted until an operator acknowledges it, regardless of whether the process value has since returned to normal.

Searches for latch / manual-reset against all issues return nothing — this is not yet tracked. It has surfaced as the queued #2/#3 candidate across several /feature-scout runs (2026-07-05 e/f/g) without being filed.

Proposed feature

Add an opt-in latched alarm mode to MonitorTag, plus a public reset() to clear the latch.

  • New property Latched = false (default preserves today's exact behavior).
  • When Latched = true, once the (debounced/hysteresed) signal goes to 1 it stays 1 for all subsequent samples until a reset boundary.
  • New public method reset(t) clears the latch as of time t (default: latest sample). Reset boundaries are recorded as state so getXY() stays deterministic and replayable across invalidate() / recompute().
m = MonitorTag('press_hi', st, @(x,y) y > 50, 'Latched', true);
[mx, my] = m.getXY();   % my rises to 1 on first excursion and HOLDS at 1
                        % even after y falls back below 50
m.reset();              % operator acknowledges -> latch clears from now on

Rough sketch

  • Lib/class: libs/SensorThreshold/MonitorTag.m only.
  • FSM: the alarm pipeline is already staged — Stage 1 raw ConditionFn, Stage 2 hysteresis (AlarmOffConditionFn), Stage 3 MinDuration debounce (see recompute_() ~L606 and applyHysteresis_() ~L682). Add a Stage 4 latch after the debounce: hold the running value at 1 once set, cleared only at recorded reset boundaries.
  • Streaming: add a latch carry-in field to cache_ (mirrors lastHystState_ / ongoingRunStart_) so appendData() preserves latch state across the append boundary.
  • Public API: Latched (logical property, NV-pair at construction), reset(t) method (t optional).
  • Serialization: add s.latched and s.resettimes to toStruct / fromStruct (note existing lowercase field convention, e.g. s.minduration). Old serialized dashboards lack the fields → default false / [].

Value

Directly serves the dashboard-watching engineer: a transient excursion is no longer missed. Latching is the standard operator-acknowledge workflow and pairs naturally with the existing EventStore emission and MinDuration/hysteresis controls.

Constraints check

  • Toolbox-free: ✅ pure logical FSM, no toolbox calls.
  • Backward-compatible:Latched defaults false (behavior unchanged); reset() is additive; serialized dashboards without the new fields load with latch off.
  • Pure MATLAB/Octave: ✅ no MEX, no language features beyond the existing class.
  • Widget/Tag contract:getXY() still returns a 0/1 vector on the parent grid — every consumer (widgets, SensorDetailPlot, event emission) works unchanged.

Effort estimate

S–M — one class. Stage-4 latch in recompute_(), a cache_ carry-in for appendData(), a reset(t) method with a recorded reset-boundary list, and two serialization fields.


AI-proposed via /feature-scout — needs a human product decision before implementation.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions