feat: support GPU combinations on the GPU Graph action
This commit is contained in:
@@ -14,6 +14,9 @@
|
|||||||
<sdpi-item label="GPU">
|
<sdpi-item label="GPU">
|
||||||
<sdpi-select setting="gpuId" datasource="gpus" loading="Loading GPUs…" hot-reload default="all" placeholder="Select a GPU" />
|
<sdpi-select setting="gpuId" datasource="gpus" loading="Loading GPUs…" hot-reload default="all" placeholder="Select a GPU" />
|
||||||
</sdpi-item>
|
</sdpi-item>
|
||||||
|
<sdpi-item label="GPU combination">
|
||||||
|
<sdpi-textfield setting="gpuCombo" placeholder="e.g. 0,2 (overrides GPU)" />
|
||||||
|
</sdpi-item>
|
||||||
<sdpi-item label="Metric">
|
<sdpi-item label="Metric">
|
||||||
<sdpi-select setting="metric" default="util_percent" placeholder="Select a metric">
|
<sdpi-select setting="metric" default="util_percent" placeholder="Select a metric">
|
||||||
<option value="util_percent">Utilization %</option>
|
<option value="util_percent">Utilization %</option>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import streamDeck, {
|
|||||||
type WillDisappearEvent,
|
type WillDisappearEvent,
|
||||||
} from "@elgato/streamdeck";
|
} from "@elgato/streamdeck";
|
||||||
import { type GpuMetricKind } from "../lib/metrics-parser";
|
import { type GpuMetricKind } from "../lib/metrics-parser";
|
||||||
|
import { combineSeries } from "../lib/metrics-poller";
|
||||||
import { renderGpuGraph, svgDataUrl } from "../lib/render";
|
import { renderGpuGraph, svgDataUrl } from "../lib/render";
|
||||||
import { runtime } from "../lib/runtime";
|
import { runtime } from "../lib/runtime";
|
||||||
import { cfgFromSettings, type CfgSettings } from "../lib/util";
|
import { cfgFromSettings, type CfgSettings } from "../lib/util";
|
||||||
@@ -15,6 +16,7 @@ import { cfgFromSettings, type CfgSettings } from "../lib/util";
|
|||||||
type GpuSettings = CfgSettings & {
|
type GpuSettings = CfgSettings & {
|
||||||
gpuId?: string;
|
gpuId?: string;
|
||||||
metric?: GpuMetricKind;
|
metric?: GpuMetricKind;
|
||||||
|
gpuCombo?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type GpuState = {
|
type GpuState = {
|
||||||
@@ -71,12 +73,28 @@ export class GpuGraph extends SingletonAction<GpuSettings> {
|
|||||||
const action = state.action;
|
const action = state.action;
|
||||||
if (!action) return;
|
if (!action) return;
|
||||||
const poller = runtime.pollerInstance;
|
const poller = runtime.pollerInstance;
|
||||||
const gpuId = state.settings.gpuId ?? "all";
|
|
||||||
const metric = state.settings.metric ?? "util_percent";
|
const metric = state.settings.metric ?? "util_percent";
|
||||||
const value = poller?.getValue(gpuId, metric);
|
const combo = parseCombo(state.settings.gpuCombo);
|
||||||
const history = poller?.getHistory(gpuId, metric) ?? [];
|
|
||||||
const offline = !poller || poller.isOffline();
|
const offline = !poller || poller.isOffline();
|
||||||
const gpuName = gpuId === "all" ? "ALL GPUS" : this.gpuLabel(gpuId);
|
|
||||||
|
let value: number | undefined;
|
||||||
|
let history: number[] = [];
|
||||||
|
let gpuName: string;
|
||||||
|
if (combo) {
|
||||||
|
const known = new Set((poller?.gpus() ?? []).map((g) => g.id));
|
||||||
|
const ids = combo.filter((id) => known.has(id));
|
||||||
|
const histories = ids.map((id) => poller?.getHistory(id, metric) ?? []);
|
||||||
|
const combined = combineSeries(histories, metric);
|
||||||
|
value = combined.value;
|
||||||
|
history = combined.history;
|
||||||
|
gpuName = `GPU ${ids.join("+")}`;
|
||||||
|
} else {
|
||||||
|
const gpuId = state.settings.gpuId ?? "all";
|
||||||
|
value = poller?.getValue(gpuId, metric);
|
||||||
|
history = poller?.getHistory(gpuId, metric) ?? [];
|
||||||
|
gpuName = gpuId === "all" ? "ALL GPUS" : this.gpuLabel(gpuId);
|
||||||
|
}
|
||||||
|
|
||||||
const svg = renderGpuGraph({ gpuName, metric, value, history, offline });
|
const svg = renderGpuGraph({ gpuName, metric, value, history, offline });
|
||||||
if (svg === state.lastSvg) return;
|
if (svg === state.lastSvg) return;
|
||||||
state.lastSvg = svg;
|
state.lastSvg = svg;
|
||||||
@@ -88,3 +106,11 @@ export class GpuGraph extends SingletonAction<GpuSettings> {
|
|||||||
return gpu && gpu.name ? `GPU ${gpuId} · ${gpu.name}` : `GPU ${gpuId}`;
|
return gpu && gpu.name ? `GPU ${gpuId} · ${gpu.name}` : `GPU ${gpuId}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseCombo(raw: string | undefined): string[] | undefined {
|
||||||
|
const ids = (raw ?? "")
|
||||||
|
.split(",")
|
||||||
|
.map((s) => s.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
return ids.length > 0 ? ids : undefined;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user