Re-added timing, refactored.
This commit is contained in:
parent
9740fe2298
commit
ac26ac7f5a
|
@ -0,0 +1,6 @@
|
||||||
|
use tui::{
|
||||||
|
layout::{Constraint, Direction, Layout},
|
||||||
|
style::{Color, Style},
|
||||||
|
widgets::{Axis, Block, Borders, Chart, Dataset, Marker, Row, Table, Widget},
|
||||||
|
Terminal,
|
||||||
|
};
|
54
src/main.rs
54
src/main.rs
|
@ -16,7 +16,7 @@ extern crate log;
|
||||||
|
|
||||||
enum Event<I> {
|
enum Event<I> {
|
||||||
Input(I),
|
Input(I),
|
||||||
Update(widgets::Data),
|
Update(Box<widgets::Data>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -58,8 +58,8 @@ async fn main() -> Result<(), io::Error> {
|
||||||
let tx = tx.clone();
|
let tx = tx.clone();
|
||||||
loop {
|
loop {
|
||||||
futures::executor::block_on(data_state.update_data()); // TODO: Fix
|
futures::executor::block_on(data_state.update_data()); // TODO: Fix
|
||||||
tx.send(Event::Update(data_state.data.clone())).unwrap();
|
tx.send(Event::Update(Box::from(data_state.data.clone()))).unwrap();
|
||||||
thread::sleep(Duration::from_millis(update_rate_in_milliseconds - 1000));
|
thread::sleep(Duration::from_millis(update_rate_in_milliseconds));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ async fn main() -> Result<(), io::Error> {
|
||||||
}
|
}
|
||||||
Event::Update(data) => {
|
Event::Update(data) => {
|
||||||
try_debug(&log, "Update event fired!");
|
try_debug(&log, "Update event fired!");
|
||||||
app_data = data;
|
app_data = *data;
|
||||||
widgets::processes::sort_processes(&mut app_data.list_of_processes, &app.process_sorting_type, app.process_sorting_reverse);
|
widgets::processes::sort_processes(&mut app_data.list_of_processes, &app.process_sorting_type, app.process_sorting_reverse);
|
||||||
try_debug(&log, "Update event complete.");
|
try_debug(&log, "Update event complete.");
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, app_data :
|
||||||
vec![
|
vec![
|
||||||
disk.name.to_string(),
|
disk.name.to_string(),
|
||||||
disk.mount_point.to_string(),
|
disk.mount_point.to_string(),
|
||||||
format!("{:.2}%", disk.used_space as f64 / disk.total_space as f64 * 100_f64),
|
format!("{:.1}%", disk.used_space as f64 / disk.total_space as f64 * 100_f64),
|
||||||
(disk.free_space / 1024).to_string() + "GB",
|
(disk.free_space / 1024).to_string() + "GB",
|
||||||
(disk.total_space / 1024).to_string() + "GB",
|
(disk.total_space / 1024).to_string() + "GB",
|
||||||
]
|
]
|
||||||
|
@ -135,14 +135,31 @@ fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, app_data :
|
||||||
vec![
|
vec![
|
||||||
process.pid.to_string(),
|
process.pid.to_string(),
|
||||||
process.command.to_string(),
|
process.command.to_string(),
|
||||||
format!("{:.2}%", process.cpu_usage_percent),
|
format!("{:.1}%", process.cpu_usage_percent),
|
||||||
format!("{:.2}%", process.mem_usage_percent),
|
format!(
|
||||||
|
"{:.1}%",
|
||||||
|
if let Some(mem_usage) = process.mem_usage_percent {
|
||||||
|
mem_usage
|
||||||
|
}
|
||||||
|
else if let Some(mem_usage_in_mb) = process.mem_usage_mb {
|
||||||
|
if let Some(mem_data) = app_data.memory.last() {
|
||||||
|
mem_usage_in_mb as f64 / mem_data.mem_total_in_mb as f64 * 100_f64
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
0_f64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
0_f64
|
||||||
|
}
|
||||||
|
),
|
||||||
]
|
]
|
||||||
.into_iter(),
|
.into_iter(),
|
||||||
Style::default().fg(Color::LightGreen),
|
Style::default().fg(Color::LightGreen),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: Convert this into a separate func!
|
||||||
terminal.draw(|mut f| {
|
terminal.draw(|mut f| {
|
||||||
let vertical_chunks = Layout::default()
|
let vertical_chunks = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
|
@ -173,22 +190,17 @@ fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, app_data :
|
||||||
// Set up blocks and their components
|
// Set up blocks and their components
|
||||||
|
|
||||||
// CPU usage graph
|
// CPU usage graph
|
||||||
|
let x_axis : Axis<String> = Axis::default().style(Style::default().fg(Color::White)).bounds([0.0, 10.0]);
|
||||||
|
let y_axis : Axis<String> = Axis::default().style(Style::default().fg(Color::White)).bounds([0.0, 10.0]);
|
||||||
Chart::default()
|
Chart::default()
|
||||||
.block(Block::default().title("CPU Usage").borders(Borders::ALL))
|
.block(Block::default().title("CPU Usage").borders(Borders::ALL))
|
||||||
.x_axis(Axis::default().style(Style::default().fg(Color::White)).bounds([0.0, 10.0]).labels(&["0.0", "10.0"]))
|
.x_axis(x_axis)
|
||||||
.y_axis(Axis::default().style(Style::default().fg(Color::White)).bounds([0.0, 10.0]).labels(&["0.0", "10.0"]))
|
.y_axis(y_axis)
|
||||||
.datasets(&[
|
.datasets(&[Dataset::default()
|
||||||
Dataset::default()
|
.name("data1")
|
||||||
.name("data1")
|
.marker(Marker::Dot)
|
||||||
.marker(Marker::Dot)
|
.style(Style::default().fg(Color::Cyan))
|
||||||
.style(Style::default().fg(Color::Cyan))
|
.data(&[(0.0, 5.0), (1.0, 6.0), (1.5, 6.434)])])
|
||||||
.data(&[(0.0, 5.0), (1.0, 6.0), (1.5, 6.434)]),
|
|
||||||
Dataset::default()
|
|
||||||
.name("data2")
|
|
||||||
.marker(Marker::Braille)
|
|
||||||
.style(Style::default().fg(Color::Magenta))
|
|
||||||
.data(&[(4.0, 5.0), (5.0, 8.0), (7.66, 13.5)]),
|
|
||||||
])
|
|
||||||
.render(&mut f, top_chunks[0]);
|
.render(&mut f, top_chunks[0]);
|
||||||
|
|
||||||
//Memory usage graph
|
//Memory usage graph
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
|
use std::time::Instant;
|
||||||
use sysinfo::{ProcessorExt, System, SystemExt};
|
use sysinfo::{ProcessorExt, System, SystemExt};
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone)]
|
||||||
pub struct CPUData {
|
pub struct CPUData {
|
||||||
pub cpu_name : Box<str>,
|
pub cpu_name : Box<str>,
|
||||||
pub cpu_usage : u32,
|
pub cpu_usage : u32,
|
||||||
|
pub instant : Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cpu_data_list(sys : &System) -> Result<Vec<CPUData>, heim::Error> {
|
pub fn get_cpu_data_list(sys : &System) -> Result<Vec<CPUData>, heim::Error> {
|
||||||
|
@ -14,6 +16,7 @@ pub fn get_cpu_data_list(sys : &System) -> Result<Vec<CPUData>, heim::Error> {
|
||||||
cpu_vec.push(CPUData {
|
cpu_vec.push(CPUData {
|
||||||
cpu_name : Box::from(cpu.get_name()),
|
cpu_name : Box::from(cpu.get_name()),
|
||||||
cpu_usage : (cpu.get_cpu_usage() * 100_f32).ceil() as u32,
|
cpu_usage : (cpu.get_cpu_usage() * 100_f32).ceil() as u32,
|
||||||
|
instant : Instant::now(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use heim_common::prelude::StreamExt;
|
use heim_common::prelude::StreamExt;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct DiskData {
|
pub struct DiskData {
|
||||||
|
@ -9,11 +10,12 @@ pub struct DiskData {
|
||||||
pub total_space : u64,
|
pub total_space : u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone)]
|
||||||
pub struct IOData {
|
pub struct IOData {
|
||||||
pub mount_point : Box<str>,
|
pub mount_point : Box<str>,
|
||||||
pub read_bytes : u64,
|
pub read_bytes : u64,
|
||||||
pub write_bytes : u64,
|
pub write_bytes : u64,
|
||||||
|
pub instant : Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_io_usage_list(get_physical : bool) -> Result<Vec<IOData>, heim::Error> {
|
pub async fn get_io_usage_list(get_physical : bool) -> Result<Vec<IOData>, heim::Error> {
|
||||||
|
@ -26,6 +28,7 @@ pub async fn get_io_usage_list(get_physical : bool) -> Result<Vec<IOData>, heim:
|
||||||
mount_point : Box::from(io.device_name().to_str().unwrap_or("Name Unavailable")),
|
mount_point : Box::from(io.device_name().to_str().unwrap_or("Name Unavailable")),
|
||||||
read_bytes : io.read_bytes().get::<heim_common::units::information::megabyte>(),
|
read_bytes : io.read_bytes().get::<heim_common::units::information::megabyte>(),
|
||||||
write_bytes : io.write_bytes().get::<heim_common::units::information::megabyte>(),
|
write_bytes : io.write_bytes().get::<heim_common::units::information::megabyte>(),
|
||||||
|
instant : Instant::now(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +40,7 @@ pub async fn get_io_usage_list(get_physical : bool) -> Result<Vec<IOData>, heim:
|
||||||
mount_point : Box::from(io.device_name().to_str().unwrap_or("Name Unavailable")),
|
mount_point : Box::from(io.device_name().to_str().unwrap_or("Name Unavailable")),
|
||||||
read_bytes : io.read_bytes().get::<heim_common::units::information::megabyte>(),
|
read_bytes : io.read_bytes().get::<heim_common::units::information::megabyte>(),
|
||||||
write_bytes : io.write_bytes().get::<heim_common::units::information::megabyte>(),
|
write_bytes : io.write_bytes().get::<heim_common::units::information::megabyte>(),
|
||||||
|
instant : Instant::now(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
use heim_common::units::information;
|
use heim_common::units::information;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone)]
|
||||||
pub struct MemData {
|
pub struct MemData {
|
||||||
pub mem_total_in_mb : u64,
|
pub mem_total_in_mb : u64,
|
||||||
pub mem_used_in_mb : u64,
|
pub mem_used_in_mb : u64,
|
||||||
|
pub instant : Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_mem_data_list() -> Result<MemData, heim::Error> {
|
pub async fn get_mem_data_list() -> Result<MemData, heim::Error> {
|
||||||
|
@ -12,6 +14,7 @@ pub async fn get_mem_data_list() -> Result<MemData, heim::Error> {
|
||||||
Ok(MemData {
|
Ok(MemData {
|
||||||
mem_total_in_mb : memory.total().get::<information::megabyte>(),
|
mem_total_in_mb : memory.total().get::<information::megabyte>(),
|
||||||
mem_used_in_mb : memory.total().get::<information::megabyte>() - memory.available().get::<information::megabyte>(),
|
mem_used_in_mb : memory.total().get::<information::megabyte>() - memory.available().get::<information::megabyte>(),
|
||||||
|
instant : Instant::now(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,5 +24,6 @@ pub async fn get_swap_data_list() -> Result<MemData, heim::Error> {
|
||||||
Ok(MemData {
|
Ok(MemData {
|
||||||
mem_total_in_mb : memory.total().get::<information::megabyte>(),
|
mem_total_in_mb : memory.total().get::<information::megabyte>(),
|
||||||
mem_used_in_mb : memory.used().get::<information::megabyte>(),
|
mem_used_in_mb : memory.used().get::<information::megabyte>(),
|
||||||
|
instant : Instant::now(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,17 +22,23 @@ fn set_if_valid<T : std::clone::Clone>(result : &Result<T, heim::Error>, value_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn push_if_valid<T : std::clone::Clone>(result : &Result<T, heim::Error>, vector_to_push : &mut Vec<T>) {
|
||||||
|
if let Ok(result) = result {
|
||||||
|
vector_to_push.push(result.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct Data {
|
pub struct Data {
|
||||||
pub list_of_cpu_packages : Vec<cpu::CPUData>,
|
pub list_of_cpu_packages : Vec<Vec<cpu::CPUData>>,
|
||||||
pub list_of_io : Vec<disks::IOData>,
|
pub list_of_io : Vec<Vec<disks::IOData>>,
|
||||||
pub list_of_physical_io : Vec<disks::IOData>,
|
pub list_of_physical_io : Vec<Vec<disks::IOData>>,
|
||||||
pub memory : mem::MemData,
|
pub memory : Vec<mem::MemData>,
|
||||||
pub swap : mem::MemData,
|
pub swap : Vec<mem::MemData>,
|
||||||
pub list_of_temperature : Vec<temperature::TempData>,
|
pub list_of_temperature : Vec<temperature::TempData>,
|
||||||
pub network : network::NetworkData,
|
pub network : Vec<network::NetworkData>,
|
||||||
pub list_of_processes : Vec<processes::ProcessData>,
|
pub list_of_processes : Vec<processes::ProcessData>, // Only need to keep a list of processes...
|
||||||
pub list_of_disks : Vec<disks::DiskData>,
|
pub list_of_disks : Vec<disks::DiskData>, // Only need to keep a list of disks and their data
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DataState {
|
pub struct DataState {
|
||||||
|
@ -56,17 +62,17 @@ impl DataState {
|
||||||
self.sys.refresh_network();
|
self.sys.refresh_network();
|
||||||
|
|
||||||
// What we want to do: For timed data, if there is an error, just do not add. For other data, just don't update!
|
// What we want to do: For timed data, if there is an error, just do not add. For other data, just don't update!
|
||||||
set_if_valid(&network::get_network_data(&self.sys), &mut self.data.network);
|
push_if_valid(&network::get_network_data(&self.sys), &mut self.data.network);
|
||||||
set_if_valid(&cpu::get_cpu_data_list(&self.sys), &mut self.data.list_of_cpu_packages);
|
push_if_valid(&cpu::get_cpu_data_list(&self.sys), &mut self.data.list_of_cpu_packages);
|
||||||
|
|
||||||
// TODO: We can convert this to a multi-threaded task...
|
// TODO: We can convert this to a multi-threaded task...
|
||||||
set_if_valid(&mem::get_mem_data_list().await, &mut self.data.memory);
|
push_if_valid(&mem::get_mem_data_list().await, &mut self.data.memory);
|
||||||
set_if_valid(&mem::get_swap_data_list().await, &mut self.data.swap);
|
push_if_valid(&mem::get_swap_data_list().await, &mut self.data.swap);
|
||||||
set_if_valid(&processes::get_sorted_processes_list(self.data.memory.mem_total_in_mb).await, &mut self.data.list_of_processes);
|
set_if_valid(&processes::get_sorted_processes_list().await, &mut self.data.list_of_processes);
|
||||||
|
|
||||||
set_if_valid(&disks::get_disk_usage_list().await, &mut self.data.list_of_disks);
|
set_if_valid(&disks::get_disk_usage_list().await, &mut self.data.list_of_disks);
|
||||||
set_if_valid(&disks::get_io_usage_list(false).await, &mut self.data.list_of_io);
|
push_if_valid(&disks::get_io_usage_list(false).await, &mut self.data.list_of_io);
|
||||||
set_if_valid(&disks::get_io_usage_list(true).await, &mut self.data.list_of_physical_io);
|
push_if_valid(&disks::get_io_usage_list(true).await, &mut self.data.list_of_physical_io);
|
||||||
set_if_valid(&temperature::get_temperature_data().await, &mut self.data.list_of_temperature);
|
set_if_valid(&temperature::get_temperature_data().await, &mut self.data.list_of_temperature);
|
||||||
debug!("End updating...");
|
debug!("End updating...");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,8 @@ pub enum ProcessSorting {
|
||||||
pub struct ProcessData {
|
pub struct ProcessData {
|
||||||
pub pid : u32,
|
pub pid : u32,
|
||||||
pub cpu_usage_percent : f64,
|
pub cpu_usage_percent : f64,
|
||||||
pub mem_usage_percent : f64,
|
pub mem_usage_percent : Option<f64>,
|
||||||
|
pub mem_usage_mb : Option<u64>,
|
||||||
pub command : String,
|
pub command : String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,9 +75,11 @@ fn get_cpu_use_val() -> std::io::Result<f64> {
|
||||||
Ok(val[0].parse::<f64>().unwrap_or(0_f64) + val[1].parse::<f64>().unwrap_or(0_f64) + val[2].parse::<f64>().unwrap_or(0_f64) + val[3].parse::<f64>().unwrap_or(0_f64))
|
Ok(val[0].parse::<f64>().unwrap_or(0_f64) + val[1].parse::<f64>().unwrap_or(0_f64) + val[2].parse::<f64>().unwrap_or(0_f64) + val[3].parse::<f64>().unwrap_or(0_f64))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn linux_cpu_usage(pid : u32, before_cpu_val : f64) -> std::io::Result<f64> {
|
async fn linux_cpu_usage(pid : u32) -> std::io::Result<f64> {
|
||||||
// Based heavily on https://stackoverflow.com/a/23376195 and https://stackoverflow.com/a/1424556
|
// Based heavily on https://stackoverflow.com/a/23376195 and https://stackoverflow.com/a/1424556
|
||||||
let before_proc_val = get_process_cpu_stats(pid)?;
|
let before_proc_val = get_process_cpu_stats(pid)?;
|
||||||
|
let before_cpu_val = get_cpu_use_val()?;
|
||||||
|
|
||||||
futures_timer::Delay::new(std::time::Duration::from_millis(1000)).await.unwrap();
|
futures_timer::Delay::new(std::time::Duration::from_millis(1000)).await.unwrap();
|
||||||
let after_proc_val = get_process_cpu_stats(pid)?;
|
let after_proc_val = get_process_cpu_stats(pid)?;
|
||||||
let after_cpu_val = get_cpu_use_val()?;
|
let after_cpu_val = get_cpu_use_val()?;
|
||||||
|
@ -85,31 +88,30 @@ async fn linux_cpu_usage(pid : u32, before_cpu_val : f64) -> std::io::Result<f64
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn convert_ps(process : &str) -> std::io::Result<ProcessData> {
|
async fn convert_ps(process : &str) -> std::io::Result<ProcessData> {
|
||||||
let before_cpu_val = get_cpu_use_val()?;
|
|
||||||
|
|
||||||
debug!("Process: |{}|", process);
|
|
||||||
if process.trim().to_string().is_empty() {
|
if process.trim().to_string().is_empty() {
|
||||||
return Ok(ProcessData {
|
return Ok(ProcessData {
|
||||||
pid : 0,
|
pid : 0,
|
||||||
command : "".to_string(),
|
command : "".to_string(),
|
||||||
mem_usage_percent : 0_f64,
|
mem_usage_percent : None,
|
||||||
|
mem_usage_mb : None,
|
||||||
cpu_usage_percent : 0_f64,
|
cpu_usage_percent : 0_f64,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let pid = (&process[..11]).trim().to_string().parse::<u32>().unwrap_or(0);
|
let pid = (&process[..11]).trim().to_string().parse::<u32>().unwrap_or(0);
|
||||||
let command = (&process[11..61]).trim().to_string();
|
let command = (&process[11..61]).trim().to_string();
|
||||||
let mem_usage_percent = (&process[62..]).trim().to_string().parse::<f64>().unwrap_or(0_f64);
|
let mem_usage_percent = Some((&process[62..]).trim().to_string().parse::<f64>().unwrap_or(0_f64));
|
||||||
|
|
||||||
Ok(ProcessData {
|
Ok(ProcessData {
|
||||||
pid,
|
pid,
|
||||||
command,
|
command,
|
||||||
mem_usage_percent,
|
mem_usage_percent,
|
||||||
cpu_usage_percent : linux_cpu_usage(pid, before_cpu_val).await?,
|
mem_usage_mb : None,
|
||||||
|
cpu_usage_percent : linux_cpu_usage(pid).await?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_sorted_processes_list(total_mem : u64) -> Result<Vec<ProcessData>, heim::Error> {
|
pub async fn get_sorted_processes_list() -> Result<Vec<ProcessData>, heim::Error> {
|
||||||
let mut process_vector : Vec<ProcessData> = Vec::new();
|
let mut process_vector : Vec<ProcessData> = Vec::new();
|
||||||
|
|
||||||
if cfg!(target_os = "linux") {
|
if cfg!(target_os = "linux") {
|
||||||
|
@ -141,7 +143,8 @@ pub async fn get_sorted_processes_list(total_mem : u64) -> Result<Vec<ProcessDat
|
||||||
command : process.name().await.unwrap_or_else(|_| "".to_string()),
|
command : process.name().await.unwrap_or_else(|_| "".to_string()),
|
||||||
pid : process.pid() as u32,
|
pid : process.pid() as u32,
|
||||||
cpu_usage_percent : f64::from(cpu_usage.get::<units::ratio::percent>()),
|
cpu_usage_percent : f64::from(cpu_usage.get::<units::ratio::percent>()),
|
||||||
mem_usage_percent : mem_measurement.rss().get::<units::information::megabyte>() as f64 / total_mem as f64 * 100_f64,
|
mem_usage_percent : None,
|
||||||
|
mem_usage_mb : Some(mem_measurement.rss().get::<units::information::megabyte>()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use heim_common::{prelude::StreamExt, units::thermodynamic_temperature};
|
use heim_common::{prelude::StreamExt, units::thermodynamic_temperature};
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone)]
|
||||||
pub struct TempData {
|
pub struct TempData {
|
||||||
pub component_name : Box<str>,
|
pub component_name : Box<str>,
|
||||||
pub temperature : f32,
|
pub temperature : f32,
|
||||||
|
|
Loading…
Reference in New Issue