rsiot/components/cmp_plc/tasks/
export_current_state.rs1use 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}