force_power_off/
force_power_off.rs

1// Copyright (c) 2025 Stuart Stock
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Will forcefully power-off the Raspberry Pi connected to the Waveshare UPS Hat E.
5//! 
6use std::env;
7use std::io::Write;
8use std::process::exit;
9use waveshare_ups_hat_e::UpsHatE;
10
11fn confirm_power_off(args: &Vec<String>) -> bool {
12    if args.len() == 2 && args[1].to_ascii_lowercase() == "-y" {
13        return true;
14    }
15
16    print!("Are you sure you want to power-off the Raspberry Pi? [y/N] ");
17    std::io::stdout().flush().unwrap();
18
19    let mut input = String::new();
20    std::io::stdin().read_line(&mut input).expect("failed to read input");
21    input.trim().to_ascii_lowercase() == "y"
22}
23
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}