use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SaunaInfo {
pub id: String,
pub name: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(try_from = "u8", into = "u8")]
pub enum SaunaMode {
Sauna = 1,
Sanarium = 2,
Infrared = 3,
}
impl TryFrom<u8> for SaunaMode {
type Error = String;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
1 => Ok(SaunaMode::Sauna),
2 => Ok(SaunaMode::Sanarium),
3 => Ok(SaunaMode::Infrared),
_ => Err(format!("Invalid sauna mode: {}", value)),
}
}
}
impl From<SaunaMode> for u8 {
fn from(mode: SaunaMode) -> Self {
mode as u8
}
}
impl std::fmt::Display for SaunaMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SaunaMode::Sauna => write!(f, "Sauna"),
SaunaMode::Sanarium => write!(f, "Sanarium"),
SaunaMode::Infrared => write!(f, "Infrared"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StatusCode {
Off,
HeatingUp,
Ready,
Standby,
Unknown(i32),
}
impl From<i32> for StatusCode {
fn from(value: i32) -> Self {
match value {
0 => StatusCode::Off,
1 => StatusCode::HeatingUp,
2 => StatusCode::Ready,
3 => StatusCode::Standby,
other => StatusCode::Unknown(other),
}
}
}
impl std::fmt::Display for StatusCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
StatusCode::Off => write!(f, "Off"),
StatusCode::HeatingUp => write!(f, "Heating Up"),
StatusCode::Ready => write!(f, "Ready"),
StatusCode::Standby => write!(f, "Standby"),
StatusCode::Unknown(code) => write!(f, "Unknown ({})", code),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize_repr, Deserialize_repr)]
#[repr(i32)]
pub enum OpStatus {
Off = 0,
Scheduled = 1,
Heating = 2,
Ready = 3,
}
impl std::fmt::Display for OpStatus {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
OpStatus::Off => write!(f, "Off"),
OpStatus::Scheduled => write!(f, "Scheduled"),
OpStatus::Heating => write!(f, "Heating"),
OpStatus::Ready => write!(f, "Ready"),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SaunaStatus {
pub sauna_id: String,
pub sauna_selected: bool,
pub sanarium_selected: bool,
pub ir_selected: bool,
pub selected_sauna_temperature: i32,
pub selected_sanarium_temperature: i32,
pub selected_ir_temperature: i32,
pub selected_hum_level: i32,
pub selected_ir_level: i32,
pub selected_hour: i32,
pub selected_minute: i32,
pub is_connected: bool,
pub is_powered_on: bool,
pub is_ready_for_use: bool,
pub current_temperature: i32,
pub current_humidity: i32,
pub status_code: i32,
pub status_message: Option<String>,
pub show_remaining_bathing_time: bool,
pub remaining_bathing_hours: i32,
pub remaining_bathing_minutes: i32,
pub bathing_time_selected: bool,
pub selected_bathing_time_hours: i32,
pub selected_bathing_time_minutes: i32,
pub time_selected: bool,
pub current_humidity_status: i32,
pub current_temperature_status: i32,
pub selected_temperature: i32,
pub selected_mode: i32,
pub op_status: OpStatus,
pub light_is_on: bool,
pub light_brightness: i32,
pub color_light_is_on: bool,
pub color_light_brightness: i32,
pub color_light_color: i32,
pub sunset_is_on: bool,
pub sunset_brightness: i32,
#[serde(default)]
pub login_required: bool,
#[serde(default = "default_true")]
pub success: bool,
#[serde(default)]
pub error_message: String,
#[serde(default)]
pub error_message_header: String,
}
fn default_true() -> bool {
true
}
impl SaunaStatus {
pub fn current_mode(&self) -> Option<SaunaMode> {
if self.sauna_selected {
Some(SaunaMode::Sauna)
} else if self.sanarium_selected {
Some(SaunaMode::Sanarium)
} else if self.ir_selected {
Some(SaunaMode::Infrared)
} else {
None
}
}
pub fn target_temperature(&self) -> i32 {
if self.sauna_selected {
self.selected_sauna_temperature
} else if self.sanarium_selected {
self.selected_sanarium_temperature
} else if self.ir_selected {
self.selected_ir_temperature
} else {
self.selected_sauna_temperature
}
}
pub fn status(&self) -> StatusCode {
StatusCode::from(self.status_code)
}
pub fn remaining_time(&self) -> String {
format!(
"{}h {:02}m",
self.remaining_bathing_hours, self.remaining_bathing_minutes
)
}
}
#[derive(Debug, Serialize)]
pub(crate) struct PowerControlRequest {
pub id: String,
pub pin: String,
pub time_selected: bool,
pub sel_hour: i32,
pub sel_min: i32,
}
#[derive(Debug, Serialize)]
pub(crate) struct SetTemperatureRequest {
pub id: String,
pub temperature: i32,
}
#[derive(Debug, Serialize)]
pub(crate) struct SetHumidityRequest {
pub id: String,
pub level: i32,
}
#[derive(Debug, Serialize)]
pub(crate) struct SetModeRequest {
pub id: String,
pub selected_mode: u8,
}
#[derive(Debug, Serialize)]
pub(crate) struct SetSelectedTimeRequest {
pub id: String,
pub time_set: bool,
pub hours: i32,
pub minutes: i32,
}
#[derive(Debug, Serialize)]
pub(crate) struct LightChangeRequest {
pub id: String,
pub light_id: u8,
pub on_off: bool,
pub brightness: i32,
pub color: i32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LightType {
Main = 1,
Color = 2,
Sunset = 3,
}
impl From<LightType> for u8 {
fn from(light: LightType) -> Self {
light as u8
}
}