feat(event): add RemLocal/RemRecovered events for REM-triggered auto-stop
When any equipment's REM signal switches to local mode, fire a dedicated `unit.rem_local` event (with unit + equipment context) and record it to the event log. Also fire `unit.rem_recovered` when all REM signals return to remote. AutoControlStopped is still fired alongside RemLocal when auto was running at the time. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
4227747852
commit
7ae952f93e
|
|
@ -326,6 +326,22 @@ async fn check_fault_comm(
|
|||
.unwrap_or(false)
|
||||
});
|
||||
|
||||
// Find the first equipment that just switched to local (for event payload).
|
||||
let rem_local_eq_id = if any_rem_local && !runtime.rem_local {
|
||||
all_roles
|
||||
.iter()
|
||||
.find(|(_, roles)| {
|
||||
roles
|
||||
.get("rem")
|
||||
.and_then(|rp| monitor.get(&rp.point_id))
|
||||
.map(|m| !super::monitor_value_as_bool(m) && m.quality == PointQuality::Good)
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.map(|(eq_id, _)| *eq_id)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
drop(monitor);
|
||||
|
||||
let prev_comm = runtime.comm_locked;
|
||||
|
|
@ -362,10 +378,18 @@ async fn check_fault_comm(
|
|||
}
|
||||
}
|
||||
|
||||
// Stop auto-control when any equipment switches to local mode.
|
||||
if any_rem_local && runtime.auto_enabled {
|
||||
runtime.auto_enabled = false;
|
||||
let _ = state.event_manager.send(AppEvent::AutoControlStopped { unit_id: unit.id });
|
||||
// Fire RemLocal event when any equipment first switches to local mode.
|
||||
if let Some(eq_id) = rem_local_eq_id {
|
||||
let _ = state.event_manager.send(AppEvent::RemLocal { unit_id: unit.id, equipment_id: eq_id });
|
||||
if runtime.auto_enabled {
|
||||
runtime.auto_enabled = false;
|
||||
let _ = state.event_manager.send(AppEvent::AutoControlStopped { unit_id: unit.id });
|
||||
}
|
||||
}
|
||||
|
||||
// Fire RemRecovered when all rem signals return to remote.
|
||||
if prev_rem_local && !any_rem_local {
|
||||
let _ = state.event_manager.send(AppEvent::RemRecovered { unit_id: unit.id });
|
||||
}
|
||||
|
||||
runtime.comm_locked != prev_comm
|
||||
|
|
|
|||
27
src/event.rs
27
src/event.rs
|
|
@ -41,6 +41,8 @@ pub enum AppEvent {
|
|||
FaultAcked { unit_id: Uuid },
|
||||
CommLocked { unit_id: Uuid },
|
||||
CommRecovered { unit_id: Uuid },
|
||||
RemLocal { unit_id: Uuid, equipment_id: Uuid },
|
||||
RemRecovered { unit_id: Uuid },
|
||||
UnitStateChanged { unit_id: Uuid, from_state: String, to_state: String },
|
||||
PointNewValue(crate::telemetry::PointNewValue),
|
||||
}
|
||||
|
|
@ -245,6 +247,12 @@ async fn handle_control_event(
|
|||
AppEvent::CommRecovered { unit_id } => {
|
||||
tracing::info!("Comm recovered for unit {}", unit_id);
|
||||
}
|
||||
AppEvent::RemLocal { unit_id, equipment_id } => {
|
||||
tracing::warn!("REM local: unit={}, equipment={}", unit_id, equipment_id);
|
||||
}
|
||||
AppEvent::RemRecovered { unit_id } => {
|
||||
tracing::info!("REM recovered for unit {}", unit_id);
|
||||
}
|
||||
AppEvent::UnitStateChanged { unit_id, from_state, to_state } => {
|
||||
tracing::info!("Unit {} state: {} → {}", unit_id, from_state, to_state);
|
||||
}
|
||||
|
|
@ -413,6 +421,25 @@ async fn persist_event_if_needed(
|
|||
serde_json::json!({ "unit_id": unit_id }),
|
||||
))
|
||||
}
|
||||
AppEvent::RemLocal { unit_id, equipment_id } => {
|
||||
let unit_code = fetch_unit_code(pool, *unit_id).await;
|
||||
let eq_code = fetch_equipment_code(pool, *equipment_id).await;
|
||||
Some((
|
||||
"unit.rem_local", "warn",
|
||||
Some(*unit_id), Some(*equipment_id), None,
|
||||
format!("单元【{}】切换为本地控制,触发设备:{},自动控制已停止", unit_code, eq_code),
|
||||
serde_json::json!({ "unit_id": unit_id, "equipment_id": equipment_id }),
|
||||
))
|
||||
}
|
||||
AppEvent::RemRecovered { unit_id } => {
|
||||
let code = fetch_unit_code(pool, *unit_id).await;
|
||||
Some((
|
||||
"unit.rem_recovered", "info",
|
||||
Some(*unit_id), None, None,
|
||||
format!("单元【{}】已切换回远程控制", code),
|
||||
serde_json::json!({ "unit_id": unit_id }),
|
||||
))
|
||||
}
|
||||
AppEvent::UnitStateChanged { .. } => None,
|
||||
AppEvent::PointNewValue(_) => None,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue