webpage_generator: report blocked on interlock even when scan is interrupted
A block interrupts the running scan, clearing active_request_block, so the old _derive_status() (which only returned 'blocked' inside the queue_has_active_scan branch) fell through to 'idle' with the blocked LED off, despite watched beamline states being out of spec. - _derive_status: return 'blocked' on beamline_blocking OR queue_locks, independent of active scan; only fresh-heartbeat 'scanning' outranks it. - _cycle: beamline_blocking = enabled is True AND any(state mismatched). Gated on enabled so a disabled/unknown interlock with an out-of-spec state does not raise BLOCKED. Also counted as activity so the idle clock restarts once cleared. - beamline-states card summary updated in lock-step: mismatched states are only called "currently blocking" when enabled, else "out of spec (interlock disabled/unknown, not blocking)", so pill and card can't disagree. - status-detail JS: describe blocking beamline states when no explicit queue lock is present. Update help text.
This commit is contained in:
@@ -1028,12 +1028,16 @@ class WebpageGeneratorBase:
|
||||
f"beamline_states read error: {exc}", level="warning")
|
||||
beamline_states_info = {"enabled": None, "states": []}
|
||||
|
||||
# True if any watched state is out of spec. Defined identically to the
|
||||
# "N watched states currently blocking" count shown on the beamline
|
||||
# states card (renderBeamlineStates: states.filter(s => s.mismatched)),
|
||||
# True if the scan interlock is enabled AND at least one watched state
|
||||
# is out of its accepted range. Gated on `enabled`: a mismatched state
|
||||
# while the interlock is disabled does not actually block a scan, so it
|
||||
# must not raise the 'blocked' status. Kept in lock-step with the
|
||||
# beamline-states card summary (renderBeamlineStates), which likewise
|
||||
# only calls mismatched states "blocking" when the interlock is enabled,
|
||||
# so the top status pill and that card can never disagree.
|
||||
beamline_blocking = any(
|
||||
s.get("mismatched") for s in beamline_states_info.get("states", [])
|
||||
beamline_blocking = bool(
|
||||
beamline_states_info.get("enabled") is True
|
||||
and any(s.get("mismatched") for s in beamline_states_info.get("states", []))
|
||||
)
|
||||
|
||||
# Current scan number (the BEC scan in progress right now, e.g. for
|
||||
@@ -2684,10 +2688,19 @@ function renderBeamlineStates(bl){{
|
||||
return;
|
||||
}}
|
||||
|
||||
summary.innerHTML = 'Scan interlock <strong>'+enabledTxt+'</strong>'
|
||||
+ (mismatched.length>0
|
||||
? ' · <strong>'+mismatched.length+'</strong> watched state'+(mismatched.length>1?'s':'')+' currently blocking'
|
||||
: ' · all watched states OK');
|
||||
// "Blocking" only applies when the interlock is enabled — a mismatched
|
||||
// state while disabled/unknown is out of spec but does not block a scan.
|
||||
// Kept in lock-step with the Python beamline_blocking gate so this card and
|
||||
// the top status pill never disagree.
|
||||
let blockNote;
|
||||
if(mismatched.length===0){{
|
||||
blockNote=' · all watched states OK';
|
||||
}} else if(bl&&bl.enabled===true){{
|
||||
blockNote=' · <strong>'+mismatched.length+'</strong> watched state'+(mismatched.length>1?'s':'')+' currently blocking';
|
||||
}} else {{
|
||||
blockNote=' · <strong>'+mismatched.length+'</strong> watched state'+(mismatched.length>1?'s':'')+' out of spec (interlock '+enabledTxt+', not blocking)';
|
||||
}}
|
||||
summary.innerHTML = 'Scan interlock <strong>'+enabledTxt+'</strong>'+blockNote;
|
||||
|
||||
let html='';
|
||||
states.forEach(s=>{{
|
||||
|
||||
Reference in New Issue
Block a user