1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::fs::File;
use std::io::Read;

// TODO: Implement API to allow callbacks backed via uevent / inotify

fn read_attribute(attr: &str) -> Result<String, String> {
    let mut data = String::new();
    match File::open(format!("/sys/class/power_supply/bq27441/{0}", attr)) {
        Err(e) => Err(format!("Unable to open file: {0}", e)),
        Ok(ref mut f) => match f.read_to_string(&mut data).unwrap_or(0) {
            0 => Err("Unable to read file".to_owned()),
            _ => Ok(data.trim().to_owned()),
        },
    }
}

/// $ cat /sys/class/power_supply/bq27441/capacity
/// 97
pub fn percentage() -> Result<i32, String> {
    let curr = read_attribute("capacity")?;
    match curr.parse::<i32>() {
        Ok(r) => Ok(r),
        Err(_) => {
            Err("Unable to parse the contents of 'capacity' during a battery query".to_owned())
        }
    }
}

/// $ cat /sys/class/power_supply/bq27441/capacity_level
/// Normal
pub fn human_readable_capacity_level() -> Result<String, String> {
    Ok(read_attribute("capacity_level")?)
}

/// $ cat /sys/class/power_supply/bq27441/charge_full
/// 1635000
pub fn charge_full() -> Result<i32, String> {
    let curr = read_attribute("charge_full")?;
    match curr.parse::<i32>() {
        Ok(r) => Ok(r),
        Err(_) => {
            Err("Unable to parse the contents of 'charge_full' during a battery query".to_owned())
        }
    }
}

/// $ cat /sys/class/power_supply/bq27441/charge_full_design
/// 1340000
pub fn charge_full_design() -> Result<i32, String> {
    let curr = read_attribute("charge_full_design")?;
    match curr.parse::<i32>() {
        Ok(r) => Ok(r),
        Err(_) => Err(
            "Unable to parse the contents of 'charge_full_design' during a battery query"
                .to_owned(),
        ),
    }
}

/// $ cat /sys/class/power_supply/bq27441/charge_now
/// 1528000
pub fn charge() -> Result<i32, String> {
    let curr = read_attribute("charge_now")?;
    match curr.parse::<i32>() {
        Ok(r) => Ok(r),
        Err(_) => {
            Err("Unable to parse the contents of 'charge_now' during a battery query".to_owned())
        }
    }
}

/// $ cat /sys/class/power_supply/bq27441/status
/// Discharging
pub fn human_readable_charging_status() -> Result<String, String> {
    Ok(read_attribute("status")?)
}

/// $ cat /sys/class/power_supply/bq27441/temp
/// 201
pub fn temperature() -> Result<i32, String> {
    let curr = read_attribute("temp")?;
    match curr.parse::<i32>() {
        Ok(r) => Ok(r),
        Err(_) => {
            Err("Unable to parse the contents of 'current_now' during a battery query".to_owned())
        }
    }
}

/// $ cat /sys/class/power_supply/bq27441/voltage_now
/// 4164000
pub fn voltage() -> Result<i32, String> {
    let curr = read_attribute("voltage_now")?;
    match curr.parse::<i32>() {
        Ok(r) => Ok(r),
        Err(_) => {
            Err("Unable to parse the contents of 'voltage_now' during a battery query".to_owned())
        }
    }
}

/// $ cat /sys/class/power_supply/bq27441/current_now
/// -132000
pub fn current() -> Result<i32, String> {
    let curr = read_attribute("current_now")?;
    match curr.parse::<i32>() {
        Ok(r) => Ok(r),
        Err(_) => {
            Err("Unable to parse the contents of 'current_now' during a battery query".to_owned())
        }
    }
}