gondola_core/monitoring/
cpu_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::cpu_type::{
8  CPUInfoDebug,
9  CPUTempDebug
10};
11
12#[derive(Debug, Copy, Clone, PartialEq)]
13#[cfg_attr(feature="pybindings", pyclass)]
14pub struct CPUMoniData {
15  pub uptime     : u32,
16  pub disk_usage : u8,
17  pub cpu_freq   : [u32; 4],
18  pub cpu_temp   : f32,
19  pub cpu0_temp  : f32,
20  pub cpu1_temp  : f32,
21  pub mb_temp    : f32,
22  // will not get serialized 
23  pub timestamp  : u64,
24}
25
26impl CPUMoniData {
27  pub fn new() -> Self {
28    Self {
29      uptime     : u32::MAX,
30      disk_usage : u8::MAX,
31      cpu_freq   : [u32::MAX; 4],
32      cpu_temp   : f32::MAX,
33      cpu0_temp  : f32::MAX,
34      cpu1_temp  : f32::MAX,
35      mb_temp    : f32::MAX,
36      timestamp  : 0,
37    }
38  }
39
40  pub fn get_temps(&self) -> Vec<f32> {
41    vec![self.cpu0_temp, self.cpu1_temp, self.cpu_temp, self.mb_temp]
42  }
43
44  #[cfg(feature = "tofcontrol")]
45  pub fn add_temps(&mut self, cpu_temps : &CPUTempDebug) {
46    self.cpu_temp   = cpu_temps.cpu_temp;
47    self.cpu0_temp  = cpu_temps.cpu0_temp;
48    self.cpu1_temp  = cpu_temps.cpu1_temp;
49    self.mb_temp    = cpu_temps.mb_temp;
50  }
51
52  #[cfg(feature = "tofcontrol")]
53  pub fn add_info(&mut self, cpu_info : &CPUInfoDebug) {
54    self.uptime = cpu_info.uptime;
55    self.disk_usage = cpu_info.disk_usage;
56    self.cpu_freq   = cpu_info.cpu_freq;
57  }
58}
59
60impl Default for CPUMoniData {
61  fn default() -> Self {
62    Self::new()
63  }
64}
65
66impl fmt::Display for CPUMoniData {
67  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68    write!(f, "<CPUMoniData:
69  core0   temp [\u{00B0}C] : {:.2} 
70  core1   temp [\u{00B0}C] : {:.2} 
71  CPU     temp [\u{00B0}C] : {:.2} 
72  MB      temp [\u{00B0}C] : {:.2} 
73  CPU (4) freq [Hz] : {} | {} | {} | {} 
74  Disc usage   [%]  : {} 
75  Uptime       [s]  : {}>",
76           self.cpu0_temp,
77           self.cpu1_temp,
78           self.cpu_temp,
79           self.mb_temp,
80           self.cpu_freq[0],
81           self.cpu_freq[1],
82           self.cpu_freq[2],
83           self.cpu_freq[3],
84           self.disk_usage,
85           self.uptime)
86  }
87}
88
89impl TofPackable for CPUMoniData {
90  const TOF_PACKET_TYPE : TofPacketType = TofPacketType::CPUMoniData;
91}
92
93impl Serialization for CPUMoniData {
94  
95  const SIZE : usize = 41;
96  const HEAD : u16   = 0xAAAA;
97  const TAIL : u16   = 0x5555;
98
99  fn to_bytestream(&self) -> Vec<u8> {
100    let mut stream = Vec::<u8>::with_capacity(Self::SIZE);
101    stream.extend_from_slice(&Self::HEAD.to_le_bytes());
102    stream.extend_from_slice(&self.uptime  .to_le_bytes());
103    stream.extend_from_slice(&self.disk_usage  .to_le_bytes());
104    for k in 0..4 {
105      stream.extend_from_slice(&self.cpu_freq[k].to_le_bytes());
106    }
107    stream.extend_from_slice(&self.cpu_temp .to_le_bytes());
108    stream.extend_from_slice(&self.cpu0_temp.to_le_bytes());
109    stream.extend_from_slice(&self.cpu1_temp.to_le_bytes());
110    stream.extend_from_slice(&self.mb_temp  .to_le_bytes());
111    stream.extend_from_slice(&Self::TAIL.to_le_bytes());
112    stream
113  }
114
115  fn from_bytestream(stream : &Vec<u8>, pos : &mut usize)
116    -> Result<Self, SerializationError> {
117    Self::verify_fixed(stream, pos)?;
118    let mut moni = CPUMoniData::new();
119    moni.uptime     = parse_u32(stream, pos); 
120    moni.disk_usage = parse_u8(stream, pos); 
121    for k in 0..4 {
122      moni.cpu_freq[k] = parse_u32(stream, pos);
123    }
124    moni.cpu_temp   = parse_f32(stream, pos);
125    moni.cpu0_temp  = parse_f32(stream, pos);
126    moni.cpu1_temp  = parse_f32(stream, pos);
127    moni.mb_temp    = parse_f32(stream, pos);
128    *pos += 2;
129    Ok(moni)
130  }
131}
132
133impl MoniData for CPUMoniData {
134
135  fn get_board_id(&self) -> u8 {
136    return 0;
137  }
138 
139  fn get_timestamp(&self) -> u64 { 
140    return self.timestamp
141  }
142
143  fn set_timestamp(&mut self, ts : u64) {
144    self.timestamp = ts;
145  }
146
147  fn get(&self, varname : &str) -> Option<f32> {
148    match varname {
149      "uptime"     =>    Some(self.uptime as f32),
150      "disk_usage" =>    Some(self.disk_usage as f32),
151      "cpu_freq0"  =>    Some(self.cpu_freq[0] as f32),
152      "cpu_freq1"  =>    Some(self.cpu_freq[1] as f32),
153      "cpu_freq2"  =>    Some(self.cpu_freq[2] as f32),
154      "cpu_freq3"  =>    Some(self.cpu_freq[0] as f32),
155      "cpu_temp"   =>    Some(self.cpu_temp),
156      "cpu0_temp"  =>    Some(self.cpu0_temp),
157      "cpu1_temp"  =>    Some(self.cpu1_temp),
158      "mb_temp"    =>    Some(self.mb_temp),
159      "timestamp"  =>    Some(self.timestamp as f32),
160      _            =>    None
161    }
162  }
163  
164  fn keys() -> Vec<&'static str> {
165    vec![
166      "uptime"     ,
167      "disk_usage" ,
168      "cpu_freq0"  ,
169      "cpu_freq1"  ,
170      "cpu_freq2"  ,
171      "cpu_freq3"  ,
172      "cpu_temp"   ,
173      "cpu0_temp"  ,
174      "cpu1_temp"  ,
175      "mb_temp"    ,
176      "timestamp"]
177  }
178}
179
180#[cfg(feature = "random")]
181impl FromRandom for CPUMoniData {
182    
183  fn from_random() -> Self {
184    let mut moni    = Self::new();
185    let mut rng     = rand::rng();
186    moni.uptime     = rng.random::<u32>();
187    moni.disk_usage = rng.random::<u8>();
188    for k in 0..4 {
189      moni.cpu_freq[k] = rng.random::<u32>();
190    }
191    moni.cpu_temp   = rng.random::<f32>();
192    moni.cpu0_temp  = rng.random::<f32>();
193    moni.cpu1_temp  = rng.random::<f32>();
194    moni.mb_temp    = rng.random::<f32>();
195    moni
196  }
197}
198
199#[cfg(feature="pybindings")]
200#[pymethods]
201impl CPUMoniData {
202
203  #[getter]
204  fn get_uptime(&self) -> u32 {
205    self.uptime
206  }
207
208  #[getter]
209  fn get_disk_usage(&self) -> u8 {
210    self.disk_usage
211  }
212
213  #[getter]
214  fn get_cpu_freq(&self) -> [u32; 4] {
215    self.cpu_freq
216  }
217
218  #[getter]
219  fn get_cpu_temp(&self) -> f32 {
220    self.cpu_temp
221  }
222
223  #[getter]
224  fn get_cpu0_temp(&self) -> f32 {
225    self.cpu0_temp
226  }
227
228  #[getter]
229  fn get_cpu1_temp(&self) -> f32 {
230    self.cpu1_temp
231  }
232
233  #[getter]
234  fn get_mb_temp(&self) -> f32 {
235    self.mb_temp
236  }  
237 
238  #[getter]
239  fn get_timestamp_py(&self) -> u64 {
240    self.timestamp
241  }
242}
243
244//----------------------------------------
245
246// make it available as a monidata series
247moniseries!(CPUMoniDataSeries, CPUMoniData);
248
249#[cfg(feature="pybindings")]
250pythonize_packable!(CPUMoniData);
251
252#[cfg(feature="pybindings")]
253pythonize_monidata!(CPUMoniData);
254
255//----------------------------------------
256
257#[test]
258#[cfg(feature = "random")]
259fn monidata_cpumonidata() {
260  let data = CPUMoniData::from_random();
261  for k in CPUMoniData::keys() {
262    assert!(data.get(k).is_some());
263  }
264  assert_eq!(data.get_board_id(), 0u8);
265}
266