From cf88642612ca64c209e907c1c3b30d25e8101c19 Mon Sep 17 00:00:00 2001 From: hodasemi Date: Sun, 24 Sep 2023 07:35:21 +0200 Subject: [PATCH] Code improvements --- cloud.py | 4 -- discover.py | 7 ++++ midea.py | 4 +- src/cloud.rs | 2 +- src/cloud_security.rs | 4 +- src/device.rs | 67 +++++++++++++++++++++++++++++ src/discover.rs | 98 +++++++++++++------------------------------ src/lib.rs | 4 +- 8 files changed, 111 insertions(+), 79 deletions(-) create mode 100644 src/device.rs diff --git a/cloud.py b/cloud.py index bfdc8d2..967a469 100644 --- a/cloud.py +++ b/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: diff --git a/discover.py b/discover.py index edd295e..2e41786 100644 --- a/discover.py +++ b/discover.py @@ -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]) diff --git a/midea.py b/midea.py index 0449c61..e6a79c7 100644 --- a/midea.py +++ b/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) diff --git a/src/cloud.rs b/src/cloud.rs index 1ccb46c..838c7a8 100644 --- a/src/cloud.rs +++ b/src/cloud.rs @@ -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; diff --git a/src/cloud_security.rs b/src/cloud_security.rs index 508c283..9fd9601 100644 --- a/src/cloud_security.rs +++ b/src/cloud_security.rs @@ -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 diff --git a/src/device.rs b/src/device.rs new file mode 100644 index 0000000..6e48a8b --- /dev/null +++ b/src/device.rs @@ -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 { + 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(()) + } +} diff --git a/src/discover.rs b/src/discover.rs index 1648131..42cdd90 100644 --- a/src/discover.rs +++ b/src/discover.rs @@ -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 { - 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(()) - } } diff --git a/src/lib.rs b/src/lib.rs index 88e203a..78ed6be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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, ParseIntError> { } pub use cloud::Cloud; -pub use discover::{Device, DeviceInfo, Startup}; +pub use device::Device; +pub use discover::{DeviceInfo, Startup};