rsiot/drivers_i2c/pcf8575/
task_write_output.rs

1use std::{sync::Arc, time::Duration};
2
3use tokio::sync::Mutex;
4
5use crate::{
6    executor::CmpInOut,
7    message::{Message, MsgDataBound},
8};
9
10use super::{
11    super::{I2cSlaveAddress, RsiotI2cDriverBase},
12    state::State,
13};
14
15/// Обработка и запись выходов
16pub struct TaskWriteOutput<TMsg, Driver>
17where
18    TMsg: MsgDataBound,
19    Driver: RsiotI2cDriverBase,
20{
21    pub in_out: CmpInOut<TMsg>,
22    pub fn_input: fn(Message<TMsg>) -> Option<bool>,
23    pub state: State,
24    pub driver: Arc<Mutex<Driver>>,
25    pub address: I2cSlaveAddress,
26    pub pin: usize,
27}
28
29impl<TMsg, Driver> TaskWriteOutput<TMsg, Driver>
30where
31    Driver: RsiotI2cDriverBase,
32    TMsg: MsgDataBound,
33{
34    pub async fn spawn(&mut self) -> Result<(), String> {
35        while let Ok(msg) = self.in_out.recv_input().await {
36            let value = (self.fn_input)(msg);
37            let Some(value) = value else { continue };
38            let state_bytes = {
39                match value {
40                    true => self.state.set_output_high(self.pin).await,
41                    false => self.state.set_output_low(self.pin).await,
42                }
43                self.state.to_bytes().await
44            };
45            {
46                let mut driver = self.driver.lock().await;
47                driver
48                    .write_read(self.address, &state_bytes, 2, Duration::from_secs(2))
49                    .await?;
50            }
51        }
52        Ok(())
53    }
54}