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