GithubHelp home page GithubHelp logo

svartalf / rust-battery Goto Github PK

View Code? Open in Web Editor NEW
350.0 6.0 38.0 254 KB

Rust crate providing cross-platform information about the notebook batteries.

Home Page: https://crates.io/crates/battery

License: Apache License 2.0

Rust 93.46% C 2.95% Python 3.59%
rust rust-crate battery battery-information linux macos windows freebsd dragonflybsd

rust-battery's People

Contributors

absolucy avatar atul9 avatar dependabot-preview[bot] avatar gerschtli avatar juanpotato avatar kerhong avatar monkeywithacupcake avatar rkday avatar simonrw avatar svartalf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

rust-battery's Issues

No license files on crates.io

There LICENSE-APACHE and LICENSE-MIT files on github, but no license files on crates.io. Could you add them? This is mandatory for some Linux distros if we want to package rust-battery for official repos.

About how to build and battery info scraping

Hey,

I want to use this awesome project in polybar via shell script. But i can't figure it out how to compile cli or ffi. I installed battop via yay battop. It works perfectly.

Actually, i couldn't see a installation guide or it could be a not-well documented. Simply,

  1. When i run this: cargo install battery-ffi

Returns:

Updating crates.io index
  Installing battery-ffi v0.7.0
error: specified package has no binaries
  1. battop is not supporting output args like this:

battop --time-to-empty

It may be really really life saver.

  1. cargo build --release

Returns:

error: failed to resolve patches for `https://github.com/rust-lang/crates.io-index`

Caused by:
  patch for `battery` in `https://github.com/rust-lang/crates.io-index` did not resolve to any crates. If this is unexpected, you may wish to consult: https://github.com/rust-lang/cargo/issues/4678

The bare-minimum thing I want is looks like:

$ battery-cli --time-to-empty

Consequently, I want to write the battery's battery_get_time_to_empty output to the polybar. I am trying to figure it out how to write a script that scrapes about battery informations.

Android support / Termux support

I tried to compile starship on a Samsung Galaxy Tab s6 in Termux and it failed with the message Support for this target OS is not implemented yet!

Compile error of rust-battery in Termux

error: Support for this target OS is not implemented yet!
 You may want to create an issue: https://github.com/svartalf/rust-battery/issues/new
  --> /data/data/com.termux/files/home/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.7.5/src/platform/mod.rs:27:9
   |
27 | /         compile_error!("Support for this target OS is not implemented yet!\n \
28 | |             You may want to create an issue: https://github.com/svartalf/rust-battery/issues/new");
   | |___________________________________________________________________________________________________^

error[E0432]: unresolved import `crate::platform::Device`
 --> /data/data/com.termux/files/home/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.7.5/src/types/battery.rs:5:5
  |
5 | use crate::platform::Device;
  |     ^^^^^^^^^^^^^^^^^^^^^^^ no `Device` in `platform`

error[E0432]: unresolved import `crate::platform::Iterator`
 --> /data/data/com.termux/files/home/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.7.5/src/types/iterator.rs:3:5
  |
3 | use crate::platform::Iterator as PlatformIterator;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `Iterator` in `platform`

error[E0432]: unresolved import `crate::platform::Iterator`
 --> /data/data/com.termux/files/home/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.7.5/src/types/manager.rs:5:5
  |
5 | use crate::platform::Iterator as PlatformIterator;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `Iterator` in `platform`

error[E0432]: unresolved import `crate::platform::Manager`
 --> /data/data/com.termux/files/home/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.7.5/src/types/manager.rs:6:5
  |
6 | use crate::platform::Manager as PlatformManager;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `Manager` in `platform`

error: aborting due to 5 previous errors

For more information about this error, try `rustc --explain E0432`.
error: could not compile `battery`.

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: failed to compile `starship v0.44.0`, intermediate artifacts can be found at `/data/data/com.termux/files/usr/tmp/cargo-install5qDCt5`

Caused by:
  build failed

Please tell me if I can help in any way (except from doing Rust).

PS: Maybe an Android Emulator or termux-docker can help.

Olimex: no battery found

When running battop v0.2.4 with battery v0.7.4 on ARM Linux A20-OLinuXino-LIME2 I get following error:

2023-02-19T14:43:20+01:00 - ERROR - Unable to find any batteries in system, exiting
Error: NoBatteries

but there is a battery:

$ ls /sys/class/power_supply/axp20x-battery/
capacity  constant_charge_current  constant_charge_current_max  current_now  device  health  online  power  present  status  subsystem  type  uevent  voltage_max_design  voltage_min_design  voltage_now  wakeup5
$ cat /sys/class/power_supply/axp20x-battery/status
Not charging
$ cat /sys/class/power_supply/axp20x-battery/health 
Good
$ cat /sys/class/power_supply/axp20x-battery/capacity
99
$ cat /sys/class/power_supply/axp20x-battery/online 
1
$ cat /sys/class/power_supply/axp20x-battery/present
1
$ cat /sys/class/power_supply/axp20x-battery/type
Battery

the strace (shortened):

openat(AT_FDCWD, "/sys/class/power_supply", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 3
fstat64(3, {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
getdents64(3, 0xa109cd8 /* 4 entries */, 32768) = 120
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-ac/type", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 4
statx(0, NULL, AT_STATX_SYNC_AS_STAT, STATX_ALL, NULL) = -1 EFAULT (Ungültige Adresse)
statx(4, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0444, stx_size=4096, ...}) = 0
read(4, "Mains\n", 4097)                = 6
read(4, "", 4091)                       = 0
close(4)                                = 0
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-battery/type", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 4
statx(4, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0444, stx_size=4096, ...}) = 0
read(4, "Battery\n", 4097)              = 8
read(4, "", 4089)                       = 0
close(4)                                = 0
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-battery/scope", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (Datei oder Verzeichnis nicht gefunden)
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-battery/manufacturer", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (Datei oder Verzeichnis nicht gefunden)
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-battery/model_name", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (Datei oder Verzeichnis nicht gefunden)
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-battery/serial_number", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (Datei oder Verzeichnis nicht gefunden)
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-battery/technology", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (Datei oder Verzeichnis nicht gefunden)
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-battery/capacity", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 4
statx(4, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_BASIC_STATS|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0444, stx_size=4096, ...}) = 0
read(4, "99\n", 4097)                  = 4
read(4, "", 4093)                       = 0
close(4)                                = 0
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-battery/energy_full", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (Datei oder Verzeichnis nicht gefunden)
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-battery/charge_full", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (Datei oder Verzeichnis nicht gefunden)
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-battery/energy_full_design", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (Datei oder Verzeichnis nicht gefunden)
openat(AT_FDCWD, "/sys/class/power_supply/axp20x-battery/charge_full_design", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (Datei oder Verzeichnis nicht gefunden)
getdents64(3, 0xa109cd8 /* 0 entries */, 32768) = 0
close(3)                                = 0
write(2, "\33[0m", 4)                   = 4
write(2, "\33[31m", 5)                  = 5
openat(AT_FDCWD, "/etc/localtime", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=2228, ...}) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=2228, ...}) = 0
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\7\0\0\0\7\0\0\0\0"..., 4096) = 2228
_llseek(3, -1410, [818], SEEK_CUR)      = 0
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\7\0\0\0\7\0\0\0\0"..., 4096) = 1410
close(3)                                = 0
write(2, "2023-02-19T14:56:03+01:00 - ERRO"..., 842023-02-19T14:56:03+01:00 - ERROR - Unable to find any batteries in system, exiting
) = 84
write(2, "\33[0m", 4)                   = 4
write(2, "Error: ", 7Error: )                  = 7
write(2, "NoBatteries", 11NoBatteries)             = 11
write(2, "\n", 1
)                       = 1

Batteries iterator order

Is the batteries iterator having a fixed order? From my tests it seem to ne be the case. acpi gives me:

Battery 0: Discharging, 15%, 00:28:40 remaining
Battery 1: Full, 100%

But the batteries iterator first give me Battery 1 then Battery 0. I didn't find anything about this in the documentation.

UTF error on NixOS

When running the example code from the readme on NixOS 20.09, I get the following output:
Error: Error { source: Custom { kind: InvalidData, error: "stream did not contain valid UTF-8" }, description: None }

I have seen the issue magically fix itself on reboot twice now, but cannot reproduce that behaviour -- it seems to happen for no reason at all. This is on a ThinkPad X1 Extreme Gen 2, I've also tested the example code on Arch Linux on the same computer and it seems to work perfectly. No idea how to troubleshoot this, I'm not particularly knowledgeable about rust (I ran into the issue because rust-battery is a dependency of dwm-status). NixOS has a pretty unique package manager that stores things at weird paths, so it might be related to that? Any help would be greatly appreciated.

Side note: I don't think this is related to #72 -- I tried using rust-battery as a local dependency after altering device.rs as described in the first post of that thread, but the error persisted.

Unable to access battery information

Operating system: Windows

I got Unable to access battery information Error: Error { source: Kind(InvalidData), description: Some("Device rate value is unknown") } error: process didn't exit successfully: target\debug\battery.exe (exit code: 1) When i ran this:

extern crate battery;

use std::io;
use std::thread;
use std::time::Duration;

fn main() -> battery::Result<()> {
    let manager = battery::Manager::new()?;
    let mut battery = match manager.batteries()?.next() {
        Some(Ok(battery)) => battery,
        Some(Err(e)) => {
            eprintln!("Unable to access battery information");
            return Err(e);
        }
        None => {
            eprintln!("Unable to find any batteries");
            return Err(io::Error::from(io::ErrorKind::NotFound).into());
        }
    };

    loop {
        println!("{:?}", battery);
        thread::sleep(Duration::from_secs(1));
        manager.refresh(&mut battery)?;
    }
}

/sys/class/power_supply/BAT0/model_name can contain non-utf8

On my system:

$ cat /sys/class/power_supply/BAT0/model_name
5�+1^^�^^�9(-:'&��

Or:

$ hexdump /sys/class/power_supply/BAT0/model_name
0000000 8035 312b 801e 801e 2839 3a2d 2627 8080
0000010 000a
0000011

This means trying to get battery info always returns an error due to https://github.com/svartalf/rust-battery/blob/master/battery/src/platform/linux/device.rs#L36

I'd suggest a change to:

let model = builder.model().unwrap_or(None);

I suspect it's a bug in the kernel that this file is basically filled with junk, but it would be nice if the crate didn't totally fail in this case.

Use MacOS bindings from Servo

Currently used CoreFoundation-sys and IOKit-sys crates for MacOS build looks abandoned.

  1. CoreFoundation-sys should be replaced with core-foundation crate by Servo team
  2. Manually implemented bindings and idiomatic wrappers should be made instead of IOKit-sys, similar to those in core-foundation-sys and core-foundation

Can't build by wasm-pack

I try building some wasm packages by wasm-pack to use on the web page. However, when I invoke "wasm-pack build" on the terminal, it throws the error: "no Device in platform", "no Iterator in platform". like the following image.

image

Handle missing energy_full_design value for Linux

According to starship/starship#613 (comment), there exist a possibility when both energy_full_design and charge_full_design files are missing for the battery device, so fetching fails with an error here:

Ok(None) => Err(Error::not_found("Unable to determine the `energy_full_design` value")),

upower just falls back to 0.0 value, but that might affect state_of_health

let energy_full_design = self.energy_full_design()?;

and energy parameters:

Ok(None) => Ok(*self.energy_full_design()?),

Requesting OpenBSD support

I attempted to build starship on OpenBSD, and it won't build because this project has not yet implemented support for OpenBSD. Any appetite or interest in adding support for OpenBSD? I'm not a rust developer so I can't make a PR, but I'd be happy to be a tester if it would be helpful.

Thanks for making a useful project for the ecosystem!

Could not compile `battery`

When i run cargo build --release I am getting this:

Compiling battery v0.6.0
   Compiling battery v0.6.0 (/home/dentrax/Projects/GitHub/rust-battery/battery)
   Compiling quote v0.6.11
   Compiling rand_chacha v0.1.1
   Compiling rand_pcg v0.1.2
   Compiling rand_os v0.1.2
   Compiling atty v0.2.11
   Compiling termion v1.5.1
error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
  --> /home/dentrax/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.6.0/src/lib.rs:34:9
   |
31 | mod types;
   | ---------- not an extern crate passed with `--extern`
...
34 | pub use types::{Manager, Batteries, Battery, State, Technology};
   |         ^^^^^
   |
   = help: add #![feature(uniform_paths)] to the crate attributes to enable
note: this import refers to the module defined here
  --> /home/dentrax/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.6.0/src/lib.rs:31:1
   |
31 | mod types;
   | ^^^^^^^^^^

error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
  --> battery/src/lib.rs:34:9
   |
31 | mod types;
   | ---------- not an extern crate passed with `--extern`
...
34 | pub use types::{Manager, Batteries, Battery, State, Technology};
   |         ^^^^^
   |
   = help: add #![feature(uniform_paths)] to the crate attributes to enable
note: this import refers to the module defined here
  --> battery/src/lib.rs:31:1
   |
31 | mod types;
   | ^^^^^^^^^^

   Compiling clap v2.32.0
error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.
error: Could not compile `battery`.
warning: build failed, waiting for other jobs to finish...
error: aborting due to previous error

For more information about this error, try `rustc --explain E0658`.
error: Could not compile `battery`.
warning: build failed, waiting for other jobs to finish...
error: build failed

OS: Arch Linux

Watch for updates

Hello everyone, nice project you created here!

Is it planned to provide a watcher-like functionality? For my package dwm-status I build a watcher based on dbus events, maybe you are interested in adding a similar API method.

Support UPSs handled by APC

As someone whose computer is connected via USB to an external power supply, I would love to be able to monitor its status from within battop. However it doesn't appear in the sysfs and as such is invisible to this library. Being able to support more types of batteries and power supplies should be a worthy goal for this type of library, but I don't know how much effort it would take to implement.

Separate the error types

This battop issue had introduced the case, when the Battery struct instance can represent the missing device. While it is possible now to handle that case (see #29), this kind of error seems to be a recoverable type of error for library users (mostly to the battop at the moment), because it can be handled (for example, by removing the device from the batteries list).

battery::Error can be reworked as an enum with the "recoverable" and "non-recoverable" members, smth like this:

enum Error {
    /// Battery device is missing now
    Gone(io::Error),
    /// Some error happened during the information fetch
    Other(io::Error),
}

Consider removing uom

First of all I just want to say I really appreciate this crate!

The issues I've had with uom regarding this crate are:

  1. It was difficult to understand how to work with the uom return type when first using this crate
  2. For some reason uom needs to recompile every time I compile my program which takes time and is annoying
  3. I don't really feel like uom provides any value as a return type. Personally, I would prefer just a simple f32/f64 or you could even alias it to a custom type.

Let me know what you think.

Termux support

error: Support for this target OS is not implemented yet!
 You may want to create an issue: https://github.com/svartalf/rust-battery/issues/new
  --> /home/builder/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.7.4/src/platform/mod.rs:27:9
   |
27 | /         compile_error!("Support for this target OS is not implemented yet!\n \
28 | |             You may want to create an issue: https://github.com/svartalf/rust-battery/issues/new");
   | |___________________________________________________________________________________________________^

error[E0432]: unresolved import `crate::platform::Device`
 --> /home/builder/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.7.4/src/types/battery.rs:5:5
  |
5 | use crate::platform::Device;
  |     ^^^^^^^^^^^^^^^^^^^^^^^ no `Device` in `platform`

error[E0432]: unresolved import `crate::platform::Iterator`
 --> /home/builder/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.7.4/src/types/iterator.rs:3:5
  |
3 | use crate::platform::Iterator as PlatformIterator;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `Iterator` in `platform`

error[E0432]: unresolved import `crate::platform::Iterator`
 --> /home/builder/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.7.4/src/types/manager.rs:5:5
  |
5 | use crate::platform::Iterator as PlatformIterator;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `Iterator` in `platform`

error[E0432]: unresolved import `crate::platform::Manager`
 --> /home/builder/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.7.4/src/types/manager.rs:6:5
  |
6 | use crate::platform::Manager as PlatformManager;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `Manager` in `platform`

Mac OS version doesn't work correctly

https://monosnap.com/file/wSyg3psLsM7m7EsdWBLYm2LcttjbIf
compiled just fine but data a lot of error data.

System Software Overview:
 System Version:	macOS 10.14.3 (18D39a)
  Kernel Version:	Darwin 18.2.0
  Boot Volume:	Macintosh HD
  Boot Mode:	Normal

Hardware Overview:
  Model Name:	MacBook Pro
  Model Identifier:	MacBookPro13,2
  Processor Name:	Intel Core i5
  Processor Speed:	2,9 GHz
  Number of Processors:	1
  Total Number of Cores:	2
  L2 Cache (per Core):	256 KB
  L3 Cache:	4 MB
  Memory:	16 GB

Battery Information:

  Model Information:
  Serial Number:	******
  Manufacturer:	SMP
  Device Name:	******
  Pack Lot Code:	0
  PCB Lot Code:	0
  Firmware Version:	901
  Hardware Revision:	1
  Cell Revision:	3922
  Charge Information:
  Charge Remaining (mAh):	4123
  Fully Charged:	Yes
  Charging:	No
  Full Charge Capacity (mAh):	4203
  Health Information:
  Cycle Count:	50
  Condition:	Normal
  Battery Installed:	Yes
  Amperage (mA):	-1037
  Voltage (mV):	12916

System Power Settings:
  AC Power:
  System Sleep Timer (Minutes):	1
  Disk Sleep Timer (Minutes):	10
  Display Sleep Timer (Minutes):	10
  Wake on AC Change:	No
  Wake on Clamshell Open:	Yes
  Wake on LAN:	Yes
  AutoPowerOff Delay:	28800
  AutoPowerOff Enabled:	1
  DarkWakeBackgroundTasks:	1
  Display Sleep Uses Dim:	Yes
  GPUSwitch:	2
  Hibernate Mode:	3
  High Standby Delay:	86400
  PrioritizeNetworkReachabilityOverSleep:	0
  ProximityDarkWake:	1
  Standby Battery Threshold:	50
  Standby Delay:	10800
  Standby Enabled:	1
  TCPKeepAlivePref:	1
  Battery Power:
  System Sleep Timer (Minutes):	1
  Disk Sleep Timer (Minutes):	10
  Display Sleep Timer (Minutes):	2
  Wake on AC Change:	No
  Wake on Clamshell Open:	Yes
  AutoPowerOff Delay:	28800
  AutoPowerOff Enabled:	1
  Current Power Source:	Yes
  DarkWakeBackgroundTasks:	0
  Display Sleep Uses Dim:	Yes
  GPUSwitch:	2
  Hibernate Mode:	3
  High Standby Delay:	86400
  ProximityDarkWake:	0
  Reduce Brightness:	Yes
  Standby Battery Threshold:	50
  Standby Delay:	10800
  Standby Enabled:	1
  TCPKeepAlivePref:	1

Hardware Configuration:
  UPS Installed:	No

AC Charger Information:
  Connected:	No
  Charging:	No

Linux implementation should ignore portable devices

Devices with scope != System should be ignored, since it is impossible to expect from drivers to provide the same amount of information as in case of system batteries.

scope attribute was introduced in this patch: http://lkml.iu.edu/hypermail/linux/kernel/1112.0/03454.html

Example of the battery report from the connected mice, reported by @o10g:

/sys/class/power_supply/hidpp_battery_0/capacity_level:Normal
/sys/class/power_supply/hidpp_battery_0/manufacturer:Logitech
/sys/class/power_supply/hidpp_battery_0/model_name:Marathon Mouse/Performance Plus M705
/sys/class/power_supply/hidpp_battery_0/online:1
/sys/class/power_supply/hidpp_battery_0/scope:Device
/sys/class/power_supply/hidpp_battery_0/serial_number:406d-25-5b-d8-be
/sys/class/power_supply/hidpp_battery_0/status:Discharging
/sys/class/power_supply/hidpp_battery_0/type:Battery
/sys/class/power_supply/hidpp_battery_0/uevent:POWER_SUPPLY_NAME=hidpp_battery_0
/sys/class/power_supply/hidpp_battery_0/uevent:POWER_SUPPLY_ONLINE=1
/sys/class/power_supply/hidpp_battery_0/uevent:POWER_SUPPLY_STATUS=Discharging
/sys/class/power_supply/hidpp_battery_0/uevent:POWER_SUPPLY_SCOPE=Device
/sys/class/power_supply/hidpp_battery_0/uevent:POWER_SUPPLY_MODEL_NAME=Marathon Mouse/Performance Plus M705
/sys/class/power_supply/hidpp_battery_0/uevent:POWER_SUPPLY_MANUFACTURER=Logitech
/sys/class/power_supply/hidpp_battery_0/uevent:POWER_SUPPLY_SERIAL_NUMBER=406d-25-5b-d8-be
/sys/class/power_supply/hidpp_battery_0/uevent:POWER_SUPPLY_CAPACITY_LEVEL=Normal

0.7.x does not build on FreeBSD

I'm new to rustlang, so maybe it's a problem on my side. What I am seeing is that all battery crates from 0.7.x on do not build on my FreeBSD 12 system:

NomadBSD:/home/lars/dev/rust/battery% cargo init
     Created binary (application) package
NomadBSD:/home/lars/dev/rust/battery% echo 'battery = "0.7.7"' >> Cargo.toml 
NomadBSD:/home/lars/dev/rust/battery% cargo run
    Updating crates.io index
   Compiling autocfg v1.0.1
   Compiling typenum v1.12.0
   Compiling libc v0.2.80
   Compiling battery v0.7.7
   Compiling cfg-if v1.0.0
   Compiling num-traits v0.2.14
   Compiling uom v0.30.0
error[E0463]: can't find crate for `nix`
  --> /home/lars/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.7.7/src/lib.rs:38:1
   |
38 | extern crate nix;
   | ^^^^^^^^^^^^^^^^^ can't find crate

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.
error: could not compile `battery`.

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: build failed

Building version 0.6.0 works:

NomadBSD:/home/lars/dev/rust/battery% perl -i -p -e 's/0\.6\.0/0.6.2/' Cargo.toml
NomadBSD:/home/lars/dev/rust/battery% cargo run                                  
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
     Running `target/debug/battery`
Hello, world!

WSL support.

rust-battery doesn't yet work in the Windows Subsystem for Linux (WSL). It isn't detecting any batteries.

Adaptive behavior for Linux

Current Linux implementation is probing multiple files in order to fetch one specific value; for example, in order to get the design voltage parameter, four files will be opened consequently: "voltage_max_design", "voltage_min_design", "voltage_present" and the "voltage_now".

Even while all files are located at the sysfs filesystem and read operations from it are very quick, for a worse case scenario there will be three unnecessary open syscalls (assuming the Manager::refresh method calls, as battop does).

Battery instance should remember which file was opened successfully during the previous information update and should open it directly on a next "refresh" call.
Yet, it is important to remember that some Linux drivers can remove or add these files on a fly, so, in case of failure, consequent probing should be started again.

In a result, it should reduce syscalls amount vastly.

failed to download `uom v0.26.0`

Operating system: Windows.
After adding

[dependencies]
battery = "0.7.5"

to my Cargo.toml and running cargo build, I get the below error:

error: failed to download uom v0.26.0

Caused by:
unable to get packages from source

Caused by:
failed to parse manifest at C:\Users\MIS\.cargo\registry\src\github.com-1ecc6299db9ec823\uom-0.26.0\Cargo.toml

Caused by:
could not parse input as TOML

Caused by:
unexpected character found: \u{0} at line 1 column 1

Battery State Unknown when battery is not charging but plugged into AC power.

Before I begin, I want to thank the maintainers of this crate, as it helped a lot in my Screen Brightness daemon, where I needed battery info.

On Linux laptops, software like TLP (https://linrunner.de/tlp/) can configure the battery to stop charging at a certain threshold while plugged in. I used TLP on my ArchLinux laptop and noticed that battery.state() will return "unknown" as a state when the battery is on AC power but was not charging.

I looked at my battery's status file and found that when the battery is on AC power but not charging, the status file will read "Not Charging."

I can work on a PR that adds support for the "Not charging" state. I would need to add a new value to the State enum and add formatting for the new state.

Energy rate miscalculation

Operating system: windows
First of all, Thanks for always being there svartalf. Please help me with this one too.

extern crate uom;
extern crate math;

use math::round::half_to_even;

fn main() -> Result<(), battery::Error> {
    let manager = battery::Manager::new()?;

    for (_idx, maybe_battery) in manager.batteries()?.enumerate() {
        let battery = maybe_battery?;
        println!("Percentage charge: {:?}%",(half_to_even(f64::from(f32::from(battery.state_of_charge()))*100.0,0) as i32));
        println!("Time to full: {:?}", battery.time_to_full());
        println!("Time to empty: {:?}", battery.time_to_empty());
        println!("Energy rate: {:?}", battery.energy_rate());
        println!("State: {:?}", battery.state());
        println!("");
    }

    Ok(())
}

I got

Percentage charge: 88%
Time to full: None
Time to empty: None
Energy rate: 0.0 m^2 kg^1 s^-3
State: Discharging

Infinite recursion possibility at Linux implementation

Reference:

fn energy_full_design(&self) -> Result<&Energy> {
// Based on the `upower` source it seems to impossible not to have any of needed files,
// so fallback to `0 mWh` was removed, error will be propagated instead.
self.energy_full_design.try_borrow_with(|| {
match fs::energy(self.root.join("energy_full_design")) {
Ok(Some(value)) => Ok(value),
Ok(None) => match fs::charge(self.root.join("charge_full_design")) {
Ok(Some(value)) => Ok(value * *self.design_voltage()?),
Ok(None) => Ok(*self.energy_full_design()?),

First of all, upower sources should be checked, since they were used as an knowledge source.
If nothing helpful can be borrowed from them, plain error should be returned there instead of calling the same one function.

Android support

I tried to add android support with same configuration as "target_os=linux", and it works.

Please add android support.

Populate battery data from uevent file

Power supply folder might contain an uevent file, which can be used to load battery data with a fewer syscalls amount.

  1. uevent file by itself should be considered as optional, implementation should not check if it is exists on each refresh (confirm than kernel will not create it suddenly at some random point of time)
  2. Consider that any expected value might be missing in this file
  3. Find format specification if any exists (Let's help Dora dig the linux sources)

Overflow panic when pretty printing Battery struct.

Setup:

fn main() {
    let batteries = battery::Manager::new().iter().collect::<Vec<_>>();
    println!("{:#?}", batteries);
}

Error 😨:

[
    Battery {
        vendor: Some(
            "SMP"
        ),
        model: Some(
            "bq20z451"
        ),
        serial_number: Some(
            "D866466Q2BPFWLKFQ"
        ),
        technology: Unknown,
        state: Full,
        capacity: 0.0,
        temperature: Some(
            30.11
thread 'main' panicked at 'attempt to multiply with overflow', /Users/a/.cargo/registry/src/github.com-1ecc6299db9ec823/battery-0.6.0/src/platform/macos/device.rs:128:10
note: Run with `RUST_BACKTRACE=1` for a backtrace.
        )

OS: macOS High Sierra 10.13.6 17G5019 x86_64
Host: MacBookPro11,4

Build error for target i686-pc-windows-msvc

Hello!

When I build for this target with GitHub action, I get this error:

error[E0793]: reference to packed field is unaligned
   --> C:\Users\runneradmin\.cargo\registry\src\index.crates.io-6f17d22bba15001f\battery-0.7.8\src\platform\windows\ffi\mod.rs:113:36
    |
113 |         let device_path = unsafe { (***pdidd).DevicePath.as_ptr() };
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

error[E0793]: reference to packed field is unaligned
   --> C:\Users\runneradmin\.cargo\registry\src\index.crates.io-6f17d22bba15001f\battery-0.7.8\src\platform\windows\ffi\mod.rs:143:17
    |
143 |                 &mut query.BatteryTag as *mut _ as minwindef::LPVOID,
    |                 ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
    = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.