liftof_rb/threads/
monitoring.rs

1//! Monitor the RB itself
2
3use std::time::{
4    Duration,
5    Instant
6};
7use std::sync::{
8    Arc,
9    Mutex,
10};
11
12use std::thread;
13
14use crossbeam_channel::Sender;
15
16//use tof_dataclasses::errors::SensorError;
17//use tof_dataclasses::serialization::Packable;
18//use tof_dataclasses::monitoring::{
19//    RBMoniData,
20//    PAMoniData,
21//    PBMoniData,
22//    LTBMoniData,
23//};
24//use tof_dataclasses::packets::TofPacket;
25////use tof_dataclasses::threading::ThreadControl;
26//use liftof_lib::thread_control::ThreadControl;
27
28// Takeru's tof-control code
29use tof_control::helper::pb_type::{
30    PBTemp,
31    PBVcp,
32};
33
34use tof_control::helper::pa_type::{
35    PATemp,
36    PAReadBias,
37};
38
39use tof_control::helper::ltb_type::{
40    LTBTemp,
41    LTBThreshold,
42};
43
44use tof_control::helper::rb_type::{
45    RBTemp,
46    RBMag,
47    RBVcp,
48    RBPh,
49};
50
51use gondola_core::prelude::*;
52
53use crate::control::{
54    get_trigger_rate
55};
56
57
58/// Gather monitoring data and pass it on over a channel
59///
60/// The readout of all other than the RB sensors itself
61/// (RBMoniData) is locked to the readout of the RB sensors.
62/// The readout interval of the other sensors has to be 
63/// specified in numbers of rb_moni_interval.
64///
65/// # Arguments:
66///
67/// * board_id          -  this RB's ID. It will be used
68///                        for all monitoring data as 
69///                        identifiier.
70/// * tp_sender         -  the resulting moni data will be 
71///                        wrapped in TofPackets. Use
72///                        `tp_sender` to send them to 
73///                        their destination
74/// * rb_moni_interval  -  Number of seconds between 2 consecutive
75///                        polls of RBMoniData. 
76///                        Set to 0 to disable monitoring.
77/// * pa_moni_every_x   -  Get PA (preamp) moni data every x polls of RBMoniData
78///                        Set to 0 to disable monitoring.
79/// * pb_moni_every_x   -  Get PB (power board) moni data every x polls of RBMoniData
80///                        Set to 0 to disable monitoring.
81/// * ltb_moni_every_x  -  Get LTB moni data every x polls of RBMoniData
82///                        Set to 0 to disable monitoring.
83/// * verbose           -  print additional output for debugging
84/// * thread_control    -  central thread control, e.g. kill signal
85pub fn monitoring(board_id          : u8,
86                  tp_sender         : &Sender<TofPacket>,
87                  rb_moni_interval  : f32,
88                  pa_moni_every_x   : f32,
89                  pb_moni_every_x   : f32,
90                  ltb_moni_every_x  : f32,
91                  verbose           : bool,
92                  thread_control    : Arc<Mutex<ThreadControl>>) {
93
94  println!("[MONI] ==> Starting monitoring thread!");
95
96  let mut rb_moni_timer   = Instant::now();
97  let mut pa_moni_timer   = Instant::now();
98  let mut pb_moni_timer   = Instant::now();
99  let mut ltb_moni_timer  = Instant::now();
100 
101  // we calculate some sleep time, to reduce CPU load
102  // check for the smallest interfval and use that as sleep.
103  let mut sleeptime_sec = rb_moni_interval;
104  if pa_moni_every_x*rb_moni_interval < sleeptime_sec {
105    sleeptime_sec = pa_moni_every_x*rb_moni_interval;
106  }
107  if pb_moni_every_x*rb_moni_interval < sleeptime_sec {
108    sleeptime_sec = pb_moni_every_x*rb_moni_interval;
109  }
110  if ltb_moni_every_x*rb_moni_interval < sleeptime_sec {
111    sleeptime_sec = ltb_moni_every_x*rb_moni_interval;
112  }
113  debug!("Setting sleeptime to {} seconds!", sleeptime_sec);
114  let sleeptime = Duration::from_secs_f32(sleeptime_sec);
115
116  loop {
117    match thread_control.lock() {
118      Ok(tc) => {
119        if tc.stop_flag {
120          println!("[MONI] ==> Received STOP signal. Will end thread!");
121          info!("Received stop signal. Will stop thread!");
122          break;
123        }
124      },
125      Err(err) => {
126        trace!("Can't acquire lock! {err}");
127      },
128    }
129
130    // RB monitoring routine
131    if rb_moni_timer.elapsed().as_secs_f32() > rb_moni_interval {
132      let moni_dt = get_rb_moni(board_id).unwrap();
133
134      if verbose {
135        println!("{}", moni_dt);
136      }
137
138      let tp = moni_dt.pack();
139      match tp_sender.try_send(tp) {
140        Err(err) => error!("Issue sending RBMoniData {:?}", err),
141        Ok(_)    => trace!("Sent RBMoniData successfully!"),
142      }
143      rb_moni_timer = Instant::now();
144    }
145
146    // Preamp monitoring routine
147    if pa_moni_timer.elapsed().as_secs_f32() > rb_moni_interval*pa_moni_every_x {
148      let moni = get_preamp_moni(board_id).unwrap();
149
150      if verbose {
151        println!("{}", moni);
152      }
153
154      let tp = moni.pack();
155      match tp_sender.try_send(tp) {
156        Err(err) => error!("Issue sending PAMoniData {:?}", err),
157        Ok(_)    => trace!("Sent PAMoniData successfully!"),
158      }
159      pa_moni_timer = Instant::now();
160    }
161
162    // PB monitoring routine
163    if pb_moni_timer.elapsed().as_secs_f32() > rb_moni_interval*pb_moni_every_x {
164      let moni = get_pb_moni(board_id).unwrap();
165
166      if verbose {
167        println!("{}", moni);
168      }
169
170      let tp = moni.pack();
171      match tp_sender.try_send(tp) {
172        Err(err) => error!("Issue sending PBMoniData {:?}", err),
173        Ok(_)    => trace!("Sent PBMoniData successfully!"),
174      }
175      pb_moni_timer = Instant::now();
176    }
177
178    // LTB monitoring routine
179    if ltb_moni_timer.elapsed().as_secs_f32() > rb_moni_interval*ltb_moni_every_x {
180      let moni = get_ltb_moni(board_id).unwrap();
181
182      if verbose {
183        println!("{}", moni);
184      }
185
186      let tp = moni.pack();
187      match tp_sender.try_send(tp) {
188        Err(err) => error!("Issue sending LTBMoniData {:?}", err),
189        Ok(_)    => debug!("Sent LTBMoniData successfully!"),
190      }
191      ltb_moni_timer = Instant::now();
192    }
193    thread::sleep(sleeptime);
194  }
195}
196
197/// Get RB monitoring data for a RB board_id
198pub fn get_rb_moni(board_id: u8) -> Result<RBMoniData, SensorError> {
199  // get tof-control data
200  let mut moni_dt = RBMoniData::new();
201  moni_dt.board_id = board_id; 
202  let rb_temp = RBTemp::new();
203  let rb_mag  = RBMag::new();
204  let rb_vcp  = RBVcp::new();
205  let rb_ph   = RBPh::new();
206  moni_dt.add_rbtemp(&rb_temp);
207  moni_dt.add_rbmag(&rb_mag);
208  moni_dt.add_rbvcp(&rb_vcp);
209  moni_dt.add_rbph(&rb_ph);
210  
211  let rate_query = get_trigger_rate();
212  match rate_query {
213    Ok(rate) => {
214      debug!("Monitoring thread -> Rate: {rate}Hz ");
215      moni_dt.rate = rate as u16;
216    },
217    Err(_)   => {
218      warn!("Can not send rate monitoring packet, register problem");
219    }
220  }
221  Ok(moni_dt)
222}
223
224/// Get Preamp monitoring data for an RB board_id
225pub fn get_preamp_moni(board_id: u8) -> Result<PAMoniData, SensorError> {
226  let mut moni = PAMoniData::new();
227  moni.board_id = board_id;
228  // FIXME - this won't fail, however, if there
229  // is an issue it will silently set all values
230  // to f32::MAX
231  let pa_tmp = PATemp::new();
232  let pa_bia = PAReadBias::new();
233  moni.add_temps(&pa_tmp);
234  moni.add_biases(&pa_bia);
235  Ok(moni)
236}
237
238/// Get PB monitoring data for an RB board_id
239pub fn get_pb_moni(board_id: u8) -> Result<PBMoniData, SensorError> {
240  let mut moni = PBMoniData::new();
241  moni.board_id = board_id;
242  let pb_temp = PBTemp::new();
243  let pb_vcp  = PBVcp::new();
244  moni.add_temps(&pb_temp);
245  moni.add_vcp(&pb_vcp);
246  Ok(moni)
247}
248
249/// Get LTB monitoring data for an RB board_id
250pub fn get_ltb_moni(board_id: u8) -> Result<LTBMoniData, SensorError> {
251  let mut moni = LTBMoniData::new();
252  moni.board_id = board_id;
253  let ltb_temp = LTBTemp::new();
254  let ltb_thrs = LTBThreshold::new();
255  moni.add_temps(&ltb_temp);
256  moni.add_thresh(&ltb_thrs);
257  Ok(moni)
258}