use serde::{Deserialize, Serialize};
use crate::tapo_vendor::error::{Error, TapoResponseError};
use crate::tapo_vendor::responses::{DesiredStateRaw, PowerState, TapoResponseExt};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(any(), pyo3::prelude::pyclass(from_py_object, get_all))]
pub struct Timer {
pub id: String,
pub delay_s: u32,
pub remaining_s: u32,
pub desired_state: PowerState,
}
#[cfg(any())]
crate::tapo_vendor::impl_to_dict!(Timer);
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct TimerListResultRaw {
#[serde(default)]
pub rule_list: Vec<TimerRaw>,
}
impl TapoResponseExt for TimerListResultRaw {}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct TimerRaw {
pub id: String,
pub delay: u32,
#[serde(default)]
pub remain: u32,
#[serde(default)]
pub desired_states: Option<DesiredStateRaw>,
#[serde(default)]
pub action: Option<String>,
}
impl TimerRaw {
pub(crate) fn into_timer(self) -> Result<Timer, Error> {
let desired_state = self
.desired_states
.unwrap_or_default()
.resolve(self.action.as_deref())
.ok_or_else(|| {
Error::Tapo(TapoResponseError::ResponseError {
description: format!(
"Timer {} reported neither desired_states.on nor a recognised action",
self.id
),
})
})?;
Ok(Timer {
id: self.id,
delay_s: self.delay,
remaining_s: self.remain,
desired_state,
})
}
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct AddTimerResult {
pub id: String,
}
impl TapoResponseExt for AddTimerResult {}