Skip to content

feat: add metrics publisher for NT #1791

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Jul 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
54e666b
feat: add metrics publisher for NT
samfreund Feb 19, 2025
1cb80b8
abstract hashmap
samfreund Feb 19, 2025
a6513bb
comments stuff
samfreund Feb 19, 2025
6e0adcd
fix the broke
samfreund Feb 19, 2025
58331b8
rename
samfreund Feb 19, 2025
bc3d905
Use record
mcm001 Apr 13, 2025
8c1e60a
Rename
mcm001 Apr 13, 2025
ee9d7ed
Publish proto
mcm001 Apr 13, 2025
21b4946
Merge branch 'main' into feat-publish-coprocessor-metrics
samfreund Apr 13, 2025
e4aa13b
Merge branch 'main' into feat-publish-coprocessor-metrics
samfreund Apr 15, 2025
cecd356
Merge branch 'main' into feat-publish-coprocessor-metrics
samfreund Jul 1, 2025
fa708a0
Merge branch 'main' into feat-publish-coprocessor-metrics
samfreund Jul 4, 2025
d6381b9
update metrics publish location
samfreund Jul 5, 2025
0850049
update metrics to publish numbers
samfreund Jul 9, 2025
f8d2589
rework metrics frontend for numbers
samfreund Jul 10, 2025
dabd275
refactor names for clarity
samfreund Jul 10, 2025
74d89ca
refactor frontend uptime display to use Intl API
samfreund Jul 11, 2025
364d7f9
annotate previous code as unused
samfreund Jul 11, 2025
cda9f0c
javadoc
samfreund Jul 11, 2025
70a9012
refactor frontend with copy of useSettingsStore
samfreund Jul 12, 2025
2e959d9
periodic updates from hardware manager
samfreund Jul 12, 2025
fa91024
Fix DurationFormatter
Gold856 Jul 12, 2025
0ac0f39
make throttling conditional
samfreund Jul 12, 2025
2bf02d1
Merge branch 'main' into feat-publish-coprocessor-metrics
samfreund Jul 12, 2025
9b79cf0
Load libraries in HardwareTest
Gold856 Jul 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 42 additions & 21 deletions photon-client/src/components/settings/MetricsCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,48 +39,69 @@ const generalMetrics = computed<MetricItem[]>(() => {
return stats;
});

// @ts-expect-error This uses Intl.DurationFormat which is newly implemented and not available in TS.
const durationFormatter = new Intl.DurationFormat("en", { style: "narrow" });
const platformMetrics = computed<MetricItem[]>(() => {
const metrics = useSettingsStore().metrics;
const stats = [
{
header: "CPU Temp",
value: useSettingsStore().metrics.cpuTemp === undefined ? "Unknown" : `${useSettingsStore().metrics.cpuTemp}°C`
value: metrics.cpuTemp === undefined || metrics.cpuTemp == -1 ? "Unknown" : `${metrics.cpuTemp}°C`
},
{
header: "CPU Usage",
value: useSettingsStore().metrics.cpuUtil === undefined ? "Unknown" : `${useSettingsStore().metrics.cpuUtil}%`
value: metrics.cpuUtil === undefined ? "Unknown" : `${metrics.cpuUtil}%`
},
{
header: "CPU Memory Usage",
value:
useSettingsStore().metrics.ramUtil === undefined || useSettingsStore().metrics.cpuMem === undefined
? "Unknown"
: `${useSettingsStore().metrics.ramUtil || "Unknown"}MB of ${useSettingsStore().metrics.cpuMem}MB`
metrics.ramUtil && metrics.ramMem && metrics.ramUtil >= 0 && metrics.ramMem >= 0
? `${metrics.ramUtil}MB of ${metrics.ramMem}MB`
: "Unknown"
},
{
header: "GPU Memory Usage",
value:
useSettingsStore().metrics.gpuMemUtil === undefined || useSettingsStore().metrics.gpuMem === undefined
? "Unknown"
: `${useSettingsStore().metrics.gpuMemUtil}MB of ${useSettingsStore().metrics.gpuMem}MB`
},
{
header: "CPU Throttling",
value: useSettingsStore().metrics.cpuThr || "Unknown"
},
{
header: "CPU Uptime",
value: useSettingsStore().metrics.cpuUptime || "Unknown"
header: "Uptime",
value: (() => {
const seconds = metrics.uptime;
if (seconds === undefined) return "Unknown";

const days = Math.floor(seconds / 86400);
const hours = Math.floor((seconds % 86400) / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const secs = Math.floor(seconds % 60);

return durationFormatter.format({
days: days,
hours: hours,
minutes: minutes,
seconds: secs
});
})()
},
{
header: "Disk Usage",
value: useSettingsStore().metrics.diskUtilPct || "Unknown"
value: metrics.diskUtilPct === undefined ? "Unknown" : `${metrics.diskUtilPct}%`
}
];

if (useSettingsStore().metrics.npuUsage) {
if (metrics.npuUsage && metrics.npuUsage.length > 0) {
stats.push({
header: "NPU Usage",
value: useSettingsStore().metrics.npuUsage || "Unknown"
value: metrics.npuUsage?.map((usage, index) => `Core${index} ${usage}%`).join(", ") || "Unknown"
});
}

if (metrics.gpuMem && metrics.gpuMemUtil && metrics.gpuMem > 0 && metrics.gpuMemUtil > 0) {
stats.push({
header: "GPU Memory Usage",
value: `${metrics.gpuMemUtil}MB of ${metrics.gpuMem}MB`
});
}

if (metrics.cpuThr) {
stats.push({
header: "CPU Throttling",
value: metrics.cpuThr.toString()
});
}

Expand Down
20 changes: 10 additions & 10 deletions photon-client/src/stores/settings/GeneralSettingsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ export const useSettingsStore = defineStore("settings", {
metrics: {
cpuTemp: undefined,
cpuUtil: undefined,
cpuMem: undefined,
gpuMem: undefined,
cpuThr: undefined,
ramMem: undefined,
ramUtil: undefined,
gpuMem: undefined,
gpuMemUtil: undefined,
cpuThr: undefined,
cpuUptime: undefined,
diskUtilPct: undefined,
npuUsage: undefined,
ipAddress: undefined
ipAddress: undefined,
uptime: undefined
},
currentFieldLayout: {
field: {
Expand All @@ -90,15 +90,15 @@ export const useSettingsStore = defineStore("settings", {
this.metrics = {
cpuTemp: data.cpuTemp || undefined,
cpuUtil: data.cpuUtil || undefined,
cpuMem: data.cpuMem || undefined,
gpuMem: data.gpuMem || undefined,
cpuThr: data.cpuThr || undefined,
ramMem: data.ramMem || undefined,
ramUtil: data.ramUtil || undefined,
gpuMem: data.gpuMem || undefined,
gpuMemUtil: data.gpuMemUtil || undefined,
cpuThr: data.cpuThr || undefined,
cpuUptime: data.cpuUptime || undefined,
diskUtilPct: data.diskUtilPct || undefined,
npuUsage: data.npuUsage || undefined,
ipAddress: data.ipAddress || undefined
ipAddress: data.ipAddress || undefined,
uptime: data.uptime || undefined
};
},
updateGeneralSettingsFromWebsocket(data: WebsocketSettingsUpdate) {
Expand Down
18 changes: 9 additions & 9 deletions photon-client/src/types/SettingTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@ export interface ObjectDetectionModelProperties {
}

export interface MetricData {
cpuTemp?: string;
cpuUtil?: string;
cpuMem?: string;
gpuMem?: string;
ramUtil?: string;
gpuMemUtil?: string;
cpuTemp?: number;
cpuUtil?: number;
cpuThr?: string;
cpuUptime?: string;
diskUtilPct?: string;
npuUsage?: string;
ramMem?: number;
ramUtil?: number;
gpuMem?: number;
gpuMemUtil?: number;
diskUtilPct?: number;
npuUsage?: number[];
ipAddress?: string;
uptime?: number;
}

export enum NetworkConnectionType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ public class NetworkTablesManager {

private final NetworkTableInstance ntInstance = NetworkTableInstance.getDefault();
private final String kRootTableName = "/photonvision";
private final String kCoprocTableName = "coprocessors";
public final String kCoprocTableName = "coprocessors";
private final String kFieldLayoutName = "apriltag_field_layout";
public final NetworkTable kRootTable = ntInstance.getTable(kRootTableName);

// This is used to subscribe to all coprocessor tables, so we can detect conflicts
@SuppressWarnings("unused")
private final MultiSubscriber sub =
new MultiSubscriber(ntInstance, new String[] {kRootTableName + "/" + kCoprocTableName + "/"});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ private HardwareManager(HardwareConfig hardwareConfig, HardwareSettings hardware
this.metricsManager = new MetricsManager();
this.metricsManager.setConfig(hardwareConfig);

TimedTaskManager.getInstance()
.addTask("Metrics Publisher", this.metricsManager::publishMetrics, 5000);

ledModeRequest =
NetworkTablesManager.getInstance()
.kRootTable
Expand Down Expand Up @@ -222,10 +225,6 @@ private void statusLEDUpdate() {
blinkCounter++;
}

public HardwareConfig getConfig() {
return hardwareConfig;
}

public void publishMetrics() {
metricsManager.publishMetrics();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (C) Photon Vision.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package org.photonvision.common.hardware.metrics;

import org.photonvision.common.hardware.metrics.proto.DeviceMetricsProto;

public record DeviceMetrics(
double cpuTemp,
double cpuUtil,
String cpuThr,
double ramMem,
double ramUtil,
double gpuMem,
double gpuMemUtil,
double diskUtilPct,
double[] npuUsage,
String ipAddress,
double uptime) {
public static final DeviceMetricsProto proto = new DeviceMetricsProto();
}
Loading
Loading