diff --git a/src/handler/control.rs b/src/handler/control.rs index 6562ba2..49709b7 100644 --- a/src/handler/control.rs +++ b/src/handler/control.rs @@ -303,3 +303,88 @@ pub async fn get_event_list( query.pagination.page_size, ))) } + +pub async fn start_auto_unit( + State(state): State, + Path(unit_id): Path, +) -> Result { + let unit = crate::service::get_unit_by_id(&state.pool, unit_id) + .await? + .ok_or_else(|| ApiErr::NotFound("Unit not found".to_string(), None))?; + + if !unit.enabled { + return Err(ApiErr::BadRequest("Unit is disabled".to_string(), None)); + } + + let mut runtime = state.control_runtime.get_or_init(unit_id).await; + runtime.auto_enabled = true; + runtime.state = crate::control::runtime::UnitRuntimeState::Stopped; + runtime.current_stop_elapsed_sec = 0; + state.control_runtime.upsert(runtime).await; + + let _ = state.event_manager.send(crate::event::AppEvent::AutoControlStarted { unit_id }); + + Ok(Json(json!({ "ok_msg": "Auto control started", "unit_id": unit_id }))) +} + +pub async fn stop_auto_unit( + State(state): State, + Path(unit_id): Path, +) -> Result { + crate::service::get_unit_by_id(&state.pool, unit_id) + .await? + .ok_or_else(|| ApiErr::NotFound("Unit not found".to_string(), None))?; + + let mut runtime = state.control_runtime.get_or_init(unit_id).await; + runtime.auto_enabled = false; + state.control_runtime.upsert(runtime).await; + + let _ = state.event_manager.send(crate::event::AppEvent::AutoControlStopped { unit_id }); + + Ok(Json(json!({ "ok_msg": "Auto control stopped", "unit_id": unit_id }))) +} + +pub async fn ack_fault_unit( + State(state): State, + Path(unit_id): Path, +) -> Result { + crate::service::get_unit_by_id(&state.pool, unit_id) + .await? + .ok_or_else(|| ApiErr::NotFound("Unit not found".to_string(), None))?; + + let mut runtime = state.control_runtime.get_or_init(unit_id).await; + + if !runtime.fault_locked { + return Err(ApiErr::BadRequest( + "Unit is not fault locked".to_string(), + Some(json!({ "unit_id": unit_id })), + )); + } + if runtime.flt_active { + return Err(ApiErr::BadRequest( + "FLT is still active, cannot acknowledge".to_string(), + Some(json!({ "unit_id": unit_id })), + )); + } + + runtime.fault_locked = false; + runtime.manual_ack_required = false; + runtime.state = crate::control::runtime::UnitRuntimeState::Stopped; + state.control_runtime.upsert(runtime).await; + + let _ = state.event_manager.send(crate::event::AppEvent::FaultAcked { unit_id }); + + Ok(Json(json!({ "ok_msg": "Fault acknowledged", "unit_id": unit_id }))) +} + +pub async fn get_unit_runtime( + State(state): State, + Path(unit_id): Path, +) -> Result { + crate::service::get_unit_by_id(&state.pool, unit_id) + .await? + .ok_or_else(|| ApiErr::NotFound("Unit not found".to_string(), None))?; + + let runtime = state.control_runtime.get_or_init(unit_id).await; + Ok(Json(runtime)) +}