Improve write test
All checks were successful
Midea Merge / Serial Reader (pull_request) Successful in 13m59s

This commit is contained in:
hodasemi 2023-10-09 07:39:13 +02:00
parent 2cf725b5aa
commit 56fe4beb2a
3 changed files with 84 additions and 26 deletions

View file

@ -2,6 +2,9 @@ use super::{body::Body, header::Header, Command, MessageType};
use std::ops::Deref; use std::ops::Deref;
pub trait RequestSerializer { pub trait RequestSerializer {
fn message_type(&self) -> MessageType;
fn body_type(&self) -> u8;
fn serialize(&self) -> Vec<u8>; fn serialize(&self) -> Vec<u8>;
} }
@ -65,6 +68,14 @@ impl RequestSerializer for CommandRequest {
stream stream
} }
fn message_type(&self) -> MessageType {
self.header().message_type()
}
fn body_type(&self) -> u8 {
self.body().body_type()
}
} }
pub struct CommandQuerySubtype { pub struct CommandQuerySubtype {
@ -102,6 +113,14 @@ impl RequestSerializer for CommandQuerySubtype {
fn serialize(&self) -> Vec<u8> { fn serialize(&self) -> Vec<u8> {
self.command.serialize() self.command.serialize()
} }
fn message_type(&self) -> MessageType {
self.header().message_type()
}
fn body_type(&self) -> u8 {
self.body().body_type()
}
} }
pub struct CommandQueryCustom { pub struct CommandQueryCustom {
@ -140,6 +159,14 @@ impl RequestSerializer for CommandQueryCustom {
fn serialize(&self) -> Vec<u8> { fn serialize(&self) -> Vec<u8> {
self.command.serialize() self.command.serialize()
} }
fn message_type(&self) -> MessageType {
self.header().message_type()
}
fn body_type(&self) -> u8 {
self.body().body_type()
}
} }
pub struct CommandHeartbeat; pub struct CommandHeartbeat;
@ -148,4 +175,12 @@ impl RequestSerializer for CommandHeartbeat {
fn serialize(&self) -> Vec<u8> { fn serialize(&self) -> Vec<u8> {
vec![0x00] vec![0x00]
} }
fn message_type(&self) -> MessageType {
MessageType::None
}
fn body_type(&self) -> u8 {
0
}
} }

View file

@ -124,24 +124,22 @@ impl Device {
} }
for cmd in cmds { for cmd in cmds {
'sending: loop { self.build_send(cmd.clone())?;
self.build_send(cmd.clone())?;
loop { loop {
let mut buf = [0; 512]; let mut buf = [0; 512];
let bytes_read = match self.socket.lock().unwrap().read(&mut buf) { let bytes_read = match self.socket.lock().unwrap().read(&mut buf) {
Ok(b) => b, Ok(b) => b,
Err(_) => continue, Err(_) => continue,
}; };
if bytes_read == 0 { if bytes_read == 0 {
break; break;
} }
match self.parse_message(&buf[..bytes_read])? { match self.parse_message(&buf[..bytes_read])? {
ParseMessage::Success => break 'sending, ParseMessage::Success => break,
ParseMessage::Padding => continue, ParseMessage::Padding => continue,
}
} }
} }
} }
@ -226,7 +224,11 @@ impl Device {
fn send_message(&self, msg: &[u8]) -> Result<()> { fn send_message(&self, msg: &[u8]) -> Result<()> {
let data = self.security.encode_8370(msg, MsgType::ENCRYPTED_REQUEST)?; let data = self.security.encode_8370(msg, MsgType::ENCRYPTED_REQUEST)?;
self.socket.lock().unwrap().write(&data)?; self.socket
.lock()
.unwrap()
.write(&data)
.context(format!("{msg:?}"))?;
Ok(()) Ok(())
} }
@ -237,15 +239,26 @@ impl Device {
} }
fn build_send(&self, cmd: impl RequestSerializer) -> Result<()> { fn build_send(&self, cmd: impl RequestSerializer) -> Result<()> {
let message_type = cmd.message_type();
let body_type = cmd.body_type();
let data = PacketBuilder::builder(self.info.id, cmd).finalize(1); let data = PacketBuilder::builder(self.info.id, cmd).finalize(1);
self.send_message(&data) Ok(self.send_message(&data).context(format!(
"message_type: {message_type:?}, body_type: {body_type}"
))?)
} }
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::net::{Ipv4Addr, SocketAddr}; use std::{
net::{Ipv4Addr, SocketAddr},
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use futures::future::try_join; use futures::future::try_join;
@ -342,19 +355,29 @@ mod test {
addr: SocketAddr::new(std::net::IpAddr::V4(Ipv4Addr::new(192, 168, 178, 94)), 6444), addr: SocketAddr::new(std::net::IpAddr::V4(Ipv4Addr::new(192, 168, 178, 94)), 6444),
}; };
let mut device = Device::connect(device_info, token, key) let power: Arc<AtomicBool> = Arc::new(AtomicBool::new(false));
.await?
.register_update(|attributes| {
println!("{attributes:?}");
Ok(()) let device = Device::connect(device_info, token, key)
.await?
.register_update({
let power = power.clone();
move |attributes| {
println!("{attributes:?}");
power.store(attributes["power"].bool(), Ordering::SeqCst);
Ok(())
}
}); });
device device
.set_attribute("attribute", AttributeValue::Bool(false)) .set_attribute("power", AttributeValue::Bool(true))
.await?; .await?;
device.refresh_status().await?; device
.set_attribute("power", AttributeValue::Bool(false))
.await?;
Ok(()) Ok(())
} }

View file

@ -127,7 +127,7 @@ impl DeviceBackend for E1 {
cmd.request() cmd.request()
} }
_ => todo!(), _ => todo!("attribute: {attribute}"),
} }
} }