Improve macro-execute function and simplify schedule in macro action

This commit is contained in:
Tobias Reisinger 2024-05-13 19:17:24 +02:00
parent 11e1a51a2a
commit d76bf0f711
Signed by: serguzim
GPG key ID: 13AD60C237A28DFE
2 changed files with 54 additions and 30 deletions

View file

@ -1116,14 +1116,14 @@
"$ref": "#/components/schemas/controller_id" "$ref": "#/components/schemas/controller_id"
}, },
"active_schedule": { "active_schedule": {
"$ref": "#/components/schemas/schedule-untagged" "$ref": "#/components/schemas/schedule_simple"
}, },
"schedules": { "schedules": {
"type": "array", "type": "array",
"maxItems": 7, "maxItems": 7,
"minItems": 7, "minItems": 7,
"items": { "items": {
"$ref": "#/components/schemas/schedule-untagged" "$ref": "#/components/schemas/schedule_simple"
} }
}, },
"tags": { "tags": {
@ -1139,8 +1139,8 @@
} }
} }
}, },
"schedule-untagged": { "schedule_simple": {
"title": "schedule", "title": "schedule (simple)",
"type": "object", "type": "object",
"description": "", "description": "",
"properties": { "properties": {
@ -1274,7 +1274,7 @@
"maximum": 6 "maximum": 6
}, },
"schedule": { "schedule": {
"$ref": "#/components/schemas/schedule" "$ref": "#/components/schemas/schedule_simple"
}, },
"relay": { "relay": {
"$ref": "#/components/schemas/relay" "$ref": "#/components/schemas/relay"

View file

@ -1,16 +1,14 @@
use actix::Addr; use actix::Addr;
use actix_web::{delete, get, HttpResponse, post, put, web}; use actix_web::{delete, get, HttpResponse, post, put, web};
use itertools::Itertools;
use sqlx::{Pool, Sqlite}; use sqlx::{Pool, Sqlite};
use sqlx::pool::PoolConnection;
use emgauwa_common::db::DbMacro; use emgauwa_common::db::{DbController, DbMacro};
use emgauwa_common::errors::{DatabaseError, EmgauwaError}; use emgauwa_common::errors::{DatabaseError, EmgauwaError};
use emgauwa_common::models::{convert_db_list, FromDbModel, Macro, MacroAction, Relay}; use emgauwa_common::models::{convert_db_list, FromDbModel, Macro, MacroAction, Relay};
use emgauwa_common::types::{ use emgauwa_common::types::{ControllerWsAction, EmgauwaUid, RequestMacroCreate, RequestMacroExecute, RequestMacroUpdate};
ControllerWsAction, EmgauwaUid, RequestMacroCreate, RequestMacroExecute, RequestMacroUpdate,
};
use crate::app_state; use crate::app_state;
use crate::app_state::AppState; use crate::app_state::AppState;
use crate::handlers::EmgauwaMessage; use crate::handlers::EmgauwaMessage;
@ -132,30 +130,15 @@ pub async fn execute(
action.execute(&mut pool_conn).await?; action.execute(&mut pool_conn).await?;
} }
let affected_controller_uids: Vec<EmgauwaUid> = actions let affected_controllers = collect_affected_controllers(&mut pool_conn, &actions).await?;
.iter()
.map(|action| action.relay.controller_id.clone())
.unique()
.collect();
for controller_uid in affected_controller_uids { for controller in affected_controllers {
let mut affected_relays: Vec<Relay> = Vec::new();
let mut affected_relay_ids: Vec<i64> = Vec::new();
for action in actions.iter_mut() { let affected_relays = collect_affected_relays(&mut pool_conn, &mut actions, &controller).await?;
if affected_relay_ids.contains(&action.relay.r.id)
|| action.relay.controller_id != controller_uid
{
continue;
}
action.relay.reload(&mut pool_conn)?;
affected_relays.push(action.relay.clone());
affected_relay_ids.push(action.relay.r.id);
}
app_state app_state
.send(app_state::Action { .send(app_state::Action {
controller_uid, controller_uid: controller.uid,
action: ControllerWsAction::Relays(affected_relays.clone()), action: ControllerWsAction::Relays(affected_relays.clone()),
}) })
.await??; .await??;
@ -163,3 +146,44 @@ pub async fn execute(
Ok(HttpResponse::Ok().emgauwa_message("macro got executed")) Ok(HttpResponse::Ok().emgauwa_message("macro got executed"))
} }
async fn collect_affected_controllers(
pool_conn: &mut PoolConnection<Sqlite>,
actions: &Vec<MacroAction>,
) -> Result<Vec<DbController>, DatabaseError> {
let mut affected_controllers: Vec<DbController> = Vec::new();
for action in actions {
let controller_id = action.relay.r.controller_id;
if affected_controllers
.iter()
.any(|controller| controller.id == controller_id)
{
continue
}
let controller = DbController::get(pool_conn, controller_id).await?
.ok_or(DatabaseError::NotFound)?;
affected_controllers.push(controller);
}
Ok(affected_controllers)
}
async fn collect_affected_relays(
pool_conn: &mut PoolConnection<Sqlite>,
actions: &mut Vec<MacroAction>,
controller: &DbController,
) -> Result<Vec<Relay>, DatabaseError> {
let mut affected_relays: Vec<Relay> = Vec::new();
for action in actions {
if affected_relays.iter().any(|relay| relay.r.id == action.relay.r.id)
|| action.relay.r.controller_id != controller.id
{
continue;
}
action.relay.reload(pool_conn)?;
affected_relays.push(action.relay.clone());
}
Ok(affected_relays)
}