Hello,
I think one of the latest commits introduced a regression in the temperature block, which is now returning an error on my system while unwrapping here: https://github.com/greshake/i3status-rust/blob/master/src/blocks/battery.rs#L364
Here is the output of running i3status-rs manually:
❯❯❯ i3status-rs ~/.config/i3/top.toml
{"version": 1, "click_events": true}
[[{"background":"#000000","color":"#dc322f","full_text":" Error in block 'temperature': sensors output is invalid ","separator":false,"separator_block_width":0}]
Error in block 'temperature': sensors output is invalid
thread 'battery' panicked at 'called `Result::unwrap()` on an `Err` value: "SendError(..)"', src/blocks/battery.rs:364:30
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
And here is my block config:
[[block]]
block = "temperature"
collapsed = false
interval = 10
good = 40
idle = 60
info = 80
warning = 90
chip = "*-isa-*"
format = "{average}°"
I am on Ubuntu bionic (18.04) and I have lm-sensors installed and working:
❯❯❯ sensors
coretemp-isa-0000
Adapter: ISA adapter
Package id 0: +44.0°C (high = +100.0°C, crit = +100.0°C)
Core 0: +43.0°C (high = +100.0°C, crit = +100.0°C)
Core 1: +44.0°C (high = +100.0°C, crit = +100.0°C)
Core 2: +43.0°C (high = +100.0°C, crit = +100.0°C)
Core 3: +44.0°C (high = +100.0°C, crit = +100.0°C)
Looks like it's just the temperature block taking down the bar than a bug in the battery block. Try switching around the order of the blocks in your config to see if that is true.
Can you show me the output of sensors --help?
I have moved the block around in multiple places and I am getting the same issue..
Here is the output of sensors --help:
❯❯❯ sensors --help
Usage: sensors [OPTION]... [CHIP]...
-c, --config-file Specify a config file
-h, --help Display this help text
-s, --set Execute `set' statements (root only)
-f, --fahrenheit Show temperatures in degrees fahrenheit
-A, --no-adapter Do not show adapter for each chip
--bus-list Generate bus statements for sensors.conf
-u Raw output
-v, --version Display the program version
Use `-' after `-c' to read the config file from stdin.
If no chips are specified, all chip info will be printed.
Example chip names:
lm78-i2c-0-2d *-i2c-0-2d
lm78-i2c-0-* *-i2c-0-*
lm78-i2c-*-2d *-i2c-*-2d
lm78-i2c-*-* *-i2c-*-*
lm78-isa-0290 *-isa-0290
lm78-isa-* *-isa-*
lm78-*
❯❯❯ sensors --version
sensors version 3.4.0 with libsensors version 3.4.0
Also, I made a typo in the title, let me fix it. There is nothing wrong with the battery block as you said, it is the temperature one.
Newer versions have the -j flag:
>sensors --help
Usage: sensors [OPTION]... [CHIP]...
-c, --config-file Specify a config file
-h, --help Display this help text
-s, --set Execute `set' statements (root only)
-f, --fahrenheit Show temperatures in degrees fahrenheit
-A, --no-adapter Do not show adapter for each chip
--bus-list Generate bus statements for sensors.conf
-u Raw output
-j Json output
-v, --version Display the program version
Use `-' after `-c' to read the config file from stdin.
If no chips are specified, all chip info will be printed.
Example chip names:
lm78-i2c-0-2d *-i2c-0-2d
lm78-i2c-0-* *-i2c-0-*
lm78-i2c-*-2d *-i2c-*-2d
lm78-i2c-*-* *-i2c-*-*
lm78-isa-0290 *-isa-0290
lm78-isa-* *-isa-*
lm78-*
>sensors --version
sensors version 3.6.0 with libsensors version 3.6.0
Unfortunately I am not able to update to lm-sensors 3.6 and libsensor5 as Bionic does not ship them and I cannot really go and upgrade to 20.04 now :(
And I have the same issue with the weather block.. curl is too old on Bionic as well.
Unfortunately there's nothing we can really do here apart from ask you to upgrade :(
It has been years since I've used Ubuntu but would Backports allow you to install the newer versions of curl and lm-sensors on 18.04? https://help.ubuntu.com/community/UbuntuBackports
(I'll close the issue but feel free to continue discussion)
I'll try to find some time and see if I can update libsensors through backports. I have searched a bit but I did not find the package, but it was not a deep search.
Thanks for the help understanding why this is happening.
Just FYI, I can't find backported package and I believe the problem comes from the fact the lm-sensors 3.6 wants a new version of libc6, not available in Bionic.
If anyone else have the same issue and cannot upgrade lm-sensors accordingly, here is a poor's man custom implementation:
[[block]]
block = "custom"
cycle = ["sensors |grep Package |awk '{print $4}' |sed 's#+##g' |sed 's#C##g'"]
interval = 10
It's ugly, but it does the job :)
ugh, i'm also affected by this. it's not _too_ painful to revert 2f223d734, here's the approximate diff you want:
click to expand
diff --git a/src/blocks/temperature.rs b/src/blocks/temperature.rs
index c7f9eef39..892366b3b 100644
--- a/src/blocks/temperature.rs
+++ b/src/blocks/temperature.rs
@@ -1,4 +1,4 @@
-use std::collections::{BTreeMap, HashMap};
+use std::collections::BTreeMap;
use std::process::Command;
use std::time::Duration;
@@ -41,7 +41,6 @@ pub struct Temperature {
maximum_warning: i64,
format: FormatTemplate,
chip: Option<String>,
- inputs: Option<Vec<String>>,
}
#[derive(Deserialize, Debug, Default, Clone)]
@@ -169,17 +168,13 @@ impl ConfigBlock for Temperature {
format: FormatTemplate::from_string(&block_config.format)
.block_error("temperature", "Invalid format specified for temperature")?,
chip: block_config.chip,
- inputs: block_config.inputs,
})
}
}
-type SensorsOutput = HashMap<String, HashMap<String, serde_json::Value>>;
-type InputReadings = HashMap<String, f64>;
-
impl Block for Temperature {
fn update(&mut self) -> Result<Option<Update>> {
- let mut args = vec!["-j"];
+ let mut args = vec!["-u"];
if let TemperatureScale::Fahrenheit = self.scale {
args.push("-f");
}
@@ -192,34 +187,33 @@ impl Block for Temperature {
.map(|o| String::from_utf8_lossy(&o.stdout).trim().to_owned())
.unwrap_or_else(|e| e.to_string());
- let parsed: SensorsOutput = serde_json::from_str(&output)
- .block_error("temperature", "sensors output is invalid")?;
-
let mut temperatures: Vec<i64> = Vec::new();
- for (_chip, inputs) in parsed {
- for (input_name, input_values) in inputs {
- if let Some(ref whitelist) = self.inputs {
- if !whitelist.contains(&input_name) {
- continue;
- }
- }
- let values_parsed: InputReadings = match serde_json::from_value(input_values) {
- Ok(values) => values,
- Err(_) => continue, // probably the "Adapter" key, just ignore.
- };
+ for line in output.lines() {
+ if line.starts_with(" temp") {
+ let rest = &line[6..]
+ .split('_')
+ .flat_map(|x| x.split(' '))
+ .flat_map(|x| x.split('.'))
+ .collect::<Vec<_>>();
- for (value_name, value) in values_parsed {
- if !value_name.starts_with("temp") || !value_name.ends_with("input") {
- continue;
- }
-
- if value > -101f64 && value < 151f64 {
- temperatures.push(value as i64);
- } else {
- // This error is recoverable and therefore should not stop the program
- eprintln!("Temperature ({}) outside of range ([-100, 150])", value);
- }
+ if rest[1].starts_with("input") {
+ match rest[2].parse::<i64>() {
+ Ok(t) if t == 0 => Ok(()),
+ Ok(t) if t > -101 && t < 151 => {
+ temperatures.push(t);
+ Ok(())
+ }
+ Ok(t) => {
+ // This error is recoverable and therefore should not stop the program
+ eprintln!("Temperature ({}) outside of range ([-100, 150])", t);
+ Ok(())
+ }
+ Err(_) => Err(BlockError(
+ "temperature".to_owned(),
+ "failed to parse temperature as an integer".to_owned(),
+ )),
+ }?
}
}
}
Hmm on second look we can do better here. First check whether the system's sensors command has the json flag, and if not fall back to the old method. The only caveat is that the "inputs" config option will have no effect since implementing that doesn't look trivial.
Most helpful comment
If anyone else have the same issue and cannot upgrade lm-sensors accordingly, here is a poor's man custom implementation:
It's ugly, but it does the job :)