1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use std::net::IpAddr;
use chrono::{DateTime, Utc};
use sqlx::MySqlPool;
use crate::io::wiser::hub::{IpWiserHub, WiserRoomData};
use crate::io::wiser::WiserManager;
use async_trait::async_trait;
use log::error;
use crate::wiser::hub::WiserHub;

const HEATING_STATE_DB_ID: u32 = 17;

pub struct DBAndHub {
    hub: IpWiserHub,
    conn: MySqlPool,
}

impl DBAndHub {
    pub fn new(conn: MySqlPool, wiser_ip: IpAddr, wiser_secret: String) -> Self {
        DBAndHub {
            hub: IpWiserHub::new(wiser_ip, wiser_secret),
            conn,
        }
    }
}

#[async_trait]
impl WiserManager for DBAndHub {
    async fn get_heating_turn_off_time(&self) -> Option<DateTime<Utc>> {
        let data = self.hub.get_room_data().await;
        if let Err(e) = data {
            error!("Error retrieving hub data: {:?}", e);
            return None;
        }
        let data = data.unwrap();
        get_turn_off_time(&data)
    }

    async fn get_heating_on(&self) -> Result<bool,()> {
        let result = sqlx::query!("SELECT raw_value FROM reading WHERE sensor_id=? ORDER BY `id` DESC LIMIT 1", HEATING_STATE_DB_ID)
            .fetch_one(&self.conn).await;
        if result.is_err() {
            error!("{}", result.unwrap_err());
            return Err(())
        }
        match result.unwrap().raw_value {
            Some(0) => Ok(false),
            Some(1) => Ok(true),
            _ => Err(())
        }
    }

    fn get_wiser_hub(&self) -> &dyn WiserHub {
        &self.hub
    }
}

fn get_turn_off_time(data: &Vec<WiserRoomData>) -> Option<DateTime<Utc>> {
    data.iter()
        .filter_map(|room| room.get_override_timeout())
        .max()
}