Re-add battery stats

This commit is contained in:
NGnius (Graham) 2022-09-05 17:02:02 -04:00
parent db3f4a85c0
commit 26e781df25
10 changed files with 118 additions and 15 deletions

2
backend/Cargo.lock generated
View file

@ -567,7 +567,7 @@ dependencies = [
[[package]]
name = "powertools-rs"
version = "1.0.0-beta4"
version = "1.0.0-rc1"
dependencies = [
"log",
"serde",

View file

@ -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

View file

@ -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

View file

@ -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()),

View file

@ -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,

View file

@ -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)

View file

@ -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",

View file

@ -1,5 +1,5 @@
{
"name": "PowerTools",
"name": "PowerTools",
"author": "NGnius",
"flags": ["root", "debug"],
"publish": {

View file

@ -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];
}

View file

@ -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)}