diff --git a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py index 7613c76..8db13a1 100644 --- a/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py +++ b/csaxs_bec/bec_ipython_client/plugins/flomni/flomni_webpage_generator.py @@ -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 '+enabledTxt+'' - + (mismatched.length>0 - ? ' · '+mismatched.length+' 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=' · '+mismatched.length+' watched state'+(mismatched.length>1?'s':'')+' currently blocking'; + }} else {{ + blockNote=' · '+mismatched.length+' watched state'+(mismatched.length>1?'s':'')+' out of spec (interlock '+enabledTxt+', not blocking)'; + }} + summary.innerHTML = 'Scan interlock '+enabledTxt+''+blockNote; let html=''; states.forEach(s=>{{