mirror of
https://gitlab.steamos.cloud/holo/steamos-manager.git
synced 2025-07-14 02:11:54 -04:00
Merge branch 'endrift/steamosctl-cleanup' into 'master'
steamosctl cleanup See merge request holo/steamos-manager!24
This commit is contained in:
commit
80c598ce68
6 changed files with 243 additions and 151 deletions
|
@ -9,9 +9,11 @@ use anyhow::Result;
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
use steamos_manager::cec::HdmiCecState;
|
||||||
|
use steamos_manager::hardware::FanControlState;
|
||||||
|
use steamos_manager::power::GPUPerformanceLevel;
|
||||||
use steamos_manager::proxy::ManagerProxy;
|
use steamos_manager::proxy::ManagerProxy;
|
||||||
use steamos_manager::wifi::WifiBackend;
|
use steamos_manager::wifi::{WifiBackend, WifiDebugMode, WifiPowerManagement};
|
||||||
use zbus::fdo::PropertiesProxy;
|
use zbus::fdo::PropertiesProxy;
|
||||||
use zbus::names::InterfaceName;
|
use zbus::names::InterfaceName;
|
||||||
use zbus::{zvariant, Connection};
|
use zbus::{zvariant, Connection};
|
||||||
|
@ -19,98 +21,122 @@ use zbus::{zvariant, Connection};
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(version, about, long_about = None)]
|
#[command(version, about, long_about = None)]
|
||||||
struct Args {
|
struct Args {
|
||||||
/// Optionally get all properties
|
|
||||||
#[arg(short, long)]
|
|
||||||
all_properties: bool,
|
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
command: Option<Commands>,
|
command: Commands,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
GetAlsCalibrationGain {},
|
/// Get all properties
|
||||||
GetHardwareCurrentlySupported {},
|
GetAllProperties,
|
||||||
|
|
||||||
|
/// Get luminance sensor calibration gain
|
||||||
|
GetAlsCalibrationGain,
|
||||||
|
|
||||||
|
/// Get if the hardware is currently supported
|
||||||
|
GetHardwareCurrentlySupported,
|
||||||
|
|
||||||
|
/// Set the fan control state
|
||||||
SetFanControlState {
|
SetFanControlState {
|
||||||
// Set the fan control state.
|
/// Valid options are bios, os
|
||||||
// 0 - BIOS, 1 - OS
|
state: FanControlState,
|
||||||
#[arg(short, long)]
|
|
||||||
value: u32,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
GetFanControlState {},
|
/// Get the fan control state
|
||||||
|
GetFanControlState,
|
||||||
|
|
||||||
|
/// Set the GPU performance level
|
||||||
SetGPUPerformanceLevel {
|
SetGPUPerformanceLevel {
|
||||||
// Set the gpu performance level
|
/// Valid levels are auto, low, high, manual, peak_performance
|
||||||
// 0 = Auto, 1 = Low, 2 = High, 3 = Manual, 4 = Profile Peak
|
level: GPUPerformanceLevel,
|
||||||
#[arg(short, long)]
|
|
||||||
value: u32,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
GetGPUPerformanceLevel {},
|
/// Get the GPU performance level
|
||||||
|
GetGPUPerformanceLevel,
|
||||||
|
|
||||||
|
/// Set the GPU clock value manually. Only works when performance level is set to Manual
|
||||||
SetManualGPUClock {
|
SetManualGPUClock {
|
||||||
// Set the GPU clock value manually
|
/// GPU clock frequency in MHz
|
||||||
// Controls the GPU clock frequency in MHz when GPUPerformanceLevel is set to Manual
|
freq: u32,
|
||||||
#[arg(short, long)]
|
|
||||||
value: u32,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
GetManualGPUClock {},
|
/// Get the GPU clock frequency, in MHz. Only works when performance level is set to Manual
|
||||||
GetManualGPUClockMax {},
|
GetManualGPUClock,
|
||||||
GetManualGPUClockMin {},
|
|
||||||
|
|
||||||
|
/// Get the maximum allowed GPU clock frequency for the Manual performance level
|
||||||
|
GetManualGPUClockMax,
|
||||||
|
|
||||||
|
/// Get the minimum allowed GPU clock frequency for the Manual performance level
|
||||||
|
GetManualGPUClockMin,
|
||||||
|
|
||||||
|
/// Set the TDP limit
|
||||||
SetTDPLimit {
|
SetTDPLimit {
|
||||||
// Set the TDP limit
|
/// TDP limit, in W
|
||||||
#[arg(short, long)]
|
limit: u32,
|
||||||
value: u32,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
GetTDPLimit {},
|
/// Get the TDP limit
|
||||||
GetTDPLimitMax {},
|
GetTDPLimit,
|
||||||
GetTDPLimitMin {},
|
|
||||||
|
|
||||||
GetVersion {},
|
/// Get the maximum allowed TDP limit
|
||||||
|
GetTDPLimitMax,
|
||||||
|
|
||||||
|
/// Get the minimum allowed TDP limit
|
||||||
|
GetTDPLimitMin,
|
||||||
|
|
||||||
|
/// Get the current API version
|
||||||
|
GetVersion,
|
||||||
|
|
||||||
|
/// Set the wifi backend if possible
|
||||||
SetWifiBackend {
|
SetWifiBackend {
|
||||||
// Set the wifi backend to given string if possible
|
/// Supported backends are iwd, wpa_supplicant
|
||||||
// Supported values are iwd|wpa_supplicant
|
backend: WifiBackend,
|
||||||
#[arg(short, long)]
|
|
||||||
backend: String,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
GetWifiBackend {},
|
/// Get the wifi backend
|
||||||
|
GetWifiBackend,
|
||||||
|
|
||||||
|
/// Set wifi debug mode
|
||||||
SetWifiDebugMode {
|
SetWifiDebugMode {
|
||||||
// Set wifi debug mode to given value
|
/// Valid modes are on, off
|
||||||
// 1 for on, 0 for off currently
|
mode: WifiDebugMode,
|
||||||
#[arg(short, long)]
|
/// The size of the debug buffer, in bytes
|
||||||
mode: u32,
|
#[arg(default_value_t = 20000)]
|
||||||
|
buffer: u32,
|
||||||
},
|
},
|
||||||
|
|
||||||
GetWifiDebugMode {},
|
/// Get wifi debug mode
|
||||||
|
GetWifiDebugMode,
|
||||||
|
|
||||||
|
/// Set the wifi power management state
|
||||||
SetWifiPowerManagementState {
|
SetWifiPowerManagementState {
|
||||||
// Set the wifi power management state
|
/// Valid modes are enabled, disabled
|
||||||
// 0 - disabled, 1 - enabled
|
state: WifiPowerManagement,
|
||||||
#[arg(short, long)]
|
|
||||||
value: u32,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
GetWifiPowerManagementState {},
|
/// Get the wifi power management state
|
||||||
|
GetWifiPowerManagementState,
|
||||||
|
|
||||||
GetHdmiCecState {},
|
/// Get the state of HDMI-CEC support
|
||||||
|
GetHdmiCecState,
|
||||||
|
|
||||||
|
/// Set the state of HDMI-CEC support
|
||||||
SetHdmiCecState {
|
SetHdmiCecState {
|
||||||
// Set the state of HDMI-CEC support
|
/// Valid modes are disabled, control-only, control-and-wake
|
||||||
// 0 - disabled, 1 - only controls, 2 - TV waking
|
state: HdmiCecState,
|
||||||
#[arg(short, long)]
|
|
||||||
value: u32,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
UpdateBios {},
|
/// Update the BIOS, if possible
|
||||||
UpdateDock {},
|
UpdateBios,
|
||||||
TrimDevices {},
|
|
||||||
FactoryReset {},
|
/// Update the dock, if possible
|
||||||
|
UpdateDock,
|
||||||
|
|
||||||
|
/// Trim applicable drives
|
||||||
|
TrimDevices,
|
||||||
|
|
||||||
|
/// Factory reset the device
|
||||||
|
FactoryReset,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -124,129 +150,139 @@ async fn main() -> Result<()> {
|
||||||
let conn = Connection::session().await?;
|
let conn = Connection::session().await?;
|
||||||
let proxy = ManagerProxy::builder(&conn).build().await?;
|
let proxy = ManagerProxy::builder(&conn).build().await?;
|
||||||
|
|
||||||
if args.all_properties {
|
|
||||||
let properties_proxy = PropertiesProxy::new(
|
|
||||||
&conn,
|
|
||||||
"com.steampowered.SteamOSManager1",
|
|
||||||
"/com/steampowered/SteamOSManager1",
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
let name = InterfaceName::try_from("com.steampowered.SteamOSManager1.Manager")?;
|
|
||||||
let properties = properties_proxy
|
|
||||||
.get_all(zvariant::Optional::from(Some(name)))
|
|
||||||
.await?;
|
|
||||||
for key in properties.keys().sorted() {
|
|
||||||
let value = &properties[key];
|
|
||||||
let val = value.deref();
|
|
||||||
println!("{key}: {val}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then process arguments
|
// Then process arguments
|
||||||
match &args.command {
|
match &args.command {
|
||||||
Some(Commands::GetAlsCalibrationGain {}) => {
|
Commands::GetAllProperties => {
|
||||||
|
let properties_proxy = PropertiesProxy::new(
|
||||||
|
&conn,
|
||||||
|
"com.steampowered.SteamOSManager1",
|
||||||
|
"/com/steampowered/SteamOSManager1",
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let name = InterfaceName::try_from("com.steampowered.SteamOSManager1.Manager")?;
|
||||||
|
let properties = properties_proxy
|
||||||
|
.get_all(zvariant::Optional::from(Some(name)))
|
||||||
|
.await?;
|
||||||
|
for key in properties.keys().sorted() {
|
||||||
|
let value = &properties[key];
|
||||||
|
let val = value.deref();
|
||||||
|
println!("{key}: {val}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Commands::GetAlsCalibrationGain => {
|
||||||
let gain = proxy.als_calibration_gain().await?;
|
let gain = proxy.als_calibration_gain().await?;
|
||||||
println!("ALS calibration gain: {gain}");
|
println!("ALS calibration gain: {gain}");
|
||||||
}
|
}
|
||||||
Some(Commands::GetHardwareCurrentlySupported {}) => {
|
Commands::GetHardwareCurrentlySupported => {
|
||||||
let supported = proxy.hardware_currently_supported().await?;
|
let supported = proxy.hardware_currently_supported().await?;
|
||||||
println!("Hardware currently supported: {supported}");
|
println!("Hardware currently supported: {supported}");
|
||||||
}
|
}
|
||||||
Some(Commands::GetVersion {}) => {
|
Commands::GetVersion => {
|
||||||
let version = proxy.version().await?;
|
let version = proxy.version().await?;
|
||||||
println!("Version: {version}");
|
println!("Version: {version}");
|
||||||
}
|
}
|
||||||
Some(Commands::SetFanControlState { value }) => {
|
Commands::SetFanControlState { state } => {
|
||||||
proxy.set_fan_control_state(*value).await?;
|
proxy.set_fan_control_state(*state as u32).await?;
|
||||||
}
|
}
|
||||||
Some(Commands::SetGPUPerformanceLevel { value }) => {
|
Commands::GetFanControlState => {
|
||||||
proxy.set_gpu_performance_level(*value).await?;
|
let state = proxy.fan_control_state().await?;
|
||||||
|
match FanControlState::try_from(state) {
|
||||||
|
Ok(s) => println!("Fan control state: {}", s.to_string()),
|
||||||
|
Err(_) => println!("Got unknown value {state} from backend"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(Commands::GetGPUPerformanceLevel {}) => {
|
Commands::SetGPUPerformanceLevel { level } => {
|
||||||
|
proxy.set_gpu_performance_level(*level as u32).await?;
|
||||||
|
}
|
||||||
|
Commands::GetGPUPerformanceLevel => {
|
||||||
let level = proxy.gpu_performance_level().await?;
|
let level = proxy.gpu_performance_level().await?;
|
||||||
println!("GPU performance level: {level}");
|
match GPUPerformanceLevel::try_from(level) {
|
||||||
|
Ok(l) => println!("GPU performance level: {}", l.to_string()),
|
||||||
|
Err(_) => println!("Got unknown value {level} from backend"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(Commands::SetManualGPUClock { value }) => {
|
Commands::SetManualGPUClock { freq } => {
|
||||||
proxy.set_manual_gpu_clock(*value).await?;
|
proxy.set_manual_gpu_clock(*freq).await?;
|
||||||
}
|
}
|
||||||
Some(Commands::GetManualGPUClock {}) => {
|
Commands::GetManualGPUClock => {
|
||||||
let clock = proxy.manual_gpu_clock().await?;
|
let clock = proxy.manual_gpu_clock().await?;
|
||||||
println!("Manual GPU Clock: {clock}");
|
println!("Manual GPU Clock: {clock}");
|
||||||
}
|
}
|
||||||
Some(Commands::GetManualGPUClockMax {}) => {
|
Commands::GetManualGPUClockMax => {
|
||||||
let value = proxy.manual_gpu_clock_max().await?;
|
let value = proxy.manual_gpu_clock_max().await?;
|
||||||
println!("Manual GPU Clock Max: {value}");
|
println!("Manual GPU Clock Max: {value}");
|
||||||
}
|
}
|
||||||
Some(Commands::GetManualGPUClockMin {}) => {
|
Commands::GetManualGPUClockMin => {
|
||||||
let value = proxy.manual_gpu_clock_min().await?;
|
let value = proxy.manual_gpu_clock_min().await?;
|
||||||
println!("Manual GPU Clock Min: {value}");
|
println!("Manual GPU Clock Min: {value}");
|
||||||
}
|
}
|
||||||
Some(Commands::SetTDPLimit { value }) => {
|
Commands::SetTDPLimit { limit } => {
|
||||||
proxy.set_tdp_limit(*value).await?;
|
proxy.set_tdp_limit(*limit).await?;
|
||||||
}
|
}
|
||||||
Some(Commands::GetTDPLimit {}) => {
|
Commands::GetTDPLimit => {
|
||||||
let limit = proxy.tdp_limit().await?;
|
let limit = proxy.tdp_limit().await?;
|
||||||
println!("TDP limit: {limit}");
|
println!("TDP limit: {limit}");
|
||||||
}
|
}
|
||||||
Some(Commands::GetFanControlState {}) => {
|
Commands::GetTDPLimitMax => {
|
||||||
let state = proxy.fan_control_state().await?;
|
|
||||||
println!("Fan control state: {state}");
|
|
||||||
}
|
|
||||||
Some(Commands::GetTDPLimitMax {}) => {
|
|
||||||
let value = proxy.tdp_limit_max().await?;
|
let value = proxy.tdp_limit_max().await?;
|
||||||
println!("TDP limit max: {value}");
|
println!("TDP limit max: {value}");
|
||||||
}
|
}
|
||||||
Some(Commands::GetTDPLimitMin {}) => {
|
Commands::GetTDPLimitMin => {
|
||||||
let value = proxy.tdp_limit_min().await?;
|
let value = proxy.tdp_limit_min().await?;
|
||||||
println!("TDP limit min: {value}");
|
println!("TDP limit min: {value}");
|
||||||
}
|
}
|
||||||
Some(Commands::SetWifiBackend { backend }) => match WifiBackend::from_str(backend) {
|
Commands::SetWifiBackend { backend } => {
|
||||||
Ok(b) => {
|
proxy.set_wifi_backend(*backend as u32).await?;
|
||||||
proxy.set_wifi_backend(b as u32).await?;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
println!("Unknown wifi backend {backend}");
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
Some(Commands::GetWifiBackend {}) => {
|
Commands::GetWifiBackend => {
|
||||||
let backend = proxy.wifi_backend().await?;
|
let backend = proxy.wifi_backend().await?;
|
||||||
let backend_string = WifiBackend::try_from(backend).unwrap().to_string();
|
match WifiBackend::try_from(backend) {
|
||||||
println!("Wifi backend: {backend_string}");
|
Ok(be) => println!("Wifi backend: {}", be.to_string()),
|
||||||
|
Err(_) => println!("Got unknown value {backend} from backend"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(Commands::SetWifiDebugMode { mode }) => {
|
Commands::SetWifiDebugMode { mode, buffer } => {
|
||||||
proxy.set_wifi_debug_mode(*mode, 20000).await?;
|
proxy.set_wifi_debug_mode(*mode as u32, *buffer).await?;
|
||||||
}
|
}
|
||||||
Some(Commands::GetWifiDebugMode {}) => {
|
Commands::GetWifiDebugMode => {
|
||||||
let mode = proxy.wifi_debug_mode_state().await?;
|
let mode = proxy.wifi_debug_mode_state().await?;
|
||||||
println!("Wifi debug mode: {mode}");
|
match WifiDebugMode::try_from(mode) {
|
||||||
|
Ok(m) => println!("Wifi debug mode: {}", m.to_string()),
|
||||||
|
Err(_) => println!("Got unknown value {mode} from backend"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(Commands::SetWifiPowerManagementState { value }) => {
|
Commands::SetWifiPowerManagementState { state } => {
|
||||||
proxy.set_wifi_power_management_state(*value).await?;
|
proxy.set_wifi_power_management_state(*state as u32).await?;
|
||||||
}
|
}
|
||||||
Some(Commands::GetWifiPowerManagementState {}) => {
|
Commands::GetWifiPowerManagementState => {
|
||||||
let state = proxy.wifi_power_management_state().await?;
|
let state = proxy.wifi_power_management_state().await?;
|
||||||
println!("Wifi power management state: {state}");
|
match WifiPowerManagement::try_from(state) {
|
||||||
|
Ok(s) => println!("Wifi power management state: {}", s.to_string()),
|
||||||
|
Err(_) => println!("Got unknown value {state} from backend"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(Commands::SetHdmiCecState { value }) => {
|
Commands::SetHdmiCecState { state } => {
|
||||||
proxy.set_hdmi_cec_state(*value).await?;
|
proxy.set_hdmi_cec_state(*state as u32).await?;
|
||||||
}
|
}
|
||||||
Some(Commands::GetHdmiCecState {}) => {
|
Commands::GetHdmiCecState => {
|
||||||
let state = proxy.hdmi_cec_state().await?;
|
let state = proxy.hdmi_cec_state().await?;
|
||||||
println!("HDMI-CEC state: {state}");
|
match HdmiCecState::try_from(state) {
|
||||||
|
Ok(s) => println!("HDMI-CEC state: {}", s.to_human_readable()),
|
||||||
|
Err(_) => println!("Got unknown value {state} from backend"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(Commands::UpdateBios {}) => {
|
Commands::UpdateBios => {
|
||||||
let _ = proxy.update_bios().await?;
|
let _ = proxy.update_bios().await?;
|
||||||
}
|
}
|
||||||
Some(Commands::UpdateDock {}) => {
|
Commands::UpdateDock => {
|
||||||
let _ = proxy.update_dock().await?;
|
let _ = proxy.update_dock().await?;
|
||||||
}
|
}
|
||||||
Some(Commands::FactoryReset {}) => {
|
Commands::FactoryReset => {
|
||||||
let _ = proxy.prepare_factory_reset().await?;
|
let _ = proxy.prepare_factory_reset().await?;
|
||||||
}
|
}
|
||||||
Some(Commands::TrimDevices {}) => {
|
Commands::TrimDevices => {
|
||||||
let _ = proxy.trim_devices().await?;
|
let _ = proxy.trim_devices().await?;
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
27
src/cec.rs
27
src/cec.rs
|
@ -6,8 +6,9 @@
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::{bail, Error, Result};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::str::FromStr;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
||||||
use crate::systemd::{daemon_reload, EnableState, SystemdUnit};
|
use crate::systemd::{daemon_reload, EnableState, SystemdUnit};
|
||||||
|
@ -31,6 +32,18 @@ impl TryFrom<u32> for HdmiCecState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for HdmiCecState {
|
||||||
|
type Err = Error;
|
||||||
|
fn from_str(input: &str) -> Result<HdmiCecState, Self::Err> {
|
||||||
|
Ok(match input {
|
||||||
|
"disable" | "disabled" | "off" => HdmiCecState::Disabled,
|
||||||
|
"control-only" | "ControlOnly" => HdmiCecState::ControlOnly,
|
||||||
|
"control-wake" | "control-and-wake" | "ControlAndWake" => HdmiCecState::ControlAndWake,
|
||||||
|
v => bail!("No enum match for value {v}"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for HdmiCecState {
|
impl fmt::Display for HdmiCecState {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -41,7 +54,17 @@ impl fmt::Display for HdmiCecState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct HdmiCecControl<'dbus> {
|
impl HdmiCecState {
|
||||||
|
pub fn to_human_readable(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
HdmiCecState::Disabled => "disabled",
|
||||||
|
HdmiCecState::ControlOnly => "control-only",
|
||||||
|
HdmiCecState::ControlAndWake => "control-and-wake",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct HdmiCecControl<'dbus> {
|
||||||
plasma_rc_unit: SystemdUnit<'dbus>,
|
plasma_rc_unit: SystemdUnit<'dbus>,
|
||||||
wakehook_unit: SystemdUnit<'dbus>,
|
wakehook_unit: SystemdUnit<'dbus>,
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use anyhow::{Error, Result};
|
use anyhow::{bail, Error, Result};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
@ -19,7 +19,7 @@ const BOARD_VENDOR_PATH: &str = "/sys/class/dmi/id/board_vendor";
|
||||||
const BOARD_NAME_PATH: &str = "/sys/class/dmi/id/board_name";
|
const BOARD_NAME_PATH: &str = "/sys/class/dmi/id/board_name";
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||||
pub enum HardwareVariant {
|
pub(crate) enum HardwareVariant {
|
||||||
Unknown,
|
Unknown,
|
||||||
Jupiter,
|
Jupiter,
|
||||||
Galileo,
|
Galileo,
|
||||||
|
@ -27,7 +27,7 @@ pub enum HardwareVariant {
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Copy, Clone)]
|
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum HardwareCurrentlySupported {
|
pub(crate) enum HardwareCurrentlySupported {
|
||||||
Unsupported = 0,
|
Unsupported = 0,
|
||||||
Supported = 1,
|
Supported = 1,
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,17 @@ impl TryFrom<u32> for FanControlState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for FanControlState {
|
||||||
|
type Err = Error;
|
||||||
|
fn from_str(input: &str) -> Result<FanControlState, Self::Err> {
|
||||||
|
Ok(match input.to_lowercase().as_str() {
|
||||||
|
"bios" => FanControlState::Bios,
|
||||||
|
"os" => FanControlState::Os,
|
||||||
|
v => bail!("No enum match for value {v}"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for FanControlState {
|
impl fmt::Display for FanControlState {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -94,7 +105,7 @@ impl fmt::Display for FanControlState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn variant() -> Result<HardwareVariant> {
|
pub(crate) async fn variant() -> Result<HardwareVariant> {
|
||||||
let board_vendor = fs::read_to_string(path(BOARD_VENDOR_PATH)).await?;
|
let board_vendor = fs::read_to_string(path(BOARD_VENDOR_PATH)).await?;
|
||||||
if board_vendor.trim_end() != "Valve" {
|
if board_vendor.trim_end() != "Valve" {
|
||||||
return Ok(HardwareVariant::Unknown);
|
return Ok(HardwareVariant::Unknown);
|
||||||
|
@ -104,7 +115,7 @@ pub async fn variant() -> Result<HardwareVariant> {
|
||||||
HardwareVariant::from_str(board_name.trim_end())
|
HardwareVariant::from_str(board_name.trim_end())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn check_support() -> Result<HardwareCurrentlySupported> {
|
pub(crate) async fn check_support() -> Result<HardwareCurrentlySupported> {
|
||||||
// Run jupiter-check-support note this script does exit 1 for "Support: No" case
|
// Run jupiter-check-support note this script does exit 1 for "Support: No" case
|
||||||
// so no need to parse output, etc.
|
// so no need to parse output, etc.
|
||||||
let res = script_exit_code("/usr/bin/jupiter-check-support", &[] as &[String; 0]).await?;
|
let res = script_exit_code("/usr/bin/jupiter-check-support", &[] as &[String; 0]).await?;
|
||||||
|
@ -115,7 +126,7 @@ pub async fn check_support() -> Result<HardwareCurrentlySupported> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FanControl {
|
pub(crate) struct FanControl {
|
||||||
connection: Connection,
|
connection: Connection,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,17 +14,17 @@ use tokio::signal::unix::{signal, SignalKind};
|
||||||
use tokio_util::sync::CancellationToken;
|
use tokio_util::sync::CancellationToken;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
|
|
||||||
mod cec;
|
|
||||||
mod ds_inhibit;
|
mod ds_inhibit;
|
||||||
mod error;
|
mod error;
|
||||||
mod hardware;
|
|
||||||
mod manager;
|
mod manager;
|
||||||
mod power;
|
|
||||||
mod process;
|
mod process;
|
||||||
mod sls;
|
mod sls;
|
||||||
mod systemd;
|
mod systemd;
|
||||||
|
|
||||||
|
pub mod cec;
|
||||||
pub mod daemon;
|
pub mod daemon;
|
||||||
|
pub mod hardware;
|
||||||
|
pub mod power;
|
||||||
pub mod proxy;
|
pub mod proxy;
|
||||||
pub mod wifi;
|
pub mod wifi;
|
||||||
|
|
||||||
|
|
32
src/power.rs
32
src/power.rs
|
@ -5,7 +5,7 @@
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, ensure, Error, Result};
|
use anyhow::{bail, ensure, Error, Result};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use tokio::fs::{self, File};
|
use tokio::fs::{self, File};
|
||||||
|
@ -52,14 +52,14 @@ impl TryFrom<u32> for GPUPerformanceLevel {
|
||||||
impl FromStr for GPUPerformanceLevel {
|
impl FromStr for GPUPerformanceLevel {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
fn from_str(input: &str) -> Result<GPUPerformanceLevel, Self::Err> {
|
fn from_str(input: &str) -> Result<GPUPerformanceLevel, Self::Err> {
|
||||||
match input {
|
Ok(match input {
|
||||||
"auto" => Ok(GPUPerformanceLevel::Auto),
|
"auto" => GPUPerformanceLevel::Auto,
|
||||||
"low" => Ok(GPUPerformanceLevel::Low),
|
"low" => GPUPerformanceLevel::Low,
|
||||||
"high" => Ok(GPUPerformanceLevel::High),
|
"high" => GPUPerformanceLevel::High,
|
||||||
"manual" => Ok(GPUPerformanceLevel::Manual),
|
"manual" => GPUPerformanceLevel::Manual,
|
||||||
"peak_performance" => Ok(GPUPerformanceLevel::ProfilePeak),
|
"peak_performance" => GPUPerformanceLevel::ProfilePeak,
|
||||||
v => Err(anyhow!("No enum match for value {v}")),
|
v => bail!("No enum match for value {v}"),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ impl ToString for GPUPerformanceLevel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_gpu_performance_level() -> Result<GPUPerformanceLevel> {
|
pub(crate) async fn get_gpu_performance_level() -> Result<GPUPerformanceLevel> {
|
||||||
let base = find_hwmon().await?;
|
let base = find_hwmon().await?;
|
||||||
let level = fs::read_to_string(base.join(GPU_PERFORMANCE_LEVEL_SUFFIX))
|
let level = fs::read_to_string(base.join(GPU_PERFORMANCE_LEVEL_SUFFIX))
|
||||||
.await
|
.await
|
||||||
|
@ -84,7 +84,7 @@ pub async fn get_gpu_performance_level() -> Result<GPUPerformanceLevel> {
|
||||||
GPUPerformanceLevel::from_str(level.trim())
|
GPUPerformanceLevel::from_str(level.trim())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_gpu_performance_level(level: GPUPerformanceLevel) -> Result<()> {
|
pub(crate) async fn set_gpu_performance_level(level: GPUPerformanceLevel) -> Result<()> {
|
||||||
let level: String = level.to_string();
|
let level: String = level.to_string();
|
||||||
let base = find_hwmon().await?;
|
let base = find_hwmon().await?;
|
||||||
write_synced(base.join(GPU_PERFORMANCE_LEVEL_SUFFIX), level.as_bytes())
|
write_synced(base.join(GPU_PERFORMANCE_LEVEL_SUFFIX), level.as_bytes())
|
||||||
|
@ -92,7 +92,7 @@ pub async fn set_gpu_performance_level(level: GPUPerformanceLevel) -> Result<()>
|
||||||
.inspect_err(|message| error!("Error writing to sysfs file: {message}"))
|
.inspect_err(|message| error!("Error writing to sysfs file: {message}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_gpu_clocks(clocks: u32) -> Result<()> {
|
pub(crate) async fn set_gpu_clocks(clocks: u32) -> Result<()> {
|
||||||
// Set GPU clocks to given value valid between 200 - 1600
|
// Set GPU clocks to given value valid between 200 - 1600
|
||||||
// Only used when GPU Performance Level is manual, but write whenever called.
|
// Only used when GPU Performance Level is manual, but write whenever called.
|
||||||
ensure!((200..=1600).contains(&clocks), "Invalid clocks");
|
ensure!((200..=1600).contains(&clocks), "Invalid clocks");
|
||||||
|
@ -125,7 +125,7 @@ pub async fn set_gpu_clocks(clocks: u32) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_gpu_clocks() -> Result<u32> {
|
pub(crate) async fn get_gpu_clocks() -> Result<u32> {
|
||||||
let base = find_hwmon().await?;
|
let base = find_hwmon().await?;
|
||||||
let clocks_file = File::open(base.join(GPU_CLOCKS_SUFFIX)).await?;
|
let clocks_file = File::open(base.join(GPU_CLOCKS_SUFFIX)).await?;
|
||||||
let mut reader = BufReader::new(clocks_file);
|
let mut reader = BufReader::new(clocks_file);
|
||||||
|
@ -170,14 +170,14 @@ async fn find_hwmon() -> Result<PathBuf> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_tdp_limit() -> Result<u32> {
|
pub(crate) async fn get_tdp_limit() -> Result<u32> {
|
||||||
let base = find_hwmon().await?;
|
let base = find_hwmon().await?;
|
||||||
let power1cap = fs::read_to_string(base.join(TDP_LIMIT1)).await?;
|
let power1cap = fs::read_to_string(base.join(TDP_LIMIT1)).await?;
|
||||||
let power1cap: u32 = power1cap.trim_end().parse()?;
|
let power1cap: u32 = power1cap.trim_end().parse()?;
|
||||||
Ok(power1cap / 1000000)
|
Ok(power1cap / 1000000)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_tdp_limit(limit: u32) -> Result<()> {
|
pub(crate) async fn set_tdp_limit(limit: u32) -> Result<()> {
|
||||||
// Set TDP limit given if within range (3-15)
|
// Set TDP limit given if within range (3-15)
|
||||||
// Returns false on error or out of range
|
// Returns false on error or out of range
|
||||||
ensure!((3..=15).contains(&limit), "Invalid limit");
|
ensure!((3..=15).contains(&limit), "Invalid limit");
|
||||||
|
@ -201,7 +201,7 @@ pub async fn set_tdp_limit(limit: u32) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod test {
|
pub(crate) mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::testing;
|
use crate::testing;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
|
22
src/wifi.rs
22
src/wifi.rs
|
@ -64,6 +64,17 @@ impl TryFrom<u32> for WifiDebugMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for WifiDebugMode {
|
||||||
|
type Err = Error;
|
||||||
|
fn from_str(input: &str) -> Result<WifiDebugMode, Self::Err> {
|
||||||
|
Ok(match input {
|
||||||
|
"enable" | "enabled" | "on" | "1" => WifiDebugMode::On,
|
||||||
|
"disable" | "disabled" | "off" | "0" => WifiDebugMode::Off,
|
||||||
|
v => bail!("No enum match for value {v}"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for WifiDebugMode {
|
impl fmt::Display for WifiDebugMode {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -84,6 +95,17 @@ impl TryFrom<u32> for WifiPowerManagement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for WifiPowerManagement {
|
||||||
|
type Err = Error;
|
||||||
|
fn from_str(input: &str) -> Result<WifiPowerManagement, Self::Err> {
|
||||||
|
Ok(match input {
|
||||||
|
"enable" | "enabled" | "on" | "1" => WifiPowerManagement::Enabled,
|
||||||
|
"disable" | "disabled" | "off" | "0" => WifiPowerManagement::Disabled,
|
||||||
|
v => bail!("No enum match for value {v}"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for WifiPowerManagement {
|
impl fmt::Display for WifiPowerManagement {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue