2023-10-05 08:08:57 +00:00
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
|
|
|
use anyhow::{bail, Result};
|
|
|
|
use midea::*;
|
|
|
|
|
|
|
|
use crate::db::DataBase;
|
|
|
|
|
|
|
|
enum LoginInfo {
|
|
|
|
Cloud { mail: String, password: String },
|
|
|
|
Token { token: String, key: String },
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LoginInfo {
|
2024-01-14 16:36:41 +00:00
|
|
|
const MIDEA_KEY_EMAIL: &'static str = "midea_cloud_mail";
|
|
|
|
const MIDEA_KEY_PW: &'static str = "midea_cloud_pw";
|
|
|
|
const MIDEA_KEY_TOKEN: &'static str = "midea_token";
|
|
|
|
const MIDEA_KEY_KEY: &'static str = "midea_key";
|
2023-10-05 08:08:57 +00:00
|
|
|
|
|
|
|
fn new(db: &Arc<Mutex<DataBase>>, device_id: u64) -> Result<LoginInfo> {
|
|
|
|
let db_lock = db.lock().unwrap();
|
|
|
|
|
|
|
|
let token = db_lock.read_credential(Self::MIDEA_KEY_TOKEN, device_id)?;
|
|
|
|
let key = db_lock.read_credential(Self::MIDEA_KEY_KEY, device_id)?;
|
|
|
|
|
|
|
|
if token.is_none() || key.is_none() {
|
|
|
|
let mail = db_lock.read_credential(Self::MIDEA_KEY_EMAIL, device_id)?;
|
|
|
|
let pw = db_lock.read_credential(Self::MIDEA_KEY_PW, device_id)?;
|
|
|
|
|
|
|
|
if mail.is_none() || pw.is_none() {
|
|
|
|
bail!("missing credentials");
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(LoginInfo::Cloud {
|
|
|
|
mail: mail.unwrap(),
|
|
|
|
password: pw.unwrap(),
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
Ok(LoginInfo::Token {
|
|
|
|
token: token.unwrap(),
|
|
|
|
key: key.unwrap(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-05 09:20:36 +00:00
|
|
|
pub struct MideaDiscovery {
|
|
|
|
infos: Vec<DeviceInfo>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MideaDiscovery {
|
|
|
|
pub async fn discover() -> Result<Self> {
|
|
|
|
Ok(Self {
|
|
|
|
infos: Startup::discover().await?,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-05 08:08:57 +00:00
|
|
|
pub struct MideaDishwasher {
|
|
|
|
device_info: DeviceInfo,
|
|
|
|
device: Device,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl MideaDishwasher {
|
2023-10-05 09:20:36 +00:00
|
|
|
pub async fn create(discovery: MideaDiscovery, db: Arc<Mutex<DataBase>>) -> Result<Vec<Self>> {
|
2023-10-05 08:08:57 +00:00
|
|
|
let mut v = Vec::new();
|
|
|
|
|
2023-10-05 09:20:36 +00:00
|
|
|
for device_info in discovery
|
|
|
|
.infos
|
2023-10-05 08:08:57 +00:00
|
|
|
.into_iter()
|
|
|
|
.filter(|device_info| device_info.device_type == 0xE1)
|
|
|
|
{
|
|
|
|
if let Ok(res) = LoginInfo::new(&db, device_info.id) {
|
|
|
|
let (token, key) = match res {
|
|
|
|
LoginInfo::Cloud { mail, password } => {
|
|
|
|
let mut cloud = Cloud::new(mail, password)?;
|
|
|
|
|
|
|
|
cloud.login().await?;
|
|
|
|
|
|
|
|
cloud.keys(device_info.id).await?
|
|
|
|
}
|
|
|
|
LoginInfo::Token { token, key } => (token, key),
|
|
|
|
};
|
|
|
|
|
|
|
|
let device = Device::connect(device_info.clone(), &token, &key).await?;
|
|
|
|
|
|
|
|
v.push(Self {
|
|
|
|
device_info,
|
|
|
|
device,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(v)
|
|
|
|
}
|
|
|
|
}
|