2022-06-11 01:02:05 +01:00
|
|
|
import {
|
2022-09-01 01:18:15 +01:00
|
|
|
ButtonItem,
|
2022-06-11 01:02:05 +01:00
|
|
|
definePlugin,
|
2022-09-01 01:18:15 +01:00
|
|
|
//DialogButton,
|
2022-06-11 01:02:05 +01:00
|
|
|
//Menu,
|
|
|
|
//MenuItem,
|
|
|
|
PanelSection,
|
|
|
|
PanelSectionRow,
|
|
|
|
ServerAPI,
|
|
|
|
//showContextMenu,
|
|
|
|
staticClasses,
|
2023-01-08 01:07:26 +00:00
|
|
|
//SliderField,
|
2022-07-04 22:12:13 +01:00
|
|
|
ToggleField,
|
2023-01-08 01:07:26 +00:00
|
|
|
//Dropdown,
|
2022-11-14 02:18:48 +00:00
|
|
|
Field,
|
|
|
|
//DropdownOption,
|
2023-01-08 01:07:26 +00:00
|
|
|
//SingleDropdownOption,
|
2022-06-11 01:02:05 +01:00
|
|
|
//NotchLabel
|
2022-11-19 20:21:09 +00:00
|
|
|
//gamepadDialogClasses,
|
|
|
|
//joinClassNames,
|
2022-06-11 01:02:05 +01:00
|
|
|
} from "decky-frontend-lib";
|
|
|
|
import { VFC, useState } from "react";
|
2023-03-04 15:32:58 +00:00
|
|
|
import { GiDrill, GiTimeBomb, GiTimeTrap, GiDynamite } from "react-icons/gi";
|
2023-03-25 17:46:58 +00:00
|
|
|
import { HiRefresh, HiTrash } from "react-icons/hi";
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2022-09-01 01:18:15 +01:00
|
|
|
//import * as python from "./python";
|
|
|
|
import * as backend from "./backend";
|
2023-01-11 01:54:33 +00:00
|
|
|
import { tr } from "usdpl-front";
|
2023-01-07 23:45:12 +00:00
|
|
|
import {
|
|
|
|
BACKEND_INFO,
|
|
|
|
DRIVER_INFO,
|
|
|
|
|
|
|
|
LIMITS_INFO,
|
|
|
|
|
|
|
|
CURRENT_BATT,
|
|
|
|
CHARGE_RATE_BATT,
|
|
|
|
CHARGE_MODE_BATT,
|
2023-03-26 15:49:17 +01:00
|
|
|
CHARGE_LIMIT_BATT,
|
2023-01-07 23:45:12 +00:00
|
|
|
CHARGE_NOW_BATT,
|
|
|
|
CHARGE_FULL_BATT,
|
|
|
|
CHARGE_DESIGN_BATT,
|
|
|
|
|
|
|
|
ONLINE_CPUS,
|
|
|
|
ONLINE_STATUS_CPUS,
|
|
|
|
SMT_CPU,
|
|
|
|
CLOCK_MIN_CPU,
|
|
|
|
CLOCK_MAX_CPU,
|
|
|
|
CLOCK_MIN_MAX_CPU,
|
|
|
|
GOVERNOR_CPU,
|
|
|
|
|
|
|
|
FAST_PPT_GPU,
|
|
|
|
SLOW_PPT_GPU,
|
|
|
|
CLOCK_MIN_GPU,
|
|
|
|
CLOCK_MAX_GPU,
|
|
|
|
SLOW_MEMORY_GPU,
|
|
|
|
|
|
|
|
PERSISTENT_GEN,
|
|
|
|
NAME_GEN,
|
2023-03-25 17:46:58 +00:00
|
|
|
PATH_GEN,
|
2023-01-07 23:45:12 +00:00
|
|
|
} from "./consts";
|
2023-01-08 01:07:26 +00:00
|
|
|
import { set_value, get_value } from "usdpl-front";
|
|
|
|
import { Debug } from "./components/debug";
|
|
|
|
import { Gpu } from "./components/gpu";
|
|
|
|
import { Battery } from "./components/battery";
|
|
|
|
import { Cpus } from "./components/cpus";
|
2022-06-11 01:02:05 +01:00
|
|
|
|
|
|
|
var periodicHook: NodeJS.Timer | null = null;
|
|
|
|
var lifetimeHook: any = null;
|
|
|
|
var startHook: any = null;
|
2022-09-01 01:18:15 +01:00
|
|
|
var usdplReady = false;
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2022-11-14 02:18:48 +00:00
|
|
|
type MinMax = {
|
|
|
|
min: number | null;
|
|
|
|
max: number | null;
|
|
|
|
}
|
|
|
|
|
2022-09-06 02:36:01 +01:00
|
|
|
function countCpus(statii: boolean[]): number {
|
|
|
|
let count = 0;
|
|
|
|
for (let i = 0; i < statii.length; i++) {
|
|
|
|
if (statii[i]) {
|
|
|
|
count += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2022-11-14 02:18:48 +00:00
|
|
|
function syncPlebClockToAdvanced() {
|
2022-11-19 20:21:09 +00:00
|
|
|
const cpuCount = (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.count;
|
2022-11-14 02:18:48 +00:00
|
|
|
const minClock = get_value(CLOCK_MIN_CPU);
|
|
|
|
const maxClock = get_value(CLOCK_MAX_CPU);
|
|
|
|
let clockArr = [];
|
|
|
|
for (let i = 0; i < cpuCount; i++) {
|
|
|
|
clockArr.push({
|
|
|
|
min: minClock,
|
|
|
|
max: maxClock,
|
|
|
|
} as MinMax);
|
|
|
|
}
|
|
|
|
set_value(CLOCK_MIN_MAX_CPU, clockArr);
|
|
|
|
}
|
|
|
|
|
2022-09-01 01:18:15 +01:00
|
|
|
const reload = function() {
|
|
|
|
if (!usdplReady) {return;}
|
2022-07-10 19:04:50 +01:00
|
|
|
|
2022-11-19 20:21:09 +00:00
|
|
|
backend.resolve(backend.getLimits(), (limits) => {
|
|
|
|
set_value(LIMITS_INFO, limits);
|
2023-01-05 00:42:59 +00:00
|
|
|
console.debug("POWERTOOLS: got limits ", limits);
|
2022-11-19 20:21:09 +00:00
|
|
|
});
|
|
|
|
|
2022-09-01 01:18:15 +01:00
|
|
|
backend.resolve(backend.getBatteryCurrent(), (rate: number) => { set_value(CURRENT_BATT, rate) });
|
2023-01-21 23:15:26 +00:00
|
|
|
backend.resolve_nullable(backend.getBatteryChargeRate(), (rate: number | null) => { set_value(CHARGE_RATE_BATT, rate) });
|
|
|
|
backend.resolve_nullable(backend.getBatteryChargeMode(), (mode: string | null) => { set_value(CHARGE_MODE_BATT, mode) });
|
2023-03-26 15:49:17 +01:00
|
|
|
backend.resolve_nullable(backend.getBatteryChargeLimit(), (limit: number | null) => { set_value(CHARGE_LIMIT_BATT, limit) });
|
2022-09-05 22:02:02 +01:00
|
|
|
backend.resolve(backend.getBatteryChargeNow(), (rate: number) => { set_value(CHARGE_NOW_BATT, rate) });
|
|
|
|
backend.resolve(backend.getBatteryChargeFull(), (rate: number) => { set_value(CHARGE_FULL_BATT, rate) });
|
|
|
|
backend.resolve(backend.getBatteryChargeDesign(), (rate: number) => { set_value(CHARGE_DESIGN_BATT, rate) });
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2022-11-19 20:21:09 +00:00
|
|
|
//backend.resolve(backend.getCpuCount(), (count: number) => { set_value(TOTAL_CPUS, count)});
|
2022-09-01 01:18:15 +01:00
|
|
|
backend.resolve(backend.getCpusOnline(), (statii: boolean[]) => {
|
2022-11-14 02:18:48 +00:00
|
|
|
set_value(ONLINE_STATUS_CPUS, statii);
|
2022-09-06 02:36:01 +01:00
|
|
|
const count = countCpus(statii);
|
2022-09-01 01:18:15 +01:00
|
|
|
set_value(ONLINE_CPUS, count);
|
2023-02-04 21:19:00 +00:00
|
|
|
//set_value(SMT_CPU, statii.length > 3 && statii[0] == statii[1] && statii[2] == statii[3]);
|
2022-09-01 01:18:15 +01:00
|
|
|
});
|
2023-01-19 02:05:04 +00:00
|
|
|
backend.resolve(backend.getCpuSmt(), (smt: boolean) => {
|
|
|
|
set_value(SMT_CPU, smt);
|
|
|
|
});
|
2022-09-01 01:18:15 +01:00
|
|
|
backend.resolve(backend.getCpuClockLimits(0), (limits: number[]) => {
|
|
|
|
set_value(CLOCK_MIN_CPU, limits[0]);
|
|
|
|
set_value(CLOCK_MAX_CPU, limits[1]);
|
2022-11-14 02:18:48 +00:00
|
|
|
syncPlebClockToAdvanced();
|
|
|
|
});
|
|
|
|
backend.resolve(backend.getCpusGovernor(), (governors: string[]) => {
|
|
|
|
set_value(GOVERNOR_CPU, governors);
|
2023-01-05 00:42:59 +00:00
|
|
|
backend.log(backend.LogLevel.Info, "POWERTOOLS: Governors from backend " + governors.toString());
|
2022-09-01 01:18:15 +01:00
|
|
|
});
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2022-09-01 01:18:15 +01:00
|
|
|
backend.resolve(backend.getGpuPpt(), (ppts: number[]) => {
|
|
|
|
set_value(FAST_PPT_GPU, ppts[0]);
|
|
|
|
set_value(SLOW_PPT_GPU, ppts[1]);
|
|
|
|
});
|
|
|
|
backend.resolve(backend.getGpuClockLimits(), (limits: number[]) => {
|
|
|
|
set_value(CLOCK_MIN_GPU, limits[0]);
|
|
|
|
set_value(CLOCK_MAX_GPU, limits[1]);
|
|
|
|
});
|
|
|
|
backend.resolve(backend.getGpuSlowMemory(), (status: boolean) => { set_value(SLOW_MEMORY_GPU, status) });
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2022-09-01 01:18:15 +01:00
|
|
|
backend.resolve(backend.getGeneralPersistent(), (value: boolean) => { set_value(PERSISTENT_GEN, value) });
|
|
|
|
backend.resolve(backend.getGeneralSettingsName(), (name: string) => { set_value(NAME_GEN, name) });
|
2023-03-25 17:46:58 +00:00
|
|
|
backend.resolve(backend.getGeneralSettingsPath(), (path: string) => { set_value(PATH_GEN, path) });
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2022-09-01 01:18:15 +01:00
|
|
|
backend.resolve(backend.getInfo(), (info: string) => { set_value(BACKEND_INFO, info) });
|
2023-01-03 02:22:53 +00:00
|
|
|
backend.resolve(backend.getDriverProviderName("gpu"), (driver: string) => { set_value(DRIVER_INFO, driver) });
|
2022-09-01 01:18:15 +01:00
|
|
|
};
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2022-09-01 01:18:15 +01:00
|
|
|
// init USDPL WASM and connection to back-end
|
|
|
|
(async function(){
|
|
|
|
await backend.initBackend();
|
|
|
|
usdplReady = true;
|
|
|
|
reload(); // technically this is only a load
|
2022-07-05 23:14:50 +01:00
|
|
|
|
2022-09-01 01:18:15 +01:00
|
|
|
// register Steam callbacks
|
|
|
|
//@ts-ignore
|
|
|
|
lifetimeHook = SteamClient.GameSessions.RegisterForAppLifetimeNotifications((update) => {
|
2023-03-27 02:16:13 +01:00
|
|
|
backend.log(backend.LogLevel.Info, "RegisterForAppLifetimeNotifications callback(" + JSON.stringify(update, null, 2) + ")");
|
2022-09-01 01:18:15 +01:00
|
|
|
if (update.bRunning) {
|
2023-01-05 00:42:59 +00:00
|
|
|
//backend.log(backend.LogLevel.Debug, "AppID " + update.unAppID.toString() + " is now running");
|
2022-09-01 01:18:15 +01:00
|
|
|
} else {
|
2023-01-05 00:42:59 +00:00
|
|
|
//backend.log(backend.LogLevel.Debug, "AppID " + update.unAppID.toString() + " is no longer running");
|
2022-09-01 01:18:15 +01:00
|
|
|
backend.resolve(
|
|
|
|
backend.loadGeneralDefaultSettings(),
|
2023-01-05 00:42:59 +00:00
|
|
|
(ok: boolean) => {backend.log(backend.LogLevel.Debug, "Loading default settings ok? " + ok)}
|
2022-09-01 01:18:15 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
//@ts-ignore
|
|
|
|
startHook = SteamClient.Apps.RegisterForGameActionStart((actionType, id) => {
|
|
|
|
//@ts-ignore
|
|
|
|
let gameInfo: any = appStore.GetAppOverviewByGameID(id);
|
2023-03-27 02:16:13 +01:00
|
|
|
|
|
|
|
backend.log(backend.LogLevel.Info, "RegisterForGameActionStart callback(" + actionType + ", " + id + ")");
|
2022-09-09 01:01:01 +01:00
|
|
|
// don't use gameInfo.appid, haha
|
2022-09-01 01:18:15 +01:00
|
|
|
backend.resolve(
|
2023-03-31 22:25:29 +01:00
|
|
|
backend.loadGeneralSettings(id.toString(), gameInfo.display_name),
|
2023-01-05 00:42:59 +00:00
|
|
|
(ok: boolean) => {backend.log(backend.LogLevel.Debug, "Loading settings ok? " + ok)}
|
2022-09-01 01:18:15 +01:00
|
|
|
);
|
|
|
|
});
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2023-01-05 00:42:59 +00:00
|
|
|
backend.log(backend.LogLevel.Debug, "Registered PowerTools callbacks, hello!");
|
2022-09-01 01:18:15 +01:00
|
|
|
})();
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2022-09-01 01:18:15 +01:00
|
|
|
const periodicals = function() {
|
|
|
|
backend.resolve(backend.getBatteryCurrent(), (rate: number) => { set_value(CURRENT_BATT, rate) });
|
2022-09-05 22:02:02 +01:00
|
|
|
backend.resolve(backend.getBatteryChargeNow(), (rate: number) => { set_value(CHARGE_NOW_BATT, rate) });
|
|
|
|
backend.resolve(backend.getBatteryChargeFull(), (rate: number) => { set_value(CHARGE_FULL_BATT, rate) });
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2023-03-25 17:46:58 +00:00
|
|
|
backend.resolve(backend.getGeneralSettingsPath(), (path: string) => {
|
|
|
|
const oldValue = get_value(PATH_GEN);
|
|
|
|
set_value(PATH_GEN, path);
|
|
|
|
if (path != oldValue) {
|
|
|
|
backend.log(backend.LogLevel.Info, "Frontend values reload triggered by path change: " + oldValue + " -> " + path);
|
2022-09-01 01:18:15 +01:00
|
|
|
reload();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2022-09-01 01:18:15 +01:00
|
|
|
const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2023-02-04 21:19:00 +00:00
|
|
|
const [idc, reloadGUI] = useState<any>("/shrug");
|
2022-06-11 01:02:05 +01:00
|
|
|
|
2022-07-10 19:04:50 +01:00
|
|
|
if (periodicHook != null) {
|
|
|
|
clearInterval(periodicHook);
|
|
|
|
periodicHook = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
periodicHook = setInterval(function() {
|
2022-09-01 01:18:15 +01:00
|
|
|
periodicals();
|
|
|
|
reloadGUI("periodic" + (new Date()).getTime().toString());
|
2022-07-10 19:04:50 +01:00
|
|
|
}, 1000);
|
|
|
|
|
2023-02-12 00:59:27 +00:00
|
|
|
if (!usdplReady || !get_value(LIMITS_INFO)) {
|
|
|
|
// Not translated on purpose (to avoid USDPL issues)
|
|
|
|
return (
|
|
|
|
<PanelSection>
|
|
|
|
USDPL or PowerTools's backend did not start correctly!
|
|
|
|
<ButtonItem
|
|
|
|
layout="below"
|
|
|
|
onClick={(_: MouseEvent) => {
|
|
|
|
console.log("POWERTOOLS: manual reload after startup failure");
|
|
|
|
reload();
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
Reload
|
|
|
|
</ButtonItem>
|
|
|
|
</PanelSection>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-06-11 01:02:05 +01:00
|
|
|
return (
|
|
|
|
<PanelSection>
|
2023-02-04 21:19:00 +00:00
|
|
|
<Cpus idc={idc}/>
|
2022-11-19 20:21:09 +00:00
|
|
|
|
2023-02-04 21:19:00 +00:00
|
|
|
<Gpu idc={idc}/>
|
2023-01-07 23:45:12 +00:00
|
|
|
|
2023-02-04 21:19:00 +00:00
|
|
|
<Battery idc={idc}/>
|
2023-01-08 01:07:26 +00:00
|
|
|
|
|
|
|
|
2022-06-11 01:02:05 +01:00
|
|
|
{/* Persistence */}
|
2022-09-01 01:18:15 +01:00
|
|
|
<div className={staticClasses.PanelSectionTitle}>
|
2023-01-11 01:54:33 +00:00
|
|
|
{tr("Miscellaneous")}
|
2022-09-01 01:18:15 +01:00
|
|
|
</div>
|
2022-06-11 01:02:05 +01:00
|
|
|
<PanelSectionRow>
|
2022-07-04 22:12:13 +01:00
|
|
|
<ToggleField
|
2022-09-01 01:18:15 +01:00
|
|
|
checked={get_value(PERSISTENT_GEN)}
|
2023-02-03 22:03:50 +00:00
|
|
|
label={tr("Persistent Profile")}
|
2023-01-11 01:54:33 +00:00
|
|
|
description={tr("Save profile and load it next time")}
|
2022-06-11 01:02:05 +01:00
|
|
|
onChange={(persist: boolean) => {
|
2023-01-05 00:42:59 +00:00
|
|
|
backend.log(backend.LogLevel.Debug, "Persist is now " + persist.toString());
|
2022-09-01 01:18:15 +01:00
|
|
|
backend.resolve(
|
|
|
|
backend.setGeneralPersistent(persist),
|
|
|
|
(val: boolean) => {set_value(PERSISTENT_GEN, val)}
|
|
|
|
);
|
2022-06-11 01:02:05 +01:00
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</PanelSectionRow>
|
|
|
|
<PanelSectionRow>
|
2022-11-19 20:21:09 +00:00
|
|
|
<Field
|
2023-01-11 01:54:33 +00:00
|
|
|
label={tr("Profile")}>
|
2022-11-19 20:21:09 +00:00
|
|
|
{get_value(NAME_GEN)}
|
|
|
|
</Field>
|
2022-06-11 01:02:05 +01:00
|
|
|
</PanelSectionRow>
|
2023-01-07 23:45:12 +00:00
|
|
|
|
2023-02-04 21:19:00 +00:00
|
|
|
<Debug idc={idc}/>
|
2023-01-07 23:45:12 +00:00
|
|
|
|
2023-03-23 02:15:36 +00:00
|
|
|
<PanelSectionRow>
|
|
|
|
<ButtonItem
|
|
|
|
layout="below"
|
|
|
|
onClick={(_: MouseEvent) => {
|
|
|
|
backend.log(backend.LogLevel.Debug, "Reapplying PowerTools settings");
|
|
|
|
backend.forceApplySettings();
|
|
|
|
}}
|
|
|
|
>
|
2023-03-25 17:46:58 +00:00
|
|
|
<HiRefresh /> {tr("Reapply settings")}
|
2023-03-23 02:15:36 +00:00
|
|
|
</ButtonItem>
|
|
|
|
</PanelSectionRow>
|
|
|
|
|
2022-09-01 01:18:15 +01:00
|
|
|
<PanelSectionRow>
|
|
|
|
<ButtonItem
|
|
|
|
layout="below"
|
|
|
|
onClick={(_: MouseEvent) => {
|
2023-01-05 00:42:59 +00:00
|
|
|
backend.log(backend.LogLevel.Debug, "Loading default PowerTools settings");
|
2022-09-01 01:18:15 +01:00
|
|
|
backend.resolve(
|
|
|
|
backend.setGeneralPersistent(false),
|
|
|
|
(val: boolean) => {
|
|
|
|
set_value(PERSISTENT_GEN, val);
|
2022-11-13 17:41:45 +00:00
|
|
|
backend.resolve(backend.loadGeneralSystemSettings(), (_) => {
|
2022-09-01 01:18:15 +01:00
|
|
|
reload();
|
2022-11-13 17:41:45 +00:00
|
|
|
backend.resolve(backend.waitForComplete(), (_) => {reloadGUI("LoadSystemDefaults")});
|
2022-09-01 01:18:15 +01:00
|
|
|
});
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}}
|
|
|
|
>
|
2023-03-25 17:46:58 +00:00
|
|
|
<HiTrash /> {tr("Defaults")}
|
2022-09-01 01:18:15 +01:00
|
|
|
</ButtonItem>
|
|
|
|
</PanelSectionRow>
|
2022-06-11 01:02:05 +01:00
|
|
|
</PanelSection>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default definePlugin((serverApi: ServerAPI) => {
|
2023-03-04 15:32:58 +00:00
|
|
|
let ico = <GiDrill />;
|
|
|
|
let now = new Date();
|
|
|
|
if (now.getDate() == 1 && now.getMonth() == 3) {
|
|
|
|
ico = <span><GiDynamite /><GiTimeTrap /><GiTimeBomb /></span>;
|
|
|
|
}
|
2022-06-11 01:02:05 +01:00
|
|
|
return {
|
2023-02-24 02:07:17 +00:00
|
|
|
title: <div className={staticClasses.Title}>I'm a tool</div>,
|
2022-06-11 01:02:05 +01:00
|
|
|
content: <Content serverAPI={serverApi} />,
|
2023-03-04 15:32:58 +00:00
|
|
|
icon: ico,
|
2022-06-11 01:02:05 +01:00
|
|
|
onDismount() {
|
2023-01-05 00:42:59 +00:00
|
|
|
backend.log(backend.LogLevel.Debug, "PowerTools shutting down");
|
2022-06-11 01:02:05 +01:00
|
|
|
clearInterval(periodicHook!);
|
2022-07-10 19:04:50 +01:00
|
|
|
periodicHook = null;
|
2022-07-05 23:14:50 +01:00
|
|
|
lifetimeHook!.unregister();
|
|
|
|
startHook!.unregister();
|
2023-02-26 18:04:09 +00:00
|
|
|
//serverApi.routerHook.removeRoute("/decky-plugin-test");
|
2023-01-11 01:54:33 +00:00
|
|
|
backend.log(backend.LogLevel.Debug, "Unregistered PowerTools callbacks, so long and thanks for all the fish.");
|
2022-06-11 01:02:05 +01:00
|
|
|
},
|
|
|
|
};
|
|
|
|
});
|