1use crate::prelude::*;
5
6#[cfg(feature="tofcontrol")]
7use tof_control::helper::pa_type::{
8 PATemp,
9 PAReadBias
10};
11
12
13#[derive(Debug, Copy, Clone, PartialEq)]
15#[cfg_attr(feature="pybindings", pyclass)]
16pub struct PAMoniData {
17 pub board_id : u8,
18 pub temps : [f32;16],
19 pub biases : [f32;16],
20 pub timestamp : u64,
21}
22
23impl PAMoniData {
24
25 pub fn new() -> Self {
26 Self {
27 board_id : 0,
28 temps : [f32::MAX;16],
29 biases : [f32::MAX;16],
30 timestamp : 0,
31 }
32 }
33
34 #[cfg(feature = "tofcontrol")]
35 pub fn add_temps(&mut self, pt : &PATemp ) {
36 self.temps = pt.pa_temps;
37 }
38
39 #[cfg(feature = "tofcontrol")]
40 pub fn add_biases(&mut self, pb : &PAReadBias) {
41 self.biases = pb.read_biases;
42 }
43}
44
45#[cfg(feature="pybindings")]
46#[pymethods]
47impl PAMoniData {
48
49 #[getter]
51 fn get_temps(&self) -> [f32;16] {
52 self.temps
53 }
54
55 #[getter]
57 fn get_biases(&self) -> [f32;16] {
58 self.biases
59 }
60}
61
62impl Default for PAMoniData {
63 fn default() -> Self {
64 Self::new()
65 }
66}
67
68impl fmt::Display for PAMoniData {
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 write!(f, "<PAMoniData:
71 Board ID : {}
72 **16 Temp values**
73 T1 : {:.2} [\u{00B0}C]
74 T2 : {:.2} [\u{00B0}C]
75 T3 : {:.2} [\u{00B0}C]
76 T4 : {:.2} [\u{00B0}C]
77 T5 : {:.2} [\u{00B0}C]
78 T6 : {:.2} [\u{00B0}C]
79 T7 : {:.2} [\u{00B0}C]
80 T8 : {:.2} [\u{00B0}C]
81 T9 : {:.2} [\u{00B0}C]
82 T10 : {:.2} [\u{00B0}C]
83 T11 : {:.2} [\u{00B0}C]
84 T12 : {:.2} [\u{00B0}C]
85 T13 : {:.2} [\u{00B0}C]
86 T14 : {:.2} [\u{00B0}C]
87 T15 : {:.2} [\u{00B0}C]
88 T16 : {:.2} [\u{00B0}C]
89 **16 Bias voltages**
90 V1 : {:.3} [V]
91 V2 : {:.3} [V]
92 V3 : {:.3} [V]
93 V4 : {:.3} [V]
94 V5 : {:.3} [V]
95 V6 : {:.3} [V]
96 V7 : {:.3} [V]
97 V8 : {:.3} [V]
98 V9 : {:.3} [V]
99 V10 : {:.3} [V]
100 V11 : {:.3} [V]
101 V12 : {:.3} [V]
102 V13 : {:.3} [V]
103 V14 : {:.3} [V]
104 V15 : {:.3} [V]
105 V16 : {:.3} [V]>",
106 self.board_id,
107 if self.temps[0] != f32::MAX {self.temps[0 ].to_string()} else {String::from("f32::MAX (ERR)")},
108 if self.temps[1] != f32::MAX {self.temps[1 ].to_string()} else {String::from("f32::MAX (ERR)")},
109 if self.temps[2] != f32::MAX {self.temps[2 ].to_string()} else {String::from("f32::MAX (ERR)")},
110 if self.temps[3] != f32::MAX {self.temps[3 ].to_string()} else {String::from("f32::MAX (ERR)")},
111 if self.temps[4] != f32::MAX {self.temps[4 ].to_string()} else {String::from("f32::MAX (ERR)")},
112 if self.temps[5] != f32::MAX {self.temps[5 ].to_string()} else {String::from("f32::MAX (ERR)")},
113 if self.temps[6] != f32::MAX {self.temps[6 ].to_string()} else {String::from("f32::MAX (ERR)")},
114 if self.temps[7] != f32::MAX {self.temps[7 ].to_string()} else {String::from("f32::MAX (ERR)")},
115 if self.temps[8] != f32::MAX {self.temps[8 ].to_string()} else {String::from("f32::MAX (ERR)")},
116 if self.temps[9] != f32::MAX {self.temps[9 ].to_string()} else {String::from("f32::MAX (ERR)")},
117 if self.temps[10] != f32::MAX {self.temps[10].to_string()} else {String::from("f32::MAX (ERR)")},
118 if self.temps[11] != f32::MAX {self.temps[11].to_string()} else {String::from("f32::MAX (ERR)")},
119 if self.temps[12] != f32::MAX {self.temps[12].to_string()} else {String::from("f32::MAX (ERR)")},
120 if self.temps[13] != f32::MAX {self.temps[13].to_string()} else {String::from("f32::MAX (ERR)")},
121 if self.temps[14] != f32::MAX {self.temps[14].to_string()} else {String::from("f32::MAX (ERR)")},
122 if self.temps[15] != f32::MAX {self.temps[15].to_string()} else {String::from("f32::MAX (ERR)")},
123 self.biases[0],
124 self.biases[1],
125 self.biases[2],
126 self.biases[3],
127 self.biases[4],
128 self.biases[5],
129 self.biases[6],
130 self.biases[7],
131 self.biases[8],
132 self.biases[9],
133 self.biases[10],
134 self.biases[11],
135 self.biases[12],
136 self.biases[13],
137 self.biases[14],
138 self.biases[15])
139 }
140}
141
142impl TofPackable for PAMoniData {
143 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::PAMoniData;
144}
145
146impl Serialization for PAMoniData {
147
148 const HEAD : u16 = 0xAAAA;
149 const TAIL : u16 = 0x5555;
150 const SIZE : usize = 4 + 1 + (4*16*2);
155
156 fn to_bytestream(&self) -> Vec<u8> {
157 let mut stream = Vec::<u8>::with_capacity(Self::SIZE);
158 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
159 stream.extend_from_slice(&self.board_id.to_le_bytes());
160 for k in 0..16 {
161 stream.extend_from_slice(&self.temps[k].to_le_bytes());
162 }
163 for k in 0..16 {
164 stream.extend_from_slice(&self.biases[k].to_le_bytes());
165 }
166 stream.extend_from_slice(&Self::TAIL.to_le_bytes());
167 stream
168 }
169
170 fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
171 -> Result<Self, SerializationError> {
172 let mut moni_data = Self::new();
173 Self::verify_fixed(stream, pos)?;
174 moni_data.board_id = parse_u8(stream, pos);
175 for k in 0..16 {
176 moni_data.temps[k] = parse_f32(stream, pos);
177 }
178 for k in 0..16 {
179 moni_data.biases[k] = parse_f32(stream, pos);
180 }
181 *pos += 2;
182 Ok(moni_data)
183 }
184}
185
186impl MoniData for PAMoniData {
187
188 fn get_board_id(&self) -> u8 {
189 return 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 keys() -> Vec<&'static str> {
201 vec!["board_id",
202 "temps1" , "temps2" , "temps3" , "temps4" ,
203 "temps5" , "temps6" , "temps7" , "temps8" ,
204 "temps9" , "temps10" , "temps11" , "temps12" ,
205 "temps13" , "temps14" , "temps15" , "temps16" ,
206 "biases1" , "biases2" , "biases3" , "biases4" ,
207 "biases5" , "biases6" , "biases7" , "biases8" ,
208 "biases9" , "biases10", "biases11", "biases12",
209 "biases13", "biases14", "biases15", "biases16",
210 "timestamp"]
211 }
212
213 fn get(&self, varname : &str) -> Option<f32> {
214 match varname {
215 "board_id" => Some(self.board_id as f32),
216 "temps1" => Some(self.temps[0] ),
217 "temps2" => Some(self.temps[1] ),
218 "temps3" => Some(self.temps[2] ),
219 "temps4" => Some(self.temps[3] ),
220 "temps5" => Some(self.temps[4] ),
221 "temps6" => Some(self.temps[5] ),
222 "temps7" => Some(self.temps[6] ),
223 "temps8" => Some(self.temps[7] ),
224 "temps9" => Some(self.temps[8] ),
225 "temps10" => Some(self.temps[9] ),
226 "temps11" => Some(self.temps[10] ),
227 "temps12" => Some(self.temps[11] ),
228 "temps13" => Some(self.temps[12] ),
229 "temps14" => Some(self.temps[13] ),
230 "temps15" => Some(self.temps[14] ),
231 "temps16" => Some(self.temps[15] ),
232 "biases1" => Some(self.biases[0] ),
233 "biases2" => Some(self.biases[1] ),
234 "biases3" => Some(self.biases[2] ),
235 "biases4" => Some(self.biases[3] ),
236 "biases5" => Some(self.biases[4] ),
237 "biases6" => Some(self.biases[5] ),
238 "biases7" => Some(self.biases[6] ),
239 "biases8" => Some(self.biases[7] ),
240 "biases9" => Some(self.biases[8] ),
241 "biases10" => Some(self.biases[9] ),
242 "biases11" => Some(self.biases[10]),
243 "biases12" => Some(self.biases[11]),
244 "biases13" => Some(self.biases[12]),
245 "biases14" => Some(self.biases[13]),
246 "biases15" => Some(self.biases[14]),
247 "biases16" => Some(self.biases[15]),
248 "timestamp" => Some(self.timestamp as f32),
249 _ => None
250 }
251 }
252}
253
254
255#[cfg(feature = "random")]
256impl FromRandom for PAMoniData {
257
258 fn from_random() -> Self {
259 let mut moni = Self::new();
260 let mut rng = rand::rng();
261 moni.board_id = rng.random::<u8>();
262 for k in 0..16 {
263 moni.temps[k] = rng.random::<f32>();
264 }
265 for k in 0..16 {
266 moni.biases[k] = rng.random::<f32>();
267 }
268 moni
269 }
270}
271
272#[cfg(feature="pybindings")]
275pythonize_packable_no_new!(PAMoniData);
276
277#[cfg(feature="pybindings")]
278pythonize_monidata!(PAMoniData);
279
280moniseries!(PAMoniDataSeries, PAMoniData);
281
282#[test]
285#[cfg(feature = "random")]
286fn pack_pamonidata() {
287 for _ in 0..100 {
288 let data = PAMoniData::from_random();
289 let test : PAMoniData = data.pack().unpack().unwrap();
290 assert_eq!(data, test);
291 }
292}
293