1#[allow(unused_imports)]
15use crate::{
16 base58::Uid, byte_converter::*, device::*, error::TinkerforgeError, ip_connection::async_io::AsyncIpConnection,
17 low_level_traits::LowLevelRead,
18};
19#[allow(unused_imports)]
20use futures_core::Stream;
21#[allow(unused_imports)]
22use tokio_stream::StreamExt;
23pub enum Io4BrickletFunction {
24 SetValue,
25 GetValue,
26 SetConfiguration,
27 GetConfiguration,
28 SetDebouncePeriod,
29 GetDebouncePeriod,
30 SetInterrupt,
31 GetInterrupt,
32 SetMonoflop,
33 GetMonoflop,
34 SetSelectedValues,
35 GetEdgeCount,
36 SetEdgeCountConfig,
37 GetEdgeCountConfig,
38 GetIdentity,
39 CallbackInterrupt,
40 CallbackMonoflopDone,
41}
42impl From<Io4BrickletFunction> for u8 {
43 fn from(fun: Io4BrickletFunction) -> Self {
44 match fun {
45 Io4BrickletFunction::SetValue => 1,
46 Io4BrickletFunction::GetValue => 2,
47 Io4BrickletFunction::SetConfiguration => 3,
48 Io4BrickletFunction::GetConfiguration => 4,
49 Io4BrickletFunction::SetDebouncePeriod => 5,
50 Io4BrickletFunction::GetDebouncePeriod => 6,
51 Io4BrickletFunction::SetInterrupt => 7,
52 Io4BrickletFunction::GetInterrupt => 8,
53 Io4BrickletFunction::SetMonoflop => 10,
54 Io4BrickletFunction::GetMonoflop => 11,
55 Io4BrickletFunction::SetSelectedValues => 13,
56 Io4BrickletFunction::GetEdgeCount => 14,
57 Io4BrickletFunction::SetEdgeCountConfig => 15,
58 Io4BrickletFunction::GetEdgeCountConfig => 16,
59 Io4BrickletFunction::GetIdentity => 255,
60 Io4BrickletFunction::CallbackInterrupt => 9,
61 Io4BrickletFunction::CallbackMonoflopDone => 12,
62 }
63 }
64}
65pub const IO4_BRICKLET_DIRECTION_IN: char = 'i';
66pub const IO4_BRICKLET_DIRECTION_OUT: char = 'o';
67pub const IO4_BRICKLET_EDGE_TYPE_RISING: u8 = 0;
68pub const IO4_BRICKLET_EDGE_TYPE_FALLING: u8 = 1;
69pub const IO4_BRICKLET_EDGE_TYPE_BOTH: u8 = 2;
70
71#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
72pub struct Configuration {
73 pub direction_mask: u8,
74 pub value_mask: u8,
75}
76impl FromByteSlice for Configuration {
77 fn bytes_expected() -> usize {
78 2
79 }
80 fn from_le_byte_slice(bytes: &[u8]) -> Configuration {
81 Configuration { direction_mask: <u8>::from_le_byte_slice(&bytes[0..1]), value_mask: <u8>::from_le_byte_slice(&bytes[1..2]) }
82 }
83}
84
85#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
86pub struct InterruptEvent {
87 pub interrupt_mask: u8,
88 pub value_mask: u8,
89}
90impl FromByteSlice for InterruptEvent {
91 fn bytes_expected() -> usize {
92 2
93 }
94 fn from_le_byte_slice(bytes: &[u8]) -> InterruptEvent {
95 InterruptEvent { interrupt_mask: <u8>::from_le_byte_slice(&bytes[0..1]), value_mask: <u8>::from_le_byte_slice(&bytes[1..2]) }
96 }
97}
98
99#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
100pub struct Monoflop {
101 pub value: u8,
102 pub time: u32,
103 pub time_remaining: u32,
104}
105impl FromByteSlice for Monoflop {
106 fn bytes_expected() -> usize {
107 9
108 }
109 fn from_le_byte_slice(bytes: &[u8]) -> Monoflop {
110 Monoflop {
111 value: <u8>::from_le_byte_slice(&bytes[0..1]),
112 time: <u32>::from_le_byte_slice(&bytes[1..5]),
113 time_remaining: <u32>::from_le_byte_slice(&bytes[5..9]),
114 }
115 }
116}
117
118#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
119pub struct MonoflopDoneEvent {
120 pub selection_mask: u8,
121 pub value_mask: u8,
122}
123impl FromByteSlice for MonoflopDoneEvent {
124 fn bytes_expected() -> usize {
125 2
126 }
127 fn from_le_byte_slice(bytes: &[u8]) -> MonoflopDoneEvent {
128 MonoflopDoneEvent { selection_mask: <u8>::from_le_byte_slice(&bytes[0..1]), value_mask: <u8>::from_le_byte_slice(&bytes[1..2]) }
129 }
130}
131
132#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
133pub struct EdgeCountConfig {
134 pub edge_type: u8,
135 pub debounce: u8,
136}
137impl FromByteSlice for EdgeCountConfig {
138 fn bytes_expected() -> usize {
139 2
140 }
141 fn from_le_byte_slice(bytes: &[u8]) -> EdgeCountConfig {
142 EdgeCountConfig { edge_type: <u8>::from_le_byte_slice(&bytes[0..1]), debounce: <u8>::from_le_byte_slice(&bytes[1..2]) }
143 }
144}
145
146#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
147pub struct Identity {
148 pub uid: String,
149 pub connected_uid: String,
150 pub position: char,
151 pub hardware_version: [u8; 3],
152 pub firmware_version: [u8; 3],
153 pub device_identifier: u16,
154}
155impl FromByteSlice for Identity {
156 fn bytes_expected() -> usize {
157 25
158 }
159 fn from_le_byte_slice(bytes: &[u8]) -> Identity {
160 Identity {
161 uid: <String>::from_le_byte_slice(&bytes[0..8]),
162 connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
163 position: <char>::from_le_byte_slice(&bytes[16..17]),
164 hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
165 firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
166 device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
167 }
168 }
169}
170
171#[derive(Clone)]
173pub struct Io4Bricklet {
174 device: Device,
175}
176impl Io4Bricklet {
177 pub const DEVICE_IDENTIFIER: u16 = 29;
178 pub const DEVICE_DISPLAY_NAME: &'static str = "IO-4 Bricklet";
179 pub fn new(uid: Uid, connection: AsyncIpConnection) -> Io4Bricklet {
181 let mut result = Io4Bricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
182 result.device.response_expected[u8::from(Io4BrickletFunction::SetValue) as usize] = ResponseExpectedFlag::False;
183 result.device.response_expected[u8::from(Io4BrickletFunction::GetValue) as usize] = ResponseExpectedFlag::AlwaysTrue;
184 result.device.response_expected[u8::from(Io4BrickletFunction::SetConfiguration) as usize] = ResponseExpectedFlag::False;
185 result.device.response_expected[u8::from(Io4BrickletFunction::GetConfiguration) as usize] = ResponseExpectedFlag::AlwaysTrue;
186 result.device.response_expected[u8::from(Io4BrickletFunction::SetDebouncePeriod) as usize] = ResponseExpectedFlag::True;
187 result.device.response_expected[u8::from(Io4BrickletFunction::GetDebouncePeriod) as usize] = ResponseExpectedFlag::AlwaysTrue;
188 result.device.response_expected[u8::from(Io4BrickletFunction::SetInterrupt) as usize] = ResponseExpectedFlag::True;
189 result.device.response_expected[u8::from(Io4BrickletFunction::GetInterrupt) as usize] = ResponseExpectedFlag::AlwaysTrue;
190 result.device.response_expected[u8::from(Io4BrickletFunction::SetMonoflop) as usize] = ResponseExpectedFlag::False;
191 result.device.response_expected[u8::from(Io4BrickletFunction::GetMonoflop) as usize] = ResponseExpectedFlag::AlwaysTrue;
192 result.device.response_expected[u8::from(Io4BrickletFunction::SetSelectedValues) as usize] = ResponseExpectedFlag::False;
193 result.device.response_expected[u8::from(Io4BrickletFunction::GetEdgeCount) as usize] = ResponseExpectedFlag::AlwaysTrue;
194 result.device.response_expected[u8::from(Io4BrickletFunction::SetEdgeCountConfig) as usize] = ResponseExpectedFlag::False;
195 result.device.response_expected[u8::from(Io4BrickletFunction::GetEdgeCountConfig) as usize] = ResponseExpectedFlag::AlwaysTrue;
196 result.device.response_expected[u8::from(Io4BrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
197 result
198 }
199
200 pub fn get_response_expected(&mut self, fun: Io4BrickletFunction) -> Result<bool, GetResponseExpectedError> {
215 self.device.get_response_expected(u8::from(fun))
216 }
217
218 pub fn set_response_expected(&mut self, fun: Io4BrickletFunction, response_expected: bool) -> Result<(), SetResponseExpectedError> {
227 self.device.set_response_expected(u8::from(fun), response_expected)
228 }
229
230 pub fn set_response_expected_all(&mut self, response_expected: bool) {
232 self.device.set_response_expected_all(response_expected)
233 }
234
235 pub fn get_api_version(&self) -> [u8; 3] {
238 self.device.api_version
239 }
240
241 pub async fn get_interrupt_callback_receiver(&mut self) -> impl Stream<Item = InterruptEvent> {
256 self.device
257 .get_callback_receiver(u8::from(Io4BrickletFunction::CallbackInterrupt))
258 .await
259 .map(|p| InterruptEvent::from_le_byte_slice(p.body()))
260 }
261
262 pub async fn get_monoflop_done_callback_receiver(&mut self) -> impl Stream<Item = MonoflopDoneEvent> {
266 self.device
267 .get_callback_receiver(u8::from(Io4BrickletFunction::CallbackMonoflopDone))
268 .await
269 .map(|p| MonoflopDoneEvent::from_le_byte_slice(p.body()))
270 }
271
272 pub async fn set_value(&mut self, value_mask: u8) -> Result<(), TinkerforgeError> {
284 let mut payload = [0; 1];
285 value_mask.write_to_slice(&mut payload[0..1]);
286
287 #[allow(unused_variables)]
288 let result = self.device.set(u8::from(Io4BrickletFunction::SetValue), &payload).await?;
289 Ok(())
290 }
291
292 pub async fn get_value(&mut self) -> Result<u8, TinkerforgeError> {
296 let payload = [0; 0];
297
298 #[allow(unused_variables)]
299 let result = self.device.get(u8::from(Io4BrickletFunction::GetValue), &payload).await?;
300 Ok(u8::from_le_byte_slice(result.body()))
301 }
302
303 pub async fn set_configuration(&mut self, selection_mask: u8, direction: char, value: bool) -> Result<(), TinkerforgeError> {
326 let mut payload = [0; 3];
327 selection_mask.write_to_slice(&mut payload[0..1]);
328 direction.write_to_slice(&mut payload[1..2]);
329 value.write_to_slice(&mut payload[2..3]);
330
331 #[allow(unused_variables)]
332 let result = self.device.set(u8::from(Io4BrickletFunction::SetConfiguration), &payload).await?;
333 Ok(())
334 }
335
336 pub async fn get_configuration(&mut self) -> Result<Configuration, TinkerforgeError> {
347 let payload = [0; 0];
348
349 #[allow(unused_variables)]
350 let result = self.device.get(u8::from(Io4BrickletFunction::GetConfiguration), &payload).await?;
351 Ok(Configuration::from_le_byte_slice(result.body()))
352 }
353
354 pub async fn set_debounce_period(&mut self, debounce: u32) -> Result<(), TinkerforgeError> {
360 let mut payload = [0; 4];
361 debounce.write_to_slice(&mut payload[0..4]);
362
363 #[allow(unused_variables)]
364 let result = self.device.set(u8::from(Io4BrickletFunction::SetDebouncePeriod), &payload).await?;
365 Ok(())
366 }
367
368 pub async fn get_debounce_period(&mut self) -> Result<u32, TinkerforgeError> {
370 let payload = [0; 0];
371
372 #[allow(unused_variables)]
373 let result = self.device.get(u8::from(Io4BrickletFunction::GetDebouncePeriod), &payload).await?;
374 Ok(u32::from_le_byte_slice(result.body()))
375 }
376
377 pub async fn set_interrupt(&mut self, interrupt_mask: u8) -> Result<(), TinkerforgeError> {
386 let mut payload = [0; 1];
387 interrupt_mask.write_to_slice(&mut payload[0..1]);
388
389 #[allow(unused_variables)]
390 let result = self.device.set(u8::from(Io4BrickletFunction::SetInterrupt), &payload).await?;
391 Ok(())
392 }
393
394 pub async fn get_interrupt(&mut self) -> Result<u8, TinkerforgeError> {
396 let payload = [0; 0];
397
398 #[allow(unused_variables)]
399 let result = self.device.get(u8::from(Io4BrickletFunction::GetInterrupt), &payload).await?;
400 Ok(u8::from_le_byte_slice(result.body()))
401 }
402
403 pub async fn set_monoflop(&mut self, selection_mask: u8, value_mask: u8, time: u32) -> Result<(), TinkerforgeError> {
423 let mut payload = [0; 6];
424 selection_mask.write_to_slice(&mut payload[0..1]);
425 value_mask.write_to_slice(&mut payload[1..2]);
426 time.write_to_slice(&mut payload[2..6]);
427
428 #[allow(unused_variables)]
429 let result = self.device.set(u8::from(Io4BrickletFunction::SetMonoflop), &payload).await?;
430 Ok(())
431 }
432
433 pub async fn get_monoflop(&mut self, pin: u8) -> Result<Monoflop, TinkerforgeError> {
439 let mut payload = [0; 1];
440 pin.write_to_slice(&mut payload[0..1]);
441
442 #[allow(unused_variables)]
443 let result = self.device.get(u8::from(Io4BrickletFunction::GetMonoflop), &payload).await?;
444 Ok(Monoflop::from_le_byte_slice(result.body()))
445 }
446
447 pub async fn set_selected_values(&mut self, selection_mask: u8, value_mask: u8) -> Result<(), TinkerforgeError> {
461 let mut payload = [0; 2];
462 selection_mask.write_to_slice(&mut payload[0..1]);
463 value_mask.write_to_slice(&mut payload[1..2]);
464
465 #[allow(unused_variables)]
466 let result = self.device.set(u8::from(Io4BrickletFunction::SetSelectedValues), &payload).await?;
467 Ok(())
468 }
469
470 pub async fn get_edge_count(&mut self, pin: u8, reset_counter: bool) -> Result<u32, TinkerforgeError> {
479 let mut payload = [0; 2];
480 pin.write_to_slice(&mut payload[0..1]);
481 reset_counter.write_to_slice(&mut payload[1..2]);
482
483 #[allow(unused_variables)]
484 let result = self.device.get(u8::from(Io4BrickletFunction::GetEdgeCount), &payload).await?;
485 Ok(u32::from_le_byte_slice(result.body()))
486 }
487
488 pub async fn set_edge_count_config(&mut self, selection_mask: u8, edge_type: u8, debounce: u8) -> Result<(), TinkerforgeError> {
510 let mut payload = [0; 3];
511 selection_mask.write_to_slice(&mut payload[0..1]);
512 edge_type.write_to_slice(&mut payload[1..2]);
513 debounce.write_to_slice(&mut payload[2..3]);
514
515 #[allow(unused_variables)]
516 let result = self.device.set(u8::from(Io4BrickletFunction::SetEdgeCountConfig), &payload).await?;
517 Ok(())
518 }
519
520 pub async fn get_edge_count_config(&mut self, pin: u8) -> Result<EdgeCountConfig, TinkerforgeError> {
531 let mut payload = [0; 1];
532 pin.write_to_slice(&mut payload[0..1]);
533
534 #[allow(unused_variables)]
535 let result = self.device.get(u8::from(Io4BrickletFunction::GetEdgeCountConfig), &payload).await?;
536 Ok(EdgeCountConfig::from_le_byte_slice(result.body()))
537 }
538
539 pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
550 let payload = [0; 0];
551
552 #[allow(unused_variables)]
553 let result = self.device.get(u8::from(Io4BrickletFunction::GetIdentity), &payload).await?;
554 Ok(Identity::from_le_byte_slice(result.body()))
555 }
556}