lego_powered_up/iodevice/
remote.rs1use crate::Result;
7
8use async_trait::async_trait;
9use core::fmt::Debug;
10use tokio::sync::broadcast;
11use tokio::task::JoinHandle;
12
13use super::Basic;
14use crate::device_trait;
15use crate::notifications::{
16 ButtonState, InputSetupSingle,
17 NetworkCommand::{self},
18 NotificationMessage, PortValueSingleFormat,
19};
20
21#[derive(Debug, Copy, Clone)]
22pub enum RcButtonState {
23 Aup,
24 Aplus,
25 Ared,
26 Aminus,
27 Bup,
28 Bplus,
29 Bred,
30 Bminus,
31 Green,
32 GreenUp,
33}
34
35device_trait!(RcDevice, [
36 fn get_rx_pvs(&self) -> Result<broadcast::Receiver<PortValueSingleFormat>>;,
37 fn get_rx_nwc(&self) -> Result<broadcast::Receiver<NetworkCommand>>;,
38
39 async fn remote_buttons_enable_by_port(&self, port_id: u8) -> Result<()> {
40 self.check()?;
41 let msg =
42 NotificationMessage::PortInputFormatSetupSingle(InputSetupSingle {
43 port_id,
44 mode: 0,
45 delta: 1,
46 notification_enabled: true,
47 });
48 self.commit(msg).await
49 },
50
51 async fn remote_connect(
52 &self,
53 ) -> Result<(broadcast::Receiver<RcButtonState>, JoinHandle<()>)> {
54 self.remote_buttons_enable_by_port(0x0).await?;
55 self.remote_buttons_enable_by_port(0x1).await?;
56
57 let (tx, rx) = broadcast::channel::<RcButtonState>(64);
59 let mut pvs_from_main = self
60 .get_rx_pvs()
61 .expect("Single value sender not in device cache");
62 let task = tokio::spawn(async move {
63 while let Ok(msg) = pvs_from_main.recv().await {
64 match msg.port_id {
65 0x0 => match msg.data[0] {
66 0 => {
67 let _ = tx.send(RcButtonState::Aup);
68 }
69 1 => {
70 let _ = tx.send(RcButtonState::Aplus);
71 }
72 127 => {
73 let _ = tx.send(RcButtonState::Ared);
74 }
75 -1 => {
76 let _ = tx.send(RcButtonState::Aminus);
77 }
78 _ => (),
79 },
80 0x1 => match msg.data[0] {
81 0 => {
82 let _ = tx.send(RcButtonState::Bup);
83 }
84 1 => {
85 let _ = tx.send(RcButtonState::Bplus);
86 }
87 127 => {
88 let _ = tx.send(RcButtonState::Bred);
89 }
90 -1 => {
91 let _ = tx.send(RcButtonState::Bminus);
92 }
93 _ => (),
94 },
95 _ => (),
96 }
97 }
98 });
99
100 Ok((rx, task))
101 },
102
103 async fn remote_connect_with_green(
104 &self,
105 ) -> Result<(broadcast::Receiver<RcButtonState>, JoinHandle<()>)> {
106 self.remote_buttons_enable_by_port(0x0).await?;
107 self.remote_buttons_enable_by_port(0x1).await?;
108
109 let (tx, rx) = broadcast::channel::<RcButtonState>(8);
111 let mut pvs_from_main = self
112 .get_rx_pvs()
113 .expect("Single value sender not in device cache");
114 let mut nwc_from_main = self
115 .get_rx_nwc()
116 .expect("Network command sender not in device cache");
117 let task = tokio::spawn(async move {
118 loop {
119 tokio::select! {
120 Ok(msg) = pvs_from_main.recv() => {
121 match msg.port_id {
122 0x0 => {
123 match msg.data[0] {
124 0 => { let _ = tx.send(RcButtonState::Aup); }
125 1 => { let _ = tx.send(RcButtonState::Aplus); }
126 127 => { let _ = tx.send(RcButtonState::Ared); }
127 -1 => { let _ = tx.send(RcButtonState::Aminus); }
128 _ => ()
129 }
130 }
131 0x1 => {
132 match msg.data[0] {
133 0 => { let _ = tx.send(RcButtonState::Bup); }
134 1 => { let _ = tx.send(RcButtonState::Bplus); }
135 127 => { let _ = tx.send(RcButtonState::Bred); }
136 -1 => { let _ = tx.send(RcButtonState::Bminus); }
137 _ => ()
138 }
139 }
140 _ => ()
141 }
142 },
143 Ok(msg) = nwc_from_main.recv() => {
144 match msg {
145 NetworkCommand::ConnectionRequest(ButtonState::Up) => { let _ = tx.send(RcButtonState::Green); },
146 NetworkCommand::ConnectionRequest(ButtonState::Released) => { let _ = tx.send(RcButtonState::GreenUp); },
147 _ => ()
148 }
149 },
150 else => { break }
151 };
152 }
153 });
154
155 Ok((rx, task))
156 }
157]);