use crate::Result;
use async_trait::async_trait;
use core::fmt::Debug;
use tokio::sync::broadcast;
use tokio::task::JoinHandle;
use super::Basic;
use crate::device_trait;
use crate::notifications::{
ButtonState, InputSetupSingle,
NetworkCommand::{self},
NotificationMessage, PortValueSingleFormat,
};
#[derive(Debug, Copy, Clone)]
pub enum RcButtonState {
Aup,
Aplus,
Ared,
Aminus,
Bup,
Bplus,
Bred,
Bminus,
Green,
GreenUp,
}
device_trait!(RcDevice, [
fn get_rx_pvs(&self) -> Result<broadcast::Receiver<PortValueSingleFormat>>;,
fn get_rx_nwc(&self) -> Result<broadcast::Receiver<NetworkCommand>>;,
async fn remote_buttons_enable_by_port(&self, port_id: u8) -> Result<()> {
self.check()?;
let msg =
NotificationMessage::PortInputFormatSetupSingle(InputSetupSingle {
port_id,
mode: 0,
delta: 1,
notification_enabled: true,
});
self.commit(msg).await
},
async fn remote_connect(
&self,
) -> Result<(broadcast::Receiver<RcButtonState>, JoinHandle<()>)> {
self.remote_buttons_enable_by_port(0x0).await?;
self.remote_buttons_enable_by_port(0x1).await?;
let (tx, rx) = broadcast::channel::<RcButtonState>(64);
let mut pvs_from_main = self
.get_rx_pvs()
.expect("Single value sender not in device cache");
let task = tokio::spawn(async move {
while let Ok(msg) = pvs_from_main.recv().await {
match msg.port_id {
0x0 => match msg.data[0] {
0 => {
let _ = tx.send(RcButtonState::Aup);
}
1 => {
let _ = tx.send(RcButtonState::Aplus);
}
127 => {
let _ = tx.send(RcButtonState::Ared);
}
-1 => {
let _ = tx.send(RcButtonState::Aminus);
}
_ => (),
},
0x1 => match msg.data[0] {
0 => {
let _ = tx.send(RcButtonState::Bup);
}
1 => {
let _ = tx.send(RcButtonState::Bplus);
}
127 => {
let _ = tx.send(RcButtonState::Bred);
}
-1 => {
let _ = tx.send(RcButtonState::Bminus);
}
_ => (),
},
_ => (),
}
}
});
Ok((rx, task))
},
async fn remote_connect_with_green(
&self,
) -> Result<(broadcast::Receiver<RcButtonState>, JoinHandle<()>)> {
self.remote_buttons_enable_by_port(0x0).await?;
self.remote_buttons_enable_by_port(0x1).await?;
let (tx, rx) = broadcast::channel::<RcButtonState>(8);
let mut pvs_from_main = self
.get_rx_pvs()
.expect("Single value sender not in device cache");
let mut nwc_from_main = self
.get_rx_nwc()
.expect("Network command sender not in device cache");
let task = tokio::spawn(async move {
loop {
tokio::select! {
Ok(msg) = pvs_from_main.recv() => {
match msg.port_id {
0x0 => {
match msg.data[0] {
0 => { let _ = tx.send(RcButtonState::Aup); }
1 => { let _ = tx.send(RcButtonState::Aplus); }
127 => { let _ = tx.send(RcButtonState::Ared); }
-1 => { let _ = tx.send(RcButtonState::Aminus); }
_ => ()
}
}
0x1 => {
match msg.data[0] {
0 => { let _ = tx.send(RcButtonState::Bup); }
1 => { let _ = tx.send(RcButtonState::Bplus); }
127 => { let _ = tx.send(RcButtonState::Bred); }
-1 => { let _ = tx.send(RcButtonState::Bminus); }
_ => ()
}
}
_ => ()
}
},
Ok(msg) = nwc_from_main.recv() => {
match msg {
NetworkCommand::ConnectionRequest(ButtonState::Up) => { let _ = tx.send(RcButtonState::Green); },
NetworkCommand::ConnectionRequest(ButtonState::Released) => { let _ = tx.send(RcButtonState::GreenUp); },
_ => ()
}
},
else => { break }
};
}
});
Ok((rx, task))
}
]);