rsiot/drivers_i2c/pm_di16/
device.rs

1use std::sync::Arc;
2
3use futures::TryFutureExt;
4use tokio::{
5    sync::{mpsc::channel, Mutex},
6    task::JoinSet,
7};
8
9use crate::{
10    components::shared_tasks,
11    drivers_i2c::RsiotI2cDriverBase,
12    executor::{join_set_spawn, CmpInOut},
13    message::MsgDataBound,
14};
15
16use super::{tasks, Config};
17
18/// Модуль PM-RQ8
19pub struct Device<TMsg, TDriver>
20where
21    TMsg: MsgDataBound,
22    TDriver: RsiotI2cDriverBase,
23{
24    /// Внутренняя шина сообщений
25    pub msg_bus: CmpInOut<TMsg>,
26
27    /// Конфигурация
28    pub config: Config<TMsg>,
29
30    /// Драйвер I2C
31    pub driver: Arc<Mutex<TDriver>>,
32}
33
34impl<TMsg, TDriver> Device<TMsg, TDriver>
35where
36    TMsg: MsgDataBound + 'static,
37    TDriver: RsiotI2cDriverBase + 'static,
38{
39    /// Запустить на выполнение
40    pub async fn spawn(self) {
41        let mut task_set: JoinSet<super::Result<()>> = JoinSet::new();
42
43        let (ch_output_to_filter_send, ch_output_to_filter_recv) = channel(50);
44        let (ch_filter_to_msgbus_send, ch_filter_to_msgbus_recv) = channel(50);
45
46        // Периодический опрос входов и генерирование сообщений
47        let task = tasks::Output {
48            output: ch_output_to_filter_send,
49            address: self.config.address,
50            fn_output_a_0: self.config.fn_output_a_0,
51            fn_output_a_1: self.config.fn_output_a_1,
52            fn_output_a_2: self.config.fn_output_a_2,
53            fn_output_a_3: self.config.fn_output_a_3,
54            fn_output_a_4: self.config.fn_output_a_4,
55            fn_output_a_5: self.config.fn_output_a_5,
56            fn_output_a_6: self.config.fn_output_a_6,
57            fn_output_a_7: self.config.fn_output_a_7,
58            fn_output_b_0: self.config.fn_output_b_0,
59            fn_output_b_1: self.config.fn_output_b_1,
60            fn_output_b_2: self.config.fn_output_b_2,
61            fn_output_b_3: self.config.fn_output_b_3,
62            fn_output_b_4: self.config.fn_output_b_4,
63            fn_output_b_5: self.config.fn_output_b_5,
64            fn_output_b_6: self.config.fn_output_b_6,
65            fn_output_b_7: self.config.fn_output_b_7,
66            fn_output_period: self.config.fn_output_period,
67            driver: self.driver,
68        };
69        join_set_spawn(&mut task_set, task.spawn());
70
71        // Фильтрация одинаковых сообщений
72        let task = shared_tasks::filter_identical_data::FilterIdenticalData {
73            input: ch_output_to_filter_recv,
74            output: ch_filter_to_msgbus_send,
75        };
76        join_set_spawn(
77            &mut task_set,
78            task.spawn().map_err(super::Error::TaskFilterIdenticalData),
79        );
80
81        // Отправка исходящих сообщений
82        let task = shared_tasks::mpsc_to_msgbus::MpscToMsgBus {
83            input: ch_filter_to_msgbus_recv,
84            msg_bus: self.msg_bus,
85        };
86        join_set_spawn(
87            &mut task_set,
88            task.spawn().map_err(super::Error::TaskMpscToMsgBus),
89        );
90
91        while let Some(res) = task_set.join_next().await {
92            res.unwrap().unwrap();
93        }
94    }
95}