HomeServer/src/midea_helper.rs

96 lines
2.6 KiB
Rust
Raw Normal View History

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)
}
}