forked from NG-SD-Plugins/PowerTools
Merge branch 'dev'
This commit is contained in:
commit
decc0cd73d
72 changed files with 2711 additions and 1424 deletions
20
README.md
20
README.md
|
@ -1,12 +1,12 @@
|
|||
# PowerTools
|
||||
|
||||
<!-- TODO Update badges for new git repo location -->
|
||||
[![Decky store](https://img.shields.io/badge/dynamic/json?color=blue&label=release&query=%24%5B%3F%28%40.name%3D%3D%27PowerTools%27%29%5D.versions%5B0%5D.name&url=https%3A%2F%2Fplugins.deckbrew.xyz%2Fplugins&style=flat-square)](https://plugins.deckbrew.xyz/)
|
||||
[![Custom store](https://img.shields.io/badge/dynamic/json?color=blue&label=preview&query=%24%5B%3F%28%40.name%3D%3D%27PowerTools%27%29%5D.versions%5B0%5D.name&url=https%3A%2F%2Fnot-decky-alpha.ngni.us%2Fplugins&style=flat-square)](https://github.com/NGnius/PowerTools/wiki)
|
||||
[![GitHub package.json version](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgit.ngni.us%2FNG-SD-Plugins%2FPowerTools%2Fraw%2Fbranch%2Fmain%2Fpackage.json&query=%24.version&style=flat-square&label=local&cacheSeconds=600)](https://git.ngni.us/NG-SD-Plugins/PowerTools/src/branch/main/package.json)
|
||||
|
||||
[![Liberapay](https://img.shields.io/liberapay/patrons/NGnius?style=flat-square)](https://liberapay.com/NGnius)
|
||||
[![GitHub](https://img.shields.io/github/license/NGnius/PowerTools?style=flat-square)](https://github.com/NGnius/PowerTools/blob/main/LICENSE)
|
||||
[![GitHub package.json version](https://img.shields.io/github/package-json/v/NGnius/PowerTools?style=flat-square)](https://github.com/NGnius/PowerTools/blob/main/package.json)
|
||||
[![GitHub package.json dependency version (prod)](https://img.shields.io/github/package-json/dependency-version/NGnius/PowerTools/decky-frontend-lib?style=flat-square)](https://github.com/NGnius/PowerTools/blob/main/pnpm-lock.yaml)
|
||||
[![GitHub](https://img.shields.io/badge/GPL--3.0-orange?style=flat-square&label=license&cacheSeconds=600)](https://github.com/NGnius/PowerTools/blob/main/LICENSE)
|
||||
[![GitHub package.json dependency version (local)](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fgit.ngni.us%2FNG-SD-Plugins%2FPowerTools%2Fraw%2Fbranch%2Fmain%2Fpackage.json&query=%24..%5B'decky-frontend-lib'%5D&style=flat-square&label=decky-frontend-lib&cacheSeconds=600)](https://github.com/NGnius/PowerTools/blob/main/pnpm-lock.yaml)
|
||||
|
||||
![plugin_demo](./assets/ui.png)
|
||||
|
||||
|
@ -24,17 +24,19 @@ You will need that installed for this plugin to work.
|
|||
- Display supplementary battery info
|
||||
- Keep settings between restarts (stored in `~/.config/powertools/<gameId>.json`)
|
||||
|
||||
This plugin is tested on Steam Deck, but is designed to work on other Linux devices as well. Unfortunately I am currently unable to test on other devices.
|
||||
|
||||
## Install
|
||||
|
||||
Please use Decky's [built-in store](https://beta.deckbrew.xyz/) to install official releases.
|
||||
If you're an advanced user, and/or would like to use an in-development version, feel free to build PowerTools yourself.
|
||||
Please use Decky's [built-in store](https://plugins.deckbrew.xyz/) to install official releases.
|
||||
If you want to test unstable versions, use [my custom store](https://not-decky-alpha.ngni.us/plugins). If you would like to use an in-development version, feel free to build PowerTools yourself.
|
||||
|
||||
## Build
|
||||
|
||||
0. Requirements: a functioning Rust toolchain for x86_64-unknown-linux-musl, npm, and some tech literacy
|
||||
0. Requirements: a functioning Rust toolchain for x86_64-unknown-linux-gnu (or -musl), pnpm, and some tech literacy
|
||||
1. In a terminal, navigate to the backend directory of this project and run `./build.sh`
|
||||
2. In the root of this project, run `npm run build`
|
||||
3. Transfer the project (especially dist/ and bin/) to a folder in your Steam Deck's homebrew plugins directory
|
||||
2. In the root of this project, run `pnpm run build`
|
||||
3. Transfer the project (especially dist/ and bin/) to a folder in your Steam Deck's `~/homebrew/plugins` directory
|
||||
|
||||
## License
|
||||
|
||||
|
|
260
assets/icon.svg
260
assets/icon.svg
|
@ -7,9 +7,9 @@
|
|||
viewBox="0 0 483.77954 483.77954"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="icon.svg"
|
||||
inkscape:export-filename="/home/ngnius/Documents/git-repos/PowerTools/extras/icon.png"
|
||||
inkscape:export-filename="logo.png"
|
||||
inkscape:export-xdpi="203.2"
|
||||
inkscape:export-ydpi="203.2"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
|
@ -30,16 +30,18 @@
|
|||
width="241.88977px"
|
||||
inkscape:snap-object-midpoints="false"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="250.66935"
|
||||
inkscape:cy="188.0904"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="1007"
|
||||
inkscape:window-x="1280"
|
||||
inkscape:cx="199.05056"
|
||||
inkscape:cy="246.07316"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="998"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-midpoints="true" />
|
||||
inkscape:snap-midpoints="true"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
|
@ -47,18 +49,25 @@
|
|||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd"
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
id="rect1945"
|
||||
width="100"
|
||||
height="10"
|
||||
x="349.94388"
|
||||
y="108.70168" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke-width:1.03075"
|
||||
id="rect31"
|
||||
width="200"
|
||||
width="212.49023"
|
||||
height="100"
|
||||
x="71.855446"
|
||||
x="59.365211"
|
||||
y="63.752789" />
|
||||
<circle
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0.5"
|
||||
id="path1244"
|
||||
cx="71.855446"
|
||||
cy="113.75279"
|
||||
r="50" />
|
||||
cx="59.355446"
|
||||
cy="88.752792"
|
||||
r="25" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
|
@ -76,24 +85,24 @@
|
|||
d="m 355.89305,113.75249 c 0,9.92465 -77.355,54.58558 -85.95,49.62325 -8.595,-4.96232 -8.595,-94.284182 0,-99.246508 8.595,-4.962325 85.95,39.698608 85.95,49.623258 z"
|
||||
inkscape:transform-center-x="-16.053868"
|
||||
inkscape:transform-center-y="-0.5295475" />
|
||||
<ellipse
|
||||
style="fill:#808080;stroke-width:1.4865"
|
||||
id="path591"
|
||||
cx="334.35544"
|
||||
cy="113.75249"
|
||||
rx="50"
|
||||
ry="20" />
|
||||
<path
|
||||
style="stroke:#000000;stroke-width:1.10309px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 72,164 v 150 l 120.000004,-150 z"
|
||||
style="stroke:none;stroke-width:0.530701px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill:#808080"
|
||||
d="m 135.67646,163.69764 v 74.33643 l 56.04644,-74.33643 z"
|
||||
id="path1655" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0.790569"
|
||||
id="rect1759"
|
||||
width="150"
|
||||
height="100"
|
||||
width="125"
|
||||
height="75"
|
||||
x="71.855446"
|
||||
y="313.75278" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
id="rect1945"
|
||||
width="100"
|
||||
height="10"
|
||||
x="349.94388"
|
||||
y="108.70168" />
|
||||
y="339" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:1.77271"
|
||||
id="rect2155"
|
||||
|
@ -101,5 +110,198 @@
|
|||
height="250.24721"
|
||||
x="71.855446"
|
||||
y="163.75279" />
|
||||
<circle
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0.5"
|
||||
id="circle277"
|
||||
cx="59.355446"
|
||||
cy="138.75279"
|
||||
r="25" />
|
||||
<rect
|
||||
style="fill:#000000"
|
||||
id="rect398"
|
||||
width="25"
|
||||
height="50"
|
||||
x="34.355446"
|
||||
y="88.752792" />
|
||||
<rect
|
||||
style="fill:#000000;stroke-width:0.820266"
|
||||
id="rect414"
|
||||
width="56.144562"
|
||||
height="25.567711"
|
||||
x="135.85544"
|
||||
y="163.4323" />
|
||||
<ellipse
|
||||
style="fill:#000000"
|
||||
id="path416"
|
||||
cx="71.855446"
|
||||
cy="357.75"
|
||||
rx="22.669472"
|
||||
ry="18.75" />
|
||||
<ellipse
|
||||
style="fill:#000000"
|
||||
id="path416-3"
|
||||
cx="71.855446"
|
||||
cy="395.25"
|
||||
rx="22.669472"
|
||||
ry="18.75" />
|
||||
<rect
|
||||
style="fill:#000000"
|
||||
id="rect458"
|
||||
width="22.669472"
|
||||
height="37.5"
|
||||
x="49.185974"
|
||||
y="357.75" />
|
||||
<ellipse
|
||||
style="fill:#000000"
|
||||
id="path416-6"
|
||||
cx="196.85544"
|
||||
cy="357.75"
|
||||
rx="22.669472"
|
||||
ry="18.75" />
|
||||
<ellipse
|
||||
style="fill:#000000"
|
||||
id="path416-3-7"
|
||||
cx="196.85544"
|
||||
cy="395.25"
|
||||
rx="22.669472"
|
||||
ry="18.75" />
|
||||
<rect
|
||||
style="fill:#000000"
|
||||
id="rect458-5"
|
||||
width="22.669472"
|
||||
height="37.5"
|
||||
x="196.85544"
|
||||
y="357.75" />
|
||||
<rect
|
||||
style="fill:#000000;stroke-width:0.987024"
|
||||
id="rect901"
|
||||
width="48.7108"
|
||||
height="40"
|
||||
x="284.37106"
|
||||
y="93.752487" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:1.49999"
|
||||
id="path1656"
|
||||
cx="64.860382"
|
||||
cy="81.150871"
|
||||
r="7.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:1.49999"
|
||||
id="path1656-3"
|
||||
cx="266.36029"
|
||||
cy="81.150871"
|
||||
r="7.5" />
|
||||
<rect
|
||||
style="fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke-width:0.84968"
|
||||
id="rect31-5"
|
||||
width="180.49001"
|
||||
height="80"
|
||||
x="75.365326"
|
||||
y="73.752792" />
|
||||
<rect
|
||||
style="fill:#808080;stroke:#808080;stroke-width:3.44828;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect1732"
|
||||
width="21.551723"
|
||||
height="21.551723"
|
||||
x="48.579582"
|
||||
y="94.675819" />
|
||||
<rect
|
||||
style="fill:#808080;stroke:#808080;stroke-width:3.44828;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect1732-9"
|
||||
width="21.551723"
|
||||
height="21.551723"
|
||||
x="261.08936"
|
||||
y="94.675819" />
|
||||
<g
|
||||
id="g2413"
|
||||
transform="translate(7.8603821,-16.500301)">
|
||||
<rect
|
||||
style="fill:#808080;stroke:none"
|
||||
id="rect1798"
|
||||
width="10"
|
||||
height="5"
|
||||
x="52"
|
||||
y="138.75279" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none"
|
||||
id="path1800"
|
||||
cx="52"
|
||||
cy="141.25279"
|
||||
r="2.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none"
|
||||
id="path1800-2"
|
||||
cx="62"
|
||||
cy="141.25279"
|
||||
r="2.5" />
|
||||
</g>
|
||||
<g
|
||||
id="g2413-1"
|
||||
transform="translate(209.36029,-16.500301)">
|
||||
<rect
|
||||
style="fill:#808080;stroke:none"
|
||||
id="rect1798-2"
|
||||
width="10"
|
||||
height="5"
|
||||
x="52"
|
||||
y="138.75279" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none"
|
||||
id="path1800-7"
|
||||
cx="52"
|
||||
cy="141.25279"
|
||||
r="2.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none"
|
||||
id="path1800-2-0"
|
||||
cx="62"
|
||||
cy="141.25279"
|
||||
r="2.5" />
|
||||
</g>
|
||||
<g
|
||||
id="g2678">
|
||||
<rect
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2563"
|
||||
width="15"
|
||||
height="5"
|
||||
x="39.355446"
|
||||
y="75.747589" />
|
||||
<rect
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2601"
|
||||
width="5"
|
||||
height="15"
|
||||
x="44.355446"
|
||||
y="70.747589" />
|
||||
</g>
|
||||
<g
|
||||
id="g2674"
|
||||
transform="translate(-1.5377998e-5,1.6793823)">
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path2605"
|
||||
cx="279.36523"
|
||||
cy="76.568207"
|
||||
r="2.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path2605-9"
|
||||
cx="284.36523"
|
||||
cy="71.574265"
|
||||
r="2.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path2605-3"
|
||||
cx="289.36523"
|
||||
cy="76.568207"
|
||||
r="2.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path2605-6"
|
||||
cx="284.36523"
|
||||
cy="81.562149"
|
||||
r="2.5" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 8.5 KiB |
BIN
assets/logo.png
BIN
assets/logo.png
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 18 KiB |
384
assets/sticker.svg
Normal file
384
assets/sticker.svg
Normal file
|
@ -0,0 +1,384 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg5"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
sodipodi:docname="sticker.svg"
|
||||
inkscape:export-filename="../../../../Pictures/Projects/DeckyLoader/powertools-sticker.png"
|
||||
inkscape:export-xdpi="384"
|
||||
inkscape:export-ydpi="384"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview7"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="true"
|
||||
inkscape:document-units="px"
|
||||
showgrid="false"
|
||||
units="mm"
|
||||
width="241.88977px"
|
||||
inkscape:snap-object-midpoints="false"
|
||||
inkscape:zoom="1.4142136"
|
||||
inkscape:cx="78.135297"
|
||||
inkscape:cy="238.29498"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="998"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-midpoints="true"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<defs
|
||||
id="defs2" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<circle
|
||||
style="fill:#ff00ff;stroke-width:1.06004"
|
||||
id="path169-0"
|
||||
cx="256.33051"
|
||||
cy="257.39117"
|
||||
r="256" />
|
||||
<rect
|
||||
style="fill:#ff00ff;stroke-width:1.4133"
|
||||
id="rect4535-6"
|
||||
width="512"
|
||||
height="510.60883"
|
||||
x="0"
|
||||
y="0.69558716" />
|
||||
<rect
|
||||
style="fill:#ff00ff"
|
||||
id="rect4535"
|
||||
width="256.33051"
|
||||
height="510.60883"
|
||||
x="0"
|
||||
y="1.3911743" />
|
||||
<circle
|
||||
style="fill:#ff00ff;stroke-width:0.621117"
|
||||
id="path169-6-2"
|
||||
cx="256"
|
||||
cy="256"
|
||||
r="150" />
|
||||
<circle
|
||||
style="fill:#ffffff;stroke-width:0.53002"
|
||||
id="path169-6"
|
||||
cx="256"
|
||||
cy="256"
|
||||
r="128" />
|
||||
<circle
|
||||
style="fill:#ffffff;stroke-width:1.06004"
|
||||
id="path169"
|
||||
cx="256.33051"
|
||||
cy="257.39117"
|
||||
r="256" />
|
||||
<g
|
||||
id="g4192"
|
||||
transform="matrix(0.84217934,0,0,0.84217934,111.88641,61.863508)">
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
id="rect1945"
|
||||
width="100"
|
||||
height="10"
|
||||
x="278.91406"
|
||||
y="100.3456" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke-width:1.03075"
|
||||
id="rect31"
|
||||
width="212.49023"
|
||||
height="100"
|
||||
x="-11.664615"
|
||||
y="55.396706" />
|
||||
<circle
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0.5"
|
||||
id="path1244"
|
||||
cx="-11.67438"
|
||||
cy="80.396706"
|
||||
r="25" />
|
||||
<path
|
||||
sodipodi:type="star"
|
||||
style="fill:#000000;fill-opacity:1"
|
||||
id="path1353"
|
||||
inkscape:flatsided="true"
|
||||
sodipodi:sides="3"
|
||||
sodipodi:cx="298.59305"
|
||||
sodipodi:cy="113.75249"
|
||||
sodipodi:r1="57.299999"
|
||||
sodipodi:r2="60"
|
||||
sodipodi:arg1="0"
|
||||
sodipodi:arg2="0"
|
||||
inkscape:rounded="0.1"
|
||||
inkscape:randomized="0"
|
||||
d="m 355.89305,113.75249 c 0,9.92465 -77.355,54.58558 -85.95,49.62325 -8.595,-4.96232 -8.595,-94.284182 0,-99.246508 8.595,-4.962325 85.95,39.698608 85.95,49.623258 z"
|
||||
inkscape:transform-center-x="-16.053868"
|
||||
inkscape:transform-center-y="-0.5295475"
|
||||
transform="translate(-71.029826,-8.356084)" />
|
||||
<ellipse
|
||||
style="fill:#808080;stroke-width:1.4865"
|
||||
id="path591"
|
||||
cx="263.32562"
|
||||
cy="105.3964"
|
||||
rx="50"
|
||||
ry="20" />
|
||||
<path
|
||||
style="fill:#808080;stroke:none;stroke-width:0.530701px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 64.646634,155.34156 v 74.33643 l 56.046436,-74.33643 z"
|
||||
id="path1655" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0.790569"
|
||||
id="rect1759"
|
||||
width="125"
|
||||
height="75"
|
||||
x="0.82561988"
|
||||
y="330.64392" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:1.77271"
|
||||
id="rect2155"
|
||||
width="64"
|
||||
height="250.24721"
|
||||
x="0.82561988"
|
||||
y="155.39671" />
|
||||
<circle
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0.5"
|
||||
id="circle277"
|
||||
cx="-11.67438"
|
||||
cy="130.39671"
|
||||
r="25" />
|
||||
<rect
|
||||
style="fill:#000000"
|
||||
id="rect398"
|
||||
width="25"
|
||||
height="50"
|
||||
x="-36.674381"
|
||||
y="80.396706" />
|
||||
<rect
|
||||
style="fill:#000000;stroke-width:0.820266"
|
||||
id="rect414"
|
||||
width="56.144562"
|
||||
height="25.567711"
|
||||
x="64.825615"
|
||||
y="155.07622" />
|
||||
<ellipse
|
||||
style="fill:#000000"
|
||||
id="path416"
|
||||
cx="0.82561988"
|
||||
cy="349.39392"
|
||||
rx="22.669472"
|
||||
ry="18.75" />
|
||||
<ellipse
|
||||
style="fill:#000000"
|
||||
id="path416-3"
|
||||
cx="0.82561988"
|
||||
cy="386.89392"
|
||||
rx="22.669472"
|
||||
ry="18.75" />
|
||||
<rect
|
||||
style="fill:#000000"
|
||||
id="rect458"
|
||||
width="22.669472"
|
||||
height="37.5"
|
||||
x="-21.843851"
|
||||
y="349.39392" />
|
||||
<ellipse
|
||||
style="fill:#000000"
|
||||
id="path416-6"
|
||||
cx="125.82561"
|
||||
cy="349.39392"
|
||||
rx="22.669472"
|
||||
ry="18.75" />
|
||||
<ellipse
|
||||
style="fill:#000000"
|
||||
id="path416-3-7"
|
||||
cx="125.82561"
|
||||
cy="386.89392"
|
||||
rx="22.669472"
|
||||
ry="18.75" />
|
||||
<rect
|
||||
style="fill:#000000"
|
||||
id="rect458-5"
|
||||
width="22.669472"
|
||||
height="37.5"
|
||||
x="125.82561"
|
||||
y="349.39392" />
|
||||
<rect
|
||||
style="fill:#000000;stroke-width:0.987024"
|
||||
id="rect901"
|
||||
width="48.7108"
|
||||
height="40"
|
||||
x="213.34123"
|
||||
y="85.3964" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:1.49999"
|
||||
id="path1656"
|
||||
cx="-6.1694441"
|
||||
cy="72.794785"
|
||||
r="7.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:1.49999"
|
||||
id="path1656-3"
|
||||
cx="195.33046"
|
||||
cy="72.794785"
|
||||
r="7.5" />
|
||||
<rect
|
||||
style="fill:#808080;fill-opacity:1;fill-rule:evenodd;stroke-width:0.84968"
|
||||
id="rect31-5"
|
||||
width="180.49001"
|
||||
height="80"
|
||||
x="4.3354998"
|
||||
y="65.396706" />
|
||||
<rect
|
||||
style="fill:#808080;stroke:#808080;stroke-width:3.44828;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect1732"
|
||||
width="21.551723"
|
||||
height="21.551723"
|
||||
x="-22.450243"
|
||||
y="86.319733" />
|
||||
<rect
|
||||
style="fill:#808080;stroke:#808080;stroke-width:3.44828;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect1732-9"
|
||||
width="21.551723"
|
||||
height="21.551723"
|
||||
x="190.05952"
|
||||
y="86.319733" />
|
||||
<g
|
||||
id="g2413"
|
||||
transform="translate(-63.169444,-24.856385)">
|
||||
<rect
|
||||
style="fill:#808080;stroke:none"
|
||||
id="rect1798"
|
||||
width="10"
|
||||
height="5"
|
||||
x="52"
|
||||
y="138.75279" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none"
|
||||
id="path1800"
|
||||
cx="52"
|
||||
cy="141.25279"
|
||||
r="2.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none"
|
||||
id="path1800-2"
|
||||
cx="62"
|
||||
cy="141.25279"
|
||||
r="2.5" />
|
||||
</g>
|
||||
<g
|
||||
id="g2413-1"
|
||||
transform="translate(138.33046,-24.856385)">
|
||||
<rect
|
||||
style="fill:#808080;stroke:none"
|
||||
id="rect1798-2"
|
||||
width="10"
|
||||
height="5"
|
||||
x="52"
|
||||
y="138.75279" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none"
|
||||
id="path1800-7"
|
||||
cx="52"
|
||||
cy="141.25279"
|
||||
r="2.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none"
|
||||
id="path1800-2-0"
|
||||
cx="62"
|
||||
cy="141.25279"
|
||||
r="2.5" />
|
||||
</g>
|
||||
<g
|
||||
id="g2678"
|
||||
transform="translate(-71.029826,-8.356084)">
|
||||
<rect
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2563"
|
||||
width="15"
|
||||
height="5"
|
||||
x="39.355446"
|
||||
y="75.747589" />
|
||||
<rect
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect2601"
|
||||
width="5"
|
||||
height="15"
|
||||
x="44.355446"
|
||||
y="70.747589" />
|
||||
</g>
|
||||
<g
|
||||
id="g2674"
|
||||
transform="translate(-71.029841,-6.6767017)">
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path2605"
|
||||
cx="279.36523"
|
||||
cy="76.568207"
|
||||
r="2.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path2605-9"
|
||||
cx="284.36523"
|
||||
cy="71.574265"
|
||||
r="2.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path2605-3"
|
||||
cx="289.36523"
|
||||
cy="76.568207"
|
||||
r="2.5" />
|
||||
<circle
|
||||
style="fill:#808080;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path2605-6"
|
||||
cx="284.36523"
|
||||
cy="81.562149"
|
||||
r="2.5" />
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;display:none;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="75.370758"
|
||||
y="473.16794"
|
||||
id="text4777"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4775"
|
||||
x="75.370758"
|
||||
y="473.16794"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:64px;font-family:Hack;-inkscape-font-specification:'Hack, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal">PowerTools</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;fill:#ffffff;fill-opacity:1;stroke:none"
|
||||
x="92.57341"
|
||||
y="389.06296"
|
||||
id="text4831"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4829"
|
||||
x="92.57341"
|
||||
y="389.06296"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:48px;font-family:Hack;-inkscape-font-specification:'Hack, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#ffffff">Power</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="237.4406"
|
||||
y="395.76608"
|
||||
id="text4835"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4833"
|
||||
x="237.4406"
|
||||
y="395.76608"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:64px;font-family:Hack;-inkscape-font-specification:'Hack, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal">Tools</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
584
backend/Cargo.lock
generated
584
backend/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "powertools"
|
||||
version = "1.3.1"
|
||||
version = "1.4.0"
|
||||
edition = "2021"
|
||||
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
|
||||
description = "Backend (superuser) functionality for PowerTools"
|
||||
|
@ -15,6 +15,7 @@ readme = "../README.md"
|
|||
usdpl-back = { version = "0.10.1", features = ["blocking"] }#, path = "../../usdpl-rs/usdpl-back"}
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
sysfuss = { version = "0.2", path = "../../sysfs-nav", features = ["derive"] }
|
||||
|
||||
# async
|
||||
tokio = { version = "*", features = ["time"] }
|
||||
|
@ -25,11 +26,11 @@ log = "0.4"
|
|||
simplelog = "0.12"
|
||||
|
||||
# limits & driver functionality
|
||||
limits_core = { version = "1.0.0", path = "./limits_core" }
|
||||
limits_core = { version = "2", path = "./limits_core" }
|
||||
regex = "1"
|
||||
libryzenadj = { version = "0.12" }
|
||||
# ureq's tls feature does not like musl targets
|
||||
ureq = { version = "2.5", features = ["json", "gzip", "brotli", "charset"], default-features = false, optional = true }
|
||||
ureq = { version = "2", features = ["json", "gzip", "brotli", "charset"], default-features = false, optional = true }
|
||||
|
||||
[features]
|
||||
default = ["online", "decky"]
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
cargo build
|
||||
|
||||
mkdir -p ../bin
|
||||
#cp ./target/x86_64-unknown-linux-musl/release/powertools ../bin/backend
|
||||
#cp ./target/x86_64-unknown-linux-musl/debug/powertools ../bin/backend
|
||||
#cp ./target/debug/powertools ../bin/backend
|
||||
cp ./target/debug/powertools ../bin/backend
|
||||
#cp --preserve=mode ./target/x86_64-unknown-linux-musl/release/powertools ../bin/backend
|
||||
#cp --preserve=mode ./target/x86_64-unknown-linux-musl/debug/powertools ../bin/backend
|
||||
#cp --preserve=mode ./target/debug/powertools ../bin/backend
|
||||
cp --preserve=mode ./target/debug/powertools ../bin/backend
|
||||
|
|
38
backend/limits_core/Cargo.lock
generated
38
backend/limits_core/Cargo.lock
generated
|
@ -4,13 +4,13 @@ version = 3
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.6"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
|
||||
|
||||
[[package]]
|
||||
name = "limits_core"
|
||||
version = "1.0.0"
|
||||
version = "2.0.1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -18,42 +18,42 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.54"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
|
||||
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.26"
|
||||
version = "1.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.13"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||
checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.159"
|
||||
version = "1.0.166"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065"
|
||||
checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.159"
|
||||
version = "1.0.166"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585"
|
||||
checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -62,9 +62,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.95"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
|
||||
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -73,9 +73,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.12"
|
||||
version = "2.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927"
|
||||
checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -84,6 +84,6 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.8"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "limits_core"
|
||||
version = "1.0.0"
|
||||
version = "2.0.1"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
@ -57,16 +57,16 @@ impl Default for Base {
|
|||
},
|
||||
limits: vec![
|
||||
super::Limits::Cpu(super::CpuLimit::GenericAMD(super::GenericCpuLimit {
|
||||
clock_min: Some(super::RangeLimit { min: 1000, max: 3700 }),
|
||||
clock_max: Some(super::RangeLimit { min: 1000, max: 3700 }),
|
||||
clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(3700) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(3700) }),
|
||||
clock_step: 100,
|
||||
})),
|
||||
super::Limits::Gpu(super::GpuLimit::GenericAMD(super::GenericGpuLimit {
|
||||
fast_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }),
|
||||
slow_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }),
|
||||
fast_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
|
||||
slow_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
|
||||
ppt_step: Some(1_000_000),
|
||||
clock_min: Some(super::RangeLimit { min: 400, max: 1100 }),
|
||||
clock_max: Some(super::RangeLimit { min: 400, max: 1100 }),
|
||||
clock_min: Some(super::RangeLimit { min: Some(400), max: Some(1100) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(400), max: Some(1100) }),
|
||||
clock_step: Some(100),
|
||||
..Default::default()
|
||||
})),
|
||||
|
@ -84,16 +84,16 @@ impl Default for Base {
|
|||
},
|
||||
limits: vec![
|
||||
super::Limits::Cpu(super::CpuLimit::GenericAMD(super::GenericCpuLimit {
|
||||
clock_min: Some(super::RangeLimit { min: 1000, max: 4000 }),
|
||||
clock_max: Some(super::RangeLimit { min: 1000, max: 4000 }),
|
||||
clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(4000) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4000) }),
|
||||
clock_step: 100,
|
||||
})),
|
||||
super::Limits::Gpu(super::GpuLimit::GenericAMD(super::GenericGpuLimit {
|
||||
fast_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }),
|
||||
slow_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }),
|
||||
fast_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
|
||||
slow_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
|
||||
ppt_step: Some(1_000_000),
|
||||
clock_min: Some(super::RangeLimit { min: 400, max: 1600 }),
|
||||
clock_max: Some(super::RangeLimit { min: 400, max: 1600 }),
|
||||
clock_min: Some(super::RangeLimit { min: Some(400), max: Some(1600) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(400), max: Some(1600) }),
|
||||
clock_step: Some(100),
|
||||
..Default::default()
|
||||
})),
|
||||
|
@ -111,16 +111,16 @@ impl Default for Base {
|
|||
},
|
||||
limits: vec![
|
||||
super::Limits::Cpu(super::CpuLimit::GenericAMD(super::GenericCpuLimit {
|
||||
clock_min: Some(super::RangeLimit { min: 1000, max: 4500 }),
|
||||
clock_max: Some(super::RangeLimit { min: 1000, max: 4500 }),
|
||||
clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(4500) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4500) }),
|
||||
clock_step: 100,
|
||||
})),
|
||||
super::Limits::Gpu(super::GpuLimit::GenericAMD(super::GenericGpuLimit {
|
||||
fast_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }),
|
||||
slow_ppt: Some(super::RangeLimit { min: 1_000_000, max: 25_000_000 }),
|
||||
fast_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
|
||||
slow_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(25_000_000) }),
|
||||
ppt_step: Some(1_000_000),
|
||||
clock_min: Some(super::RangeLimit { min: 400, max: 2000 }),
|
||||
clock_max: Some(super::RangeLimit { min: 400, max: 2000 }),
|
||||
clock_min: Some(super::RangeLimit { min: Some(400), max: Some(2000) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(400), max: Some(2000) }),
|
||||
clock_step: Some(100),
|
||||
..Default::default()
|
||||
})),
|
||||
|
@ -138,16 +138,16 @@ impl Default for Base {
|
|||
},
|
||||
limits: vec![
|
||||
super::Limits::Cpu(super::CpuLimit::Generic(super::GenericCpuLimit {
|
||||
clock_min: Some(super::RangeLimit { min: 1000, max: 4700 }),
|
||||
clock_max: Some(super::RangeLimit { min: 1000, max: 4700 }),
|
||||
clock_min: Some(super::RangeLimit { min: Some(1000), max: Some(4700) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(1000), max: Some(4700) }),
|
||||
clock_step: 100,
|
||||
})),
|
||||
super::Limits::Gpu(super::GpuLimit::Generic(super::GenericGpuLimit {
|
||||
fast_ppt: Some(super::RangeLimit { min: 1_000_000, max: 28_000_000 }),
|
||||
slow_ppt: Some(super::RangeLimit { min: 1_000_000, max: 28_000_000 }),
|
||||
fast_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(28_000_000) }),
|
||||
slow_ppt: Some(super::RangeLimit { min: Some(1_000_000), max: Some(28_000_000) }),
|
||||
ppt_step: Some(1_000_000),
|
||||
clock_min: Some(super::RangeLimit { min: 400, max: 2200 }),
|
||||
clock_max: Some(super::RangeLimit { min: 400, max: 2200 }),
|
||||
clock_min: Some(super::RangeLimit { min: Some(400), max: Some(2200) }),
|
||||
clock_max: Some(super::RangeLimit { min: Some(400), max: Some(2200) }),
|
||||
clock_step: Some(100),
|
||||
..Default::default()
|
||||
})),
|
||||
|
@ -170,7 +170,14 @@ impl Default for Base {
|
|||
]
|
||||
}
|
||||
],
|
||||
messages: Vec::new(),
|
||||
messages: vec![
|
||||
super::DeveloperMessage {
|
||||
id: 1,
|
||||
title: "Welcome".to_owned(),
|
||||
body: "Thanks for installing PowerTools! For more information, please check the wiki. For bugs and requests, please create an issue on GitHub.".to_owned(),
|
||||
url: Some("https://github.com/NGnius/PowerTools/wiki".to_owned()),
|
||||
}
|
||||
],
|
||||
refresh: Some("http://limits.ngni.us:45000/powertools/v1".to_owned())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,6 @@ use serde::{Deserialize, Serialize};
|
|||
/// Base JSON limits information
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct RangeLimit<T> {
|
||||
pub min: T,
|
||||
pub max: T,
|
||||
pub min: Option<T>,
|
||||
pub max: Option<T>,
|
||||
}
|
||||
|
|
483
backend/limits_srv/Cargo.lock
generated
483
backend/limits_srv/Cargo.lock
generated
|
@ -2,6 +2,27 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
|
@ -17,6 +38,21 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
|
@ -25,9 +61,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
|||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.0"
|
||||
version = "0.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
|
||||
checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
|
@ -46,9 +82,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.12.0"
|
||||
version = "3.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
|
||||
checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
|
@ -76,40 +112,30 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.24"
|
||||
version = "0.4.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b"
|
||||
checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"time",
|
||||
"wasm-bindgen",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "codespan-reporting"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
|
||||
dependencies = [
|
||||
"termcolor",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.6"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181"
|
||||
checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
@ -124,60 +150,25 @@ dependencies = [
|
|||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
"cxxbridge-macro",
|
||||
"link-cplusplus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx-build"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"codespan-reporting",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"scratch",
|
||||
"syn 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.6"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
|
@ -186,9 +177,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.1.0"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
||||
checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
@ -247,9 +238,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.8"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
|
@ -257,10 +248,16 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.16"
|
||||
name = "gimli"
|
||||
version = "0.27.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d"
|
||||
checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e"
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
|
@ -308,12 +305,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
|
@ -351,9 +345,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
|||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.25"
|
||||
version = "0.14.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899"
|
||||
checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
|
@ -375,9 +369,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.54"
|
||||
version = "0.1.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c17cc76786e99f8d2f055c11159e7f0091c42474dcc3189fbab96072e873e6d"
|
||||
checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
|
@ -389,19 +383,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cxx",
|
||||
"cxx-build",
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||
checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
|
@ -419,28 +412,28 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.6"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||
checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.61"
|
||||
version = "0.3.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
|
||||
checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.140"
|
||||
version = "0.2.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
|
||||
[[package]]
|
||||
name = "limits_core"
|
||||
version = "1.0.0"
|
||||
version = "2.0.1"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -448,7 +441,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "limits_srv"
|
||||
version = "1.0.0"
|
||||
version = "2.0.1"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"limits_core",
|
||||
|
@ -458,23 +451,11 @@ dependencies = [
|
|||
"warp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
version = "0.4.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
|
@ -499,39 +480,41 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.6"
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
|
||||
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multiparty"
|
||||
version = "0.1.0"
|
||||
name = "multer"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed1ec6589a6d4a1e0b33b4c0a3f6ee96dfba88ebdb3da51403fd7cf0a24a4b04"
|
||||
checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"encoding_rs",
|
||||
"futures-util",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
"mime",
|
||||
"spin",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -545,51 +528,60 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.15.0"
|
||||
version = "1.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
|
||||
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.1"
|
||||
name = "object"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
|
||||
checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.2.0"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.12"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
|
||||
checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.0.12"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
|
||||
checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||
checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
|
@ -605,18 +597,18 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.54"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e472a104799c74b514a57226160104aa483546de37e839ec50e3c2e41dd87534"
|
||||
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.26"
|
||||
version = "1.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
@ -652,19 +644,25 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.2"
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
|
||||
checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2"
|
||||
dependencies = [
|
||||
"base64 0.21.0",
|
||||
"base64 0.21.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.13"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||
checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
|
@ -672,37 +670,31 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||
|
||||
[[package]]
|
||||
name = "scratch"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.159"
|
||||
version = "1.0.166"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065"
|
||||
checksum = "d01b7404f9d441d3ad40e6a636a7782c377d2abdbe4fa2440e2edcc2f4f10db8"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.159"
|
||||
version = "1.0.166"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585"
|
||||
checksum = "5dd83d6dde2b6b2d466e14d9d1acce8816dedee94f735eac6395808b3483c6d6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.12",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.95"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744"
|
||||
checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -752,36 +744,22 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.40"
|
||||
|
@ -799,7 +777,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.12",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -830,11 +808,12 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.27.0"
|
||||
version = "1.29.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001"
|
||||
checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
|
@ -847,20 +826,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.0.0"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce"
|
||||
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.12",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-stream"
|
||||
version = "0.1.12"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313"
|
||||
checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
|
@ -881,9 +860,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.7"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2"
|
||||
checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
|
@ -913,9 +892,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.30"
|
||||
version = "0.1.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
|
||||
checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
@ -968,9 +947,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
|||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.8"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
|
@ -981,17 +960,11 @@ dependencies = [
|
|||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.3.1"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
|
@ -1012,19 +985,18 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
|||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.0"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
|
||||
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
|
||||
dependencies = [
|
||||
"log",
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "warp"
|
||||
version = "0.3.4"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27e1a710288f0f91a98dd8a74f05b76a10768db245ce183edf64dc1afdc3016c"
|
||||
checksum = "ba431ef570df1287f7f8b07e376491ad54f84d26ac473489427231e1718e1f69"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
|
@ -1035,7 +1007,7 @@ dependencies = [
|
|||
"log",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"multiparty",
|
||||
"multer",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"rustls-pemfile",
|
||||
|
@ -1065,9 +1037,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.84"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
|
||||
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
|
@ -1075,24 +1047,24 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.84"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
|
||||
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.84"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
|
||||
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
|
@ -1100,22 +1072,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.84"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
|
||||
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.84"
|
||||
version = "0.2.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
|
||||
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
|
@ -1133,15 +1105,6 @@ version = "0.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
@ -1150,27 +1113,27 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.46.0"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25"
|
||||
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
version = "0.48.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
||||
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
|
@ -1183,42 +1146,42 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
[package]
|
||||
name = "limits_srv"
|
||||
version = "1.0.0"
|
||||
version = "2.0.1"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
limits_core = { version = "1.0.0", path = "../limits_core" }
|
||||
limits_core = { version = "2.0.1", path = "../limits_core" }
|
||||
chrono = { version = "0.4" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
|
|
@ -289,6 +289,13 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"messages": [],
|
||||
"messages": [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "Welcome",
|
||||
"body": "Thanks for installing PowerTools! For more information, please check the wiki. For bugs and requests, please create an issue on GitHub.",
|
||||
"url": "https://github.com/NGnius/PowerTools/wiki"
|
||||
}
|
||||
],
|
||||
"refresh": "http://limits.ngni.us:45000/powertools/v1"
|
||||
}
|
|
@ -1,18 +1,14 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct RangeLimit<T> {
|
||||
pub min: T,
|
||||
pub max: T,
|
||||
}
|
||||
|
||||
impl<T> From<limits_core::json::RangeLimit<T>> for RangeLimit<T> {
|
||||
#[inline]
|
||||
fn from(other: limits_core::json::RangeLimit<T>) -> Self {
|
||||
RangeLimit {
|
||||
min: other.min,
|
||||
max: other.max,
|
||||
}
|
||||
impl<T> RangeLimit<T> {
|
||||
pub fn new(min: T, max: T) -> Self {
|
||||
Self { min, max }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,11 +30,6 @@ pub fn current_now(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
|||
}
|
||||
}
|
||||
|
||||
/// Current current (ha!) web method
|
||||
/*pub fn current_now(_: super::ApiParameterType) -> super::ApiParameterType {
|
||||
super::utility::map_optional_result(crate::settings::driver::read_current_now())
|
||||
}*/
|
||||
|
||||
/// Charge now web method
|
||||
pub fn charge_now(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
|
@ -110,6 +105,31 @@ pub fn charge_design(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
|||
}
|
||||
}
|
||||
|
||||
/// Charge wattage web method
|
||||
pub fn charge_power(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback =
|
||||
move |val: Option<f64>| tx.send(val).expect("power_now callback send failed");
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::ReadChargePower(
|
||||
Box::new(callback),
|
||||
)))
|
||||
.expect("power_now send failed");
|
||||
rx.recv().expect("power_now callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |result| super::utility::map_optional_result(Ok(result)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate set battery charge rate web method
|
||||
pub fn set_charge_rate(
|
||||
sender: Sender<ApiMessage>,
|
||||
|
|
|
@ -6,6 +6,7 @@ use usdpl_back::AsyncCallable;
|
|||
use crate::settings::{MinMax, SettingError, SettingVariant};
|
||||
//use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
||||
use super::handler::{ApiMessage, CpuMessage};
|
||||
use super::utility::map_optional;
|
||||
|
||||
/// Available CPUs web method
|
||||
pub fn max_cpus(_: super::ApiParameterType) -> super::ApiParameterType {
|
||||
|
@ -205,8 +206,8 @@ pub fn set_clock_limits(
|
|||
setter(
|
||||
index as usize,
|
||||
MinMax {
|
||||
min: safe_min as u64,
|
||||
max: safe_max as u64,
|
||||
min: Some(safe_min as u64),
|
||||
max: Some(safe_max as u64),
|
||||
},
|
||||
);
|
||||
vec![safe_min.into(), safe_max.into()]
|
||||
|
@ -220,6 +221,7 @@ pub fn set_clock_limits(
|
|||
vec!["set_clock_limits missing parameter 0".into()]
|
||||
}
|
||||
}
|
||||
// TODO allow param 0 and/or 1 to be Primitive::Empty
|
||||
}
|
||||
|
||||
pub fn get_clock_limits(
|
||||
|
@ -245,7 +247,7 @@ pub fn get_clock_limits(
|
|||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||
if let Some(min_max) = getter(index as usize) {
|
||||
vec![min_max.min.into(), min_max.max.into()]
|
||||
vec![map_optional(min_max.min), map_optional(min_max.max)]
|
||||
} else {
|
||||
vec![Primitive::Empty, Primitive::Empty]
|
||||
}
|
||||
|
|
|
@ -321,3 +321,57 @@ pub fn force_apply(
|
|||
vec![true.into()]
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate get periodicals aggregate method
|
||||
pub fn get_periodicals(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (rx_curr, callback_curr) = build_comms("battery current callback send failed");
|
||||
let (rx_charge_now, callback_charge_now) = build_comms("battery charge now callback send failed");
|
||||
let (rx_charge_full, callback_charge_full) = build_comms("battery charge full callback send failed");
|
||||
let (rx_charge_power, callback_charge_power) = build_comms("battery charge power callback send failed");
|
||||
|
||||
let (rx_path, callback_path) = build_comms("general get path (periodical) send failed");
|
||||
|
||||
let sender_locked = sender2
|
||||
.lock()
|
||||
.unwrap();
|
||||
let curr = wait_for_response(&*sender_locked, rx_curr,
|
||||
ApiMessage::Battery(super::handler::BatteryMessage::ReadCurrentNow(callback_curr)), "battery current");
|
||||
let charge_now = wait_for_response(&*sender_locked, rx_charge_now,
|
||||
ApiMessage::Battery(super::handler::BatteryMessage::ReadChargeNow(callback_charge_now)), "battery charge now");
|
||||
let charge_full = wait_for_response(&*sender_locked, rx_charge_full,
|
||||
ApiMessage::Battery(super::handler::BatteryMessage::ReadChargeFull(callback_charge_full)), "battery charge full");
|
||||
let charge_power = wait_for_response(&*sender_locked, rx_charge_power,
|
||||
ApiMessage::Battery(super::handler::BatteryMessage::ReadChargePower(callback_charge_power)), "battery charge power");
|
||||
|
||||
let settings_path = wait_for_response(&*sender_locked, rx_path,
|
||||
ApiMessage::General(GeneralMessage::GetPath(callback_path)), "general get path");
|
||||
vec![
|
||||
super::utility::map_optional(curr),
|
||||
super::utility::map_optional(charge_now),
|
||||
super::utility::map_optional(charge_full),
|
||||
super::utility::map_optional(charge_power),
|
||||
|
||||
super::utility::map_optional(settings_path.to_str()),
|
||||
]
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |result| result,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_comms<'a, T: Send + 'a>(msg: &'static str) -> (mpsc::Receiver<T>, Box<dyn FnOnce(T) + Send + 'a>) {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |t: T| tx.send(t).expect(msg);
|
||||
(rx, Box::new(callback))
|
||||
}
|
||||
|
||||
fn wait_for_response<T>(sender: &Sender<ApiMessage>, rx: mpsc::Receiver<T>, api_msg: ApiMessage, op: &str) -> T {
|
||||
sender.send(api_msg).expect(&format!("{} send failed", op));
|
||||
rx.recv().expect(&format!("{} callback recv failed", op))
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::sync::{Arc, Mutex};
|
|||
use usdpl_back::core::serdes::Primitive;
|
||||
use usdpl_back::AsyncCallable;
|
||||
|
||||
use super::utility::map_optional;
|
||||
use crate::settings::MinMax;
|
||||
//use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
||||
use super::handler::{ApiMessage, GpuMessage};
|
||||
|
@ -94,8 +95,8 @@ pub fn set_clock_limits(
|
|||
let safe_max = if max < min { min } else { max };
|
||||
let safe_min = if min > max { max } else { min };
|
||||
setter(MinMax {
|
||||
min: safe_min as _,
|
||||
max: safe_max as _,
|
||||
min: Some(safe_min as _),
|
||||
max: Some(safe_max as _),
|
||||
});
|
||||
vec![(safe_min as u64).into(), (safe_max as u64).into()]
|
||||
} else {
|
||||
|
@ -105,6 +106,7 @@ pub fn set_clock_limits(
|
|||
vec!["set_clock_limits missing parameter 0".into()]
|
||||
}
|
||||
}
|
||||
// TODO allow param 0 and/or 1 to be Primitive::Empty
|
||||
}
|
||||
|
||||
pub fn get_clock_limits(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
|
@ -131,7 +133,7 @@ pub fn get_clock_limits(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
|||
set_get: getter,
|
||||
trans_getter: |clocks: Option<MinMax<u64>>| {
|
||||
clocks
|
||||
.map(|x| vec![x.min.into(), x.max.into()])
|
||||
.map(|x| vec![map_optional(x.min), map_optional(x.max)])
|
||||
.unwrap_or_else(|| vec![Primitive::Empty, Primitive::Empty])
|
||||
},
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ pub enum BatteryMessage {
|
|||
ReadChargeNow(Callback<Option<f64>>),
|
||||
ReadChargeDesign(Callback<Option<f64>>),
|
||||
ReadCurrentNow(Callback<Option<f64>>),
|
||||
ReadChargePower(Callback<Option<f64>>),
|
||||
SetChargeLimit(Option<f64>),
|
||||
GetChargeLimit(Callback<Option<f64>>),
|
||||
}
|
||||
|
@ -55,6 +56,7 @@ impl BatteryMessage {
|
|||
Self::ReadChargeNow(cb) => cb(settings.read_charge_now()),
|
||||
Self::ReadChargeDesign(cb) => cb(settings.read_charge_design()),
|
||||
Self::ReadCurrentNow(cb) => cb(settings.read_current_now()),
|
||||
Self::ReadChargePower(cb) => cb(settings.read_charge_power()),
|
||||
Self::SetChargeLimit(limit) => settings.charge_limit(limit),
|
||||
Self::GetChargeLimit(cb) => cb(settings.get_charge_limit()),
|
||||
}
|
||||
|
@ -268,7 +270,9 @@ impl ApiMessageHandler {
|
|||
while let Ok(msg) = self.intake.try_recv() {
|
||||
dirty |= self.process(settings, msg);
|
||||
}
|
||||
if dirty /*|| dirty_echo */ {
|
||||
if dirty
|
||||
/*|| dirty_echo */
|
||||
{
|
||||
//dirty_echo = dirty; // echo only once
|
||||
|
||||
// run on_set
|
||||
|
@ -288,6 +292,16 @@ impl ApiMessageHandler {
|
|||
let settings_clone = settings.json();
|
||||
let save_json: SettingsJson = settings_clone.into();
|
||||
unwrap_maybe_fatal(save_json.save(&save_path), "Failed to save settings");
|
||||
if let Some(event) = &settings.general.on_event().on_save {
|
||||
if !event.is_empty() {
|
||||
unwrap_maybe_fatal(
|
||||
std::process::Command::new("/bin/bash")
|
||||
.args(&["-c", event])
|
||||
.spawn(),
|
||||
"Failed to start on_save event command",
|
||||
);
|
||||
}
|
||||
}
|
||||
log::debug!("Saved settings to {}", save_path.display());
|
||||
if let Err(e) = crate::utility::chown_settings_dir() {
|
||||
log::error!("Failed to change config dir permissions: {}", e);
|
||||
|
|
141
backend/src/api/message.rs
Normal file
141
backend/src/api/message.rs
Normal file
|
@ -0,0 +1,141 @@
|
|||
use std::sync::{atomic::{AtomicU64, Ordering}, Arc};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use usdpl_back::AsyncCallable;
|
||||
use usdpl_back::core::serdes::Primitive;
|
||||
|
||||
use limits_core::json::DeveloperMessage;
|
||||
|
||||
use crate::MESSAGE_SEEN_ID_FILE;
|
||||
use crate::utility::settings_dir;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct ApiMessage {
|
||||
/// Message identifier
|
||||
pub id: Option<u64>,
|
||||
/// Message title
|
||||
pub title: String,
|
||||
/// Message content
|
||||
pub body: String,
|
||||
/// Link for further information
|
||||
pub url: Option<String>,
|
||||
}
|
||||
|
||||
impl std::convert::From<DeveloperMessage> for ApiMessage {
|
||||
fn from(other: DeveloperMessage) -> Self {
|
||||
Self {
|
||||
id: Some(other.id),
|
||||
title: other.title,
|
||||
body: other.body,
|
||||
url: other.url,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_dev_messages() -> Vec<ApiMessage> {
|
||||
crate::settings::get_dev_messages().drain(..).map(|msg| ApiMessage::from(msg)).collect()
|
||||
}
|
||||
|
||||
pub struct MessageHandler {
|
||||
seen: Arc<AtomicU64>,
|
||||
}
|
||||
|
||||
impl MessageHandler {
|
||||
pub fn new() -> Self {
|
||||
let last_seen_id = if let Ok(last_seen_id_bytes) = std::fs::read(settings_dir().join(MESSAGE_SEEN_ID_FILE)) {
|
||||
if last_seen_id_bytes.len() >= 8 /* bytes in u64 */ {
|
||||
u64::from_le_bytes([
|
||||
last_seen_id_bytes[0],
|
||||
last_seen_id_bytes[1],
|
||||
last_seen_id_bytes[2],
|
||||
last_seen_id_bytes[3],
|
||||
last_seen_id_bytes[4],
|
||||
last_seen_id_bytes[5],
|
||||
last_seen_id_bytes[6],
|
||||
last_seen_id_bytes[7],
|
||||
])
|
||||
} else {
|
||||
u64::MAX
|
||||
}
|
||||
} else {
|
||||
u64::MIN
|
||||
};
|
||||
Self {
|
||||
seen: Arc::new(AtomicU64::new(last_seen_id)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_callables(self) -> (AsyncMessageGetter, AsyncMessageDismisser) {
|
||||
(
|
||||
AsyncMessageGetter {
|
||||
seen: self.seen.clone(),
|
||||
},
|
||||
AsyncMessageDismisser {
|
||||
seen: self.seen.clone(),
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AsyncMessageGetter {
|
||||
seen: Arc<AtomicU64>,
|
||||
}
|
||||
|
||||
impl AsyncMessageGetter {
|
||||
fn remove_before_id(id: u64, messages: impl Iterator<Item=ApiMessage>) -> impl Iterator<Item=ApiMessage> {
|
||||
messages.skip_while(move |msg| if let Some(msg_id) = msg.id { msg_id <= id } else { true })
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl AsyncCallable for AsyncMessageGetter {
|
||||
async fn call(&self, params: super::ApiParameterType) -> super::ApiParameterType {
|
||||
let since = if let Some(param0) = params.get(0) {
|
||||
if let Primitive::Empty = param0 {
|
||||
self.seen.load(Ordering::Relaxed)
|
||||
} else if let Primitive::U64(since) = param0 {
|
||||
*since
|
||||
} else {
|
||||
return vec!["get message invalid parameter 0".into()];
|
||||
}
|
||||
} else {
|
||||
self.seen.load(Ordering::Relaxed)
|
||||
};
|
||||
let mut messages = get_dev_messages();
|
||||
Self::remove_before_id(since, messages.drain(..))
|
||||
.filter_map(|msg| serde_json::to_string(&msg).ok().map(|x| Primitive::Json(x)))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AsyncMessageDismisser {
|
||||
seen: Arc<AtomicU64>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl AsyncCallable for AsyncMessageDismisser {
|
||||
async fn call(&self, params: super::ApiParameterType) -> super::ApiParameterType {
|
||||
let id = if let Some(param0) = params.get(0) {
|
||||
if let Primitive::Empty = param0 {
|
||||
None
|
||||
} else if let Primitive::F64(since) = param0 {
|
||||
Some(*since as u64)
|
||||
} else {
|
||||
return vec!["dismiss message invalid parameter 0".into()];
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if let Some(id) = id {
|
||||
self.seen.store(id, Ordering::Relaxed);
|
||||
let filename = settings_dir().join(MESSAGE_SEEN_ID_FILE);
|
||||
if let Err(e) = std::fs::write(&filename, id.to_le_bytes()) {
|
||||
log::error!("Failed to write seen id to {}: {}", filename.display(), e);
|
||||
}
|
||||
} else {
|
||||
// TODO clear non-dev messages in cache
|
||||
}
|
||||
vec![true.into()]
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ pub mod cpu;
|
|||
pub mod general;
|
||||
pub mod gpu;
|
||||
pub mod handler;
|
||||
pub mod message;
|
||||
mod utility;
|
||||
|
||||
pub(super) type ApiParameterType = Vec<usdpl_back::core::serdes::Primitive>;
|
||||
|
|
|
@ -19,10 +19,7 @@ pub fn map_optional_result<T: Into<Primitive>>(
|
|||
result: Result<Option<T>, SettingError>,
|
||||
) -> super::ApiParameterType {
|
||||
match result {
|
||||
Ok(val) => match val {
|
||||
Some(val) => vec![val.into()],
|
||||
None => vec![Primitive::Empty],
|
||||
},
|
||||
Ok(val) => vec![map_optional(val)],
|
||||
Err(e) => {
|
||||
log::debug!("Mapping error to primitive: {}", e);
|
||||
vec![e.msg.into()]
|
||||
|
@ -30,6 +27,13 @@ pub fn map_optional_result<T: Into<Primitive>>(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn map_optional<T: Into<Primitive>>(option: Option<T>) -> Primitive {
|
||||
match option {
|
||||
Some(val) => val.into(),
|
||||
None => Primitive::Empty,
|
||||
}
|
||||
}
|
||||
|
||||
/*#[inline]
|
||||
pub fn map_empty_result<T: Into<Primitive>>(
|
||||
result: Result<(), SettingError>,
|
||||
|
|
|
@ -7,3 +7,5 @@ pub const DEFAULT_SETTINGS_FILE: &str = "default_settings.json";
|
|||
pub const DEFAULT_SETTINGS_NAME: &str = "Main";
|
||||
|
||||
pub const LIMITS_FILE: &str = "limits_cache.json";
|
||||
|
||||
pub const MESSAGE_SEEN_ID_FILE: &str = "seen_message.bin";
|
||||
|
|
|
@ -73,10 +73,6 @@ fn main() -> Result<(), ()> {
|
|||
}
|
||||
|
||||
let _limits_handle = crate::settings::limits_worker_spawn();
|
||||
log::info!(
|
||||
"Detected device automatically, starting with driver: {:?} (This can be overriden)",
|
||||
crate::settings::auto_detect_provider()
|
||||
);
|
||||
|
||||
let mut loaded_settings =
|
||||
persist::SettingsJson::open(utility::settings_dir().join(DEFAULT_SETTINGS_FILE))
|
||||
|
@ -88,6 +84,11 @@ fn main() -> Result<(), ()> {
|
|||
)
|
||||
});
|
||||
|
||||
log::info!(
|
||||
"Detected device automatically {:?}, using driver: {:?} (This can be overriden)",
|
||||
crate::settings::auto_detect_provider(), loaded_settings.cpus.provider()
|
||||
);
|
||||
|
||||
log::debug!("Settings: {:?}", loaded_settings);
|
||||
|
||||
let (api_handler, api_sender) = crate::api::handler::ApiMessageHandler::new();
|
||||
|
@ -96,6 +97,8 @@ fn main() -> Result<(), ()> {
|
|||
let _resume_handle = resume_worker::spawn(api_sender.clone());
|
||||
let _power_handle = power_worker::spawn(api_sender.clone());
|
||||
|
||||
let (message_getter, message_dismisser) = api::message::MessageHandler::new().to_callables();
|
||||
|
||||
let instance = Instance::new(PORT)
|
||||
.register("V_INFO", |_: Vec<Primitive>| {
|
||||
#[cfg(debug_assertions)]
|
||||
|
@ -126,6 +129,10 @@ fn main() -> Result<(), ()> {
|
|||
"BATTERY_charge_design",
|
||||
api::battery::charge_design(api_sender.clone()),
|
||||
)
|
||||
.register_async(
|
||||
"BATTERY_charge_power",
|
||||
api::battery::charge_power(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"BATTERY_set_charge_rate",
|
||||
api::battery::set_charge_rate(api_sender.clone()),
|
||||
|
@ -279,7 +286,13 @@ fn main() -> Result<(), ()> {
|
|||
.register(
|
||||
"GENERAL_on_unplugged",
|
||||
api::battery::on_unplugged(api_sender.clone()),
|
||||
);
|
||||
)
|
||||
.register_async(
|
||||
"GENERAL_get_periodicals",
|
||||
api::general::get_periodicals(api_sender.clone())
|
||||
)
|
||||
.register_async("MESSAGE_get", message_getter)
|
||||
.register_async("MESSAGE_dismiss", message_dismisser);
|
||||
|
||||
if let Err(e) = loaded_settings.on_set() {
|
||||
e.iter()
|
||||
|
|
|
@ -9,6 +9,8 @@ pub struct BatteryJson {
|
|||
pub charge_mode: Option<String>,
|
||||
#[serde(default)]
|
||||
pub events: Vec<BatteryEventJson>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub root: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
|
@ -24,6 +26,7 @@ impl Default for BatteryJson {
|
|||
charge_rate: None,
|
||||
charge_mode: None,
|
||||
events: Vec::new(),
|
||||
root: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ pub struct CpuJson {
|
|||
pub online: bool,
|
||||
pub clock_limits: Option<MinMaxJson<u64>>,
|
||||
pub governor: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub root: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for CpuJson {
|
||||
|
@ -20,6 +22,7 @@ impl Default for CpuJson {
|
|||
online: true,
|
||||
clock_limits: None,
|
||||
governor: "schedutil".to_owned(),
|
||||
root: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,25 @@ use serde::{Deserialize, Serialize};
|
|||
use super::JsonError;
|
||||
use super::{BatteryJson, CpuJson, DriverJson, GpuJson};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct OnEventJson {
|
||||
pub on_save: Option<String>,
|
||||
pub on_load: Option<String>,
|
||||
pub on_set: Option<String>,
|
||||
pub on_resume: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for OnEventJson {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
on_save: None,
|
||||
on_load: None,
|
||||
on_set: None,
|
||||
on_resume: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SettingsJson {
|
||||
pub version: u64,
|
||||
|
@ -14,6 +33,7 @@ pub struct SettingsJson {
|
|||
pub gpu: GpuJson,
|
||||
pub battery: BatteryJson,
|
||||
pub provider: Option<DriverJson>,
|
||||
pub events: Option<OnEventJson>,
|
||||
}
|
||||
|
||||
impl Default for SettingsJson {
|
||||
|
@ -26,6 +46,7 @@ impl Default for SettingsJson {
|
|||
gpu: GpuJson::default(),
|
||||
battery: BatteryJson::default(),
|
||||
provider: None,
|
||||
events: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +79,6 @@ impl SettingsJson {
|
|||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct MinMaxJson<T> {
|
||||
pub max: T,
|
||||
pub min: T,
|
||||
pub max: Option<T>,
|
||||
pub min: Option<T>,
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ pub struct GpuJson {
|
|||
pub slow_ppt: Option<u64>,
|
||||
pub clock_limits: Option<MinMaxJson<u64>>,
|
||||
pub slow_memory: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub root: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for GpuJson {
|
||||
|
@ -19,6 +21,7 @@ impl Default for GpuJson {
|
|||
slow_ppt: None,
|
||||
clock_limits: None,
|
||||
slow_memory: false,
|
||||
root: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ mod gpu;
|
|||
pub use battery::{BatteryEventJson, BatteryJson};
|
||||
pub use cpu::CpuJson;
|
||||
pub use driver::DriverJson;
|
||||
pub use general::{MinMaxJson, SettingsJson};
|
||||
pub use general::{MinMaxJson, OnEventJson, SettingsJson};
|
||||
pub use gpu::GpuJson;
|
||||
|
||||
pub use error::JsonError;
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::time::{Duration, Instant};
|
|||
use crate::api::handler::ApiMessage;
|
||||
//use crate::utility::unwrap_maybe_fatal;
|
||||
|
||||
const ALLOWED_ERROR: f64 = 100.0; // period of 10ms with 100x means sleep has to be >= 1s to be detected
|
||||
const ALLOWED_ERROR: f64 = 20.0; // period of 50ms with 20x means sleep has to be >= 1s to be detected
|
||||
|
||||
pub fn spawn(sender: Sender<ApiMessage>) -> JoinHandle<()> {
|
||||
thread::spawn(move || {
|
||||
|
|
|
@ -303,6 +303,7 @@ impl DriverBuilder {
|
|||
path: json_path,
|
||||
name: profile_name,
|
||||
driver: DriverJson::AutoDetect,
|
||||
events: Default::default(),
|
||||
}),
|
||||
cpus: None,
|
||||
gpu: None,
|
||||
|
|
|
@ -3,3 +3,4 @@ pub mod limits_worker;
|
|||
mod utility;
|
||||
|
||||
pub use auto_detect::{auto_detect0, auto_detect_provider};
|
||||
pub use utility::get_dev_messages;
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
use limits_core::json::{DeveloperMessage, Base};
|
||||
|
||||
pub fn limits_path() -> std::path::PathBuf {
|
||||
crate::utility::settings_dir().join(crate::consts::LIMITS_FILE)
|
||||
}
|
||||
|
||||
// NOTE: eats errors
|
||||
pub fn get_dev_messages() -> Vec<DeveloperMessage> {
|
||||
let limits_path = limits_path();
|
||||
if let Ok(file) = std::fs::File::open(&limits_path) {
|
||||
if let Ok(base) = serde_json::from_reader::<_, Base>(file) {
|
||||
base.messages
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ impl Driver {
|
|||
path: json_path,
|
||||
name: settings.name,
|
||||
driver: DriverJson::SteamDeck,
|
||||
events: settings.events.unwrap_or_default(),
|
||||
}),
|
||||
cpus: Box::new(super::steam_deck::Cpus::from_json(
|
||||
settings.cpus,
|
||||
|
@ -51,6 +52,7 @@ impl Driver {
|
|||
path: json_path,
|
||||
name: settings.name,
|
||||
driver: DriverJson::SteamDeck,
|
||||
events: settings.events.unwrap_or_default(),
|
||||
}),
|
||||
cpus: Box::new(super::steam_deck::Cpus::from_json(
|
||||
settings.cpus,
|
||||
|
@ -72,6 +74,7 @@ impl Driver {
|
|||
path: json_path,
|
||||
name: settings.name,
|
||||
driver: DriverJson::SteamDeckAdvance,
|
||||
events: settings.events.unwrap_or_default(),
|
||||
}),
|
||||
cpus: Box::new(super::steam_deck::Cpus::from_json(
|
||||
settings.cpus,
|
||||
|
|
|
@ -34,16 +34,43 @@ pub struct General {
|
|||
pub path: PathBuf,
|
||||
pub name: String,
|
||||
pub driver: crate::persist::DriverJson,
|
||||
pub events: crate::persist::OnEventJson,
|
||||
}
|
||||
|
||||
impl OnSet for General {
|
||||
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
|
||||
if let Some(event) = &self.events.on_set {
|
||||
if !event.is_empty() {
|
||||
std::process::Command::new("/bin/bash")
|
||||
.args(&["-c", event])
|
||||
.spawn()
|
||||
.map_err(|e| {
|
||||
vec![SettingError {
|
||||
msg: format!("on_set event command error: {}", e),
|
||||
setting: SettingVariant::General,
|
||||
}]
|
||||
})?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl OnResume for General {
|
||||
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
|
||||
if let Some(event) = &self.events.on_resume {
|
||||
if !event.is_empty() {
|
||||
std::process::Command::new("/bin/bash")
|
||||
.args(&["-c", event])
|
||||
.spawn()
|
||||
.map_err(|e| {
|
||||
vec![SettingError {
|
||||
msg: format!("on_resume event command error: {}", e),
|
||||
setting: SettingVariant::General,
|
||||
}]
|
||||
})?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +109,10 @@ impl TGeneral for General {
|
|||
fn provider(&self) -> crate::persist::DriverJson {
|
||||
self.driver.clone()
|
||||
}
|
||||
|
||||
fn on_event(&self) -> &crate::persist::OnEventJson {
|
||||
&self.events
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -214,6 +245,17 @@ impl Settings {
|
|||
*self.general.persistent() = false;
|
||||
}
|
||||
self.general.path(filename);
|
||||
if let Some(event) = &self.general.on_event().on_load {
|
||||
if !event.is_empty() {
|
||||
std::process::Command::new("/bin/bash")
|
||||
.args(&["-c", event])
|
||||
.spawn()
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("on_save event command error: {}", e),
|
||||
setting: SettingVariant::General,
|
||||
})?;
|
||||
}
|
||||
}
|
||||
Ok(*self.general.persistent())
|
||||
}
|
||||
|
||||
|
@ -257,6 +299,7 @@ impl Settings {
|
|||
gpu: self.gpu.json(),
|
||||
battery: self.battery.json(),
|
||||
provider: Some(self.general.provider()),
|
||||
events: Some(self.general.on_event().clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::convert::Into;
|
||||
|
||||
use limits_core::json::GenericBatteryLimit;
|
||||
use sysfuss::SysEntity;
|
||||
|
||||
use crate::persist::BatteryJson;
|
||||
use crate::settings::TBattery;
|
||||
|
@ -10,6 +11,7 @@ use crate::settings::{OnResume, OnSet, SettingError};
|
|||
pub struct Battery {
|
||||
#[allow(dead_code)]
|
||||
limits: GenericBatteryLimit,
|
||||
sysfs: sysfuss::PowerSupplyPath,
|
||||
}
|
||||
|
||||
impl Into<BatteryJson> for Battery {
|
||||
|
@ -19,6 +21,7 @@ impl Into<BatteryJson> for Battery {
|
|||
charge_rate: None,
|
||||
charge_mode: None,
|
||||
events: Vec::default(),
|
||||
root: self.sysfs.root().and_then(|p| p.as_ref().to_str().map(|s| s.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,18 +40,41 @@ impl Battery {
|
|||
}
|
||||
}
|
||||
|
||||
fn find_psu_sysfs(root: Option<impl AsRef<std::path::Path>>) -> sysfuss::PowerSupplyPath {
|
||||
let root = crate::settings::util::root_or_default_sysfs(root);
|
||||
match root.power_supply(crate::settings::util::always_satisfied) {
|
||||
Ok(mut iter) => {
|
||||
iter.next()
|
||||
.unwrap_or_else(|| {
|
||||
log::error!("Failed to find generic battery power_supply in sysfs (no results), using naive fallback");
|
||||
root.power_supply_by_name("BAT0")
|
||||
})
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Failed to find generic battery power_supply in sysfs ({}), using naive fallback", e);
|
||||
root.power_supply_by_name("BAT0")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_limits(limits: limits_core::json::GenericBatteryLimit) -> Self {
|
||||
// TODO
|
||||
Self { limits }
|
||||
Self {
|
||||
limits,
|
||||
sysfs: Self::find_psu_sysfs(None::<&'static str>),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_json_and_limits(
|
||||
_other: BatteryJson,
|
||||
other: BatteryJson,
|
||||
_version: u64,
|
||||
limits: limits_core::json::GenericBatteryLimit,
|
||||
) -> Self {
|
||||
// TODO
|
||||
Self { limits }
|
||||
Self {
|
||||
limits,
|
||||
sysfs: Self::find_psu_sysfs(other.root)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,6 +155,10 @@ impl TBattery for Battery {
|
|||
None
|
||||
}
|
||||
|
||||
fn read_charge_power(&self) -> Option<f64> {
|
||||
None
|
||||
}
|
||||
|
||||
fn charge_limit(&mut self, _limit: Option<f64>) {}
|
||||
|
||||
fn get_charge_limit(&self) -> Option<f64> {
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::convert::{AsMut, AsRef, Into};
|
|||
use limits_core::json::GenericCpuLimit;
|
||||
|
||||
use super::FromGenericCpuInfo;
|
||||
use crate::api::RangeLimit;
|
||||
use crate::persist::CpuJson;
|
||||
use crate::settings::{min_max_from_json, MinMax};
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
|
@ -201,6 +202,7 @@ pub struct Cpu {
|
|||
limits: GenericCpuLimit,
|
||||
index: usize,
|
||||
state: crate::state::steam_deck::Cpu,
|
||||
root: std::path::PathBuf,
|
||||
}
|
||||
|
||||
/*impl Cpu {
|
||||
|
@ -234,6 +236,7 @@ impl FromGenericCpuInfo for Cpu {
|
|||
limits,
|
||||
index: cpu_index,
|
||||
state: crate::state::steam_deck::Cpu::default(),
|
||||
root: "/".into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,6 +260,7 @@ impl FromGenericCpuInfo for Cpu {
|
|||
limits,
|
||||
index: i,
|
||||
state: crate::state::steam_deck::Cpu::default(),
|
||||
root: other.root.unwrap_or_else(|| "/".to_string()).into(),
|
||||
},
|
||||
_ => Self {
|
||||
online: other.online,
|
||||
|
@ -265,6 +269,7 @@ impl FromGenericCpuInfo for Cpu {
|
|||
limits,
|
||||
index: i,
|
||||
state: crate::state::steam_deck::Cpu::default(),
|
||||
root: other.root.unwrap_or_else(|| "/".to_string()).into(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -330,8 +335,16 @@ impl Cpu {
|
|||
|
||||
fn limits(&self) -> crate::api::CpuLimits {
|
||||
crate::api::CpuLimits {
|
||||
clock_min_limits: self.limits.clock_min.clone().map(|x| x.into()),
|
||||
clock_max_limits: self.limits.clock_max.clone().map(|x| x.into()),
|
||||
clock_min_limits: self
|
||||
.limits
|
||||
.clock_min
|
||||
.clone()
|
||||
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(5_000))),
|
||||
clock_max_limits: self
|
||||
.limits
|
||||
.clock_max
|
||||
.clone()
|
||||
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(5_000))),
|
||||
clock_step: self.limits.clock_step,
|
||||
governors: self.governors(),
|
||||
}
|
||||
|
@ -345,6 +358,7 @@ impl Into<CpuJson> for Cpu {
|
|||
online: self.online,
|
||||
clock_limits: self.clock_limits.map(|x| x.into()),
|
||||
governor: self.governor,
|
||||
root: self.root.to_str().map(|s| s.to_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
use std::convert::Into;
|
||||
|
||||
use limits_core::json::GenericGpuLimit;
|
||||
use sysfuss::{BasicEntityPath, SysEntity};
|
||||
|
||||
use crate::api::RangeLimit;
|
||||
use crate::persist::GpuJson;
|
||||
use crate::settings::TGpu;
|
||||
use crate::settings::{min_max_from_json, MinMax};
|
||||
|
@ -14,6 +16,7 @@ pub struct Gpu {
|
|||
pub slow_ppt: Option<u64>,
|
||||
pub clock_limits: Option<MinMax<u64>>,
|
||||
limits: GenericGpuLimit,
|
||||
sysfs: BasicEntityPath,
|
||||
}
|
||||
|
||||
impl Gpu {
|
||||
|
@ -30,6 +33,23 @@ impl Gpu {
|
|||
}
|
||||
}*/
|
||||
|
||||
fn find_card_sysfs(root: Option<impl AsRef<std::path::Path>>) -> BasicEntityPath {
|
||||
let root = crate::settings::util::root_or_default_sysfs(root);
|
||||
match root.class("drm", crate::settings::util::always_satisfied) {
|
||||
Ok(mut iter) => {
|
||||
iter.next()
|
||||
.unwrap_or_else(|| {
|
||||
log::error!("Failed to find generic gpu drm in sysfs (no results), using naive fallback");
|
||||
BasicEntityPath::new(root.as_ref().join("sys/class/drm/card0"))
|
||||
})
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Failed to find generic gpu drm in sysfs ({}), using naive fallback", e);
|
||||
BasicEntityPath::new(root.as_ref().join("sys/class/drm/card0"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_limits(limits: limits_core::json::GenericGpuLimit) -> Self {
|
||||
Self {
|
||||
slow_memory: false,
|
||||
|
@ -37,6 +57,7 @@ impl Gpu {
|
|||
slow_ppt: None,
|
||||
clock_limits: None,
|
||||
limits,
|
||||
sysfs: Self::find_card_sysfs(None::<&'static str>),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,6 +85,7 @@ impl Gpu {
|
|||
},
|
||||
clock_limits: clock_lims,
|
||||
limits,
|
||||
sysfs: Self::find_card_sysfs(other.root)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +98,7 @@ impl Into<GpuJson> for Gpu {
|
|||
slow_ppt: self.slow_ppt,
|
||||
clock_limits: self.clock_limits.map(|x| x.into()),
|
||||
slow_memory: false,
|
||||
root: self.sysfs.root().and_then(|p| p.as_ref().to_str().map(|s| s.to_owned()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,14 +120,38 @@ impl crate::settings::OnPowerEvent for Gpu {}
|
|||
impl TGpu for Gpu {
|
||||
fn limits(&self) -> crate::api::GpuLimits {
|
||||
crate::api::GpuLimits {
|
||||
fast_ppt_limits: self.limits.fast_ppt.clone().map(|x| x.into()),
|
||||
slow_ppt_limits: self.limits.slow_ppt.clone().map(|x| x.into()),
|
||||
fast_ppt_limits: self
|
||||
.limits
|
||||
.fast_ppt
|
||||
.clone()
|
||||
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(15_000_000))),
|
||||
slow_ppt_limits: self
|
||||
.limits
|
||||
.slow_ppt
|
||||
.clone()
|
||||
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(15_000_000))),
|
||||
ppt_step: self.limits.ppt_step.unwrap_or(1_000_000),
|
||||
tdp_limits: self.limits.tdp.clone().map(|x| x.into()),
|
||||
tdp_boost_limits: self.limits.tdp_boost.clone().map(|x| x.into()),
|
||||
tdp_limits: self
|
||||
.limits
|
||||
.tdp
|
||||
.clone()
|
||||
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(15_000_000))),
|
||||
tdp_boost_limits: self
|
||||
.limits
|
||||
.tdp_boost
|
||||
.clone()
|
||||
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(15_000_000))),
|
||||
tdp_step: self.limits.tdp_step.unwrap_or(42),
|
||||
clock_min_limits: self.limits.clock_min.clone().map(|x| x.into()),
|
||||
clock_max_limits: self.limits.clock_max.clone().map(|x| x.into()),
|
||||
clock_min_limits: self
|
||||
.limits
|
||||
.clock_min
|
||||
.clone()
|
||||
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(3_000))),
|
||||
clock_max_limits: self
|
||||
.limits
|
||||
.clock_max
|
||||
.clone()
|
||||
.map(|x| RangeLimit::new(x.min.unwrap_or(0), x.max.unwrap_or(3_000))),
|
||||
clock_step: self.limits.clock_step.unwrap_or(100),
|
||||
memory_control_capable: false,
|
||||
}
|
||||
|
@ -116,10 +163,20 @@ impl TGpu for Gpu {
|
|||
|
||||
fn ppt(&mut self, fast: Option<u64>, slow: Option<u64>) {
|
||||
if let Some(fast_lims) = &self.limits.fast_ppt {
|
||||
self.fast_ppt = fast.map(|x| x.clamp(fast_lims.min, fast_lims.max));
|
||||
self.fast_ppt = fast.map(|x| {
|
||||
x.clamp(
|
||||
fast_lims.min.unwrap_or(0),
|
||||
fast_lims.max.unwrap_or(u64::MAX),
|
||||
)
|
||||
});
|
||||
}
|
||||
if let Some(slow_lims) = &self.limits.slow_ppt {
|
||||
self.slow_ppt = slow.map(|x| x.clamp(slow_lims.min, slow_lims.max));
|
||||
self.slow_ppt = slow.map(|x| {
|
||||
x.clamp(
|
||||
slow_lims.min.unwrap_or(0),
|
||||
slow_lims.max.unwrap_or(u64::MAX),
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -128,24 +128,22 @@ impl Gpu {
|
|||
}
|
||||
if let Some(clock_limits) = &self.generic.clock_limits {
|
||||
self.state.clock_limits_set = true;
|
||||
lock.set_max_gfxclk_freq(clock_limits.max as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"RyzenAdj set_max_gfxclk_freq({}) err: {}",
|
||||
clock_limits.max, e
|
||||
),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_min_gfxclk_freq(clock_limits.min as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"RyzenAdj set_min_gfxclk_freq({}) err: {}",
|
||||
clock_limits.min, e
|
||||
),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
if let Some(max) = clock_limits.max {
|
||||
lock.set_max_gfxclk_freq(max as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", max, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
if let Some(min) = clock_limits.min {
|
||||
lock.set_min_gfxclk_freq(min as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", min, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
} else if self.state.clock_limits_set {
|
||||
self.state.clock_limits_set = false;
|
||||
let limits = self.generic.limits();
|
||||
|
@ -218,24 +216,22 @@ impl Gpu {
|
|||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
if let Some(clock_limits) = &self.generic.clock_limits {
|
||||
lock.set_max_gfxclk_freq(clock_limits.max as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"RyzenAdj set_max_gfxclk_freq({}) err: {}",
|
||||
clock_limits.max, e
|
||||
),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_min_gfxclk_freq(clock_limits.min as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"RyzenAdj set_min_gfxclk_freq({}) err: {}",
|
||||
clock_limits.min, e
|
||||
),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
if let Some(max) = clock_limits.max {
|
||||
lock.set_max_gfxclk_freq(max as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", max, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
if let Some(min) = clock_limits.min {
|
||||
lock.set_min_gfxclk_freq(min as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", min, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ pub type MinMax<T> = RangeLimit<T>;
|
|||
|
||||
pub fn min_max_from_json<T, X: Into<T>>(other: MinMaxJson<X>, _version: u64) -> MinMax<T> {
|
||||
MinMax {
|
||||
max: other.max.into(),
|
||||
min: other.min.into(),
|
||||
max: other.max.map(|x| x.into()),
|
||||
min: other.min.map(|x| x.into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,8 @@ impl<X: Into<Y>, Y> Into<MinMaxJson<Y>> for RangeLimit<X> {
|
|||
#[inline]
|
||||
fn into(self) -> MinMaxJson<Y> {
|
||||
MinMaxJson {
|
||||
max: self.max.into(),
|
||||
min: self.min.into(),
|
||||
max: self.max.map(|x| x.into()),
|
||||
min: self.min.map(|x| x.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ pub mod generic_amd;
|
|||
pub mod steam_deck;
|
||||
pub mod unknown;
|
||||
|
||||
pub use detect::{auto_detect0, auto_detect_provider, limits_worker::spawn as limits_worker_spawn};
|
||||
pub use detect::{auto_detect0, auto_detect_provider, limits_worker::spawn as limits_worker_spawn, get_dev_messages};
|
||||
pub use driver::Driver;
|
||||
pub use general::{General, SettingVariant, Settings};
|
||||
pub use min_max::{min_max_from_json, MinMax};
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
use std::convert::Into;
|
||||
use std::sync::Arc;
|
||||
|
||||
use sysfuss::{PowerSupplyAttribute, PowerSupplyPath, HwMonAttribute, HwMonAttributeItem, HwMonAttributeType, HwMonPath, SysEntity, SysEntityAttributesExt, SysAttribute};
|
||||
use sysfuss::capability::attributes;
|
||||
|
||||
use super::oc_limits::{BatteryLimits, OverclockLimits};
|
||||
use super::util::ChargeMode;
|
||||
|
@ -15,6 +19,8 @@ pub struct Battery {
|
|||
limits: BatteryLimits,
|
||||
state: crate::state::steam_deck::Battery,
|
||||
driver_mode: crate::persist::DriverJson,
|
||||
sysfs_bat: PowerSupplyPath,
|
||||
sysfs_hwmon: Arc<HwMonPath>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -32,6 +38,7 @@ struct EventInstruction {
|
|||
charge_rate: Option<u64>,
|
||||
charge_mode: Option<ChargeMode>,
|
||||
is_triggered: bool,
|
||||
sysfs_hwmon: Arc<HwMonPath>,
|
||||
}
|
||||
|
||||
impl OnPowerEvent for EventInstruction {
|
||||
|
@ -99,17 +106,17 @@ impl EventInstruction {
|
|||
.trim_start_matches('>')
|
||||
.parse::<f64>()
|
||||
.ok()
|
||||
.map(|x| EventTrigger::BatteryAbove(x/100.0)),
|
||||
.map(|x| EventTrigger::BatteryAbove(x / 100.0)),
|
||||
s if s.starts_with('<') => s
|
||||
.trim_start_matches('<')
|
||||
.parse::<f64>()
|
||||
.ok()
|
||||
.map(|x| EventTrigger::BatteryBelow(x/100.0)),
|
||||
.map(|x| EventTrigger::BatteryBelow(x / 100.0)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_json(other: BatteryEventJson, _version: u64) -> Self {
|
||||
fn from_json(other: BatteryEventJson, _version: u64, hwmon: Arc<HwMonPath>) -> Self {
|
||||
Self {
|
||||
trigger: Self::str_to_trigger(&other.trigger).unwrap_or(EventTrigger::Ignored),
|
||||
charge_rate: other.charge_rate,
|
||||
|
@ -118,6 +125,7 @@ impl EventInstruction {
|
|||
.map(|x| Battery::str_to_charge_mode(&x))
|
||||
.flatten(),
|
||||
is_triggered: false,
|
||||
sysfs_hwmon: hwmon,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,12 +144,17 @@ impl EventInstruction {
|
|||
|
||||
fn set_charge_rate(&self) -> Result<(), SettingError> {
|
||||
if let Some(charge_rate) = self.charge_rate {
|
||||
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
||||
let attr = if MAX_BATTERY_CHARGE_RATE_ATTR.exists(&*self.sysfs_hwmon) {
|
||||
MAX_BATTERY_CHARGE_RATE_ATTR
|
||||
} else {
|
||||
MAXIMUM_BATTERY_CHARGE_RATE_ATTR
|
||||
};
|
||||
self.sysfs_hwmon.set(attr, charge_rate).map_err(
|
||||
|e| SettingError {
|
||||
msg: format!("Failed to write to `{:?}`: {}", attr, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
})
|
||||
.map(|_| ())
|
||||
},
|
||||
)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -173,12 +186,36 @@ impl Into<BatteryEventJson> for EventInstruction {
|
|||
|
||||
const BATTERY_VOLTAGE: f64 = 7.7;
|
||||
|
||||
const BATTERY_CHARGE_RATE_PATH: &str = "/sys/class/hwmon/hwmon5/maximum_battery_charge_rate"; // write-only
|
||||
/*const BATTERY_CHARGE_RATE_PATH: &str = "/sys/class/hwmon/hwmon5/maximum_battery_charge_rate"; // write-only
|
||||
const BATTERY_CURRENT_NOW_PATH: &str = "/sys/class/power_supply/BAT1/current_now"; // read-only
|
||||
const BATTERY_CHARGE_NOW_PATH: &str = "/sys/class/power_supply/BAT1/charge_now"; // read-only
|
||||
const BATTERY_CHARGE_FULL_PATH: &str = "/sys/class/power_supply/BAT1/charge_full"; // read-only
|
||||
const BATTERY_CHARGE_DESIGN_PATH: &str = "/sys/class/power_supply/BAT1/charge_full_design"; // read-only
|
||||
const USB_PD_IN_MVOLTAGE_PATH: &str = "/sys/class/hwmon/hwmon5/in0_input"; // read-only
|
||||
const USB_PD_IN_CURRENT_PATH: &str = "/sys/class/hwmon/hwmon5/curr1_input"; // read-only*/
|
||||
|
||||
|
||||
const BATTERY_NEEDS: &[PowerSupplyAttribute] = &[
|
||||
PowerSupplyAttribute::Type,
|
||||
PowerSupplyAttribute::CurrentNow,
|
||||
PowerSupplyAttribute::ChargeNow,
|
||||
PowerSupplyAttribute::ChargeFull,
|
||||
PowerSupplyAttribute::ChargeFullDesign,
|
||||
PowerSupplyAttribute::CycleCount,
|
||||
PowerSupplyAttribute::Capacity,
|
||||
PowerSupplyAttribute::CapacityLevel,
|
||||
];
|
||||
|
||||
const HWMON_NEEDS: &[HwMonAttribute] = &[
|
||||
HwMonAttribute::name(),
|
||||
HwMonAttribute::new(HwMonAttributeType::In, 0, HwMonAttributeItem::Input),
|
||||
HwMonAttribute::new(HwMonAttributeType::Curr, 1, HwMonAttributeItem::Input),
|
||||
//HwMonAttribute::custom("maximum_battery_charge_rate"), // NOTE: Cannot filter by custom capabilities
|
||||
];
|
||||
|
||||
const MAXIMUM_BATTERY_CHARGE_RATE_ATTR: HwMonAttribute = HwMonAttribute::custom("maximum_battery_charge_rate");
|
||||
const MAX_BATTERY_CHARGE_RATE_ATTR: HwMonAttribute = HwMonAttribute::custom("maximum_battery_charge_rate");
|
||||
const MAX_BATTERY_CHARGE_LEVEL_ATTR: HwMonAttribute = HwMonAttribute::custom("max_battery_charge_level");
|
||||
|
||||
impl Battery {
|
||||
#[inline]
|
||||
|
@ -190,6 +227,7 @@ impl Battery {
|
|||
} else {
|
||||
crate::persist::DriverJson::SteamDeckAdvance
|
||||
};
|
||||
let hwmon_sys = Arc::new(Self::find_hwmon_sysfs(None::<&'static str>));
|
||||
match version {
|
||||
0 => Self {
|
||||
charge_rate: other.charge_rate,
|
||||
|
@ -200,11 +238,13 @@ impl Battery {
|
|||
events: other
|
||||
.events
|
||||
.into_iter()
|
||||
.map(|x| EventInstruction::from_json(x, version))
|
||||
.map(|x| EventInstruction::from_json(x, version, hwmon_sys.clone()))
|
||||
.collect(),
|
||||
limits: oc_limits,
|
||||
state: crate::state::steam_deck::Battery::default(),
|
||||
driver_mode: driver,
|
||||
sysfs_bat: Self::find_battery_sysfs(None::<&'static str>),
|
||||
sysfs_hwmon: hwmon_sys,
|
||||
},
|
||||
_ => Self {
|
||||
charge_rate: other.charge_rate,
|
||||
|
@ -215,15 +255,68 @@ impl Battery {
|
|||
events: other
|
||||
.events
|
||||
.into_iter()
|
||||
.map(|x| EventInstruction::from_json(x, version))
|
||||
.map(|x| EventInstruction::from_json(x, version, hwmon_sys.clone()))
|
||||
.collect(),
|
||||
limits: oc_limits,
|
||||
state: crate::state::steam_deck::Battery::default(),
|
||||
driver_mode: driver,
|
||||
sysfs_bat: Self::find_battery_sysfs(None::<&'static str>),
|
||||
sysfs_hwmon: hwmon_sys,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn find_battery_sysfs(root: Option<impl AsRef<std::path::Path>>) -> PowerSupplyPath {
|
||||
let root = crate::settings::util::root_or_default_sysfs(root);
|
||||
match root.power_supply(attributes(BATTERY_NEEDS.into_iter().copied())) {
|
||||
Ok(mut iter) => {
|
||||
let psu = iter.next()
|
||||
.unwrap_or_else(|| {
|
||||
log::error!("Failed to find SteamDeck battery power_supply in sysfs (no results), using naive fallback");
|
||||
root.power_supply_by_name("BAT1")
|
||||
});
|
||||
log::info!("Found SteamDeck battery power_supply in sysfs: {}", psu.as_ref().display());
|
||||
psu
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Failed to find SteamDeck battery power_supply in sysfs ({}), using naive fallback", e);
|
||||
root.power_supply_by_name("BAT1")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_hwmon_sysfs(root: Option<impl AsRef<std::path::Path>>) -> HwMonPath {
|
||||
let root = crate::settings::util::root_or_default_sysfs(root);
|
||||
match root.hwmon_by_name(super::util::JUPITER_HWMON_NAME) {
|
||||
Ok(hwmon) => {
|
||||
if !hwmon.capable(attributes(HWMON_NEEDS.into_iter().copied())) {
|
||||
log::warn!("Found incapable SteamDeck battery hwmon in sysfs (hwmon by name {} exists but missing attributes), persevering because ignorance is bliss", super::util::JUPITER_HWMON_NAME);
|
||||
} else {
|
||||
log::info!("Found SteamDeck battery hwmon {} in sysfs: {}", super::util::JUPITER_HWMON_NAME, hwmon.as_ref().display());
|
||||
}
|
||||
hwmon
|
||||
},
|
||||
Err(e) => {
|
||||
log::warn!("Failed to find SteamDeck battery hwmon {} in sysfs ({}), trying alternate name",
|
||||
super::util::JUPITER_HWMON_NAME, e);
|
||||
match root.hwmon_by_name(super::util::STEAMDECK_HWMON_NAME) {
|
||||
Ok(hwmon) => {
|
||||
if !hwmon.capable(attributes(HWMON_NEEDS.into_iter().copied())) {
|
||||
log::warn!("Found incapable SteamDeck battery hwmon in sysfs (hwmon by name {} exists but missing attributes), persevering because ignorance is bliss", super::util::STEAMDECK_HWMON_NAME);
|
||||
} else {
|
||||
log::info!("Found SteamDeck battery hwmon {} in sysfs: {}", super::util::STEAMDECK_HWMON_NAME, hwmon.as_ref().display());
|
||||
}
|
||||
hwmon
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Failed to find SteamDeck battery hwmon {} in sysfs ({}), using naive fallback", super::util::STEAMDECK_HWMON_NAME, e);
|
||||
root.hwmon_by_index(5)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn charge_mode_to_str(mode: ChargeMode) -> String {
|
||||
match mode {
|
||||
|
@ -244,6 +337,40 @@ impl Battery {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_charge_rate(&mut self) -> Result<(), SettingError> {
|
||||
if let Some(charge_rate) = self.charge_rate {
|
||||
self.state.charge_rate_set = true;
|
||||
let attr = if MAX_BATTERY_CHARGE_RATE_ATTR.exists(&*self.sysfs_hwmon) {
|
||||
MAX_BATTERY_CHARGE_RATE_ATTR
|
||||
} else {
|
||||
MAXIMUM_BATTERY_CHARGE_RATE_ATTR
|
||||
};
|
||||
let path = attr.path(&*self.sysfs_hwmon);
|
||||
self.sysfs_hwmon.set(attr, charge_rate).map_err(
|
||||
|e| SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", path.display(), e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
},
|
||||
)
|
||||
} else if self.state.charge_rate_set {
|
||||
self.state.charge_rate_set = false;
|
||||
let attr = if MAX_BATTERY_CHARGE_RATE_ATTR.exists(&*self.sysfs_hwmon) {
|
||||
MAX_BATTERY_CHARGE_RATE_ATTR
|
||||
} else {
|
||||
MAXIMUM_BATTERY_CHARGE_RATE_ATTR
|
||||
};
|
||||
let path = attr.path(&*self.sysfs_hwmon);
|
||||
self.sysfs_hwmon.set(attr, self.limits.charge_rate.max,).map_err(
|
||||
|e| SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", path.display(), e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn set_charge_mode(&mut self) -> Result<(), SettingError> {
|
||||
if let Some(charge_mode) = self.charge_mode {
|
||||
self.state.charge_mode_set = true;
|
||||
|
@ -268,26 +395,7 @@ impl Battery {
|
|||
|
||||
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
if let Some(charge_rate) = self.charge_rate {
|
||||
self.state.charge_rate_set = true;
|
||||
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
} else if self.state.charge_rate_set {
|
||||
self.state.charge_rate_set = false;
|
||||
usdpl_back::api::files::write_single(
|
||||
BATTERY_CHARGE_RATE_PATH,
|
||||
self.limits.charge_rate.max,
|
||||
)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
self.set_charge_rate().unwrap_or_else(|e| errors.push(e));
|
||||
self.set_charge_mode().unwrap_or_else(|e| errors.push(e));
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
|
@ -303,10 +411,11 @@ impl Battery {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read_current_now() -> Result<u64, SettingError> {
|
||||
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CURRENT_NOW_PATH) {
|
||||
pub fn read_current_now(&self) -> Result<u64, SettingError> {
|
||||
let attr = PowerSupplyAttribute::CurrentNow;
|
||||
match self.sysfs_bat.attribute::<u64, _>(attr) {
|
||||
Err(e) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CURRENT_NOW_PATH, e),
|
||||
msg: format!("Failed to read from `{:?}`: {}", attr, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
}),
|
||||
// this value is in uA, while it's set in mA
|
||||
|
@ -315,10 +424,17 @@ impl Battery {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read_charge_now() -> Result<f64, SettingError> {
|
||||
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_NOW_PATH) {
|
||||
pub fn read_charge_power(&self) -> Result<f64, SettingError> {
|
||||
let current = self.read_usb_current()?;
|
||||
let voltage = self.read_usb_voltage()?;
|
||||
Ok(current * voltage)
|
||||
}
|
||||
|
||||
pub fn read_charge_now(&self) -> Result<f64, SettingError> {
|
||||
let attr = PowerSupplyAttribute::ChargeNow;
|
||||
match self.sysfs_bat.attribute::<u64, _>(attr) {
|
||||
Err(e) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_NOW_PATH, e),
|
||||
msg: format!("Failed to read from `{:?}`: {}", attr, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
}),
|
||||
// convert to Wh
|
||||
|
@ -326,10 +442,11 @@ impl Battery {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read_charge_full() -> Result<f64, SettingError> {
|
||||
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_FULL_PATH) {
|
||||
pub fn read_charge_full(&self) -> Result<f64, SettingError> {
|
||||
let attr = PowerSupplyAttribute::ChargeFull;
|
||||
match self.sysfs_bat.attribute::<u64, _>(attr) {
|
||||
Err(e) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_FULL_PATH, e),
|
||||
msg: format!("Failed to read from `{:?}`: {}", attr, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
}),
|
||||
// convert to Wh
|
||||
|
@ -337,13 +454,11 @@ impl Battery {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read_charge_design() -> Result<f64, SettingError> {
|
||||
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_DESIGN_PATH) {
|
||||
pub fn read_charge_design(&self) -> Result<f64, SettingError> {
|
||||
let attr = PowerSupplyAttribute::ChargeFullDesign;
|
||||
match self.sysfs_bat.attribute::<u64, _>(attr) {
|
||||
Err(e) => Err(SettingError {
|
||||
msg: format!(
|
||||
"Failed to read from `{}`: {}",
|
||||
BATTERY_CHARGE_DESIGN_PATH, e
|
||||
),
|
||||
msg: format!("Failed to read from `{:?}`: {}", attr, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
}),
|
||||
// convert to Wh
|
||||
|
@ -351,10 +466,11 @@ impl Battery {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read_usb_voltage() -> Result<f64, SettingError> {
|
||||
match usdpl_back::api::files::read_single::<_, u64, _>(USB_PD_IN_MVOLTAGE_PATH) {
|
||||
pub fn read_usb_voltage(&self) -> Result<f64, SettingError> {
|
||||
let attr = HwMonAttribute::new(HwMonAttributeType::In, 0, HwMonAttributeItem::Input);
|
||||
match self.sysfs_hwmon.attribute::<u64, _>(attr) {
|
||||
Err(e) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", USB_PD_IN_MVOLTAGE_PATH, e),
|
||||
msg: format!("Failed to read from `{:?}`: {}", attr, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
}),
|
||||
// convert to V (from mV)
|
||||
|
@ -362,6 +478,17 @@ impl Battery {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read_usb_current(&self) -> Result<f64, SettingError> {
|
||||
let attr = HwMonAttribute::new(HwMonAttributeType::Curr, 1, HwMonAttributeItem::Input);
|
||||
match self.sysfs_hwmon.attribute::<u64, _>(attr) {
|
||||
Err(e) => Err(SettingError {
|
||||
msg: format!("Failed to read `{:?}`: {}", attr, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
}),
|
||||
Ok(val) => Ok((val as f64) / 1000.0), // mA -> A
|
||||
}
|
||||
}
|
||||
|
||||
pub fn system_default() -> Self {
|
||||
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
||||
let oc_limits = oc_limits.battery;
|
||||
|
@ -377,6 +504,8 @@ impl Battery {
|
|||
limits: oc_limits,
|
||||
state: crate::state::steam_deck::Battery::default(),
|
||||
driver_mode: driver,
|
||||
sysfs_bat: Self::find_battery_sysfs(None::<&'static str>),
|
||||
sysfs_hwmon: Arc::new(Self::find_hwmon_sysfs(None::<&'static str>)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,6 +545,7 @@ impl Into<BatteryJson> for Battery {
|
|||
charge_rate: self.charge_rate,
|
||||
charge_mode: self.charge_mode.map(Self::charge_mode_to_str),
|
||||
events: self.events.into_iter().map(|x| x.into()).collect(),
|
||||
root: self.sysfs_bat.root().or(self.sysfs_hwmon.root()).and_then(|p| p.as_ref().to_str().map(|x| x.to_owned()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -454,7 +584,22 @@ impl OnPowerEvent for Battery {
|
|||
PowerMode::BatteryCharge(_) => Ok(()),
|
||||
}
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
let attr_exists = MAX_BATTERY_CHARGE_LEVEL_ATTR.exists(&*self.sysfs_hwmon);
|
||||
log::info!("Does battery limit attribute (max_battery_charge_level) exist? {}", attr_exists);
|
||||
for ev in &mut self.events {
|
||||
if attr_exists {
|
||||
if let EventTrigger::BatteryAbove(level) = ev.trigger {
|
||||
if let Some(ChargeMode::Idle) = ev.charge_mode {
|
||||
self.sysfs_hwmon.set(MAX_BATTERY_CHARGE_LEVEL_ATTR, (level * 100.0).round() as u64)
|
||||
.unwrap_or_else(|e| errors.push(
|
||||
SettingError {
|
||||
msg: format!("Failed to write to {:?}: {}", MAX_BATTERY_CHARGE_LEVEL_ATTR, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
ev.on_power_event(new_mode)
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
|
@ -508,7 +653,7 @@ impl TBattery for Battery {
|
|||
}
|
||||
|
||||
fn read_charge_full(&self) -> Option<f64> {
|
||||
match Self::read_charge_full() {
|
||||
match self.read_charge_full() {
|
||||
Ok(x) => Some(x),
|
||||
Err(e) => {
|
||||
log::warn!("read_charge_full err: {}", e.msg);
|
||||
|
@ -518,7 +663,7 @@ impl TBattery for Battery {
|
|||
}
|
||||
|
||||
fn read_charge_now(&self) -> Option<f64> {
|
||||
match Self::read_charge_now() {
|
||||
match self.read_charge_now() {
|
||||
Ok(x) => Some(x),
|
||||
Err(e) => {
|
||||
log::warn!("read_charge_now err: {}", e.msg);
|
||||
|
@ -528,7 +673,7 @@ impl TBattery for Battery {
|
|||
}
|
||||
|
||||
fn read_charge_design(&self) -> Option<f64> {
|
||||
match Self::read_charge_design() {
|
||||
match self.read_charge_design() {
|
||||
Ok(x) => Some(x),
|
||||
Err(e) => {
|
||||
log::warn!("read_charge_design err: {}", e.msg);
|
||||
|
@ -538,12 +683,30 @@ impl TBattery for Battery {
|
|||
}
|
||||
|
||||
fn read_current_now(&self) -> Option<f64> {
|
||||
match Self::read_current_now() {
|
||||
Ok(x) => Some(x as f64),
|
||||
Err(e) => {
|
||||
log::warn!("read_current_now err: {}", e.msg);
|
||||
None
|
||||
if self.limits.extra_readouts {
|
||||
match self.read_current_now() {
|
||||
Ok(x) => Some(x as f64),
|
||||
Err(e) => {
|
||||
log::warn!("read_current_now err: {}", e.msg);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn read_charge_power(&self) -> Option<f64> {
|
||||
if self.limits.extra_readouts {
|
||||
match self.read_charge_power() {
|
||||
Ok(x) => Some(x as f64),
|
||||
Err(e) => {
|
||||
log::warn!("read_current_now err: {}", e.msg);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -561,6 +724,7 @@ impl TBattery for Battery {
|
|||
charge_rate: None,
|
||||
charge_mode: Some(ChargeMode::Idle),
|
||||
is_triggered: false,
|
||||
sysfs_hwmon: self.sysfs_hwmon.clone(),
|
||||
};
|
||||
} else {
|
||||
self.events.remove(index);
|
||||
|
@ -575,6 +739,7 @@ impl TBattery for Battery {
|
|||
charge_rate: None,
|
||||
charge_mode: Some(ChargeMode::Idle),
|
||||
is_triggered: false,
|
||||
sysfs_hwmon: self.sysfs_hwmon.clone(),
|
||||
});
|
||||
}
|
||||
// lower limit
|
||||
|
@ -591,6 +756,7 @@ impl TBattery for Battery {
|
|||
charge_rate: None,
|
||||
charge_mode: Some(ChargeMode::Normal),
|
||||
is_triggered: false,
|
||||
sysfs_hwmon: self.sysfs_hwmon.clone(),
|
||||
};
|
||||
} else {
|
||||
self.events.remove(index);
|
||||
|
@ -606,6 +772,7 @@ impl TBattery for Battery {
|
|||
charge_rate: None,
|
||||
charge_mode: Some(ChargeMode::Normal),
|
||||
is_triggered: false,
|
||||
sysfs_hwmon: self.sysfs_hwmon.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -628,7 +795,7 @@ impl TBattery for Battery {
|
|||
log::debug!("Steam Deck power vibe check");
|
||||
let mut errors = Vec::new();
|
||||
let mut events = Vec::new();
|
||||
match (Self::read_charge_full(), Self::read_charge_now()) {
|
||||
match (self.read_charge_full(), self.read_charge_now()) {
|
||||
(Ok(full), Ok(now)) => events.push(PowerMode::BatteryCharge(now / full)),
|
||||
(Err(e1), Err(e2)) => {
|
||||
errors.push(e1);
|
||||
|
@ -637,7 +804,7 @@ impl TBattery for Battery {
|
|||
(Err(e), _) => errors.push(e),
|
||||
(_, Err(e)) => errors.push(e),
|
||||
}
|
||||
match Self::read_usb_voltage() {
|
||||
match self.read_usb_voltage() {
|
||||
Ok(voltage) => {
|
||||
if voltage > 0.0
|
||||
&& self.state.charger_state != crate::state::steam_deck::ChargeState::PluggedIn
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use std::convert::Into;
|
||||
|
||||
use sysfuss::{BasicEntityPath, SysEntity, SysEntityAttributesExt};
|
||||
|
||||
use super::oc_limits::{CpuLimits, CpusLimits, OverclockLimits};
|
||||
use super::POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT;
|
||||
use crate::api::RangeLimit;
|
||||
|
@ -11,6 +13,10 @@ use crate::settings::{TCpu, TCpus};
|
|||
const CPU_PRESENT_PATH: &str = "/sys/devices/system/cpu/present";
|
||||
const CPU_SMT_PATH: &str = "/sys/devices/system/cpu/smt/control";
|
||||
|
||||
const CARD_EXTENSIONS: &[&'static str] = &[
|
||||
super::DPM_FORCE_LIMITS_ATTRIBUTE
|
||||
];
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Cpus {
|
||||
pub cpus: Vec<Cpu>,
|
||||
|
@ -230,9 +236,16 @@ pub struct Cpu {
|
|||
limits: CpuLimits,
|
||||
index: usize,
|
||||
state: crate::state::steam_deck::Cpu,
|
||||
sysfs: BasicEntityPath,
|
||||
}
|
||||
|
||||
const CPU_CLOCK_LIMITS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage";
|
||||
//const CPU_CLOCK_LIMITS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage";
|
||||
const CPU_CLOCK_LIMITS_ATTRIBUTE: &str = "device/pp_od_clk_voltage";
|
||||
|
||||
enum ClockType {
|
||||
Min = 0,
|
||||
Max = 1,
|
||||
}
|
||||
|
||||
impl Cpu {
|
||||
#[inline]
|
||||
|
@ -245,6 +258,7 @@ impl Cpu {
|
|||
limits: oc_limits,
|
||||
index: i,
|
||||
state: crate::state::steam_deck::Cpu::default(),
|
||||
sysfs: Self::find_card_sysfs(other.root),
|
||||
},
|
||||
_ => Self {
|
||||
online: other.online,
|
||||
|
@ -253,99 +267,161 @@ impl Cpu {
|
|||
limits: oc_limits,
|
||||
index: i,
|
||||
state: crate::state::steam_deck::Cpu::default(),
|
||||
sysfs: Self::find_card_sysfs(other.root),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn find_card_sysfs(root: Option<impl AsRef<std::path::Path>>) -> BasicEntityPath {
|
||||
let root = crate::settings::util::root_or_default_sysfs(root);
|
||||
match root.class("drm", sysfuss::capability::attributes(crate::settings::util::CARD_NEEDS.into_iter().map(|s| s.to_string()))) {
|
||||
Ok(iter) => {
|
||||
let card = iter
|
||||
.filter(|ent| if let Ok(name) = ent.name() { name.starts_with("card")} else { false })
|
||||
.filter(|ent| super::util::card_also_has(ent, CARD_EXTENSIONS))
|
||||
.next()
|
||||
.unwrap_or_else(|| {
|
||||
log::error!("Failed to find SteamDeck drm in sysfs (no results), using naive fallback");
|
||||
BasicEntityPath::new(root.as_ref().join("sys/class/drm/card0"))
|
||||
});
|
||||
log::info!("Found SteamDeck drm in sysfs: {}", card.as_ref().display());
|
||||
card
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Failed to find SteamDeck drm in sysfs ({}), using naive fallback", e);
|
||||
BasicEntityPath::new(root.as_ref().join("sys/class/drm/card0"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn set_clock_limit(&self, index: usize, speed: u64, mode: ClockType) -> Result<(), SettingError> {
|
||||
let payload = format!("p {} {} {}\n", index / 2, mode as u8, speed);
|
||||
self.sysfs.set(CPU_CLOCK_LIMITS_ATTRIBUTE.to_owned(), &payload).map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload, CPU_CLOCK_LIMITS_ATTRIBUTE, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn set_clock_limits(&mut self) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
if let Some(clock_limits) = &self.clock_limits {
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(true, self.index);
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level(&self.sysfs)?;
|
||||
log::debug!(
|
||||
"Setting CPU {} (min, max) clockspeed to ({:?}, {:?})",
|
||||
self.index,
|
||||
clock_limits.min,
|
||||
clock_limits.max
|
||||
);
|
||||
self.state.clock_limits_set = true;
|
||||
// max clock
|
||||
if let Some(max) = clock_limits.max {
|
||||
self.set_clock_limit(self.index, max, ClockType::Max)
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
// min clock
|
||||
if let Some(min) = clock_limits.min {
|
||||
let valid_min = if min < self.limits.clock_min.min {
|
||||
self.limits.clock_min.min
|
||||
} else {
|
||||
min
|
||||
};
|
||||
self.set_clock_limit(self.index, valid_min, ClockType::Min)
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errors)
|
||||
}
|
||||
} else if self.state.clock_limits_set
|
||||
|| (self.state.is_resuming && !self.limits.skip_resume_reclock)
|
||||
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual()
|
||||
{
|
||||
let mut errors = Vec::new();
|
||||
self.state.clock_limits_set = false;
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(false, self.index);
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||
.enforce_level(&self.sysfs)?;
|
||||
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||
// always set clock speeds, since it doesn't reset correctly (kernel/hardware bug)
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level(&self.sysfs)?;
|
||||
// disable manual clock limits
|
||||
log::debug!("Setting CPU {} to default clockspeed", self.index);
|
||||
// max clock
|
||||
self.set_clock_limit(self.index, self.limits.clock_max.max, ClockType::Max)
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
// min clock
|
||||
self.set_clock_limit(self.index, self.limits.clock_min.min, ClockType::Min)
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
// TODO remove this when it's no longer needed
|
||||
self.clock_unset_workaround().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errors)
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/NGnius/PowerTools/issues/107
|
||||
fn clock_unset_workaround(&self) -> Result<(), Vec<SettingError>> {
|
||||
if !self.state.is_resuming {
|
||||
let mut errors = Vec::new();
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(true, self.index);
|
||||
// always set clock speeds, since it doesn't reset correctly (kernel/hardware bug)
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level(&self.sysfs)?;
|
||||
// disable manual clock limits
|
||||
log::debug!("Setting CPU {} to default clockspeed", self.index);
|
||||
// max clock
|
||||
self.set_clock_limit(self.index, self.limits.clock_max.max, ClockType::Max)
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
// min clock
|
||||
self.set_clock_limit(self.index, self.limits.clock_min.min, ClockType::Min)
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
|
||||
self.set_confirm().unwrap_or_else(|e| errors.push(e));
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(false, self.index);
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errors)
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn set_confirm(&self) -> Result<(), SettingError> {
|
||||
self.sysfs.set(CPU_CLOCK_LIMITS_ATTRIBUTE.to_owned(), "c\n").map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_ATTRIBUTE, e),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn set_force_performance_related(&mut self) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
|
||||
// set clock limits
|
||||
//log::debug!("Setting {} to manual", CPU_FORCE_LIMITS_PATH);
|
||||
//let mode: String = usdpl_back::api::files::read_single(CPU_FORCE_LIMITS_PATH.to_owned()).unwrap();
|
||||
if let Some(clock_limits) = &self.clock_limits {
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(true, self.index);
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
||||
log::debug!(
|
||||
"Setting CPU {} (min, max) clockspeed to ({}, {})",
|
||||
self.index,
|
||||
clock_limits.min,
|
||||
clock_limits.max
|
||||
);
|
||||
self.state.clock_limits_set = true;
|
||||
// max clock
|
||||
let payload_max = format!("p {} 1 {}\n", self.index / 2, clock_limits.max);
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_max, CPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
// min clock
|
||||
let valid_min = if clock_limits.min < self.limits.clock_min.min {
|
||||
self.limits.clock_min.min
|
||||
} else {
|
||||
clock_limits.min
|
||||
};
|
||||
let payload_min = format!("p {} 0 {}\n", self.index / 2, valid_min);
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_min, CPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
} else if self.state.clock_limits_set
|
||||
|| (self.state.is_resuming && !self.limits.skip_resume_reclock)
|
||||
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual()
|
||||
{
|
||||
self.state.clock_limits_set = false;
|
||||
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
||||
// disable manual clock limits
|
||||
log::debug!("Setting CPU {} to default clockspeed", self.index);
|
||||
// max clock
|
||||
let payload_max = format!("p {} 1 {}\n", self.index / 2, self.limits.clock_max.max);
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_max, CPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
// min clock
|
||||
let payload_min = format!("p {} 0 {}\n", self.index / 2, self.limits.clock_min.min);
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_min, CPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(false, self.index);
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||
.enforce_level()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
self.set_clock_limits()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
// commit changes (if no errors have already occured)
|
||||
if errors.is_empty() {
|
||||
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n").map_err(|e| {
|
||||
vec![SettingError {
|
||||
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}]
|
||||
})
|
||||
self.set_confirm().map_err(|e| vec![e])
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -354,6 +430,23 @@ impl Cpu {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_governor(&self) -> Result<(), SettingError> {
|
||||
if self.index == 0 || self.online {
|
||||
let governor_path = cpu_governor_path(self.index);
|
||||
usdpl_back::api::files::write_single(&governor_path, &self.governor).map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&self.governor, &governor_path, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
// set cpu online/offline
|
||||
|
@ -371,19 +464,8 @@ impl Cpu {
|
|||
self.set_force_performance_related()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
|
||||
// set governor
|
||||
if self.index == 0 || self.online {
|
||||
let governor_path = cpu_governor_path(self.index);
|
||||
usdpl_back::api::files::write_single(&governor_path, &self.governor)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&self.governor, &governor_path, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
self.set_governor().unwrap_or_else(|e| errors.push(e));
|
||||
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
|
@ -393,12 +475,14 @@ impl Cpu {
|
|||
|
||||
fn clamp_all(&mut self) {
|
||||
if let Some(clock_limits) = &mut self.clock_limits {
|
||||
clock_limits.min = clock_limits
|
||||
.min
|
||||
.clamp(self.limits.clock_min.min, self.limits.clock_min.max);
|
||||
clock_limits.max = clock_limits
|
||||
.max
|
||||
.clamp(self.limits.clock_max.min, self.limits.clock_max.max);
|
||||
if let Some(min) = clock_limits.min {
|
||||
clock_limits.min =
|
||||
Some(min.clamp(self.limits.clock_min.min, self.limits.clock_min.max));
|
||||
}
|
||||
if let Some(max) = clock_limits.max {
|
||||
clock_limits.max =
|
||||
Some(max.clamp(self.limits.clock_max.min, self.limits.clock_max.max));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -422,6 +506,7 @@ impl Cpu {
|
|||
limits: oc_limits,
|
||||
index: cpu_index,
|
||||
state: crate::state::steam_deck::Cpu::default(),
|
||||
sysfs: Self::find_card_sysfs(None::<&'static str>)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,6 +546,7 @@ impl Into<CpuJson> for Cpu {
|
|||
online: self.online,
|
||||
clock_limits: self.clock_limits.map(|x| x.into()),
|
||||
governor: self.governor,
|
||||
root: self.sysfs.root().and_then(|p| p.as_ref().to_str().map(|r| r.to_owned()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use std::convert::Into;
|
||||
|
||||
use sysfuss::{BasicEntityPath, HwMonPath, SysEntity, capability::attributes, SysEntityAttributesExt, SysAttribute};
|
||||
|
||||
use super::oc_limits::{GpuLimits, OverclockLimits};
|
||||
use super::POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT;
|
||||
use crate::api::RangeLimit;
|
||||
|
@ -8,8 +10,9 @@ use crate::settings::TGpu;
|
|||
use crate::settings::{min_max_from_json, MinMax};
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
|
||||
const SLOW_PPT: u8 = 1;
|
||||
const FAST_PPT: u8 = 2;
|
||||
// usually in /sys/class/hwmon/hwmon4/<attribute>
|
||||
const SLOW_PPT_ATTRIBUTE: sysfuss::HwMonAttribute = sysfuss::HwMonAttribute::custom("power1_cap");
|
||||
const FAST_PPT_ATTRIBUTE: sysfuss::HwMonAttribute = sysfuss::HwMonAttribute::custom("power2_cap");
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Gpu {
|
||||
|
@ -20,11 +23,27 @@ pub struct Gpu {
|
|||
limits: GpuLimits,
|
||||
state: crate::state::steam_deck::Gpu,
|
||||
driver_mode: crate::persist::DriverJson,
|
||||
sysfs_card: BasicEntityPath,
|
||||
sysfs_hwmon: HwMonPath
|
||||
}
|
||||
|
||||
// same as CPU
|
||||
const GPU_CLOCK_LIMITS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage";
|
||||
const GPU_MEMORY_DOWNCLOCK_PATH: &str = "/sys/class/drm/card0/device/pp_dpm_fclk";
|
||||
//const GPU_CLOCK_LIMITS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage";
|
||||
//const GPU_MEMORY_DOWNCLOCK_PATH: &str = "/sys/class/drm/card0/device/pp_dpm_fclk";
|
||||
|
||||
const GPU_CLOCK_LIMITS_ATTRIBUTE: &str = "device/pp_od_clk_voltage";
|
||||
const GPU_MEMORY_DOWNCLOCK_ATTRIBUTE: &str = "device/pp_dpm_fclk";
|
||||
|
||||
const CARD_EXTENSIONS: &[&'static str] = &[
|
||||
GPU_CLOCK_LIMITS_ATTRIBUTE,
|
||||
GPU_MEMORY_DOWNCLOCK_ATTRIBUTE,
|
||||
super::DPM_FORCE_LIMITS_ATTRIBUTE,
|
||||
];
|
||||
|
||||
enum ClockType {
|
||||
Min = 0,
|
||||
Max = 1,
|
||||
}
|
||||
|
||||
impl Gpu {
|
||||
#[inline]
|
||||
|
@ -44,6 +63,8 @@ impl Gpu {
|
|||
limits: oc_limits.gpu,
|
||||
state: crate::state::steam_deck::Gpu::default(),
|
||||
driver_mode: driver,
|
||||
sysfs_card: Self::find_card_sysfs(other.root.clone()),
|
||||
sysfs_hwmon: Self::find_hwmon_sysfs(other.root),
|
||||
},
|
||||
_ => Self {
|
||||
fast_ppt: other.fast_ppt,
|
||||
|
@ -53,93 +74,104 @@ impl Gpu {
|
|||
limits: oc_limits.gpu,
|
||||
state: crate::state::steam_deck::Gpu::default(),
|
||||
driver_mode: driver,
|
||||
sysfs_card: Self::find_card_sysfs(other.root.clone()),
|
||||
sysfs_hwmon: Self::find_hwmon_sysfs(other.root),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn find_card_sysfs(root: Option<impl AsRef<std::path::Path>>) -> BasicEntityPath {
|
||||
let root = crate::settings::util::root_or_default_sysfs(root);
|
||||
match root.class("drm", attributes(crate::settings::util::CARD_NEEDS.into_iter().map(|s| s.to_string()))) {
|
||||
Ok(iter) => {
|
||||
let card = iter
|
||||
.filter(|ent| if let Ok(name) = ent.name() { name.starts_with("card")} else { false })
|
||||
.filter(|ent| super::util::card_also_has(ent, CARD_EXTENSIONS))
|
||||
.next()
|
||||
.unwrap_or_else(|| {
|
||||
log::error!("Failed to find SteamDeck gpu drm in sysfs (no results), using naive fallback");
|
||||
BasicEntityPath::new(root.as_ref().join("sys/class/drm/card0"))
|
||||
});
|
||||
log::info!("Found SteamDeck gpu drm in sysfs: {}", card.as_ref().display());
|
||||
card
|
||||
},
|
||||
Err(e) => {
|
||||
log::error!("Failed to find SteamDeck gpu drm in sysfs ({}), using naive fallback", e);
|
||||
BasicEntityPath::new(root.as_ref().join("sys/class/drm/card0"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_hwmon_sysfs(root: Option<impl AsRef<std::path::Path>>) -> HwMonPath {
|
||||
let root = crate::settings::util::root_or_default_sysfs(root);
|
||||
let hwmon = root.hwmon_by_name(super::util::GPU_HWMON_NAME).unwrap_or_else(|e| {
|
||||
log::error!("Failed to find SteamDeck gpu hwmon in sysfs ({}), using naive fallback", e);
|
||||
root.hwmon_by_index(4)
|
||||
});
|
||||
log::info!("Found SteamDeck gpu hwmon {} in sysfs: {}", super::util::GPU_HWMON_NAME, hwmon.as_ref().display());
|
||||
hwmon
|
||||
}
|
||||
|
||||
fn set_clock_limit(&self, speed: u64, mode: ClockType) -> Result<(), SettingError> {
|
||||
let payload = format!("s {} {}\n", mode as u8, speed);
|
||||
let path = GPU_CLOCK_LIMITS_ATTRIBUTE.path(&self.sysfs_card);
|
||||
self.sysfs_card.set(GPU_CLOCK_LIMITS_ATTRIBUTE.to_owned(), &payload).map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!("Failed to write `{}` to `{}`: {}", &payload, path.display(), e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn set_confirm(&self) -> Result<(), SettingError> {
|
||||
let path = GPU_CLOCK_LIMITS_ATTRIBUTE.path(&self.sysfs_card);
|
||||
self.sysfs_card.set(GPU_CLOCK_LIMITS_ATTRIBUTE.to_owned(), "c\n").map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!("Failed to write `c` to `{}`: {}", path.display(), e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn set_clocks(&mut self) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
if let Some(clock_limits) = &self.clock_limits {
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(true);
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level(&self.sysfs_card)?;
|
||||
// set clock limits
|
||||
self.state.clock_limits_set = true;
|
||||
// max clock
|
||||
let payload_max = format!("s 1 {}\n", clock_limits.max);
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_max, GPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
if let Some(max) = clock_limits.max {
|
||||
self.set_clock_limit(max, ClockType::Max).unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
// min clock
|
||||
let payload_min = format!("s 0 {}\n", clock_limits.min);
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_min, GPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|
||||
|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
},
|
||||
);
|
||||
if let Some(min) = clock_limits.min {
|
||||
self.set_clock_limit(min, ClockType::Min).unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
|
||||
self.set_confirm().unwrap_or_else(|e| errors.push(e));
|
||||
} else if self.state.clock_limits_set
|
||||
|| (self.state.is_resuming && !self.limits.skip_resume_reclock)
|
||||
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual()
|
||||
{
|
||||
self.state.clock_limits_set = false;
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.slow_memory);
|
||||
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level(&self.sysfs_card)?;
|
||||
// disable manual clock limits
|
||||
// max clock
|
||||
let payload_max = format!("s 1 {}\n", self.limits.clock_max.max);
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_max, GPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
self.set_clock_limit(self.limits.clock_max.max, ClockType::Max)
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
// min clock
|
||||
let payload_min = format!("s 0 {}\n", self.limits.clock_min.min);
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_min, GPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
self.set_clock_limit(self.limits.clock_min.min, ClockType::Min)
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|
||||
|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `c` to `{}`: {}",
|
||||
GPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
self.set_confirm().unwrap_or_else(|e| errors.push(e));
|
||||
} else {
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||
.enforce_level(&self.sysfs_card)
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.slow_memory);
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||
.enforce_level()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
|
@ -148,32 +180,40 @@ impl Gpu {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_slow_memory(&self, slow: bool) -> Result<(), SettingError> {
|
||||
let path = GPU_MEMORY_DOWNCLOCK_ATTRIBUTE.path(&self.sysfs_card);
|
||||
if slow {
|
||||
self.sysfs_card.set(GPU_MEMORY_DOWNCLOCK_ATTRIBUTE.to_owned(), slow as u8).map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", path.display(), e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// NOTE: there is a GPU driver/hardware bug that prevents this from working
|
||||
self.sysfs_card.set(GPU_MEMORY_DOWNCLOCK_ATTRIBUTE.to_owned(), "0 1\n").map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", path.display(), e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn set_force_performance_related(&mut self) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
// enable/disable downclock of GPU memory (to 400Mhz?)
|
||||
if self.slow_memory {
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(true);
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||
.enforce_level()
|
||||
.enforce_level(&self.sysfs_card)
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
usdpl_back::api::files::write_single(GPU_MEMORY_DOWNCLOCK_PATH, self.slow_memory as u8)
|
||||
.unwrap_or_else(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
});
|
||||
});
|
||||
self.set_slow_memory(self.slow_memory).unwrap_or_else(|e| errors.push(e));
|
||||
} else if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||
usdpl_back::api::files::write_single(GPU_MEMORY_DOWNCLOCK_PATH, self.slow_memory as u8)
|
||||
.unwrap_or_else(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
});
|
||||
});
|
||||
self.set_slow_memory(self.slow_memory).unwrap_or_else(|e| errors.push(e));
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.clock_limits.is_some());
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||
.enforce_level()
|
||||
.enforce_level(&self.sysfs_card)
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
self.set_clocks()
|
||||
|
@ -181,11 +221,9 @@ impl Gpu {
|
|||
// commit changes (if no errors have already occured)
|
||||
if errors.is_empty() {
|
||||
if self.slow_memory || self.clock_limits.is_some() {
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").map_err(|e| {
|
||||
vec![SettingError {
|
||||
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
}]
|
||||
self.set_confirm().map_err(|e| {
|
||||
errors.push(e);
|
||||
errors
|
||||
})
|
||||
} else {
|
||||
Ok(())
|
||||
|
@ -200,12 +238,11 @@ impl Gpu {
|
|||
// set fast PPT
|
||||
if let Some(fast_ppt) = &self.fast_ppt {
|
||||
self.state.fast_ppt_set = true;
|
||||
let fast_ppt_path = gpu_power_path(FAST_PPT);
|
||||
usdpl_back::api::files::write_single(&fast_ppt_path, fast_ppt)
|
||||
self.sysfs_hwmon.set(FAST_PPT_ATTRIBUTE, fast_ppt)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
fast_ppt, &fast_ppt_path, e
|
||||
"Failed to write `{}` to `{:?}`: {}",
|
||||
fast_ppt, FAST_PPT_ATTRIBUTE, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
|
@ -215,12 +252,11 @@ impl Gpu {
|
|||
} else if self.state.fast_ppt_set {
|
||||
self.state.fast_ppt_set = false;
|
||||
let fast_ppt = self.limits.fast_ppt_default;
|
||||
let fast_ppt_path = gpu_power_path(FAST_PPT);
|
||||
usdpl_back::api::files::write_single(&fast_ppt_path, fast_ppt)
|
||||
self.sysfs_hwmon.set(FAST_PPT_ATTRIBUTE, fast_ppt)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
fast_ppt, &fast_ppt_path, e
|
||||
"Failed to write `{}` to `{:?}`: {}",
|
||||
fast_ppt, FAST_PPT_ATTRIBUTE, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
|
@ -231,12 +267,11 @@ impl Gpu {
|
|||
// set slow PPT
|
||||
if let Some(slow_ppt) = &self.slow_ppt {
|
||||
self.state.slow_ppt_set = true;
|
||||
let slow_ppt_path = gpu_power_path(SLOW_PPT);
|
||||
usdpl_back::api::files::write_single(&slow_ppt_path, slow_ppt)
|
||||
self.sysfs_hwmon.set(SLOW_PPT_ATTRIBUTE, slow_ppt)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
slow_ppt, &slow_ppt_path, e
|
||||
"Failed to write `{}` to `{:?}`: {}",
|
||||
slow_ppt, SLOW_PPT_ATTRIBUTE, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
|
@ -246,12 +281,11 @@ impl Gpu {
|
|||
} else if self.state.slow_ppt_set {
|
||||
self.state.slow_ppt_set = false;
|
||||
let slow_ppt = self.limits.slow_ppt_default;
|
||||
let slow_ppt_path = gpu_power_path(SLOW_PPT);
|
||||
usdpl_back::api::files::write_single(&slow_ppt_path, slow_ppt)
|
||||
self.sysfs_hwmon.set(SLOW_PPT_ATTRIBUTE, slow_ppt)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
slow_ppt, &slow_ppt_path, e
|
||||
"Failed to write `{}` to `{:?}`: {}",
|
||||
slow_ppt, SLOW_PPT_ATTRIBUTE, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
|
@ -276,12 +310,14 @@ impl Gpu {
|
|||
*slow_ppt = (*slow_ppt).clamp(self.limits.slow_ppt.min, self.limits.slow_ppt.max);
|
||||
}
|
||||
if let Some(clock_limits) = &mut self.clock_limits {
|
||||
clock_limits.min = clock_limits
|
||||
.min
|
||||
.clamp(self.limits.clock_min.min, self.limits.clock_min.max);
|
||||
clock_limits.max = clock_limits
|
||||
.max
|
||||
.clamp(self.limits.clock_max.min, self.limits.clock_max.max);
|
||||
if let Some(min) = clock_limits.min {
|
||||
clock_limits.min =
|
||||
Some(min.clamp(self.limits.clock_min.min, self.limits.clock_min.max));
|
||||
}
|
||||
if let Some(max) = clock_limits.max {
|
||||
clock_limits.max =
|
||||
Some(max.clamp(self.limits.clock_max.min, self.limits.clock_max.max));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,6 +335,8 @@ impl Gpu {
|
|||
} else {
|
||||
crate::persist::DriverJson::SteamDeckAdvance
|
||||
},
|
||||
sysfs_card: Self::find_card_sysfs(None::<&'static str>),
|
||||
sysfs_hwmon: Self::find_hwmon_sysfs(None::<&'static str>),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -311,6 +349,7 @@ impl Into<GpuJson> for Gpu {
|
|||
slow_ppt: self.slow_ppt,
|
||||
clock_limits: self.clock_limits.map(|x| x.into()),
|
||||
slow_memory: self.slow_memory,
|
||||
root: self.sysfs_card.root().or(self.sysfs_hwmon.root()).and_then(|p| p.as_ref().to_str().map(|r| r.to_owned()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -392,8 +431,3 @@ impl TGpu for Gpu {
|
|||
self.driver_mode.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn gpu_power_path(power_number: u8) -> String {
|
||||
format!("/sys/class/hwmon/hwmon4/power{}_cap", power_number)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,6 @@ mod util;
|
|||
pub use battery::Battery;
|
||||
pub use cpu::{Cpu, Cpus};
|
||||
pub use gpu::Gpu;
|
||||
pub(self) use power_dpm_force::POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT;
|
||||
pub(self) use power_dpm_force::{POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT, DPM_FORCE_LIMITS_ATTRIBUTE};
|
||||
|
||||
pub use util::flash_led;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::settings::MinMax;
|
||||
use crate::api::RangeLimit as MinMax;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const OC_LIMITS_FILEPATH: &str = "pt_oc.json";
|
||||
|
@ -67,6 +67,7 @@ impl OverclockLimits {
|
|||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub(super) struct BatteryLimits {
|
||||
pub charge_rate: MinMax<u64>,
|
||||
pub extra_readouts: bool,
|
||||
}
|
||||
|
||||
impl Default for BatteryLimits {
|
||||
|
@ -76,6 +77,7 @@ impl Default for BatteryLimits {
|
|||
min: 250,
|
||||
max: 2500,
|
||||
},
|
||||
extra_readouts: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,6 +173,7 @@ fn oc_limits_filepath() -> std::path::PathBuf {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[cfg(not(feature = "dev_stuff"))] // this can fail due to reading from incompletely-written file otherwise
|
||||
#[test]
|
||||
fn load_pt_oc() {
|
||||
let mut file = std::fs::File::open("../pt_oc.json").unwrap();
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
|
||||
use sysfuss::{BasicEntityPath, SysEntityAttributesExt, SysAttribute};
|
||||
|
||||
use crate::settings::SettingError;
|
||||
|
||||
const DEFAULT_BITS: u64 = 0;
|
||||
|
@ -19,7 +21,8 @@ pub struct PDFPLManager(AtomicU64);
|
|||
const GPU_BIT: usize = 1;
|
||||
const CPU_BITS_START: usize = 2;
|
||||
|
||||
const DPM_FORCE_LIMITS_PATH: &str = "/sys/class/drm/card0/device/power_dpm_force_performance_level";
|
||||
//const DPM_FORCE_LIMITS_PATH: &str = "/sys/class/drm/card0/device/power_dpm_force_performance_level";
|
||||
pub const DPM_FORCE_LIMITS_ATTRIBUTE: &str = "device/power_dpm_force_performance_level";
|
||||
|
||||
impl PDFPLManager {
|
||||
#[inline]
|
||||
|
@ -56,49 +59,44 @@ impl PDFPLManager {
|
|||
self.set(DEFAULT_BITS);
|
||||
}
|
||||
|
||||
pub fn enforce_level(&self) -> Result<(), Vec<SettingError>> {
|
||||
pub fn enforce_level(&self, entity: &BasicEntityPath) -> Result<(), Vec<SettingError>> {
|
||||
let needs = self.needs_manual();
|
||||
let mut errors = Vec::new();
|
||||
let mode: String = usdpl_back::api::files::read_single(DPM_FORCE_LIMITS_PATH.to_owned())
|
||||
let path = DPM_FORCE_LIMITS_ATTRIBUTE.path(entity);
|
||||
let mode: String = entity.attribute(DPM_FORCE_LIMITS_ATTRIBUTE.to_owned())
|
||||
.map_err(|e| {
|
||||
vec![SettingError {
|
||||
msg: format!("Failed to read `{}`: {}", DPM_FORCE_LIMITS_PATH, e),
|
||||
msg: format!("Failed to read `{}`: {}", path.display(), e),
|
||||
setting: crate::settings::SettingVariant::General,
|
||||
}]
|
||||
})?;
|
||||
if mode != "manual" && needs {
|
||||
log::info!("Setting `{}` to manual", DPM_FORCE_LIMITS_PATH);
|
||||
log::info!("Setting `{}` to manual", path.display());
|
||||
// set manual control
|
||||
usdpl_back::api::files::write_single(DPM_FORCE_LIMITS_PATH, "manual")
|
||||
entity.set(DPM_FORCE_LIMITS_ATTRIBUTE.to_owned(), "manual")
|
||||
.map_err(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `manual` to `{}`: {}",
|
||||
DPM_FORCE_LIMITS_PATH, e
|
||||
),
|
||||
msg: format!("Failed to write `manual` to `{}`: {}", path.display(), e),
|
||||
setting: crate::settings::SettingVariant::General,
|
||||
})
|
||||
})
|
||||
.unwrap_or(());
|
||||
} else if mode != "auto" && !needs {
|
||||
log::info!("Setting `{}` to auto", DPM_FORCE_LIMITS_PATH);
|
||||
log::info!("Setting `{}` to auto", path.display());
|
||||
// unset manual control
|
||||
usdpl_back::api::files::write_single(DPM_FORCE_LIMITS_PATH, "auto")
|
||||
entity.set(DPM_FORCE_LIMITS_ATTRIBUTE.to_owned(), "auto")
|
||||
.map_err(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `auto` to `{}`: {}",
|
||||
DPM_FORCE_LIMITS_PATH, e
|
||||
),
|
||||
msg: format!("Failed to write `auto` to `{}`: {}", path.display(), e),
|
||||
setting: crate::settings::SettingVariant::General,
|
||||
})
|
||||
})
|
||||
.unwrap_or(());
|
||||
}
|
||||
if let Ok(mode_now) =
|
||||
usdpl_back::api::files::read_single::<_, String, _>(DPM_FORCE_LIMITS_PATH.to_owned())
|
||||
entity.attribute::<String, _>(DPM_FORCE_LIMITS_ATTRIBUTE.to_owned())
|
||||
{
|
||||
log::debug!("Mode for `{}` is now `{}`", DPM_FORCE_LIMITS_PATH, mode_now);
|
||||
log::debug!("Mode for `{}` is now `{}`", path.display(), mode_now);
|
||||
} else {
|
||||
log::debug!("Error getting new mode for debugging purposes");
|
||||
}
|
||||
|
|
|
@ -8,6 +8,15 @@
|
|||
use std::fs::OpenOptions;
|
||||
use std::io::{Error, Read, Seek, SeekFrom, Write};
|
||||
|
||||
pub const JUPITER_HWMON_NAME: &'static str = "jupiter";
|
||||
pub const STEAMDECK_HWMON_NAME: &'static str = "steamdeck_hwmon";
|
||||
pub const GPU_HWMON_NAME: &'static str = "amdgpu";
|
||||
|
||||
pub fn card_also_has(card: &dyn sysfuss::SysEntity, extensions: &'static [&'static str]) -> bool {
|
||||
extensions.iter()
|
||||
.all(|ext| card.as_ref().join(ext).exists())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write2(p0: u8, p1: u8) -> Result<usize, Error> {
|
||||
write_to(0x6c, 0x81)?;
|
||||
|
|
|
@ -104,6 +104,8 @@ pub trait TGeneral: OnSet + OnResume + OnPowerEvent + Debug + Send {
|
|||
fn name(&mut self, name: String);
|
||||
|
||||
fn provider(&self) -> crate::persist::DriverJson;
|
||||
|
||||
fn on_event(&self) -> &'_ crate::persist::OnEventJson;
|
||||
}
|
||||
|
||||
pub trait TBattery: OnSet + OnResume + OnPowerEvent + Debug + Send {
|
||||
|
@ -127,6 +129,8 @@ pub trait TBattery: OnSet + OnResume + OnPowerEvent + Debug + Send {
|
|||
|
||||
fn read_current_now(&self) -> Option<f64>;
|
||||
|
||||
fn read_charge_power(&self) -> Option<f64>;
|
||||
|
||||
fn charge_limit(&mut self, limit: Option<f64>);
|
||||
|
||||
fn get_charge_limit(&self) -> Option<f64>;
|
||||
|
|
|
@ -14,6 +14,7 @@ impl Into<BatteryJson> for Battery {
|
|||
charge_rate: None,
|
||||
charge_mode: None,
|
||||
events: Vec::default(),
|
||||
root: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +76,10 @@ impl TBattery for Battery {
|
|||
None
|
||||
}
|
||||
|
||||
fn read_charge_power(&self) -> Option<f64> {
|
||||
None
|
||||
}
|
||||
|
||||
fn charge_limit(&mut self, _limit: Option<f64>) {}
|
||||
|
||||
fn get_charge_limit(&self) -> Option<f64> {
|
||||
|
|
|
@ -180,6 +180,7 @@ pub struct Cpu {
|
|||
pub governor: String,
|
||||
index: usize,
|
||||
state: crate::state::steam_deck::Cpu,
|
||||
root: std::path::PathBuf,
|
||||
}
|
||||
|
||||
impl Cpu {
|
||||
|
@ -191,12 +192,14 @@ impl Cpu {
|
|||
governor: other.governor,
|
||||
index: i,
|
||||
state: crate::state::steam_deck::Cpu::default(),
|
||||
root: other.root.unwrap_or_else(|| "/".to_owned()).into(),
|
||||
},
|
||||
_ => Self {
|
||||
online: other.online,
|
||||
governor: other.governor,
|
||||
index: i,
|
||||
state: crate::state::steam_deck::Cpu::default(),
|
||||
root: other.root.unwrap_or_else(|| "/".to_owned()).into(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -243,6 +246,7 @@ impl Cpu {
|
|||
.unwrap_or("schedutil".to_owned()),
|
||||
index: cpu_index,
|
||||
state: crate::state::steam_deck::Cpu::default(),
|
||||
root: "/".into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,6 +267,7 @@ impl Into<CpuJson> for Cpu {
|
|||
online: self.online,
|
||||
clock_limits: None,
|
||||
governor: self.governor,
|
||||
root: self.root.to_str().map(|s| s.to_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ impl Into<GpuJson> for Gpu {
|
|||
slow_ppt: None,
|
||||
clock_limits: None,
|
||||
slow_memory: false,
|
||||
root: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,23 @@ pub fn guess_smt(cpus: &Vec<crate::persist::CpuJson>) -> bool {
|
|||
guess
|
||||
}
|
||||
|
||||
pub fn root_or_default_sysfs(root: Option<impl AsRef<std::path::Path>>) -> sysfuss::SysPath {
|
||||
if let Some(root) = root {
|
||||
sysfuss::SysPath::path(root)
|
||||
} else {
|
||||
sysfuss::SysPath::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn always_satisfied<'a, X>(_: &'a X) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub const CARD_NEEDS: &[&'static str] = &[
|
||||
"dev",
|
||||
"uevent"
|
||||
];
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
|
|
@ -76,6 +76,9 @@ fn version_filepath() -> std::path::PathBuf {
|
|||
|
||||
pub fn save_version_file() -> std::io::Result<usize> {
|
||||
let path = version_filepath();
|
||||
if let Some(parent_dir) = path.parent() {
|
||||
std::fs::create_dir_all(parent_dir)?;
|
||||
}
|
||||
std::fs::File::create(path)?.write(crate::consts::PACKAGE_VERSION.as_bytes())
|
||||
}
|
||||
|
||||
|
|
14
package.json
14
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "PowerTools",
|
||||
"version": "1.3.1",
|
||||
"version": "1.4.0",
|
||||
"description": "Power tweaks for power users",
|
||||
"scripts": {
|
||||
"build": "shx rm -rf dist && rollup -c",
|
||||
|
@ -9,7 +9,7 @@
|
|||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/NGnius/PowerTools.git"
|
||||
"url": "git+https://git.ngni.us/NG-SD-Plugins/PowerTools.git"
|
||||
},
|
||||
"keywords": [
|
||||
"plugin",
|
||||
|
@ -21,9 +21,9 @@
|
|||
"author": "NGnius (Graham) <ngniusness@gmail.com>",
|
||||
"license": "GPL-3.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/NGnius/PowerTools/issues"
|
||||
"url": "https://git.ngni.us/NG-SD-Plugins/PowerTools/issues"
|
||||
},
|
||||
"homepage": "https://github.com/NGnius/PowerTools#readme",
|
||||
"homepage": "https://git.ngni.us/NG-SD-Plugins/PowerTools#readme",
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^21.1.0",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
|
@ -35,12 +35,12 @@
|
|||
"rollup": "^2.79.1",
|
||||
"rollup-plugin-import-assets": "^1.1.1",
|
||||
"shx": "^0.3.4",
|
||||
"tslib": "^2.5.0",
|
||||
"tslib": "^2.5.3",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"decky-frontend-lib": "~3.20.7",
|
||||
"react-icons": "^4.8.0",
|
||||
"decky-frontend-lib": "~3.21.1",
|
||||
"react-icons": "^4.9.0",
|
||||
"usdpl-front": "file:src/usdpl_front"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
"discord_id": "106537989684887552",
|
||||
"description": "Power tweaks for power users",
|
||||
"tags": [ "utility", "power-management", "root" ],
|
||||
"image": "https://raw.githubusercontent.com/NGnius/PowerTools/main/assets/thumbnail.png"
|
||||
"image": "https://git.ngni.us/NG-SD-Plugins/PowerTools/raw/branch/main/assets/thumbnail.png"
|
||||
}
|
||||
}
|
||||
|
|
328
pnpm-lock.yaml
328
pnpm-lock.yaml
|
@ -1,12 +1,16 @@
|
|||
lockfileVersion: '6.0'
|
||||
lockfileVersion: '6.1'
|
||||
|
||||
settings:
|
||||
autoInstallPeers: true
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
decky-frontend-lib:
|
||||
specifier: ~3.20.7
|
||||
version: 3.20.7
|
||||
specifier: ~3.21.1
|
||||
version: 3.21.1
|
||||
react-icons:
|
||||
specifier: ^4.8.0
|
||||
version: 4.8.0(react@18.2.0)
|
||||
specifier: ^4.9.0
|
||||
version: 4.9.0(react@18.2.0)
|
||||
usdpl-front:
|
||||
specifier: file:src/usdpl_front
|
||||
version: file:src/usdpl_front
|
||||
|
@ -26,7 +30,7 @@ devDependencies:
|
|||
version: 4.0.0(rollup@2.79.1)
|
||||
'@rollup/plugin-typescript':
|
||||
specifier: ^8.5.0
|
||||
version: 8.5.0(rollup@2.79.1)(tslib@2.5.0)(typescript@4.9.5)
|
||||
version: 8.5.0(rollup@2.79.1)(tslib@2.5.3)(typescript@4.9.5)
|
||||
'@types/react':
|
||||
specifier: 16.14.0
|
||||
version: 16.14.0
|
||||
|
@ -43,21 +47,21 @@ devDependencies:
|
|||
specifier: ^0.3.4
|
||||
version: 0.3.4
|
||||
tslib:
|
||||
specifier: ^2.5.0
|
||||
version: 2.5.0
|
||||
specifier: ^2.5.3
|
||||
version: 2.5.3
|
||||
typescript:
|
||||
specifier: ^4.9.5
|
||||
version: 4.9.5
|
||||
|
||||
packages:
|
||||
|
||||
/@jridgewell/gen-mapping@0.3.2:
|
||||
resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==}
|
||||
/@jridgewell/gen-mapping@0.3.3:
|
||||
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
dependencies:
|
||||
'@jridgewell/set-array': 1.1.2
|
||||
'@jridgewell/sourcemap-codec': 1.4.14
|
||||
'@jridgewell/trace-mapping': 0.3.17
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
'@jridgewell/trace-mapping': 0.3.18
|
||||
dev: true
|
||||
|
||||
/@jridgewell/resolve-uri@3.1.0:
|
||||
|
@ -70,19 +74,23 @@ packages:
|
|||
engines: {node: '>=6.0.0'}
|
||||
dev: true
|
||||
|
||||
/@jridgewell/source-map@0.3.2:
|
||||
resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==}
|
||||
/@jridgewell/source-map@0.3.3:
|
||||
resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==}
|
||||
dependencies:
|
||||
'@jridgewell/gen-mapping': 0.3.2
|
||||
'@jridgewell/trace-mapping': 0.3.17
|
||||
'@jridgewell/gen-mapping': 0.3.3
|
||||
'@jridgewell/trace-mapping': 0.3.18
|
||||
dev: true
|
||||
|
||||
/@jridgewell/sourcemap-codec@1.4.14:
|
||||
resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
|
||||
dev: true
|
||||
|
||||
/@jridgewell/trace-mapping@0.3.17:
|
||||
resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==}
|
||||
/@jridgewell/sourcemap-codec@1.4.15:
|
||||
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
|
||||
dev: true
|
||||
|
||||
/@jridgewell/trace-mapping@0.3.18:
|
||||
resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==}
|
||||
dependencies:
|
||||
'@jridgewell/resolve-uri': 3.1.0
|
||||
'@jridgewell/sourcemap-codec': 1.4.14
|
||||
|
@ -138,7 +146,7 @@ packages:
|
|||
rollup: 2.79.1
|
||||
dev: true
|
||||
|
||||
/@rollup/plugin-typescript@8.5.0(rollup@2.79.1)(tslib@2.5.0)(typescript@4.9.5):
|
||||
/@rollup/plugin-typescript@8.5.0(rollup@2.79.1)(tslib@2.5.3)(typescript@4.9.5):
|
||||
resolution: {integrity: sha512-wMv1/scv0m/rXx21wD2IsBbJFba8wGF3ErJIr6IKRfRj49S85Lszbxb4DCo8iILpluTjk2GAAu9CoZt4G3ppgQ==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
peerDependencies:
|
||||
|
@ -152,7 +160,7 @@ packages:
|
|||
'@rollup/pluginutils': 3.1.0(rollup@2.79.1)
|
||||
resolve: 1.22.2
|
||||
rollup: 2.79.1
|
||||
tslib: 2.5.0
|
||||
tslib: 2.5.3
|
||||
typescript: 4.9.5
|
||||
dev: true
|
||||
|
||||
|
@ -171,35 +179,31 @@ packages:
|
|||
/@types/eslint-scope@3.7.4:
|
||||
resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==}
|
||||
dependencies:
|
||||
'@types/eslint': 8.37.0
|
||||
'@types/estree': 0.0.51
|
||||
'@types/eslint': 8.40.2
|
||||
'@types/estree': 1.0.1
|
||||
dev: true
|
||||
|
||||
/@types/eslint@8.37.0:
|
||||
resolution: {integrity: sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==}
|
||||
/@types/eslint@8.40.2:
|
||||
resolution: {integrity: sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ==}
|
||||
dependencies:
|
||||
'@types/estree': 0.0.51
|
||||
'@types/json-schema': 7.0.11
|
||||
'@types/estree': 1.0.1
|
||||
'@types/json-schema': 7.0.12
|
||||
dev: true
|
||||
|
||||
/@types/estree@0.0.39:
|
||||
resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
|
||||
dev: true
|
||||
|
||||
/@types/estree@0.0.51:
|
||||
resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==}
|
||||
/@types/estree@1.0.1:
|
||||
resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
|
||||
dev: true
|
||||
|
||||
/@types/estree@1.0.0:
|
||||
resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==}
|
||||
/@types/json-schema@7.0.12:
|
||||
resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
|
||||
dev: true
|
||||
|
||||
/@types/json-schema@7.0.11:
|
||||
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
|
||||
dev: true
|
||||
|
||||
/@types/node@18.15.11:
|
||||
resolution: {integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==}
|
||||
/@types/node@20.3.1:
|
||||
resolution: {integrity: sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==}
|
||||
dev: true
|
||||
|
||||
/@types/prop-types@15.7.5:
|
||||
|
@ -216,15 +220,15 @@ packages:
|
|||
/@types/resolve@1.17.1:
|
||||
resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
|
||||
dependencies:
|
||||
'@types/node': 18.15.11
|
||||
'@types/node': 20.3.1
|
||||
dev: true
|
||||
|
||||
/@types/webpack@5.28.1:
|
||||
resolution: {integrity: sha512-qw1MqGZclCoBrpiSe/hokSgQM/su8Ocpl3L/YHE0L6moyaypg4+5F7Uzq7NgaPKPxUxUbQ4fLPLpDWdR27bCZw==}
|
||||
dependencies:
|
||||
'@types/node': 18.15.11
|
||||
'@types/node': 20.3.1
|
||||
tapable: 2.2.1
|
||||
webpack: 5.78.0
|
||||
webpack: 5.87.0
|
||||
transitivePeerDependencies:
|
||||
- '@swc/core'
|
||||
- esbuild
|
||||
|
@ -232,109 +236,109 @@ packages:
|
|||
- webpack-cli
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/ast@1.11.1:
|
||||
resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==}
|
||||
/@webassemblyjs/ast@1.11.6:
|
||||
resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==}
|
||||
dependencies:
|
||||
'@webassemblyjs/helper-numbers': 1.11.1
|
||||
'@webassemblyjs/helper-wasm-bytecode': 1.11.1
|
||||
'@webassemblyjs/helper-numbers': 1.11.6
|
||||
'@webassemblyjs/helper-wasm-bytecode': 1.11.6
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/floating-point-hex-parser@1.11.1:
|
||||
resolution: {integrity: sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==}
|
||||
/@webassemblyjs/floating-point-hex-parser@1.11.6:
|
||||
resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==}
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/helper-api-error@1.11.1:
|
||||
resolution: {integrity: sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==}
|
||||
/@webassemblyjs/helper-api-error@1.11.6:
|
||||
resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==}
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/helper-buffer@1.11.1:
|
||||
resolution: {integrity: sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==}
|
||||
/@webassemblyjs/helper-buffer@1.11.6:
|
||||
resolution: {integrity: sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==}
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/helper-numbers@1.11.1:
|
||||
resolution: {integrity: sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==}
|
||||
/@webassemblyjs/helper-numbers@1.11.6:
|
||||
resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==}
|
||||
dependencies:
|
||||
'@webassemblyjs/floating-point-hex-parser': 1.11.1
|
||||
'@webassemblyjs/helper-api-error': 1.11.1
|
||||
'@webassemblyjs/floating-point-hex-parser': 1.11.6
|
||||
'@webassemblyjs/helper-api-error': 1.11.6
|
||||
'@xtuc/long': 4.2.2
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/helper-wasm-bytecode@1.11.1:
|
||||
resolution: {integrity: sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==}
|
||||
/@webassemblyjs/helper-wasm-bytecode@1.11.6:
|
||||
resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==}
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/helper-wasm-section@1.11.1:
|
||||
resolution: {integrity: sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==}
|
||||
/@webassemblyjs/helper-wasm-section@1.11.6:
|
||||
resolution: {integrity: sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==}
|
||||
dependencies:
|
||||
'@webassemblyjs/ast': 1.11.1
|
||||
'@webassemblyjs/helper-buffer': 1.11.1
|
||||
'@webassemblyjs/helper-wasm-bytecode': 1.11.1
|
||||
'@webassemblyjs/wasm-gen': 1.11.1
|
||||
'@webassemblyjs/ast': 1.11.6
|
||||
'@webassemblyjs/helper-buffer': 1.11.6
|
||||
'@webassemblyjs/helper-wasm-bytecode': 1.11.6
|
||||
'@webassemblyjs/wasm-gen': 1.11.6
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/ieee754@1.11.1:
|
||||
resolution: {integrity: sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==}
|
||||
/@webassemblyjs/ieee754@1.11.6:
|
||||
resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==}
|
||||
dependencies:
|
||||
'@xtuc/ieee754': 1.2.0
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/leb128@1.11.1:
|
||||
resolution: {integrity: sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==}
|
||||
/@webassemblyjs/leb128@1.11.6:
|
||||
resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==}
|
||||
dependencies:
|
||||
'@xtuc/long': 4.2.2
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/utf8@1.11.1:
|
||||
resolution: {integrity: sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==}
|
||||
/@webassemblyjs/utf8@1.11.6:
|
||||
resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==}
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/wasm-edit@1.11.1:
|
||||
resolution: {integrity: sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==}
|
||||
/@webassemblyjs/wasm-edit@1.11.6:
|
||||
resolution: {integrity: sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==}
|
||||
dependencies:
|
||||
'@webassemblyjs/ast': 1.11.1
|
||||
'@webassemblyjs/helper-buffer': 1.11.1
|
||||
'@webassemblyjs/helper-wasm-bytecode': 1.11.1
|
||||
'@webassemblyjs/helper-wasm-section': 1.11.1
|
||||
'@webassemblyjs/wasm-gen': 1.11.1
|
||||
'@webassemblyjs/wasm-opt': 1.11.1
|
||||
'@webassemblyjs/wasm-parser': 1.11.1
|
||||
'@webassemblyjs/wast-printer': 1.11.1
|
||||
'@webassemblyjs/ast': 1.11.6
|
||||
'@webassemblyjs/helper-buffer': 1.11.6
|
||||
'@webassemblyjs/helper-wasm-bytecode': 1.11.6
|
||||
'@webassemblyjs/helper-wasm-section': 1.11.6
|
||||
'@webassemblyjs/wasm-gen': 1.11.6
|
||||
'@webassemblyjs/wasm-opt': 1.11.6
|
||||
'@webassemblyjs/wasm-parser': 1.11.6
|
||||
'@webassemblyjs/wast-printer': 1.11.6
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/wasm-gen@1.11.1:
|
||||
resolution: {integrity: sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==}
|
||||
/@webassemblyjs/wasm-gen@1.11.6:
|
||||
resolution: {integrity: sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==}
|
||||
dependencies:
|
||||
'@webassemblyjs/ast': 1.11.1
|
||||
'@webassemblyjs/helper-wasm-bytecode': 1.11.1
|
||||
'@webassemblyjs/ieee754': 1.11.1
|
||||
'@webassemblyjs/leb128': 1.11.1
|
||||
'@webassemblyjs/utf8': 1.11.1
|
||||
'@webassemblyjs/ast': 1.11.6
|
||||
'@webassemblyjs/helper-wasm-bytecode': 1.11.6
|
||||
'@webassemblyjs/ieee754': 1.11.6
|
||||
'@webassemblyjs/leb128': 1.11.6
|
||||
'@webassemblyjs/utf8': 1.11.6
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/wasm-opt@1.11.1:
|
||||
resolution: {integrity: sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==}
|
||||
/@webassemblyjs/wasm-opt@1.11.6:
|
||||
resolution: {integrity: sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==}
|
||||
dependencies:
|
||||
'@webassemblyjs/ast': 1.11.1
|
||||
'@webassemblyjs/helper-buffer': 1.11.1
|
||||
'@webassemblyjs/wasm-gen': 1.11.1
|
||||
'@webassemblyjs/wasm-parser': 1.11.1
|
||||
'@webassemblyjs/ast': 1.11.6
|
||||
'@webassemblyjs/helper-buffer': 1.11.6
|
||||
'@webassemblyjs/wasm-gen': 1.11.6
|
||||
'@webassemblyjs/wasm-parser': 1.11.6
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/wasm-parser@1.11.1:
|
||||
resolution: {integrity: sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==}
|
||||
/@webassemblyjs/wasm-parser@1.11.6:
|
||||
resolution: {integrity: sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==}
|
||||
dependencies:
|
||||
'@webassemblyjs/ast': 1.11.1
|
||||
'@webassemblyjs/helper-api-error': 1.11.1
|
||||
'@webassemblyjs/helper-wasm-bytecode': 1.11.1
|
||||
'@webassemblyjs/ieee754': 1.11.1
|
||||
'@webassemblyjs/leb128': 1.11.1
|
||||
'@webassemblyjs/utf8': 1.11.1
|
||||
'@webassemblyjs/ast': 1.11.6
|
||||
'@webassemblyjs/helper-api-error': 1.11.6
|
||||
'@webassemblyjs/helper-wasm-bytecode': 1.11.6
|
||||
'@webassemblyjs/ieee754': 1.11.6
|
||||
'@webassemblyjs/leb128': 1.11.6
|
||||
'@webassemblyjs/utf8': 1.11.6
|
||||
dev: true
|
||||
|
||||
/@webassemblyjs/wast-printer@1.11.1:
|
||||
resolution: {integrity: sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==}
|
||||
/@webassemblyjs/wast-printer@1.11.6:
|
||||
resolution: {integrity: sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==}
|
||||
dependencies:
|
||||
'@webassemblyjs/ast': 1.11.1
|
||||
'@webassemblyjs/ast': 1.11.6
|
||||
'@xtuc/long': 4.2.2
|
||||
dev: true
|
||||
|
||||
|
@ -346,16 +350,16 @@ packages:
|
|||
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
|
||||
dev: true
|
||||
|
||||
/acorn-import-assertions@1.8.0(acorn@8.8.2):
|
||||
resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==}
|
||||
/acorn-import-assertions@1.9.0(acorn@8.9.0):
|
||||
resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==}
|
||||
peerDependencies:
|
||||
acorn: ^8
|
||||
dependencies:
|
||||
acorn: 8.8.2
|
||||
acorn: 8.9.0
|
||||
dev: true
|
||||
|
||||
/acorn@8.8.2:
|
||||
resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==}
|
||||
/acorn@8.9.0:
|
||||
resolution: {integrity: sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
@ -388,15 +392,15 @@ packages:
|
|||
concat-map: 0.0.1
|
||||
dev: true
|
||||
|
||||
/browserslist@4.21.5:
|
||||
resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==}
|
||||
/browserslist@4.21.9:
|
||||
resolution: {integrity: sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==}
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001474
|
||||
electron-to-chromium: 1.4.353
|
||||
node-releases: 2.0.10
|
||||
update-browserslist-db: 1.0.10(browserslist@4.21.5)
|
||||
caniuse-lite: 1.0.30001503
|
||||
electron-to-chromium: 1.4.433
|
||||
node-releases: 2.0.12
|
||||
update-browserslist-db: 1.0.11(browserslist@4.21.9)
|
||||
dev: true
|
||||
|
||||
/buffer-from@1.1.2:
|
||||
|
@ -408,8 +412,8 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/caniuse-lite@1.0.30001474:
|
||||
resolution: {integrity: sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q==}
|
||||
/caniuse-lite@1.0.30001503:
|
||||
resolution: {integrity: sha512-Sf9NiF+wZxPfzv8Z3iS0rXM1Do+iOy2Lxvib38glFX+08TCYYYGR5fRJXk4d77C4AYwhUjgYgMsMudbh2TqCKw==}
|
||||
dev: true
|
||||
|
||||
/chrome-trace-event@1.0.3:
|
||||
|
@ -433,8 +437,8 @@ packages:
|
|||
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
|
||||
dev: true
|
||||
|
||||
/decky-frontend-lib@3.20.7:
|
||||
resolution: {integrity: sha512-Zwwbo50cqpTbCfSCZaqITgTRvWs7pK9KO1A+Oo2sCC/DqOfyUtEH5niNPid4Qxu+yh4lsbEjTurJk1nCfd+nZw==}
|
||||
/decky-frontend-lib@3.21.1:
|
||||
resolution: {integrity: sha512-30605ET9qqZ6St6I9WmMmLGgSrTIdMwo7xy85+lRaF1miUd2icOGEJjwnbVcZDdkal+1fJ3tNEDXlchVfG4TrA==}
|
||||
dev: false
|
||||
|
||||
/deepmerge@4.3.1:
|
||||
|
@ -442,20 +446,20 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/electron-to-chromium@1.4.353:
|
||||
resolution: {integrity: sha512-IdJVpMHJoBT/nn0GQ02wPfbhogDVpd1ud95lP//FTf5l35wzxKJwibB4HBdY7Q+xKPA1nkZ0UDLOMyRj5U5IAQ==}
|
||||
/electron-to-chromium@1.4.433:
|
||||
resolution: {integrity: sha512-MGO1k0w1RgrfdbLVwmXcDhHHuxCn2qRgR7dYsJvWFKDttvYPx6FNzCGG0c/fBBvzK2LDh3UV7Tt9awnHnvAAUQ==}
|
||||
dev: true
|
||||
|
||||
/enhanced-resolve@5.12.0:
|
||||
resolution: {integrity: sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==}
|
||||
/enhanced-resolve@5.15.0:
|
||||
resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
tapable: 2.2.1
|
||||
dev: true
|
||||
|
||||
/es-module-lexer@0.9.3:
|
||||
resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==}
|
||||
/es-module-lexer@1.3.0:
|
||||
resolution: {integrity: sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==}
|
||||
dev: true
|
||||
|
||||
/escalade@3.1.1:
|
||||
|
@ -583,8 +587,8 @@ packages:
|
|||
builtin-modules: 3.3.0
|
||||
dev: true
|
||||
|
||||
/is-core-module@2.11.0:
|
||||
resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==}
|
||||
/is-core-module@2.12.1:
|
||||
resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==}
|
||||
dependencies:
|
||||
has: 1.0.3
|
||||
dev: true
|
||||
|
@ -596,14 +600,14 @@ packages:
|
|||
/is-reference@1.2.1:
|
||||
resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
|
||||
dependencies:
|
||||
'@types/estree': 1.0.0
|
||||
'@types/estree': 1.0.1
|
||||
dev: true
|
||||
|
||||
/jest-worker@27.5.1:
|
||||
resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
dependencies:
|
||||
'@types/node': 18.15.11
|
||||
'@types/node': 20.3.1
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 8.1.1
|
||||
dev: true
|
||||
|
@ -668,8 +672,8 @@ packages:
|
|||
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
|
||||
dev: true
|
||||
|
||||
/node-releases@2.0.10:
|
||||
resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==}
|
||||
/node-releases@2.0.12:
|
||||
resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==}
|
||||
dev: true
|
||||
|
||||
/once@1.4.0:
|
||||
|
@ -707,8 +711,8 @@ packages:
|
|||
safe-buffer: 5.2.1
|
||||
dev: true
|
||||
|
||||
/react-icons@4.8.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==}
|
||||
/react-icons@4.9.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-ijUnFr//ycebOqujtqtV9PFS7JjhWg0QU6ykURVHuL4cbofvRCf3f6GMn9+fBktEFQOIVZnuAYLZdiyadRQRFg==}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
dependencies:
|
||||
|
@ -733,7 +737,7 @@ packages:
|
|||
resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
is-core-module: 2.11.0
|
||||
is-core-module: 2.12.1
|
||||
path-parse: 1.0.7
|
||||
supports-preserve-symlinks-flag: 1.0.0
|
||||
dev: true
|
||||
|
@ -766,11 +770,11 @@ packages:
|
|||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
dev: true
|
||||
|
||||
/schema-utils@3.1.1:
|
||||
resolution: {integrity: sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==}
|
||||
/schema-utils@3.3.0:
|
||||
resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.11
|
||||
'@types/json-schema': 7.0.12
|
||||
ajv: 6.12.6
|
||||
ajv-keywords: 3.5.2(ajv@6.12.6)
|
||||
dev: true
|
||||
|
@ -834,8 +838,8 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/terser-webpack-plugin@5.3.7(webpack@5.78.0):
|
||||
resolution: {integrity: sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==}
|
||||
/terser-webpack-plugin@5.3.9(webpack@5.87.0):
|
||||
resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
peerDependencies:
|
||||
'@swc/core': '*'
|
||||
|
@ -850,27 +854,27 @@ packages:
|
|||
uglify-js:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.17
|
||||
'@jridgewell/trace-mapping': 0.3.18
|
||||
jest-worker: 27.5.1
|
||||
schema-utils: 3.1.1
|
||||
schema-utils: 3.3.0
|
||||
serialize-javascript: 6.0.1
|
||||
terser: 5.16.8
|
||||
webpack: 5.78.0
|
||||
terser: 5.18.0
|
||||
webpack: 5.87.0
|
||||
dev: true
|
||||
|
||||
/terser@5.16.8:
|
||||
resolution: {integrity: sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA==}
|
||||
/terser@5.18.0:
|
||||
resolution: {integrity: sha512-pdL757Ig5a0I+owA42l6tIuEycRuM7FPY4n62h44mRLRfnOxJkkOHd6i89dOpwZlpF6JXBwaAHF6yWzFrt+QyA==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@jridgewell/source-map': 0.3.2
|
||||
acorn: 8.8.2
|
||||
'@jridgewell/source-map': 0.3.3
|
||||
acorn: 8.9.0
|
||||
commander: 2.20.3
|
||||
source-map-support: 0.5.21
|
||||
dev: true
|
||||
|
||||
/tslib@2.5.0:
|
||||
resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==}
|
||||
/tslib@2.5.3:
|
||||
resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==}
|
||||
dev: true
|
||||
|
||||
/typescript@4.9.5:
|
||||
|
@ -879,13 +883,13 @@ packages:
|
|||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/update-browserslist-db@1.0.10(browserslist@4.21.5):
|
||||
resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==}
|
||||
/update-browserslist-db@1.0.11(browserslist@4.21.9):
|
||||
resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
browserslist: '>= 4.21.0'
|
||||
dependencies:
|
||||
browserslist: 4.21.5
|
||||
browserslist: 4.21.9
|
||||
escalade: 3.1.1
|
||||
picocolors: 1.0.0
|
||||
dev: true
|
||||
|
@ -913,8 +917,8 @@ packages:
|
|||
engines: {node: '>=10.13.0'}
|
||||
dev: true
|
||||
|
||||
/webpack@5.78.0:
|
||||
resolution: {integrity: sha512-gT5DP72KInmE/3azEaQrISjTvLYlSM0j1Ezhht/KLVkrqtv10JoP/RXhwmX/frrutOPuSq3o5Vq0ehR/4Vmd1g==}
|
||||
/webpack@5.87.0:
|
||||
resolution: {integrity: sha512-GOu1tNbQ7p1bDEoFRs2YPcfyGs8xq52yyPBZ3m2VGnXGtV9MxjrkABHm4V9Ia280OefsSLzvbVoXcfLxjKY/Iw==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
|
@ -924,16 +928,16 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
'@types/eslint-scope': 3.7.4
|
||||
'@types/estree': 0.0.51
|
||||
'@webassemblyjs/ast': 1.11.1
|
||||
'@webassemblyjs/wasm-edit': 1.11.1
|
||||
'@webassemblyjs/wasm-parser': 1.11.1
|
||||
acorn: 8.8.2
|
||||
acorn-import-assertions: 1.8.0(acorn@8.8.2)
|
||||
browserslist: 4.21.5
|
||||
'@types/estree': 1.0.1
|
||||
'@webassemblyjs/ast': 1.11.6
|
||||
'@webassemblyjs/wasm-edit': 1.11.6
|
||||
'@webassemblyjs/wasm-parser': 1.11.6
|
||||
acorn: 8.9.0
|
||||
acorn-import-assertions: 1.9.0(acorn@8.9.0)
|
||||
browserslist: 4.21.9
|
||||
chrome-trace-event: 1.0.3
|
||||
enhanced-resolve: 5.12.0
|
||||
es-module-lexer: 0.9.3
|
||||
enhanced-resolve: 5.15.0
|
||||
es-module-lexer: 1.3.0
|
||||
eslint-scope: 5.1.1
|
||||
events: 3.3.0
|
||||
glob-to-regexp: 0.4.1
|
||||
|
@ -942,9 +946,9 @@ packages:
|
|||
loader-runner: 4.3.0
|
||||
mime-types: 2.1.35
|
||||
neo-async: 2.6.2
|
||||
schema-utils: 3.1.1
|
||||
schema-utils: 3.3.0
|
||||
tapable: 2.2.1
|
||||
terser-webpack-plugin: 5.3.7(webpack@5.78.0)
|
||||
terser-webpack-plugin: 5.3.9(webpack@5.87.0)
|
||||
watchpack: 2.4.0
|
||||
webpack-sources: 3.2.3
|
||||
transitivePeerDependencies:
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
"charge_rate": {
|
||||
"min": 250,
|
||||
"max": 2500
|
||||
}
|
||||
},
|
||||
"extra_readouts": false
|
||||
},
|
||||
"cpus": {
|
||||
"cpus": [
|
||||
|
|
|
@ -117,6 +117,10 @@ export async function getBatteryChargeDesign(): Promise<number> {
|
|||
return (await call_backend("BATTERY_charge_design", []))[0];
|
||||
}
|
||||
|
||||
export async function getBatteryChargePower(): Promise<number> {
|
||||
return (await call_backend("BATTERY_charge_power", []))[0];
|
||||
}
|
||||
|
||||
export async function getBatteryChargeRate(): Promise<number | null> {
|
||||
return (await call_backend("BATTERY_get_charge_rate", []))[0];
|
||||
}
|
||||
|
@ -302,3 +306,41 @@ export async function onPluggedIn(): Promise<boolean> {
|
|||
export async function onUnplugged(): Promise<boolean> {
|
||||
return (await call_backend("GENERAL_on_unplugged", []))[0];
|
||||
}
|
||||
|
||||
export type Message = {
|
||||
/// Message identifier
|
||||
id: number | null,
|
||||
/// Message title
|
||||
title: string,
|
||||
/// Message content
|
||||
body: string,
|
||||
/// Link for further information
|
||||
url: string | null,
|
||||
};
|
||||
|
||||
export async function getMessages(since: number | null): Promise<Message[]> {
|
||||
return (await call_backend("MESSAGE_get", [since]));
|
||||
}
|
||||
|
||||
export async function dismissMessage(id: number): Promise<boolean> {
|
||||
return (await call_backend("MESSAGE_dismiss", [id]))[0];
|
||||
}
|
||||
|
||||
export type Periodicals = {
|
||||
battery_current: number | null,
|
||||
battery_charge_now: number | null,
|
||||
battery_charge_full: number | null,
|
||||
battery_charge_power: number | null,
|
||||
settings_path: string | null,
|
||||
};
|
||||
|
||||
export async function getPeriodicals(): Promise<Periodicals> {
|
||||
const result: any[] = await call_backend("GENERAL_get_periodicals", []);
|
||||
return {
|
||||
battery_current: result[0],
|
||||
battery_charge_now: result[1],
|
||||
battery_charge_full: result[2],
|
||||
battery_charge_power: result[3],
|
||||
settings_path: result[4],
|
||||
};
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
CHARGE_MODE_BATT,
|
||||
CURRENT_BATT,
|
||||
CHARGE_LIMIT_BATT,
|
||||
CHARGE_POWER_BATT,
|
||||
} from "../consts";
|
||||
import { set_value, get_value} from "usdpl-front";
|
||||
|
||||
|
@ -54,12 +55,18 @@ export class Battery extends Component<backend.IdcProps> {
|
|||
{get_value(CHARGE_FULL_BATT).toFixed(1)} Wh ({(100 * get_value(CHARGE_FULL_BATT) / get_value(CHARGE_DESIGN_BATT)).toFixed(1)}%)
|
||||
</Field>
|
||||
</PanelSectionRow>}
|
||||
<PanelSectionRow>
|
||||
{get_value(CHARGE_POWER_BATT) != null && get_value(CHARGE_POWER_BATT) > 0 && <PanelSectionRow>
|
||||
<Field
|
||||
label={tr("Charge Power")}>
|
||||
{get_value(CHARGE_POWER_BATT).toFixed(2)} W
|
||||
</Field>
|
||||
</PanelSectionRow>}
|
||||
{get_value(CURRENT_BATT) != null && <PanelSectionRow>
|
||||
<Field
|
||||
label={tr("Current")}>
|
||||
{get_value(CURRENT_BATT)} mA
|
||||
</Field>
|
||||
</PanelSectionRow>
|
||||
</PanelSectionRow>}
|
||||
{(get_value(LIMITS_INFO) as backend.SettingsLimits).battery.charge_current != null && <PanelSectionRow>
|
||||
<ToggleField
|
||||
checked={get_value(CHARGE_RATE_BATT) != null}
|
||||
|
|
58
src/components/message.tsx
Normal file
58
src/components/message.tsx
Normal file
|
@ -0,0 +1,58 @@
|
|||
import { Component, Fragment } from "react";
|
||||
import * as backend from "../backend";
|
||||
|
||||
import {
|
||||
Field,
|
||||
staticClasses,
|
||||
PanelSectionRow,
|
||||
ButtonItem,
|
||||
Navigation,
|
||||
} from "decky-frontend-lib";
|
||||
|
||||
import { MESSAGE_LIST } from "../consts";
|
||||
|
||||
import { set_value, get_value, tr } from "usdpl-front";
|
||||
|
||||
export class DevMessages extends Component<backend.IdcProps> {
|
||||
constructor(props: backend.IdcProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
reloadThingy: "/shrug",
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const reloadGUI = (x: string) => this.setState({reloadThingy: x});
|
||||
const messages: backend.Message[] = get_value(MESSAGE_LIST) as backend.Message[];
|
||||
if (messages.length != 0) {
|
||||
const message = messages[0];
|
||||
return (<Fragment>
|
||||
<div className={staticClasses.PanelSectionTitle}>
|
||||
{message.title}
|
||||
</div>
|
||||
<PanelSectionRow>
|
||||
<Field
|
||||
onClick={()=> { if (message.url) { Navigation.NavigateToExternalWeb(message.url); } }}>
|
||||
{message.body}
|
||||
</Field>
|
||||
<ButtonItem
|
||||
layout="below"
|
||||
onClick={(_: MouseEvent) => {
|
||||
if (message.id) {
|
||||
backend.dismissMessage(message.id);
|
||||
}
|
||||
messages.shift();
|
||||
set_value(MESSAGE_LIST, messages);
|
||||
reloadGUI("MessageDismissed");
|
||||
}}
|
||||
>
|
||||
{tr("Dismiss")}
|
||||
</ButtonItem>
|
||||
</PanelSectionRow>
|
||||
</Fragment>
|
||||
)
|
||||
} else {
|
||||
return <Fragment></Fragment>
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ export const CHARGE_LIMIT_BATT = "BATTERY_charge_limit";
|
|||
export const CHARGE_NOW_BATT = "BATTERY_charge_now";
|
||||
export const CHARGE_FULL_BATT = "BATTERY_charge_full";
|
||||
export const CHARGE_DESIGN_BATT = "BATTERY_charge_design";
|
||||
export const CHARGE_POWER_BATT = "BATTERY_charge_power";
|
||||
|
||||
//export const TOTAL_CPUS = "CPUs_total";
|
||||
export const ONLINE_CPUS = "CPUs_online";
|
||||
|
@ -30,3 +31,8 @@ export const PERSISTENT_GEN = "GENERAL_persistent";
|
|||
export const NAME_GEN = "GENERAL_name";
|
||||
export const PATH_GEN = "GENERAL_path";
|
||||
|
||||
export const MESSAGE_LIST = "MESSAGE_messages";
|
||||
|
||||
export const PERIODICAL_BACKEND_PERIOD = 5000; // milliseconds
|
||||
export const AUTOMATIC_REAPPLY_WAIT = 2000; // milliseconds
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ import {
|
|||
CHARGE_NOW_BATT,
|
||||
CHARGE_FULL_BATT,
|
||||
CHARGE_DESIGN_BATT,
|
||||
CHARGE_POWER_BATT,
|
||||
|
||||
ONLINE_CPUS,
|
||||
ONLINE_STATUS_CPUS,
|
||||
|
@ -57,16 +58,23 @@ import {
|
|||
PERSISTENT_GEN,
|
||||
NAME_GEN,
|
||||
PATH_GEN,
|
||||
|
||||
MESSAGE_LIST,
|
||||
|
||||
PERIODICAL_BACKEND_PERIOD,
|
||||
AUTOMATIC_REAPPLY_WAIT,
|
||||
} from "./consts";
|
||||
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";
|
||||
import { DevMessages } from "./components/message";
|
||||
|
||||
var periodicHook: NodeJS.Timer | null = null;
|
||||
var lifetimeHook: any = null;
|
||||
var startHook: any = null;
|
||||
var endHook: any = null;
|
||||
var usdplReady = false;
|
||||
|
||||
type MinMax = {
|
||||
|
@ -113,6 +121,7 @@ const reload = function() {
|
|||
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) });
|
||||
backend.resolve(backend.getBatteryChargePower(), (rate: number) => { set_value(CHARGE_POWER_BATT, rate) });
|
||||
|
||||
//backend.resolve(backend.getCpuCount(), (count: number) => { set_value(TOTAL_CPUS, count)});
|
||||
backend.resolve(backend.getCpusOnline(), (statii: boolean[]) => {
|
||||
|
@ -150,6 +159,8 @@ const reload = function() {
|
|||
|
||||
backend.resolve(backend.getInfo(), (info: string) => { set_value(BACKEND_INFO, info) });
|
||||
backend.resolve(backend.getDriverProviderName("gpu"), (driver: string) => { set_value(DRIVER_INFO, driver) });
|
||||
|
||||
backend.resolve(backend.getMessages(null), (messages: backend.Message[]) => { set_value(MESSAGE_LIST, messages) });
|
||||
};
|
||||
|
||||
// init USDPL WASM and connection to back-end
|
||||
|
@ -185,22 +196,30 @@ const reload = function() {
|
|||
);
|
||||
});
|
||||
|
||||
//@ts-ignore
|
||||
endHook = SteamClient.Apps.RegisterForGameActionEnd((actionType) => {
|
||||
backend.log(backend.LogLevel.Info, "RegisterForGameActionEnd callback(" + actionType + ")");
|
||||
setTimeout(() => backend.forceApplySettings(), AUTOMATIC_REAPPLY_WAIT);
|
||||
});
|
||||
|
||||
backend.log(backend.LogLevel.Debug, "Registered PowerTools callbacks, hello!");
|
||||
})();
|
||||
|
||||
const periodicals = function() {
|
||||
backend.resolve(backend.getBatteryCurrent(), (rate: number) => { set_value(CURRENT_BATT, rate) });
|
||||
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.getPeriodicals(), (periodicals) => {
|
||||
set_value(CURRENT_BATT, periodicals.battery_current);
|
||||
set_value(CHARGE_NOW_BATT, periodicals.battery_charge_now);
|
||||
set_value(CHARGE_FULL_BATT, periodicals.battery_charge_full);
|
||||
set_value(CHARGE_POWER_BATT, periodicals.battery_charge_power);
|
||||
|
||||
backend.resolve(backend.getGeneralSettingsPath(), (path: string) => {
|
||||
const path = periodicals.settings_path;
|
||||
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);
|
||||
reload();
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
||||
|
@ -215,7 +234,7 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
|||
periodicHook = setInterval(function() {
|
||||
periodicals();
|
||||
reloadGUI("periodic" + (new Date()).getTime().toString());
|
||||
}, 1000);
|
||||
}, PERIODICAL_BACKEND_PERIOD);
|
||||
|
||||
if (!usdplReady || !get_value(LIMITS_INFO)) {
|
||||
// Not translated on purpose (to avoid USDPL issues)
|
||||
|
@ -237,6 +256,8 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
|||
|
||||
return (
|
||||
<PanelSection>
|
||||
<DevMessages idc={idc}/>
|
||||
|
||||
<Cpus idc={idc}/>
|
||||
|
||||
<Gpu idc={idc}/>
|
||||
|
@ -314,15 +335,16 @@ export default definePlugin((serverApi: ServerAPI) => {
|
|||
ico = <span><GiDynamite /><GiTimeTrap /><GiTimeBomb /></span>;
|
||||
}
|
||||
return {
|
||||
title: <div className={staticClasses.Title}>I'm a tool</div>,
|
||||
title: <div className={staticClasses.Title}>PowerTools</div>,
|
||||
content: <Content serverAPI={serverApi} />,
|
||||
icon: ico,
|
||||
onDismount() {
|
||||
backend.log(backend.LogLevel.Debug, "PowerTools shutting down");
|
||||
clearInterval(periodicHook!);
|
||||
periodicHook = null;
|
||||
lifetimeHook!.unregister();
|
||||
startHook!.unregister();
|
||||
lifetimeHook?.unregister();
|
||||
startHook?.unregister();
|
||||
endHook?.unregister();
|
||||
//serverApi.routerHook.removeRoute("/decky-plugin-test");
|
||||
backend.log(backend.LogLevel.Debug, "Unregistered PowerTools callbacks, so long and thanks for all the fish.");
|
||||
},
|
||||
|
|
Binary file not shown.
|
@ -65,6 +65,11 @@ msgstr "Présentement (Charge)"
|
|||
msgid "Max (Design)"
|
||||
msgstr "Max (Conçue)"
|
||||
|
||||
#: components/battery.tsx:60
|
||||
# (Wattage of battery charging input)
|
||||
msgid "Charge Power"
|
||||
msgstr "Puissance de charge"
|
||||
|
||||
# (Charge current limit override toggle)
|
||||
#: components/battery.tsx:59
|
||||
msgid "Charge Current Limits"
|
||||
|
|
Binary file not shown.
|
@ -64,6 +64,11 @@ msgstr ""
|
|||
msgid "Max (Design)"
|
||||
msgstr ""
|
||||
|
||||
#: components/battery.tsx:60
|
||||
# (Wattage of battery charging input)
|
||||
msgid "Charge Power"
|
||||
msgstr ""
|
||||
|
||||
#: components/battery.tsx:59
|
||||
# (Charge current limit override toggle)
|
||||
msgid "Charge Current Limits"
|
||||
|
|
BIN
translations/ru-RU.mo
Normal file
BIN
translations/ru-RU.mo
Normal file
Binary file not shown.
Binary file not shown.
|
@ -1,227 +0,0 @@
|
|||
# TEMPLATE TITLE.
|
||||
# Copyright (C) 2023 NGnius
|
||||
# This file is distributed under the same license as the PowerTools package.
|
||||
# NGnius (Graham) <ngniusness@gmail.com>, 2023.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: v1.1\n"
|
||||
"Report-Msgid-Bugs-To: https://github.com/NGnius/PowerTools/issues\n"
|
||||
"POT-Creation-Date: 2023-01-10 20:06-0500\n"
|
||||
"PO-Revision-Date: 2023-01-10 20:06-0500\n"
|
||||
"Last-Translator: NGnius <ngniusness@gmail.com>\n"
|
||||
"Language-Team: NGnius <ngniusness@gmail.com>\n"
|
||||
"Language: conlang\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
# -- index.tsx --
|
||||
|
||||
#: index.tsx:226
|
||||
# (Section title)
|
||||
msgid "Miscellaneous"
|
||||
msgstr "test123"
|
||||
|
||||
#: index.tsx:226
|
||||
# (Profile persistence toggle)
|
||||
msgid "Persistent"
|
||||
msgstr "test123"
|
||||
|
||||
#: index.tsx:227
|
||||
# (Profile persistence toggle description)
|
||||
msgid "Save profile and load it next time"
|
||||
msgstr "test123"
|
||||
|
||||
#: index.tsx:239
|
||||
# (Profile display)
|
||||
msgid "Profile"
|
||||
msgstr "test123"
|
||||
|
||||
# -- components/battery.tsx --
|
||||
|
||||
#: components/battery.tsx:42
|
||||
# (Battery section title)
|
||||
msgid "Battery"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/battery.tsx:46
|
||||
# (Charge of battery at this moment, with percentage of expected full charge in brackets)
|
||||
msgid "Now (Charge)"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/battery.tsx:52
|
||||
# (Maximum capacity of battery, with percentage of design capacity in brackets)
|
||||
msgid "Max (Design)"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/battery.tsx:59
|
||||
# (Charge current limit override toggle)
|
||||
msgid "Charge Current Limits"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/battery.tsx:60
|
||||
# (Charge current limit override toggle description)
|
||||
msgid "Control battery charge rate when awake"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/battery.tsx:74
|
||||
# (Battery maximum input current with unit)
|
||||
msgid "Maximum (mA)"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/battery.tsx:97,115
|
||||
# (Battery charge mode override toggle)
|
||||
msgid "Charge Mode"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/battery.tsx:98
|
||||
# (Battery charge mode override toggle description)
|
||||
msgid "Force battery charge mode"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/battery.tsx:112
|
||||
# (Battery charge mode dropdown)
|
||||
msgid "Mode"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/battery.tsx:133
|
||||
# (Battery current display)
|
||||
msgid "Current"
|
||||
msgstr "test123"
|
||||
|
||||
# -- components/cpus.tsx --
|
||||
|
||||
#: components/cpus.tsx:64
|
||||
# (CPU section title)
|
||||
msgid "CPU"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:70
|
||||
# (CPU advanced mode toggle)
|
||||
msgid "Advanced"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:71
|
||||
# (CPU advanced mode toggle description)
|
||||
msgid "Enables per-thread configuration"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:88
|
||||
# (CPU Simultaneous MultiThreading toggle)
|
||||
msgid "SMT"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:89
|
||||
# (CPU SMT toggle description)
|
||||
msgid "Enables odd-numbered CPUs"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:106
|
||||
# (CPU thread count slider)
|
||||
msgid "Threads"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:137
|
||||
#: components/gpu.tsx:112
|
||||
# (Clock speed override toggle)
|
||||
msgid "Frequency Limits"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:138
|
||||
#: components/gpu.tsx:113
|
||||
# (Clock speed override toggle description)
|
||||
msgid "Set bounds on clock speed"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:165
|
||||
#: components/gpu.tsx:137
|
||||
# (Minimum clock speed with unit)
|
||||
msgid "Minimum (MHz)"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:195
|
||||
#: components/gpu.tsx:160
|
||||
# (Maximum clock speed with unit)
|
||||
msgid "Maximum (MHz)"
|
||||
msgstr "test123"
|
||||
|
||||
# advanced mode
|
||||
|
||||
#: components/cpus.tsx:226
|
||||
# (CPU selection slider)
|
||||
msgid "Selected CPU"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:246
|
||||
# (CPU Online toggle)
|
||||
msgid "Online"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:247
|
||||
# (CPU Online description)
|
||||
msgid "Allow the CPU thread to do work"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/cpus.tsx:342
|
||||
# (CPU scheduling governor dropdown -- governor names are not translated)
|
||||
msgid "Governor"
|
||||
msgstr "test123"
|
||||
|
||||
# -- components/debug.tsx --
|
||||
|
||||
#: components/debug.tsx:29
|
||||
# (Debug section title)
|
||||
msgid "Debug"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/debug.tsx:33
|
||||
# (Version display for native back-end of PowerTools)
|
||||
msgid "Native"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/debug.tsx:47
|
||||
# (Mode display for framework of USDPL API)
|
||||
msgid "Framework"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/debug.tsx:54
|
||||
# (Display for software implementation in PowerTools which applies settings)
|
||||
msgid "Driver"
|
||||
msgstr "test123"
|
||||
|
||||
# -- components/gpu.tsx --
|
||||
|
||||
#: components/gpu.tsx:34
|
||||
# (GPU section title)
|
||||
msgid "GPU"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/gpu.tsx:39
|
||||
# (PPT Limits override toggle)
|
||||
msgid "PowerPlay Limits"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/gpu.tsx:40
|
||||
# (PPT Limits override toggle description)
|
||||
msgid "Override APU TDP settings"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/gpu.tsx:63
|
||||
# (SlowPPT slider with unit)
|
||||
msgid "SlowPPT (W)"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/gpu.tsx:87
|
||||
# (FastPPT slider with unit)
|
||||
msgid "FastPPT (W)"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/gpu.tsx:112
|
||||
# (Reduce memory clock speed toggle)
|
||||
msgid "Downclock Memory"
|
||||
msgstr "test123"
|
||||
|
||||
#: components/gpu.tsx:112
|
||||
# (Reduce memory clock speed toggle description)
|
||||
msgid "Force RAM into low-power mode"
|
||||
msgstr "test123"
|
BIN
translations/uk-UA.mo
Normal file
BIN
translations/uk-UA.mo
Normal file
Binary file not shown.
Loading…
Reference in a new issue