1use crate::prelude::*;
5
6#[cfg(feature="tofcontrol")]
7use tof_control::helper::pb_type::{
8 PBTemp,
9 PBVcp
10};
11
12#[derive(Debug, Copy, Clone, PartialEq)]
16#[cfg_attr(feature="pybindings", pyclass)]
17pub struct PBMoniData {
18 pub board_id : u8,
19 pub p3v6_preamp_vcp: [f32; 3],
20 pub n1v6_preamp_vcp: [f32; 3],
21 pub p3v4f_ltb_vcp : [f32; 3],
22 pub p3v4d_ltb_vcp : [f32; 3],
23 pub p3v6_ltb_vcp : [f32; 3],
24 pub n1v6_ltb_vcp : [f32; 3],
25 pub pds_temp : f32,
26 pub pas_temp : f32,
27 pub nas_temp : f32,
28 pub shv_temp : f32,
29 pub timestamp : u64,
31}
32
33impl PBMoniData {
34 pub fn new() -> Self {
35 Self {
36 board_id : 0,
37 p3v6_preamp_vcp: [f32::MAX, f32::MAX, f32::MAX],
38 n1v6_preamp_vcp: [f32::MAX, f32::MAX, f32::MAX],
39 p3v4f_ltb_vcp : [f32::MAX, f32::MAX, f32::MAX],
40 p3v4d_ltb_vcp : [f32::MAX, f32::MAX, f32::MAX],
41 p3v6_ltb_vcp : [f32::MAX, f32::MAX, f32::MAX],
42 n1v6_ltb_vcp : [f32::MAX, f32::MAX, f32::MAX],
43 pds_temp : f32::MAX,
44 pas_temp : f32::MAX,
45 nas_temp : f32::MAX,
46 shv_temp : f32::MAX,
47 timestamp : 0,
48 }
49 }
50
51 #[cfg(feature = "tofcontrol")]
52 pub fn add_temps(&mut self, pbtmp : &PBTemp) {
53 self.pds_temp = pbtmp.pds_temp;
54 self.pas_temp = pbtmp.pas_temp;
55 self.nas_temp = pbtmp.nas_temp;
56 self.shv_temp = pbtmp.shv_temp;
57 }
58
59 #[cfg(feature = "tofcontrol")]
60 pub fn add_vcp(&mut self, pbvcp : &PBVcp) {
61 self.p3v6_preamp_vcp = pbvcp.p3v6_pa_vcp;
62 self.n1v6_preamp_vcp = pbvcp.n1v6_pa_vcp;
63 self.p3v4f_ltb_vcp = pbvcp.p3v4f_ltb_vcp;
64 self.p3v4d_ltb_vcp = pbvcp.p3v4d_ltb_vcp;
65 self.p3v6_ltb_vcp = pbvcp.p3v6_ltb_vcp;
66 self.n1v6_ltb_vcp = pbvcp.n1v6_ltb_vcp;
67 }
68}
69
70#[cfg(feature="pybindings")]
71#[pymethods]
72impl PBMoniData {
73
74 #[getter]
75 fn get_board_id(&self) -> u8 {
76 self.board_id
77 }
78
79 #[getter]
80 #[pyo3(name="timestamp")]
81 fn get_timestamp_py(&self) -> u64 {
82 self.timestamp
83 }
84
85 #[getter]
86 fn get_p3v6_preamp_vcp(&self) -> [f32; 3] {
87 self.p3v6_preamp_vcp
88 }
89
90 #[getter]
91 fn get_n1v6_preamp_vcp(&self) -> [f32; 3] {
92 self.n1v6_preamp_vcp
93 }
94
95 #[getter]
96 fn get_p3v4f_ltb_vcp(&self) -> [f32; 3] {
97 self.p3v4f_ltb_vcp
98 }
99
100 #[getter]
101 fn get_p3v4d_ltb_vcp(&self) -> [f32; 3] {
102 self.p3v4d_ltb_vcp
103 }
104
105 #[getter]
106 fn get_p3v6_ltb_vcp(&self) -> [f32; 3] {
107 self.p3v6_ltb_vcp
108 }
109
110 #[getter]
111 fn get_n1v6_ltb_vcp(&self) -> [f32; 3] {
112 self.n1v6_ltb_vcp
113 }
114
115 #[getter]
116 fn get_pds_temp(&self) -> f32 {
117 self.pds_temp
118 }
119 #[getter]
120 fn get_pas_temp(&self) -> f32 {
121 self.pas_temp
122 }
123 #[getter]
124 fn get_nas_temp(&self) -> f32 {
125 self.nas_temp
126 }
127
128 #[getter]
129 fn get_shv_temp(&self) -> f32 {
130 self.shv_temp
131 }
132}
133
134impl Default for PBMoniData {
135 fn default() -> Self {
136 Self::new()
137 }
138}
139
140impl fmt::Display for PBMoniData {
141 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
142 write!(f, "<PBMoniData:
143 BOARD ID : {}
144 ** Temperatures **
145 PDS TMP : {:.2} [\u{00B0}C]
146 PAS TMP : {:.2} [\u{00B0}C]
147 NAS TMP : {:.2} [\u{00B0}C]
148 SHV TMP : {:.2} [\u{00B0}C]
149 ** Power **
150 P3V6 Preamp : {:.3} [V] | {:.3} [A] | {:.3} [W]
151 N1V6 Preamp : {:.3} [V] | {:.3} [A] | {:.3} [W]
152 P3V4f LTB : {:.3} [V] | {:.3} [A] | {:.3} [W]
153 P3V4d LTB : {:.3} [V] | {:.3} [A] | {:.3} [W]
154 P3V6 LTB : {:.3} [V] | {:.3} [A] | {:.3} [W]
155 N1V6 LTB : {:.3} [V] | {:.3} [A] | {:.3} [W]>",
156 self.board_id ,
157 if self.pds_temp != f32::MAX {self.pds_temp.to_string()} else {String::from("f32::MAX (ERR)")},
158 if self.pas_temp != f32::MAX {self.pas_temp.to_string()} else {String::from("f32::MAX (ERR)")},
159 if self.nas_temp != f32::MAX {self.nas_temp.to_string()} else {String::from("f32::MAX (ERR)")},
160 if self.shv_temp != f32::MAX {self.shv_temp.to_string()} else {String::from("f32::MAX (ERR)")},
161 if self.p3v6_preamp_vcp[0] != f32::MAX {self.p3v6_preamp_vcp[0].to_string()} else {String::from("f32::MAX (ERR)")},
162 if self.p3v6_preamp_vcp[1] != f32::MAX {self.p3v6_preamp_vcp[1].to_string()} else {String::from("f32::MAX (ERR)")},
163 if self.p3v6_preamp_vcp[2] != f32::MAX {self.p3v6_preamp_vcp[2].to_string()} else {String::from("f32::MAX (ERR)")},
164 if self.n1v6_preamp_vcp[0] != f32::MAX {self.n1v6_preamp_vcp[0].to_string()} else {String::from("f32::MAX (ERR)")},
165 if self.n1v6_preamp_vcp[1] != f32::MAX {self.n1v6_preamp_vcp[1].to_string()} else {String::from("f32::MAX (ERR)")},
166 if self.n1v6_preamp_vcp[2] != f32::MAX {self.n1v6_preamp_vcp[2].to_string()} else {String::from("f32::MAX (ERR)")},
167 if self.p3v4f_ltb_vcp[0] != f32::MAX {self.p3v4f_ltb_vcp[0].to_string() } else {String::from("f32::MAX (ERR)")},
168 if self.p3v4f_ltb_vcp[1] != f32::MAX {self.p3v4f_ltb_vcp[1].to_string() } else {String::from("f32::MAX (ERR)")},
169 if self.p3v4f_ltb_vcp[2] != f32::MAX {self.p3v4f_ltb_vcp[2].to_string() } else {String::from("f32::MAX (ERR)")},
170 if self.p3v4d_ltb_vcp[0] != f32::MAX {self.p3v4d_ltb_vcp[0].to_string() } else {String::from("f32::MAX (ERR)")},
171 if self.p3v4d_ltb_vcp[1] != f32::MAX {self.p3v4d_ltb_vcp[1].to_string() } else {String::from("f32::MAX (ERR)")},
172 if self.p3v4d_ltb_vcp[2] != f32::MAX {self.p3v4d_ltb_vcp[2].to_string() } else {String::from("f32::MAX (ERR)")},
173 if self.p3v6_ltb_vcp[0] != f32::MAX {self.p3v6_ltb_vcp[0].to_string() } else {String::from("f32::MAX (ERR)")},
174 if self.p3v6_ltb_vcp[1] != f32::MAX {self.p3v6_ltb_vcp[1].to_string() } else {String::from("f32::MAX (ERR)")},
175 if self.p3v6_ltb_vcp[2] != f32::MAX {self.p3v6_ltb_vcp[2].to_string() } else {String::from("f32::MAX (ERR)")},
176 if self.n1v6_ltb_vcp[0] != f32::MAX {self.n1v6_ltb_vcp[0].to_string() } else {String::from("f32::MAX (ERR)")},
177 if self.n1v6_ltb_vcp[1] != f32::MAX {self.n1v6_ltb_vcp[1].to_string() } else {String::from("f32::MAX (ERR)")},
178 if self.n1v6_ltb_vcp[2] != f32::MAX {self.n1v6_ltb_vcp[2].to_string() } else {String::from("f32::MAX (ERR)")})
179 }
180}
181
182impl TofPackable for PBMoniData {
183 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::PBMoniData;
184}
185
186impl MoniData for PBMoniData {
187
188 fn get_board_id(&self) -> u8 {
189 self.board_id
190 }
191
192 fn get_timestamp(&self) -> u64 {
193 self.timestamp
194 }
195
196 fn set_timestamp(&mut self, ts : u64) {
197 self.timestamp = ts;
198 }
199
200 fn get(&self, varname : &str) -> Option<f32> {
201 match varname {
202 "board_id" => Some(0.0f32),
203 "p3v6_preamp_v" => Some(self.p3v6_preamp_vcp[0]),
204 "p3v6_preamp_c" => Some(self.p3v6_preamp_vcp[1]),
205 "p3v6_preamp_p" => Some(self.p3v6_preamp_vcp[2]),
206 "n1v6_preamp_v" => Some(self.n1v6_preamp_vcp[0]),
207 "n1v6_preamp_c" => Some(self.n1v6_preamp_vcp[1]),
208 "n1v6_preamp_p" => Some(self.n1v6_preamp_vcp[2]),
209 "p3v4f_ltb_v" => Some(self.p3v4f_ltb_vcp[0]),
210 "p3v4f_ltb_c" => Some(self.p3v4f_ltb_vcp[1]),
211 "p3v4f_ltb_p" => Some(self.p3v4f_ltb_vcp[2]),
212 "p3v4d_ltb_v" => Some(self.p3v4d_ltb_vcp[0]),
213 "p3v4d_ltb_c" => Some(self.p3v4d_ltb_vcp[1]),
214 "p3v4d_ltb_p" => Some(self.p3v4d_ltb_vcp[2]),
215 "p3v6_ltb_v" => Some(self.p3v6_ltb_vcp[0]),
216 "p3v6_ltb_c" => Some(self.p3v6_ltb_vcp[1]),
217 "p3v6_ltb_p" => Some(self.p3v6_ltb_vcp[2]),
218 "n1v6_ltb_v" => Some(self.n1v6_ltb_vcp[0]),
219 "n1v6_ltb_c" => Some(self.n1v6_ltb_vcp[1]),
220 "n1v6_ltb_p" => Some(self.n1v6_ltb_vcp[2]),
221 "pds_temp" => Some(self.pds_temp),
222 "pas_temp" => Some(self.pas_temp),
223 "nas_temp" => Some(self.nas_temp),
224 "shv_temp" => Some(self.shv_temp),
225 "timestamp" => Some(self.timestamp as f32),
226 _ => None,
227 }
228 }
229
230 fn keys() -> Vec<&'static str> {
231 vec!["board_id",
232 "p3v6_preamp_v", "p3v6_preamp_c", "p3v6_preamp_p",
233 "n1v6_preamp_v", "n1v6_preamp_c", "n1v6_preamp_p",
234 "p3v4f_ltb_v", "p3v4f_ltb_c", "p3v4f_ltb_p",
235 "p3v4d_ltb_v", "p3v4d_ltb_c", "p3v4d_ltb_p",
236 "p3v6_ltb_v", "p3v6_ltb_c", "p3v6_ltb_p",
237 "n1v6_ltb_v", "n1v6_ltb_c", "n1v6_ltb_p",
238 "pds_temp", "pas_temp", "nas_temp", "shv_temp","timestamp"]
239 }
240}
241
242
243impl Serialization for PBMoniData {
244 const HEAD : u16 = 0xAAAA;
245 const TAIL : u16 = 0x5555;
246 const SIZE : usize = 89 + 4; fn to_bytestream(&self) -> Vec<u8> {
253 let mut stream = Vec::<u8>::with_capacity(Self::SIZE);
254 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
255 stream.extend_from_slice(&self.board_id .to_le_bytes());
256 stream.extend_from_slice(&self.p3v6_preamp_vcp[0].to_le_bytes());
257 stream.extend_from_slice(&self.p3v6_preamp_vcp[1].to_le_bytes());
258 stream.extend_from_slice(&self.p3v6_preamp_vcp[2].to_le_bytes());
259 stream.extend_from_slice(&self.n1v6_preamp_vcp[0].to_le_bytes());
260 stream.extend_from_slice(&self.n1v6_preamp_vcp[1].to_le_bytes());
261 stream.extend_from_slice(&self.n1v6_preamp_vcp[2].to_le_bytes());
262 stream.extend_from_slice(&self.p3v4f_ltb_vcp[0] .to_le_bytes());
263 stream.extend_from_slice(&self.p3v4f_ltb_vcp[1] .to_le_bytes());
264 stream.extend_from_slice(&self.p3v4f_ltb_vcp[2] .to_le_bytes());
265 stream.extend_from_slice(&self.p3v4d_ltb_vcp[0] .to_le_bytes());
266 stream.extend_from_slice(&self.p3v4d_ltb_vcp[1] .to_le_bytes());
267 stream.extend_from_slice(&self.p3v4d_ltb_vcp[2] .to_le_bytes());
268 stream.extend_from_slice(&self.p3v6_ltb_vcp[0] .to_le_bytes());
269 stream.extend_from_slice(&self.p3v6_ltb_vcp[1] .to_le_bytes());
270 stream.extend_from_slice(&self.p3v6_ltb_vcp[2] .to_le_bytes());
271 stream.extend_from_slice(&self.n1v6_ltb_vcp[0] .to_le_bytes());
272 stream.extend_from_slice(&self.n1v6_ltb_vcp[1] .to_le_bytes());
273 stream.extend_from_slice(&self.n1v6_ltb_vcp[2] .to_le_bytes());
274 stream.extend_from_slice(&self.pds_temp .to_le_bytes());
275 stream.extend_from_slice(&self.pas_temp .to_le_bytes());
276 stream.extend_from_slice(&self.nas_temp .to_le_bytes());
277 stream.extend_from_slice(&self.shv_temp .to_le_bytes());
278 stream.extend_from_slice(&Self::TAIL.to_le_bytes());
279 stream
280 }
281
282 fn from_bytestream(stream : &Vec<u8>,
283 pos : &mut usize)
284 -> Result<PBMoniData, SerializationError>{
285 Self::verify_fixed(stream, pos)?;
286 let mut moni = PBMoniData::new();
287 moni.board_id = parse_u8(stream, pos) ;
288 moni.p3v6_preamp_vcp[0] = parse_f32(stream, pos);
289 moni.p3v6_preamp_vcp[1] = parse_f32(stream, pos);
290 moni.p3v6_preamp_vcp[2] = parse_f32(stream, pos);
291 moni.n1v6_preamp_vcp[0] = parse_f32(stream, pos);
292 moni.n1v6_preamp_vcp[1] = parse_f32(stream, pos);
293 moni.n1v6_preamp_vcp[2] = parse_f32(stream, pos);
294 moni.p3v4f_ltb_vcp[0] = parse_f32(stream, pos);
295 moni.p3v4f_ltb_vcp[1] = parse_f32(stream, pos);
296 moni.p3v4f_ltb_vcp[2] = parse_f32(stream, pos);
297 moni.p3v4d_ltb_vcp[0] = parse_f32(stream, pos);
298 moni.p3v4d_ltb_vcp[1] = parse_f32(stream, pos);
299 moni.p3v4d_ltb_vcp[2] = parse_f32(stream, pos);
300 moni.p3v6_ltb_vcp[0] = parse_f32(stream, pos);
301 moni.p3v6_ltb_vcp[1] = parse_f32(stream, pos);
302 moni.p3v6_ltb_vcp[2] = parse_f32(stream, pos);
303 moni.n1v6_ltb_vcp[0] = parse_f32(stream, pos);
304 moni.n1v6_ltb_vcp[1] = parse_f32(stream, pos);
305 moni.n1v6_ltb_vcp[2] = parse_f32(stream, pos);
306 moni.pds_temp = parse_f32(stream, pos);
307 moni.pas_temp = parse_f32(stream, pos);
308 moni.nas_temp = parse_f32(stream, pos);
309 moni.shv_temp = parse_f32(stream, pos);
310 *pos += 2;Ok(moni)
312 }
313}
314
315#[cfg(feature = "random")]
316impl FromRandom for PBMoniData {
317
318 fn from_random() -> PBMoniData {
319 let mut moni = Self::new();
320 let mut rng = rand::rng();
321 moni.board_id = rng.random::<u8>();
322 for k in 0..3 {
323 let foo = rng.random::<f32>();
324 moni.p3v6_preamp_vcp[k] = foo;
325 }
326 for k in 0..3 {
327 let foo = rng.random::<f32>();
328 moni.n1v6_preamp_vcp[k] = foo;
329 }
330 for k in 0..3 {
331 let foo = rng.random::<f32>();
332 moni.p3v4f_ltb_vcp[k] = foo;
333 }
334 for k in 0..3 {
335 let foo = rng.random::<f32>();
336 moni.p3v4d_ltb_vcp[k] = foo;
337 }
338 for k in 0..3 {
339 let foo = rng.random::<f32>();
340 moni.p3v6_ltb_vcp[k] = foo;
341 }
342 for k in 0..3 {
343 let foo = rng.random::<f32>();
344 moni.n1v6_ltb_vcp[k] = foo;
345 }
346 moni.pds_temp = rng.random::<f32>();
347 moni.pas_temp = rng.random::<f32>();
348 moni.nas_temp = rng.random::<f32>();
349 moni.shv_temp = rng.random::<f32>();
350 moni
351 }
352}
353
354moniseries!(PBMoniDataSeries, PBMoniData);
357
358#[cfg(feature="pybindings")]
359pythonize_packable!(PBMoniData);
360
361#[cfg(feature="pybindings")]
362pythonize_monidata!(PBMoniData);
363
364#[test]
367#[cfg(feature = "random")]
368fn pack_pbmonidata() {
369 for _ in 0..100 {
370 let data = PBMoniData::from_random();
371 let test : PBMoniData = data.pack().unpack().unwrap();
372 assert_eq!(data, test);
373 }
374}
375