tinkerforge_async/bindings/industrial_digital_out_4_bricklet.rs
1/* ***********************************************************
2 * This file was automatically generated on 2024-02-16. *
3 * *
4 * Rust Bindings Version 2.0.20 *
5 * *
6 * If you have a bugfix for this file and want to commit it, *
7 * please fix the bug in the generator. You can find a link *
8 * to the generators git repository on tinkerforge.com *
9 *************************************************************/
10
11//! 4 galvanically isolated digital outputs.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/IndustrialDigitalOut4_Bricklet_Rust.html).
14#[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 IndustrialDigitalOut4BrickletFunction {
24 SetValue,
25 GetValue,
26 SetMonoflop,
27 GetMonoflop,
28 SetGroup,
29 GetGroup,
30 GetAvailableForGroup,
31 SetSelectedValues,
32 GetIdentity,
33 CallbackMonoflopDone,
34}
35impl From<IndustrialDigitalOut4BrickletFunction> for u8 {
36 fn from(fun: IndustrialDigitalOut4BrickletFunction) -> Self {
37 match fun {
38 IndustrialDigitalOut4BrickletFunction::SetValue => 1,
39 IndustrialDigitalOut4BrickletFunction::GetValue => 2,
40 IndustrialDigitalOut4BrickletFunction::SetMonoflop => 3,
41 IndustrialDigitalOut4BrickletFunction::GetMonoflop => 4,
42 IndustrialDigitalOut4BrickletFunction::SetGroup => 5,
43 IndustrialDigitalOut4BrickletFunction::GetGroup => 6,
44 IndustrialDigitalOut4BrickletFunction::GetAvailableForGroup => 7,
45 IndustrialDigitalOut4BrickletFunction::SetSelectedValues => 9,
46 IndustrialDigitalOut4BrickletFunction::GetIdentity => 255,
47 IndustrialDigitalOut4BrickletFunction::CallbackMonoflopDone => 8,
48 }
49 }
50}
51
52#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
53pub struct Monoflop {
54 pub value: u16,
55 pub time: u32,
56 pub time_remaining: u32,
57}
58impl FromByteSlice for Monoflop {
59 fn bytes_expected() -> usize {
60 10
61 }
62 fn from_le_byte_slice(bytes: &[u8]) -> Monoflop {
63 Monoflop {
64 value: <u16>::from_le_byte_slice(&bytes[0..2]),
65 time: <u32>::from_le_byte_slice(&bytes[2..6]),
66 time_remaining: <u32>::from_le_byte_slice(&bytes[6..10]),
67 }
68 }
69}
70
71#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
72pub struct MonoflopDoneEvent {
73 pub selection_mask: u16,
74 pub value_mask: u16,
75}
76impl FromByteSlice for MonoflopDoneEvent {
77 fn bytes_expected() -> usize {
78 4
79 }
80 fn from_le_byte_slice(bytes: &[u8]) -> MonoflopDoneEvent {
81 MonoflopDoneEvent { selection_mask: <u16>::from_le_byte_slice(&bytes[0..2]), value_mask: <u16>::from_le_byte_slice(&bytes[2..4]) }
82 }
83}
84
85#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
86pub struct Identity {
87 pub uid: String,
88 pub connected_uid: String,
89 pub position: char,
90 pub hardware_version: [u8; 3],
91 pub firmware_version: [u8; 3],
92 pub device_identifier: u16,
93}
94impl FromByteSlice for Identity {
95 fn bytes_expected() -> usize {
96 25
97 }
98 fn from_le_byte_slice(bytes: &[u8]) -> Identity {
99 Identity {
100 uid: <String>::from_le_byte_slice(&bytes[0..8]),
101 connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
102 position: <char>::from_le_byte_slice(&bytes[16..17]),
103 hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
104 firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
105 device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
106 }
107 }
108}
109
110/// 4 galvanically isolated digital outputs
111#[derive(Clone)]
112pub struct IndustrialDigitalOut4Bricklet {
113 device: Device,
114}
115impl IndustrialDigitalOut4Bricklet {
116 pub const DEVICE_IDENTIFIER: u16 = 224;
117 pub const DEVICE_DISPLAY_NAME: &'static str = "Industrial Digital Out 4 Bricklet";
118 /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
119 pub fn new(uid: Uid, connection: AsyncIpConnection) -> IndustrialDigitalOut4Bricklet {
120 let mut result = IndustrialDigitalOut4Bricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
121 result.device.response_expected[u8::from(IndustrialDigitalOut4BrickletFunction::SetValue) as usize] = ResponseExpectedFlag::False;
122 result.device.response_expected[u8::from(IndustrialDigitalOut4BrickletFunction::GetValue) as usize] =
123 ResponseExpectedFlag::AlwaysTrue;
124 result.device.response_expected[u8::from(IndustrialDigitalOut4BrickletFunction::SetMonoflop) as usize] =
125 ResponseExpectedFlag::False;
126 result.device.response_expected[u8::from(IndustrialDigitalOut4BrickletFunction::GetMonoflop) as usize] =
127 ResponseExpectedFlag::AlwaysTrue;
128 result.device.response_expected[u8::from(IndustrialDigitalOut4BrickletFunction::SetGroup) as usize] = ResponseExpectedFlag::False;
129 result.device.response_expected[u8::from(IndustrialDigitalOut4BrickletFunction::GetGroup) as usize] =
130 ResponseExpectedFlag::AlwaysTrue;
131 result.device.response_expected[u8::from(IndustrialDigitalOut4BrickletFunction::GetAvailableForGroup) as usize] =
132 ResponseExpectedFlag::AlwaysTrue;
133 result.device.response_expected[u8::from(IndustrialDigitalOut4BrickletFunction::SetSelectedValues) as usize] =
134 ResponseExpectedFlag::False;
135 result.device.response_expected[u8::from(IndustrialDigitalOut4BrickletFunction::GetIdentity) as usize] =
136 ResponseExpectedFlag::AlwaysTrue;
137 result
138 }
139
140 /// Returns the response expected flag for the function specified by the function ID parameter.
141 /// It is true if the function is expected to send a response, false otherwise.
142 ///
143 /// For getter functions this is enabled by default and cannot be disabled, because those
144 /// functions will always send a response. For callback configuration functions it is enabled
145 /// by default too, but can be disabled by [`set_response_expected`](crate::industrial_digital_out_4_bricklet::IndustrialDigitalOut4Bricklet::set_response_expected).
146 /// For setter functions it is disabled by default and can be enabled.
147 ///
148 /// Enabling the response expected flag for a setter function allows to detect timeouts
149 /// and other error conditions calls of this setter as well. The device will then send a response
150 /// for this purpose. If this flag is disabled for a setter function then no response is sent
151 /// and errors are silently ignored, because they cannot be detected.
152 ///
153 /// See [`set_response_expected`](crate::industrial_digital_out_4_bricklet::IndustrialDigitalOut4Bricklet::set_response_expected) for the list of function ID constants available for this function.
154 pub fn get_response_expected(&mut self, fun: IndustrialDigitalOut4BrickletFunction) -> Result<bool, GetResponseExpectedError> {
155 self.device.get_response_expected(u8::from(fun))
156 }
157
158 /// Changes the response expected flag of the function specified by the function ID parameter.
159 /// This flag can only be changed for setter (default value: false) and callback configuration
160 /// functions (default value: true). For getter functions it is always enabled.
161 ///
162 /// Enabling the response expected flag for a setter function allows to detect timeouts and
163 /// other error conditions calls of this setter as well. The device will then send a response
164 /// for this purpose. If this flag is disabled for a setter function then no response is sent
165 /// and errors are silently ignored, because they cannot be detected.
166 pub fn set_response_expected(
167 &mut self,
168 fun: IndustrialDigitalOut4BrickletFunction,
169 response_expected: bool,
170 ) -> Result<(), SetResponseExpectedError> {
171 self.device.set_response_expected(u8::from(fun), response_expected)
172 }
173
174 /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
175 pub fn set_response_expected_all(&mut self, response_expected: bool) {
176 self.device.set_response_expected_all(response_expected)
177 }
178
179 /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
180 /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
181 pub fn get_api_version(&self) -> [u8; 3] {
182 self.device.api_version
183 }
184
185 /// This receiver is triggered whenever a monoflop timer reaches 0. The
186 /// parameters contain the involved pins and the current value of the pins
187 /// (the value after the monoflop).
188 pub async fn get_monoflop_done_callback_receiver(&mut self) -> impl Stream<Item = MonoflopDoneEvent> {
189 self.device
190 .get_callback_receiver(u8::from(IndustrialDigitalOut4BrickletFunction::CallbackMonoflopDone))
191 .await
192 .map(|p| MonoflopDoneEvent::from_le_byte_slice(p.body()))
193 }
194
195 /// Sets the output value with a bitmask (16bit). A 1 in the bitmask means high
196 /// and a 0 in the bitmask means low.
197 ///
198 /// For example: The value 3 or 0b0011 will turn pins 0-1 high and the other pins
199 /// low.
200 ///
201 /// If no groups are used (see [`set_group`]), the pins correspond to the
202 /// markings on the Industrial Digital Out 4 Bricklet.
203 ///
204 /// If groups are used, the pins correspond to the element in the group.
205 /// Element 1 in the group will get pins 0-3, element 2 pins 4-7, element 3
206 /// pins 8-11 and element 4 pins 12-15.
207 ///
208 /// All running monoflop timers will be aborted if this function is called.
209 pub async fn set_value(&mut self, value_mask: u16) -> Result<(), TinkerforgeError> {
210 let mut payload = [0; 2];
211 value_mask.write_to_slice(&mut payload[0..2]);
212
213 #[allow(unused_variables)]
214 let result = self.device.set(u8::from(IndustrialDigitalOut4BrickletFunction::SetValue), &payload).await?;
215 Ok(())
216 }
217
218 /// Returns the bitmask as set by [`set_value`].
219 pub async fn get_value(&mut self) -> Result<u16, TinkerforgeError> {
220 let payload = [0; 0];
221
222 #[allow(unused_variables)]
223 let result = self.device.get(u8::from(IndustrialDigitalOut4BrickletFunction::GetValue), &payload).await?;
224 Ok(u16::from_le_byte_slice(result.body()))
225 }
226
227 /// Configures a monoflop of the pins specified by the first parameter
228 /// bitmask.
229 ///
230 /// The second parameter is a bitmask with the desired value of the specified
231 /// pins. A 1 in the bitmask means high and a 0 in the bitmask means low.
232 ///
233 /// The third parameter indicates the time that the pins should hold
234 /// the value.
235 ///
236 /// If this function is called with the parameters (9, 1, 1500) or
237 /// (0b1001, 0b0001, 1500): Pin 0 will get high and pin 3 will get low. In 1.5s
238 /// pin 0 will get low and pin 3 will get high again.
239 ///
240 /// A monoflop can be used as a fail-safe mechanism. For example: Lets assume you
241 /// have a RS485 bus and a Digital Out 4 Bricklet connected to one of the slave
242 /// stacks. You can now call this function every second, with a time parameter
243 /// of two seconds and pin 0 high. Pin 0 will be high all the time. If now
244 /// the RS485 connection is lost, then pin 0 will turn low in at most two seconds.
245 pub async fn set_monoflop(&mut self, selection_mask: u16, value_mask: u16, time: u32) -> Result<(), TinkerforgeError> {
246 let mut payload = [0; 8];
247 selection_mask.write_to_slice(&mut payload[0..2]);
248 value_mask.write_to_slice(&mut payload[2..4]);
249 time.write_to_slice(&mut payload[4..8]);
250
251 #[allow(unused_variables)]
252 let result = self.device.set(u8::from(IndustrialDigitalOut4BrickletFunction::SetMonoflop), &payload).await?;
253 Ok(())
254 }
255
256 /// Returns (for the given pin) the current value and the time as set by
257 /// [`set_monoflop`] as well as the remaining time until the value flips.
258 ///
259 /// If the timer is not running currently, the remaining time will be returned
260 /// as 0.
261 pub async fn get_monoflop(&mut self, pin: u8) -> Result<Monoflop, TinkerforgeError> {
262 let mut payload = [0; 1];
263 pin.write_to_slice(&mut payload[0..1]);
264
265 #[allow(unused_variables)]
266 let result = self.device.get(u8::from(IndustrialDigitalOut4BrickletFunction::GetMonoflop), &payload).await?;
267 Ok(Monoflop::from_le_byte_slice(result.body()))
268 }
269
270 /// Sets a group of Digital Out 4 Bricklets that should work together. You can
271 /// find Bricklets that can be grouped together with [`get_available_for_group`].
272 ///
273 /// The group consists of 4 elements. Element 1 in the group will get pins 0-3,
274 /// element 2 pins 4-7, element 3 pins 8-11 and element 4 pins 12-15.
275 ///
276 /// Each element can either be one of the ports ('a' to 'd') or 'n' if it should
277 /// not be used.
278 ///
279 /// For example: If you have two Digital Out 4 Bricklets connected to port A and
280 /// port B respectively, you could call with ``['a', 'b', 'n', 'n']``.
281 ///
282 /// Now the pins on the Digital Out 4 on port A are assigned to 0-3 and the
283 /// pins on the Digital Out 4 on port B are assigned to 4-7. It is now possible
284 /// to call [`set_value`] and control two Bricklets at the same time.
285 pub async fn set_group(&mut self, group: &[char; 4]) -> Result<(), TinkerforgeError> {
286 let mut payload = [0; 4];
287 group.write_to_slice(&mut payload[0..4]);
288
289 #[allow(unused_variables)]
290 let result = self.device.set(u8::from(IndustrialDigitalOut4BrickletFunction::SetGroup), &payload).await?;
291 Ok(())
292 }
293
294 /// Returns the group as set by [`set_group`]
295 pub async fn get_group(&mut self) -> Result<Box<[char; 4]>, TinkerforgeError> {
296 let payload = [0; 0];
297
298 #[allow(unused_variables)]
299 let result = self.device.get(u8::from(IndustrialDigitalOut4BrickletFunction::GetGroup), &payload).await?;
300 Ok(Box::<[char; 4]>::from_le_byte_slice(result.body()))
301 }
302
303 /// Returns a bitmask of ports that are available for grouping. For example the
304 /// value 5 or 0b0101 means: Port A and port C are connected to Bricklets that
305 /// can be grouped together.
306 pub async fn get_available_for_group(&mut self) -> Result<u8, TinkerforgeError> {
307 let payload = [0; 0];
308
309 #[allow(unused_variables)]
310 let result = self.device.get(u8::from(IndustrialDigitalOut4BrickletFunction::GetAvailableForGroup), &payload).await?;
311 Ok(u8::from_le_byte_slice(result.body()))
312 }
313
314 /// Sets the output value with a bitmask, according to the selection mask.
315 /// The bitmask is 16 bit long, *true* refers to high and *false* refers to
316 /// low.
317 ///
318 /// For example: The values (3, 1) or (0b0011, 0b0001) will turn pin 0 high, pin 1
319 /// low the other pins remain untouched.
320 ///
321 /// If no groups are used (see [`set_group`]), the pins correspond to the
322 /// markings on the Industrial Digital Out 4 Bricklet.
323 ///
324 /// If groups are used, the pins correspond to the element in the group.
325 /// Element 1 in the group will get pins 0-3, element 2 pins 4-7, element 3
326 /// pins 8-11 and element 4 pins 12-15.
327 ///
328 /// Running monoflop timers for the selected pins will be aborted if this function
329 /// is called.
330 pub async fn set_selected_values(&mut self, selection_mask: u16, value_mask: u16) -> Result<(), TinkerforgeError> {
331 let mut payload = [0; 4];
332 selection_mask.write_to_slice(&mut payload[0..2]);
333 value_mask.write_to_slice(&mut payload[2..4]);
334
335 #[allow(unused_variables)]
336 let result = self.device.set(u8::from(IndustrialDigitalOut4BrickletFunction::SetSelectedValues), &payload).await?;
337 Ok(())
338 }
339
340 /// Returns the UID, the UID where the Bricklet is connected to,
341 /// the position, the hardware and firmware version as well as the
342 /// device identifier.
343 ///
344 /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
345 /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
346 /// position 'z'.
347 ///
348 /// The device identifier numbers can be found [here](device_identifier).
349 /// |device_identifier_constant|
350 pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
351 let payload = [0; 0];
352
353 #[allow(unused_variables)]
354 let result = self.device.get(u8::from(IndustrialDigitalOut4BrickletFunction::GetIdentity), &payload).await?;
355 Ok(Identity::from_le_byte_slice(result.body()))
356 }
357}