rsiot/components/cmp_plc/tasks/
export_current_state.rs

1use std::sync::Arc;
2
3use serde::Serialize;
4use tokio::sync::Mutex;
5
6use crate::{
7    executor::{sleep, CmpInOut},
8    message::MsgDataBound,
9};
10
11use super::super::{
12    plc::{FunctionBlockBase, IFunctionBlock},
13    ConfigRetention,
14};
15
16pub struct ExportCurrentState<TMsg, I, Q, S>
17where
18    TMsg: MsgDataBound,
19    I: Clone + Default + Send + Serialize,
20    Q: Clone + Default + Send + Serialize,
21    S: Clone + Default + Send + Serialize,
22    FunctionBlockBase<I, Q, S>: IFunctionBlock<I, Q, S>,
23{
24    pub in_out: CmpInOut<TMsg>,
25    pub config_retention: Option<ConfigRetention<TMsg, I, Q, S>>,
26    pub fb_main: Arc<Mutex<FunctionBlockBase<I, Q, S>>>,
27}
28
29impl<TMsg, I, Q, S> ExportCurrentState<TMsg, I, Q, S>
30where
31    TMsg: MsgDataBound,
32    I: Clone + Default + Send + Serialize,
33    Q: Clone + Default + Send + Serialize,
34    S: Clone + Default + Send + Serialize,
35    FunctionBlockBase<I, Q, S>: IFunctionBlock<I, Q, S>,
36{
37    pub async fn spawn(self) -> super::Result<()> {
38        let Some(config_retention) = self.config_retention else {
39            return Ok(());
40        };
41        loop {
42            sleep(config_retention.save_period).await;
43            let input;
44            let output;
45            let stat;
46            {
47                let fb_main = self.fb_main.lock().await;
48                input = fb_main.i.clone();
49                output = fb_main.q.clone();
50                stat = fb_main.s.clone();
51            }
52            let msgs = (config_retention.fn_export)(&input, &output, &stat);
53            let Some(msgs) = msgs else { continue };
54            for msg in msgs {
55                self.in_out.send_output(msg).await.unwrap();
56            }
57        }
58    }
59}