From bbe128e05542bf4b97520a4197879b786d407c4c Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Sat, 31 Aug 2024 20:26:16 +0200 Subject: [PATCH] Add the route to update a relay --- central_backend/src/devices/device.rs | 6 +-- central_backend/src/devices/devices_list.rs | 52 +++++++++++++++---- central_backend/src/energy/energy_actor.rs | 13 +++++ central_backend/src/server/servers.rs | 4 ++ .../src/server/web_api/relays_controller.rs | 21 ++++++++ .../src/routes/DeviceRoute/DeviceRelays.tsx | 7 ++- 6 files changed, 88 insertions(+), 15 deletions(-) diff --git a/central_backend/src/devices/device.rs b/central_backend/src/devices/device.rs index aa6913f..e75eb19 100644 --- a/central_backend/src/devices/device.rs +++ b/central_backend/src/devices/device.rs @@ -92,11 +92,11 @@ pub struct DeviceRelay { #[serde(default)] pub id: DeviceRelayID, /// Human-readable name for the relay - name: String, + pub name: String, /// Whether this relay can be turned on or not - enabled: bool, + pub enabled: bool, /// Relay priority when selecting relays to turn on. 0 = lowest priority - priority: usize, + pub priority: usize, /// Estimated consumption of the electrical equipment triggered by the relay consumption: usize, /// Minimal time this relay shall be left on before it can be turned off (in seconds) diff --git a/central_backend/src/devices/devices_list.rs b/central_backend/src/devices/devices_list.rs index 0f0fa95..bc8b23e 100644 --- a/central_backend/src/devices/devices_list.rs +++ b/central_backend/src/devices/devices_list.rs @@ -23,6 +23,8 @@ pub enum DevicesListError { DeviceNotFound, #[error("Requested device is not validated")] DeviceNotValidated, + #[error("Failed to update relay configuration: {0}")] + UpdateRelayFailed(&'static str), #[error("Failed to delete relay: {0}")] DeleteRelayFailed(&'static str), } @@ -224,12 +226,23 @@ impl DevicesList { self.relays_list().into_iter().find(|i| i.id == relay_id) } - /// Get the device hosting a relay - pub fn relay_get_device(&self, relay_id: DeviceRelayID) -> Option { + /// Get a mutable reference on a single relay + pub fn relay_get_single_mut(&mut self, relay_id: DeviceRelayID) -> Option<&mut DeviceRelay> { self.0 - .iter() + .iter_mut() + .find(|d| d.1.relays.iter().any(|r| r.id == relay_id))? + .1 + .relays + .iter_mut() + .find(|r| r.id == relay_id) + } + + /// Get the device hosting a relay + pub fn relay_get_device(&mut self, relay_id: DeviceRelayID) -> Option<&mut Device> { + self.0 + .iter_mut() .find(|r| r.1.relays.iter().any(|r| r.id == relay_id)) - .map(|d| d.1.clone()) + .map(|d| d.1) } /// Get all the relays that depends directly on a relay @@ -240,6 +253,27 @@ impl DevicesList { .collect() } + /// Update a relay configuration + pub fn relay_update(&mut self, relay: DeviceRelay) -> anyhow::Result<()> { + let device = self + .relay_get_device(relay.id) + .ok_or(DevicesListError::UpdateRelayFailed( + "Relay does not exists!", + ))?; + + let idx = device.relays.iter().position(|r| r.id == relay.id).ok_or( + DevicesListError::UpdateRelayFailed("Relay index not found!"), + )?; + + // Update the relay configuration + device.relays[idx] = relay; + let device_id = device.id.clone(); + + self.persist_dev_config(&device_id)?; + + Ok(()) + } + /// Delete a relay pub fn relay_delete(&mut self, relay_id: DeviceRelayID) -> anyhow::Result<()> { if !self.relay_get_direct_dependencies(relay_id).is_empty() { @@ -256,14 +290,10 @@ impl DevicesList { "Relay does not exists!", ))?; - let dev = self - .0 - .get_mut(&device.id) - .ok_or(DevicesListError::UpdateDeviceFailedDeviceNotFound)?; + device.relays.retain(|r| r.id != relay_id); - dev.relays.retain(|r| r.id != relay_id); - - self.persist_dev_config(&device.id)?; + let device_id = device.id.clone(); + self.persist_dev_config(&device_id)?; Ok(()) } diff --git a/central_backend/src/energy/energy_actor.rs b/central_backend/src/energy/energy_actor.rs index a1fd019..8ecff6a 100644 --- a/central_backend/src/energy/energy_actor.rs +++ b/central_backend/src/energy/energy_actor.rs @@ -213,6 +213,19 @@ impl Handler for EnergyActor { } } +/// Update a device relay +#[derive(Message)] +#[rtype(result = "anyhow::Result<()>")] +pub struct UpdateDeviceRelay(pub DeviceRelay); + +impl Handler for EnergyActor { + type Result = anyhow::Result<()>; + + fn handle(&mut self, msg: UpdateDeviceRelay, _ctx: &mut Context) -> Self::Result { + self.devices.relay_update(msg.0) + } +} + /// Delete a device relay #[derive(Message)] #[rtype(result = "anyhow::Result<()>")] diff --git a/central_backend/src/server/servers.rs b/central_backend/src/server/servers.rs index 5011eae..f18e63f 100644 --- a/central_backend/src/server/servers.rs +++ b/central_backend/src/server/servers.rs @@ -169,6 +169,10 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()> "/web_api/relay/create", web::post().to(relays_controller::create), ) + .route( + "/web_api/relay/{id}", + web::put().to(relays_controller::update), + ) .route( "/web_api/relay/{id}", web::delete().to(relays_controller::delete), diff --git a/central_backend/src/server/web_api/relays_controller.rs b/central_backend/src/server/web_api/relays_controller.rs index 4e47d38..3ff5dfc 100644 --- a/central_backend/src/server/web_api/relays_controller.rs +++ b/central_backend/src/server/web_api/relays_controller.rs @@ -64,6 +64,27 @@ pub struct RelayIDInPath { id: DeviceRelayID, } +/// Update a relay configuration +pub async fn update( + actor: WebEnergyActor, + mut req: web::Json, + path: web::Path, +) -> HttpResult { + req.id = path.id; + + let list = actor.send(energy_actor::GetRelaysList).await?; + + if let Some(e) = req.error(&list) { + log::error!("Invalid relay update query: {e}"); + return Ok(HttpResponse::BadRequest().json(e)); + } + + // Create the device relay + actor.send(energy_actor::UpdateDeviceRelay(req.0)).await??; + + Ok(HttpResponse::Accepted().finish()) +} + /// Delete an existing relay pub async fn delete(actor: WebEnergyActor, path: web::Path) -> HttpResult { actor diff --git a/central_frontend/src/routes/DeviceRoute/DeviceRelays.tsx b/central_frontend/src/routes/DeviceRoute/DeviceRelays.tsx index 9c2de14..a0810ad 100644 --- a/central_frontend/src/routes/DeviceRoute/DeviceRelays.tsx +++ b/central_frontend/src/routes/DeviceRoute/DeviceRelays.tsx @@ -35,6 +35,11 @@ export function DeviceRelays(p: { setCurrRelay(undefined); }; + const updateRelay = async (r: DeviceRelay) => { + setDialogOpen(true); + setCurrRelay(r); + }; + const deleteRelay = async (r: DeviceRelay) => { if ( !(await confirm("Do you really want to delete this relay configuration?")) @@ -95,7 +100,7 @@ export function DeviceRelays(p: { secondaryAction={ <> - + updateRelay(r)}>