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}