Code improvements
This commit is contained in:
parent
1cf3e17faa
commit
cf88642612
8 changed files with 111 additions and 79 deletions
4
cloud.py
4
cloud.py
|
@ -90,9 +90,6 @@ class MideaCloud:
|
|||
})
|
||||
response:dict = {"code": -1}
|
||||
|
||||
print(header)
|
||||
print(dump_data)
|
||||
|
||||
for i in range(0, 3):
|
||||
try:
|
||||
with self._api_lock:
|
||||
|
@ -105,7 +102,6 @@ class MideaCloud:
|
|||
pass
|
||||
if int(response["code"]) == 0 and "data" in response:
|
||||
return response["data"]
|
||||
print(response)
|
||||
return None
|
||||
|
||||
async def _get_login_id(self) -> str | None:
|
||||
|
|
|
@ -71,6 +71,13 @@ def discover(discover_type=None, ip_address=None):
|
|||
encrypt_data = data[40:-16]
|
||||
reply = security.aes_decrypt(encrypt_data)
|
||||
_LOGGER.debug(f"Declassified reply: {reply.hex()}")
|
||||
|
||||
start = 41
|
||||
end = start + reply[40]
|
||||
|
||||
ssid_bytes = reply[start:end]
|
||||
print(ssid_bytes)
|
||||
|
||||
ssid = reply[41:41 + reply[40]].decode("utf-8")
|
||||
device_type = ssid.split("_")[1]
|
||||
port = bytes2port(reply[4:8])
|
||||
|
|
4
midea.py
4
midea.py
|
@ -13,9 +13,9 @@ async def test():
|
|||
"Hoda.semi1"
|
||||
)
|
||||
|
||||
if await cl.login():
|
||||
devices = discover.discover()
|
||||
devices = discover.discover()
|
||||
|
||||
if await cl.login():
|
||||
for device_id in devices:
|
||||
keys = await cl.get_keys(device_id)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::{
|
|||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
use anyhow::{anyhow, bail, Error, Result};
|
||||
use anyhow::{bail, Error, Result};
|
||||
use base64::{engine::general_purpose, Engine};
|
||||
|
||||
use chrono::Local;
|
||||
|
|
|
@ -99,8 +99,8 @@ impl CloudSecurity {
|
|||
|
||||
v
|
||||
}
|
||||
1 => {
|
||||
let mut v = device_id.to_be_bytes().to_vec();
|
||||
2 => {
|
||||
let mut v = device_id.to_le_bytes().to_vec();
|
||||
v.truncate(6);
|
||||
|
||||
v
|
||||
|
|
67
src/device.rs
Normal file
67
src/device.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
use std::{net::UdpSocket, time::Duration};
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::{
|
||||
security::{MsgType, Security},
|
||||
DeviceInfo,
|
||||
};
|
||||
|
||||
pub struct Device {
|
||||
info: DeviceInfo,
|
||||
|
||||
socket: UdpSocket,
|
||||
security: Security,
|
||||
}
|
||||
|
||||
impl Device {
|
||||
pub fn connect(info: DeviceInfo) -> Result<Self> {
|
||||
let socket = UdpSocket::bind("0.0.0.0:0")?;
|
||||
socket.set_write_timeout(Some(Duration::from_secs(10)))?;
|
||||
socket.set_read_timeout(Some(Duration::from_secs(10)))?;
|
||||
|
||||
socket.connect(info.addr)?;
|
||||
|
||||
let mut me = Self {
|
||||
info,
|
||||
socket,
|
||||
security: Security::default(),
|
||||
};
|
||||
|
||||
if me.info.protocol == 3 {
|
||||
me.authenticate()?;
|
||||
}
|
||||
|
||||
me.refresh_status()?;
|
||||
|
||||
Ok(me)
|
||||
}
|
||||
|
||||
fn authenticate(&mut self) -> Result<()> {
|
||||
let request = self.security.encode_8370(MsgType::HANDSHAKE_REQUEST)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn refresh_status(&self) -> Result<()> {
|
||||
//
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::{device::Device, Startup};
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect() -> Result<()> {
|
||||
for device_info in Startup::discover().await? {
|
||||
Device::connect(device_info)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -7,62 +7,17 @@ use std::{
|
|||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::{
|
||||
hex,
|
||||
security::{MsgType, Security},
|
||||
};
|
||||
use crate::{hex, security::Security};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DeviceInfo {
|
||||
pub id: u64,
|
||||
model: String,
|
||||
sn: String,
|
||||
protocol: u8,
|
||||
pub model: String,
|
||||
pub sn: String,
|
||||
pub protocol: u8,
|
||||
pub device_type: u32,
|
||||
|
||||
addr: SocketAddr,
|
||||
}
|
||||
|
||||
pub struct Device {
|
||||
info: DeviceInfo,
|
||||
|
||||
socket: UdpSocket,
|
||||
security: Security,
|
||||
}
|
||||
|
||||
impl Device {
|
||||
pub fn connect(info: DeviceInfo) -> Result<Self> {
|
||||
let socket = UdpSocket::bind("0.0.0.0:0")?;
|
||||
socket.set_write_timeout(Some(Duration::from_secs(10)))?;
|
||||
socket.set_read_timeout(Some(Duration::from_secs(10)))?;
|
||||
|
||||
socket.connect(info.addr)?;
|
||||
|
||||
let mut me = Self {
|
||||
info,
|
||||
socket,
|
||||
security: Security::default(),
|
||||
};
|
||||
|
||||
if me.info.protocol == 3 {
|
||||
me.authenticate()?;
|
||||
}
|
||||
|
||||
me.refresh_status()?;
|
||||
|
||||
Ok(me)
|
||||
}
|
||||
|
||||
fn authenticate(&mut self) -> Result<()> {
|
||||
let request = self.security.encode_8370(MsgType::HANDSHAKE_REQUEST)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn refresh_status(&self) -> Result<()> {
|
||||
//
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub addr: SocketAddr,
|
||||
}
|
||||
|
||||
pub struct Startup;
|
||||
|
@ -119,12 +74,23 @@ impl Startup {
|
|||
let len = bytes.len();
|
||||
let encrypt_data = Security::decrypt(&mut bytes[40..(len - 16)]);
|
||||
|
||||
let start = 41;
|
||||
let upper = start + encrypt_data[40] as usize;
|
||||
let ssid = from_utf8(&encrypt_data[start..upper])?;
|
||||
|
||||
let device_type = u32::from_str_radix(ssid.split('_').nth(1).unwrap(), 16)?;
|
||||
let model = from_utf8(&encrypt_data[17..25])?;
|
||||
let sn = from_utf8(&encrypt_data[8..40])?;
|
||||
|
||||
devices.insert(
|
||||
device_id,
|
||||
(addr, model.to_string(), sn.to_string(), protocol),
|
||||
(
|
||||
addr,
|
||||
model.to_string(),
|
||||
sn.to_string(),
|
||||
protocol,
|
||||
device_type,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -132,14 +98,17 @@ impl Startup {
|
|||
|
||||
Ok(devices
|
||||
.into_iter()
|
||||
.map(|(id, (addr, model, sn, protocol))| DeviceInfo {
|
||||
id,
|
||||
model,
|
||||
sn,
|
||||
protocol,
|
||||
.map(
|
||||
|(id, (addr, model, sn, protocol, device_type))| DeviceInfo {
|
||||
id,
|
||||
model,
|
||||
sn,
|
||||
protocol,
|
||||
device_type,
|
||||
|
||||
addr,
|
||||
})
|
||||
addr,
|
||||
},
|
||||
)
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +151,7 @@ impl Startup {
|
|||
mod test {
|
||||
use anyhow::Result;
|
||||
|
||||
use super::{Device, Startup};
|
||||
use super::Startup;
|
||||
|
||||
#[tokio::test]
|
||||
async fn discover() -> Result<()> {
|
||||
|
@ -192,13 +161,4 @@ mod test {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect() -> Result<()> {
|
||||
for device_info in Startup::discover().await? {
|
||||
Device::connect(device_info)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::num::ParseIntError;
|
|||
|
||||
mod cloud;
|
||||
mod cloud_security;
|
||||
mod device;
|
||||
mod discover;
|
||||
mod security;
|
||||
|
||||
|
@ -13,4 +14,5 @@ fn hex(s: &str) -> Result<Vec<u8>, ParseIntError> {
|
|||
}
|
||||
|
||||
pub use cloud::Cloud;
|
||||
pub use discover::{Device, DeviceInfo, Startup};
|
||||
pub use device::Device;
|
||||
pub use discover::{DeviceInfo, Startup};
|
||||
|
|
Loading…
Reference in a new issue