gondola_core/monitoring/
ltb_moni_data.rs

1// This file is part of gaps-online-software and published 
2// under the GPLv3 license
3
4use crate::prelude::*;
5
6#[cfg(feature="tofcontrol")]
7use tof_control::helper::ltb_type::{
8  LTBThreshold,
9  LTBTemp
10};
11
12/// Sensors on the LTB
13#[derive(Debug, Copy, Clone, PartialEq)]
14#[cfg_attr(feature="pybindings", pyclass)]
15pub struct LTBMoniData {
16  pub board_id   : u8,
17  pub trenz_temp : f32,
18  pub ltb_temp   : f32,
19  pub thresh     : [f32;3],
20  // not serialzied 
21  pub timestamp  : u64, 
22}
23
24impl LTBMoniData {
25  pub fn new() -> LTBMoniData {
26    LTBMoniData {
27      board_id   : 0,
28      trenz_temp : f32::MAX,
29      ltb_temp   : f32::MAX,
30      thresh     : [f32::MAX,f32::MAX,f32::MAX],
31      timestamp  : 0,
32    }
33  }
34
35  #[cfg(feature = "tofcontrol")]
36  pub fn add_temps(&mut self, lt : &LTBTemp) {
37    self.trenz_temp = lt.trenz_temp;
38    self.ltb_temp   = lt.board_temp;
39  }
40
41  #[cfg(feature = "tofcontrol")]
42  pub fn add_thresh(&mut self, lt : &LTBThreshold) {
43    self.thresh = [lt.thresh_0, lt.thresh_1, lt.thresh_2];
44  }
45}
46
47impl Default for LTBMoniData {
48  fn default() -> Self {
49    Self::new()
50  }
51}
52
53impl fmt::Display for LTBMoniData {
54  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55    write!(f, "<LTBMoniData:
56  Board ID  : {}
57  ** Temperatures **
58  TRENZ TMP : {:.2} [\u{00B0}C]
59  LTB   TMP : {:.2} [\u{00B0}C]
60  ** Threshold Voltages **
61  THR HIT, THR BETA, THR VETO : {:.3} | {:.3} | {:.3} [mV]>",
62  self.board_id,
63  self.trenz_temp,
64  self.ltb_temp,
65  self.thresh[0],
66  self.thresh[1],
67  self.thresh[2])
68  }
69}
70
71impl TofPackable for LTBMoniData {
72  const TOF_PACKET_TYPE : TofPacketType = TofPacketType::LTBMoniData;
73}
74
75impl Serialization for LTBMoniData {
76  
77  const HEAD : u16 = 0xAAAA;
78  const TAIL : u16 = 0x5555;
79  /// The data size when serialized to a bytestream
80  /// This needs to be updated when we change the 
81  /// packet layout, e.g. add new members.
82  /// HEAD + TAIL + sum(sizeof(m) for m in _all_members_))
83  const SIZE : usize  = 4 + 1 + (4*5) ;
84  
85  fn to_bytestream(&self) -> Vec<u8> {
86    let mut stream = Vec::<u8>::with_capacity(Self::SIZE);
87    stream.extend_from_slice(&Self::HEAD.to_le_bytes());
88    stream.extend_from_slice(&self.board_id          .to_le_bytes()); 
89    stream.extend_from_slice(&self.trenz_temp. to_le_bytes());
90    stream.extend_from_slice(&self.ltb_temp.   to_le_bytes());
91    for k in 0..3 {
92      stream.extend_from_slice(&self.thresh[k].to_le_bytes());
93    }
94    stream.extend_from_slice(&Self::TAIL.to_le_bytes());
95    stream
96  }
97  
98  fn from_bytestream(stream    : &Vec<u8>, 
99                     pos       : &mut usize) 
100    -> Result<Self, SerializationError>{
101    let mut moni     = Self::new();
102    Self::verify_fixed(stream, pos)?;
103    moni.board_id    = parse_u8(stream, pos);
104    moni.trenz_temp  = parse_f32(stream, pos);
105    moni.ltb_temp    = parse_f32(stream, pos);
106    for k in 0..3 {
107      moni.thresh[k] = parse_f32(stream, pos);
108    }
109    *pos += 2;
110    Ok(moni)
111  }
112}
113
114#[cfg(feature = "random")]
115impl FromRandom for LTBMoniData {
116    
117  fn from_random() -> LTBMoniData {
118    let mut moni  = Self::new();
119    let mut rng   = rand::rng();
120    moni.board_id = rng.random::<u8>(); 
121    moni.trenz_temp = rng.random::<f32>();
122    moni.ltb_temp   = rng.random::<f32>();
123    for k in 0..3 {
124      moni.thresh[k] = rng.random::<f32>();
125    }
126    moni.timestamp = 0;
127    moni
128  }
129}
130
131impl MoniData for LTBMoniData {
132  fn get_board_id(&self) -> u8 {
133    self.board_id
134  }
135  
136  fn get_timestamp(&self) -> u64 {
137    self.timestamp
138  }
139
140  /// Access the (data) members by name 
141  fn get(&self, varname : &str) -> Option<f32> {
142    match varname {
143    "board_id"    => Some(self.board_id as f32),
144    "trenz_temp"  => Some(self.trenz_temp),
145    "ltb_temp"    => Some(self.ltb_temp),
146    "thresh0"     => Some(self.thresh[0]),
147    "thresh1"     => Some(self.thresh[1]),
148    "thresh2"     => Some(self.thresh[2]),
149    "timestamp"   => Some(self.timestamp as f32),
150    _             => None
151    }
152  }
153
154  /// A list of the variables in this MoniData
155  fn keys() -> Vec<&'static str> {
156    vec!["board_id", "trenz_temp", "ltb_temp",
157         "thresh0", "thresh1", "thresh2", "timestamp"]
158  }
159}
160
161#[cfg(feature="pybindings")]
162#[pymethods]
163impl LTBMoniData {
164  
165  #[getter]
166  fn get_trenz_temp    (&self)  -> f32  {
167    self.trenz_temp
168  }
169
170  #[getter]
171  fn get_ltb_temp      (&self)  -> f32  {
172    self.ltb_temp
173  }
174  #[getter]
175  fn get_thresh0       (&self)  -> f32  {
176    self.thresh[0]
177  }
178  #[getter]
179  fn get_thresh1       (&self)  -> f32  {
180    self.thresh[1]
181  }
182  #[getter]
183  fn get_thresh2       (&self)  -> f32  {
184    self.thresh[2]
185  }
186
187  #[getter]
188  #[pyo3(name = "timestamp")]
189  fn get_timestamp_py(&self)  -> u64 {
190    self.timestamp 
191  }
192}
193
194//----------------------------------------
195
196moniseries!(LTBMoniDataSeries, LTBMoniData);
197
198#[cfg(feature="pybindings")]
199pythonize_packable!(LTBMoniData);
200
201#[cfg(feature="pybindings")]
202pythonize_monidata!(LTBMoniData);
203
204//----------------------------------------
205
206#[test]
207#[cfg(feature = "random")]
208fn pack_ltbmonidata() {
209  for _ in 0..100 {
210    let data = LTBMoniData::from_random();
211    let test : LTBMoniData = data.pack().unpack().unwrap();
212    assert_eq!(data, test);
213  }
214}
215
216