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