tinkerforge_async/bindings/
dual_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//! Two relays to switch AC/DC devices.
12//!
13//! See also the documentation [here](https://www.tinkerforge.com/en/doc/Software/Bricklets/DualRelay_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 DualRelayBrickletFunction {
24    SetState,
25    GetState,
26    SetMonoflop,
27    GetMonoflop,
28    SetSelectedState,
29    GetIdentity,
30    CallbackMonoflopDone,
31}
32impl From<DualRelayBrickletFunction> for u8 {
33    fn from(fun: DualRelayBrickletFunction) -> Self {
34        match fun {
35            DualRelayBrickletFunction::SetState => 1,
36            DualRelayBrickletFunction::GetState => 2,
37            DualRelayBrickletFunction::SetMonoflop => 3,
38            DualRelayBrickletFunction::GetMonoflop => 4,
39            DualRelayBrickletFunction::SetSelectedState => 6,
40            DualRelayBrickletFunction::GetIdentity => 255,
41            DualRelayBrickletFunction::CallbackMonoflopDone => 5,
42        }
43    }
44}
45
46#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
47pub struct State {
48    pub relay1: bool,
49    pub relay2: bool,
50}
51impl FromByteSlice for State {
52    fn bytes_expected() -> usize {
53        2
54    }
55    fn from_le_byte_slice(bytes: &[u8]) -> State {
56        State { relay1: <bool>::from_le_byte_slice(&bytes[0..1]), relay2: <bool>::from_le_byte_slice(&bytes[1..2]) }
57    }
58}
59
60#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
61pub struct Monoflop {
62    pub state: bool,
63    pub time: u32,
64    pub time_remaining: u32,
65}
66impl FromByteSlice for Monoflop {
67    fn bytes_expected() -> usize {
68        9
69    }
70    fn from_le_byte_slice(bytes: &[u8]) -> Monoflop {
71        Monoflop {
72            state: <bool>::from_le_byte_slice(&bytes[0..1]),
73            time: <u32>::from_le_byte_slice(&bytes[1..5]),
74            time_remaining: <u32>::from_le_byte_slice(&bytes[5..9]),
75        }
76    }
77}
78
79#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
80pub struct MonoflopDoneEvent {
81    pub relay: u8,
82    pub state: bool,
83}
84impl FromByteSlice for MonoflopDoneEvent {
85    fn bytes_expected() -> usize {
86        2
87    }
88    fn from_le_byte_slice(bytes: &[u8]) -> MonoflopDoneEvent {
89        MonoflopDoneEvent { relay: <u8>::from_le_byte_slice(&bytes[0..1]), state: <bool>::from_le_byte_slice(&bytes[1..2]) }
90    }
91}
92
93#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
94pub struct Identity {
95    pub uid: String,
96    pub connected_uid: String,
97    pub position: char,
98    pub hardware_version: [u8; 3],
99    pub firmware_version: [u8; 3],
100    pub device_identifier: u16,
101}
102impl FromByteSlice for Identity {
103    fn bytes_expected() -> usize {
104        25
105    }
106    fn from_le_byte_slice(bytes: &[u8]) -> Identity {
107        Identity {
108            uid: <String>::from_le_byte_slice(&bytes[0..8]),
109            connected_uid: <String>::from_le_byte_slice(&bytes[8..16]),
110            position: <char>::from_le_byte_slice(&bytes[16..17]),
111            hardware_version: <[u8; 3]>::from_le_byte_slice(&bytes[17..20]),
112            firmware_version: <[u8; 3]>::from_le_byte_slice(&bytes[20..23]),
113            device_identifier: <u16>::from_le_byte_slice(&bytes[23..25]),
114        }
115    }
116}
117
118/// Two relays to switch AC/DC devices
119#[derive(Clone)]
120pub struct DualRelayBricklet {
121    device: Device,
122}
123impl DualRelayBricklet {
124    pub const DEVICE_IDENTIFIER: u16 = 26;
125    pub const DEVICE_DISPLAY_NAME: &'static str = "Dual Relay Bricklet";
126    /// Creates an object with the unique device ID `uid`. This object can then be used after the IP Connection `ip_connection` is connected.
127    pub fn new(uid: Uid, connection: AsyncIpConnection) -> DualRelayBricklet {
128        let mut result = DualRelayBricklet { device: Device::new([2, 0, 10], uid, connection, Self::DEVICE_DISPLAY_NAME) };
129        result.device.response_expected[u8::from(DualRelayBrickletFunction::SetState) as usize] = ResponseExpectedFlag::False;
130        result.device.response_expected[u8::from(DualRelayBrickletFunction::GetState) as usize] = ResponseExpectedFlag::AlwaysTrue;
131        result.device.response_expected[u8::from(DualRelayBrickletFunction::SetMonoflop) as usize] = ResponseExpectedFlag::False;
132        result.device.response_expected[u8::from(DualRelayBrickletFunction::GetMonoflop) as usize] = ResponseExpectedFlag::AlwaysTrue;
133        result.device.response_expected[u8::from(DualRelayBrickletFunction::SetSelectedState) as usize] = ResponseExpectedFlag::False;
134        result.device.response_expected[u8::from(DualRelayBrickletFunction::GetIdentity) as usize] = ResponseExpectedFlag::AlwaysTrue;
135        result
136    }
137
138    /// Returns the response expected flag for the function specified by the function ID parameter.
139    /// It is true if the function is expected to send a response, false otherwise.
140    ///
141    /// For getter functions this is enabled by default and cannot be disabled, because those
142    /// functions will always send a response. For callback configuration functions it is enabled
143    /// by default too, but can be disabled by [`set_response_expected`](crate::dual_relay_bricklet::DualRelayBricklet::set_response_expected).
144    /// For setter functions it is disabled by default and can be enabled.
145    ///
146    /// Enabling the response expected flag for a setter function allows to detect timeouts
147    /// and other error conditions calls of this setter as well. The device will then send a response
148    /// for this purpose. If this flag is disabled for a setter function then no response is sent
149    /// and errors are silently ignored, because they cannot be detected.
150    ///
151    /// See [`set_response_expected`](crate::dual_relay_bricklet::DualRelayBricklet::set_response_expected) for the list of function ID constants available for this function.
152    pub fn get_response_expected(&mut self, fun: DualRelayBrickletFunction) -> Result<bool, GetResponseExpectedError> {
153        self.device.get_response_expected(u8::from(fun))
154    }
155
156    /// Changes the response expected flag of the function specified by the function ID parameter.
157    /// This flag can only be changed for setter (default value: false) and callback configuration
158    /// functions (default value: true). For getter functions it is always enabled.
159    ///
160    /// Enabling the response expected flag for a setter function allows to detect timeouts and
161    /// other error conditions calls of this setter as well. The device will then send a response
162    /// for this purpose. If this flag is disabled for a setter function then no response is sent
163    /// and errors are silently ignored, because they cannot be detected.
164    pub fn set_response_expected(
165        &mut self,
166        fun: DualRelayBrickletFunction,
167        response_expected: bool,
168    ) -> Result<(), SetResponseExpectedError> {
169        self.device.set_response_expected(u8::from(fun), response_expected)
170    }
171
172    /// Changes the response expected flag for all setter and callback configuration functions of this device at once.
173    pub fn set_response_expected_all(&mut self, response_expected: bool) {
174        self.device.set_response_expected_all(response_expected)
175    }
176
177    /// Returns the version of the API definition (major, minor, revision) implemented by this API bindings.
178    /// This is neither the release version of this API bindings nor does it tell you anything about the represented Brick or Bricklet.
179    pub fn get_api_version(&self) -> [u8; 3] {
180        self.device.api_version
181    }
182
183    /// This receiver is triggered whenever a monoflop timer reaches 0. The
184    /// parameter contain the relay (1 or 2) and the current state of the relay
185    /// (the state after the monoflop).
186    pub async fn get_monoflop_done_callback_receiver(&mut self) -> impl Stream<Item = MonoflopDoneEvent> {
187        self.device
188            .get_callback_receiver(u8::from(DualRelayBrickletFunction::CallbackMonoflopDone))
189            .await
190            .map(|p| MonoflopDoneEvent::from_le_byte_slice(p.body()))
191    }
192
193    /// Sets the state of the relays, *true* means on and *false* means off.
194    /// For example: (true, false) turns relay 1 on and relay 2 off.
195    ///
196    /// If you just want to set one of the relays and don't know the current state
197    /// of the other relay, you can get the state with [`get_state`] or you
198    /// can use [`set_selected_state`].
199    ///
200    /// All running monoflop timers will be aborted if this function is called.
201    pub async fn set_state(&mut self, relay1: bool, relay2: bool) -> Result<(), TinkerforgeError> {
202        let mut payload = [0; 2];
203        relay1.write_to_slice(&mut payload[0..1]);
204        relay2.write_to_slice(&mut payload[1..2]);
205
206        #[allow(unused_variables)]
207        let result = self.device.set(u8::from(DualRelayBrickletFunction::SetState), &payload).await?;
208        Ok(())
209    }
210
211    /// Returns the state of the relays, *true* means on and *false* means off.
212    pub async fn get_state(&mut self) -> Result<State, TinkerforgeError> {
213        let payload = [0; 0];
214
215        #[allow(unused_variables)]
216        let result = self.device.get(u8::from(DualRelayBrickletFunction::GetState), &payload).await?;
217        Ok(State::from_le_byte_slice(result.body()))
218    }
219
220    /// The first parameter can be 1 or 2 (relay 1 or relay 2). The second parameter
221    /// is the desired state of the relay (*true* means on and *false* means off).
222    /// The third parameter indicates the time that the relay should hold
223    /// the state.
224    ///
225    /// If this function is called with the parameters (1, true, 1500):
226    /// Relay 1 will turn on and in 1.5s it will turn off again.
227    ///
228    /// A monoflop can be used as a failsafe mechanism. For example: Lets assume you
229    /// have a RS485 bus and a Dual Relay Bricklet connected to one of the slave
230    /// stacks. You can now call this function every second, with a time parameter
231    /// of two seconds. The relay will be on all the time. If now the RS485
232    /// connection is lost, the relay will turn off in at most two seconds.
233    pub async fn set_monoflop(&mut self, relay: u8, state: bool, time: u32) -> Result<(), TinkerforgeError> {
234        let mut payload = [0; 6];
235        relay.write_to_slice(&mut payload[0..1]);
236        state.write_to_slice(&mut payload[1..2]);
237        time.write_to_slice(&mut payload[2..6]);
238
239        #[allow(unused_variables)]
240        let result = self.device.set(u8::from(DualRelayBrickletFunction::SetMonoflop), &payload).await?;
241        Ok(())
242    }
243
244    /// Returns (for the given relay) the current state and the time as set by
245    /// [`set_monoflop`] as well as the remaining time until the state flips.
246    ///
247    /// If the timer is not running currently, the remaining time will be returned
248    /// as 0.
249    pub async fn get_monoflop(&mut self, relay: u8) -> Result<Monoflop, TinkerforgeError> {
250        let mut payload = [0; 1];
251        relay.write_to_slice(&mut payload[0..1]);
252
253        #[allow(unused_variables)]
254        let result = self.device.get(u8::from(DualRelayBrickletFunction::GetMonoflop), &payload).await?;
255        Ok(Monoflop::from_le_byte_slice(result.body()))
256    }
257
258    /// Sets the state of the selected relay (1 or 2), *true* means on and *false* means off.
259    ///
260    /// A running monoflop timer for the selected relay will be aborted if this function is called.
261    ///
262    /// The other relay remains untouched.
263    pub async fn set_selected_state(&mut self, relay: u8, state: bool) -> Result<(), TinkerforgeError> {
264        let mut payload = [0; 2];
265        relay.write_to_slice(&mut payload[0..1]);
266        state.write_to_slice(&mut payload[1..2]);
267
268        #[allow(unused_variables)]
269        let result = self.device.set(u8::from(DualRelayBrickletFunction::SetSelectedState), &payload).await?;
270        Ok(())
271    }
272
273    /// Returns the UID, the UID where the Bricklet is connected to,
274    /// the position, the hardware and firmware version as well as the
275    /// device identifier.
276    ///
277    /// The position can be 'a', 'b', 'c', 'd', 'e', 'f', 'g' or 'h' (Bricklet Port).
278    /// A Bricklet connected to an [Isolator Bricklet](isolator_bricklet) is always at
279    /// position 'z'.
280    ///
281    /// The device identifier numbers can be found [here](device_identifier).
282    /// |device_identifier_constant|
283    pub async fn get_identity(&mut self) -> Result<Identity, TinkerforgeError> {
284        let payload = [0; 0];
285
286        #[allow(unused_variables)]
287        let result = self.device.get(u8::from(DualRelayBrickletFunction::GetIdentity), &payload).await?;
288        Ok(Identity::from_le_byte_slice(result.body()))
289    }
290}