1use serde::{Deserialize, Serialize};
2use serde_repr::{Deserialize_repr, Serialize_repr};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct SaunaInfo {
7 pub id: String,
9 pub name: String,
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
15#[serde(try_from = "u8", into = "u8")]
16pub enum SaunaMode {
17 Sauna = 1,
19 Sanarium = 2,
21 Infrared = 3,
23}
24
25impl TryFrom<u8> for SaunaMode {
26 type Error = String;
27
28 fn try_from(value: u8) -> Result<Self, Self::Error> {
29 match value {
30 1 => Ok(SaunaMode::Sauna),
31 2 => Ok(SaunaMode::Sanarium),
32 3 => Ok(SaunaMode::Infrared),
33 _ => Err(format!("Invalid sauna mode: {}", value)),
34 }
35 }
36}
37
38impl From<SaunaMode> for u8 {
39 fn from(mode: SaunaMode) -> Self {
40 mode as u8
41 }
42}
43
44impl std::fmt::Display for SaunaMode {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 match self {
47 SaunaMode::Sauna => write!(f, "Sauna"),
48 SaunaMode::Sanarium => write!(f, "Sanarium"),
49 SaunaMode::Infrared => write!(f, "Infrared"),
50 }
51 }
52}
53
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
56pub enum StatusCode {
57 Off,
59 HeatingUp,
61 Ready,
63 Standby,
65 Unknown(i32),
67}
68
69impl From<i32> for StatusCode {
70 fn from(value: i32) -> Self {
71 match value {
72 0 => StatusCode::Off,
73 1 => StatusCode::HeatingUp,
74 2 => StatusCode::Ready,
75 3 => StatusCode::Standby,
76 other => StatusCode::Unknown(other),
77 }
78 }
79}
80
81impl std::fmt::Display for StatusCode {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 match self {
84 StatusCode::Off => write!(f, "Off"),
85 StatusCode::HeatingUp => write!(f, "Heating Up"),
86 StatusCode::Ready => write!(f, "Ready"),
87 StatusCode::Standby => write!(f, "Standby"),
88 StatusCode::Unknown(code) => write!(f, "Unknown ({})", code),
89 }
90 }
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize_repr, Deserialize_repr)]
95#[repr(i32)]
96pub enum OpStatus {
97 Off = 0,
99 Scheduled = 1,
101 Heating = 2,
103 Ready = 3,
105}
106
107impl std::fmt::Display for OpStatus {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 match self {
110 OpStatus::Off => write!(f, "Off"),
111 OpStatus::Scheduled => write!(f, "Scheduled"),
112 OpStatus::Heating => write!(f, "Heating"),
113 OpStatus::Ready => write!(f, "Ready"),
114 }
115 }
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize)]
120#[serde(rename_all = "camelCase")]
121pub struct SaunaStatus {
122 pub sauna_id: String,
124
125 pub sauna_selected: bool,
127
128 pub sanarium_selected: bool,
130
131 pub ir_selected: bool,
133
134 pub selected_sauna_temperature: i32,
136
137 pub selected_sanarium_temperature: i32,
139
140 pub selected_ir_temperature: i32,
142
143 pub selected_hum_level: i32,
145
146 pub selected_ir_level: i32,
148
149 pub selected_hour: i32,
151
152 pub selected_minute: i32,
154
155 pub is_connected: bool,
157
158 pub is_powered_on: bool,
160
161 pub is_ready_for_use: bool,
163
164 pub current_temperature: i32,
166
167 pub current_humidity: i32,
169
170 pub status_code: i32,
172
173 pub status_message: Option<String>,
175
176 pub show_remaining_bathing_time: bool,
178
179 pub remaining_bathing_hours: i32,
181
182 pub remaining_bathing_minutes: i32,
184
185 pub bathing_time_selected: bool,
187
188 pub selected_bathing_time_hours: i32,
190
191 pub selected_bathing_time_minutes: i32,
193
194 pub time_selected: bool,
196
197 pub current_humidity_status: i32,
199
200 pub current_temperature_status: i32,
202
203 pub selected_temperature: i32,
205
206 pub selected_mode: i32,
208
209 pub op_status: OpStatus,
211
212 pub light_is_on: bool,
214
215 pub light_brightness: i32,
217
218 pub color_light_is_on: bool,
220
221 pub color_light_brightness: i32,
223
224 pub color_light_color: i32,
226
227 pub sunset_is_on: bool,
229
230 pub sunset_brightness: i32,
232
233 #[serde(default)]
235 pub login_required: bool,
236
237 #[serde(default = "default_true")]
239 pub success: bool,
240
241 #[serde(default)]
243 pub error_message: String,
244
245 #[serde(default)]
247 pub error_message_header: String,
248}
249
250fn default_true() -> bool {
251 true
252}
253
254impl SaunaStatus {
255 pub fn current_mode(&self) -> Option<SaunaMode> {
257 if self.sauna_selected {
258 Some(SaunaMode::Sauna)
259 } else if self.sanarium_selected {
260 Some(SaunaMode::Sanarium)
261 } else if self.ir_selected {
262 Some(SaunaMode::Infrared)
263 } else {
264 None
265 }
266 }
267
268 pub fn target_temperature(&self) -> i32 {
270 if self.sauna_selected {
271 self.selected_sauna_temperature
272 } else if self.sanarium_selected {
273 self.selected_sanarium_temperature
274 } else if self.ir_selected {
275 self.selected_ir_temperature
276 } else {
277 self.selected_sauna_temperature
278 }
279 }
280
281 pub fn status(&self) -> StatusCode {
283 StatusCode::from(self.status_code)
284 }
285
286 pub fn remaining_time(&self) -> String {
288 format!(
289 "{}h {:02}m",
290 self.remaining_bathing_hours, self.remaining_bathing_minutes
291 )
292 }
293}
294
295#[derive(Debug, Serialize)]
297pub(crate) struct PowerControlRequest {
298 pub id: String,
299 pub pin: String,
300 pub time_selected: bool,
301 pub sel_hour: i32,
302 pub sel_min: i32,
303}
304
305#[derive(Debug, Serialize)]
307pub(crate) struct SetTemperatureRequest {
308 pub id: String,
309 pub temperature: i32,
310}
311
312#[derive(Debug, Serialize)]
314pub(crate) struct SetHumidityRequest {
315 pub id: String,
316 pub level: i32,
317}
318
319#[derive(Debug, Serialize)]
321pub(crate) struct SetModeRequest {
322 pub id: String,
323 pub selected_mode: u8,
324}
325
326#[derive(Debug, Serialize)]
328pub(crate) struct SetSelectedTimeRequest {
329 pub id: String,
330 pub time_set: bool,
331 pub hours: i32,
332 pub minutes: i32,
333}
334
335#[derive(Debug, Serialize)]
337pub(crate) struct LightChangeRequest {
338 pub id: String,
339 pub light_id: u8,
340 pub on_off: bool,
341 pub brightness: i32,
342 pub color: i32,
343}
344
345#[derive(Debug, Clone, Copy, PartialEq, Eq)]
347pub enum LightType {
348 Main = 1,
350 Color = 2,
352 Sunset = 3,
354}
355
356impl From<LightType> for u8 {
357 fn from(light: LightType) -> Self {
358 light as u8
359 }
360}