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