lego_powered_up/iodevice/
visionsensor.rs1use async_trait::async_trait;
5use core::fmt::Debug;
6use tokio::sync::broadcast;
7use tokio::task::JoinHandle;
8
9use super::modes;
10use super::Basic;
11use crate::device_trait;
12use crate::error::Result;
13use crate::notifications::{
14 CompletionInfo, PortOutputSubcommand, StartupInfo,
15 WriteDirectModeDataPayload,
16};
17
18#[derive(Debug, Copy, Clone)]
19pub enum DetectedColor {
20 NoObject = -1,
21 Black = 0,
22 Color1 = 1,
23 Color2 = 2,
24 Blue = 3,
25 Color4 = 4,
26 Green = 5,
27 Color6 = 6,
28 Yellow = 7,
29 Color8 = 8,
30 Red = 9,
31 White = 10,
32}
33#[derive(Debug, Copy, Clone)]
34pub enum OutputColor {
35 Off = 0,
36 Blue = 3,
37 Green = 5,
38 Red = 9,
39 White = 10,
40}
41
42device_trait!(VisionSensor, [
43 async fn visionsensor_color(
44 &self,
45 ) -> Result<(broadcast::Receiver<DetectedColor>, JoinHandle<()>)> {
46 self.device_mode(modes::VisionSensor::COLOR, 1, true).await?;
47 let port_id = self.port();
48
49 let (tx, rx) = broadcast::channel::<DetectedColor>(8);
51 let mut rx_from_main = self
52 .get_rx()
53 .expect("Single value sender not in device cache");
54 let task = tokio::spawn(async move {
55 while let Ok(msg) = rx_from_main.recv().await {
56 if msg.port_id == port_id {
57 match msg.data[0] {
58 -1 => {
59 let _ = tx.send(DetectedColor::NoObject);
60 }
61 0 => {
62 let _ = tx.send(DetectedColor::Black);
63 }
64 1 => {
65 let _ = tx.send(DetectedColor::Color1);
66 }
67 2 => {
68 let _ = tx.send(DetectedColor::Color2);
69 }
70 3 => {
71 let _ = tx.send(DetectedColor::Blue);
72 }
73 4 => {
74 let _ = tx.send(DetectedColor::Color4);
75 }
76 5 => {
77 let _ = tx.send(DetectedColor::Green);
78 }
79 6 => {
80 let _ = tx.send(DetectedColor::Color6);
81 }
82 7 => {
83 let _ = tx.send(DetectedColor::Yellow);
84 }
85 8 => {
86 let _ = tx.send(DetectedColor::Color8);
87 }
88 9 => {
89 let _ = tx.send(DetectedColor::Red);
90 }
91 10 => {
92 let _ = tx.send(DetectedColor::White);
93 }
94 _ => (),
95 }
96 }
97 }
98 });
99
100 Ok((rx, task))
101 },
102
103 async fn visionsensor_light_output_mode(&self) -> Result<()> {
105 self.check()?;
106 self.device_mode(modes::VisionSensor::COL_O, 1, true).await
107 },
108
109 async fn visionsensor_set_color(&self, color: OutputColor) -> Result<()> {
111 self.check()?;
112 let subcommand = PortOutputSubcommand::WriteDirectModeData(
113 WriteDirectModeDataPayload::SetVisionSensorColor(color as i8),
114 );
115 self.device_command(subcommand, StartupInfo::ExecuteImmediately, CompletionInfo::NoAction).await
116 }
117]);