Improve macro-execute function and simplify schedule in macro action
This commit is contained in:
		
							parent
							
								
									11e1a51a2a
								
							
						
					
					
						commit
						d76bf0f711
					
				
					 2 changed files with 54 additions and 30 deletions
				
			
		
							
								
								
									
										10
									
								
								api.v1.json
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								api.v1.json
									
										
									
									
									
								
							| 
						 | 
					@ -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"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue