forked from NG-SD-Plugins/PowerTools
Re-add battery stats
This commit is contained in:
parent
db3f4a85c0
commit
26e781df25
10 changed files with 118 additions and 15 deletions
2
backend/Cargo.lock
generated
2
backend/Cargo.lock
generated
|
@ -567,7 +567,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "powertools-rs"
|
||||
version = "1.0.0-beta4"
|
||||
version = "1.0.0-rc1"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "powertools-rs"
|
||||
version = "1.0.0-beta4"
|
||||
version = "1.0.0-rc1"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
@ -6,7 +6,22 @@ use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
|||
|
||||
/// Current current (ha!) web method
|
||||
pub fn current_now(_: super::ApiParameterType) -> super::ApiParameterType {
|
||||
super::utility::map_result(crate::settings::Battery::current_now())
|
||||
super::utility::map_result(crate::settings::Battery::read_current_now())
|
||||
}
|
||||
|
||||
/// Charge now web method
|
||||
pub fn charge_now(_: super::ApiParameterType) -> super::ApiParameterType {
|
||||
super::utility::map_result(crate::settings::Battery::read_charge_now())
|
||||
}
|
||||
|
||||
/// Charge full web method
|
||||
pub fn charge_full(_: super::ApiParameterType) -> super::ApiParameterType {
|
||||
super::utility::map_result(crate::settings::Battery::read_charge_full())
|
||||
}
|
||||
|
||||
/// Charge design web method
|
||||
pub fn charge_design(_: super::ApiParameterType) -> super::ApiParameterType {
|
||||
super::utility::map_result(crate::settings::Battery::read_charge_design())
|
||||
}
|
||||
|
||||
/// Generate set battery charge rate web method
|
||||
|
|
|
@ -17,11 +17,14 @@ use usdpl_back::core::serdes::Primitive;
|
|||
use usdpl_back::Instance;
|
||||
|
||||
fn main() -> Result<(), ()> {
|
||||
#[cfg(debug_assertions)]
|
||||
let log_filepath = format!("/home/deck/{}.log", PACKAGE_NAME);
|
||||
#[cfg(not(debug_assertions))]
|
||||
let log_filepath = format!("/tmp/{}.log", PACKAGE_NAME);
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
if std::path::Path::new(&log_filepath).exists() {
|
||||
std::fs::copy(&log_filepath, "/home/deck/powertools.log.old").unwrap();
|
||||
std::fs::copy(&log_filepath, format!("/home/deck/{}.log.old", PACKAGE_NAME)).unwrap();
|
||||
}
|
||||
}
|
||||
WriteLogger::init(
|
||||
|
@ -59,6 +62,9 @@ fn main() -> Result<(), ()> {
|
|||
})
|
||||
// battery API functions
|
||||
.register("BATTERY_current_now", api::battery::current_now)
|
||||
.register("BATTERY_charge_now", api::battery::charge_now)
|
||||
.register("BATTERY_charge_full", api::battery::charge_full)
|
||||
.register("BATTERY_charge_design", api::battery::charge_design)
|
||||
.register(
|
||||
"BATTERY_set_charge_rate",
|
||||
api::battery::set_charge_rate(loaded_settings.battery.clone(), save_sender.clone()),
|
||||
|
|
|
@ -9,8 +9,13 @@ pub struct Battery {
|
|||
state: crate::state::Battery,
|
||||
}
|
||||
|
||||
const BATTERY_VOLTAGE: f64 = 7.7;
|
||||
|
||||
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/hwmon/hwmon2/device/charge_now"; // read-only
|
||||
const BATTERY_CHARGE_FULL_PATH: &str = "/sys/class/hwmon/hwmon2/device/charge_full"; // read-only
|
||||
const BATTERY_CHARGE_DESIGN_PATH: &str = "/sys/class/hwmon/hwmon2/device/charge_full_design"; // read-only
|
||||
|
||||
impl Battery {
|
||||
#[inline]
|
||||
|
@ -57,7 +62,7 @@ impl Battery {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn current_now() -> Result<u64, SettingError> {
|
||||
pub fn read_current_now() -> Result<u64, SettingError> {
|
||||
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CURRENT_NOW_PATH) {
|
||||
Err((Some(e), None)) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CURRENT_NOW_PATH, e),
|
||||
|
@ -77,6 +82,63 @@ impl Battery {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read_charge_now() -> Result<f64, SettingError> {
|
||||
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_NOW_PATH) {
|
||||
Err((Some(e), None)) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_NOW_PATH, e),
|
||||
setting: super::SettingVariant::Battery,
|
||||
}),
|
||||
Err((None, Some(e))) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_NOW_PATH, e),
|
||||
setting: super::SettingVariant::Battery,
|
||||
}),
|
||||
Err(_) => panic!(
|
||||
"Invalid error while reading from `{}`",
|
||||
BATTERY_CHARGE_NOW_PATH
|
||||
),
|
||||
// convert to Wh
|
||||
Ok(val) => Ok((val as f64) / 1000000.0 * BATTERY_VOLTAGE),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_charge_full() -> Result<f64, SettingError> {
|
||||
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_FULL_PATH) {
|
||||
Err((Some(e), None)) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_FULL_PATH, e),
|
||||
setting: super::SettingVariant::Battery,
|
||||
}),
|
||||
Err((None, Some(e))) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_FULL_PATH, e),
|
||||
setting: super::SettingVariant::Battery,
|
||||
}),
|
||||
Err(_) => panic!(
|
||||
"Invalid error while reading from `{}`",
|
||||
BATTERY_CHARGE_NOW_PATH
|
||||
),
|
||||
// convert to Wh
|
||||
Ok(val) => Ok((val as f64) / 1000000.0 * BATTERY_VOLTAGE),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_charge_design() -> Result<f64, SettingError> {
|
||||
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_DESIGN_PATH) {
|
||||
Err((Some(e), None)) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_DESIGN_PATH, e),
|
||||
setting: super::SettingVariant::Battery,
|
||||
}),
|
||||
Err((None, Some(e))) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_DESIGN_PATH, e),
|
||||
setting: super::SettingVariant::Battery,
|
||||
}),
|
||||
Err(_) => panic!(
|
||||
"Invalid error while reading from `{}`",
|
||||
BATTERY_CHARGE_NOW_PATH
|
||||
),
|
||||
// convert to Wh
|
||||
Ok(val) => Ok((val as f64) / 1000000.0 * BATTERY_VOLTAGE),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn system_default() -> Self {
|
||||
Self {
|
||||
charge_rate: None,
|
||||
|
|
2
main.py
2
main.py
|
@ -11,6 +11,6 @@ class Plugin:
|
|||
# Asyncio-compatible long-running code, executed in a task when the plugin is loaded
|
||||
async def _main(self):
|
||||
# startup
|
||||
#self.backend_proc = subprocess.Popen([PARENT_DIR + "/bin/backend"])
|
||||
self.backend_proc = subprocess.Popen([PARENT_DIR + "/bin/backend"])
|
||||
while True:
|
||||
await asyncio.sleep(1)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "PowerTools",
|
||||
"version": "1.0.0-alpha",
|
||||
"version": "1.0.0-rc1",
|
||||
"description": "Power tweaks for power users",
|
||||
"scripts": {
|
||||
"build": "shx rm -rf dist && rollup -c",
|
||||
|
|
|
@ -36,6 +36,18 @@ export async function getBatteryCurrent(): Promise<number> {
|
|||
return (await call_backend("BATTERY_current_now", []))[0];
|
||||
}
|
||||
|
||||
export async function getBatteryChargeNow(): Promise<number> {
|
||||
return (await call_backend("BATTERY_charge_now", []))[0];
|
||||
}
|
||||
|
||||
export async function getBatteryChargeFull(): Promise<number> {
|
||||
return (await call_backend("BATTERY_charge_full", []))[0];
|
||||
}
|
||||
|
||||
export async function getBatteryChargeDesign(): Promise<number> {
|
||||
return (await call_backend("BATTERY_charge_design", []))[0];
|
||||
}
|
||||
|
||||
export async function getBatteryChargeRate(): Promise<number> {
|
||||
return (await call_backend("BATTERY_get_charge_rate", []))[0];
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ const BACKEND_INFO = "VINFO";
|
|||
|
||||
const CURRENT_BATT = "BATTERY_current_now";
|
||||
const CHARGE_RATE_BATT = "BATTERY_charge_rate";
|
||||
const CHARGE_NOW_BATT = "BATTERY_charge_now";
|
||||
const CHARGE_FULL_BATT = "BATTERY_charge_full";
|
||||
const CHARGE_DESIGN_BATT = "BATTERY_charge_design"
|
||||
|
||||
const TOTAL_CPUS = "CPUs_total";
|
||||
const ONLINE_CPUS = "CPUs_online";
|
||||
|
@ -58,6 +61,9 @@ const reload = function() {
|
|||
|
||||
backend.resolve(backend.getBatteryCurrent(), (rate: number) => { set_value(CURRENT_BATT, rate) });
|
||||
backend.resolve(backend.getBatteryChargeRate(), (rate: number) => { set_value(CHARGE_RATE_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.getBatteryChargeDesign(), (rate: number) => { set_value(CHARGE_DESIGN_BATT, rate) });
|
||||
|
||||
backend.resolve(backend.getCpuCount(), (count: number) => { set_value(TOTAL_CPUS, count)});
|
||||
backend.resolve(backend.getCpusOnline(), (statii: boolean[]) => {
|
||||
|
@ -130,6 +136,8 @@ const reload = function() {
|
|||
|
||||
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.getGeneralPersistent(), (value: boolean) => { set_value(PERSISTENT_GEN, value) });
|
||||
backend.resolve(backend.getGeneralSettingsName(), (name: string) => {
|
||||
|
@ -457,30 +465,30 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
|||
<div className={staticClasses.PanelSectionTitle}>
|
||||
Battery
|
||||
</div>
|
||||
{ false && <PanelSectionRow>
|
||||
<PanelSectionRow>
|
||||
<div className={FieldWithSeparator}>
|
||||
<div className={gamepadDialogClasses.FieldLabelRow}>
|
||||
<div className={gamepadDialogClasses.FieldLabel}>
|
||||
Now (Charge)
|
||||
</div>
|
||||
<div className={gamepadDialogClasses.FieldChildren}>
|
||||
{/* TODO: (7.7 * chargeNowGlobal / 1000000).toFixed(1).toString() + " Wh (" + (100 * chargeNowGlobal / chargeFullGlobal).toFixed(1).toString() + "%)"*/}
|
||||
{get_value(CHARGE_NOW_BATT).toFixed(1)} Wh ({(100 * get_value(CHARGE_NOW_BATT) / get_value(CHARGE_FULL_BATT)).toFixed(1)}%)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PanelSectionRow>}
|
||||
{ false && <PanelSectionRow>
|
||||
</PanelSectionRow>
|
||||
<PanelSectionRow>
|
||||
<div className={FieldWithSeparator}>
|
||||
<div className={gamepadDialogClasses.FieldLabelRow}>
|
||||
<div className={gamepadDialogClasses.FieldLabel}>
|
||||
Max (Design)
|
||||
</div>
|
||||
<div className={gamepadDialogClasses.FieldChildren}>
|
||||
{/* TODO: (7.7 * chargeFullGlobal / 1000000).toFixed(1).toString() + " Wh (" + (100 * chargeFullGlobal / chargeDesignGlobal).toFixed(1).toString() + "%)"*/}
|
||||
{get_value(CHARGE_FULL_BATT).toFixed(1)} Wh ({(100 * get_value(CHARGE_FULL_BATT) / get_value(CHARGE_DESIGN_BATT)).toFixed(1)}%)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PanelSectionRow>}
|
||||
</PanelSectionRow>
|
||||
<PanelSectionRow>
|
||||
<ToggleField
|
||||
checked={get_value(CHARGE_RATE_BATT) != null}
|
||||
|
@ -553,7 +561,7 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
|
|||
<div className={FieldWithSeparator}>
|
||||
<div className={gamepadDialogClasses.FieldLabelRow}>
|
||||
<div className={gamepadDialogClasses.FieldLabel}>
|
||||
Now Playing
|
||||
Profile
|
||||
</div>
|
||||
<div className={gamepadDialogClasses.FieldChildren}>
|
||||
{get_value(NAME_GEN)}
|
||||
|
|
Loading…
Reference in a new issue