pikvm/pikvm#1347: added CPU and MEM to /api/info

This commit is contained in:
Maxim Devaev 2024-07-08 04:34:32 +03:00
parent 53c2d253f2
commit ca639f6be8
3 changed files with 54 additions and 6 deletions

View File

@ -384,7 +384,7 @@ def _get_config_scheme() -> dict:
"hw": {
"vcgencmd_cmd": Option(["/usr/bin/vcgencmd"], type=valid_command),
"ignore_past": Option(False, type=valid_bool),
"state_poll": Option(10.0, type=valid_float_f01),
"state_poll": Option(5.0, type=valid_float_f01),
},
"fan": {
"daemon": Option("kvmd-fan", type=valid_stripped_string),

View File

@ -27,6 +27,8 @@ from typing import Callable
from typing import AsyncGenerator
from typing import TypeVar
import psutil
from ....logging import get_logger
from .... import env
@ -57,11 +59,17 @@ class HwInfoSubmanager(BaseInfoSubmanager):
self.__dt_cache: dict[str, str] = {}
async def get_state(self) -> dict:
(model, serial, cpu_temp, throttling) = await asyncio.gather(
(
model, serial, throttling,
cpu_percent, cpu_temp,
(mem_percent, mem_total, mem_available),
) = await asyncio.gather(
self.__read_dt_file("model"),
self.__read_dt_file("serial-number"),
self.__get_cpu_temp(),
self.__get_throttling(),
self.__get_cpu_percent(),
self.__get_cpu_temp(),
self.__get_mem(),
)
return {
"platform": {
@ -73,6 +81,14 @@ class HwInfoSubmanager(BaseInfoSubmanager):
"temp": {
"cpu": cpu_temp,
},
"cpu": {
"percent": cpu_percent,
},
"mem": {
"percent": mem_percent,
"total": mem_total,
"available": mem_available,
},
"throttling": throttling,
},
}
@ -106,6 +122,33 @@ class HwInfoSubmanager(BaseInfoSubmanager):
get_logger(0).error("Can't read CPU temp from %s: %s", temp_path, err)
return None
async def __get_cpu_percent(self) -> (float | None):
try:
st = psutil.cpu_times_percent()
user = st.user - st.guest
nice = st.nice - st.guest_nice
idle_all = st.idle + st.iowait
system_all = st.system + st.irq + st.softirq
virtual = st.guest + st.guest_nice
total = max(1, user + nice + system_all + idle_all + st.steal + virtual)
return int(
st.nice / total * 100
+ st.user / total * 100
+ system_all / total * 100
+ (st.steal + st.guest) / total * 100
)
except Exception as err:
get_logger(0).error("Can't get CPU percent: %s", err)
return None
async def __get_mem(self) -> (tuple[float, int, int] | tuple[None, None, None]):
try:
st = psutil.virtual_memory()
return (st.percent, st.total, st.available)
except Exception as err:
get_logger(0).error("Can't get memory info: %s", err)
return (None, None, None)
async def __get_throttling(self) -> (dict | None):
# https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=147781&start=50#p972790
flags = await self.__parse_vcgencmd(

View File

@ -132,7 +132,7 @@ export function Session() {
if (__info_hw_state !== null) {
html += `
Platform:
${__formatPlatform(__info_hw_state.platform)}
${__formatMisc(__info_hw_state)}
<hr>
Temperature:
${__formatTemp(__info_hw_state.health.temp)}
@ -153,8 +153,13 @@ export function Session() {
$("about-hardware").innerHTML = html;
};
var __formatPlatform = function(state) {
return __formatUl([["Base", state.base], ["Serial", state.serial]]);
var __formatMisc = function(state) {
return __formatUl([
["Base", state.platform.base],
["Serial", state.platform.serial],
["CPU", `${state.health.cpu.percent}%`],
["MEM", `${state.health.mem.percent}%`],
]);
};
var __formatFan = function(state) {