UI Upgrade, add max frequency slider
This commit is contained in:
parent
67087f9ef2
commit
dc625f023e
5 changed files with 145 additions and 47 deletions
|
@ -1,6 +1,8 @@
|
||||||
# PowerTools
|
# PowerTools
|
||||||
|
|
||||||
Power tweaks for Steam Deck.
|
![plugin_demo](https://raw.githubusercontent.com/NGnius/PowerTools/master/extras/ui.png)
|
||||||
|
|
||||||
|
Steam Deck power tweaks for power users.
|
||||||
|
|
||||||
This is generated from the template plugin for the [SteamOS Plugin Loader](https://github.com/SteamDeckHomebrew/PluginLoader).
|
This is generated from the template plugin for the [SteamOS Plugin Loader](https://github.com/SteamDeckHomebrew/PluginLoader).
|
||||||
|
|
||||||
|
|
BIN
extras/ui.png
Normal file
BIN
extras/ui.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 119 KiB |
27
main.py
27
main.py
|
@ -2,6 +2,7 @@ import time
|
||||||
|
|
||||||
class Plugin:
|
class Plugin:
|
||||||
CPU_COUNT = 8
|
CPU_COUNT = 8
|
||||||
|
SCALING_FREQUENCIES = [1700000, 2400000, 2800000]
|
||||||
|
|
||||||
# call from main_view.html with setCPUs(onclick_event) or call_plugin_method("set_cpus", count)
|
# call from main_view.html with setCPUs(onclick_event) or call_plugin_method("set_cpus", count)
|
||||||
async def set_cpus(self, count) -> int:
|
async def set_cpus(self, count) -> int:
|
||||||
|
@ -32,6 +33,23 @@ class Plugin:
|
||||||
async def get_boost(self) -> bool:
|
async def get_boost(self) -> bool:
|
||||||
return read_from_sys("/sys/devices/system/cpu/cpufreq/boost") == "1"
|
return read_from_sys("/sys/devices/system/cpu/cpufreq/boost") == "1"
|
||||||
|
|
||||||
|
async def set_max_boost(self, index) -> int:
|
||||||
|
if index >= len(self.SCALING_FREQUENCIES):
|
||||||
|
return False
|
||||||
|
selected_freq = self.SCALING_FREQUENCIES[index]
|
||||||
|
updated = 0
|
||||||
|
for cpu in range(0, self.CPU_COUNT):
|
||||||
|
if cpu == 0 or status_cpu(cpu):
|
||||||
|
path = cpu_freq_scaling_path(cpu)
|
||||||
|
write_to_sys(path, selected_freq)
|
||||||
|
updated += 1
|
||||||
|
return updated
|
||||||
|
|
||||||
|
async def get_max_boost(self) -> int:
|
||||||
|
path = cpu_freq_scaling_path(0)
|
||||||
|
freq = int(read_from_sys(path, amount=-1).strip())
|
||||||
|
return self.SCALING_FREQUENCIES.index(freq)
|
||||||
|
|
||||||
# Asyncio-compatible long-running code, executed in a task when the plugin is loaded
|
# Asyncio-compatible long-running code, executed in a task when the plugin is loaded
|
||||||
async def _main(self):
|
async def _main(self):
|
||||||
with open("/home/deck/PowerTools.log", "w") as f:
|
with open("/home/deck/PowerTools.log", "w") as f:
|
||||||
|
@ -42,15 +60,18 @@ class Plugin:
|
||||||
# these are stateless (well, the state is not saved internally) functions, so there's no need for these to be called like a class method
|
# these are stateless (well, the state is not saved internally) functions, so there's no need for these to be called like a class method
|
||||||
|
|
||||||
def cpu_online_path(cpu_number: int) -> str:
|
def cpu_online_path(cpu_number: int) -> str:
|
||||||
return f"/sys/devices/system/cpu/cpu{cpu_number}/online"
|
return f"/sys/devices/system/cpu/cpu{cpu_number}/online"
|
||||||
|
|
||||||
|
def cpu_freq_scaling_path(cpu_number: int) -> str:
|
||||||
|
return f"/sys/devices/system/cpu/cpu{cpu_number}/cpufreq/scaling_setspeed"
|
||||||
|
|
||||||
def write_to_sys(path, value: int):
|
def write_to_sys(path, value: int):
|
||||||
with open(path, mode="w") as f:
|
with open(path, mode="w") as f:
|
||||||
f.write(str(value))
|
f.write(str(value))
|
||||||
|
|
||||||
def read_from_sys(path):
|
def read_from_sys(path, amount=1):
|
||||||
with open(path, mode="r") as f:
|
with open(path, mode="r") as f:
|
||||||
return f.read(1)
|
return f.read(amount)
|
||||||
|
|
||||||
def enable_cpu(cpu_number: int):
|
def enable_cpu(cpu_number: int):
|
||||||
filepath = cpu_online_path(cpu_number)
|
filepath = cpu_online_path(cpu_number)
|
||||||
|
|
157
main_view.html
157
main_view.html
|
@ -22,40 +22,27 @@
|
||||||
return call_plugin_method("get_boost", {});
|
return call_plugin_method("get_boost", {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setMaxBoost(index) {
|
||||||
|
return call_plugin_method("set_max_boost", {"index": index});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMaxBoost() {
|
||||||
|
return call_plugin_method("get_max_boost", {});
|
||||||
|
}
|
||||||
|
|
||||||
// other logic
|
// other logic
|
||||||
|
|
||||||
async function onSetCPUs() {
|
|
||||||
let target = document.getElementById("cpu_threads");
|
|
||||||
let ok = await setCPUs(target.value);
|
|
||||||
target.value = await getCPUs();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function onReady() {
|
async function onReady() {
|
||||||
document.getElementById("cpu_threads").value = await getCPUs();
|
|
||||||
let boostToggle = document.getElementById("boostToggle");
|
let boostToggle = document.getElementById("boostToggle");
|
||||||
setToggleState(boostToggle, await getCPUBoost());
|
setToggleState(boostToggle, await getCPUBoost());
|
||||||
|
selectNotch("cpuThreadsNotch", await getCPUs() - 1, 8);
|
||||||
|
selectNotch("frequencyNotch", await getMaxBoost(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function decrementCPUs() {
|
async function setCPUNotch(index) {
|
||||||
let target = document.getElementById("cpu_threads");
|
const ROOT_ID = "cpuThreadsNotch";
|
||||||
if (target.value >= 2) {
|
await setCPUs(index);
|
||||||
target.value -= 1;
|
selectNotch(ROOT_ID, await getCPUs() - 1, 8);
|
||||||
}
|
|
||||||
await onSetCPUs();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function incrementCPUs() {
|
|
||||||
let target = document.getElementById("cpu_threads");
|
|
||||||
if (target.value <= 7) {
|
|
||||||
target.value += 1;
|
|
||||||
}
|
|
||||||
await onSetCPUs();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function resetCPUs() {
|
|
||||||
let target = document.getElementById("cpu_threads");
|
|
||||||
target.value = 8;
|
|
||||||
await onSetCPUs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setToggleState(toggle, state) {
|
function setToggleState(toggle, state) {
|
||||||
|
@ -80,28 +67,86 @@
|
||||||
setToggleState(toggle, await getCPUBoost());
|
setToggleState(toggle, await getCPUBoost());
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
async function setBoostNotch(index) {
|
||||||
<style type="text/css" media="screen">
|
const ROOT_ID = "frequencyNotch";
|
||||||
input::-webkit-outer-spin-button,
|
await setMaxBoost(index);
|
||||||
input::-webkit-inner-spin-button {
|
selectNotch(ROOT_ID, await getMaxBoost(), 3);
|
||||||
-webkit-appearance: none;
|
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
function selectNotch(rootId, index, elements) {
|
||||||
|
// WARNING: this yeets any style in div of slider
|
||||||
|
const ENABLED_CLASS = "gamepadslider_TickActive_j418S";
|
||||||
|
//console.log("Selecting notches up to " + index);
|
||||||
|
let root = document.getElementById(rootId);
|
||||||
|
root.style = "--normalized-slider-value:" + index/(elements-1) + ";";
|
||||||
|
for (let i = 0; i < elements; i++) {
|
||||||
|
let notch = document.getElementById(rootId + i);
|
||||||
|
if (notch.classList.contains(ENABLED_CLASS) && i > index) {
|
||||||
|
notch.classList.remove(ENABLED_CLASS);
|
||||||
|
} else if (!notch.classList.contains(ENABLED_CLASS) && i <= index) {
|
||||||
|
notch.classList.add(ENABLED_CLASS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style type="text/css" media="screen"></style>
|
||||||
</head>
|
</head>
|
||||||
<body onload="onReady()">
|
<body onload="onReady()">
|
||||||
<div>
|
<!-- CPUs selector -->
|
||||||
<label for="cpu_threads">Online CPUs</label>
|
<div class="gamepaddialog_Field_eKmEX gamepaddialog_WithFirstRow_2bDqk gamepaddialog_WithChildrenBelow_37xzV gamepaddialog_InlineWrapShiftsChildrenBelow_3LCXh gamepaddialog_WithBottomSeparator_3YKpU gamepaddialog_ChildrenWidthFixed_ljcbL gamepaddialog_ExtraPaddingOnChildrenBelow_3nLNL gamepaddialog_StandardPadding_xIITX gamepaddialog_HighlightOnFocus_2HFrm Panel Focusable">
|
||||||
<input type="number" id="cpu_threads" name="cpu_threads" min="1" max="8">
|
<div class="gamepaddialog_FieldLabelRow_2VcTl">
|
||||||
<button type="button" onclick="incrementCPUs()">/\</button>
|
<div class="gamepaddialog_FieldLabel_3jMlJ">Threads</div>
|
||||||
<button type="button" onclick="decrementCPUs()">\/</button>
|
</div>
|
||||||
<button type="button" onclick="resetCPUs()">Reset</button>
|
<div id="cpuThreadsNotch" class="gamepadslider_SliderControlAndNotches_23hjX Focusable" tabindex="0" style="--normalized-slider-value:0.5;">
|
||||||
|
<div class="gamepadslider_SliderControl_1udlG">
|
||||||
|
<div class="gamepadslider_SliderTrack_2_vG6 gamepadslider_SliderHasNotches_1Lr71 "></div>
|
||||||
|
<div class="gamepadslider_SliderHandleContainer_8xNY6">
|
||||||
|
<div class="gamepadslider_SliderHandle_11PBf"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotchContainer_2yM7S Panel Focusable">
|
||||||
|
<div class="gamepadslider_SliderNotch_LYPXt">
|
||||||
|
<div id="cpuThreadsNotch0" class="gamepadslider_SliderNotchTick_u8QEa" onclick='setCPUNotch(1)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_dbACW">1</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_LYPXt">
|
||||||
|
<div id="cpuThreadsNotch1" class="gamepadslider_SliderNotchTick_u8QEa" onclick='setCPUNotch(2)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_dbACW">2</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_LYPXt">
|
||||||
|
<div id="cpuThreadsNotch2" class="gamepadslider_SliderNotchTick_u8QEa" onclick='setCPUNotch(3)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_dbACW">3</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_LYPXt">
|
||||||
|
<div id="cpuThreadsNotch3" class="gamepadslider_SliderNotchTick_u8QEa" onclick='setCPUNotch(4)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_dbACW">4</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_LYPXt">
|
||||||
|
<div id="cpuThreadsNotch4" class="gamepadslider_SliderNotchTick_u8QEa" onclick='setCPUNotch(5)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_dbACW">5</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_LYPXt">
|
||||||
|
<div id="cpuThreadsNotch5" class="gamepadslider_SliderNotchTick_u8QEa" onclick='setCPUNotch(6)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_dbACW">6</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_LYPXt">
|
||||||
|
<div id="cpuThreadsNotch6" class="gamepadslider_SliderNotchTick_u8QEa" onclick='setCPUNotch(7)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_dbACW">7</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_LYPXt">
|
||||||
|
<div id="cpuThreadsNotch7" class="gamepadslider_SliderNotchTick_u8QEa" onclick='setCPUNotch(8)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_dbACW">8</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Toggle switch, roughly copied from https://github.com/SteamDeckHomebrew/ExtraSettingsPlugin/blob/main/main_view.html -->
|
<!-- Toggle switch, roughly copied from https://github.com/SteamDeckHomebrew/ExtraSettingsPlugin/blob/main/main_view.html -->
|
||||||
<div class="quickaccessmenu_TabGroupPanel_1QO7b Panel Focusable">
|
<div class="quickaccessmenu_TabGroupPanel_1QO7b Panel Focusable">
|
||||||
<div class="quickaccesscontrols_PanelSectionRow_26R5w">
|
<div class="quickaccesscontrols_PanelSectionRow_26R5w">
|
||||||
<div class="quickaccesscontrols_PanelSectionRow_26R5w">
|
<div class="quickaccesscontrols_PanelSectionRow_26R5w">
|
||||||
<div class="gamepaddialog_Field_eKmEX gamepaddialog_WithFirstRow_2bDqk gamepaddialog_WithBottomSeparator_3YKpU gamepaddialog_ExtraPaddingOnChildrenBelow_3nLNL gamepaddialog_StandardPadding_xIITX gamepaddialog_HighlightOnFocus_2HFrm Panel Focusable" style="--indent-level:0;">
|
<div class="gamepaddialog_Field_eKmEX gamepaddialog_WithFirstRow_2bDqk gamepaddialog_ExtraPaddingOnChildrenBelow_3nLNL gamepaddialog_StandardPadding_xIITX gamepaddialog_HighlightOnFocus_2HFrm gamepaddialog_WithBottomSeparator_3YKpU Panel Focusable" style="--indent-level:0;">
|
||||||
<div class="gamepaddialog_FieldLabelRow_2VcTl">
|
<div class="gamepaddialog_FieldLabelRow_2VcTl">
|
||||||
<div class="gamepaddialog_FieldLabel_3jMlJ">
|
<div class="gamepaddialog_FieldLabel_3jMlJ">
|
||||||
CPU Boost
|
CPU Boost
|
||||||
|
@ -116,5 +161,35 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Frequency selector -->
|
||||||
|
<div class="gamepaddialog_Field_eKmEX gamepaddialog_WithFirstRow_2bDqk gamepaddialog_WithChildrenBelow_37xzV gamepaddialog_InlineWrapShiftsChildrenBelow_3LCXh gamepaddialog_WithBottomSeparator_3YKpU gamepaddialog_ChildrenWidthFixed_ljcbL gamepaddialog_ExtraPaddingOnChildrenBelow_3nLNL gamepaddialog_StandardPadding_xIITX gamepaddialog_HighlightOnFocus_2HFrm Panel Focusable">
|
||||||
|
<div class="gamepaddialog_FieldLabelRow_2VcTl">
|
||||||
|
<div class="gamepaddialog_FieldLabel_3jMlJ">Max Frequency</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepaddialog_FieldChildren_2rhav">
|
||||||
|
<div id="frequencyNotch" class="gamepadslider_SliderControlAndNotches_23hjX Focusable" tabindex="0" style="--normalized-slider-value:0.5;">
|
||||||
|
<div class="gamepadslider_SliderControl_1udlG">
|
||||||
|
<div class="gamepadslider_SliderTrack_2_vG6 gamepadslider_SliderHasNotches_1Lr71 "></div>
|
||||||
|
<div class="gamepadslider_SliderHandleContainer_8xNY6">
|
||||||
|
<div class="gamepadslider_SliderHandle_11PBf"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotchContainer_2yM7S Panel Focusable">
|
||||||
|
<div class="gamepadslider_SliderNotch_LYPXt">
|
||||||
|
<div id="frequencyNotch0" class="gamepadslider_SliderNotchTick_u8QEa gamepadslider_TickActive_j418S" onclick='setBoostNotch(0)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_dbACW" style="margin-left:2em;">1.7GHz</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_LYPXt">
|
||||||
|
<div id="frequencyNotch1" class="gamepadslider_SliderNotchTick_u8QEa gamepadslider_TickActive_j418S" onclick='setBoostNotch(1)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_dbACW">2.4GHz</div>
|
||||||
|
</div>
|
||||||
|
<div class="gamepadslider_SliderNotch_LYPXt">
|
||||||
|
<div id="frequencyNotch2" class="gamepadslider_SliderNotchTick_u8QEa" onclick='setBoostNotch(2)'></div>
|
||||||
|
<div class="gamepadslider_SliderNotchLabel_dbACW" style="margin-right:2em;">2.8GHz</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"flags": ["root", "_debug"],
|
"flags": ["root", "_debug"],
|
||||||
"publish": {
|
"publish": {
|
||||||
"discord_id": "106537989684887552",
|
"discord_id": "106537989684887552",
|
||||||
"description": "Additional power management settings",
|
"description": "Power tweaks for power users",
|
||||||
"tags": [ "utility", "power-management" ]
|
"tags": [ "utility", "power-management" ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue