Device metrics in the sidebar

Added functions to enable device monitoring in the sidebar by tapping on their respective metric boxes.
This commit is contained in:
FrogAi
2024-02-27 16:34:47 -07:00
parent 8f2cb1dd53
commit 3794b4f06b
6 changed files with 127 additions and 4 deletions

View File

@@ -13,6 +13,8 @@ struct FrogPilotCarControl @0x81c2f05a394cf4af {
}
struct FrogPilotDeviceState @0xaedffd8f31e7b55d {
freeSpace @0 :Int16;
usedSpace @1 :Int16;
}
struct FrogPilotNavigation @0xf35cc4560bbf6ec2 {

View File

@@ -267,6 +267,11 @@ std::unordered_map<std::string, uint32_t> keys = {
{"RelaxedJerk", PERSISTENT},
{"RoadEdgesWidth", PERSISTENT},
{"SilentMode", PERSISTENT},
{"ShowCPU", PERSISTENT},
{"ShowGPU", PERSISTENT},
{"ShowMemoryUsage", PERSISTENT},
{"ShowStorageLeft", PERSISTENT},
{"ShowStorageUsed", PERSISTENT},
{"StandardFollow", PERSISTENT},
{"StandardJerk", PERSISTENT},
{"StockTune", PERSISTENT},

View File

@@ -19,7 +19,7 @@ from openpilot.common.params import Params
from openpilot.common.realtime import DT_TRML
from openpilot.selfdrive.controls.lib.alertmanager import set_offroad_alert
from openpilot.system.hardware import HARDWARE, TICI, AGNOS
from openpilot.system.loggerd.config import get_available_percent
from openpilot.system.loggerd.config import get_available_bytes, get_available_percent, get_used_bytes
from openpilot.selfdrive.statsd import statlog
from openpilot.common.swaglog import cloudlog
from openpilot.selfdrive.thermald.power_monitoring import PowerMonitoring
@@ -244,6 +244,9 @@ def thermald_thread(end_event, hw_queue) -> None:
fpmsg = messaging.new_message('frogpilotDeviceState')
fpmsg.frogpilotDeviceState.freeSpace = round(get_available_bytes(default=32.0 * (2 ** 30)) / (2 ** 30))
fpmsg.frogpilotDeviceState.usedSpace = round(get_used_bytes(default=0.0 * (2 ** 30)) / (2 ** 30))
pm.send("frogpilotDeviceState", fpmsg)
msg.deviceState.freeSpacePercent = get_available_percent(default=100.0)

View File

@@ -40,6 +40,13 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed(
pm = std::make_unique<PubMaster, const std::initializer_list<const char *>>({"userFlag"});
// FrogPilot variables
isCPU = params.getBool("ShowCPU");
isGPU = params.getBool("ShowGPU");
isMemoryUsage = params.getBool("ShowMemoryUsage");
isStorageLeft = params.getBool("ShowStorageLeft");
isStorageUsed = params.getBool("ShowStorageUsed");
themeConfiguration = {
{0, {"stock", {QColor(255, 255, 255)}}},
{1, {"frog_theme", {QColor(23, 134, 68)}}},
@@ -65,7 +72,31 @@ Sidebar::Sidebar(QWidget *parent) : QFrame(parent), onroad(false), flag_pressed(
}
void Sidebar::mousePressEvent(QMouseEvent *event) {
if (onroad && home_btn.contains(event->pos())) {
// Declare the click boxes
QRect cpuRect = {30, 496, 240, 126};
QRect memoryRect = {30, 654, 240, 126};
static int showChip = 0;
static int showMemory = 0;
// Swap between the respective metrics upon tap
if (cpuRect.contains(event->pos())) {
showChip = (showChip + 1) % 3;
isCPU = (showChip == 1);
isGPU = (showChip == 2);
params.putBoolNonBlocking("ShowCPU", isCPU);
params.putBoolNonBlocking("ShowGPU", isGPU);
update();
} else if (memoryRect.contains(event->pos())) {
showMemory = (showMemory + 1) % 4;
isMemoryUsage = (showMemory == 1);
isStorageLeft = (showMemory == 2);
isStorageUsed = (showMemory == 3);
params.putBoolNonBlocking("ShowMemoryUsage", isMemoryUsage);
params.putBoolNonBlocking("ShowStorageLeft", isStorageLeft);
params.putBoolNonBlocking("ShowStorageUsed", isStorageUsed);
update();
} else if (onroad && home_btn.contains(event->pos())) {
flag_pressed = true;
update();
} else if (settings_btn.contains(event->pos())) {
@@ -114,6 +145,54 @@ void Sidebar::updateState(const UIState &s) {
QColor theme_color = currentColors[0];
// FrogPilot metrics
if (isCPU || isGPU) {
auto cpu_loads = deviceState.getCpuUsagePercent();
int cpu_usage = std::accumulate(cpu_loads.begin(), cpu_loads.end(), 0) / cpu_loads.size();
int gpu_usage = deviceState.getGpuUsagePercent();
QString cpu = QString::number(cpu_usage) + "%";
QString gpu = QString::number(gpu_usage) + "%";
QString metric = isGPU ? gpu : cpu;
int usage = isGPU ? gpu_usage : cpu_usage;
ItemStatus cpuStatus = {{tr(isGPU ? "GPU" : "CPU"), metric}, theme_color};
if (usage >= 85) {
cpuStatus = {{tr(isGPU ? "GPU" : "CPU"), metric}, danger_color};
} else if (usage >= 70) {
cpuStatus = {{tr(isGPU ? "GPU" : "CPU"), metric}, warning_color};
}
setProperty("cpuStatus", QVariant::fromValue(cpuStatus));
}
if (isMemoryUsage || isStorageLeft || isStorageUsed) {
int memory_usage = deviceState.getMemoryUsagePercent();
int storage_left = frogpilotDeviceState.getFreeSpace();
int storage_used = frogpilotDeviceState.getUsedSpace();
QString memory = QString::number(memory_usage) + "%";
QString storage = QString::number(isStorageLeft ? storage_left : storage_used) + " GB";
if (isMemoryUsage) {
ItemStatus memoryStatus = {{tr("MEMORY"), memory}, theme_color};
if (memory_usage >= 85) {
memoryStatus = {{tr("MEMORY"), memory}, danger_color};
} else if (memory_usage >= 70) {
memoryStatus = {{tr("MEMORY"), memory}, warning_color};
}
setProperty("memoryStatus", QVariant::fromValue(memoryStatus));
} else {
ItemStatus storageStatus = {{tr(isStorageLeft ? "LEFT" : "USED"), storage}, theme_color};
if (10 <= storage_left && storage_left < 25) {
storageStatus = {{tr(isStorageLeft ? "LEFT" : "USED"), storage}, warning_color};
} else if (storage_left < 10) {
storageStatus = {{tr(isStorageLeft ? "LEFT" : "USED"), storage}, danger_color};
}
setProperty("storageStatus", QVariant::fromValue(storageStatus));
}
}
ItemStatus connectStatus;
auto last_ping = deviceState.getLastAthenaPingTime();
if (last_ping == 0) {
@@ -173,6 +252,18 @@ void Sidebar::paintEvent(QPaintEvent *event) {
// metrics
drawMetric(p, temp_status.first, temp_status.second, 338);
drawMetric(p, panda_status.first, panda_status.second, 496);
drawMetric(p, connect_status.first, connect_status.second, 654);
if (isCPU || isGPU) {
drawMetric(p, cpu_status.first, cpu_status.second, 496);
} else {
drawMetric(p, panda_status.first, panda_status.second, 496);
}
if (isMemoryUsage) {
drawMetric(p, memory_status.first, memory_status.second, 654);
} else if (isStorageLeft || isStorageUsed) {
drawMetric(p, storage_status.first, storage_status.second, 654);
} else {
drawMetric(p, connect_status.first, connect_status.second, 654);
}
}

View File

@@ -19,6 +19,9 @@ class Sidebar : public QFrame {
Q_PROPERTY(int netStrength MEMBER net_strength NOTIFY valueChanged);
// FrogPilot properties
Q_PROPERTY(ItemStatus cpuStatus MEMBER cpu_status NOTIFY valueChanged)
Q_PROPERTY(ItemStatus memoryStatus MEMBER memory_status NOTIFY valueChanged)
Q_PROPERTY(ItemStatus storageStatus MEMBER storage_status NOTIFY valueChanged)
public:
explicit Sidebar(QWidget* parent = 0);
@@ -66,6 +69,14 @@ private:
Params params;
UIScene &scene;
ItemStatus cpu_status, memory_status, storage_status;
bool isCPU;
bool isGPU;
bool isMemoryUsage;
bool isStorageLeft;
bool isStorageUsed;
std::unordered_map<int, std::pair<QString, std::vector<QColor>>> themeConfiguration;
std::unordered_map<int, QPixmap> flag_imgs;
std::unordered_map<int, QPixmap> home_imgs;

View File

@@ -27,3 +27,14 @@ def get_available_bytes(default=None):
available_bytes = default
return available_bytes
def get_used_bytes(default=None):
try:
statvfs = os.statvfs(Paths.log_root())
total_bytes = statvfs.f_blocks * statvfs.f_frsize
available_bytes = statvfs.f_bavail * statvfs.f_frsize
used_bytes = total_bytes - available_bytes
except OSError:
used_bytes = default
return used_bytes