UpsHatE

Struct UpsHatE 

Source
pub struct UpsHatE { /* private fields */ }
Expand description

Monitor a Waveshare UPS HAT E (Uninterruptible Power Supply model E) for a Raspberry Pi.

This struct can monitor the UPS HAT status, such as battery voltage, current, power, and other interesting information

Implementations§

Source§

impl UpsHatE

Source

pub fn new() -> Self

Create a new instance of the UPS Hat E monitor using the default I2C bus device path and address. This works in most cases.

Examples found in repository?
examples/force_power_off.rs (line 39)
24fn main() {
25    let args = env::args().collect::<Vec<_>>();
26
27    if args.len() == 2 && args[1].to_ascii_lowercase() != "-y" {
28        println!("Usage: force_power_off [-y]");
29        println!("  -y: skip confirmation prompt");
30        println!();
31        exit(1);
32    };
33
34    if !confirm_power_off(&args) {
35        println!("Aborting power-off due to user input. Use -y to skip confirmation prompt.");
36        exit(1);
37    }
38
39    let mut ups = UpsHatE::new();
40
41    ups.force_power_off().expect("failed to issue power-off command");
42
43    let pending = ups.is_power_off_pending().expect("failed reading power-off status");
44
45    if pending {
46        println!("UPS will power-off the attached Raspberry Pi in 30 seconds");
47        exit(0);
48    } else {
49        println!("Error: UPS failed to initiate power-off");
50        exit(2);
51    }
52}
More examples
Hide additional examples
examples/ups_monitor.rs (line 17)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    let mut ups = UpsHatE::new();
18    let mut stdout = io::stdout();
19
20    let software_revision = ups.get_software_revision()?;
21
22    loop {
23        let battery = ups.get_battery_state()?;
24        let power = ups.get_power_state()?;
25        let comm = ups.get_communication_state()?;
26        let vbus = ups.get_usbc_vbus()?;
27        let cells = ups.get_cell_voltage()?;
28        let battery_low = ups.is_battery_low()?;
29        let power_off_pending = ups.is_power_off_pending()?;
30
31        print!("{CLEAR_SCREEN}{CURSOR_HOME}");
32
33        let epoch_secs = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
34
35        println!("{BOLD}UPS HAT (E) Monitor{RESET}");
36        println!("═══════════════════════════════════════════");
37        println!("Unix time: {epoch_secs}");
38        println!();
39
40        println!("{BOLD}UPS Info{RESET}");
41        println!("  Software Rev:  {:?}", software_revision);
42        println!();
43
44        // Power state
45        println!("{BOLD}Power{RESET}");
46        println!("  State:         {:?}", power.charging_state);
47        println!("  Activity:      {:?}", power.charger_activity);
48        println!("  USB-C In:      {:?}", power.usbc_input_state);
49        println!("  USB-C PD:      {:?}", power.usbc_power_delivery);
50        println!("  Off Pending?   {}", if power_off_pending { "Yes" } else { "No" });
51        println!();
52
53        // Communication state
54        println!("{BOLD}Communication{RESET}");
55        println!("  BQ4050:        {:?}", comm.bq4050);
56        println!("  IP2368:        {:?}", comm.ip2368);
57        println!();
58
59        // Battery
60        println!("{BOLD}Battery{RESET}");
61        println!("  Charge:        {}%", battery.remaining_percent);
62        println!("  Voltage:       {} mV", battery.millivolts);
63        println!("  Current:       {} mA", battery.milliamps);
64        println!("  Est. Capacity: {} mAh", battery.remaining_capacity_milliamphours);
65        if battery.milliamps < 0 {
66            println!("  Est. Runtime:  {} min", battery.remaining_runtime_minutes);
67        } else if battery.time_to_full_minutes > 0 {
68            println!("  Time To Full:  {} min", battery.time_to_full_minutes);
69        }
70        println!("  Low Battery?   {}", if battery_low { "Yes" } else { "No" });
71        println!();
72
73        // USB-C VBUS
74        println!("{BOLD}USB-C VBUS{RESET}");
75        println!("  Voltage:      {} mV", vbus.millivolts);
76        println!("  Current:      {} mA", vbus.milliamps);
77        println!("  Power:        {} mW", vbus.milliwatts);
78        println!();
79
80        // Cell voltages
81        println!("{BOLD}Cell Voltages{RESET}");
82        println!("  Cell 1:       {} mV", cells.cell_1_millivolts);
83        println!("  Cell 2:       {} mV", cells.cell_2_millivolts);
84        println!("  Cell 3:       {} mV", cells.cell_3_millivolts);
85        println!("  Cell 4:       {} mV", cells.cell_4_millivolts);
86        println!();
87
88        println!("Press Ctrl+C to exit");
89
90        stdout.flush()?;
91        thread::sleep(Duration::from_secs(2));
92    }
93}
Source

pub fn from_i2c_device(i2c_bus: LinuxI2CDevice) -> Self

Expert option: create a new instance of the UPS Hat E monitor using a custom I2C bus device (custom path and address).

Source

pub fn get_cell_voltage(&mut self) -> Result<CellVoltage, Error>

Examples found in repository?
examples/ups_monitor.rs (line 27)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    let mut ups = UpsHatE::new();
18    let mut stdout = io::stdout();
19
20    let software_revision = ups.get_software_revision()?;
21
22    loop {
23        let battery = ups.get_battery_state()?;
24        let power = ups.get_power_state()?;
25        let comm = ups.get_communication_state()?;
26        let vbus = ups.get_usbc_vbus()?;
27        let cells = ups.get_cell_voltage()?;
28        let battery_low = ups.is_battery_low()?;
29        let power_off_pending = ups.is_power_off_pending()?;
30
31        print!("{CLEAR_SCREEN}{CURSOR_HOME}");
32
33        let epoch_secs = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
34
35        println!("{BOLD}UPS HAT (E) Monitor{RESET}");
36        println!("═══════════════════════════════════════════");
37        println!("Unix time: {epoch_secs}");
38        println!();
39
40        println!("{BOLD}UPS Info{RESET}");
41        println!("  Software Rev:  {:?}", software_revision);
42        println!();
43
44        // Power state
45        println!("{BOLD}Power{RESET}");
46        println!("  State:         {:?}", power.charging_state);
47        println!("  Activity:      {:?}", power.charger_activity);
48        println!("  USB-C In:      {:?}", power.usbc_input_state);
49        println!("  USB-C PD:      {:?}", power.usbc_power_delivery);
50        println!("  Off Pending?   {}", if power_off_pending { "Yes" } else { "No" });
51        println!();
52
53        // Communication state
54        println!("{BOLD}Communication{RESET}");
55        println!("  BQ4050:        {:?}", comm.bq4050);
56        println!("  IP2368:        {:?}", comm.ip2368);
57        println!();
58
59        // Battery
60        println!("{BOLD}Battery{RESET}");
61        println!("  Charge:        {}%", battery.remaining_percent);
62        println!("  Voltage:       {} mV", battery.millivolts);
63        println!("  Current:       {} mA", battery.milliamps);
64        println!("  Est. Capacity: {} mAh", battery.remaining_capacity_milliamphours);
65        if battery.milliamps < 0 {
66            println!("  Est. Runtime:  {} min", battery.remaining_runtime_minutes);
67        } else if battery.time_to_full_minutes > 0 {
68            println!("  Time To Full:  {} min", battery.time_to_full_minutes);
69        }
70        println!("  Low Battery?   {}", if battery_low { "Yes" } else { "No" });
71        println!();
72
73        // USB-C VBUS
74        println!("{BOLD}USB-C VBUS{RESET}");
75        println!("  Voltage:      {} mV", vbus.millivolts);
76        println!("  Current:      {} mA", vbus.milliamps);
77        println!("  Power:        {} mW", vbus.milliwatts);
78        println!();
79
80        // Cell voltages
81        println!("{BOLD}Cell Voltages{RESET}");
82        println!("  Cell 1:       {} mV", cells.cell_1_millivolts);
83        println!("  Cell 2:       {} mV", cells.cell_2_millivolts);
84        println!("  Cell 3:       {} mV", cells.cell_3_millivolts);
85        println!("  Cell 4:       {} mV", cells.cell_4_millivolts);
86        println!();
87
88        println!("Press Ctrl+C to exit");
89
90        stdout.flush()?;
91        thread::sleep(Duration::from_secs(2));
92    }
93}
Source

pub fn get_usbc_vbus(&mut self) -> Result<UsbCVBus, Error>

Examples found in repository?
examples/ups_monitor.rs (line 26)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    let mut ups = UpsHatE::new();
18    let mut stdout = io::stdout();
19
20    let software_revision = ups.get_software_revision()?;
21
22    loop {
23        let battery = ups.get_battery_state()?;
24        let power = ups.get_power_state()?;
25        let comm = ups.get_communication_state()?;
26        let vbus = ups.get_usbc_vbus()?;
27        let cells = ups.get_cell_voltage()?;
28        let battery_low = ups.is_battery_low()?;
29        let power_off_pending = ups.is_power_off_pending()?;
30
31        print!("{CLEAR_SCREEN}{CURSOR_HOME}");
32
33        let epoch_secs = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
34
35        println!("{BOLD}UPS HAT (E) Monitor{RESET}");
36        println!("═══════════════════════════════════════════");
37        println!("Unix time: {epoch_secs}");
38        println!();
39
40        println!("{BOLD}UPS Info{RESET}");
41        println!("  Software Rev:  {:?}", software_revision);
42        println!();
43
44        // Power state
45        println!("{BOLD}Power{RESET}");
46        println!("  State:         {:?}", power.charging_state);
47        println!("  Activity:      {:?}", power.charger_activity);
48        println!("  USB-C In:      {:?}", power.usbc_input_state);
49        println!("  USB-C PD:      {:?}", power.usbc_power_delivery);
50        println!("  Off Pending?   {}", if power_off_pending { "Yes" } else { "No" });
51        println!();
52
53        // Communication state
54        println!("{BOLD}Communication{RESET}");
55        println!("  BQ4050:        {:?}", comm.bq4050);
56        println!("  IP2368:        {:?}", comm.ip2368);
57        println!();
58
59        // Battery
60        println!("{BOLD}Battery{RESET}");
61        println!("  Charge:        {}%", battery.remaining_percent);
62        println!("  Voltage:       {} mV", battery.millivolts);
63        println!("  Current:       {} mA", battery.milliamps);
64        println!("  Est. Capacity: {} mAh", battery.remaining_capacity_milliamphours);
65        if battery.milliamps < 0 {
66            println!("  Est. Runtime:  {} min", battery.remaining_runtime_minutes);
67        } else if battery.time_to_full_minutes > 0 {
68            println!("  Time To Full:  {} min", battery.time_to_full_minutes);
69        }
70        println!("  Low Battery?   {}", if battery_low { "Yes" } else { "No" });
71        println!();
72
73        // USB-C VBUS
74        println!("{BOLD}USB-C VBUS{RESET}");
75        println!("  Voltage:      {} mV", vbus.millivolts);
76        println!("  Current:      {} mA", vbus.milliamps);
77        println!("  Power:        {} mW", vbus.milliwatts);
78        println!();
79
80        // Cell voltages
81        println!("{BOLD}Cell Voltages{RESET}");
82        println!("  Cell 1:       {} mV", cells.cell_1_millivolts);
83        println!("  Cell 2:       {} mV", cells.cell_2_millivolts);
84        println!("  Cell 3:       {} mV", cells.cell_3_millivolts);
85        println!("  Cell 4:       {} mV", cells.cell_4_millivolts);
86        println!();
87
88        println!("Press Ctrl+C to exit");
89
90        stdout.flush()?;
91        thread::sleep(Duration::from_secs(2));
92    }
93}
Source

pub fn get_battery_state(&mut self) -> Result<BatteryState, Error>

Examples found in repository?
examples/ups_monitor.rs (line 23)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    let mut ups = UpsHatE::new();
18    let mut stdout = io::stdout();
19
20    let software_revision = ups.get_software_revision()?;
21
22    loop {
23        let battery = ups.get_battery_state()?;
24        let power = ups.get_power_state()?;
25        let comm = ups.get_communication_state()?;
26        let vbus = ups.get_usbc_vbus()?;
27        let cells = ups.get_cell_voltage()?;
28        let battery_low = ups.is_battery_low()?;
29        let power_off_pending = ups.is_power_off_pending()?;
30
31        print!("{CLEAR_SCREEN}{CURSOR_HOME}");
32
33        let epoch_secs = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
34
35        println!("{BOLD}UPS HAT (E) Monitor{RESET}");
36        println!("═══════════════════════════════════════════");
37        println!("Unix time: {epoch_secs}");
38        println!();
39
40        println!("{BOLD}UPS Info{RESET}");
41        println!("  Software Rev:  {:?}", software_revision);
42        println!();
43
44        // Power state
45        println!("{BOLD}Power{RESET}");
46        println!("  State:         {:?}", power.charging_state);
47        println!("  Activity:      {:?}", power.charger_activity);
48        println!("  USB-C In:      {:?}", power.usbc_input_state);
49        println!("  USB-C PD:      {:?}", power.usbc_power_delivery);
50        println!("  Off Pending?   {}", if power_off_pending { "Yes" } else { "No" });
51        println!();
52
53        // Communication state
54        println!("{BOLD}Communication{RESET}");
55        println!("  BQ4050:        {:?}", comm.bq4050);
56        println!("  IP2368:        {:?}", comm.ip2368);
57        println!();
58
59        // Battery
60        println!("{BOLD}Battery{RESET}");
61        println!("  Charge:        {}%", battery.remaining_percent);
62        println!("  Voltage:       {} mV", battery.millivolts);
63        println!("  Current:       {} mA", battery.milliamps);
64        println!("  Est. Capacity: {} mAh", battery.remaining_capacity_milliamphours);
65        if battery.milliamps < 0 {
66            println!("  Est. Runtime:  {} min", battery.remaining_runtime_minutes);
67        } else if battery.time_to_full_minutes > 0 {
68            println!("  Time To Full:  {} min", battery.time_to_full_minutes);
69        }
70        println!("  Low Battery?   {}", if battery_low { "Yes" } else { "No" });
71        println!();
72
73        // USB-C VBUS
74        println!("{BOLD}USB-C VBUS{RESET}");
75        println!("  Voltage:      {} mV", vbus.millivolts);
76        println!("  Current:      {} mA", vbus.milliamps);
77        println!("  Power:        {} mW", vbus.milliwatts);
78        println!();
79
80        // Cell voltages
81        println!("{BOLD}Cell Voltages{RESET}");
82        println!("  Cell 1:       {} mV", cells.cell_1_millivolts);
83        println!("  Cell 2:       {} mV", cells.cell_2_millivolts);
84        println!("  Cell 3:       {} mV", cells.cell_3_millivolts);
85        println!("  Cell 4:       {} mV", cells.cell_4_millivolts);
86        println!();
87
88        println!("Press Ctrl+C to exit");
89
90        stdout.flush()?;
91        thread::sleep(Duration::from_secs(2));
92    }
93}
Source

pub fn get_power_state(&mut self) -> Result<PowerState, Error>

Examples found in repository?
examples/ups_monitor.rs (line 24)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    let mut ups = UpsHatE::new();
18    let mut stdout = io::stdout();
19
20    let software_revision = ups.get_software_revision()?;
21
22    loop {
23        let battery = ups.get_battery_state()?;
24        let power = ups.get_power_state()?;
25        let comm = ups.get_communication_state()?;
26        let vbus = ups.get_usbc_vbus()?;
27        let cells = ups.get_cell_voltage()?;
28        let battery_low = ups.is_battery_low()?;
29        let power_off_pending = ups.is_power_off_pending()?;
30
31        print!("{CLEAR_SCREEN}{CURSOR_HOME}");
32
33        let epoch_secs = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
34
35        println!("{BOLD}UPS HAT (E) Monitor{RESET}");
36        println!("═══════════════════════════════════════════");
37        println!("Unix time: {epoch_secs}");
38        println!();
39
40        println!("{BOLD}UPS Info{RESET}");
41        println!("  Software Rev:  {:?}", software_revision);
42        println!();
43
44        // Power state
45        println!("{BOLD}Power{RESET}");
46        println!("  State:         {:?}", power.charging_state);
47        println!("  Activity:      {:?}", power.charger_activity);
48        println!("  USB-C In:      {:?}", power.usbc_input_state);
49        println!("  USB-C PD:      {:?}", power.usbc_power_delivery);
50        println!("  Off Pending?   {}", if power_off_pending { "Yes" } else { "No" });
51        println!();
52
53        // Communication state
54        println!("{BOLD}Communication{RESET}");
55        println!("  BQ4050:        {:?}", comm.bq4050);
56        println!("  IP2368:        {:?}", comm.ip2368);
57        println!();
58
59        // Battery
60        println!("{BOLD}Battery{RESET}");
61        println!("  Charge:        {}%", battery.remaining_percent);
62        println!("  Voltage:       {} mV", battery.millivolts);
63        println!("  Current:       {} mA", battery.milliamps);
64        println!("  Est. Capacity: {} mAh", battery.remaining_capacity_milliamphours);
65        if battery.milliamps < 0 {
66            println!("  Est. Runtime:  {} min", battery.remaining_runtime_minutes);
67        } else if battery.time_to_full_minutes > 0 {
68            println!("  Time To Full:  {} min", battery.time_to_full_minutes);
69        }
70        println!("  Low Battery?   {}", if battery_low { "Yes" } else { "No" });
71        println!();
72
73        // USB-C VBUS
74        println!("{BOLD}USB-C VBUS{RESET}");
75        println!("  Voltage:      {} mV", vbus.millivolts);
76        println!("  Current:      {} mA", vbus.milliamps);
77        println!("  Power:        {} mW", vbus.milliwatts);
78        println!();
79
80        // Cell voltages
81        println!("{BOLD}Cell Voltages{RESET}");
82        println!("  Cell 1:       {} mV", cells.cell_1_millivolts);
83        println!("  Cell 2:       {} mV", cells.cell_2_millivolts);
84        println!("  Cell 3:       {} mV", cells.cell_3_millivolts);
85        println!("  Cell 4:       {} mV", cells.cell_4_millivolts);
86        println!();
87
88        println!("Press Ctrl+C to exit");
89
90        stdout.flush()?;
91        thread::sleep(Duration::from_secs(2));
92    }
93}
Source

pub fn get_communication_state(&mut self) -> Result<CommunicationState, Error>

Examples found in repository?
examples/ups_monitor.rs (line 25)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    let mut ups = UpsHatE::new();
18    let mut stdout = io::stdout();
19
20    let software_revision = ups.get_software_revision()?;
21
22    loop {
23        let battery = ups.get_battery_state()?;
24        let power = ups.get_power_state()?;
25        let comm = ups.get_communication_state()?;
26        let vbus = ups.get_usbc_vbus()?;
27        let cells = ups.get_cell_voltage()?;
28        let battery_low = ups.is_battery_low()?;
29        let power_off_pending = ups.is_power_off_pending()?;
30
31        print!("{CLEAR_SCREEN}{CURSOR_HOME}");
32
33        let epoch_secs = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
34
35        println!("{BOLD}UPS HAT (E) Monitor{RESET}");
36        println!("═══════════════════════════════════════════");
37        println!("Unix time: {epoch_secs}");
38        println!();
39
40        println!("{BOLD}UPS Info{RESET}");
41        println!("  Software Rev:  {:?}", software_revision);
42        println!();
43
44        // Power state
45        println!("{BOLD}Power{RESET}");
46        println!("  State:         {:?}", power.charging_state);
47        println!("  Activity:      {:?}", power.charger_activity);
48        println!("  USB-C In:      {:?}", power.usbc_input_state);
49        println!("  USB-C PD:      {:?}", power.usbc_power_delivery);
50        println!("  Off Pending?   {}", if power_off_pending { "Yes" } else { "No" });
51        println!();
52
53        // Communication state
54        println!("{BOLD}Communication{RESET}");
55        println!("  BQ4050:        {:?}", comm.bq4050);
56        println!("  IP2368:        {:?}", comm.ip2368);
57        println!();
58
59        // Battery
60        println!("{BOLD}Battery{RESET}");
61        println!("  Charge:        {}%", battery.remaining_percent);
62        println!("  Voltage:       {} mV", battery.millivolts);
63        println!("  Current:       {} mA", battery.milliamps);
64        println!("  Est. Capacity: {} mAh", battery.remaining_capacity_milliamphours);
65        if battery.milliamps < 0 {
66            println!("  Est. Runtime:  {} min", battery.remaining_runtime_minutes);
67        } else if battery.time_to_full_minutes > 0 {
68            println!("  Time To Full:  {} min", battery.time_to_full_minutes);
69        }
70        println!("  Low Battery?   {}", if battery_low { "Yes" } else { "No" });
71        println!();
72
73        // USB-C VBUS
74        println!("{BOLD}USB-C VBUS{RESET}");
75        println!("  Voltage:      {} mV", vbus.millivolts);
76        println!("  Current:      {} mA", vbus.milliamps);
77        println!("  Power:        {} mW", vbus.milliwatts);
78        println!();
79
80        // Cell voltages
81        println!("{BOLD}Cell Voltages{RESET}");
82        println!("  Cell 1:       {} mV", cells.cell_1_millivolts);
83        println!("  Cell 2:       {} mV", cells.cell_2_millivolts);
84        println!("  Cell 3:       {} mV", cells.cell_3_millivolts);
85        println!("  Cell 4:       {} mV", cells.cell_4_millivolts);
86        println!();
87
88        println!("Press Ctrl+C to exit");
89
90        stdout.flush()?;
91        thread::sleep(Duration::from_secs(2));
92    }
93}
Source

pub fn get_software_revision(&mut self) -> Result<u8, Error>

Examples found in repository?
examples/ups_monitor.rs (line 20)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    let mut ups = UpsHatE::new();
18    let mut stdout = io::stdout();
19
20    let software_revision = ups.get_software_revision()?;
21
22    loop {
23        let battery = ups.get_battery_state()?;
24        let power = ups.get_power_state()?;
25        let comm = ups.get_communication_state()?;
26        let vbus = ups.get_usbc_vbus()?;
27        let cells = ups.get_cell_voltage()?;
28        let battery_low = ups.is_battery_low()?;
29        let power_off_pending = ups.is_power_off_pending()?;
30
31        print!("{CLEAR_SCREEN}{CURSOR_HOME}");
32
33        let epoch_secs = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
34
35        println!("{BOLD}UPS HAT (E) Monitor{RESET}");
36        println!("═══════════════════════════════════════════");
37        println!("Unix time: {epoch_secs}");
38        println!();
39
40        println!("{BOLD}UPS Info{RESET}");
41        println!("  Software Rev:  {:?}", software_revision);
42        println!();
43
44        // Power state
45        println!("{BOLD}Power{RESET}");
46        println!("  State:         {:?}", power.charging_state);
47        println!("  Activity:      {:?}", power.charger_activity);
48        println!("  USB-C In:      {:?}", power.usbc_input_state);
49        println!("  USB-C PD:      {:?}", power.usbc_power_delivery);
50        println!("  Off Pending?   {}", if power_off_pending { "Yes" } else { "No" });
51        println!();
52
53        // Communication state
54        println!("{BOLD}Communication{RESET}");
55        println!("  BQ4050:        {:?}", comm.bq4050);
56        println!("  IP2368:        {:?}", comm.ip2368);
57        println!();
58
59        // Battery
60        println!("{BOLD}Battery{RESET}");
61        println!("  Charge:        {}%", battery.remaining_percent);
62        println!("  Voltage:       {} mV", battery.millivolts);
63        println!("  Current:       {} mA", battery.milliamps);
64        println!("  Est. Capacity: {} mAh", battery.remaining_capacity_milliamphours);
65        if battery.milliamps < 0 {
66            println!("  Est. Runtime:  {} min", battery.remaining_runtime_minutes);
67        } else if battery.time_to_full_minutes > 0 {
68            println!("  Time To Full:  {} min", battery.time_to_full_minutes);
69        }
70        println!("  Low Battery?   {}", if battery_low { "Yes" } else { "No" });
71        println!();
72
73        // USB-C VBUS
74        println!("{BOLD}USB-C VBUS{RESET}");
75        println!("  Voltage:      {} mV", vbus.millivolts);
76        println!("  Current:      {} mA", vbus.milliamps);
77        println!("  Power:        {} mW", vbus.milliwatts);
78        println!();
79
80        // Cell voltages
81        println!("{BOLD}Cell Voltages{RESET}");
82        println!("  Cell 1:       {} mV", cells.cell_1_millivolts);
83        println!("  Cell 2:       {} mV", cells.cell_2_millivolts);
84        println!("  Cell 3:       {} mV", cells.cell_3_millivolts);
85        println!("  Cell 4:       {} mV", cells.cell_4_millivolts);
86        println!();
87
88        println!("Press Ctrl+C to exit");
89
90        stdout.flush()?;
91        thread::sleep(Duration::from_secs(2));
92    }
93}
Source

pub fn is_battery_low(&mut self) -> Result<bool, Error>

Returns true if the overall battery voltage is less than or equal to (4 * DEFAULT_CELL_LOW_VOLTAGE_THRESHOLD).

If you want an easy “is the battery low?” indicator, use this function.

Examples found in repository?
examples/ups_monitor.rs (line 28)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    let mut ups = UpsHatE::new();
18    let mut stdout = io::stdout();
19
20    let software_revision = ups.get_software_revision()?;
21
22    loop {
23        let battery = ups.get_battery_state()?;
24        let power = ups.get_power_state()?;
25        let comm = ups.get_communication_state()?;
26        let vbus = ups.get_usbc_vbus()?;
27        let cells = ups.get_cell_voltage()?;
28        let battery_low = ups.is_battery_low()?;
29        let power_off_pending = ups.is_power_off_pending()?;
30
31        print!("{CLEAR_SCREEN}{CURSOR_HOME}");
32
33        let epoch_secs = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
34
35        println!("{BOLD}UPS HAT (E) Monitor{RESET}");
36        println!("═══════════════════════════════════════════");
37        println!("Unix time: {epoch_secs}");
38        println!();
39
40        println!("{BOLD}UPS Info{RESET}");
41        println!("  Software Rev:  {:?}", software_revision);
42        println!();
43
44        // Power state
45        println!("{BOLD}Power{RESET}");
46        println!("  State:         {:?}", power.charging_state);
47        println!("  Activity:      {:?}", power.charger_activity);
48        println!("  USB-C In:      {:?}", power.usbc_input_state);
49        println!("  USB-C PD:      {:?}", power.usbc_power_delivery);
50        println!("  Off Pending?   {}", if power_off_pending { "Yes" } else { "No" });
51        println!();
52
53        // Communication state
54        println!("{BOLD}Communication{RESET}");
55        println!("  BQ4050:        {:?}", comm.bq4050);
56        println!("  IP2368:        {:?}", comm.ip2368);
57        println!();
58
59        // Battery
60        println!("{BOLD}Battery{RESET}");
61        println!("  Charge:        {}%", battery.remaining_percent);
62        println!("  Voltage:       {} mV", battery.millivolts);
63        println!("  Current:       {} mA", battery.milliamps);
64        println!("  Est. Capacity: {} mAh", battery.remaining_capacity_milliamphours);
65        if battery.milliamps < 0 {
66            println!("  Est. Runtime:  {} min", battery.remaining_runtime_minutes);
67        } else if battery.time_to_full_minutes > 0 {
68            println!("  Time To Full:  {} min", battery.time_to_full_minutes);
69        }
70        println!("  Low Battery?   {}", if battery_low { "Yes" } else { "No" });
71        println!();
72
73        // USB-C VBUS
74        println!("{BOLD}USB-C VBUS{RESET}");
75        println!("  Voltage:      {} mV", vbus.millivolts);
76        println!("  Current:      {} mA", vbus.milliamps);
77        println!("  Power:        {} mW", vbus.milliwatts);
78        println!();
79
80        // Cell voltages
81        println!("{BOLD}Cell Voltages{RESET}");
82        println!("  Cell 1:       {} mV", cells.cell_1_millivolts);
83        println!("  Cell 2:       {} mV", cells.cell_2_millivolts);
84        println!("  Cell 3:       {} mV", cells.cell_3_millivolts);
85        println!("  Cell 4:       {} mV", cells.cell_4_millivolts);
86        println!();
87
88        println!("Press Ctrl+C to exit");
89
90        stdout.flush()?;
91        thread::sleep(Duration::from_secs(2));
92    }
93}
Source

pub fn force_power_off(&mut self) -> Result<(), Error>

Unconditionally and uncleanly power-off the Raspberry Pi in 30 seconds.

This operation cannot be canceled once called.

Examples found in repository?
examples/force_power_off.rs (line 41)
24fn main() {
25    let args = env::args().collect::<Vec<_>>();
26
27    if args.len() == 2 && args[1].to_ascii_lowercase() != "-y" {
28        println!("Usage: force_power_off [-y]");
29        println!("  -y: skip confirmation prompt");
30        println!();
31        exit(1);
32    };
33
34    if !confirm_power_off(&args) {
35        println!("Aborting power-off due to user input. Use -y to skip confirmation prompt.");
36        exit(1);
37    }
38
39    let mut ups = UpsHatE::new();
40
41    ups.force_power_off().expect("failed to issue power-off command");
42
43    let pending = ups.is_power_off_pending().expect("failed reading power-off status");
44
45    if pending {
46        println!("UPS will power-off the attached Raspberry Pi in 30 seconds");
47        exit(0);
48    } else {
49        println!("Error: UPS failed to initiate power-off");
50        exit(2);
51    }
52}
Source

pub fn is_power_off_pending(&mut self) -> Result<bool, Error>

Returns true if a power-off has been initiated.

Examples found in repository?
examples/force_power_off.rs (line 43)
24fn main() {
25    let args = env::args().collect::<Vec<_>>();
26
27    if args.len() == 2 && args[1].to_ascii_lowercase() != "-y" {
28        println!("Usage: force_power_off [-y]");
29        println!("  -y: skip confirmation prompt");
30        println!();
31        exit(1);
32    };
33
34    if !confirm_power_off(&args) {
35        println!("Aborting power-off due to user input. Use -y to skip confirmation prompt.");
36        exit(1);
37    }
38
39    let mut ups = UpsHatE::new();
40
41    ups.force_power_off().expect("failed to issue power-off command");
42
43    let pending = ups.is_power_off_pending().expect("failed reading power-off status");
44
45    if pending {
46        println!("UPS will power-off the attached Raspberry Pi in 30 seconds");
47        exit(0);
48    } else {
49        println!("Error: UPS failed to initiate power-off");
50        exit(2);
51    }
52}
More examples
Hide additional examples
examples/ups_monitor.rs (line 29)
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    let mut ups = UpsHatE::new();
18    let mut stdout = io::stdout();
19
20    let software_revision = ups.get_software_revision()?;
21
22    loop {
23        let battery = ups.get_battery_state()?;
24        let power = ups.get_power_state()?;
25        let comm = ups.get_communication_state()?;
26        let vbus = ups.get_usbc_vbus()?;
27        let cells = ups.get_cell_voltage()?;
28        let battery_low = ups.is_battery_low()?;
29        let power_off_pending = ups.is_power_off_pending()?;
30
31        print!("{CLEAR_SCREEN}{CURSOR_HOME}");
32
33        let epoch_secs = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();
34
35        println!("{BOLD}UPS HAT (E) Monitor{RESET}");
36        println!("═══════════════════════════════════════════");
37        println!("Unix time: {epoch_secs}");
38        println!();
39
40        println!("{BOLD}UPS Info{RESET}");
41        println!("  Software Rev:  {:?}", software_revision);
42        println!();
43
44        // Power state
45        println!("{BOLD}Power{RESET}");
46        println!("  State:         {:?}", power.charging_state);
47        println!("  Activity:      {:?}", power.charger_activity);
48        println!("  USB-C In:      {:?}", power.usbc_input_state);
49        println!("  USB-C PD:      {:?}", power.usbc_power_delivery);
50        println!("  Off Pending?   {}", if power_off_pending { "Yes" } else { "No" });
51        println!();
52
53        // Communication state
54        println!("{BOLD}Communication{RESET}");
55        println!("  BQ4050:        {:?}", comm.bq4050);
56        println!("  IP2368:        {:?}", comm.ip2368);
57        println!();
58
59        // Battery
60        println!("{BOLD}Battery{RESET}");
61        println!("  Charge:        {}%", battery.remaining_percent);
62        println!("  Voltage:       {} mV", battery.millivolts);
63        println!("  Current:       {} mA", battery.milliamps);
64        println!("  Est. Capacity: {} mAh", battery.remaining_capacity_milliamphours);
65        if battery.milliamps < 0 {
66            println!("  Est. Runtime:  {} min", battery.remaining_runtime_minutes);
67        } else if battery.time_to_full_minutes > 0 {
68            println!("  Time To Full:  {} min", battery.time_to_full_minutes);
69        }
70        println!("  Low Battery?   {}", if battery_low { "Yes" } else { "No" });
71        println!();
72
73        // USB-C VBUS
74        println!("{BOLD}USB-C VBUS{RESET}");
75        println!("  Voltage:      {} mV", vbus.millivolts);
76        println!("  Current:      {} mA", vbus.milliamps);
77        println!("  Power:        {} mW", vbus.milliwatts);
78        println!();
79
80        // Cell voltages
81        println!("{BOLD}Cell Voltages{RESET}");
82        println!("  Cell 1:       {} mV", cells.cell_1_millivolts);
83        println!("  Cell 2:       {} mV", cells.cell_2_millivolts);
84        println!("  Cell 3:       {} mV", cells.cell_3_millivolts);
85        println!("  Cell 4:       {} mV", cells.cell_4_millivolts);
86        println!();
87
88        println!("Press Ctrl+C to exit");
89
90        stdout.flush()?;
91        thread::sleep(Duration::from_secs(2));
92    }
93}

Trait Implementations§

Source§

impl Default for UpsHatE

Source§

fn default() -> Self

Create a new instance of the UPS Hat E monitor using the default I2C bus device path and address. This works in most cases.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.