Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into maxleiko-pedantic
Browse files Browse the repository at this point in the history
* origin/master:
  add path for aarch64 faketime on debian
  add --locked to stop CI from breaking unexpectedly
  justfile: update repositories before installing dependencies
  battery: fix bug when autodetecting batteries
  rename sensors item "label" to "component" to add a label option
  remove unneeded dbg!
  update justfile for fedora distributions
  battery: fallback to capacity if charge_* missing
  • Loading branch information
acheronfail committed Apr 16, 2024
2 parents b4614b0 + 4d840d3 commit 8154154
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 30 deletions.
6 changes: 3 additions & 3 deletions bin/sensors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ use sysinfo::{ComponentExt, RefreshKind, System, SystemExt};
///
/// Each line contains a sensor and its temperature, in the following format:
///
/// TEMP:LABEL
/// TEMP:COMPONENT
///
/// Where TEMP is the temperature in Celsius, and LABEL is the name of the sensor.
/// The LABEL property can by used to configure bar items with type "sensors".
/// Where TEMP is the temperature in Celsius, and COMPONENT is the name of the sensor.
/// The COMPONENT property can by used to configure bar items with type "sensors".
struct Cli;

fn main() {
Expand Down
18 changes: 12 additions & 6 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@ _default:
setup:
cd ./scripts/node && yarn

if ! command -v cargo-lbuild >/dev/null 2>&1 /dev/null; then cargo install cargo-limit; fi
if ! command -v cargo-lbuild >/dev/null 2>&1 /dev/null; then cargo install --locked cargo-limit; fi

if command -v pacman >/dev/null 2>&1 /dev/null; then sudo pacman -S --needed \
if command -v pacman >/dev/null 2>&1 /dev/null; then sudo pacman -Sy --needed \
clang dbus dunst libfaketime libpulse i3-wm imagemagick scrot xorg-server-xephyr xorg-server-xvfb yarn; \
fi

if command -v apt-get >/dev/null 2>&1 /dev/null; then sudo apt-get install -y \
if command -v apt-get >/dev/null 2>&1 /dev/null; then sudo apt-get update && sudo apt-get install -y \
build-essential clang dbus dunst i3-wm imagemagick libfaketime libiw-dev libpulse-dev libx11-dev scrot xserver-xephyr xvfb; \
fi

if command -v dnf >/dev/null 2>&1 /dev/null; then sudo dnf install -y \
clang dbus dunst libfaketime i3 ImageMagick iw scrot xorg-x11-server-Xephyr xorg-x11-server-Xvfb libX11-devel yarnpkg; \
fi

cd ./scripts/node && yarn

@check +CMDS:
echo {{CMDS}} | xargs -n1 sh -c 'if ! command -v $1 >/dev/null 2>&1 /dev/null; then echo "$1 is required!"; exit 1; fi' bash

Expand Down Expand Up @@ -51,9 +57,9 @@ install *args:

# start a nested X server with i3 and i3stat
debug dimensions="3800x200": _lbuild
Xephyr -ac -br -reset -terminate -screen {{dimensions}} :1 &
until [ -e /tmp/.X11-unix/X1 ]; do sleep 0.1; done
env -u I3SOCK DISPLAY=:1.0 i3-with-shmlog --config ./scripts/i3.conf
Xephyr -ac -br -reset -terminate -screen {{dimensions}} :42 &
until [ -e /tmp/.X11-unix/X42 ]; do sleep 0.1; done
env -u I3SOCK DISPLAY=:42.0 i3-with-shmlog --config ./scripts/i3.conf

# run tests in a nested dbus session so the host session isn't affected
alias t := test
Expand Down
4 changes: 3 additions & 1 deletion sample_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ name = "cpu-temp"
interval = "5s"
# The name of the component to display temperature for.
# The `i3stat-sensors` command is provided and outputs a list of components that can be used.
label = "coretemp Package id 0"
component = "coretemp Package id 0"
# Optional: set a label to be shown in the item (useful if you have multiple sensor items)
label = " (cpu)"
# See: FLOAT FORMAT OPTIONS
pad = ' '
pad_count = 2
Expand Down
54 changes: 39 additions & 15 deletions src/bar_items/battery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,35 +63,48 @@ struct BatInfo {
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(transparent)]
struct Bat {
file: PathBuf,
/// Battery directory in procfs.
dir: PathBuf,

/// Whether `/charge_{now,full}` is used or `/capacity` to check battery levels.
#[serde(skip)]
uses_charge: OnceCell<bool>,

/// Name of the battery.
#[serde(skip)]
cached_name: OnceCell<String>,
}

impl Bat {
pub fn new(file: PathBuf) -> Bat {
pub fn new(dir: PathBuf) -> Bat {
Bat {
file,
dir,
uses_charge: OnceCell::new(),
cached_name: OnceCell::new(),
}
}

fn name(&self) -> Result<&String> {
match self.cached_name.get() {
Some(cached) => Ok(cached),
None => match self.file.file_name() {
None => match self.dir.file_name() {
Some(name) => match self.cached_name.set(name.to_string_lossy().into_owned()) {
Ok(()) => self.name(),
Err(_) => bail!("failed to set name cache"),
},
None => bail!("failed to parse file name from: {}", self.file.display()),
None => bail!("failed to parse file name from: {}", self.dir.display()),
},
}
}

fn uses_charge(&self) -> bool {
*self.uses_charge.get_or_init(|| {
self.dir.join("charge_now").exists() && self.dir.join("charge_full").exists()
})
}

async fn read(&self, file_name: impl AsRef<str>) -> Result<String> {
Ok(read_to_string(self.file.join(file_name.as_ref())).await?)
Ok(read_to_string(self.dir.join(file_name.as_ref())).await?)
}

async fn read_usize(&self, file_name: impl AsRef<str>) -> Result<usize> {
Expand All @@ -102,13 +115,17 @@ impl Bat {
Ok(BatState::from_str(self.read("status").await?.trim())?)
}

// NOTE: there is also `/capacity` which returns an integer percentage
pub async fn percent(&self) -> Result<f32> {
let (charge_now, charge_full) = try_join!(
self.read_usize("charge_now"),
self.read_usize("charge_full"),
)?;
Ok((charge_now as f32) / (charge_full as f32) * 100.0)
match self.uses_charge() {
false => Ok(self.read_usize("capacity").await? as f32),
true => {
let (charge_now, charge_full) = try_join!(
self.read_usize("charge_now"),
self.read_usize("charge_full"),
)?;
Ok((charge_now as f32) / (charge_full as f32) * 100.0)
}
}
}

pub async fn watts_now(&self) -> Result<f64> {
Expand Down Expand Up @@ -136,8 +153,15 @@ impl Bat {
while let Some(entry) = entries.next_entry().await? {
if entry.file_type().await?.is_symlink() {
let file = entry.path();
if fs::try_exists(file.join("charge_now")).await? {
batteries.push(Bat::new(file));
let b = fs::try_exists(file.join("capacity")).await;
let a = fs::try_exists(file.join("charge_now")).await;

match (a, b) {
(Ok(true), _) | (_, Ok(true)) => {
log::debug!("autodetected battery: {}", &file.display());
batteries.push(Bat::new(file));
}
_ => {}
}
}
}
Expand Down Expand Up @@ -332,7 +356,7 @@ mod tests {
fn de() {
let path = "/sys/class/power_supply/BAT0";
let battery = serde_json::from_str::<Bat>(&format!(r#""{}""#, path)).unwrap();
assert_eq!(battery.file, PathBuf::from(path));
assert_eq!(battery.dir, PathBuf::from(path));
}

#[test]
Expand Down
13 changes: 9 additions & 4 deletions src/bar_items/sensors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ use crate::util::format::{float, FloatFormat};
pub struct Sensors {
#[serde(with = "crate::human_time")]
interval: Duration,
label: String,
#[serde(default)]
label: Option<String>,
component: String,
#[serde(flatten)]
float_fmt: FloatFormat,
}
Expand All @@ -40,10 +42,11 @@ impl BarItem for Sensors {
ctx.state.sys.refresh_components_list();
}

let label = self.label.as_deref().unwrap_or("");
loop {
let temp = {
let search = ctx.state.sys.components_mut().iter_mut().find_map(|c| {
if c.label() == self.label {
if c.label() == self.component {
c.refresh();
Some(c.temperature())
} else {
Expand All @@ -54,14 +57,16 @@ impl BarItem for Sensors {
match search {
Some(temp) => temp,
None => {
break Err(format!("no component found with label: {}", self.label).into())
break Err(
format!("no component found with name: {}", self.component).into()
)
}
}
};

let (icon, color) = Self::get_icon(&ctx.config.theme, temp as u32);
let temp = float(temp, &self.float_fmt);
let mut item = I3Item::new(format!("{} {}°C", icon, temp))
let mut item = I3Item::new(format!("{} {}°C{}", icon, temp, label))
.short_text(format!("{}C", temp))
.markup(I3Markup::Pango);

Expand Down
2 changes: 1 addition & 1 deletion tests/i3/screenshots.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ screenshot!(
json!({
"type": "sensors",
"interval": "1s",
"label": "name temp1"
"component": "name temp1"
}),
{
at_0: {
Expand Down
3 changes: 3 additions & 0 deletions tests/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ pub const FAKE_TIME: &str = "1985-10-26 01:35:00";
const FAKE_TIME_LIB_PATHS: &[&str] = &[
// Arch Linux
"/usr/lib/faketime/libfaketime.so.1",
// Fedora
"/usr/lib64/faketime/libfaketime.so.1",
// Debian/Ubuntu (used in CI)
"/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1",
"/usr/lib/aarch64-linux-gnu/faketime/libfaketime.so.1",
];

pub fn get_faketime_lib() -> &'static str {
Expand Down

0 comments on commit 8154154

Please sign in to comment.