fix(unit): block auto control start when fault is active or unacknowledged
Prevent starting unit auto control while fault_locked or manual_ack_required, enforcing that faults must be manually acknowledged before resuming automation. Also disable the Start Auto button in the frontend with descriptive tooltips. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f37924ae36
commit
00c16ae3d7
|
|
@ -96,7 +96,7 @@ async fn unit_task(state: AppState, store: Arc<ControlRuntimeStore>, unit_id: Uu
|
|||
}
|
||||
|
||||
// ── Wait when not active ──────────────────────────────────────────────
|
||||
if !runtime.auto_enabled || runtime.fault_locked || runtime.comm_locked {
|
||||
if !runtime.auto_enabled || runtime.fault_locked || runtime.comm_locked || runtime.manual_ack_required {
|
||||
tokio::select! {
|
||||
_ = fault_tick.tick() => {}
|
||||
_ = notify.notified() => {
|
||||
|
|
@ -261,7 +261,7 @@ async fn wait_phase(
|
|||
store.upsert(runtime.clone()).await;
|
||||
push_ws(state, &runtime).await;
|
||||
}
|
||||
if !runtime.auto_enabled || runtime.fault_locked || runtime.comm_locked {
|
||||
if !runtime.auto_enabled || runtime.fault_locked || runtime.comm_locked || runtime.manual_ack_required {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -488,6 +488,18 @@ pub async fn start_auto_unit(
|
|||
}
|
||||
|
||||
let mut runtime = state.control_runtime.get_or_init(unit_id).await;
|
||||
if runtime.fault_locked {
|
||||
return Err(ApiErr::BadRequest(
|
||||
"Unit is fault locked, cannot start auto control".to_string(),
|
||||
None,
|
||||
));
|
||||
}
|
||||
if runtime.manual_ack_required {
|
||||
return Err(ApiErr::BadRequest(
|
||||
"Fault acknowledgement required before starting auto control".to_string(),
|
||||
None,
|
||||
));
|
||||
}
|
||||
runtime.auto_enabled = true;
|
||||
runtime.state = crate::control::runtime::UnitRuntimeState::Stopped;
|
||||
state.control_runtime.upsert(runtime).await;
|
||||
|
|
@ -529,7 +541,7 @@ pub async fn batch_start_auto(
|
|||
skipped.push(unit.id);
|
||||
continue;
|
||||
}
|
||||
if runtime.fault_locked || runtime.comm_locked {
|
||||
if runtime.fault_locked || runtime.comm_locked || runtime.manual_ack_required {
|
||||
skipped.push(unit.id);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,10 +50,14 @@ export function renderOpsUnits() {
|
|||
const actions = item.querySelector(".ops-unit-item-actions");
|
||||
|
||||
const isAutoOn = runtime?.auto_enabled;
|
||||
const startBlocked = !isAutoOn && (runtime?.fault_locked || runtime?.manual_ack_required);
|
||||
const autoBtn = document.createElement("button");
|
||||
autoBtn.className = isAutoOn ? "danger" : "secondary";
|
||||
autoBtn.textContent = isAutoOn ? "Stop Auto" : "Start Auto";
|
||||
autoBtn.title = isAutoOn ? "停止自动控制" : "启动自动控制";
|
||||
autoBtn.disabled = startBlocked;
|
||||
autoBtn.title = startBlocked
|
||||
? (runtime?.fault_locked ? "设备故障中,无法启动自动控制" : "需人工确认故障后才可启动自动控制")
|
||||
: (isAutoOn ? "停止自动控制" : "启动自动控制");
|
||||
autoBtn.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
apiFetch(`/api/control/unit/${unit.id}/${isAutoOn ? "stop-auto" : "start-auto"}`, { method: "POST" })
|
||||
|
|
|
|||
|
|
@ -151,10 +151,14 @@ export function renderUnits() {
|
|||
actions.append(editBtn, deleteBtn);
|
||||
|
||||
const isAutoOn = runtime?.auto_enabled;
|
||||
const startBlocked = !isAutoOn && (runtime?.fault_locked || runtime?.manual_ack_required);
|
||||
const autoBtn = document.createElement("button");
|
||||
autoBtn.className = isAutoOn ? "danger" : "secondary";
|
||||
autoBtn.textContent = isAutoOn ? "Stop Auto" : "Start Auto";
|
||||
autoBtn.title = isAutoOn ? "停止自动控制" : "启动自动控制";
|
||||
autoBtn.disabled = startBlocked;
|
||||
autoBtn.title = startBlocked
|
||||
? (runtime?.fault_locked ? "设备故障中,无法启动自动控制" : "需人工确认故障后才可启动自动控制")
|
||||
: (isAutoOn ? "停止自动控制" : "启动自动控制");
|
||||
autoBtn.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
const url = `/api/control/unit/${unit.id}/${isAutoOn ? "stop-auto" : "start-auto"}`;
|
||||
|
|
|
|||
Loading…
Reference in New Issue