Skip to content

Commit

Permalink
feat(dashboard): add CPU temperature (#232)
Browse files Browse the repository at this point in the history
  • Loading branch information
ravenclaw900 committed Jun 1, 2022
1 parent c4d6616 commit 6567d10
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 21 deletions.
5 changes: 5 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,8 @@
# This will do 1 GitHub API call per day
# - Default: true
#update_check = true

# Preferred temperature unit
# - Options: fahrenheit, celsius
# - Default: celsius
#temp_unit = celsius
5 changes: 5 additions & 0 deletions src/backend/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::shared::TempUnit;
use figment::{
providers::{Env, Format, Serialized, Toml},
Figment,
Expand Down Expand Up @@ -39,6 +40,8 @@ pub struct Config {
pub terminal_user: String,

pub update_check: bool,

pub temp_unit: TempUnit,
}

impl Default for Config {
Expand All @@ -63,6 +66,8 @@ impl Default for Config {
terminal_user: "root".to_string(),

update_check: true,

temp_unit: TempUnit::Celsius,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/backend/src/page_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub async fn main_handler(socket_ptr: SocketPtr, quit: &Arc<Notify>) {
swap: systemdata::swap(),
disk: systemdata::disk(),
network: systemdata::network(),
temp: systemdata::temp(),
})))
.await;
} => {}
Expand Down
18 changes: 18 additions & 0 deletions src/backend/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub struct SysData {
pub swap: UsageData,
pub disk: UsageData,
pub network: NetData,
pub temp: CPUTemp,
}

#[derive(SerJson)]
Expand Down Expand Up @@ -103,6 +104,7 @@ pub struct GlobalData {
pub update_check: bool,
#[cfg(feature = "frontend")]
pub nodes: Vec<String>,
pub temp_unit: TempUnit,
}

#[derive(SerJson, Debug)]
Expand Down Expand Up @@ -153,3 +155,19 @@ pub struct JWTClaims {
pub exp: u64,
pub iat: u64,
}

#[derive(SerJson)]
pub struct CPUTemp {
pub available: bool,
pub celsius: i16,
pub fahrenheit: i16,
}

#[derive(Deserialize, Serialize, SerJson, Clone)]
#[serde(rename_all = "lowercase")]
pub enum TempUnit {
#[nserde(rename = "fahrenheit")]
Fahrenheit,
#[nserde(rename = "celsius")]
Celsius,
}
30 changes: 26 additions & 4 deletions src/backend/src/systemdata.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use lazy_static::lazy_static;
use psutil::{cpu, disk, host, memory, network, process};
use psutil::{cpu, disk, host, memory, network, process, sensors};
use std::fs;
use std::process::Command;
use std::str::from_utf8;
Expand Down Expand Up @@ -350,15 +350,18 @@ pub fn services() -> Vec<shared::ServiceData> {
}

pub fn global() -> shared::GlobalData {
use crate::CONFIG;

let update =
fs::read_to_string("/run/dietpi/.update_available").unwrap_or_else(|_| String::new());
shared::GlobalData {
update,
login: crate::CONFIG.pass,
login: CONFIG.pass,
version: env!("CARGO_PKG_VERSION").to_string(),
update_check: crate::CONFIG.update_check,
update_check: CONFIG.update_check,
#[cfg(feature = "frontend")]
nodes: crate::CONFIG.nodes.clone(),
nodes: CONFIG.nodes.clone(),
temp_unit: CONFIG.temp_unit.clone(),
}
}

Expand Down Expand Up @@ -440,3 +443,22 @@ pub fn browser_dir(path: &std::path::Path) -> Vec<shared::BrowserData> {
}
file_list
}

#[allow(clippy::cast_possible_truncation)]
pub fn temp() -> shared::CPUTemp {
match &sensors::temperatures().get(0) {
Some(Ok(temp)) => {
let temp = temp.current();
shared::CPUTemp {
available: true,
celsius: temp.celsius().round() as i16,
fahrenheit: temp.fahrenheit().round() as i16,
}
}
None | Some(Err(_)) => shared::CPUTemp {
available: false,
celsius: 0,
fahrenheit: 0,
},
}
}
6 changes: 5 additions & 1 deletion src/frontend/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
let notify = false;
let menu = window.innerWidth > 768;
let dpUpdate = "";
let tempUnit: "fahrenheit" | "celsius";
let navPage = "";
let token = "";
let password = "";
Expand Down Expand Up @@ -109,6 +110,7 @@
nodes = socketData.nodes;
}
backendVersion = socketData.version;
tempUnit = socketData.temp_unit;
// Get token
if (login) {
let obj = JSON.parse(localStorage.getItem("tokens"));
Expand Down Expand Up @@ -420,7 +422,9 @@
<Route path="process"
><Process {socketData} {socketSend} /></Route
>
<Route path="/"><Home {socketData} {darkMode} /></Route>
<Route path="/"
><Home {socketData} {darkMode} {tempUnit} /></Route
>
<Route path="software"
><Software {socketData} {socketSend} /></Route
>
Expand Down
102 changes: 86 additions & 16 deletions src/frontend/src/pages/Home.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
export let socketData: Partial<socketData>;
export let darkMode: boolean;
export let tempUnit: "fahrenheit" | "celsius";
let portrait = window.innerHeight > window.innerWidth;
Expand All @@ -34,7 +35,7 @@
swapData: (string | number)[],
diskData: (string | number)[];
let data: uPlot.AlignedData = [[], [], [], [], [], [], []];
let data: uPlot.AlignedData = [[], [], [], [], [], [], [], []];
$: socketData.cpu != undefined &&
(cpuAnimate.set(socketData.cpu),
Expand Down Expand Up @@ -76,10 +77,40 @@
}
}
function getTempMsg(temp: number) {
if (temp >= 70) {
return "WARNING: Reducing the life of your device";
} else if (temp >= 60) {
return "Running hot, not recommended";
} else if (temp >= 50) {
return "Running warm, but safe";
} else if (temp >= 40) {
return "Optimal temperature";
} else if (temp >= 30) {
return "Cool runnings";
} else {
return "Who put me in the freezer!";
}
}
function getTempClass(temp: number) {
if (temp >= 70) {
return "font-semibold text-red-500";
} else if (temp >= 60) {
return "text-red-500";
} else if (temp >= 50) {
return "text-yellow-500";
} else if (temp >= 40) {
return "text-green-500";
} else {
return "text-blue-500";
}
}
let uplot: uPlot;
onMount(() => {
let opts = {
let opts: uPlot.Options = {
...getSize(),
series: [
{},
Expand Down Expand Up @@ -132,7 +163,8 @@
stroke: "#ec4899",
width: 3,
scale: "mb",
value: (_: any, val: number) => prettyBytes(val * 1000000),
value: (_: uPlot, val: number) =>
prettyBytes(val * 1000000),
},
],
axes: [
Expand All @@ -154,9 +186,29 @@
values: (_: any, vals: number[]) =>
vals.map((v: number) => +v.toFixed(2) + "%"),
grid: { show: false },
stroke: () => (darkMode ? "#fff" : "#000"),
stroke: "#10b981",
},
{
side: 1,
scale: "deg",
values: (_: any, vals: number[]) =>
vals.map(
(v: number) =>
+v + (tempUnit == "celsius" ? "ºC" : "ºF")
),
grid: { show: false },
stroke: "#94A3B8",
size: 75,
},
],
scales: {
"%": {
auto: false,
// Hide CPU axis when CPU series is disabled
range: (u: uPlot) =>
u.series[1].show ? [0, 100] : [null, null],
},
},
};
uplot = new uPlot(opts, data, chart);
Expand All @@ -177,28 +229,38 @@
dataPush[5].push(socketData.network.sent / 1000000);
dataPush[6].push(socketData.network.received / 1000000);
}
if (socketData.temp != undefined && socketData.temp.available) {
if (uplot.series[7] == undefined) {
uplot.addSeries({
spanGaps: false,
label: "CPU Temperature",
stroke: "#94A3B8",
width: 3,
scale: "deg",
value: (_: any, val: number) =>
val + (tempUnit == "celsius" ? "ºC" : "ºF"),
});
}
if (tempUnit == "celsius") {
dataPush[7].push(socketData.temp.celsius);
} else if (tempUnit == "fahrenheit") {
dataPush[7].push(socketData.temp.fahrenheit);
}
}
uplot.setData(data);
}, 2000);
let handle2 = setInterval(() => {
let oldSize = getSize();
setTimeout(() => {
let newSize = getSize();
if (oldSize != newSize) {
uplot.setSize(newSize);
}
}, 100);
}, 100);
onDestroy(() => {
uplot = undefined;
clearInterval(handle1);
clearInterval(handle2);
});
</script>

<svelte:window
on:resize={() => (portrait = window.innerHeight > window.innerWidth)}
on:resize={() => {
portrait = window.innerHeight > window.innerWidth;
uplot.setSize(getSize());
}}
/>

<main
Expand All @@ -210,6 +272,14 @@
</Card>
<Card header="System Stats">
{#if ramData != undefined}
{#if socketData.temp.available}
<div class="text-center">
<span class={getTempClass(socketData.temp.celsius)}>
{socketData.temp.celsius}ºC/{socketData.temp
.fahrenheit}ºF</span
>: {getTempMsg(socketData.temp.celsius)}
</div>
{/if}
CPU:<span class="float-right">{socketData.cpu}/100%</span>
<div class="bg-gray-200 dark:bg-gray-800 w-full h-3 my-1">
<div class="bg-green-500 h-3" style="width:{$cpuAnimate}%" />
Expand Down
8 changes: 8 additions & 0 deletions src/frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ interface socketData {
swap: usage;
disk: usage;
network: net;
temp: temp;
// Software page
uninstalled: software[];
installed: software[];
Expand Down Expand Up @@ -33,6 +34,7 @@ interface socketData {
nodes: string[];
version: string;
update_check: boolean;
temp_unit: "fahrenheit" | "celsius";
}

interface software {
Expand Down Expand Up @@ -78,5 +80,11 @@ interface net {
received: number;
}

interface temp {
available: boolean;
celsius: number;
fahrenheit: number;
}

// 'browser' required for selected path in file browser
export type { socketData, browser };

0 comments on commit 6567d10

Please sign in to comment.