Skip to main content

gondola_core/monitoring/
cooling.rs

1// This file is part of gaps-online-software and published 
2// under the GPLv3 license
3
4use crate::prelude::*;
5
6// Thermal team cooling data (tracker)
7#[derive(Debug, Copy, Clone, PartialEq)]
8#[cfg_attr(feature="pybindings", pyclass)] 
9pub struct CoolingMoniData {
10  pub frame_counter   : u32, 
11  pub status_1        : u8,  
12  pub status_2        : u8,  
13  pub rx_byte_num     : u8,  
14  pub rx_cmd_num      : u8,  
15  pub last_cmd        : u64,
16  pub rsv_t           : u16, 
17  pub rh_on           : u16, 
18  pub rh_off          : u16, 
19  pub fpga_board_v_in : u16, 
20  pub fpga_board_i_in : u16, 
21  pub fpga_board_t    : u16, 
22  pub fpga_board_p    : u16, 
23  //d::array<u16, 64> : u32, rtd;
24  //pub rtd             : Vec<u16>, // 64 temperatures
25  // needs to satisfy copy trait
26  pub rtd_1           : u16,        
27  pub rtd_2           : u16,        
28  pub rtd_3           : u16,        
29  pub rtd_4           : u16,        
30  pub rtd_5           : u16,        
31  pub rtd_6           : u16,        
32  pub rtd_7           : u16,        
33  pub rtd_8           : u16,        
34  pub rtd_9           : u16,        
35  pub rtd_10          : u16,        
36  pub rtd_11          : u16,        
37  pub rtd_12          : u16,        
38  pub rtd_13          : u16,        
39  pub rtd_14          : u16,        
40  pub rtd_15          : u16,        
41  pub rtd_16          : u16,        
42  pub rtd_17          : u16,        
43  pub rtd_18          : u16,        
44  pub rtd_19          : u16,        
45  pub rtd_20          : u16,        
46  pub rtd_21          : u16,        
47  pub rtd_22          : u16,        
48  pub rtd_23          : u16,        
49  pub rtd_24          : u16,        
50  pub rtd_25          : u16,        
51  pub rtd_26          : u16,        
52  pub rtd_27          : u16,        
53  pub rtd_28          : u16,        
54  pub rtd_29          : u16,        
55  pub rtd_30          : u16,        
56  pub rtd_31          : u16,        
57  pub rtd_32          : u16,        
58  pub rtd_33          : u16,        
59  pub rtd_34          : u16,        
60  pub rtd_35          : u16,        
61  pub rtd_36          : u16,        
62  pub rtd_37          : u16,        
63  pub rtd_38          : u16,        
64  pub rtd_39          : u16, 
65  pub rtd_40          : u16,
66  pub rtd_41          : u16,
67  pub rtd_42          : u16,
68  pub rtd_43          : u16,
69  pub rtd_44          : u16,
70  pub rtd_45          : u16,
71  pub rtd_46          : u16,
72  pub rtd_47          : u16,
73  pub rtd_48          : u16,
74  pub rtd_49          : u16,
75  pub rtd_50          : u16,
76  pub rtd_51          : u16,
77  pub rtd_52          : u16,
78  pub rtd_53          : u16,
79  pub rtd_54          : u16,
80  pub rtd_55          : u16,
81  pub rtd_56          : u16,
82  pub rtd_57          : u16,
83  pub rtd_58          : u16,
84  pub rtd_59          : u16,
85  pub rtd_60          : u16,
86  pub rtd_61          : u16,
87  pub rtd_62          : u16,
88  pub rtd_63          : u16,
89  pub rtd_64          : u16,        
90  pub sh_current      : u16, 
91  pub rh_current      : u16, 
92  pub pw_board1_t     : u16, 
93  pub pw_board2_t     : u16, 
94  pub sh1_time_left   : u16, 
95  pub sh2_time_left   : u16, 
96  pub sh3_time_left   : u16, 
97  
98  // to make it a moni data
99  pub timestamp       : u64,
100}
101
102impl CoolingMoniData {
103  pub fn new() -> Self {
104    Self {
105      frame_counter   : u32::MAX, 
106      status_1        : u8::MAX,  
107      status_2        : u8::MAX,  
108      rx_byte_num     : u8::MAX,  
109      rx_cmd_num      : u8::MAX,  
110      last_cmd        : u64::MAX,
111      rsv_t           : u16::MAX, 
112      rh_on           : u16::MAX, 
113      rh_off          : u16::MAX, 
114      fpga_board_v_in : u16::MAX, 
115      fpga_board_i_in : u16::MAX, 
116      fpga_board_t    : u16::MAX, 
117      fpga_board_p    : u16::MAX, 
118      // we can't use a vector eree because we 
119      // need to obey te Copy trait
120      rtd_1           : u16::MAX,        
121      rtd_2           : u16::MAX,        
122      rtd_3           : u16::MAX,        
123      rtd_4           : u16::MAX,        
124      rtd_5           : u16::MAX,        
125      rtd_6           : u16::MAX,        
126      rtd_7           : u16::MAX,        
127      rtd_8           : u16::MAX,        
128      rtd_9           : u16::MAX,        
129      rtd_10          : u16::MAX,        
130      rtd_11          : u16::MAX,        
131      rtd_12          : u16::MAX,        
132      rtd_13          : u16::MAX,        
133      rtd_14          : u16::MAX,        
134      rtd_15          : u16::MAX,        
135      rtd_16          : u16::MAX,        
136      rtd_17          : u16::MAX,        
137      rtd_18          : u16::MAX,        
138      rtd_19          : u16::MAX,        
139      rtd_20          : u16::MAX,        
140      rtd_21          : u16::MAX,        
141      rtd_22          : u16::MAX,        
142      rtd_23          : u16::MAX,        
143      rtd_24          : u16::MAX,        
144      rtd_25          : u16::MAX,        
145      rtd_26          : u16::MAX,        
146      rtd_27          : u16::MAX,        
147      rtd_28          : u16::MAX,        
148      rtd_29          : u16::MAX,        
149      rtd_30          : u16::MAX,        
150      rtd_31          : u16::MAX,        
151      rtd_32          : u16::MAX,        
152      rtd_33          : u16::MAX,        
153      rtd_34          : u16::MAX,        
154      rtd_35          : u16::MAX,        
155      rtd_36          : u16::MAX,        
156      rtd_37          : u16::MAX,        
157      rtd_38          : u16::MAX,        
158      rtd_39          : u16::MAX, 
159      rtd_40          : u16::MAX,
160      rtd_41          : u16::MAX,
161      rtd_42          : u16::MAX,
162      rtd_43          : u16::MAX,
163      rtd_44          : u16::MAX,
164      rtd_45          : u16::MAX,
165      rtd_46          : u16::MAX,
166      rtd_47          : u16::MAX,
167      rtd_48          : u16::MAX,
168      rtd_49          : u16::MAX,
169      rtd_50          : u16::MAX,
170      rtd_51          : u16::MAX,
171      rtd_52          : u16::MAX,
172      rtd_53          : u16::MAX,
173      rtd_54          : u16::MAX,
174      rtd_55          : u16::MAX,
175      rtd_56          : u16::MAX,
176      rtd_57          : u16::MAX,
177      rtd_58          : u16::MAX,
178      rtd_59          : u16::MAX,
179      rtd_60          : u16::MAX,
180      rtd_61          : u16::MAX,
181      rtd_62          : u16::MAX,
182      rtd_63          : u16::MAX,
183      rtd_64          : u16::MAX,        
184      sh_current      : u16::MAX, 
185      rh_current      : u16::MAX, 
186      pw_board1_t     : u16::MAX, 
187      pw_board2_t     : u16::MAX, 
188      sh1_time_left   : u16::MAX, 
189      sh2_time_left   : u16::MAX, 
190      sh3_time_left   : u16::MAX,
191      timestamp       : u64::MAX
192    }
193  }
194
195  /// Transformation of saved u16 values for rtd to 
196  /// Temperature in C
197  #[allow(non_snake_case)]
198  fn rtd_temp(adc : u16) -> f32 { 
199    // Keita :) 
200    //  u, d, w, G, A, B = 3.3, 1, 1.25, 21.58, 3.9083e-3, -5.775e-7  # constants
201    //I = x  # if isinstance(x, int) else int.from_bytes(x, byteorder='little', signed=False)
202    //# I = I if I <= 2047 else I - 4096
203    //I = np.where(I <= 2047, I, I - 4096)
204    //V = I * 10 / 4096 
205    //R = u * (w * d + V * (u + d) / G) / (w * u - V * (u + d) / G) 
206    //T = (-A + (A**2 - 4 * B * (1 - R)) ** 0.5) / (2 * B) 
207    //return T  # degree C
208    let mut adc_signed = adc as f32;
209    let u : f32 = 3.3;
210    let d : f32 = 1.0; 
211    let w : f32 = 1.25;
212    let G : f32 = 21.58;
213    let A : f32 = 3.9083e-3; 
214    let B : f32 = -5.775e-7;
215    // unsigned -> signed conversion
216    if adc > 2047 { 
217      adc_signed -= 4086.0;  
218    } 
219    let V = adc_signed * 10.0 / 4096.0; 
220    let R = u * (w * d + V * (u + d) / G) / (w * u - V * (u + d) / G); 
221    let T : f32 = (-A + (A.powf(2.0) - 4.0 * B * (1.0 - R)).powf(0.5)) / (2.0 * B); 
222    return T;
223  }
224
225  // not entirely sure how to map this yet - FIXME
226  //fn current(x : u16) -> f32 {
227  //  return (5.0 * x as f32 / 4096.0 - 1.25) * 0.1650 / 4.1 / 0.02 
228  //}
229
230  //// power board 2 
231  //fn current2(x : u16) -> f32 { 
232  //  (5.0 * x as f32 / 4096.0 - 1.25) * 0.2050 / 4.1 / 0.05
233  //}
234  //
235  //fn board_temp(x : u16) -> f32 {
236  //  (5.0 * x as f32 / 4096.0) * 100.0 - 273.2
237  //}
238  //
239  //fn fpga_v(x : u16) -> f32 {
240  //  40.0 * x as f32 / 4096.0
241  //}
242  //
243  //fn fpga_i(x : u16) -> f32 {
244  //  3.0 * x as f32 / 4096.0
245  //}
246  //
247  //fn cooling_fpga_p(x : u16) -> f32 {
248  //  (5.0 * x as f32 / 4096.0) * 22.878 - 5.253
249  //}
250}
251
252impl Serialization for CoolingMoniData { 
253  
254  const SIZE : usize  = 105;
255
256  fn from_bytestream(stream : &Vec<u8>,
257                     pos    : &mut usize)
258    -> Result<Self, SerializationError> {
259    let mut cln = Self::new();
260    if stream.len() - *pos < Self::SIZE {
261      return Err(SerializationError::StreamTooShort);
262    }
263    let start_byte = parse_u8(stream, pos);
264    if start_byte != 0x1e {
265      error!("Start byte is {} and not 0x1e!", start_byte);
266      return Err(SerializationError::InvalidByte);
267    } 
268    //cln.rtd.fill(0xffff);
269    cln.frame_counter   = 0xffffff & parse_u32(stream, pos);
270    *pos -= 1;
271    cln.status_1        = parse_u8(stream, pos);  
272    cln.status_2        = parse_u8(stream, pos);  
273    cln.rx_byte_num     = parse_u8(stream, pos);  
274    cln.rx_cmd_num      = parse_u8(stream, pos);  
275    cln.last_cmd        = 0xffffffffffffff & parse_u64(stream, pos); 
276    *pos -= 1;
277    cln.rsv_t           = parse_u16(stream, pos);
278    cln.rh_on           = parse_u16(stream, pos);
279    cln.rh_off          = parse_u16(stream, pos);
280    cln.fpga_board_v_in = parse_u16(stream, pos);
281    cln.fpga_board_i_in = parse_u16(stream, pos);
282    *pos += 2;
283    cln.fpga_board_t    = parse_u16(stream, pos);
284    cln.fpga_board_p    = parse_u16(stream, pos);
285    *pos += 6;
286    cln.rtd_1           = parse_u16(stream, pos);        
287    cln.rtd_2           = parse_u16(stream, pos);        
288    cln.rtd_3           = parse_u16(stream, pos);        
289    cln.rtd_4           = parse_u16(stream, pos);        
290    cln.rtd_5           = parse_u16(stream, pos);        
291    cln.rtd_6           = parse_u16(stream, pos);        
292    cln.rtd_7           = parse_u16(stream, pos);        
293    cln.rtd_8           = parse_u16(stream, pos);        
294    cln.rtd_9           = parse_u16(stream, pos);        
295    cln.rtd_10          = parse_u16(stream, pos);        
296    cln.rtd_11          = parse_u16(stream, pos);        
297    cln.rtd_12          = parse_u16(stream, pos);        
298    cln.rtd_13          = parse_u16(stream, pos);        
299    cln.rtd_14          = parse_u16(stream, pos);        
300    cln.rtd_15          = parse_u16(stream, pos);        
301    cln.rtd_16          = parse_u16(stream, pos);        
302    cln.rtd_17          = parse_u16(stream, pos);        
303    cln.rtd_18          = parse_u16(stream, pos);        
304    cln.rtd_19          = parse_u16(stream, pos);        
305    cln.rtd_20          = parse_u16(stream, pos);        
306    cln.rtd_21          = parse_u16(stream, pos);        
307    cln.rtd_22          = parse_u16(stream, pos);        
308    cln.rtd_23          = parse_u16(stream, pos);        
309    cln.rtd_24          = parse_u16(stream, pos);        
310    cln.rtd_25          = parse_u16(stream, pos);        
311    cln.rtd_26          = parse_u16(stream, pos);        
312    cln.rtd_27          = parse_u16(stream, pos);        
313    cln.rtd_28          = parse_u16(stream, pos);        
314    cln.rtd_29          = parse_u16(stream, pos);        
315    cln.rtd_30          = parse_u16(stream, pos);        
316    cln.rtd_31          = parse_u16(stream, pos);        
317    cln.rtd_32          = parse_u16(stream, pos);        
318    cln.rtd_33          = parse_u16(stream, pos);        
319    cln.rtd_34          = parse_u16(stream, pos);        
320    cln.rtd_35          = parse_u16(stream, pos);        
321    cln.rtd_36          = parse_u16(stream, pos);        
322    cln.rtd_37          = parse_u16(stream, pos);        
323    cln.rtd_38          = parse_u16(stream, pos);        
324    cln.rtd_39          = parse_u16(stream, pos); 
325    cln.rtd_40          = parse_u16(stream, pos);
326    cln.rtd_41          = parse_u16(stream, pos);
327    cln.rtd_42          = parse_u16(stream, pos);
328    cln.rtd_43          = parse_u16(stream, pos);
329    cln.rtd_44          = parse_u16(stream, pos);
330    cln.rtd_45          = parse_u16(stream, pos);
331    cln.rtd_46          = parse_u16(stream, pos);
332    cln.rtd_47          = parse_u16(stream, pos);
333    cln.rtd_48          = parse_u16(stream, pos);
334    cln.rtd_49          = parse_u16(stream, pos);
335    cln.rtd_50          = parse_u16(stream, pos);
336    cln.rtd_51          = parse_u16(stream, pos);
337    cln.rtd_52          = parse_u16(stream, pos);
338    cln.rtd_53          = parse_u16(stream, pos);
339    cln.rtd_54          = parse_u16(stream, pos);
340    cln.rtd_55          = parse_u16(stream, pos);
341    cln.rtd_56          = parse_u16(stream, pos);
342    cln.rtd_57          = parse_u16(stream, pos);
343    cln.rtd_58          = parse_u16(stream, pos);
344    cln.rtd_59          = parse_u16(stream, pos);
345    cln.rtd_60          = parse_u16(stream, pos);
346    cln.rtd_61          = parse_u16(stream, pos);
347    cln.rtd_62          = parse_u16(stream, pos);
348    cln.rtd_63          = parse_u16(stream, pos);
349    cln.rtd_64          = parse_u16(stream, pos);        
350    cln.sh_current    = parse_u16(stream, pos);
351    cln.rh_current    = parse_u16(stream, pos);
352    cln.pw_board1_t   = parse_u16(stream, pos);
353    cln.pw_board2_t   = parse_u16(stream, pos);
354    cln.sh1_time_left = parse_u16(stream, pos);
355    cln.sh2_time_left = parse_u16(stream, pos);
356    cln.sh3_time_left = parse_u16(stream, pos);
357    *pos += 2; //spare
358    //auto stop_byte = parse_u8(stream,pos);
359    //if (stop_byte != 0x0a) {
360    //  std::string message = std::format("Stop byte for cooling packet incorrect! Got {} instead of 0x0a", stop_byte);
361    //  auto err = g::IOError(g::IOError::ErrorKind::WrongDelimiter, message);
362    //  return Err(err);
363    //} 
364    //return Ok(cln);
365    Ok(cln)
366  }
367}
368
369
370impl FromRandom for CoolingMoniData {
371    
372  fn from_random() -> Self {
373    let mut moni         = Self::new();
374    let mut rng          = rand::rng();
375    moni.frame_counter   = rng.random::<u32>();
376    moni.status_1        = rng.random::<u8>(); 
377    moni.status_2        = rng.random::<u8>(); 
378    moni.rx_byte_num     = rng.random::<u8>(); 
379    moni.rx_cmd_num      = rng.random::<u8>(); 
380    moni.last_cmd        = rng.random::<u64>();
381    moni.rsv_t           = rng.random::<u16>(); 
382    moni.rh_on           = rng.random::<u16>(); 
383    moni.rh_off          = rng.random::<u16>(); 
384    moni.fpga_board_v_in = rng.random::<u16>(); 
385    moni.fpga_board_i_in = rng.random::<u16>(); 
386    moni.fpga_board_t    = rng.random::<u16>(); 
387    moni.fpga_board_p    = rng.random::<u16>(); 
388    moni.rtd_1           = rng.random::<u16>();        
389    moni.rtd_2           = rng.random::<u16>();        
390    moni.rtd_3           = rng.random::<u16>();        
391    moni.rtd_4           = rng.random::<u16>();        
392    moni.rtd_5           = rng.random::<u16>();        
393    moni.rtd_6           = rng.random::<u16>();        
394    moni.rtd_7           = rng.random::<u16>();        
395    moni.rtd_8           = rng.random::<u16>();        
396    moni.rtd_9           = rng.random::<u16>();        
397    moni.rtd_10          = rng.random::<u16>();        
398    moni.rtd_11          = rng.random::<u16>();        
399    moni.rtd_12          = rng.random::<u16>();        
400    moni.rtd_13          = rng.random::<u16>();        
401    moni.rtd_14          = rng.random::<u16>();        
402    moni.rtd_15          = rng.random::<u16>();        
403    moni.rtd_16          = rng.random::<u16>();        
404    moni.rtd_17          = rng.random::<u16>();        
405    moni.rtd_18          = rng.random::<u16>();        
406    moni.rtd_19          = rng.random::<u16>();        
407    moni.rtd_20          = rng.random::<u16>();        
408    moni.rtd_21          = rng.random::<u16>();        
409    moni.rtd_22          = rng.random::<u16>();        
410    moni.rtd_23          = rng.random::<u16>();        
411    moni.rtd_24          = rng.random::<u16>();        
412    moni.rtd_25          = rng.random::<u16>();        
413    moni.rtd_26          = rng.random::<u16>();        
414    moni.rtd_27          = rng.random::<u16>();        
415    moni.rtd_28          = rng.random::<u16>();        
416    moni.rtd_29          = rng.random::<u16>();        
417    moni.rtd_30          = rng.random::<u16>();        
418    moni.rtd_31          = rng.random::<u16>();        
419    moni.rtd_32          = rng.random::<u16>();        
420    moni.rtd_33          = rng.random::<u16>();        
421    moni.rtd_34          = rng.random::<u16>();        
422    moni.rtd_35          = rng.random::<u16>();        
423    moni.rtd_36          = rng.random::<u16>();        
424    moni.rtd_37          = rng.random::<u16>();        
425    moni.rtd_38          = rng.random::<u16>();        
426    moni.rtd_39          = rng.random::<u16>(); 
427    moni.rtd_40          = rng.random::<u16>();
428    moni.rtd_41          = rng.random::<u16>();
429    moni.rtd_42          = rng.random::<u16>();
430    moni.rtd_43          = rng.random::<u16>();
431    moni.rtd_44          = rng.random::<u16>();
432    moni.rtd_45          = rng.random::<u16>();
433    moni.rtd_46          = rng.random::<u16>();
434    moni.rtd_47          = rng.random::<u16>();
435    moni.rtd_48          = rng.random::<u16>();
436    moni.rtd_49          = rng.random::<u16>();
437    moni.rtd_50          = rng.random::<u16>();
438    moni.rtd_51          = rng.random::<u16>();
439    moni.rtd_52          = rng.random::<u16>();
440    moni.rtd_53          = rng.random::<u16>();
441    moni.rtd_54          = rng.random::<u16>();
442    moni.rtd_55          = rng.random::<u16>();
443    moni.rtd_56          = rng.random::<u16>();
444    moni.rtd_57          = rng.random::<u16>();
445    moni.rtd_58          = rng.random::<u16>();
446    moni.rtd_59          = rng.random::<u16>();
447    moni.rtd_60          = rng.random::<u16>();
448    moni.rtd_61          = rng.random::<u16>();
449    moni.rtd_62          = rng.random::<u16>();
450    moni.rtd_63          = rng.random::<u16>();
451    moni.rtd_64          = rng.random::<u16>();        
452    moni.sh_current      = rng.random::<u16>(); 
453    moni.rh_current      = rng.random::<u16>(); 
454    moni.pw_board1_t     = rng.random::<u16>(); 
455    moni.pw_board2_t     = rng.random::<u16>(); 
456    moni.sh1_time_left   = rng.random::<u16>(); 
457    moni.sh2_time_left   = rng.random::<u16>(); 
458    moni.sh3_time_left   = rng.random::<u16>(); 
459    moni
460  }
461}
462
463impl MoniData for CoolingMoniData {
464  
465  fn get_board_id(&self) -> u8 {
466    return 0;
467  }
468
469  fn get_timestamp(&self) -> u64 {
470    self.timestamp 
471  }
472
473  fn set_timestamp(&mut self, ts: u64) {
474    self.timestamp = ts;
475  }
476
477  fn keys() -> Vec<&'static str> {
478    vec!["board_id",
479         "frame_counter",   
480         "status_1",        
481         "status_2",        
482         "rx_byte_num",     
483         "rx_cmd_num",      
484         "last_cmd",        
485         "rsv_t",           
486         "rh_on",           
487         "rh_off",          
488         "fpga_board_v_in", 
489         "fpga_board_i_in", 
490         "fpga_board_t",    
491         "fpga_board_p",    
492         "rtd_1",        
493         "rtd_2",        
494         "rtd_3",        
495         "rtd_4",        
496         "rtd_5",        
497         "rtd_6",        
498         "rtd_7",        
499         "rtd_8",        
500         "rtd_9",        
501         "rtd_10",        
502         "rtd_11",        
503         "rtd_12",        
504         "rtd_13",        
505         "rtd_14",        
506         "rtd_15",        
507         "rtd_16",        
508         "rtd_17",        
509         "rtd_18",        
510         "rtd_19",        
511         "rtd_20",        
512         "rtd_21",        
513         "rtd_22",        
514         "rtd_23",        
515         "rtd_24",        
516         "rtd_25",        
517         "rtd_26",        
518         "rtd_27",        
519         "rtd_28",        
520         "rtd_29",        
521         "rtd_30",        
522         "rtd_31",        
523         "rtd_32",        
524         "rtd_33",        
525         "rtd_34",        
526         "rtd_35",        
527         "rtd_36",        
528         "rtd_37",        
529         "rtd_38",        
530         "rtd_39", 
531         "rtd_40",
532         "rtd_41",
533         "rtd_42",
534         "rtd_43",
535         "rtd_44",
536         "rtd_45",
537         "rtd_46",
538         "rtd_47",
539         "rtd_48",
540         "rtd_49",
541         "rtd_50",
542         "rtd_51",
543         "rtd_52",
544         "rtd_53",
545         "rtd_54",
546         "rtd_55",
547         "rtd_56",
548         "rtd_57",
549         "rtd_58",
550         "rtd_59",
551         "rtd_60",
552         "rtd_61",
553         "rtd_62",
554         "rtd_63",
555         "rtd_64",        
556         "sh_current",      
557         "rh_current",      
558         "pw_board1_t",     
559         "pw_board2_t",     
560         "sh1_time_left",   
561         "sh2_time_left",   
562         "sh3_time_left",   
563         "timestamp"]
564  }
565
566  fn get(&self, varname : &str) -> Option<f32> {
567    match varname {
568      "board_id"        => Some(0.0),
569      "frame_counter"   => Some(self.frame_counter   as f32),   
570      "status_1"        => Some(self.status_1        as f32),        
571      "status_2"        => Some(self.status_2        as f32),        
572      "rx_byte_num"     => Some(self.rx_byte_num     as f32),     
573      "rx_cmd_num"      => Some(self.rx_cmd_num      as f32),      
574      "last_cmd"        => Some(self.last_cmd        as f32),        
575      "rsv_t"           => Some(self.rsv_t           as f32),           
576      "rh_on"           => Some(self.rh_on           as f32),           
577      "rh_off"          => Some(self.rh_off          as f32),          
578      "fpga_board_v_in" => Some(self.fpga_board_v_in as f32), 
579      "fpga_board_i_in" => Some(self.fpga_board_i_in as f32), 
580      "fpga_board_t"    => Some(self.fpga_board_t   as f32),    
581      "fpga_board_p"    => Some(self.fpga_board_p   as f32),    
582      "rtd_1"           => Some(Self::rtd_temp(self.rtd_1 )),         
583      "rtd_2"           => Some(Self::rtd_temp(self.rtd_2 )),        
584      "rtd_3"           => Some(Self::rtd_temp(self.rtd_3 )),        
585      "rtd_4"           => Some(Self::rtd_temp(self.rtd_4 )),        
586      "rtd_5"           => Some(Self::rtd_temp(self.rtd_5 )),        
587      "rtd_6"           => Some(Self::rtd_temp(self.rtd_6 )),        
588      "rtd_7"           => Some(Self::rtd_temp(self.rtd_7 )),        
589      "rtd_8"           => Some(Self::rtd_temp(self.rtd_8 )),        
590      "rtd_9"           => Some(Self::rtd_temp(self.rtd_9 )),        
591      "rtd_10"          => Some(Self::rtd_temp(self.rtd_10)),        
592      "rtd_11"          => Some(Self::rtd_temp(self.rtd_11)),        
593      "rtd_12"          => Some(Self::rtd_temp(self.rtd_12)),        
594      "rtd_13"          => Some(Self::rtd_temp(self.rtd_13)),        
595      "rtd_14"          => Some(Self::rtd_temp(self.rtd_14)),        
596      "rtd_15"          => Some(Self::rtd_temp(self.rtd_15)),        
597      "rtd_16"          => Some(Self::rtd_temp(self.rtd_16)),        
598      "rtd_17"          => Some(Self::rtd_temp(self.rtd_17)),        
599      "rtd_18"          => Some(Self::rtd_temp(self.rtd_18)),        
600      "rtd_19"          => Some(Self::rtd_temp(self.rtd_19)),        
601      "rtd_20"          => Some(Self::rtd_temp(self.rtd_20)),        
602      "rtd_21"          => Some(Self::rtd_temp(self.rtd_21)),        
603      "rtd_22"          => Some(Self::rtd_temp(self.rtd_22)),        
604      "rtd_23"          => Some(Self::rtd_temp(self.rtd_23)),        
605      "rtd_24"          => Some(Self::rtd_temp(self.rtd_24)),        
606      "rtd_25"          => Some(Self::rtd_temp(self.rtd_25)),        
607      "rtd_26"          => Some(Self::rtd_temp(self.rtd_26)),        
608      "rtd_27"          => Some(Self::rtd_temp(self.rtd_27)),        
609      "rtd_28"          => Some(Self::rtd_temp(self.rtd_28)),        
610      "rtd_29"          => Some(Self::rtd_temp(self.rtd_29)),        
611      "rtd_30"          => Some(Self::rtd_temp(self.rtd_30)),        
612      "rtd_31"          => Some(Self::rtd_temp(self.rtd_31)),        
613      "rtd_32"          => Some(Self::rtd_temp(self.rtd_32)),        
614      "rtd_33"          => Some(Self::rtd_temp(self.rtd_33)),        
615      "rtd_34"          => Some(Self::rtd_temp(self.rtd_34)),        
616      "rtd_35"          => Some(Self::rtd_temp(self.rtd_35)),        
617      "rtd_36"          => Some(Self::rtd_temp(self.rtd_36)),        
618      "rtd_37"          => Some(Self::rtd_temp(self.rtd_37)),        
619      "rtd_38"          => Some(Self::rtd_temp(self.rtd_38)),        
620      "rtd_39"          => Some(Self::rtd_temp(self.rtd_39)), 
621      "rtd_40"          => Some(Self::rtd_temp(self.rtd_40)),
622      "rtd_41"          => Some(Self::rtd_temp(self.rtd_41)),
623      "rtd_42"          => Some(Self::rtd_temp(self.rtd_42)),
624      "rtd_43"          => Some(Self::rtd_temp(self.rtd_43)),
625      "rtd_44"          => Some(Self::rtd_temp(self.rtd_44)),
626      "rtd_45"          => Some(Self::rtd_temp(self.rtd_45)),
627      "rtd_46"          => Some(Self::rtd_temp(self.rtd_46)),
628      "rtd_47"          => Some(Self::rtd_temp(self.rtd_47)),
629      "rtd_48"          => Some(Self::rtd_temp(self.rtd_48)),
630      "rtd_49"          => Some(Self::rtd_temp(self.rtd_49)),
631      "rtd_50"          => Some(Self::rtd_temp(self.rtd_50)),
632      "rtd_51"          => Some(Self::rtd_temp(self.rtd_51)),
633      "rtd_52"          => Some(Self::rtd_temp(self.rtd_52)),
634      "rtd_53"          => Some(Self::rtd_temp(self.rtd_53)),
635      "rtd_54"          => Some(Self::rtd_temp(self.rtd_54)),
636      "rtd_55"          => Some(Self::rtd_temp(self.rtd_55)),
637      "rtd_56"          => Some(Self::rtd_temp(self.rtd_56)),
638      "rtd_57"          => Some(Self::rtd_temp(self.rtd_57)),
639      "rtd_58"          => Some(Self::rtd_temp(self.rtd_58)),
640      "rtd_59"          => Some(Self::rtd_temp(self.rtd_59)),
641      "rtd_60"          => Some(Self::rtd_temp(self.rtd_60)),
642      "rtd_61"          => Some(Self::rtd_temp(self.rtd_61)),
643      "rtd_62"          => Some(Self::rtd_temp(self.rtd_62)),
644      "rtd_63"          => Some(Self::rtd_temp(self.rtd_63)),
645      "rtd_64"          => Some(Self::rtd_temp(self.rtd_64)),        
646      "sh_current"      => Some(self.sh_current     as f32),      
647      "rh_current"      => Some(self.rh_current     as f32),      
648      "pw_board1_t"     => Some(self.pw_board1_t    as f32),     
649      "pw_board2_t"     => Some(self.pw_board2_t    as f32),     
650      "sh1_time_left"   => Some(self.sh1_time_left  as f32),   
651      "sh2_time_left"   => Some(self.sh2_time_left  as f32),   
652      "sh3_time_left"   => Some(self.sh3_time_left  as f32),   
653      "timestamp" => Some(self.timestamp as f32),
654      _           => None
655    }
656  }  
657}
658
659impl TelemetryPackable for CoolingMoniData {
660  const TEL_PACKET_TYPE : TelemetryPacketType = TelemetryPacketType::CoolingHK;
661}
662
663moniseries_telemetry!(CoolingMoniDataSeries, CoolingMoniData);
664
665#[cfg(feature="pybindings")]
666pythonize_monidata!(CoolingMoniData);
667