Impl rest interface to post push-actions

This commit is contained in:
hodasemi 2023-10-23 11:07:37 +02:00
parent 184011c232
commit c71e5c63ee
3 changed files with 71 additions and 8 deletions

View file

@ -40,8 +40,13 @@ impl FromStr for ActionType {
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct ActionID(pub(crate) i64);
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Action {
pub(crate) id: Option<ActionID>,
pub device_id: String,
pub action_type: ActionType,
pub parameter: String,
@ -54,6 +59,8 @@ impl Action {
parameter: impl ToString,
) -> Self {
Self {
id: None,
device_id: device_id.to_string(),
action_type,
parameter: parameter.to_string(),
@ -86,6 +93,10 @@ impl ActionSet {
}
}
pub(crate) fn first_id(&self) -> Option<ActionID> {
self.actions.get(0).map(|action| action.id).flatten()
}
pub fn parameter(&self, parameter: &str) -> bool {
match self.actions.get(0) {
Some(action) => action.parameter == parameter,

View file

@ -4,7 +4,7 @@ use anyhow::Result;
use rusqlite::{Connection, OptionalExtension, ToSql};
use crate::{
action::{Action, ActionSet, ActionType},
action::{Action, ActionID, ActionSet, ActionType},
devices::{DeviceWithName, Devices, DevicesWithName},
};
@ -100,7 +100,7 @@ impl DataBase {
.query_row([], |row| Ok(row.get(0)?))?)
}
pub fn insert_action_set(&self, action_set: ActionSet) -> Result<i64> {
pub fn insert_action_set(&self, action_set: ActionSet) -> Result<ActionID> {
let mut action_ids = Vec::new();
for (i, action) in action_set.iter().enumerate() {
@ -134,10 +134,24 @@ impl DataBase {
}
}
Ok(action_ids[0])
Ok(ActionID(action_ids[0]))
}
pub fn action_set(&self, mut action_id: i64) -> Result<ActionSet> {
pub fn remove_action_set(&self, action_set: &ActionSet) -> Result<()> {
if let Some(action_id) = action_set.first_id() {
self.sql.execute(
"
DELETE FROM actions
WHERE id=?1
",
&[&action_id.0],
)?;
}
Ok(())
}
pub fn action_set(&self, mut action_id: ActionID) -> Result<ActionSet> {
let mut action_set = ActionSet::default();
loop {
@ -148,7 +162,7 @@ impl DataBase {
FROM actions
WHERE id=?1
",
&[&action_id],
&[&action_id.0],
|row| Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?)),
)?;
@ -162,12 +176,13 @@ impl DataBase {
|row| row.get(0),
)?;
let action = Action::new(device_name, ActionType::from_str(&action)?, parameter);
let mut action = Action::new(device_name, ActionType::from_str(&action)?, parameter);
action.id = Some(action_id);
action_set.chain(action);
match next_action {
Some(id) => action_id = id,
Some(id) => action_id.0 = id,
None => break,
}
}
@ -213,7 +228,7 @@ impl DataBase {
{
Some(id) => action_id = id,
None => {
action_sets.push(self.action_set(action_id)?);
action_sets.push(self.action_set(ActionID(action_id))?);
break;
}
}

View file

@ -8,6 +8,7 @@ use serde::Serialize;
use serde_json::to_string;
use crate::{
action::{Action, ActionSet, ActionType},
db::DataBase,
task_scheduler::Scheduler,
tasmota::Tasmota,
@ -271,6 +272,42 @@ async fn push_humidity(
Ok("Ok")
}
#[post("/update_push_action/{source_device}/{parameter}/{destination_device}")]
async fn update_push_action(
param: Path<(String, String, String)>,
db: Data<Arc<Mutex<DataBase>>>,
) -> Result<impl Responder, Error> {
let (source_device, parameter, destination_device) = param.into_inner();
let db_lock = db.lock().unwrap();
let action_sets = db_lock
.action_sets(&source_device)
.map_err(|err| MyError::from(err))?;
// check if action set is already present
if let Some(old_action_set) = action_sets.iter().find(|action_set| {
action_set.push_device() == Some(source_device.clone())
&& action_set.receive_device() == Some(destination_device.clone())
&& action_set.parameter(&parameter)
}) {
// remove old action set
db_lock
.remove_action_set(old_action_set)
.map_err(|err| MyError::from(err))?;
}
let new_action_set = ActionSet::from(vec![
Action::new(source_device, ActionType::Push, parameter.clone()),
Action::new(destination_device, ActionType::Receive, parameter),
]);
db_lock
.insert_action_set(new_action_set)
.map_err(|err| MyError::from(err))?;
Ok("Ok")
}
fn collapse_data<F>(data: Vec<(u64, f32)>, f: F) -> Vec<(u64, f32)>
where
F: Fn(NaiveDateTime) -> NaiveDateTime,