Add macros
This commit is contained in:
parent
51aa0d3c99
commit
661b5004e8
28 changed files with 582 additions and 2 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -554,6 +554,12 @@ paths:
|
||||||
responses:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: OK
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/macro'
|
||||||
operationId: get-api-v1-macros
|
operationId: get-api-v1-macros
|
||||||
description: Receive a list with all available macros.
|
description: Receive a list with all available macros.
|
||||||
post:
|
post:
|
||||||
|
|
161
emgauwa-core/src/handlers/v1/macros.rs
Normal file
161
emgauwa-core/src/handlers/v1/macros.rs
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
use actix::Addr;
|
||||||
|
use actix_web::{delete, get, post, put, web, HttpResponse};
|
||||||
|
use emgauwa_lib::db::DbMacro;
|
||||||
|
use emgauwa_lib::errors::{DatabaseError, EmgauwaError};
|
||||||
|
use emgauwa_lib::models::{convert_db_list, FromDbModel, Macro, MacroAction, Relay};
|
||||||
|
use emgauwa_lib::types::{
|
||||||
|
ControllerWsAction, EmgauwaUid, RequestMacroCreate, RequestMacroExecute, RequestMacroUpdate,
|
||||||
|
};
|
||||||
|
use itertools::Itertools;
|
||||||
|
use sqlx::{Pool, Sqlite};
|
||||||
|
|
||||||
|
use crate::app_state;
|
||||||
|
use crate::app_state::AppState;
|
||||||
|
|
||||||
|
#[get("/macros")]
|
||||||
|
pub async fn index(pool: web::Data<Pool<Sqlite>>) -> Result<HttpResponse, EmgauwaError> {
|
||||||
|
let mut pool_conn = pool.acquire().await?;
|
||||||
|
|
||||||
|
let db_macros = DbMacro::get_all(&mut pool_conn).await?;
|
||||||
|
let macros: Vec<Macro> = convert_db_list(&mut pool_conn, db_macros)?;
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok().json(macros))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/macros/{macro_id}")]
|
||||||
|
pub async fn show(
|
||||||
|
pool: web::Data<Pool<Sqlite>>,
|
||||||
|
path: web::Path<(String,)>,
|
||||||
|
) -> Result<HttpResponse, EmgauwaError> {
|
||||||
|
let mut pool_conn = pool.acquire().await?;
|
||||||
|
|
||||||
|
let (macro_uid,) = path.into_inner();
|
||||||
|
let uid = EmgauwaUid::try_from(macro_uid.as_str())?;
|
||||||
|
|
||||||
|
let db_macro = DbMacro::get_by_uid(&mut pool_conn, &uid)
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::NotFound)?;
|
||||||
|
|
||||||
|
let return_macro = Macro::from_db_model(&mut pool_conn, db_macro)?;
|
||||||
|
Ok(HttpResponse::Ok().json(return_macro))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/macros")]
|
||||||
|
pub async fn add(
|
||||||
|
pool: web::Data<Pool<Sqlite>>,
|
||||||
|
data: web::Json<RequestMacroCreate>,
|
||||||
|
) -> Result<HttpResponse, EmgauwaError> {
|
||||||
|
let mut pool_conn = pool.acquire().await?;
|
||||||
|
|
||||||
|
let new_macro = DbMacro::create(&mut pool_conn, EmgauwaUid::default(), &data.name).await?;
|
||||||
|
|
||||||
|
new_macro
|
||||||
|
.set_actions(&mut pool_conn, data.actions.as_slice())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let return_macro = Macro::from_db_model(&mut pool_conn, new_macro)?;
|
||||||
|
Ok(HttpResponse::Created().json(return_macro))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[put("/macros/{macro_id}")]
|
||||||
|
pub async fn update(
|
||||||
|
pool: web::Data<Pool<Sqlite>>,
|
||||||
|
path: web::Path<(String,)>,
|
||||||
|
data: web::Json<RequestMacroUpdate>,
|
||||||
|
) -> Result<HttpResponse, EmgauwaError> {
|
||||||
|
let mut pool_conn = pool.acquire().await?;
|
||||||
|
|
||||||
|
let (macro_uid,) = path.into_inner();
|
||||||
|
let uid = EmgauwaUid::try_from(macro_uid.as_str())?;
|
||||||
|
|
||||||
|
let db_macro = DbMacro::get_by_uid(&mut pool_conn, &uid)
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::NotFound)?;
|
||||||
|
|
||||||
|
if let Some(name) = &data.name {
|
||||||
|
db_macro.update(&mut pool_conn, name).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(actions) = &data.actions {
|
||||||
|
db_macro
|
||||||
|
.set_actions(&mut pool_conn, actions.as_slice())
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let return_macro = Macro::from_db_model(&mut pool_conn, db_macro)?;
|
||||||
|
Ok(HttpResponse::Ok().json(return_macro))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[delete("/macros/{macro_id}")]
|
||||||
|
pub async fn delete(
|
||||||
|
pool: web::Data<Pool<Sqlite>>,
|
||||||
|
path: web::Path<(String,)>,
|
||||||
|
) -> Result<HttpResponse, EmgauwaError> {
|
||||||
|
let mut pool_conn = pool.acquire().await?;
|
||||||
|
|
||||||
|
let (macro_uid,) = path.into_inner();
|
||||||
|
let uid = EmgauwaUid::try_from(macro_uid.as_str())?;
|
||||||
|
|
||||||
|
DbMacro::delete_by_uid(&mut pool_conn, uid).await?;
|
||||||
|
Ok(HttpResponse::Ok().json("macro got deleted"))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[put("/macros/{macro_id}/execute")]
|
||||||
|
pub async fn execute(
|
||||||
|
pool: web::Data<Pool<Sqlite>>,
|
||||||
|
app_state: web::Data<Addr<AppState>>,
|
||||||
|
path: web::Path<(String,)>,
|
||||||
|
query: web::Query<RequestMacroExecute>,
|
||||||
|
) -> Result<HttpResponse, EmgauwaError> {
|
||||||
|
let mut pool_conn = pool.acquire().await?;
|
||||||
|
|
||||||
|
let (macro_uid,) = path.into_inner();
|
||||||
|
let uid = EmgauwaUid::try_from(macro_uid.as_str())?;
|
||||||
|
|
||||||
|
let db_macro = DbMacro::get_by_uid(&mut pool_conn, &uid)
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::NotFound)?;
|
||||||
|
|
||||||
|
let actions_db = match query.weekday {
|
||||||
|
None => db_macro.get_actions(&mut pool_conn).await?,
|
||||||
|
Some(weekday) => {
|
||||||
|
db_macro
|
||||||
|
.get_actions_weekday(&mut pool_conn, weekday)
|
||||||
|
.await?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut actions: Vec<MacroAction> = convert_db_list(&mut pool_conn, actions_db)?;
|
||||||
|
|
||||||
|
for action in &actions {
|
||||||
|
action.execute(&mut pool_conn).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let affected_controller_uids: Vec<EmgauwaUid> = actions
|
||||||
|
.iter()
|
||||||
|
.map(|action| action.relay.controller_id.clone())
|
||||||
|
.unique()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for controller_uid in affected_controller_uids {
|
||||||
|
let mut affected_relays: Vec<Relay> = Vec::new();
|
||||||
|
let mut affected_relay_ids: Vec<i64> = Vec::new();
|
||||||
|
|
||||||
|
for action in actions.iter_mut() {
|
||||||
|
if affected_relay_ids.contains(&action.relay.r.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
action.relay.reload(&mut pool_conn)?;
|
||||||
|
affected_relays.push(action.relay.clone());
|
||||||
|
affected_relay_ids.push(action.relay.r.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
app_state
|
||||||
|
.send(app_state::Action {
|
||||||
|
controller_uid,
|
||||||
|
action: ControllerWsAction::Relays(affected_relays.clone()),
|
||||||
|
})
|
||||||
|
.await??;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok().finish()) // TODO add a message?
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod controllers;
|
pub mod controllers;
|
||||||
|
pub mod macros;
|
||||||
pub mod relays;
|
pub mod relays;
|
||||||
pub mod schedules;
|
pub mod schedules;
|
||||||
pub mod tags;
|
pub mod tags;
|
||||||
|
|
|
@ -108,6 +108,12 @@ async fn main() -> Result<(), std::io::Error> {
|
||||||
.service(handlers::v1::tags::show)
|
.service(handlers::v1::tags::show)
|
||||||
.service(handlers::v1::tags::delete)
|
.service(handlers::v1::tags::delete)
|
||||||
.service(handlers::v1::tags::add)
|
.service(handlers::v1::tags::add)
|
||||||
|
.service(handlers::v1::macros::index)
|
||||||
|
.service(handlers::v1::macros::show)
|
||||||
|
.service(handlers::v1::macros::add)
|
||||||
|
.service(handlers::v1::macros::update)
|
||||||
|
.service(handlers::v1::macros::delete)
|
||||||
|
.service(handlers::v1::macros::execute)
|
||||||
.service(handlers::v1::ws::ws_controllers)
|
.service(handlers::v1::ws::ws_controllers)
|
||||||
.service(handlers::v1::ws::ws_relays),
|
.service(handlers::v1::ws::ws_relays),
|
||||||
)
|
)
|
||||||
|
|
166
emgauwa-lib/src/db/macro.rs
Normal file
166
emgauwa-lib/src/db/macro.rs
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use sqlx::pool::PoolConnection;
|
||||||
|
use sqlx::Sqlite;
|
||||||
|
|
||||||
|
use crate::db::{DbController, DbMacroAction, DbRelay, DbSchedule};
|
||||||
|
use crate::errors::DatabaseError;
|
||||||
|
use crate::types::{EmgauwaUid, RequestMacroAction};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct DbMacro {
|
||||||
|
#[serde(skip)]
|
||||||
|
pub id: i64,
|
||||||
|
#[serde(rename = "id")]
|
||||||
|
pub uid: EmgauwaUid,
|
||||||
|
pub name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl DbMacro {
|
||||||
|
pub async fn get_all(conn: &mut PoolConnection<Sqlite>) -> Result<Vec<DbMacro>, DatabaseError> {
|
||||||
|
sqlx::query_as!(DbMacro, "SELECT * FROM macros")
|
||||||
|
.fetch_all(conn.deref_mut())
|
||||||
|
.await
|
||||||
|
.map_err(DatabaseError::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
id: i64,
|
||||||
|
) -> Result<Option<DbMacro>, DatabaseError> {
|
||||||
|
sqlx::query_as!(DbMacro, "SELECT * FROM macros WHERE id = ?", id)
|
||||||
|
.fetch_optional(conn.deref_mut())
|
||||||
|
.await
|
||||||
|
.map_err(DatabaseError::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_by_uid(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
filter_uid: &EmgauwaUid,
|
||||||
|
) -> Result<Option<DbMacro>, DatabaseError> {
|
||||||
|
sqlx::query_as!(DbMacro, "SELECT * FROM macros WHERE uid = ?", filter_uid)
|
||||||
|
.fetch_optional(conn.deref_mut())
|
||||||
|
.await
|
||||||
|
.map_err(DatabaseError::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
new_uid: EmgauwaUid,
|
||||||
|
new_name: &str,
|
||||||
|
) -> Result<DbMacro, DatabaseError> {
|
||||||
|
sqlx::query_as!(
|
||||||
|
DbMacro,
|
||||||
|
"INSERT INTO macros (uid, name) VALUES (?, ?) RETURNING *",
|
||||||
|
new_uid,
|
||||||
|
new_name
|
||||||
|
)
|
||||||
|
.fetch_optional(conn.deref_mut())
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::InsertGetError)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete(&self, conn: &mut PoolConnection<Sqlite>) -> Result<(), DatabaseError> {
|
||||||
|
sqlx::query!("DELETE FROM macros WHERE id = ?", self.id)
|
||||||
|
.execute(conn.deref_mut())
|
||||||
|
.await
|
||||||
|
.map(|res| match res.rows_affected() {
|
||||||
|
0 => Err(DatabaseError::DeleteError),
|
||||||
|
_ => Ok(()),
|
||||||
|
})?
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete_by_uid(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
filter_uid: EmgauwaUid,
|
||||||
|
) -> Result<(), DatabaseError> {
|
||||||
|
if sqlx::query_scalar!("SELECT 1 FROM macros WHERE uid = ?", filter_uid)
|
||||||
|
.fetch_optional(conn.deref_mut())
|
||||||
|
.await?
|
||||||
|
.is_none()
|
||||||
|
{
|
||||||
|
return Err(DatabaseError::NotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlx::query!("DELETE FROM macros WHERE uid = ?", filter_uid)
|
||||||
|
.execute(conn.deref_mut())
|
||||||
|
.await
|
||||||
|
.map(|res| match res.rows_affected() {
|
||||||
|
0 => Err(DatabaseError::DeleteError),
|
||||||
|
_ => Ok(()),
|
||||||
|
})?
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update(
|
||||||
|
&self,
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
new_name: &str,
|
||||||
|
) -> Result<DbMacro, DatabaseError> {
|
||||||
|
sqlx::query!("UPDATE relays SET name = ? WHERE id = ?", new_name, self.id,)
|
||||||
|
.execute(conn.deref_mut())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
DbMacro::get(conn, self.id)
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::UpdateGetError)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn set_actions(
|
||||||
|
&self,
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
new_actions: &[RequestMacroAction],
|
||||||
|
) -> Result<(), DatabaseError> {
|
||||||
|
sqlx::query!("DELETE FROM macro_actions WHERE macro_id = ?", self.id)
|
||||||
|
.execute(conn.deref_mut())
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
for new_action in new_actions {
|
||||||
|
let controller = DbController::get_by_uid(conn, &new_action.relay.controller_id)
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::NotFound)?;
|
||||||
|
let relay =
|
||||||
|
DbRelay::get_by_controller_and_num(conn, &controller, new_action.relay.number)
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::NotFound)?;
|
||||||
|
|
||||||
|
let schedule = DbSchedule::get_by_uid(conn, &new_action.schedule.id)
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::NotFound)?;
|
||||||
|
|
||||||
|
DbMacroAction::create(conn, self, &relay, &schedule, new_action.weekday).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_actions(
|
||||||
|
&self,
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
) -> Result<Vec<DbMacroAction>, DatabaseError> {
|
||||||
|
sqlx::query_as!(
|
||||||
|
DbMacroAction,
|
||||||
|
"SELECT * FROM macro_actions WHERE macro_id = ?",
|
||||||
|
self.id
|
||||||
|
)
|
||||||
|
.fetch_all(conn.deref_mut())
|
||||||
|
.await
|
||||||
|
.map_err(DatabaseError::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_actions_weekday(
|
||||||
|
&self,
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
weekday: i64,
|
||||||
|
) -> Result<Vec<DbMacroAction>, DatabaseError> {
|
||||||
|
sqlx::query_as!(
|
||||||
|
DbMacroAction,
|
||||||
|
"SELECT * FROM macro_actions WHERE macro_id = ? AND weekday = ?",
|
||||||
|
self.id,
|
||||||
|
weekday
|
||||||
|
)
|
||||||
|
.fetch_all(conn.deref_mut())
|
||||||
|
.await
|
||||||
|
.map_err(DatabaseError::from)
|
||||||
|
}
|
||||||
|
}
|
99
emgauwa-lib/src/db/macro_action.rs
Normal file
99
emgauwa-lib/src/db/macro_action.rs
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
|
use sqlx::pool::PoolConnection;
|
||||||
|
use sqlx::Sqlite;
|
||||||
|
|
||||||
|
use crate::db::{DbMacro, DbRelay, DbSchedule};
|
||||||
|
use crate::errors::DatabaseError;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct DbMacroAction {
|
||||||
|
pub id: i64,
|
||||||
|
pub macro_id: i64,
|
||||||
|
pub relay_id: i64,
|
||||||
|
pub schedule_id: i64,
|
||||||
|
pub weekday: i64, // should be u8, but sqlite will store it as i64
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl DbMacroAction {
|
||||||
|
pub async fn get_all(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
) -> Result<Vec<DbMacroAction>, DatabaseError> {
|
||||||
|
sqlx::query_as!(DbMacroAction, "SELECT * FROM macro_actions")
|
||||||
|
.fetch_all(conn.deref_mut())
|
||||||
|
.await
|
||||||
|
.map_err(DatabaseError::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
id: i64,
|
||||||
|
) -> Result<Option<DbMacroAction>, DatabaseError> {
|
||||||
|
sqlx::query_as!(
|
||||||
|
DbMacroAction,
|
||||||
|
"SELECT * FROM macro_actions WHERE id = ?",
|
||||||
|
id
|
||||||
|
)
|
||||||
|
.fetch_optional(conn.deref_mut())
|
||||||
|
.await
|
||||||
|
.map_err(DatabaseError::from)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
new_macro: &DbMacro,
|
||||||
|
new_relay: &DbRelay,
|
||||||
|
new_schedule: &DbSchedule,
|
||||||
|
new_weekday: i64,
|
||||||
|
) -> Result<DbMacroAction, DatabaseError> {
|
||||||
|
sqlx::query_as!(
|
||||||
|
DbMacroAction,
|
||||||
|
"INSERT INTO macro_actions (macro_id, relay_id, schedule_id, weekday) VALUES (?, ?, ?, ?) RETURNING *",
|
||||||
|
new_macro.id,
|
||||||
|
new_relay.id,
|
||||||
|
new_schedule.id,
|
||||||
|
new_weekday
|
||||||
|
)
|
||||||
|
.fetch_optional(conn.deref_mut())
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::InsertGetError)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete(&self, conn: &mut PoolConnection<Sqlite>) -> Result<(), DatabaseError> {
|
||||||
|
sqlx::query!("DELETE FROM macro_actions WHERE id = ?", self.id)
|
||||||
|
.execute(conn.deref_mut())
|
||||||
|
.await
|
||||||
|
.map(|res| match res.rows_affected() {
|
||||||
|
0 => Err(DatabaseError::DeleteError),
|
||||||
|
_ => Ok(()),
|
||||||
|
})?
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_relay(
|
||||||
|
&self,
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
) -> Result<DbRelay, DatabaseError> {
|
||||||
|
DbRelay::get(conn, self.relay_id)
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::NotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_schedule(
|
||||||
|
&self,
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
) -> Result<DbSchedule, DatabaseError> {
|
||||||
|
DbSchedule::get(conn, self.schedule_id)
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::NotFound)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_macro(
|
||||||
|
&self,
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
) -> Result<DbMacro, DatabaseError> {
|
||||||
|
DbMacro::get(conn, self.macro_id)
|
||||||
|
.await?
|
||||||
|
.ok_or(DatabaseError::NotFound)
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ use sqlx::{ConnectOptions, Pool, Sqlite};
|
||||||
mod controllers;
|
mod controllers;
|
||||||
mod junction_relay_schedule;
|
mod junction_relay_schedule;
|
||||||
mod junction_tag;
|
mod junction_tag;
|
||||||
|
mod r#macro;
|
||||||
|
mod macro_action;
|
||||||
mod model_utils;
|
mod model_utils;
|
||||||
mod relays;
|
mod relays;
|
||||||
mod schedules;
|
mod schedules;
|
||||||
|
@ -15,6 +17,8 @@ mod tag;
|
||||||
pub use controllers::DbController;
|
pub use controllers::DbController;
|
||||||
pub use junction_relay_schedule::DbJunctionRelaySchedule;
|
pub use junction_relay_schedule::DbJunctionRelaySchedule;
|
||||||
pub use junction_tag::DbJunctionTag;
|
pub use junction_tag::DbJunctionTag;
|
||||||
|
pub use macro_action::DbMacroAction;
|
||||||
|
pub use r#macro::DbMacro;
|
||||||
pub use relays::DbRelay;
|
pub use relays::DbRelay;
|
||||||
pub use schedules::{DbPeriods, DbSchedule};
|
pub use schedules::{DbPeriods, DbSchedule};
|
||||||
pub use tag::DbTag;
|
pub use tag::DbTag;
|
||||||
|
|
42
emgauwa-lib/src/models/macro.rs
Normal file
42
emgauwa-lib/src/models/macro.rs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
use futures::executor::block_on;
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use sqlx::pool::PoolConnection;
|
||||||
|
use sqlx::Sqlite;
|
||||||
|
|
||||||
|
use crate::db::DbMacro;
|
||||||
|
use crate::errors::DatabaseError;
|
||||||
|
use crate::models::{convert_db_list, FromDbModel, MacroAction};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct Macro {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub m: DbMacro,
|
||||||
|
pub actions: Vec<MacroAction>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl FromDbModel for Macro {
|
||||||
|
type DbModel = DbMacro;
|
||||||
|
type DbModelCache = ();
|
||||||
|
|
||||||
|
fn from_db_model(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
db_model: Self::DbModel,
|
||||||
|
) -> Result<Self, DatabaseError> {
|
||||||
|
Self::from_db_model_cache(conn, db_model, ())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_db_model_cache(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
db_model: Self::DbModel,
|
||||||
|
_cache: Self::DbModelCache,
|
||||||
|
) -> Result<Self, DatabaseError> {
|
||||||
|
let actions_db = block_on(db_model.get_actions(conn))?;
|
||||||
|
let actions: Vec<MacroAction> = convert_db_list(conn, actions_db)?;
|
||||||
|
|
||||||
|
Ok(Macro {
|
||||||
|
m: db_model,
|
||||||
|
actions,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
56
emgauwa-lib/src/models/macro_action.rs
Normal file
56
emgauwa-lib/src/models/macro_action.rs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
use futures::executor::block_on;
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use sqlx::pool::PoolConnection;
|
||||||
|
use sqlx::Sqlite;
|
||||||
|
|
||||||
|
use crate::db::{DbJunctionRelaySchedule, DbMacroAction};
|
||||||
|
use crate::errors::{DatabaseError, EmgauwaError};
|
||||||
|
use crate::models::{FromDbModel, Relay, Schedule};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct MacroAction {
|
||||||
|
pub schedule: Schedule,
|
||||||
|
pub relay: Relay,
|
||||||
|
pub weekday: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl FromDbModel for MacroAction {
|
||||||
|
type DbModel = DbMacroAction;
|
||||||
|
type DbModelCache = ();
|
||||||
|
|
||||||
|
fn from_db_model(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
db_model: Self::DbModel,
|
||||||
|
) -> Result<Self, DatabaseError> {
|
||||||
|
Self::from_db_model_cache(conn, db_model, ())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_db_model_cache(
|
||||||
|
conn: &mut PoolConnection<Sqlite>,
|
||||||
|
db_model: Self::DbModel,
|
||||||
|
_cache: Self::DbModelCache,
|
||||||
|
) -> Result<Self, DatabaseError> {
|
||||||
|
let schedule_db = block_on(db_model.get_schedule(conn))?;
|
||||||
|
let schedule = Schedule::from_db_model(conn, schedule_db)?;
|
||||||
|
|
||||||
|
let relay_db = block_on(db_model.get_relay(conn))?;
|
||||||
|
let relay = Relay::from_db_model(conn, relay_db)?;
|
||||||
|
|
||||||
|
let weekday = db_model.weekday;
|
||||||
|
|
||||||
|
Ok(MacroAction {
|
||||||
|
schedule,
|
||||||
|
relay,
|
||||||
|
weekday,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MacroAction {
|
||||||
|
pub async fn execute(&self, conn: &mut PoolConnection<Sqlite>) -> Result<(), EmgauwaError> {
|
||||||
|
DbJunctionRelaySchedule::set_schedule(conn, &self.relay.r, &self.schedule.s, self.weekday)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,13 @@
|
||||||
mod controller;
|
mod controller;
|
||||||
|
mod r#macro;
|
||||||
|
mod macro_action;
|
||||||
mod relay;
|
mod relay;
|
||||||
mod schedule;
|
mod schedule;
|
||||||
mod tag;
|
mod tag;
|
||||||
|
|
||||||
pub use controller::Controller;
|
pub use controller::Controller;
|
||||||
|
pub use macro_action::MacroAction;
|
||||||
|
pub use r#macro::Macro;
|
||||||
pub use relay::Relay;
|
pub use relay::Relay;
|
||||||
pub use schedule::Schedule;
|
pub use schedule::Schedule;
|
||||||
use sqlx::pool::PoolConnection;
|
use sqlx::pool::PoolConnection;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use sqlx::Sqlite;
|
||||||
|
|
||||||
use crate::db::{DbPeriods, DbSchedule};
|
use crate::db::{DbPeriods, DbSchedule};
|
||||||
use crate::errors::DatabaseError;
|
use crate::errors::DatabaseError;
|
||||||
use crate::types::ScheduleUid;
|
use crate::types::{EmgauwaUid, ScheduleUid};
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct RequestScheduleCreate {
|
pub struct RequestScheduleCreate {
|
||||||
|
@ -48,6 +48,41 @@ pub struct RequestTagCreate {
|
||||||
pub tag: String,
|
pub tag: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct RequestMacroActionRelay {
|
||||||
|
pub number: i64,
|
||||||
|
pub controller_id: EmgauwaUid,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct RequestMacroActionSchedule {
|
||||||
|
pub id: ScheduleUid,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct RequestMacroAction {
|
||||||
|
pub weekday: i64,
|
||||||
|
pub relay: RequestMacroActionRelay,
|
||||||
|
pub schedule: RequestMacroActionSchedule,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct RequestMacroCreate {
|
||||||
|
pub name: String,
|
||||||
|
pub actions: Vec<RequestMacroAction>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct RequestMacroUpdate {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub actions: Option<Vec<RequestMacroAction>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct RequestMacroExecute {
|
||||||
|
pub weekday: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
impl RequestScheduleId {
|
impl RequestScheduleId {
|
||||||
pub async fn get_schedule(
|
pub async fn get_schedule(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -125,7 +125,7 @@ CREATE TABLE macros
|
||||||
AUTOINCREMENT
|
AUTOINCREMENT
|
||||||
NOT NULL,
|
NOT NULL,
|
||||||
uid
|
uid
|
||||||
VARCHAR(36)
|
BLOB
|
||||||
NOT NULL
|
NOT NULL
|
||||||
UNIQUE,
|
UNIQUE,
|
||||||
name
|
name
|
||||||
|
|
Loading…
Reference in a new issue