Cargo fmt
This commit is contained in:
parent
2c0cac125c
commit
54393cd0cb
38 changed files with 1725 additions and 1023 deletions
|
@ -9,7 +9,10 @@ pub struct RangeLimit<T> {
|
||||||
impl<T> From<limits_core::json::RangeLimit<T>> for RangeLimit<T> {
|
impl<T> From<limits_core::json::RangeLimit<T>> for RangeLimit<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(other: limits_core::json::RangeLimit<T>) -> Self {
|
fn from(other: limits_core::json::RangeLimit<T>) -> Self {
|
||||||
RangeLimit { min: other.min, max: other.max }
|
RangeLimit {
|
||||||
|
min: other.min,
|
||||||
|
max: other.max,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,8 +50,7 @@ pub struct CpuLimits {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct GeneralLimits {
|
pub struct GeneralLimits {}
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct GpuLimits {
|
pub struct GpuLimits {
|
||||||
|
|
|
@ -1,29 +1,33 @@
|
||||||
//use usdpl_back::core::serdes::Primitive;
|
//use usdpl_back::core::serdes::Primitive;
|
||||||
use usdpl_back::AsyncCallable;
|
use usdpl_back::AsyncCallable;
|
||||||
|
|
||||||
pub struct AsyncIsh<In: Send + 'static,
|
pub struct AsyncIsh<
|
||||||
|
In: Send + 'static,
|
||||||
Out: Send + 'static,
|
Out: Send + 'static,
|
||||||
TS: (Fn(super::ApiParameterType) -> Result<In, String>) + Send + Sync,
|
TS: (Fn(super::ApiParameterType) -> Result<In, String>) + Send + Sync,
|
||||||
Gen: (Fn() -> SG) + Send + Sync,
|
Gen: (Fn() -> SG) + Send + Sync,
|
||||||
SG: (Fn(In) -> Out) + Send + Sync + 'static,
|
SG: (Fn(In) -> Out) + Send + Sync + 'static,
|
||||||
TG: (Fn(Out) -> super::ApiParameterType) + Send + Sync> {
|
TG: (Fn(Out) -> super::ApiParameterType) + Send + Sync,
|
||||||
|
> {
|
||||||
pub trans_setter: TS, // assumed to be pretty fast
|
pub trans_setter: TS, // assumed to be pretty fast
|
||||||
pub set_get: Gen, // probably has locks (i.e. slow)
|
pub set_get: Gen, // probably has locks (i.e. slow)
|
||||||
pub trans_getter: TG, // assumed to be pretty fast
|
pub trans_getter: TG, // assumed to be pretty fast
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl <In: Send + 'static,
|
impl<
|
||||||
Out: Send + 'static,
|
In: Send + 'static,
|
||||||
TS: (Fn(super::ApiParameterType) -> Result<In, String>) + Send + Sync,
|
Out: Send + 'static,
|
||||||
Gen: (Fn() -> SG) + Send + Sync,
|
TS: (Fn(super::ApiParameterType) -> Result<In, String>) + Send + Sync,
|
||||||
SG: (Fn(In) -> Out) + Send + Sync + 'static,
|
Gen: (Fn() -> SG) + Send + Sync,
|
||||||
TG: (Fn(Out) -> super::ApiParameterType) + Send + Sync>
|
SG: (Fn(In) -> Out) + Send + Sync + 'static,
|
||||||
AsyncCallable for AsyncIsh<In, Out, TS, Gen, SG, TG> {
|
TG: (Fn(Out) -> super::ApiParameterType) + Send + Sync,
|
||||||
|
> AsyncCallable for AsyncIsh<In, Out, TS, Gen, SG, TG>
|
||||||
|
{
|
||||||
async fn call(&self, params: super::ApiParameterType) -> super::ApiParameterType {
|
async fn call(&self, params: super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let t_to_set = match (self.trans_setter)(params) {
|
let t_to_set = match (self.trans_setter)(params) {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
Err(e) => return vec![e.into()]
|
Err(e) => return vec![e.into()],
|
||||||
};
|
};
|
||||||
let setter = (self.set_get)();
|
let setter = (self.set_get)();
|
||||||
let t_got = match tokio::task::spawn_blocking(move || setter(t_to_set)).await {
|
let t_got = match tokio::task::spawn_blocking(move || setter(t_to_set)).await {
|
||||||
|
@ -34,20 +38,24 @@ impl <In: Send + 'static,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AsyncIshGetter<T: Send + 'static,
|
pub struct AsyncIshGetter<
|
||||||
|
T: Send + 'static,
|
||||||
Gen: (Fn() -> G) + Send + Sync,
|
Gen: (Fn() -> G) + Send + Sync,
|
||||||
G: (Fn() -> T) + Send + Sync + 'static,
|
G: (Fn() -> T) + Send + Sync + 'static,
|
||||||
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync> {
|
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync,
|
||||||
pub set_get: Gen, // probably has locks (i.e. slow)
|
> {
|
||||||
|
pub set_get: Gen, // probably has locks (i.e. slow)
|
||||||
pub trans_getter: TG, // assumed to be pretty fast
|
pub trans_getter: TG, // assumed to be pretty fast
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl <T: Send + 'static,
|
impl<
|
||||||
Gen: (Fn() -> G) + Send + Sync,
|
T: Send + 'static,
|
||||||
G: (Fn() -> T) + Send + Sync + 'static,
|
Gen: (Fn() -> G) + Send + Sync,
|
||||||
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync>
|
G: (Fn() -> T) + Send + Sync + 'static,
|
||||||
AsyncCallable for AsyncIshGetter<T, Gen, G, TG> {
|
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync,
|
||||||
|
> AsyncCallable for AsyncIshGetter<T, Gen, G, TG>
|
||||||
|
{
|
||||||
async fn call(&self, _params: super::ApiParameterType) -> super::ApiParameterType {
|
async fn call(&self, _params: super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let getter = (self.set_get)();
|
let getter = (self.set_get)();
|
||||||
let t_got = match tokio::task::spawn_blocking(move || getter()).await {
|
let t_got = match tokio::task::spawn_blocking(move || getter()).await {
|
||||||
|
@ -63,7 +71,9 @@ pub struct Blocking<F: (Fn(super::ApiParameterType) -> super::ApiParameterType)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl <F: (Fn(super::ApiParameterType) -> super::ApiParameterType) + Send + Sync> AsyncCallable for Blocking<F> {
|
impl<F: (Fn(super::ApiParameterType) -> super::ApiParameterType) + Send + Sync> AsyncCallable
|
||||||
|
for Blocking<F>
|
||||||
|
{
|
||||||
async fn call(&self, params: super::ApiParameterType) -> super::ApiParameterType {
|
async fn call(&self, params: super::ApiParameterType) -> super::ApiParameterType {
|
||||||
(self.func)(params)
|
(self.func)(params)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::sync::mpsc::{Sender, self};
|
use std::sync::mpsc::{self, Sender};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use usdpl_back::core::serdes::Primitive;
|
use usdpl_back::core::serdes::Primitive;
|
||||||
use usdpl_back::AsyncCallable;
|
use usdpl_back::AsyncCallable;
|
||||||
|
@ -6,24 +6,27 @@ use usdpl_back::AsyncCallable;
|
||||||
use super::handler::{ApiMessage, BatteryMessage};
|
use super::handler::{ApiMessage, BatteryMessage};
|
||||||
|
|
||||||
/// Current current (ha!) web method
|
/// Current current (ha!) web method
|
||||||
pub fn current_now(
|
pub fn current_now(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |val: Option<f64>| tx.send(val).expect("current_now callback send failed");
|
let callback =
|
||||||
sender2.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::ReadCurrentNow(Box::new(callback)))).expect("current_now send failed");
|
move |val: Option<f64>| tx.send(val).expect("current_now callback send failed");
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Battery(BatteryMessage::ReadCurrentNow(
|
||||||
|
Box::new(callback),
|
||||||
|
)))
|
||||||
|
.expect("current_now send failed");
|
||||||
rx.recv().expect("current_now callback recv failed")
|
rx.recv().expect("current_now callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |result| {
|
trans_getter: |result| super::utility::map_optional_result(Ok(result)),
|
||||||
super::utility::map_optional_result(Ok(result))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,68 +36,77 @@ pub fn current_now(
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/// Charge now web method
|
/// Charge now web method
|
||||||
pub fn charge_now(
|
pub fn charge_now(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |val: Option<f64>| tx.send(val).expect("charge_now callback send failed");
|
let callback =
|
||||||
sender2.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::ReadChargeNow(Box::new(callback)))).expect("charge_now send failed");
|
move |val: Option<f64>| tx.send(val).expect("charge_now callback send failed");
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Battery(BatteryMessage::ReadChargeNow(
|
||||||
|
Box::new(callback),
|
||||||
|
)))
|
||||||
|
.expect("charge_now send failed");
|
||||||
rx.recv().expect("charge_now callback recv failed")
|
rx.recv().expect("charge_now callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |result| {
|
trans_getter: |result| super::utility::map_optional_result(Ok(result)),
|
||||||
super::utility::map_optional_result(Ok(result))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Charge full web method
|
/// Charge full web method
|
||||||
pub fn charge_full(
|
pub fn charge_full(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |val: Option<f64>| tx.send(val).expect("charge_full callback send failed");
|
let callback =
|
||||||
sender2.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::ReadChargeFull(Box::new(callback)))).expect("charge_full send failed");
|
move |val: Option<f64>| tx.send(val).expect("charge_full callback send failed");
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Battery(BatteryMessage::ReadChargeFull(
|
||||||
|
Box::new(callback),
|
||||||
|
)))
|
||||||
|
.expect("charge_full send failed");
|
||||||
rx.recv().expect("charge_full callback recv failed")
|
rx.recv().expect("charge_full callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |result| {
|
trans_getter: |result| super::utility::map_optional_result(Ok(result)),
|
||||||
super::utility::map_optional_result(Ok(result))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Charge design web method
|
/// Charge design web method
|
||||||
pub fn charge_design(
|
pub fn charge_design(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |val: Option<f64>| tx.send(val).expect("charge_design callback send failed");
|
let callback =
|
||||||
sender2.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::ReadChargeDesign(Box::new(callback)))).expect("charge_design send failed");
|
move |val: Option<f64>| tx.send(val).expect("charge_design callback send failed");
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Battery(BatteryMessage::ReadChargeDesign(
|
||||||
|
Box::new(callback),
|
||||||
|
)))
|
||||||
|
.expect("charge_design send failed");
|
||||||
rx.recv().expect("charge_design callback recv failed")
|
rx.recv().expect("charge_design callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |result| {
|
trans_getter: |result| super::utility::map_optional_result(Ok(result)),
|
||||||
super::utility::map_optional_result(Ok(result))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,11 +115,15 @@ pub fn set_charge_rate(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |rate: f64|
|
let setter = move |rate: f64| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeRate(Some(rate as u64))))
|
.send(ApiMessage::Battery(BatteryMessage::SetChargeRate(Some(
|
||||||
.expect("set_charge_rate send failed");
|
rate as u64,
|
||||||
|
))))
|
||||||
|
.expect("set_charge_rate send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(&Primitive::F64(new_val)) = params_in.get(0) {
|
if let Some(&Primitive::F64(new_val)) = params_in.get(0) {
|
||||||
setter(new_val);
|
setter(new_val);
|
||||||
|
@ -125,13 +141,18 @@ pub fn get_charge_rate(
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |rate: Option<u64>| tx.send(rate).expect("get_charge_rate callback send failed");
|
let callback =
|
||||||
sender.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::GetChargeRate(Box::new(callback)))).expect("get_charge_rate send failed");
|
move |rate: Option<u64>| tx.send(rate).expect("get_charge_rate callback send failed");
|
||||||
|
sender
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Battery(BatteryMessage::GetChargeRate(
|
||||||
|
Box::new(callback),
|
||||||
|
)))
|
||||||
|
.expect("get_charge_rate send failed");
|
||||||
rx.recv().expect("get_charge_rate callback recv failed")
|
rx.recv().expect("get_charge_rate callback recv failed")
|
||||||
};
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| vec![getter().map(|x| x.into()).unwrap_or(Primitive::Empty)]
|
||||||
vec![getter().map(|x| x.into()).unwrap_or(Primitive::Empty)]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate unset battery charge rate web method
|
/// Generate unset battery charge rate web method
|
||||||
|
@ -139,7 +160,13 @@ pub fn unset_charge_rate(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move || sender.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::SetChargeRate(None))).expect("unset_charge_rate send failed");
|
let setter = move || {
|
||||||
|
sender
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Battery(BatteryMessage::SetChargeRate(None)))
|
||||||
|
.expect("unset_charge_rate send failed")
|
||||||
|
};
|
||||||
move |_params_in: super::ApiParameterType| {
|
move |_params_in: super::ApiParameterType| {
|
||||||
setter();
|
setter();
|
||||||
vec![true.into()]
|
vec![true.into()]
|
||||||
|
@ -151,11 +178,15 @@ pub fn set_charge_mode(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |mode: String|
|
let setter = move |mode: String| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeMode(Some(mode))))
|
.send(ApiMessage::Battery(BatteryMessage::SetChargeMode(Some(
|
||||||
.expect("set_charge_mode send failed");
|
mode,
|
||||||
|
))))
|
||||||
|
.expect("set_charge_mode send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::String(new_val)) = params_in.get(0) {
|
if let Some(Primitive::String(new_val)) = params_in.get(0) {
|
||||||
setter(new_val.to_owned());
|
setter(new_val.to_owned());
|
||||||
|
@ -173,13 +204,19 @@ pub fn get_charge_mode(
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |mode: Option<String>| tx.send(mode).expect("get_charge_mode callback send failed");
|
let callback = move |mode: Option<String>| {
|
||||||
sender.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::GetChargeMode(Box::new(callback)))).expect("get_charge_mode send failed");
|
tx.send(mode).expect("get_charge_mode callback send failed")
|
||||||
|
};
|
||||||
|
sender
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Battery(BatteryMessage::GetChargeMode(
|
||||||
|
Box::new(callback),
|
||||||
|
)))
|
||||||
|
.expect("get_charge_mode send failed");
|
||||||
rx.recv().expect("get_charge_mode callback recv failed")
|
rx.recv().expect("get_charge_mode callback recv failed")
|
||||||
};
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| vec![getter().map(|x| x.into()).unwrap_or(Primitive::Empty)]
|
||||||
vec![getter().map(|x| x.into()).unwrap_or(Primitive::Empty)]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate unset battery charge mode web method
|
/// Generate unset battery charge mode web method
|
||||||
|
@ -187,7 +224,13 @@ pub fn unset_charge_mode(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move || sender.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::SetChargeMode(None))).expect("unset_charge_mode send failed");
|
let setter = move || {
|
||||||
|
sender
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Battery(BatteryMessage::SetChargeMode(None)))
|
||||||
|
.expect("unset_charge_mode send failed")
|
||||||
|
};
|
||||||
move |_params_in: super::ApiParameterType| {
|
move |_params_in: super::ApiParameterType| {
|
||||||
setter();
|
setter();
|
||||||
vec![true.into()]
|
vec![true.into()]
|
||||||
|
@ -200,7 +243,11 @@ pub fn on_unplugged(
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
move |_| {
|
move |_| {
|
||||||
sender.lock().unwrap().send(ApiMessage::OnUnplugged).expect("on_unplugged send failed");
|
sender
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::OnUnplugged)
|
||||||
|
.expect("on_unplugged send failed");
|
||||||
vec![true.into()]
|
vec![true.into()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,7 +258,11 @@ pub fn on_plugged(
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
move |_| {
|
move |_| {
|
||||||
sender.lock().unwrap().send(ApiMessage::OnPluggedIn).expect("on_plugged send failed");
|
sender
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::OnPluggedIn)
|
||||||
|
.expect("on_plugged send failed");
|
||||||
vec![true.into()]
|
vec![true.into()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,11 +272,15 @@ pub fn set_charge_limit(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |limit: f64|
|
let setter = move |limit: f64| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeLimit(Some(limit))))
|
.send(ApiMessage::Battery(BatteryMessage::SetChargeLimit(Some(
|
||||||
.expect("set_charge_limit send failed");
|
limit,
|
||||||
|
))))
|
||||||
|
.expect("set_charge_limit send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(&Primitive::F64(new_val)) = params_in.get(0) {
|
if let Some(&Primitive::F64(new_val)) = params_in.get(0) {
|
||||||
setter(new_val);
|
setter(new_val);
|
||||||
|
@ -241,11 +296,13 @@ pub fn unset_charge_limit(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let unsetter = move ||
|
let unsetter = move || {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeLimit(None)))
|
.send(ApiMessage::Battery(BatteryMessage::SetChargeLimit(None)))
|
||||||
.expect("unset_charge_limit send failed");
|
.expect("unset_charge_limit send failed")
|
||||||
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
unsetter();
|
unsetter();
|
||||||
vec![true.into()]
|
vec![true.into()]
|
||||||
|
@ -253,23 +310,27 @@ pub fn unset_charge_limit(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Charge design web method
|
/// Charge design web method
|
||||||
pub fn get_charge_limit(
|
pub fn get_charge_limit(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |val: Option<f64>| tx.send(val).expect("get_charge_limit callback send failed");
|
let callback = move |val: Option<f64>| {
|
||||||
sender2.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::GetChargeLimit(Box::new(callback)))).expect("get_charge_limit send failed");
|
tx.send(val).expect("get_charge_limit callback send failed")
|
||||||
|
};
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Battery(BatteryMessage::GetChargeLimit(
|
||||||
|
Box::new(callback),
|
||||||
|
)))
|
||||||
|
.expect("get_charge_limit send failed");
|
||||||
rx.recv().expect("get_charge_limit callback recv failed")
|
rx.recv().expect("get_charge_limit callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |result| {
|
trans_getter: |result| super::utility::map_optional_result(Ok(result)),
|
||||||
super::utility::map_optional_result(Ok(result))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use std::sync::mpsc::{Sender, self};
|
use std::sync::mpsc::{self, Sender};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use usdpl_back::core::serdes::Primitive;
|
use usdpl_back::core::serdes::Primitive;
|
||||||
use usdpl_back::AsyncCallable;
|
use usdpl_back::AsyncCallable;
|
||||||
|
|
||||||
use crate::settings::{SettingError, SettingVariant, MinMax};
|
use crate::settings::{MinMax, SettingError, SettingVariant};
|
||||||
//use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
//use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
||||||
use super::handler::{ApiMessage, CpuMessage};
|
use super::handler::{ApiMessage, CpuMessage};
|
||||||
|
|
||||||
|
@ -12,13 +12,11 @@ pub fn max_cpus(_: super::ApiParameterType) -> super::ApiParameterType {
|
||||||
super::utility::map_result(
|
super::utility::map_result(
|
||||||
crate::settings::steam_deck::Cpus::cpu_count()
|
crate::settings::steam_deck::Cpus::cpu_count()
|
||||||
.map(|x| x as u64)
|
.map(|x| x as u64)
|
||||||
.ok_or_else(
|
.ok_or_else(|| SettingError {
|
||||||
|| SettingError {
|
msg: "Failed to parse CPU count".to_owned(),
|
||||||
msg: "Failed to parse CPU count".to_owned(),
|
setting: SettingVariant::Cpu,
|
||||||
setting: SettingVariant::Cpu,
|
}),
|
||||||
}
|
)
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate set CPU online web method
|
/// Generate set CPU online web method
|
||||||
|
@ -26,10 +24,13 @@ pub fn set_cpu_online(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |index: usize, value: bool|
|
let setter = move |index: usize, value: bool| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Cpu(CpuMessage::SetCpuOnline(index, value))).expect("set_cpu_online send failed");
|
.send(ApiMessage::Cpu(CpuMessage::SetCpuOnline(index, value)))
|
||||||
|
.expect("set_cpu_online send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||||
//let mut settings_lock = unwrap_lock(settings.lock(), "cpu");
|
//let mut settings_lock = unwrap_lock(settings.lock(), "cpu");
|
||||||
|
@ -49,10 +50,13 @@ pub fn set_cpus_online(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |values: Vec<bool>|
|
let setter = move |values: Vec<bool>| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Cpu(CpuMessage::SetCpusOnline(values))).expect("set_cpus_online send failed");
|
.send(ApiMessage::Cpu(CpuMessage::SetCpusOnline(values)))
|
||||||
|
.expect("set_cpus_online send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
let mut result = Vec::with_capacity(params_in.len());
|
let mut result = Vec::with_capacity(params_in.len());
|
||||||
let mut values = Vec::with_capacity(params_in.len());
|
let mut values = Vec::with_capacity(params_in.len());
|
||||||
|
@ -90,16 +94,19 @@ pub fn set_cpus_online(
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
pub fn set_smt(
|
pub fn set_smt(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move |smt: bool| {
|
move |smt: bool| {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |values: Vec<bool>| tx.send(values).expect("set_smt callback send failed");
|
let callback =
|
||||||
sender2.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::SetSmt(smt, Box::new(callback)))).expect("set_smt send failed");
|
move |values: Vec<bool>| tx.send(values).expect("set_smt callback send failed");
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Cpu(CpuMessage::SetSmt(smt, Box::new(callback))))
|
||||||
|
.expect("set_smt send failed");
|
||||||
rx.recv().expect("set_smt callback recv failed")
|
rx.recv().expect("set_smt callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -118,41 +125,48 @@ pub fn set_smt(
|
||||||
output.push(status.into());
|
output.push(status.into());
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_smt(
|
pub fn get_smt(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |value: bool| tx.send(value).expect("get_smt callback send failed");
|
let callback = move |value: bool| tx.send(value).expect("get_smt callback send failed");
|
||||||
sender2.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetSmt(Box::new(callback)))).expect("get_smt send failed");
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Cpu(CpuMessage::GetSmt(Box::new(callback))))
|
||||||
|
.expect("get_smt send failed");
|
||||||
rx.recv().expect("get_smt callback recv failed")
|
rx.recv().expect("get_smt callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |result| {
|
trans_getter: |result| vec![result.into()],
|
||||||
vec![result.into()]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cpus_online(
|
pub fn get_cpus_online(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |values: Vec<bool>| tx.send(values).expect("get_cpus_online callback send failed");
|
let callback = move |values: Vec<bool>| {
|
||||||
sender2.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetCpusOnline(Box::new(callback)))).expect("get_cpus_online send failed");
|
tx.send(values)
|
||||||
|
.expect("get_cpus_online callback send failed")
|
||||||
|
};
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Cpu(CpuMessage::GetCpusOnline(Box::new(
|
||||||
|
callback,
|
||||||
|
))))
|
||||||
|
.expect("get_cpus_online send failed");
|
||||||
rx.recv().expect("get_cpus_online callback recv failed")
|
rx.recv().expect("get_cpus_online callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -164,7 +178,7 @@ pub fn get_cpus_online(
|
||||||
output.push(status.into());
|
output.push(status.into());
|
||||||
}
|
}
|
||||||
output
|
output
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,25 +186,29 @@ pub fn set_clock_limits(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |index: usize, value: MinMax<u64>|
|
let setter = move |index: usize, value: MinMax<u64>| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Cpu(CpuMessage::SetClockLimits(index, Some(value)))).expect("set_clock_limits send failed");
|
.send(ApiMessage::Cpu(CpuMessage::SetClockLimits(
|
||||||
|
index,
|
||||||
|
Some(value),
|
||||||
|
)))
|
||||||
|
.expect("set_clock_limits send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||||
if let Some(&Primitive::F64(min)) = params_in.get(1) {
|
if let Some(&Primitive::F64(min)) = params_in.get(1) {
|
||||||
if let Some(&Primitive::F64(max)) = params_in.get(2) {
|
if let Some(&Primitive::F64(max)) = params_in.get(2) {
|
||||||
let safe_max = if max < min {
|
let safe_max = if max < min { min } else { max };
|
||||||
min
|
let safe_min = if min > max { max } else { min };
|
||||||
} else {
|
setter(
|
||||||
max
|
index as usize,
|
||||||
};
|
MinMax {
|
||||||
let safe_min = if min > max {
|
min: safe_min as u64,
|
||||||
max
|
max: safe_max as u64,
|
||||||
} else {
|
},
|
||||||
min
|
);
|
||||||
};
|
|
||||||
setter(index as usize, MinMax {min: safe_min as u64, max: safe_max as u64});
|
|
||||||
vec![safe_min.into(), safe_max.into()]
|
vec![safe_min.into(), safe_max.into()]
|
||||||
} else {
|
} else {
|
||||||
vec!["set_clock_limits missing parameter 2".into()]
|
vec!["set_clock_limits missing parameter 2".into()]
|
||||||
|
@ -210,8 +228,18 @@ pub fn get_clock_limits(
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let getter = move |index: usize| {
|
let getter = move |index: usize| {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |values: Option<MinMax<u64>>| tx.send(values).expect("get_clock_limits callback send failed");
|
let callback = move |values: Option<MinMax<u64>>| {
|
||||||
sender.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetClockLimits(index, Box::new(callback)))).expect("get_clock_limits send failed");
|
tx.send(values)
|
||||||
|
.expect("get_clock_limits callback send failed")
|
||||||
|
};
|
||||||
|
sender
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Cpu(CpuMessage::GetClockLimits(
|
||||||
|
index,
|
||||||
|
Box::new(callback),
|
||||||
|
)))
|
||||||
|
.expect("get_clock_limits send failed");
|
||||||
rx.recv().expect("get_clock_limits callback recv failed")
|
rx.recv().expect("get_clock_limits callback recv failed")
|
||||||
};
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
|
@ -231,10 +259,13 @@ pub fn unset_clock_limits(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |index: usize|
|
let setter = move |index: usize| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Cpu(CpuMessage::SetClockLimits(index, None))).expect("unset_clock_limits send failed");
|
.send(ApiMessage::Cpu(CpuMessage::SetClockLimits(index, None)))
|
||||||
|
.expect("unset_clock_limits send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||||
setter(index as usize);
|
setter(index as usize);
|
||||||
|
@ -249,10 +280,13 @@ pub fn set_cpu_governor(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |index: usize, governor: String|
|
let setter = move |index: usize, governor: String| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Cpu(CpuMessage::SetCpuGovernor(index, governor))).expect("set_cpu_governor send failed");
|
.send(ApiMessage::Cpu(CpuMessage::SetCpuGovernor(index, governor)))
|
||||||
|
.expect("set_cpu_governor send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||||
if let Some(Primitive::String(governor)) = params_in.get(1) {
|
if let Some(Primitive::String(governor)) = params_in.get(1) {
|
||||||
|
@ -271,10 +305,13 @@ pub fn set_cpus_governors(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |governors: Vec<String>|
|
let setter = move |governors: Vec<String>| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Cpu(CpuMessage::SetCpusGovernor(governors))).expect("set_cpus_governor send failed");
|
.send(ApiMessage::Cpu(CpuMessage::SetCpusGovernor(governors)))
|
||||||
|
.expect("set_cpus_governor send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
let mut result = Vec::with_capacity(params_in.len());
|
let mut result = Vec::with_capacity(params_in.len());
|
||||||
let mut values = Vec::with_capacity(params_in.len());
|
let mut values = Vec::with_capacity(params_in.len());
|
||||||
|
@ -298,8 +335,17 @@ pub fn get_cpu_governors(
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |values: Vec<String>| tx.send(values).expect("get_cpu_governors callback send failed");
|
let callback = move |values: Vec<String>| {
|
||||||
sender.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetCpusGovernor(Box::new(callback)))).expect("get_cpu_governors send failed");
|
tx.send(values)
|
||||||
|
.expect("get_cpu_governors callback send failed")
|
||||||
|
};
|
||||||
|
sender
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Cpu(CpuMessage::GetCpusGovernor(Box::new(
|
||||||
|
callback,
|
||||||
|
))))
|
||||||
|
.expect("get_cpu_governors send failed");
|
||||||
rx.recv().expect("get_cpu_governors callback recv failed")
|
rx.recv().expect("get_cpu_governors callback recv failed")
|
||||||
};
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::sync::mpsc::{Sender, self};
|
use std::sync::mpsc::{self, Sender};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use usdpl_back::core::serdes::Primitive;
|
use usdpl_back::core::serdes::Primitive;
|
||||||
use usdpl_back::AsyncCallable;
|
use usdpl_back::AsyncCallable;
|
||||||
|
@ -11,10 +11,13 @@ pub fn set_persistent(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |pers: bool|
|
let setter = move |pers: bool| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::General(GeneralMessage::SetPersistent(pers))).expect("set_persistent send failed");
|
.send(ApiMessage::General(GeneralMessage::SetPersistent(pers)))
|
||||||
|
.expect("set_persistent send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(&Primitive::Bool(new_val)) = params_in.get(0) {
|
if let Some(&Primitive::Bool(new_val)) = params_in.get(0) {
|
||||||
setter(new_val);
|
setter(new_val);
|
||||||
|
@ -33,13 +36,18 @@ pub fn get_persistent(
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |value: bool| tx.send(value).expect("get_persistent callback send failed");
|
let callback =
|
||||||
sender.lock().unwrap().send(ApiMessage::General(GeneralMessage::GetPersistent(Box::new(callback)))).expect("get_persistent send failed");
|
move |value: bool| tx.send(value).expect("get_persistent callback send failed");
|
||||||
|
sender
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::General(GeneralMessage::GetPersistent(
|
||||||
|
Box::new(callback),
|
||||||
|
)))
|
||||||
|
.expect("get_persistent send failed");
|
||||||
rx.recv().expect("get_persistent callback recv failed")
|
rx.recv().expect("get_persistent callback recv failed")
|
||||||
};
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| vec![getter().into()]
|
||||||
vec![getter().into()]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate load app settings from file web method
|
/// Generate load app settings from file web method
|
||||||
|
@ -47,10 +55,13 @@ pub fn load_settings(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |path: i64, name: String|
|
let setter = move |path: i64, name: String| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::LoadSettings(path, name)).expect("load_settings send failed");
|
.send(ApiMessage::LoadSettings(path, name))
|
||||||
|
.expect("load_settings send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(Primitive::F64(id)) = params_in.get(0) {
|
if let Some(Primitive::F64(id)) = params_in.get(0) {
|
||||||
if let Some(Primitive::String(name)) = params_in.get(1) {
|
if let Some(Primitive::String(name)) = params_in.get(1) {
|
||||||
|
@ -73,10 +84,13 @@ pub fn load_default_settings(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move ||
|
let setter = move || {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::LoadMainSettings).expect("load_default_settings send failed");
|
.send(ApiMessage::LoadMainSettings)
|
||||||
|
.expect("load_default_settings send failed")
|
||||||
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
setter();
|
setter();
|
||||||
vec![true.into()]
|
vec![true.into()]
|
||||||
|
@ -99,10 +113,13 @@ pub fn load_system_settings(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move ||
|
let setter = move || {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::LoadSystemSettings).expect("load_default_settings send failed");
|
.send(ApiMessage::LoadSystemSettings)
|
||||||
|
.expect("load_default_settings send failed")
|
||||||
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
setter();
|
setter();
|
||||||
vec![true.into()]
|
vec![true.into()]
|
||||||
|
@ -121,68 +138,75 @@ pub fn load_system_settings(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate get current settings name
|
/// Generate get current settings name
|
||||||
pub fn get_name(
|
pub fn get_name(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |name: String| tx.send(name).expect("get_name callback send failed");
|
let callback =
|
||||||
sender2.lock().unwrap().send(ApiMessage::General(GeneralMessage::GetCurrentProfileName(Box::new(callback)))).expect("get_name send failed");
|
move |name: String| tx.send(name).expect("get_name callback send failed");
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::General(GeneralMessage::GetCurrentProfileName(
|
||||||
|
Box::new(callback),
|
||||||
|
)))
|
||||||
|
.expect("get_name send failed");
|
||||||
rx.recv().expect("get_name callback recv failed")
|
rx.recv().expect("get_name callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |result| {
|
trans_getter: |result| vec![result.into()],
|
||||||
vec![result.into()]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate get current settings name
|
/// Generate get current settings name
|
||||||
pub fn get_path(
|
pub fn get_path(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |name: std::path::PathBuf| tx.send(name).expect("get_path callback send failed");
|
let callback = move |name: std::path::PathBuf| {
|
||||||
sender2.lock().unwrap().send(ApiMessage::General(GeneralMessage::GetPath(Box::new(callback)))).expect("get_name send failed");
|
tx.send(name).expect("get_path callback send failed")
|
||||||
|
};
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::General(GeneralMessage::GetPath(Box::new(
|
||||||
|
callback,
|
||||||
|
))))
|
||||||
|
.expect("get_name send failed");
|
||||||
rx.recv().expect("get_path callback recv failed")
|
rx.recv().expect("get_path callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |result| {
|
trans_getter: |result| vec![result.to_string_lossy().to_string().into()],
|
||||||
vec![result.to_string_lossy().to_string().into()]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate wait for all locks to be available web method
|
/// Generate wait for all locks to be available web method
|
||||||
pub fn lock_unlock_all(
|
pub fn lock_unlock_all(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |x| tx.send(x).expect("lock_unlock_all callback send failed");
|
let callback = move |x| tx.send(x).expect("lock_unlock_all callback send failed");
|
||||||
sender2.lock().unwrap().send(ApiMessage::WaitForEmptyQueue(Box::new(callback))).expect("lock_unlock_all send failed");
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::WaitForEmptyQueue(Box::new(callback)))
|
||||||
|
.expect("lock_unlock_all send failed");
|
||||||
rx.recv().expect("lock_unlock_all callback recv failed")
|
rx.recv().expect("lock_unlock_all callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |_| {
|
trans_getter: |_| vec![true.into()],
|
||||||
vec![true.into()]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,8 +217,14 @@ pub fn get_limits(
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |value: super::SettingsLimits| tx.send(value).expect("get_limits callback send failed");
|
let callback = move |value: super::SettingsLimits| {
|
||||||
sender.lock().unwrap().send(ApiMessage::GetLimits(Box::new(callback))).expect("get_limits send failed");
|
tx.send(value).expect("get_limits callback send failed")
|
||||||
|
};
|
||||||
|
sender
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::GetLimits(Box::new(callback)))
|
||||||
|
.expect("get_limits send failed");
|
||||||
rx.recv().expect("get_limits callback recv failed")
|
rx.recv().expect("get_limits callback recv failed")
|
||||||
};
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
|
@ -203,16 +233,20 @@ pub fn get_limits(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate get current driver name
|
/// Generate get current driver name
|
||||||
pub fn get_provider(
|
pub fn get_provider(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move |provider_name: String| {
|
move |provider_name: String| {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |name: crate::persist::DriverJson| tx.send(name).expect("get_provider callback send failed");
|
let callback = move |name: crate::persist::DriverJson| {
|
||||||
sender2.lock().unwrap().send(ApiMessage::GetProvider(provider_name, Box::new(callback))).expect("get_provider send failed");
|
tx.send(name).expect("get_provider callback send failed")
|
||||||
|
};
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::GetProvider(provider_name, Box::new(callback)))
|
||||||
|
.expect("get_provider send failed");
|
||||||
rx.recv().expect("get_provider callback recv failed")
|
rx.recv().expect("get_provider callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -225,9 +259,7 @@ pub fn get_provider(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |result| {
|
trans_getter: |result| vec![format!("{:?}", result).into()],
|
||||||
vec![format!("{:?}", result).into()]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,14 +309,15 @@ pub fn force_apply(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |_: ()|
|
let setter = move |_: ()| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::General(GeneralMessage::ApplyNow))
|
.send(ApiMessage::General(GeneralMessage::ApplyNow))
|
||||||
.expect("force_apply send failed");
|
.expect("force_apply send failed")
|
||||||
|
};
|
||||||
move |_params_in: super::ApiParameterType| {
|
move |_params_in: super::ApiParameterType| {
|
||||||
setter(());
|
setter(());
|
||||||
vec![true.into()]
|
vec![true.into()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::sync::mpsc::{Sender, self};
|
use std::sync::mpsc::{self, Sender};
|
||||||
use std::sync::{Mutex, Arc};
|
use std::sync::{Arc, Mutex};
|
||||||
use usdpl_back::core::serdes::Primitive;
|
use usdpl_back::core::serdes::Primitive;
|
||||||
use usdpl_back::AsyncCallable;
|
use usdpl_back::AsyncCallable;
|
||||||
|
|
||||||
|
@ -11,10 +11,13 @@ pub fn set_ppt(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |fast: u64, slow: u64|
|
let setter = move |fast: u64, slow: u64| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Gpu(GpuMessage::SetPpt(Some(fast), Some(slow)))).expect("set_ppt send failed");
|
.send(ApiMessage::Gpu(GpuMessage::SetPpt(Some(fast), Some(slow))))
|
||||||
|
.expect("set_ppt send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(&Primitive::F64(fast_ppt)) = params_in.get(0) {
|
if let Some(&Primitive::F64(fast_ppt)) = params_in.get(0) {
|
||||||
if let Some(&Primitive::F64(slow_ppt)) = params_in.get(1) {
|
if let Some(&Primitive::F64(slow_ppt)) = params_in.get(1) {
|
||||||
|
@ -29,16 +32,20 @@ pub fn set_ppt(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ppt(
|
pub fn get_ppt(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |ppt: (Option<u64>, Option<u64>)| tx.send(ppt).expect("get_ppt callback send failed");
|
let callback = move |ppt: (Option<u64>, Option<u64>)| {
|
||||||
sender2.lock().unwrap().send(ApiMessage::Gpu(GpuMessage::GetPpt(Box::new(callback)))).expect("get_ppt send failed");
|
tx.send(ppt).expect("get_ppt callback send failed")
|
||||||
|
};
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Gpu(GpuMessage::GetPpt(Box::new(callback))))
|
||||||
|
.expect("get_ppt send failed");
|
||||||
rx.recv().expect("get_ppt callback recv failed")
|
rx.recv().expect("get_ppt callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -49,7 +56,7 @@ pub fn get_ppt(
|
||||||
fast.map(|x| x.into()).unwrap_or(Primitive::Empty),
|
fast.map(|x| x.into()).unwrap_or(Primitive::Empty),
|
||||||
slow.map(|x| x.into()).unwrap_or(Primitive::Empty),
|
slow.map(|x| x.into()).unwrap_or(Primitive::Empty),
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,10 +64,13 @@ pub fn unset_ppt(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move ||
|
let setter = move || {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Gpu(GpuMessage::SetPpt(None, None))).expect("set_ppt send failed");
|
.send(ApiMessage::Gpu(GpuMessage::SetPpt(None, None)))
|
||||||
|
.expect("set_ppt send failed")
|
||||||
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
setter();
|
setter();
|
||||||
vec![true.into()]
|
vec![true.into()]
|
||||||
|
@ -71,23 +81,18 @@ pub fn set_clock_limits(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |value: MinMax<u64>|
|
let setter = move |value: MinMax<u64>| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Gpu(GpuMessage::SetClockLimits(Some(value)))).expect("set_clock_limits send failed");
|
.send(ApiMessage::Gpu(GpuMessage::SetClockLimits(Some(value))))
|
||||||
|
.expect("set_clock_limits send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(&Primitive::F64(min)) = params_in.get(0) {
|
if let Some(&Primitive::F64(min)) = params_in.get(0) {
|
||||||
if let Some(&Primitive::F64(max)) = params_in.get(1) {
|
if let Some(&Primitive::F64(max)) = params_in.get(1) {
|
||||||
let safe_max = if max < min {
|
let safe_max = if max < min { min } else { max };
|
||||||
min
|
let safe_min = if min > max { max } else { min };
|
||||||
} else {
|
|
||||||
max
|
|
||||||
};
|
|
||||||
let safe_min = if min > max {
|
|
||||||
max
|
|
||||||
} else {
|
|
||||||
min
|
|
||||||
};
|
|
||||||
setter(MinMax {
|
setter(MinMax {
|
||||||
min: safe_min as _,
|
min: safe_min as _,
|
||||||
max: safe_max as _,
|
max: safe_max as _,
|
||||||
|
@ -102,26 +107,33 @@ pub fn set_clock_limits(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_clock_limits(
|
pub fn get_clock_limits(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move|| {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |clocks: Option<MinMax<u64>>| tx.send(clocks).expect("get_clock_limits callback send failed");
|
let callback = move |clocks: Option<MinMax<u64>>| {
|
||||||
sender2.lock().unwrap().send(ApiMessage::Gpu(GpuMessage::GetClockLimits(Box::new(callback)))).expect("get_clock_limits send failed");
|
tx.send(clocks)
|
||||||
|
.expect("get_clock_limits callback send failed")
|
||||||
|
};
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Gpu(GpuMessage::GetClockLimits(Box::new(
|
||||||
|
callback,
|
||||||
|
))))
|
||||||
|
.expect("get_clock_limits send failed");
|
||||||
rx.recv().expect("get_clock_limits callback recv failed")
|
rx.recv().expect("get_clock_limits callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |clocks: Option<MinMax<u64>>| {
|
trans_getter: |clocks: Option<MinMax<u64>>| {
|
||||||
clocks.map(|x| vec![
|
clocks
|
||||||
x.min.into(), x.max.into()
|
.map(|x| vec![x.min.into(), x.max.into()])
|
||||||
]).unwrap_or_else(|| vec![Primitive::Empty, Primitive::Empty])
|
.unwrap_or_else(|| vec![Primitive::Empty, Primitive::Empty])
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,10 +141,13 @@ pub fn unset_clock_limits(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move ||
|
let setter = move || {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Gpu(GpuMessage::SetClockLimits(None))).expect("unset_clock_limits send failed");
|
.send(ApiMessage::Gpu(GpuMessage::SetClockLimits(None)))
|
||||||
|
.expect("unset_clock_limits send failed")
|
||||||
|
};
|
||||||
move |_: super::ApiParameterType| {
|
move |_: super::ApiParameterType| {
|
||||||
setter();
|
setter();
|
||||||
vec![true.into()]
|
vec![true.into()]
|
||||||
|
@ -143,10 +158,13 @@ pub fn set_slow_memory(
|
||||||
sender: Sender<ApiMessage>,
|
sender: Sender<ApiMessage>,
|
||||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||||
let setter = move |value: bool|
|
let setter = move |value: bool| {
|
||||||
sender.lock()
|
sender
|
||||||
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ApiMessage::Gpu(GpuMessage::SetSlowMemory(value))).expect("unset_clock_limits send failed");
|
.send(ApiMessage::Gpu(GpuMessage::SetSlowMemory(value)))
|
||||||
|
.expect("unset_clock_limits send failed")
|
||||||
|
};
|
||||||
move |params_in: super::ApiParameterType| {
|
move |params_in: super::ApiParameterType| {
|
||||||
if let Some(&Primitive::Bool(memory_is_slow)) = params_in.get(0) {
|
if let Some(&Primitive::Bool(memory_is_slow)) = params_in.get(0) {
|
||||||
setter(memory_is_slow);
|
setter(memory_is_slow);
|
||||||
|
@ -157,23 +175,28 @@ pub fn set_slow_memory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_slow_memory(
|
pub fn get_slow_memory(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||||
sender: Sender<ApiMessage>,
|
|
||||||
) -> impl AsyncCallable {
|
|
||||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||||
let getter = move || {
|
let getter = move || {
|
||||||
let sender2 = sender.clone();
|
let sender2 = sender.clone();
|
||||||
move || {
|
move || {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
let callback = move |value: bool| tx.send(value).expect("get_slow_memory callback send failed");
|
let callback = move |value: bool| {
|
||||||
sender2.lock().unwrap().send(ApiMessage::Gpu(GpuMessage::GetSlowMemory(Box::new(callback)))).expect("get_slow_memory send failed");
|
tx.send(value)
|
||||||
|
.expect("get_slow_memory callback send failed")
|
||||||
|
};
|
||||||
|
sender2
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.send(ApiMessage::Gpu(GpuMessage::GetSlowMemory(Box::new(
|
||||||
|
callback,
|
||||||
|
))))
|
||||||
|
.expect("get_slow_memory send failed");
|
||||||
rx.recv().expect("get_slow_memory callback recv failed")
|
rx.recv().expect("get_slow_memory callback recv failed")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
super::async_utils::AsyncIshGetter {
|
super::async_utils::AsyncIshGetter {
|
||||||
set_get: getter,
|
set_get: getter,
|
||||||
trans_getter: |value: bool| {
|
trans_getter: |value: bool| vec![value.into()],
|
||||||
vec![value.into()]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use std::sync::mpsc::{self, Receiver, Sender};
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
use std::sync::mpsc::{self, Receiver, Sender};
|
||||||
|
|
||||||
use crate::settings::{Settings, TCpus, TGpu, TBattery, TGeneral, OnSet, OnResume, MinMax, OnPowerEvent, PowerMode};
|
|
||||||
use crate::persist::SettingsJson;
|
use crate::persist::SettingsJson;
|
||||||
|
use crate::settings::{
|
||||||
|
MinMax, OnPowerEvent, OnResume, OnSet, PowerMode, Settings, TBattery, TCpus, TGeneral, TGpu,
|
||||||
|
};
|
||||||
use crate::utility::unwrap_maybe_fatal;
|
use crate::utility::unwrap_maybe_fatal;
|
||||||
|
|
||||||
type Callback<T> = Box<dyn FnOnce(T) + Send>;
|
type Callback<T> = Box<dyn FnOnce(T) + Send>;
|
||||||
|
@ -84,12 +86,14 @@ impl CpuMessage {
|
||||||
// NOTE: "cpu" refers to the Linux kernel definition of a CPU, which is actually a hardware thread
|
// NOTE: "cpu" refers to the Linux kernel definition of a CPU, which is actually a hardware thread
|
||||||
// not to be confused with a CPU chip, which usually has multiple hardware threads (cpu cores/threads) in the chip
|
// not to be confused with a CPU chip, which usually has multiple hardware threads (cpu cores/threads) in the chip
|
||||||
match self {
|
match self {
|
||||||
Self::SetCpuOnline(index, status) => {settings.cpus().get_mut(index).map(|c| *c.online() = status);},
|
Self::SetCpuOnline(index, status) => {
|
||||||
|
settings.cpus().get_mut(index).map(|c| *c.online() = status);
|
||||||
|
}
|
||||||
Self::SetCpusOnline(cpus) => {
|
Self::SetCpusOnline(cpus) => {
|
||||||
for i in 0..cpus.len() {
|
for i in 0..cpus.len() {
|
||||||
settings.cpus().get_mut(i).map(|c| *c.online() = cpus[i]);
|
settings.cpus().get_mut(i).map(|c| *c.online() = cpus[i]);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Self::SetSmt(status, cb) => {
|
Self::SetSmt(status, cb) => {
|
||||||
if *settings.smt() == status {
|
if *settings.smt() == status {
|
||||||
// already set, do nothing
|
// already set, do nothing
|
||||||
|
@ -105,8 +109,8 @@ impl CpuMessage {
|
||||||
// for 1c:2t configs (i.e. anything with SMT2), the highest cpu core is always odd
|
// for 1c:2t configs (i.e. anything with SMT2), the highest cpu core is always odd
|
||||||
// (e.g. 4c8t has CPUs 0-7, inclusive)
|
// (e.g. 4c8t has CPUs 0-7, inclusive)
|
||||||
// this enables the """fake""" (i.e. odd) cpu which is disabled when SMT is set off
|
// this enables the """fake""" (i.e. odd) cpu which is disabled when SMT is set off
|
||||||
if i % 2 == 0 && i+1 != cpu_count {
|
if i % 2 == 0 && i + 1 != cpu_count {
|
||||||
*(settings.cpus()[i+1].online()) = true;
|
*(settings.cpus()[i + 1].online()) = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*settings.cpus()[i].online() = should_be_online;
|
*settings.cpus()[i].online() = should_be_online;
|
||||||
|
@ -118,7 +122,8 @@ impl CpuMessage {
|
||||||
for i in 0..settings.len() {
|
for i in 0..settings.len() {
|
||||||
// this disables the """fake""" (odd) cpu for appearances' sake
|
// this disables the """fake""" (odd) cpu for appearances' sake
|
||||||
// the kernel will automatically disable that same cpu when SMT is changed
|
// the kernel will automatically disable that same cpu when SMT is changed
|
||||||
*settings.cpus()[i].online() = *settings.cpus()[i].online() && (status || i % 2 == 0);
|
*settings.cpus()[i].online() =
|
||||||
|
*settings.cpus()[i].online() && (status || i % 2 == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut result = Vec::with_capacity(settings.len());
|
let mut result = Vec::with_capacity(settings.len());
|
||||||
|
@ -126,25 +131,40 @@ impl CpuMessage {
|
||||||
result.push(*settings.cpus()[i].online());
|
result.push(*settings.cpus()[i].online());
|
||||||
}
|
}
|
||||||
cb(result);
|
cb(result);
|
||||||
},
|
}
|
||||||
Self::GetSmt(cb) => {
|
Self::GetSmt(cb) => {
|
||||||
cb(*settings.smt());
|
cb(*settings.smt());
|
||||||
},
|
}
|
||||||
Self::GetCpusOnline(cb) => {
|
Self::GetCpusOnline(cb) => {
|
||||||
let mut result = Vec::with_capacity(settings.len());
|
let mut result = Vec::with_capacity(settings.len());
|
||||||
for cpu in settings.cpus() {
|
for cpu in settings.cpus() {
|
||||||
result.push(*cpu.online());
|
result.push(*cpu.online());
|
||||||
}
|
}
|
||||||
cb(result);
|
cb(result);
|
||||||
},
|
}
|
||||||
Self::SetClockLimits(index, clocks) => {settings.cpus().get_mut(index).map(|c| c.clock_limits(clocks));},
|
Self::SetClockLimits(index, clocks) => {
|
||||||
Self::GetClockLimits(index, cb) => {settings.cpus().get(index).map(|c| cb(c.get_clock_limits().map(|x| x.to_owned())));},
|
settings
|
||||||
Self::SetCpuGovernor(index, gov) => {settings.cpus().get_mut(index).map(|c| c.governor(gov));},
|
.cpus()
|
||||||
|
.get_mut(index)
|
||||||
|
.map(|c| c.clock_limits(clocks));
|
||||||
|
}
|
||||||
|
Self::GetClockLimits(index, cb) => {
|
||||||
|
settings
|
||||||
|
.cpus()
|
||||||
|
.get(index)
|
||||||
|
.map(|c| cb(c.get_clock_limits().map(|x| x.to_owned())));
|
||||||
|
}
|
||||||
|
Self::SetCpuGovernor(index, gov) => {
|
||||||
|
settings.cpus().get_mut(index).map(|c| c.governor(gov));
|
||||||
|
}
|
||||||
Self::SetCpusGovernor(govs) => {
|
Self::SetCpusGovernor(govs) => {
|
||||||
for i in 0..govs.len() {
|
for i in 0..govs.len() {
|
||||||
settings.cpus().get_mut(i).map(|c| c.governor(govs[i].clone()));
|
settings
|
||||||
|
.cpus()
|
||||||
|
.get_mut(i)
|
||||||
|
.map(|c| c.governor(govs[i].clone()));
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Self::GetCpusGovernor(cb) => {
|
Self::GetCpusGovernor(cb) => {
|
||||||
let mut result = Vec::with_capacity(settings.len());
|
let mut result = Vec::with_capacity(settings.len());
|
||||||
for cpu in settings.cpus() {
|
for cpu in settings.cpus() {
|
||||||
|
@ -158,13 +178,14 @@ impl CpuMessage {
|
||||||
|
|
||||||
/// Message instructs the driver to modify settings
|
/// Message instructs the driver to modify settings
|
||||||
fn is_modify(&self) -> bool {
|
fn is_modify(&self) -> bool {
|
||||||
matches!(self,
|
matches!(
|
||||||
|
self,
|
||||||
Self::SetCpuOnline(_, _)
|
Self::SetCpuOnline(_, _)
|
||||||
| Self::SetCpusOnline(_)
|
| Self::SetCpusOnline(_)
|
||||||
| Self::SetSmt(_, _)
|
| Self::SetSmt(_, _)
|
||||||
| Self::SetClockLimits(_, _)
|
| Self::SetClockLimits(_, _)
|
||||||
| Self::SetCpuGovernor(_, _)
|
| Self::SetCpuGovernor(_, _)
|
||||||
| Self::SetCpusGovernor(_)
|
| Self::SetCpusGovernor(_)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -193,10 +214,9 @@ impl GpuMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_modify(&self) -> bool {
|
fn is_modify(&self) -> bool {
|
||||||
matches!(self,
|
matches!(
|
||||||
Self::SetPpt(_, _)
|
self,
|
||||||
| Self::SetClockLimits(_)
|
Self::SetPpt(_, _) | Self::SetClockLimits(_) | Self::SetSlowMemory(_)
|
||||||
| Self::SetSlowMemory(_)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,7 +237,7 @@ impl GeneralMessage {
|
||||||
Self::GetPersistent(cb) => cb(*settings.persistent()),
|
Self::GetPersistent(cb) => cb(*settings.persistent()),
|
||||||
Self::GetCurrentProfileName(cb) => cb(settings.get_name().to_owned()),
|
Self::GetCurrentProfileName(cb) => cb(settings.get_name().to_owned()),
|
||||||
Self::GetPath(cb) => cb(settings.get_path().to_owned()),
|
Self::GetPath(cb) => cb(settings.get_path().to_owned()),
|
||||||
Self::ApplyNow => {},
|
Self::ApplyNow => {}
|
||||||
}
|
}
|
||||||
dirty
|
dirty
|
||||||
}
|
}
|
||||||
|
@ -234,7 +254,9 @@ pub struct ApiMessageHandler {
|
||||||
|
|
||||||
fn print_errors(call_name: &str, errors: Vec<crate::settings::SettingError>) {
|
fn print_errors(call_name: &str, errors: Vec<crate::settings::SettingError>) {
|
||||||
let mut err_list = String::new();
|
let mut err_list = String::new();
|
||||||
errors.iter().for_each(|e| write!(err_list, "\t{},\n", e).unwrap_or(()));
|
errors
|
||||||
|
.iter()
|
||||||
|
.for_each(|e| write!(err_list, "\t{},\n", e).unwrap_or(()));
|
||||||
log::error!("Settings {}() err:\n{}", call_name, err_list);
|
log::error!("Settings {}() err:\n{}", call_name, err_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +270,7 @@ impl ApiMessageHandler {
|
||||||
}
|
}
|
||||||
if dirty || dirty_echo {
|
if dirty || dirty_echo {
|
||||||
dirty_echo = dirty; // echo only once
|
dirty_echo = dirty; // echo only once
|
||||||
// run on_set
|
// run on_set
|
||||||
if let Err(e) = settings.on_set() {
|
if let Err(e) = settings.on_set() {
|
||||||
print_errors("on_set", e);
|
print_errors("on_set", e);
|
||||||
}
|
}
|
||||||
|
@ -259,8 +281,8 @@ impl ApiMessageHandler {
|
||||||
// save
|
// save
|
||||||
log::debug!("api_worker is saving...");
|
log::debug!("api_worker is saving...");
|
||||||
let is_persistent = *settings.general.persistent();
|
let is_persistent = *settings.general.persistent();
|
||||||
let save_path = crate::utility::settings_dir()
|
let save_path =
|
||||||
.join(settings.general.get_path().clone());
|
crate::utility::settings_dir().join(settings.general.get_path().clone());
|
||||||
if is_persistent {
|
if is_persistent {
|
||||||
let settings_clone = settings.json();
|
let settings_clone = settings.json();
|
||||||
let save_json: SettingsJson = settings_clone.into();
|
let save_json: SettingsJson = settings_clone.into();
|
||||||
|
@ -272,7 +294,11 @@ impl ApiMessageHandler {
|
||||||
} else {
|
} else {
|
||||||
if save_path.exists() {
|
if save_path.exists() {
|
||||||
if let Err(e) = std::fs::remove_file(&save_path) {
|
if let Err(e) = std::fs::remove_file(&save_path) {
|
||||||
log::warn!("Failed to delete persistent settings file {}: {}", save_path.display(), e);
|
log::warn!(
|
||||||
|
"Failed to delete persistent settings file {}: {}",
|
||||||
|
save_path.display(),
|
||||||
|
e
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
log::debug!("Deleted persistent settings file {}", save_path.display());
|
log::debug!("Deleted persistent settings file {}", save_path.display());
|
||||||
}
|
}
|
||||||
|
@ -333,7 +359,7 @@ impl ApiMessageHandler {
|
||||||
ApiMessage::WaitForEmptyQueue(callback) => {
|
ApiMessage::WaitForEmptyQueue(callback) => {
|
||||||
self.on_empty.push(callback);
|
self.on_empty.push(callback);
|
||||||
false
|
false
|
||||||
},
|
}
|
||||||
ApiMessage::LoadSettings(id, name) => {
|
ApiMessage::LoadSettings(id, name) => {
|
||||||
let path = format!("{}.json", id);
|
let path = format!("{}.json", id);
|
||||||
match settings.load_file(path.into(), name, false) {
|
match settings.load_file(path.into(), name, false) {
|
||||||
|
@ -346,7 +372,7 @@ impl ApiMessageHandler {
|
||||||
match settings.load_file(
|
match settings.load_file(
|
||||||
crate::consts::DEFAULT_SETTINGS_FILE.into(),
|
crate::consts::DEFAULT_SETTINGS_FILE.into(),
|
||||||
crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
||||||
true
|
true,
|
||||||
) {
|
) {
|
||||||
Ok(success) => log::info!("Loaded main settings file? {}", success),
|
Ok(success) => log::info!("Loaded main settings file? {}", success),
|
||||||
Err(e) => log::warn!("Load file err: {}", e),
|
Err(e) => log::warn!("Load file err: {}", e),
|
||||||
|
@ -356,7 +382,7 @@ impl ApiMessageHandler {
|
||||||
ApiMessage::LoadSystemSettings => {
|
ApiMessage::LoadSystemSettings => {
|
||||||
settings.load_system_default(settings.general.get_name().to_owned());
|
settings.load_system_default(settings.general.get_name().to_owned());
|
||||||
true
|
true
|
||||||
},
|
}
|
||||||
ApiMessage::GetLimits(cb) => {
|
ApiMessage::GetLimits(cb) => {
|
||||||
cb(super::SettingsLimits {
|
cb(super::SettingsLimits {
|
||||||
battery: settings.battery.limits(),
|
battery: settings.battery.limits(),
|
||||||
|
@ -365,7 +391,7 @@ impl ApiMessageHandler {
|
||||||
general: settings.general.limits(),
|
general: settings.general.limits(),
|
||||||
});
|
});
|
||||||
false
|
false
|
||||||
},
|
}
|
||||||
ApiMessage::GetProvider(name, cb) => {
|
ApiMessage::GetProvider(name, cb) => {
|
||||||
cb(match &name as &str {
|
cb(match &name as &str {
|
||||||
"battery" => settings.battery.provider(),
|
"battery" => settings.battery.provider(),
|
||||||
|
@ -380,9 +406,12 @@ impl ApiMessageHandler {
|
||||||
|
|
||||||
pub fn new() -> (Self, Sender<ApiMessage>) {
|
pub fn new() -> (Self, Sender<ApiMessage>) {
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
(Self {
|
(
|
||||||
intake: rx,
|
Self {
|
||||||
on_empty: Vec::with_capacity(4),
|
intake: rx,
|
||||||
}, tx)
|
on_empty: Vec::with_capacity(4),
|
||||||
|
},
|
||||||
|
tx,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
mod api_types;
|
mod api_types;
|
||||||
|
mod async_utils;
|
||||||
pub mod battery;
|
pub mod battery;
|
||||||
pub mod cpu;
|
pub mod cpu;
|
||||||
pub mod general;
|
pub mod general;
|
||||||
pub mod gpu;
|
pub mod gpu;
|
||||||
pub mod handler;
|
pub mod handler;
|
||||||
mod async_utils;
|
|
||||||
mod utility;
|
mod utility;
|
||||||
|
|
||||||
pub(super) type ApiParameterType = Vec<usdpl_back::core::serdes::Primitive>;
|
pub(super) type ApiParameterType = Vec<usdpl_back::core::serdes::Primitive>;
|
||||||
|
|
|
@ -10,12 +10,14 @@ pub fn map_result<T: Into<Primitive>>(result: Result<T, SettingError>) -> super:
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::debug!("Mapping error to primitive: {}", e);
|
log::debug!("Mapping error to primitive: {}", e);
|
||||||
vec![e.msg.into()]
|
vec![e.msg.into()]
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn map_optional_result<T: Into<Primitive>>(result: Result<Option<T>, SettingError>) -> super::ApiParameterType {
|
pub fn map_optional_result<T: Into<Primitive>>(
|
||||||
|
result: Result<Option<T>, SettingError>,
|
||||||
|
) -> super::ApiParameterType {
|
||||||
match result {
|
match result {
|
||||||
Ok(val) => match val {
|
Ok(val) => match val {
|
||||||
Some(val) => vec![val.into()],
|
Some(val) => vec![val.into()],
|
||||||
|
@ -24,7 +26,7 @@ pub fn map_optional_result<T: Into<Primitive>>(result: Result<Option<T>, Setting
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::debug!("Mapping error to primitive: {}", e);
|
log::debug!("Mapping error to primitive: {}", e);
|
||||||
vec![e.msg.into()]
|
vec![e.msg.into()]
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,17 +22,18 @@ fn main() -> Result<(), ()> {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let log_filepath = usdpl_back::api::dirs::home()
|
let log_filepath = usdpl_back::api::dirs::home()
|
||||||
.unwrap_or_else(|| "/tmp/".into())
|
.unwrap_or_else(|| "/tmp/".into())
|
||||||
.join(PACKAGE_NAME.to_owned()+".log");
|
.join(PACKAGE_NAME.to_owned() + ".log");
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
let log_filepath = std::path::Path::new("/tmp").join(format!("{}.log", PACKAGE_NAME));
|
let log_filepath = std::path::Path::new("/tmp").join(format!("{}.log", PACKAGE_NAME));
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let old_log_filepath = usdpl_back::api::dirs::home()
|
let old_log_filepath = usdpl_back::api::dirs::home()
|
||||||
.unwrap_or_else(|| "/tmp/".into())
|
.unwrap_or_else(|| "/tmp/".into())
|
||||||
.join(PACKAGE_NAME.to_owned()+".log.old");
|
.join(PACKAGE_NAME.to_owned() + ".log.old");
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
if std::path::Path::new(&log_filepath).exists() {
|
if std::path::Path::new(&log_filepath).exists() {
|
||||||
std::fs::copy(&log_filepath, &old_log_filepath).expect("Unable to increment logs. Do you have write permissions?");
|
std::fs::copy(&log_filepath, &old_log_filepath)
|
||||||
|
.expect("Unable to increment logs. Do you have write permissions?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WriteLogger::init(
|
WriteLogger::init(
|
||||||
|
@ -53,8 +54,14 @@ fn main() -> Result<(), ()> {
|
||||||
println!("Logging to: {:?}", log_filepath);
|
println!("Logging to: {:?}", log_filepath);
|
||||||
log::info!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION);
|
log::info!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION);
|
||||||
println!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION);
|
println!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION);
|
||||||
log::info!("Current dir `{}`", std::env::current_dir().unwrap().display());
|
log::info!(
|
||||||
println!("Current dir `{}`", std::env::current_dir().unwrap().display());
|
"Current dir `{}`",
|
||||||
|
std::env::current_dir().unwrap().display()
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"Current dir `{}`",
|
||||||
|
std::env::current_dir().unwrap().display()
|
||||||
|
);
|
||||||
|
|
||||||
log::info!("home dir: {:?}", usdpl_back::api::dirs::home());
|
log::info!("home dir: {:?}", usdpl_back::api::dirs::home());
|
||||||
|
|
||||||
|
@ -66,11 +73,20 @@ fn main() -> Result<(), ()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let _limits_handle = crate::settings::limits_worker_spawn();
|
let _limits_handle = crate::settings::limits_worker_spawn();
|
||||||
log::info!("Detected device automatically, starting with driver: {:?} (This can be overriden)", crate::settings::auto_detect_provider());
|
log::info!(
|
||||||
|
"Detected device automatically, starting with driver: {:?} (This can be overriden)",
|
||||||
|
crate::settings::auto_detect_provider()
|
||||||
|
);
|
||||||
|
|
||||||
let mut loaded_settings = persist::SettingsJson::open(utility::settings_dir().join(DEFAULT_SETTINGS_FILE))
|
let mut loaded_settings =
|
||||||
.map(|settings| settings::Settings::from_json(settings, DEFAULT_SETTINGS_FILE.into()))
|
persist::SettingsJson::open(utility::settings_dir().join(DEFAULT_SETTINGS_FILE))
|
||||||
.unwrap_or_else(|_| settings::Settings::system_default(DEFAULT_SETTINGS_FILE.into(), DEFAULT_SETTINGS_NAME.into()));
|
.map(|settings| settings::Settings::from_json(settings, DEFAULT_SETTINGS_FILE.into()))
|
||||||
|
.unwrap_or_else(|_| {
|
||||||
|
settings::Settings::system_default(
|
||||||
|
DEFAULT_SETTINGS_FILE.into(),
|
||||||
|
DEFAULT_SETTINGS_NAME.into(),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
log::debug!("Settings: {:?}", loaded_settings);
|
log::debug!("Settings: {:?}", loaded_settings);
|
||||||
|
|
||||||
|
@ -83,19 +99,33 @@ fn main() -> Result<(), ()> {
|
||||||
let instance = Instance::new(PORT)
|
let instance = Instance::new(PORT)
|
||||||
.register("V_INFO", |_: Vec<Primitive>| {
|
.register("V_INFO", |_: Vec<Primitive>| {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{vec![format!("v{}-dbg", PACKAGE_VERSION).into()]}
|
{
|
||||||
|
vec![format!("v{}-dbg", PACKAGE_VERSION).into()]
|
||||||
|
}
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
{vec![format!("v{}-rls", PACKAGE_VERSION).into()]}
|
{
|
||||||
})
|
vec![format!("v{}-rls", PACKAGE_VERSION).into()]
|
||||||
.register("NAME", |_: Vec<Primitive>| {
|
}
|
||||||
vec![PACKAGE_NAME.into()]
|
|
||||||
})
|
})
|
||||||
|
.register("NAME", |_: Vec<Primitive>| vec![PACKAGE_NAME.into()])
|
||||||
.register("LOG", api::general::log_it())
|
.register("LOG", api::general::log_it())
|
||||||
// battery API functions
|
// battery API functions
|
||||||
.register_async("BATTERY_current_now", api::battery::current_now(api_sender.clone()))
|
.register_async(
|
||||||
.register_async("BATTERY_charge_now", api::battery::charge_now(api_sender.clone()))
|
"BATTERY_current_now",
|
||||||
.register_async("BATTERY_charge_full", api::battery::charge_full(api_sender.clone()))
|
api::battery::current_now(api_sender.clone()),
|
||||||
.register_async("BATTERY_charge_design", api::battery::charge_design(api_sender.clone()))
|
)
|
||||||
|
.register_async(
|
||||||
|
"BATTERY_charge_now",
|
||||||
|
api::battery::charge_now(api_sender.clone()),
|
||||||
|
)
|
||||||
|
.register_async(
|
||||||
|
"BATTERY_charge_full",
|
||||||
|
api::battery::charge_full(api_sender.clone()),
|
||||||
|
)
|
||||||
|
.register_async(
|
||||||
|
"BATTERY_charge_design",
|
||||||
|
api::battery::charge_design(api_sender.clone()),
|
||||||
|
)
|
||||||
.register(
|
.register(
|
||||||
"BATTERY_set_charge_rate",
|
"BATTERY_set_charge_rate",
|
||||||
api::battery::set_charge_rate(api_sender.clone()),
|
api::battery::set_charge_rate(api_sender.clone()),
|
||||||
|
@ -136,138 +166,124 @@ fn main() -> Result<(), ()> {
|
||||||
.register("CPU_count", api::cpu::max_cpus)
|
.register("CPU_count", api::cpu::max_cpus)
|
||||||
.register(
|
.register(
|
||||||
"CPU_set_online",
|
"CPU_set_online",
|
||||||
api::cpu::set_cpu_online(api_sender.clone())
|
api::cpu::set_cpu_online(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_set_onlines",
|
"CPU_set_onlines",
|
||||||
api::cpu::set_cpus_online(api_sender.clone())
|
api::cpu::set_cpus_online(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register_async(
|
.register_async(
|
||||||
"CPU_get_onlines",
|
"CPU_get_onlines",
|
||||||
api::cpu::get_cpus_online(api_sender.clone())
|
api::cpu::get_cpus_online(api_sender.clone()),
|
||||||
)
|
|
||||||
.register_async(
|
|
||||||
"CPU_set_smt",
|
|
||||||
api::cpu::set_smt(api_sender.clone())
|
|
||||||
)
|
|
||||||
.register_async(
|
|
||||||
"CPU_get_smt",
|
|
||||||
api::cpu::get_smt(api_sender.clone())
|
|
||||||
)
|
)
|
||||||
|
.register_async("CPU_set_smt", api::cpu::set_smt(api_sender.clone()))
|
||||||
|
.register_async("CPU_get_smt", api::cpu::get_smt(api_sender.clone()))
|
||||||
.register(
|
.register(
|
||||||
"CPU_set_clock_limits",
|
"CPU_set_clock_limits",
|
||||||
api::cpu::set_clock_limits(api_sender.clone())
|
api::cpu::set_clock_limits(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_get_clock_limits",
|
"CPU_get_clock_limits",
|
||||||
api::cpu::get_clock_limits(api_sender.clone())
|
api::cpu::get_clock_limits(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_unset_clock_limits",
|
"CPU_unset_clock_limits",
|
||||||
api::cpu::unset_clock_limits(api_sender.clone())
|
api::cpu::unset_clock_limits(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_set_governor",
|
"CPU_set_governor",
|
||||||
api::cpu::set_cpu_governor(api_sender.clone())
|
api::cpu::set_cpu_governor(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_set_governors",
|
"CPU_set_governors",
|
||||||
api::cpu::set_cpus_governors(api_sender.clone())
|
api::cpu::set_cpus_governors(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"CPU_get_governors",
|
"CPU_get_governors",
|
||||||
api::cpu::get_cpu_governors(api_sender.clone())
|
api::cpu::get_cpu_governors(api_sender.clone()),
|
||||||
)
|
)
|
||||||
// gpu API functions
|
// gpu API functions
|
||||||
.register(
|
.register("GPU_set_ppt", api::gpu::set_ppt(api_sender.clone()))
|
||||||
"GPU_set_ppt",
|
.register_async("GPU_get_ppt", api::gpu::get_ppt(api_sender.clone()))
|
||||||
api::gpu::set_ppt(api_sender.clone())
|
.register("GPU_unset_ppt", api::gpu::unset_ppt(api_sender.clone()))
|
||||||
)
|
|
||||||
.register_async(
|
|
||||||
"GPU_get_ppt",
|
|
||||||
api::gpu::get_ppt(api_sender.clone())
|
|
||||||
)
|
|
||||||
.register(
|
|
||||||
"GPU_unset_ppt",
|
|
||||||
api::gpu::unset_ppt(api_sender.clone())
|
|
||||||
)
|
|
||||||
.register(
|
.register(
|
||||||
"GPU_set_clock_limits",
|
"GPU_set_clock_limits",
|
||||||
api::gpu::set_clock_limits(api_sender.clone())
|
api::gpu::set_clock_limits(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register_async(
|
.register_async(
|
||||||
"GPU_get_clock_limits",
|
"GPU_get_clock_limits",
|
||||||
api::gpu::get_clock_limits(api_sender.clone())
|
api::gpu::get_clock_limits(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GPU_unset_clock_limits",
|
"GPU_unset_clock_limits",
|
||||||
api::gpu::unset_clock_limits(api_sender.clone())
|
api::gpu::unset_clock_limits(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GPU_set_slow_memory",
|
"GPU_set_slow_memory",
|
||||||
api::gpu::set_slow_memory(api_sender.clone())
|
api::gpu::set_slow_memory(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register_async(
|
.register_async(
|
||||||
"GPU_get_slow_memory",
|
"GPU_get_slow_memory",
|
||||||
api::gpu::get_slow_memory(api_sender.clone())
|
api::gpu::get_slow_memory(api_sender.clone()),
|
||||||
)
|
)
|
||||||
// general API functions
|
// general API functions
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_set_persistent",
|
"GENERAL_set_persistent",
|
||||||
api::general::set_persistent(api_sender.clone())
|
api::general::set_persistent(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_get_persistent",
|
"GENERAL_get_persistent",
|
||||||
api::general::get_persistent(api_sender.clone())
|
api::general::get_persistent(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_load_settings",
|
"GENERAL_load_settings",
|
||||||
api::general::load_settings(api_sender.clone())
|
api::general::load_settings(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_load_default_settings",
|
"GENERAL_load_default_settings",
|
||||||
api::general::load_default_settings(api_sender.clone())
|
api::general::load_default_settings(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_load_system_settings",
|
"GENERAL_load_system_settings",
|
||||||
api::general::load_system_settings(api_sender.clone())
|
api::general::load_system_settings(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register_async(
|
.register_async(
|
||||||
"GENERAL_get_name",
|
"GENERAL_get_name",
|
||||||
api::general::get_name(api_sender.clone())
|
api::general::get_name(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register_async(
|
.register_async(
|
||||||
"GENERAL_get_path",
|
"GENERAL_get_path",
|
||||||
api::general::get_path(api_sender.clone())
|
api::general::get_path(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register_async(
|
.register_async(
|
||||||
"GENERAL_wait_for_unlocks",
|
"GENERAL_wait_for_unlocks",
|
||||||
api::general::lock_unlock_all(api_sender.clone())
|
api::general::lock_unlock_all(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register_blocking(
|
.register_blocking(
|
||||||
"GENERAL_get_limits",
|
"GENERAL_get_limits",
|
||||||
api::general::get_limits(api_sender.clone())
|
api::general::get_limits(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register_async(
|
.register_async(
|
||||||
"GENERAL_get_provider",
|
"GENERAL_get_provider",
|
||||||
api::general::get_provider(api_sender.clone())
|
api::general::get_provider(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register("GENERAL_idk", api::general::gunter)
|
.register("GENERAL_idk", api::general::gunter)
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_apply_now",
|
"GENERAL_apply_now",
|
||||||
api::general::force_apply(api_sender.clone())
|
api::general::force_apply(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_on_pluggedin",
|
"GENERAL_on_pluggedin",
|
||||||
api::battery::on_plugged(api_sender.clone())
|
api::battery::on_plugged(api_sender.clone()),
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
"GENERAL_on_unplugged",
|
"GENERAL_on_unplugged",
|
||||||
api::battery::on_unplugged(api_sender.clone())
|
api::battery::on_unplugged(api_sender.clone()),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Err(e) = loaded_settings.on_set() {
|
if let Err(e) = loaded_settings.on_set() {
|
||||||
e.iter().for_each(|e| log::error!("Startup Settings.on_set() error: {}", e));
|
e.iter()
|
||||||
|
.for_each(|e| log::error!("Startup Settings.on_set() error: {}", e));
|
||||||
} else {
|
} else {
|
||||||
log::info!("Startup Settings.on_set() success");
|
log::info!("Startup Settings.on_set() success");
|
||||||
}
|
}
|
||||||
|
@ -278,6 +294,5 @@ fn main() -> Result<(), ()> {
|
||||||
|
|
||||||
api_worker::spawn(loaded_settings, api_handler);
|
api_worker::spawn(loaded_settings, api_handler);
|
||||||
|
|
||||||
instance
|
instance.run_blocking()
|
||||||
.run_blocking()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::default::Default;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::JsonError;
|
use super::JsonError;
|
||||||
use super::{BatteryJson, CpuJson, GpuJson, DriverJson};
|
use super::{BatteryJson, CpuJson, DriverJson, GpuJson};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct SettingsJson {
|
pub struct SettingsJson {
|
||||||
|
|
|
@ -5,7 +5,7 @@ mod error;
|
||||||
mod general;
|
mod general;
|
||||||
mod gpu;
|
mod gpu;
|
||||||
|
|
||||||
pub use battery::{BatteryJson, BatteryEventJson};
|
pub use battery::{BatteryEventJson, BatteryJson};
|
||||||
pub use cpu::CpuJson;
|
pub use cpu::CpuJson;
|
||||||
pub use driver::DriverJson;
|
pub use driver::DriverJson;
|
||||||
pub use general::{MinMaxJson, SettingsJson};
|
pub use general::{MinMaxJson, SettingsJson};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
use std::sync::mpsc::Sender;
|
||||||
use std::thread::{self, JoinHandle};
|
use std::thread::{self, JoinHandle};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
use crate::api::handler::ApiMessage;
|
use crate::api::handler::ApiMessage;
|
||||||
//use crate::utility::unwrap_maybe_fatal;
|
//use crate::utility::unwrap_maybe_fatal;
|
||||||
|
@ -11,7 +11,9 @@ pub fn spawn(sender: Sender<ApiMessage>) -> JoinHandle<()> {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
log::info!("power_worker starting...");
|
log::info!("power_worker starting...");
|
||||||
loop {
|
loop {
|
||||||
sender.send(ApiMessage::PowerVibeCheck).expect("power_worker send failed");
|
sender
|
||||||
|
.send(ApiMessage::PowerVibeCheck)
|
||||||
|
.expect("power_worker send failed");
|
||||||
thread::sleep(PERIOD);
|
thread::sleep(PERIOD);
|
||||||
}
|
}
|
||||||
//log::warn!("resume_worker completed!");
|
//log::warn!("resume_worker completed!");
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
use std::sync::mpsc::Sender;
|
||||||
use std::thread::{self, JoinHandle};
|
use std::thread::{self, JoinHandle};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use std::sync::mpsc::Sender;
|
|
||||||
|
|
||||||
use crate::api::handler::ApiMessage;
|
use crate::api::handler::ApiMessage;
|
||||||
//use crate::utility::unwrap_maybe_fatal;
|
//use crate::utility::unwrap_maybe_fatal;
|
||||||
|
@ -11,7 +11,7 @@ pub fn spawn(sender: Sender<ApiMessage>) -> JoinHandle<()> {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
log::info!("resume_worker starting...");
|
log::info!("resume_worker starting...");
|
||||||
let duration = Duration::from_millis(10); // very low so it detects before Steam client does
|
let duration = Duration::from_millis(10); // very low so it detects before Steam client does
|
||||||
// this allows PowerTools to set some values at wakeup and Steam to override them before user notices
|
// this allows PowerTools to set some values at wakeup and Steam to override them before user notices
|
||||||
let mut start = Instant::now();
|
let mut start = Instant::now();
|
||||||
loop {
|
loop {
|
||||||
let old_start = start.elapsed();
|
let old_start = start.elapsed();
|
||||||
|
@ -19,7 +19,9 @@ pub fn spawn(sender: Sender<ApiMessage>) -> JoinHandle<()> {
|
||||||
if old_start.as_secs_f64() > duration.as_secs_f64() * (1.0 + ALLOWED_ERROR) {
|
if old_start.as_secs_f64() > duration.as_secs_f64() * (1.0 + ALLOWED_ERROR) {
|
||||||
// has just resumed from sleep
|
// has just resumed from sleep
|
||||||
log::info!("Resume detected");
|
log::info!("Resume detected");
|
||||||
sender.send(ApiMessage::OnResume).expect("resume_worker send failed");
|
sender
|
||||||
|
.send(ApiMessage::OnResume)
|
||||||
|
.expect("resume_worker send failed");
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"OnResume completed after sleeping for {}s",
|
"OnResume completed after sleeping for {}s",
|
||||||
old_start.as_secs_f32()
|
old_start.as_secs_f32()
|
||||||
|
|
|
@ -2,25 +2,31 @@ use std::fs::File;
|
||||||
|
|
||||||
use regex::RegexBuilder;
|
use regex::RegexBuilder;
|
||||||
|
|
||||||
use limits_core::json::{Limits, BatteryLimit, CpuLimit, GpuLimit};
|
use limits_core::json::{BatteryLimit, CpuLimit, GpuLimit, Limits};
|
||||||
|
|
||||||
use crate::persist::{DriverJson, SettingsJson};
|
use crate::persist::{DriverJson, SettingsJson};
|
||||||
use crate::settings::{TGeneral, TCpus, TGpu, TBattery, Driver, General};
|
use crate::settings::{Driver, General, TBattery, TCpus, TGeneral, TGpu};
|
||||||
|
|
||||||
fn get_limits() -> limits_core::json::Base {
|
fn get_limits() -> limits_core::json::Base {
|
||||||
let limits_path = super::utility::limits_path();
|
let limits_path = super::utility::limits_path();
|
||||||
match File::open(&limits_path) {
|
match File::open(&limits_path) {
|
||||||
Ok(f) => {
|
Ok(f) => match serde_json::from_reader(f) {
|
||||||
match serde_json::from_reader(f) {
|
Ok(lim) => lim,
|
||||||
Ok(lim) => lim,
|
Err(e) => {
|
||||||
Err(e) => {
|
log::warn!(
|
||||||
log::warn!("Failed to parse limits file `{}`, cannot use for auto_detect: {}", limits_path.display(), e);
|
"Failed to parse limits file `{}`, cannot use for auto_detect: {}",
|
||||||
limits_core::json::Base::default()
|
limits_path.display(),
|
||||||
}
|
e
|
||||||
|
);
|
||||||
|
limits_core::json::Base::default()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("Failed to open limits file `{}` (trying force refresh...): {}", limits_path.display(), e);
|
log::warn!(
|
||||||
|
"Failed to open limits file `{}` (trying force refresh...): {}",
|
||||||
|
limits_path.display(),
|
||||||
|
e
|
||||||
|
);
|
||||||
super::limits_worker::get_limits_blocking()
|
super::limits_worker::get_limits_blocking()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,22 +34,34 @@ fn get_limits() -> limits_core::json::Base {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn auto_detect_provider() -> DriverJson {
|
pub fn auto_detect_provider() -> DriverJson {
|
||||||
let provider = auto_detect0(None, crate::utility::settings_dir().join("autodetect.json"), "".to_owned())
|
let provider = auto_detect0(
|
||||||
.battery
|
None,
|
||||||
.provider();
|
crate::utility::settings_dir().join("autodetect.json"),
|
||||||
|
"".to_owned(),
|
||||||
|
)
|
||||||
|
.battery
|
||||||
|
.provider();
|
||||||
//log::info!("Detected device automatically, compatible driver: {:?}", provider);
|
//log::info!("Detected device automatically, compatible driver: {:?}", provider);
|
||||||
provider
|
provider
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Device detection logic
|
/// Device detection logic
|
||||||
pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::PathBuf, name: String) -> Driver {
|
pub fn auto_detect0(
|
||||||
|
settings_opt: Option<SettingsJson>,
|
||||||
|
json_path: std::path::PathBuf,
|
||||||
|
name: String,
|
||||||
|
) -> Driver {
|
||||||
let mut builder = DriverBuilder::new(json_path, name);
|
let mut builder = DriverBuilder::new(json_path, name);
|
||||||
|
|
||||||
let cpu_info: String = usdpl_back::api::files::read_single("/proc/cpuinfo").unwrap_or_default();
|
let cpu_info: String = usdpl_back::api::files::read_single("/proc/cpuinfo").unwrap_or_default();
|
||||||
log::debug!("Read from /proc/cpuinfo:\n{}", cpu_info);
|
log::debug!("Read from /proc/cpuinfo:\n{}", cpu_info);
|
||||||
let os_info: String = usdpl_back::api::files::read_single("/etc/os-release").unwrap_or_default();
|
let os_info: String =
|
||||||
|
usdpl_back::api::files::read_single("/etc/os-release").unwrap_or_default();
|
||||||
log::debug!("Read from /etc/os-release:\n{}", os_info);
|
log::debug!("Read from /etc/os-release:\n{}", os_info);
|
||||||
let dmi_info: String = std::process::Command::new("dmidecode").output().map(|out| String::from_utf8_lossy(&out.stdout).into_owned()).unwrap_or_default();
|
let dmi_info: String = std::process::Command::new("dmidecode")
|
||||||
|
.output()
|
||||||
|
.map(|out| String::from_utf8_lossy(&out.stdout).into_owned())
|
||||||
|
.unwrap_or_default();
|
||||||
log::debug!("Read dmidecode:\n{}", dmi_info);
|
log::debug!("Read dmidecode:\n{}", dmi_info);
|
||||||
|
|
||||||
let limits = get_limits();
|
let limits = get_limits();
|
||||||
|
@ -60,26 +78,27 @@ pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::Pa
|
||||||
.multi_line(true)
|
.multi_line(true)
|
||||||
.build()
|
.build()
|
||||||
.expect("Invalid DMI regex");
|
.expect("Invalid DMI regex");
|
||||||
matches &=pattern.is_match(&dmi_info);
|
matches &= pattern.is_match(&dmi_info);
|
||||||
}
|
}
|
||||||
if let Some(cpuinfo) = &conditions.cpuinfo {
|
if let Some(cpuinfo) = &conditions.cpuinfo {
|
||||||
let pattern = RegexBuilder::new(cpuinfo)
|
let pattern = RegexBuilder::new(cpuinfo)
|
||||||
.multi_line(true)
|
.multi_line(true)
|
||||||
.build()
|
.build()
|
||||||
.expect("Invalid CPU regex");
|
.expect("Invalid CPU regex");
|
||||||
matches &=pattern.is_match(&cpu_info);
|
matches &= pattern.is_match(&cpu_info);
|
||||||
}
|
}
|
||||||
if let Some(os) = &conditions.os {
|
if let Some(os) = &conditions.os {
|
||||||
let pattern = RegexBuilder::new(os)
|
let pattern = RegexBuilder::new(os)
|
||||||
.multi_line(true)
|
.multi_line(true)
|
||||||
.build()
|
.build()
|
||||||
.expect("Invalid OS regex");
|
.expect("Invalid OS regex");
|
||||||
matches &=pattern.is_match(&os_info);
|
matches &= pattern.is_match(&os_info);
|
||||||
}
|
}
|
||||||
if let Some(cmd) = &conditions.command {
|
if let Some(cmd) = &conditions.command {
|
||||||
match std::process::Command::new("bash")
|
match std::process::Command::new("bash")
|
||||||
.args(["-c", cmd])
|
.args(["-c", cmd])
|
||||||
.status() {
|
.status()
|
||||||
|
{
|
||||||
Ok(status) => matches &= status.code().map(|c| c == 0).unwrap_or(false),
|
Ok(status) => matches &= status.code().map(|c| c == 0).unwrap_or(false),
|
||||||
Err(e) => log::warn!("Ignoring bash limits error: {}", e),
|
Err(e) => log::warn!("Ignoring bash limits error: {}", e),
|
||||||
}
|
}
|
||||||
|
@ -97,30 +116,102 @@ pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::Pa
|
||||||
match limit {
|
match limit {
|
||||||
Limits::Cpu(cpus) => {
|
Limits::Cpu(cpus) => {
|
||||||
let cpu_driver: Box<dyn TCpus> = match cpus {
|
let cpu_driver: Box<dyn TCpus> = match cpus {
|
||||||
CpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Cpus::from_json(settings.cpus.clone(), settings.version)),
|
CpuLimit::SteamDeck => {
|
||||||
CpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Cpus::from_json(settings.cpus.clone(), settings.version)),
|
Box::new(crate::settings::steam_deck::Cpus::from_json(
|
||||||
CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::<crate::settings::generic::Cpu>::from_json_and_limits(settings.cpus.clone(), settings.version, x)),
|
settings.cpus.clone(),
|
||||||
CpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Cpus::from_json_and_limits(settings.cpus.clone(), settings.version, x)),
|
settings.version,
|
||||||
CpuLimit::Unknown => Box::new(crate::settings::unknown::Cpus::from_json(settings.cpus.clone(), settings.version)),
|
))
|
||||||
|
}
|
||||||
|
CpuLimit::SteamDeckAdvance => {
|
||||||
|
Box::new(crate::settings::steam_deck::Cpus::from_json(
|
||||||
|
settings.cpus.clone(),
|
||||||
|
settings.version,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::<
|
||||||
|
crate::settings::generic::Cpu,
|
||||||
|
>::from_json_and_limits(
|
||||||
|
settings.cpus.clone(),
|
||||||
|
settings.version,
|
||||||
|
x,
|
||||||
|
)),
|
||||||
|
CpuLimit::GenericAMD(x) => Box::new(
|
||||||
|
crate::settings::generic_amd::Cpus::from_json_and_limits(
|
||||||
|
settings.cpus.clone(),
|
||||||
|
settings.version,
|
||||||
|
x,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
CpuLimit::Unknown => {
|
||||||
|
Box::new(crate::settings::unknown::Cpus::from_json(
|
||||||
|
settings.cpus.clone(),
|
||||||
|
settings.version,
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
builder.cpus = Some(cpu_driver);
|
builder.cpus = Some(cpu_driver);
|
||||||
},
|
}
|
||||||
Limits::Gpu(gpu) => {
|
Limits::Gpu(gpu) => {
|
||||||
let driver: Box<dyn TGpu> = match gpu {
|
let driver: Box<dyn TGpu> = match gpu {
|
||||||
GpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Gpu::from_json(settings.gpu.clone(), settings.version)),
|
GpuLimit::SteamDeck => {
|
||||||
GpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Gpu::from_json(settings.gpu.clone(), settings.version)),
|
Box::new(crate::settings::steam_deck::Gpu::from_json(
|
||||||
GpuLimit::Generic(x) => Box::new(crate::settings::generic::Gpu::from_json_and_limits(settings.gpu.clone(), settings.version, x)),
|
settings.gpu.clone(),
|
||||||
GpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Gpu::from_json_and_limits(settings.gpu.clone(), settings.version, x)),
|
settings.version,
|
||||||
GpuLimit::Unknown => Box::new(crate::settings::unknown::Gpu::from_json(settings.gpu.clone(), settings.version)),
|
))
|
||||||
|
}
|
||||||
|
GpuLimit::SteamDeckAdvance => {
|
||||||
|
Box::new(crate::settings::steam_deck::Gpu::from_json(
|
||||||
|
settings.gpu.clone(),
|
||||||
|
settings.version,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
GpuLimit::Generic(x) => {
|
||||||
|
Box::new(crate::settings::generic::Gpu::from_json_and_limits(
|
||||||
|
settings.gpu.clone(),
|
||||||
|
settings.version,
|
||||||
|
x,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
GpuLimit::GenericAMD(x) => Box::new(
|
||||||
|
crate::settings::generic_amd::Gpu::from_json_and_limits(
|
||||||
|
settings.gpu.clone(),
|
||||||
|
settings.version,
|
||||||
|
x,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GpuLimit::Unknown => {
|
||||||
|
Box::new(crate::settings::unknown::Gpu::from_json(
|
||||||
|
settings.gpu.clone(),
|
||||||
|
settings.version,
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
builder.gpu = Some(driver);
|
builder.gpu = Some(driver);
|
||||||
},
|
}
|
||||||
Limits::Battery(batt) => {
|
Limits::Battery(batt) => {
|
||||||
let driver: Box<dyn TBattery> = match batt {
|
let driver: Box<dyn TBattery> = match batt {
|
||||||
BatteryLimit::SteamDeck => Box::new(crate::settings::steam_deck::Battery::from_json(settings.battery.clone(), settings.version)),
|
BatteryLimit::SteamDeck => {
|
||||||
BatteryLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Battery::from_json(settings.battery.clone(), settings.version)),
|
Box::new(crate::settings::steam_deck::Battery::from_json(
|
||||||
BatteryLimit::Generic(x) => Box::new(crate::settings::generic::Battery::from_json_and_limits(settings.battery.clone(), settings.version, x)),
|
settings.battery.clone(),
|
||||||
BatteryLimit::Unknown => Box::new(crate::settings::unknown::Battery),
|
settings.version,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
BatteryLimit::SteamDeckAdvance => {
|
||||||
|
Box::new(crate::settings::steam_deck::Battery::from_json(
|
||||||
|
settings.battery.clone(),
|
||||||
|
settings.version,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
BatteryLimit::Generic(x) => Box::new(
|
||||||
|
crate::settings::generic::Battery::from_json_and_limits(
|
||||||
|
settings.battery.clone(),
|
||||||
|
settings.version,
|
||||||
|
x,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
BatteryLimit::Unknown => {
|
||||||
|
Box::new(crate::settings::unknown::Battery)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
builder.battery = Some(driver);
|
builder.battery = Some(driver);
|
||||||
}
|
}
|
||||||
|
@ -131,37 +222,66 @@ pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::Pa
|
||||||
match limit {
|
match limit {
|
||||||
Limits::Cpu(cpus) => {
|
Limits::Cpu(cpus) => {
|
||||||
let cpu_driver: Box<dyn TCpus> = match cpus {
|
let cpu_driver: Box<dyn TCpus> = match cpus {
|
||||||
CpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Cpus::system_default()),
|
CpuLimit::SteamDeck => {
|
||||||
CpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Cpus::system_default()),
|
Box::new(crate::settings::steam_deck::Cpus::system_default())
|
||||||
CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::<crate::settings::generic::Cpu>::from_limits(x)),
|
}
|
||||||
CpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Cpus::from_limits(x)),
|
CpuLimit::SteamDeckAdvance => {
|
||||||
CpuLimit::Unknown => Box::new(crate::settings::unknown::Cpus::system_default()),
|
Box::new(crate::settings::steam_deck::Cpus::system_default())
|
||||||
|
}
|
||||||
|
CpuLimit::Generic(x) => {
|
||||||
|
Box::new(crate::settings::generic::Cpus::<
|
||||||
|
crate::settings::generic::Cpu,
|
||||||
|
>::from_limits(x))
|
||||||
|
}
|
||||||
|
CpuLimit::GenericAMD(x) => {
|
||||||
|
Box::new(crate::settings::generic_amd::Cpus::from_limits(x))
|
||||||
|
}
|
||||||
|
CpuLimit::Unknown => {
|
||||||
|
Box::new(crate::settings::unknown::Cpus::system_default())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
builder.cpus = Some(cpu_driver);
|
builder.cpus = Some(cpu_driver);
|
||||||
},
|
}
|
||||||
Limits::Gpu(gpu) => {
|
Limits::Gpu(gpu) => {
|
||||||
let driver: Box<dyn TGpu> = match gpu {
|
let driver: Box<dyn TGpu> = match gpu {
|
||||||
GpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Gpu::system_default()),
|
GpuLimit::SteamDeck => {
|
||||||
GpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Gpu::system_default()),
|
Box::new(crate::settings::steam_deck::Gpu::system_default())
|
||||||
GpuLimit::Generic(x) => Box::new(crate::settings::generic::Gpu::from_limits(x)),
|
}
|
||||||
GpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Gpu::from_limits(x)),
|
GpuLimit::SteamDeckAdvance => {
|
||||||
GpuLimit::Unknown => Box::new(crate::settings::unknown::Gpu::system_default()),
|
Box::new(crate::settings::steam_deck::Gpu::system_default())
|
||||||
|
}
|
||||||
|
GpuLimit::Generic(x) => {
|
||||||
|
Box::new(crate::settings::generic::Gpu::from_limits(x))
|
||||||
|
}
|
||||||
|
GpuLimit::GenericAMD(x) => {
|
||||||
|
Box::new(crate::settings::generic_amd::Gpu::from_limits(x))
|
||||||
|
}
|
||||||
|
GpuLimit::Unknown => {
|
||||||
|
Box::new(crate::settings::unknown::Gpu::system_default())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
builder.gpu = Some(driver);
|
builder.gpu = Some(driver);
|
||||||
},
|
}
|
||||||
Limits::Battery(batt) => {
|
Limits::Battery(batt) => {
|
||||||
let driver: Box<dyn TBattery> = match batt {
|
let driver: Box<dyn TBattery> = match batt {
|
||||||
BatteryLimit::SteamDeck => Box::new(crate::settings::steam_deck::Battery::system_default()),
|
BatteryLimit::SteamDeck => {
|
||||||
BatteryLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Battery::system_default()),
|
Box::new(crate::settings::steam_deck::Battery::system_default())
|
||||||
BatteryLimit::Generic(x) => Box::new(crate::settings::generic::Battery::from_limits(x)),
|
}
|
||||||
BatteryLimit::Unknown => Box::new(crate::settings::unknown::Battery),
|
BatteryLimit::SteamDeckAdvance => {
|
||||||
|
Box::new(crate::settings::steam_deck::Battery::system_default())
|
||||||
|
}
|
||||||
|
BatteryLimit::Generic(x) => {
|
||||||
|
Box::new(crate::settings::generic::Battery::from_limits(x))
|
||||||
|
}
|
||||||
|
BatteryLimit::Unknown => {
|
||||||
|
Box::new(crate::settings::unknown::Battery)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
builder.battery = Some(driver);
|
builder.battery = Some(driver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,9 +317,15 @@ impl DriverBuilder {
|
||||||
fn build(self) -> Driver {
|
fn build(self) -> Driver {
|
||||||
Driver {
|
Driver {
|
||||||
general: self.general,
|
general: self.general,
|
||||||
cpus: self.cpus.unwrap_or_else(|| Box::new(crate::settings::unknown::Cpus::system_default())),
|
cpus: self
|
||||||
gpu: self.gpu.unwrap_or_else(|| Box::new(crate::settings::unknown::Gpu::system_default())),
|
.cpus
|
||||||
battery: self.battery.unwrap_or_else(|| Box::new(crate::settings::unknown::Battery))
|
.unwrap_or_else(|| Box::new(crate::settings::unknown::Cpus::system_default())),
|
||||||
|
gpu: self
|
||||||
|
.gpu
|
||||||
|
.unwrap_or_else(|| Box::new(crate::settings::unknown::Gpu::system_default())),
|
||||||
|
battery: self
|
||||||
|
.battery
|
||||||
|
.unwrap_or_else(|| Box::new(crate::settings::unknown::Battery)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,20 +8,18 @@ use limits_core::json::Base;
|
||||||
pub fn spawn() -> JoinHandle<()> {
|
pub fn spawn() -> JoinHandle<()> {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
log::info!("limits_worker starting...");
|
log::info!("limits_worker starting...");
|
||||||
let sleep_dur = Duration::from_secs(60*60*24); // 1 day
|
let sleep_dur = Duration::from_secs(60 * 60 * 24); // 1 day
|
||||||
let limits_path = super::utility::limits_path();
|
let limits_path = super::utility::limits_path();
|
||||||
loop {
|
loop {
|
||||||
thread::sleep(sleep_dur);
|
thread::sleep(sleep_dur);
|
||||||
if (limits_path.exists() && limits_path.is_file()) || !limits_path.exists() {
|
if (limits_path.exists() && limits_path.is_file()) || !limits_path.exists() {
|
||||||
// try to load limits from file, fallback to built-in default
|
// try to load limits from file, fallback to built-in default
|
||||||
let base = match std::fs::File::open(&limits_path) {
|
let base = match std::fs::File::open(&limits_path) {
|
||||||
Ok(f) => {
|
Ok(f) => match serde_json::from_reader(f) {
|
||||||
match serde_json::from_reader(f) {
|
Ok(b) => b,
|
||||||
Ok(b) => b,
|
Err(e) => {
|
||||||
Err(e) => {
|
log::error!("Cannot parse {}: {}", limits_path.display(), e);
|
||||||
log::error!("Cannot parse {}: {}", limits_path.display(), e);
|
Base::default()
|
||||||
Base::default()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -31,17 +29,18 @@ pub fn spawn() -> JoinHandle<()> {
|
||||||
};
|
};
|
||||||
if let Some(refresh) = &base.refresh {
|
if let Some(refresh) = &base.refresh {
|
||||||
// try to retrieve newer version
|
// try to retrieve newer version
|
||||||
match ureq::get(refresh)
|
match ureq::get(refresh).call() {
|
||||||
.call() {
|
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
let json_res: std::io::Result<Base> = response.into_json();
|
let json_res: std::io::Result<Base> = response.into_json();
|
||||||
match json_res {
|
match json_res {
|
||||||
Ok(new_base) => {
|
Ok(new_base) => {
|
||||||
save_base(&new_base, &limits_path);
|
save_base(&new_base, &limits_path);
|
||||||
},
|
}
|
||||||
Err(e) => log::error!("Cannot parse response from `{}`: {}", refresh, e),
|
Err(e) => {
|
||||||
|
log::error!("Cannot parse response from `{}`: {}", refresh, e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => log::warn!("Cannot download limits from `{}`: {}", refresh, e),
|
Err(e) => log::warn!("Cannot download limits from `{}`: {}", refresh, e),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -67,13 +66,11 @@ pub fn get_limits_blocking() -> Base {
|
||||||
let limits_path = super::utility::limits_path();
|
let limits_path = super::utility::limits_path();
|
||||||
if limits_path.is_file() {
|
if limits_path.is_file() {
|
||||||
match std::fs::File::open(&limits_path) {
|
match std::fs::File::open(&limits_path) {
|
||||||
Ok(f) => {
|
Ok(f) => match serde_json::from_reader(f) {
|
||||||
match serde_json::from_reader(f) {
|
Ok(b) => b,
|
||||||
Ok(b) => b,
|
Err(e) => {
|
||||||
Err(e) => {
|
log::error!("Cannot parse {}: {}", limits_path.display(), e);
|
||||||
log::error!("Cannot parse {}: {}", limits_path.display(), e);
|
Base::default()
|
||||||
Base::default()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -86,17 +83,18 @@ pub fn get_limits_blocking() -> Base {
|
||||||
{
|
{
|
||||||
let refresh = Base::default().refresh.unwrap();
|
let refresh = Base::default().refresh.unwrap();
|
||||||
match ureq::get(&refresh) // try to retrieve newer version
|
match ureq::get(&refresh) // try to retrieve newer version
|
||||||
.call() {
|
.call()
|
||||||
|
{
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
let json_res: std::io::Result<Base> = response.into_json();
|
let json_res: std::io::Result<Base> = response.into_json();
|
||||||
match json_res {
|
match json_res {
|
||||||
Ok(new_base) => {
|
Ok(new_base) => {
|
||||||
save_base(&new_base, &limits_path);
|
save_base(&new_base, &limits_path);
|
||||||
return new_base;
|
return new_base;
|
||||||
},
|
}
|
||||||
Err(e) => log::error!("Cannot parse response from `{}`: {}", refresh, e)
|
Err(e) => log::error!("Cannot parse response from `{}`: {}", refresh, e),
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => log::warn!("Cannot download limits from `{}`: {}", refresh, e),
|
Err(e) => log::warn!("Cannot download limits from `{}`: {}", refresh, e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,12 +106,14 @@ pub fn get_limits_blocking() -> Base {
|
||||||
fn save_base(new_base: &Base, path: impl AsRef<std::path::Path>) {
|
fn save_base(new_base: &Base, path: impl AsRef<std::path::Path>) {
|
||||||
let limits_path = path.as_ref();
|
let limits_path = path.as_ref();
|
||||||
match std::fs::File::create(&limits_path) {
|
match std::fs::File::create(&limits_path) {
|
||||||
Ok(f) => {
|
Ok(f) => match serde_json::to_writer_pretty(f, &new_base) {
|
||||||
match serde_json::to_writer_pretty(f, &new_base) {
|
Ok(_) => log::info!("Successfully saved new limits to {}", limits_path.display()),
|
||||||
Ok(_) => log::info!("Successfully saved new limits to {}", limits_path.display()),
|
Err(e) => log::error!(
|
||||||
Err(e) => log::error!("Failed to save limits json to file `{}`: {}", limits_path.display(), e),
|
"Failed to save limits json to file `{}`: {}",
|
||||||
}
|
limits_path.display(),
|
||||||
|
e
|
||||||
|
),
|
||||||
},
|
},
|
||||||
Err(e) => log::error!("Cannot create {}: {}", limits_path.display(), e)
|
Err(e) => log::error!("Cannot create {}: {}", limits_path.display(), e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,4 +2,4 @@ mod auto_detect;
|
||||||
pub mod limits_worker;
|
pub mod limits_worker;
|
||||||
mod utility;
|
mod utility;
|
||||||
|
|
||||||
pub use auto_detect::{auto_detect_provider, auto_detect0};
|
pub use auto_detect::{auto_detect0, auto_detect_provider};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
use super::{auto_detect0, General, SettingError, TBattery, TCpus, TGeneral, TGpu};
|
||||||
use crate::persist::{DriverJson, SettingsJson};
|
use crate::persist::{DriverJson, SettingsJson};
|
||||||
use super::{TGeneral, TCpus, TGpu, TBattery, SettingError, General, auto_detect0};
|
|
||||||
|
|
||||||
pub struct Driver {
|
pub struct Driver {
|
||||||
pub general: Box<dyn TGeneral>,
|
pub general: Box<dyn TGeneral>,
|
||||||
|
@ -9,7 +9,10 @@ pub struct Driver {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Driver {
|
impl Driver {
|
||||||
pub fn init(settings: SettingsJson, json_path: std::path::PathBuf) -> Result<Self, SettingError> {
|
pub fn init(
|
||||||
|
settings: SettingsJson,
|
||||||
|
json_path: std::path::PathBuf,
|
||||||
|
) -> Result<Self, SettingError> {
|
||||||
Ok(match settings.version {
|
Ok(match settings.version {
|
||||||
0 => Self::version0(settings, json_path)?,
|
0 => Self::version0(settings, json_path)?,
|
||||||
_ => Self {
|
_ => Self {
|
||||||
|
@ -19,14 +22,26 @@ impl Driver {
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
driver: DriverJson::SteamDeck,
|
driver: DriverJson::SteamDeck,
|
||||||
}),
|
}),
|
||||||
cpus: Box::new(super::steam_deck::Cpus::from_json(settings.cpus, settings.version)),
|
cpus: Box::new(super::steam_deck::Cpus::from_json(
|
||||||
gpu: Box::new(super::steam_deck::Gpu::from_json(settings.gpu, settings.version)),
|
settings.cpus,
|
||||||
battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)),
|
settings.version,
|
||||||
|
)),
|
||||||
|
gpu: Box::new(super::steam_deck::Gpu::from_json(
|
||||||
|
settings.gpu,
|
||||||
|
settings.version,
|
||||||
|
)),
|
||||||
|
battery: Box::new(super::steam_deck::Battery::from_json(
|
||||||
|
settings.battery,
|
||||||
|
settings.version,
|
||||||
|
)),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn version0(settings: SettingsJson, json_path: std::path::PathBuf) -> Result<Self, SettingError> {
|
fn version0(
|
||||||
|
settings: SettingsJson,
|
||||||
|
json_path: std::path::PathBuf,
|
||||||
|
) -> Result<Self, SettingError> {
|
||||||
let name = settings.name.clone();
|
let name = settings.name.clone();
|
||||||
if let Some(provider) = &settings.provider {
|
if let Some(provider) = &settings.provider {
|
||||||
match provider {
|
match provider {
|
||||||
|
@ -37,9 +52,18 @@ impl Driver {
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
driver: DriverJson::SteamDeck,
|
driver: DriverJson::SteamDeck,
|
||||||
}),
|
}),
|
||||||
cpus: Box::new(super::steam_deck::Cpus::from_json(settings.cpus, settings.version)),
|
cpus: Box::new(super::steam_deck::Cpus::from_json(
|
||||||
gpu: Box::new(super::steam_deck::Gpu::from_json(settings.gpu, settings.version)),
|
settings.cpus,
|
||||||
battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)),
|
settings.version,
|
||||||
|
)),
|
||||||
|
gpu: Box::new(super::steam_deck::Gpu::from_json(
|
||||||
|
settings.gpu,
|
||||||
|
settings.version,
|
||||||
|
)),
|
||||||
|
battery: Box::new(super::steam_deck::Battery::from_json(
|
||||||
|
settings.battery,
|
||||||
|
settings.version,
|
||||||
|
)),
|
||||||
}),
|
}),
|
||||||
// There's nothing special about SteamDeckAdvance, it just appears different
|
// There's nothing special about SteamDeckAdvance, it just appears different
|
||||||
DriverJson::SteamDeckAdvance => Ok(Self {
|
DriverJson::SteamDeckAdvance => Ok(Self {
|
||||||
|
@ -49,13 +73,28 @@ impl Driver {
|
||||||
name: settings.name,
|
name: settings.name,
|
||||||
driver: DriverJson::SteamDeckAdvance,
|
driver: DriverJson::SteamDeckAdvance,
|
||||||
}),
|
}),
|
||||||
cpus: Box::new(super::steam_deck::Cpus::from_json(settings.cpus, settings.version)),
|
cpus: Box::new(super::steam_deck::Cpus::from_json(
|
||||||
gpu: Box::new(super::steam_deck::Gpu::from_json(settings.gpu, settings.version)),
|
settings.cpus,
|
||||||
battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)),
|
settings.version,
|
||||||
|
)),
|
||||||
|
gpu: Box::new(super::steam_deck::Gpu::from_json(
|
||||||
|
settings.gpu,
|
||||||
|
settings.version,
|
||||||
|
)),
|
||||||
|
battery: Box::new(super::steam_deck::Battery::from_json(
|
||||||
|
settings.battery,
|
||||||
|
settings.version,
|
||||||
|
)),
|
||||||
}),
|
}),
|
||||||
DriverJson::Generic | DriverJson::GenericAMD => Ok(super::detect::auto_detect0(Some(settings), json_path, name)),
|
DriverJson::Generic | DriverJson::GenericAMD => {
|
||||||
DriverJson::Unknown => Ok(super::detect::auto_detect0(Some(settings), json_path, name)),
|
Ok(super::detect::auto_detect0(Some(settings), json_path, name))
|
||||||
DriverJson::AutoDetect => Ok(super::detect::auto_detect0(Some(settings), json_path, name)),
|
}
|
||||||
|
DriverJson::Unknown => {
|
||||||
|
Ok(super::detect::auto_detect0(Some(settings), json_path, name))
|
||||||
|
}
|
||||||
|
DriverJson::AutoDetect => {
|
||||||
|
Ok(super::detect::auto_detect0(Some(settings), json_path, name))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(super::detect::auto_detect0(Some(settings), json_path, name))
|
Ok(super::detect::auto_detect0(Some(settings), json_path, name))
|
||||||
|
@ -73,9 +112,11 @@ pub fn maybe_do_button() {
|
||||||
match super::auto_detect_provider() {
|
match super::auto_detect_provider() {
|
||||||
DriverJson::SteamDeck | DriverJson::SteamDeckAdvance => {
|
DriverJson::SteamDeck | DriverJson::SteamDeckAdvance => {
|
||||||
crate::settings::steam_deck::flash_led();
|
crate::settings::steam_deck::flash_led();
|
||||||
},
|
}
|
||||||
DriverJson::Generic | DriverJson::GenericAMD => log::warn!("You need to come up with something fun on generic"),
|
DriverJson::Generic | DriverJson::GenericAMD => {
|
||||||
|
log::warn!("You need to come up with something fun on generic")
|
||||||
|
}
|
||||||
DriverJson::Unknown => log::warn!("Can't do button activities on unknown platform"),
|
DriverJson::Unknown => log::warn!("Can't do button activities on unknown platform"),
|
||||||
DriverJson::AutoDetect => log::warn!("WTF, why is auto_detect detecting AutoDetect???")
|
DriverJson::AutoDetect => log::warn!("WTF, why is auto_detect detecting AutoDetect???"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::path::PathBuf;
|
||||||
|
|
||||||
//use super::{Battery, Cpus, Gpu};
|
//use super::{Battery, Cpus, Gpu};
|
||||||
use super::{OnResume, OnSet, SettingError};
|
use super::{OnResume, OnSet, SettingError};
|
||||||
use super::{TGeneral, TGpu, TCpus, TBattery};
|
use super::{TBattery, TCpus, TGeneral, TGpu};
|
||||||
use crate::persist::SettingsJson;
|
use crate::persist::SettingsJson;
|
||||||
//use crate::utility::unwrap_lock;
|
//use crate::utility::unwrap_lock;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ impl crate::settings::OnPowerEvent for General {}
|
||||||
|
|
||||||
impl TGeneral for General {
|
impl TGeneral for General {
|
||||||
fn limits(&self) -> crate::api::GeneralLimits {
|
fn limits(&self) -> crate::api::GeneralLimits {
|
||||||
crate::api::GeneralLimits { }
|
crate::api::GeneralLimits {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_persistent(&self) -> bool {
|
fn get_persistent(&self) -> bool {
|
||||||
|
@ -97,17 +97,25 @@ impl OnSet for Settings {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
|
|
||||||
log::debug!("Applying settings for on_resume");
|
log::debug!("Applying settings for on_resume");
|
||||||
self.general.on_set().unwrap_or_else(|mut e| errors.append(&mut e));
|
self.general
|
||||||
|
.on_set()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
log::debug!("Resumed general");
|
log::debug!("Resumed general");
|
||||||
self.battery.on_set().unwrap_or_else(|mut e| errors.append(&mut e));
|
self.battery
|
||||||
|
.on_set()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
log::debug!("Resumed battery");
|
log::debug!("Resumed battery");
|
||||||
self.cpus.on_set().unwrap_or_else(|mut e| errors.append(&mut e));
|
self.cpus
|
||||||
|
.on_set()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
log::debug!("Resumed CPUs");
|
log::debug!("Resumed CPUs");
|
||||||
self.gpu.on_set().unwrap_or_else(|mut e| errors.append(&mut e));
|
self.gpu
|
||||||
|
.on_set()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
log::debug!("Resumed GPU");
|
log::debug!("Resumed GPU");
|
||||||
|
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(errors)
|
Err(errors)
|
||||||
}
|
}
|
||||||
|
@ -120,14 +128,20 @@ impl Settings {
|
||||||
let name_bup = other.name.clone();
|
let name_bup = other.name.clone();
|
||||||
match super::Driver::init(other, json_path.clone()) {
|
match super::Driver::init(other, json_path.clone()) {
|
||||||
Ok(x) => {
|
Ok(x) => {
|
||||||
log::info!("Loaded settings with drivers general:{:?},cpus:{:?},gpu:{:?},battery:{:?}", x.general.provider(), x.cpus.provider(), x.gpu.provider(), x.battery.provider());
|
log::info!(
|
||||||
|
"Loaded settings with drivers general:{:?},cpus:{:?},gpu:{:?},battery:{:?}",
|
||||||
|
x.general.provider(),
|
||||||
|
x.cpus.provider(),
|
||||||
|
x.gpu.provider(),
|
||||||
|
x.battery.provider()
|
||||||
|
);
|
||||||
Self {
|
Self {
|
||||||
general: x.general,
|
general: x.general,
|
||||||
cpus: x.cpus,
|
cpus: x.cpus,
|
||||||
gpu: x.gpu,
|
gpu: x.gpu,
|
||||||
battery: x.battery,
|
battery: x.battery,
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Driver init error: {}", e);
|
log::error!("Driver init error: {}", e);
|
||||||
Self::system_default(json_path, name_bup)
|
Self::system_default(json_path, name_bup)
|
||||||
|
@ -153,7 +167,12 @@ impl Settings {
|
||||||
self.general = driver.general;
|
self.general = driver.general;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_file(&mut self, filename: PathBuf, name: String, system_defaults: bool) -> Result<bool, SettingError> {
|
pub fn load_file(
|
||||||
|
&mut self,
|
||||||
|
filename: PathBuf,
|
||||||
|
name: String,
|
||||||
|
system_defaults: bool,
|
||||||
|
) -> Result<bool, SettingError> {
|
||||||
let json_path = crate::utility::settings_dir().join(&filename);
|
let json_path = crate::utility::settings_dir().join(&filename);
|
||||||
if json_path.exists() {
|
if json_path.exists() {
|
||||||
let settings_json = SettingsJson::open(&json_path).map_err(|e| SettingError {
|
let settings_json = SettingsJson::open(&json_path).map_err(|e| SettingError {
|
||||||
|
@ -161,7 +180,11 @@ impl Settings {
|
||||||
setting: SettingVariant::General,
|
setting: SettingVariant::General,
|
||||||
})?;
|
})?;
|
||||||
if !settings_json.persistent {
|
if !settings_json.persistent {
|
||||||
log::warn!("Loaded persistent config `{}` ({}) with persistent=false", &settings_json.name, json_path.display());
|
log::warn!(
|
||||||
|
"Loaded persistent config `{}` ({}) with persistent=false",
|
||||||
|
&settings_json.name,
|
||||||
|
json_path.display()
|
||||||
|
);
|
||||||
*self.general.persistent() = false;
|
*self.general.persistent() = false;
|
||||||
self.general.name(name);
|
self.general.name(name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -172,7 +195,7 @@ impl Settings {
|
||||||
self.cpus = x.cpus;
|
self.cpus = x.cpus;
|
||||||
self.gpu = x.gpu;
|
self.gpu = x.gpu;
|
||||||
self.battery = x.battery;
|
self.battery = x.battery;
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Driver init error: {}", e);
|
log::error!("Driver init error: {}", e);
|
||||||
self.general.name(name);
|
self.general.name(name);
|
||||||
|
@ -193,7 +216,7 @@ impl Settings {
|
||||||
self.general.path(filename);
|
self.general.path(filename);
|
||||||
Ok(*self.general.persistent())
|
Ok(*self.general.persistent())
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub fn load_file(&mut self, filename: PathBuf, name: String, system_defaults: bool) -> Result<bool, SettingError> {
|
pub fn load_file(&mut self, filename: PathBuf, name: String, system_defaults: bool) -> Result<bool, SettingError> {
|
||||||
let json_path = crate::utility::settings_dir().join(filename);
|
let json_path = crate::utility::settings_dir().join(filename);
|
||||||
|
@ -243,17 +266,25 @@ impl OnResume for Settings {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
|
|
||||||
log::debug!("Applying settings for on_resume");
|
log::debug!("Applying settings for on_resume");
|
||||||
self.general.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
self.general
|
||||||
|
.on_resume()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
log::debug!("Resumed general");
|
log::debug!("Resumed general");
|
||||||
self.battery.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
self.battery
|
||||||
|
.on_resume()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
log::debug!("Resumed battery");
|
log::debug!("Resumed battery");
|
||||||
self.cpus.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
self.cpus
|
||||||
|
.on_resume()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
log::debug!("Resumed CPUs");
|
log::debug!("Resumed CPUs");
|
||||||
self.gpu.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
self.gpu
|
||||||
|
.on_resume()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
log::debug!("Resumed GPU");
|
log::debug!("Resumed GPU");
|
||||||
|
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(errors)
|
Err(errors)
|
||||||
}
|
}
|
||||||
|
@ -264,13 +295,21 @@ impl crate::settings::OnPowerEvent for Settings {
|
||||||
fn on_power_event(&mut self, new_mode: super::PowerMode) -> Result<(), Vec<SettingError>> {
|
fn on_power_event(&mut self, new_mode: super::PowerMode) -> Result<(), Vec<SettingError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
|
|
||||||
self.general.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
self.general
|
||||||
self.battery.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
.on_power_event(new_mode)
|
||||||
self.cpus.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
self.gpu.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
self.battery
|
||||||
|
.on_power_event(new_mode)
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
|
self.cpus
|
||||||
|
.on_power_event(new_mode)
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
|
self.gpu
|
||||||
|
.on_power_event(new_mode)
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
|
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(errors)
|
Err(errors)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,9 @@ use std::convert::Into;
|
||||||
|
|
||||||
use limits_core::json::GenericBatteryLimit;
|
use limits_core::json::GenericBatteryLimit;
|
||||||
|
|
||||||
use crate::settings::{OnResume, OnSet, SettingError};
|
|
||||||
use crate::settings::TBattery;
|
|
||||||
use crate::persist::BatteryJson;
|
use crate::persist::BatteryJson;
|
||||||
|
use crate::settings::TBattery;
|
||||||
|
use crate::settings::{OnResume, OnSet, SettingError};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Battery {
|
pub struct Battery {
|
||||||
|
@ -39,16 +39,16 @@ impl Battery {
|
||||||
|
|
||||||
pub fn from_limits(limits: limits_core::json::GenericBatteryLimit) -> Self {
|
pub fn from_limits(limits: limits_core::json::GenericBatteryLimit) -> Self {
|
||||||
// TODO
|
// TODO
|
||||||
Self {
|
Self { limits }
|
||||||
limits
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_json_and_limits(_other: BatteryJson, _version: u64, limits: limits_core::json::GenericBatteryLimit) -> Self {
|
pub fn from_json_and_limits(
|
||||||
|
_other: BatteryJson,
|
||||||
|
_version: u64,
|
||||||
|
limits: limits_core::json::GenericBatteryLimit,
|
||||||
|
) -> Self {
|
||||||
// TODO
|
// TODO
|
||||||
Self {
|
Self { limits }
|
||||||
limits
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,15 +83,13 @@ impl TBattery for Battery {
|
||||||
self.clone().into()
|
self.clone().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn charge_rate(&mut self, _rate: Option<u64>) {
|
fn charge_rate(&mut self, _rate: Option<u64>) {}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_charge_rate(&self) -> Option<u64> {
|
fn get_charge_rate(&self) -> Option<u64> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn charge_mode(&mut self, _rate: Option<String>) {
|
fn charge_mode(&mut self, _rate: Option<String>) {}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_charge_mode(&self) -> Option<String> {
|
fn get_charge_mode(&self) -> Option<String> {
|
||||||
None
|
None
|
||||||
|
@ -133,7 +131,9 @@ impl TBattery for Battery {
|
||||||
|
|
||||||
fn charge_limit(&mut self, _limit: Option<f64>) {}
|
fn charge_limit(&mut self, _limit: Option<f64>) {}
|
||||||
|
|
||||||
fn get_charge_limit(&self) -> Option<f64> { None }
|
fn get_charge_limit(&self) -> Option<f64> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn provider(&self) -> crate::persist::DriverJson {
|
fn provider(&self) -> crate::persist::DriverJson {
|
||||||
crate::persist::DriverJson::Generic
|
crate::persist::DriverJson::Generic
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use std::convert::{Into, AsMut, AsRef};
|
use std::convert::{AsMut, AsRef, Into};
|
||||||
|
|
||||||
use limits_core::json::GenericCpuLimit;
|
use limits_core::json::GenericCpuLimit;
|
||||||
|
|
||||||
use crate::settings::{MinMax, min_max_from_json};
|
|
||||||
use crate::settings::{OnResume, OnSet, SettingError};
|
|
||||||
use crate::settings::{TCpus, TCpu};
|
|
||||||
use crate::persist::CpuJson;
|
|
||||||
use super::FromGenericCpuInfo;
|
use super::FromGenericCpuInfo;
|
||||||
|
use crate::persist::CpuJson;
|
||||||
|
use crate::settings::{min_max_from_json, MinMax};
|
||||||
|
use crate::settings::{OnResume, OnSet, SettingError};
|
||||||
|
use crate::settings::{TCpu, TCpus};
|
||||||
|
|
||||||
const CPU_PRESENT_PATH: &str = "/sys/devices/system/cpu/present";
|
const CPU_PRESENT_PATH: &str = "/sys/devices/system/cpu/present";
|
||||||
const CPU_SMT_PATH: &str = "/sys/devices/system/cpu/smt/control";
|
const CPU_SMT_PATH: &str = "/sys/devices/system/cpu/smt/control";
|
||||||
|
@ -24,25 +24,19 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnSet> OnSet for Cpus<C> {
|
||||||
if self.smt_capable {
|
if self.smt_capable {
|
||||||
// toggle SMT
|
// toggle SMT
|
||||||
if self.smt {
|
if self.smt {
|
||||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on").map_err(|e| {
|
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on")
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!("Failed to write `on` to `{}`: {}", CPU_SMT_PATH, e),
|
||||||
"Failed to write `on` to `{}`: {}",
|
|
||||||
CPU_SMT_PATH, e
|
|
||||||
),
|
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
} else {
|
} else {
|
||||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off").map_err(|e| {
|
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off")
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!("Failed to write `off` to `{}`: {}", CPU_SMT_PATH, e),
|
||||||
"Failed to write `off` to `{}`: {}",
|
|
||||||
CPU_SMT_PATH, e
|
|
||||||
),
|
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
|
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
|
||||||
|
@ -61,7 +55,8 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnResume> OnResume for Cpus<C> {
|
||||||
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
|
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
for cpu in &self.cpus {
|
for cpu in &self.cpus {
|
||||||
cpu.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
cpu.on_resume()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
}
|
}
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -88,7 +83,7 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + FromGenericCpuInfo> Cpus<C> {
|
||||||
fn system_smt_capabilities() -> (bool, bool) {
|
fn system_smt_capabilities() -> (bool, bool) {
|
||||||
match usdpl_back::api::files::read_single::<_, String, _>(CPU_SMT_PATH) {
|
match usdpl_back::api::files::read_single::<_, String, _>(CPU_SMT_PATH) {
|
||||||
Ok(val) => (val.trim().to_lowercase() == "on", true),
|
Ok(val) => (val.trim().to_lowercase() == "on", true),
|
||||||
Err(_) => (false, false)
|
Err(_) => (false, false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +102,11 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + FromGenericCpuInfo> Cpus<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_json_and_limits(mut other: Vec<CpuJson>, version: u64, limits: limits_core::json::GenericCpuLimit) -> Self {
|
pub fn from_json_and_limits(
|
||||||
|
mut other: Vec<CpuJson>,
|
||||||
|
version: u64,
|
||||||
|
limits: limits_core::json::GenericCpuLimit,
|
||||||
|
) -> Self {
|
||||||
let (_, can_smt) = Self::system_smt_capabilities();
|
let (_, can_smt) = Self::system_smt_capabilities();
|
||||||
let mut result = Vec::with_capacity(other.len());
|
let mut result = Vec::with_capacity(other.len());
|
||||||
let max_cpus = Self::cpu_count();
|
let max_cpus = Self::cpu_count();
|
||||||
|
@ -138,11 +137,17 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + FromGenericCpuInfo> Cpus<C> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + crate::settings::OnPowerEvent> crate::settings::OnPowerEvent for Cpus<C> {
|
impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + crate::settings::OnPowerEvent>
|
||||||
fn on_power_event(&mut self, new_mode: crate::settings::PowerMode) -> Result<(), Vec<SettingError>> {
|
crate::settings::OnPowerEvent for Cpus<C>
|
||||||
|
{
|
||||||
|
fn on_power_event(
|
||||||
|
&mut self,
|
||||||
|
new_mode: crate::settings::PowerMode,
|
||||||
|
) -> Result<(), Vec<SettingError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
for cpu in &mut self.cpus {
|
for cpu in &mut self.cpus {
|
||||||
cpu.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
cpu.on_power_event(new_mode)
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
}
|
}
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -152,7 +157,9 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + crate::settings::OnPowerEvent> crate::s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnResume + OnSet + crate::settings::OnPowerEvent> TCpus for Cpus<C> {
|
impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnResume + OnSet + crate::settings::OnPowerEvent> TCpus
|
||||||
|
for Cpus<C>
|
||||||
|
{
|
||||||
fn limits(&self) -> crate::api::CpusLimits {
|
fn limits(&self) -> crate::api::CpusLimits {
|
||||||
crate::api::CpusLimits {
|
crate::api::CpusLimits {
|
||||||
cpus: self.cpus.iter().map(|x| x.as_ref().limits()).collect(),
|
cpus: self.cpus.iter().map(|x| x.as_ref().limits()).collect(),
|
||||||
|
@ -163,7 +170,10 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnResume + OnSet + crate::settings::OnP
|
||||||
}
|
}
|
||||||
|
|
||||||
fn json(&self) -> Vec<crate::persist::CpuJson> {
|
fn json(&self) -> Vec<crate::persist::CpuJson> {
|
||||||
self.cpus.iter().map(|x| x.as_ref().to_owned().into()).collect()
|
self.cpus
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.as_ref().to_owned().into())
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cpus(&mut self) -> Vec<&mut dyn TCpu> {
|
fn cpus(&mut self) -> Vec<&mut dyn TCpu> {
|
||||||
|
@ -228,7 +238,12 @@ impl FromGenericCpuInfo for Cpu {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_json_and_limits(other: CpuJson, version: u64, i: usize, limits: GenericCpuLimit) -> Self {
|
fn from_json_and_limits(
|
||||||
|
other: CpuJson,
|
||||||
|
version: u64,
|
||||||
|
i: usize,
|
||||||
|
limits: GenericCpuLimit,
|
||||||
|
) -> Self {
|
||||||
let clock_lims = if limits.clock_min.is_some() && limits.clock_max.is_some() {
|
let clock_lims = if limits.clock_min.is_some() && limits.clock_max.is_some() {
|
||||||
other.clock_limits.map(|x| min_max_from_json(x, version))
|
other.clock_limits.map(|x| min_max_from_json(x, version))
|
||||||
} else {
|
} else {
|
||||||
|
@ -259,28 +274,29 @@ impl Cpu {
|
||||||
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
|
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
// set cpu online/offline
|
// set cpu online/offline
|
||||||
if self.index != 0 && self.state.do_set_online { // cpu0 cannot be disabled
|
if self.index != 0 && self.state.do_set_online {
|
||||||
|
// cpu0 cannot be disabled
|
||||||
let online_path = cpu_online_path(self.index);
|
let online_path = cpu_online_path(self.index);
|
||||||
usdpl_back::api::files::write_single(&online_path, self.online as u8).map_err(|e| {
|
usdpl_back::api::files::write_single(&online_path, self.online as u8)
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!("Failed to write to `{}`: {}", &online_path, e),
|
msg: format!("Failed to write to `{}`: {}", &online_path, e),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set governor
|
// set governor
|
||||||
if self.index == 0 || self.online {
|
if self.index == 0 || self.online {
|
||||||
let governor_path = cpu_governor_path(self.index);
|
let governor_path = cpu_governor_path(self.index);
|
||||||
usdpl_back::api::files::write_single(&governor_path, &self.governor).map_err(|e| {
|
usdpl_back::api::files::write_single(&governor_path, &self.governor)
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
&self.governor, &governor_path, e
|
&self.governor, &governor_path, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -301,13 +317,14 @@ impl Cpu {
|
||||||
|
|
||||||
fn governors(&self) -> Vec<String> {
|
fn governors(&self) -> Vec<String> {
|
||||||
// NOTE: this eats errors
|
// NOTE: this eats errors
|
||||||
let gov_str: String = match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) {
|
let gov_str: String =
|
||||||
Ok(s) => s,
|
match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) {
|
||||||
Err(e) => {
|
Ok(s) => s,
|
||||||
log::warn!("Error getting available CPU governors: {}", e);
|
Err(e) => {
|
||||||
return vec![];
|
log::warn!("Error getting available CPU governors: {}", e);
|
||||||
},
|
return vec![];
|
||||||
};
|
}
|
||||||
|
};
|
||||||
gov_str.split(' ').map(|s| s.to_owned()).collect()
|
gov_str.split(' ').map(|s| s.to_owned()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@ use std::convert::Into;
|
||||||
|
|
||||||
use limits_core::json::GenericGpuLimit;
|
use limits_core::json::GenericGpuLimit;
|
||||||
|
|
||||||
use crate::settings::{MinMax, min_max_from_json};
|
|
||||||
use crate::settings::{OnResume, OnSet, SettingError};
|
|
||||||
use crate::settings::TGpu;
|
|
||||||
use crate::persist::GpuJson;
|
use crate::persist::GpuJson;
|
||||||
|
use crate::settings::TGpu;
|
||||||
|
use crate::settings::{min_max_from_json, MinMax};
|
||||||
|
use crate::settings::{OnResume, OnSet, SettingError};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Gpu {
|
pub struct Gpu {
|
||||||
|
@ -40,7 +40,11 @@ impl Gpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_json_and_limits(other: GpuJson, version: u64, limits: limits_core::json::GenericGpuLimit) -> Self {
|
pub fn from_json_and_limits(
|
||||||
|
other: GpuJson,
|
||||||
|
version: u64,
|
||||||
|
limits: limits_core::json::GenericGpuLimit,
|
||||||
|
) -> Self {
|
||||||
let clock_lims = if limits.clock_min.is_some() && limits.clock_max.is_some() {
|
let clock_lims = if limits.clock_min.is_some() && limits.clock_max.is_some() {
|
||||||
other.clock_limits.map(|x| min_max_from_json(x, version))
|
other.clock_limits.map(|x| min_max_from_json(x, version))
|
||||||
} else {
|
} else {
|
||||||
|
@ -48,8 +52,16 @@ impl Gpu {
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
slow_memory: false,
|
slow_memory: false,
|
||||||
fast_ppt: if limits.fast_ppt.is_some() {other.fast_ppt} else {None},
|
fast_ppt: if limits.fast_ppt.is_some() {
|
||||||
slow_ppt: if limits.slow_ppt.is_some() {other.slow_ppt} else {None},
|
other.fast_ppt
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
slow_ppt: if limits.slow_ppt.is_some() {
|
||||||
|
other.slow_ppt
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
clock_limits: clock_lims,
|
clock_limits: clock_lims,
|
||||||
limits,
|
limits,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,13 @@
|
||||||
use limits_core::json::GenericCpuLimit;
|
|
||||||
use crate::persist::CpuJson;
|
use crate::persist::CpuJson;
|
||||||
|
use limits_core::json::GenericCpuLimit;
|
||||||
|
|
||||||
pub trait FromGenericCpuInfo {
|
pub trait FromGenericCpuInfo {
|
||||||
fn from_limits(cpu_index: usize, limits: GenericCpuLimit) -> Self;
|
fn from_limits(cpu_index: usize, limits: GenericCpuLimit) -> Self;
|
||||||
|
|
||||||
fn from_json_and_limits(other: CpuJson, version: u64, cpu_index: usize, limits: GenericCpuLimit) -> Self;
|
fn from_json_and_limits(
|
||||||
|
other: CpuJson,
|
||||||
|
version: u64,
|
||||||
|
cpu_index: usize,
|
||||||
|
limits: GenericCpuLimit,
|
||||||
|
) -> Self;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::persist::CpuJson;
|
use crate::persist::CpuJson;
|
||||||
use crate::settings::MinMax;
|
|
||||||
use crate::settings::generic::{Cpu as GenericCpu, Cpus as GenericCpus, FromGenericCpuInfo};
|
use crate::settings::generic::{Cpu as GenericCpu, Cpus as GenericCpus, FromGenericCpuInfo};
|
||||||
|
use crate::settings::MinMax;
|
||||||
use crate::settings::{OnResume, OnSet, SettingError};
|
use crate::settings::{OnResume, OnSet, SettingError};
|
||||||
use crate::settings::{TCpus, TCpu};
|
use crate::settings::{TCpu, TCpus};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Cpus {
|
pub struct Cpus {
|
||||||
|
@ -16,7 +16,11 @@ impl Cpus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_json_and_limits(other: Vec<CpuJson>, version: u64, limits: limits_core::json::GenericCpuLimit) -> Self {
|
pub fn from_json_and_limits(
|
||||||
|
other: Vec<CpuJson>,
|
||||||
|
version: u64,
|
||||||
|
limits: limits_core::json::GenericCpuLimit,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
generic: GenericCpus::from_json_and_limits(other, version, limits),
|
generic: GenericCpus::from_json_and_limits(other, version, limits),
|
||||||
}
|
}
|
||||||
|
@ -73,16 +77,17 @@ pub struct Cpu {
|
||||||
impl FromGenericCpuInfo for Cpu {
|
impl FromGenericCpuInfo for Cpu {
|
||||||
fn from_limits(cpu_index: usize, limits: limits_core::json::GenericCpuLimit) -> Self {
|
fn from_limits(cpu_index: usize, limits: limits_core::json::GenericCpuLimit) -> Self {
|
||||||
let gen = GenericCpu::from_limits(cpu_index, limits.clone());
|
let gen = GenericCpu::from_limits(cpu_index, limits.clone());
|
||||||
Self {
|
Self { generic: gen }
|
||||||
generic: gen,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_json_and_limits(other: CpuJson, version: u64, cpu_index: usize, limits: limits_core::json::GenericCpuLimit) -> Self {
|
fn from_json_and_limits(
|
||||||
|
other: CpuJson,
|
||||||
|
version: u64,
|
||||||
|
cpu_index: usize,
|
||||||
|
limits: limits_core::json::GenericCpuLimit,
|
||||||
|
) -> Self {
|
||||||
let gen = GenericCpu::from_json_and_limits(other, version, cpu_index, limits);
|
let gen = GenericCpu::from_json_and_limits(other, version, cpu_index, limits);
|
||||||
Self {
|
Self { generic: gen }
|
||||||
generic: gen,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use std::sync::Mutex;
|
|
||||||
use libryzenadj::RyzenAdj;
|
use libryzenadj::RyzenAdj;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use crate::persist::GpuJson;
|
use crate::persist::GpuJson;
|
||||||
use crate::settings::MinMax;
|
|
||||||
use crate::settings::generic::Gpu as GenericGpu;
|
use crate::settings::generic::Gpu as GenericGpu;
|
||||||
use crate::settings::{OnResume, OnSet, SettingError, SettingVariant};
|
use crate::settings::MinMax;
|
||||||
use crate::settings::TGpu;
|
use crate::settings::TGpu;
|
||||||
|
use crate::settings::{OnResume, OnSet, SettingError, SettingVariant};
|
||||||
|
|
||||||
fn ryzen_adj_or_log() -> Option<Mutex<RyzenAdj>> {
|
fn ryzen_adj_or_log() -> Option<Mutex<RyzenAdj>> {
|
||||||
match RyzenAdj::new() {
|
match RyzenAdj::new() {
|
||||||
|
@ -44,7 +44,11 @@ impl Gpu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_json_and_limits(other: GpuJson, version: u64, limits: limits_core::json::GenericGpuLimit) -> Self {
|
pub fn from_json_and_limits(
|
||||||
|
other: GpuJson,
|
||||||
|
version: u64,
|
||||||
|
limits: limits_core::json::GenericGpuLimit,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
generic: GenericGpu::from_json_and_limits(other, version, limits),
|
generic: GenericGpu::from_json_and_limits(other, version, limits),
|
||||||
implementor: ryzen_adj_or_log(),
|
implementor: ryzen_adj_or_log(),
|
||||||
|
@ -76,71 +80,95 @@ impl Gpu {
|
||||||
if self.state.old_fast_ppt.is_none() {
|
if self.state.old_fast_ppt.is_none() {
|
||||||
match lock.get_fast_value() {
|
match lock.get_fast_value() {
|
||||||
Ok(val) => self.state.old_fast_ppt = Some(val as _),
|
Ok(val) => self.state.old_fast_ppt = Some(val as _),
|
||||||
Err(e) => errors.push(
|
Err(e) => errors.push(SettingError {
|
||||||
SettingError {
|
msg: format!("RyzenAdj get_fast_value() err: {}", e),
|
||||||
msg: format!("RyzenAdj get_fast_value() err: {}", e),
|
setting: SettingVariant::Gpu,
|
||||||
setting: SettingVariant::Gpu,
|
}),
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
|
lock.set_fast_limit(*fast_ppt as _)
|
||||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
.map_err(|e| SettingError {
|
||||||
setting: SettingVariant::Gpu,
|
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
setting: SettingVariant::Gpu,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
} else if let Some(fast_ppt) = &self.state.old_fast_ppt {
|
} else if let Some(fast_ppt) = &self.state.old_fast_ppt {
|
||||||
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
|
lock.set_fast_limit(*fast_ppt as _)
|
||||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
.map_err(|e| SettingError {
|
||||||
setting: SettingVariant::Gpu,
|
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
setting: SettingVariant::Gpu,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
self.state.old_fast_ppt = None;
|
self.state.old_fast_ppt = None;
|
||||||
}
|
}
|
||||||
if let Some(slow_ppt) = &self.generic.slow_ppt {
|
if let Some(slow_ppt) = &self.generic.slow_ppt {
|
||||||
if self.state.old_slow_ppt.is_none() {
|
if self.state.old_slow_ppt.is_none() {
|
||||||
match lock.get_slow_value() {
|
match lock.get_slow_value() {
|
||||||
Ok(val) => self.state.old_fast_ppt = Some(val as _),
|
Ok(val) => self.state.old_fast_ppt = Some(val as _),
|
||||||
Err(e) => errors.push(
|
Err(e) => errors.push(SettingError {
|
||||||
SettingError {
|
msg: format!("RyzenAdj get_slow_value() err: {}", e),
|
||||||
msg: format!("RyzenAdj get_slow_value() err: {}", e),
|
setting: SettingVariant::Gpu,
|
||||||
setting: SettingVariant::Gpu,
|
}),
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
|
lock.set_slow_limit(*slow_ppt as _)
|
||||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
.map_err(|e| SettingError {
|
||||||
setting: SettingVariant::Gpu,
|
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
setting: SettingVariant::Gpu,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
} else if let Some(slow_ppt) = &self.state.old_slow_ppt {
|
} else if let Some(slow_ppt) = &self.state.old_slow_ppt {
|
||||||
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
|
lock.set_slow_limit(*slow_ppt as _)
|
||||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
.map_err(|e| SettingError {
|
||||||
setting: SettingVariant::Gpu,
|
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
setting: SettingVariant::Gpu,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
self.state.old_slow_ppt = None;
|
self.state.old_slow_ppt = None;
|
||||||
}
|
}
|
||||||
if let Some(clock_limits) = &self.generic.clock_limits {
|
if let Some(clock_limits) = &self.generic.clock_limits {
|
||||||
self.state.clock_limits_set = true;
|
self.state.clock_limits_set = true;
|
||||||
lock.set_max_gfxclk_freq(clock_limits.max as _).map_err(|e| SettingError {
|
lock.set_max_gfxclk_freq(clock_limits.max as _)
|
||||||
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", clock_limits.max, e),
|
.map_err(|e| SettingError {
|
||||||
setting: SettingVariant::Gpu,
|
msg: format!(
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
"RyzenAdj set_max_gfxclk_freq({}) err: {}",
|
||||||
lock.set_min_gfxclk_freq(clock_limits.min as _).map_err(|e| SettingError {
|
clock_limits.max, e
|
||||||
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", clock_limits.min, e),
|
),
|
||||||
setting: SettingVariant::Gpu,
|
setting: SettingVariant::Gpu,
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
|
lock.set_min_gfxclk_freq(clock_limits.min as _)
|
||||||
|
.map_err(|e| SettingError {
|
||||||
|
msg: format!(
|
||||||
|
"RyzenAdj set_min_gfxclk_freq({}) err: {}",
|
||||||
|
clock_limits.min, e
|
||||||
|
),
|
||||||
|
setting: SettingVariant::Gpu,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
} else if self.state.clock_limits_set {
|
} else if self.state.clock_limits_set {
|
||||||
self.state.clock_limits_set = false;
|
self.state.clock_limits_set = false;
|
||||||
let limits = self.generic.limits();
|
let limits = self.generic.limits();
|
||||||
if let Some(min_limits) = limits.clock_min_limits {
|
if let Some(min_limits) = limits.clock_min_limits {
|
||||||
if let Some(max_limits) = limits.clock_max_limits {
|
if let Some(max_limits) = limits.clock_max_limits {
|
||||||
lock.set_max_gfxclk_freq(max_limits.max as _).map_err(|e| SettingError {
|
lock.set_max_gfxclk_freq(max_limits.max as _)
|
||||||
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", max_limits.max, e),
|
.map_err(|e| SettingError {
|
||||||
setting: SettingVariant::Gpu,
|
msg: format!(
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
"RyzenAdj set_max_gfxclk_freq({}) err: {}",
|
||||||
lock.set_min_gfxclk_freq(min_limits.min as _).map_err(|e| SettingError {
|
max_limits.max, e
|
||||||
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", min_limits.min, e),
|
),
|
||||||
setting: SettingVariant::Gpu,
|
setting: SettingVariant::Gpu,
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
|
lock.set_min_gfxclk_freq(min_limits.min as _)
|
||||||
|
.map_err(|e| SettingError {
|
||||||
|
msg: format!(
|
||||||
|
"RyzenAdj set_min_gfxclk_freq({}) err: {}",
|
||||||
|
min_limits.min, e
|
||||||
|
),
|
||||||
|
setting: SettingVariant::Gpu,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,26 +202,40 @@ impl Gpu {
|
||||||
};
|
};
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
if let Some(fast_ppt) = &self.generic.fast_ppt {
|
if let Some(fast_ppt) = &self.generic.fast_ppt {
|
||||||
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
|
lock.set_fast_limit(*fast_ppt as _)
|
||||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
.map_err(|e| SettingError {
|
||||||
setting: SettingVariant::Gpu,
|
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
setting: SettingVariant::Gpu,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
if let Some(slow_ppt) = &self.generic.slow_ppt {
|
if let Some(slow_ppt) = &self.generic.slow_ppt {
|
||||||
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
|
lock.set_slow_limit(*slow_ppt as _)
|
||||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
.map_err(|e| SettingError {
|
||||||
setting: SettingVariant::Gpu,
|
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
setting: SettingVariant::Gpu,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
if let Some(clock_limits) = &self.generic.clock_limits {
|
if let Some(clock_limits) = &self.generic.clock_limits {
|
||||||
lock.set_max_gfxclk_freq(clock_limits.max as _).map_err(|e| SettingError {
|
lock.set_max_gfxclk_freq(clock_limits.max as _)
|
||||||
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", clock_limits.max, e),
|
.map_err(|e| SettingError {
|
||||||
setting: SettingVariant::Gpu,
|
msg: format!(
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
"RyzenAdj set_max_gfxclk_freq({}) err: {}",
|
||||||
lock.set_min_gfxclk_freq(clock_limits.min as _).map_err(|e| SettingError {
|
clock_limits.max, e
|
||||||
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", clock_limits.min, e),
|
),
|
||||||
setting: SettingVariant::Gpu,
|
setting: SettingVariant::Gpu,
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
|
lock.set_min_gfxclk_freq(clock_limits.min as _)
|
||||||
|
.map_err(|e| SettingError {
|
||||||
|
msg: format!(
|
||||||
|
"RyzenAdj set_min_gfxclk_freq({}) err: {}",
|
||||||
|
clock_limits.min, e
|
||||||
|
),
|
||||||
|
setting: SettingVariant::Gpu,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,11 @@ pub mod unknown;
|
||||||
|
|
||||||
pub use detect::{auto_detect0, auto_detect_provider, limits_worker::spawn as limits_worker_spawn};
|
pub use detect::{auto_detect0, auto_detect_provider, limits_worker::spawn as limits_worker_spawn};
|
||||||
pub use driver::Driver;
|
pub use driver::Driver;
|
||||||
pub use general::{SettingVariant, Settings, General};
|
pub use general::{General, SettingVariant, Settings};
|
||||||
pub use min_max::{MinMax, min_max_from_json};
|
pub use min_max::{min_max_from_json, MinMax};
|
||||||
|
|
||||||
pub use error::SettingError;
|
pub use error::SettingError;
|
||||||
pub use traits::{OnResume, OnSet, TGeneral, TGpu, TCpus, TBattery, TCpu, OnPowerEvent, PowerMode};
|
pub use traits::{OnPowerEvent, OnResume, OnSet, PowerMode, TBattery, TCpu, TCpus, TGeneral, TGpu};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
|
|
||||||
use crate::api::RangeLimit;
|
|
||||||
use crate::settings::{OnResume, OnSet, SettingError, OnPowerEvent, PowerMode};
|
|
||||||
use crate::settings::TBattery;
|
|
||||||
use crate::persist::{BatteryJson, BatteryEventJson};
|
|
||||||
use super::util::ChargeMode;
|
|
||||||
use super::oc_limits::{BatteryLimits, OverclockLimits};
|
use super::oc_limits::{BatteryLimits, OverclockLimits};
|
||||||
|
use super::util::ChargeMode;
|
||||||
|
use crate::api::RangeLimit;
|
||||||
|
use crate::persist::{BatteryEventJson, BatteryJson};
|
||||||
|
use crate::settings::TBattery;
|
||||||
|
use crate::settings::{OnPowerEvent, OnResume, OnSet, PowerMode, SettingError};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Battery {
|
pub struct Battery {
|
||||||
|
@ -40,11 +40,11 @@ impl OnPowerEvent for EventInstruction {
|
||||||
(EventTrigger::PluggedIn, PowerMode::PluggedIn) => {
|
(EventTrigger::PluggedIn, PowerMode::PluggedIn) => {
|
||||||
log::info!("Steam Deck plugged in event handled");
|
log::info!("Steam Deck plugged in event handled");
|
||||||
self.set_all()
|
self.set_all()
|
||||||
},
|
}
|
||||||
(EventTrigger::PluggedOut, PowerMode::PluggedOut) => {
|
(EventTrigger::PluggedOut, PowerMode::PluggedOut) => {
|
||||||
log::info!("Steam Deck plugged out event handled");
|
log::info!("Steam Deck plugged out event handled");
|
||||||
self.set_all()
|
self.set_all()
|
||||||
},
|
}
|
||||||
(EventTrigger::BatteryAbove(exp), PowerMode::BatteryCharge(act)) => {
|
(EventTrigger::BatteryAbove(exp), PowerMode::BatteryCharge(act)) => {
|
||||||
if act > *exp {
|
if act > *exp {
|
||||||
if self.is_triggered {
|
if self.is_triggered {
|
||||||
|
@ -58,7 +58,7 @@ impl OnPowerEvent for EventInstruction {
|
||||||
self.is_triggered = false;
|
self.is_triggered = false;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
(EventTrigger::BatteryBelow(exp), PowerMode::BatteryCharge(act)) => {
|
(EventTrigger::BatteryBelow(exp), PowerMode::BatteryCharge(act)) => {
|
||||||
if act < *exp {
|
if act < *exp {
|
||||||
if self.is_triggered {
|
if self.is_triggered {
|
||||||
|
@ -72,8 +72,8 @@ impl OnPowerEvent for EventInstruction {
|
||||||
self.is_triggered = false;
|
self.is_triggered = false;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => Ok(())
|
_ => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,8 +95,16 @@ impl EventInstruction {
|
||||||
match s {
|
match s {
|
||||||
"normal" => Some(EventTrigger::PluggedIn),
|
"normal" => Some(EventTrigger::PluggedIn),
|
||||||
"idle" => Some(EventTrigger::PluggedOut),
|
"idle" => Some(EventTrigger::PluggedOut),
|
||||||
s if s.starts_with('>') => s.trim_start_matches('>').parse::<f64>().ok().map(|x| EventTrigger::BatteryAbove(x)),
|
s if s.starts_with('>') => s
|
||||||
s if s.starts_with('<') => s.trim_start_matches('<').parse::<f64>().ok().map(|x| EventTrigger::BatteryBelow(x)),
|
.trim_start_matches('>')
|
||||||
|
.parse::<f64>()
|
||||||
|
.ok()
|
||||||
|
.map(|x| EventTrigger::BatteryAbove(x)),
|
||||||
|
s if s.starts_with('<') => s
|
||||||
|
.trim_start_matches('<')
|
||||||
|
.parse::<f64>()
|
||||||
|
.ok()
|
||||||
|
.map(|x| EventTrigger::BatteryBelow(x)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,19 +113,22 @@ impl EventInstruction {
|
||||||
Self {
|
Self {
|
||||||
trigger: Self::str_to_trigger(&other.trigger).unwrap_or(EventTrigger::Ignored),
|
trigger: Self::str_to_trigger(&other.trigger).unwrap_or(EventTrigger::Ignored),
|
||||||
charge_rate: other.charge_rate,
|
charge_rate: other.charge_rate,
|
||||||
charge_mode: other.charge_mode.map(|x| Battery::str_to_charge_mode(&x)).flatten(),
|
charge_mode: other
|
||||||
|
.charge_mode
|
||||||
|
.map(|x| Battery::str_to_charge_mode(&x))
|
||||||
|
.flatten(),
|
||||||
is_triggered: false,
|
is_triggered: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_charge_mode(&self) -> Result<(), SettingError> {
|
fn set_charge_mode(&self) -> Result<(), SettingError> {
|
||||||
if let Some(charge_mode) = self.charge_mode {
|
if let Some(charge_mode) = self.charge_mode {
|
||||||
super::util::set(super::util::Setting::ChargeMode, charge_mode as _).map_err(
|
super::util::set(super::util::Setting::ChargeMode, charge_mode as _)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!("Failed to set charge mode: {}", e),
|
msg: format!("Failed to set charge mode: {}", e),
|
||||||
setting: crate::settings::SettingVariant::Battery,
|
setting: crate::settings::SettingVariant::Battery,
|
||||||
},
|
})
|
||||||
).map(|_| ())
|
.map(|_| ())
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -125,18 +136,18 @@ impl EventInstruction {
|
||||||
|
|
||||||
fn set_charge_rate(&self) -> Result<(), SettingError> {
|
fn set_charge_rate(&self) -> Result<(), SettingError> {
|
||||||
if let Some(charge_rate) = self.charge_rate {
|
if let Some(charge_rate) = self.charge_rate {
|
||||||
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate).map_err(
|
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
||||||
setting: crate::settings::SettingVariant::Battery,
|
setting: crate::settings::SettingVariant::Battery,
|
||||||
},
|
})
|
||||||
).map(|_| ())
|
.map(|_| ())
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_all(&self) -> Result<(), Vec<SettingError>> {
|
fn set_all(&self) -> Result<(), Vec<SettingError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
|
|
||||||
self.set_charge_rate().unwrap_or_else(|e| errors.push(e));
|
self.set_charge_rate().unwrap_or_else(|e| errors.push(e));
|
||||||
|
@ -174,20 +185,38 @@ impl Battery {
|
||||||
pub fn from_json(other: BatteryJson, version: u64) -> Self {
|
pub fn from_json(other: BatteryJson, version: u64) -> Self {
|
||||||
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
||||||
let oc_limits = oc_limits.battery;
|
let oc_limits = oc_limits.battery;
|
||||||
let driver = if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance };
|
let driver = if is_default {
|
||||||
|
crate::persist::DriverJson::SteamDeck
|
||||||
|
} else {
|
||||||
|
crate::persist::DriverJson::SteamDeckAdvance
|
||||||
|
};
|
||||||
match version {
|
match version {
|
||||||
0 => Self {
|
0 => Self {
|
||||||
charge_rate: other.charge_rate,
|
charge_rate: other.charge_rate,
|
||||||
charge_mode: other.charge_mode.map(|x| Self::str_to_charge_mode(&x)).flatten(),
|
charge_mode: other
|
||||||
events: other.events.into_iter().map(|x| EventInstruction::from_json(x, version)).collect(),
|
.charge_mode
|
||||||
|
.map(|x| Self::str_to_charge_mode(&x))
|
||||||
|
.flatten(),
|
||||||
|
events: other
|
||||||
|
.events
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| EventInstruction::from_json(x, version))
|
||||||
|
.collect(),
|
||||||
limits: oc_limits,
|
limits: oc_limits,
|
||||||
state: crate::state::steam_deck::Battery::default(),
|
state: crate::state::steam_deck::Battery::default(),
|
||||||
driver_mode: driver,
|
driver_mode: driver,
|
||||||
},
|
},
|
||||||
_ => Self {
|
_ => Self {
|
||||||
charge_rate: other.charge_rate,
|
charge_rate: other.charge_rate,
|
||||||
charge_mode: other.charge_mode.map(|x| Self::str_to_charge_mode(&x)).flatten(),
|
charge_mode: other
|
||||||
events: other.events.into_iter().map(|x| EventInstruction::from_json(x, version)).collect(),
|
.charge_mode
|
||||||
|
.map(|x| Self::str_to_charge_mode(&x))
|
||||||
|
.flatten(),
|
||||||
|
events: other
|
||||||
|
.events
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| EventInstruction::from_json(x, version))
|
||||||
|
.collect(),
|
||||||
limits: oc_limits,
|
limits: oc_limits,
|
||||||
state: crate::state::steam_deck::Battery::default(),
|
state: crate::state::steam_deck::Battery::default(),
|
||||||
driver_mode: driver,
|
driver_mode: driver,
|
||||||
|
@ -201,7 +230,8 @@ impl Battery {
|
||||||
ChargeMode::Normal => "normal",
|
ChargeMode::Normal => "normal",
|
||||||
ChargeMode::Idle => "idle",
|
ChargeMode::Idle => "idle",
|
||||||
ChargeMode::Discharge => "discharge",
|
ChargeMode::Discharge => "discharge",
|
||||||
}.to_owned()
|
}
|
||||||
|
.to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -217,20 +247,20 @@ impl Battery {
|
||||||
fn set_charge_mode(&mut self) -> Result<(), SettingError> {
|
fn set_charge_mode(&mut self) -> Result<(), SettingError> {
|
||||||
if let Some(charge_mode) = self.charge_mode {
|
if let Some(charge_mode) = self.charge_mode {
|
||||||
self.state.charge_mode_set = true;
|
self.state.charge_mode_set = true;
|
||||||
super::util::set(super::util::Setting::ChargeMode, charge_mode as _).map_err(
|
super::util::set(super::util::Setting::ChargeMode, charge_mode as _)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!("Failed to set charge mode: {}", e),
|
msg: format!("Failed to set charge mode: {}", e),
|
||||||
setting: crate::settings::SettingVariant::Battery,
|
setting: crate::settings::SettingVariant::Battery,
|
||||||
},
|
})
|
||||||
).map(|_| ())
|
.map(|_| ())
|
||||||
} else if self.state.charge_mode_set {
|
} else if self.state.charge_mode_set {
|
||||||
self.state.charge_mode_set = false;
|
self.state.charge_mode_set = false;
|
||||||
super::util::set(super::util::Setting::ChargeMode, ChargeMode::Normal as _).map_err(
|
super::util::set(super::util::Setting::ChargeMode, ChargeMode::Normal as _)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!("Failed to set charge mode: {}", e),
|
msg: format!("Failed to set charge mode: {}", e),
|
||||||
setting: crate::settings::SettingVariant::Battery,
|
setting: crate::settings::SettingVariant::Battery,
|
||||||
},
|
})
|
||||||
).map(|_| ())
|
.map(|_| ())
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -240,20 +270,23 @@ impl Battery {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
if let Some(charge_rate) = self.charge_rate {
|
if let Some(charge_rate) = self.charge_rate {
|
||||||
self.state.charge_rate_set = true;
|
self.state.charge_rate_set = true;
|
||||||
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate).map_err(
|
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
||||||
setting: crate::settings::SettingVariant::Battery,
|
setting: crate::settings::SettingVariant::Battery,
|
||||||
},
|
})
|
||||||
).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
} else if self.state.charge_rate_set {
|
} else if self.state.charge_rate_set {
|
||||||
self.state.charge_rate_set = false;
|
self.state.charge_rate_set = false;
|
||||||
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, self.limits.charge_rate.max).map_err(
|
usdpl_back::api::files::write_single(
|
||||||
|e| SettingError {
|
BATTERY_CHARGE_RATE_PATH,
|
||||||
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
self.limits.charge_rate.max,
|
||||||
setting: crate::settings::SettingVariant::Battery,
|
)
|
||||||
},
|
.map_err(|e| SettingError {
|
||||||
).unwrap_or_else(|e| errors.push(e));
|
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
||||||
|
setting: crate::settings::SettingVariant::Battery,
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
self.set_charge_mode().unwrap_or_else(|e| errors.push(e));
|
self.set_charge_mode().unwrap_or_else(|e| errors.push(e));
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
|
@ -265,7 +298,8 @@ impl Battery {
|
||||||
|
|
||||||
fn clamp_all(&mut self) {
|
fn clamp_all(&mut self) {
|
||||||
if let Some(charge_rate) = &mut self.charge_rate {
|
if let Some(charge_rate) = &mut self.charge_rate {
|
||||||
*charge_rate = (*charge_rate).clamp(self.limits.charge_rate.min, self.limits.charge_rate.max);
|
*charge_rate =
|
||||||
|
(*charge_rate).clamp(self.limits.charge_rate.min, self.limits.charge_rate.max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,7 +340,10 @@ impl Battery {
|
||||||
pub fn read_charge_design() -> Result<f64, SettingError> {
|
pub fn read_charge_design() -> Result<f64, SettingError> {
|
||||||
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_DESIGN_PATH) {
|
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_DESIGN_PATH) {
|
||||||
Err(e) => Err(SettingError {
|
Err(e) => Err(SettingError {
|
||||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_DESIGN_PATH, e),
|
msg: format!(
|
||||||
|
"Failed to read from `{}`: {}",
|
||||||
|
BATTERY_CHARGE_DESIGN_PATH, e
|
||||||
|
),
|
||||||
setting: crate::settings::SettingVariant::Battery,
|
setting: crate::settings::SettingVariant::Battery,
|
||||||
}),
|
}),
|
||||||
// convert to Wh
|
// convert to Wh
|
||||||
|
@ -321,14 +358,18 @@ impl Battery {
|
||||||
setting: crate::settings::SettingVariant::Battery,
|
setting: crate::settings::SettingVariant::Battery,
|
||||||
}),
|
}),
|
||||||
// convert to V (from mV)
|
// convert to V (from mV)
|
||||||
Ok(val) => Ok((val as f64)/1000.0),
|
Ok(val) => Ok((val as f64) / 1000.0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn system_default() -> Self {
|
pub fn system_default() -> Self {
|
||||||
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
||||||
let oc_limits = oc_limits.battery;
|
let oc_limits = oc_limits.battery;
|
||||||
let driver = if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance };
|
let driver = if is_default {
|
||||||
|
crate::persist::DriverJson::SteamDeck
|
||||||
|
} else {
|
||||||
|
crate::persist::DriverJson::SteamDeckAdvance
|
||||||
|
};
|
||||||
Self {
|
Self {
|
||||||
charge_rate: None,
|
charge_rate: None,
|
||||||
charge_mode: None,
|
charge_mode: None,
|
||||||
|
@ -346,8 +387,8 @@ impl Battery {
|
||||||
if event.charge_mode.is_some() {
|
if event.charge_mode.is_some() {
|
||||||
return Some(i);
|
return Some(i);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => {},
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -360,8 +401,8 @@ impl Battery {
|
||||||
if event.charge_mode.is_some() {
|
if event.charge_mode.is_some() {
|
||||||
return Some(i);
|
return Some(i);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => {},
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -374,7 +415,7 @@ impl Into<BatteryJson> for Battery {
|
||||||
BatteryJson {
|
BatteryJson {
|
||||||
charge_rate: self.charge_rate,
|
charge_rate: self.charge_rate,
|
||||||
charge_mode: self.charge_mode.map(Self::charge_mode_to_str),
|
charge_mode: self.charge_mode.map(Self::charge_mode_to_str),
|
||||||
events: self.events.into_iter().map(|x| x.into()).collect()
|
events: self.events.into_iter().map(|x| x.into()).collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -398,20 +439,24 @@ impl OnPowerEvent for Battery {
|
||||||
match new_mode {
|
match new_mode {
|
||||||
PowerMode::PluggedIn => {
|
PowerMode::PluggedIn => {
|
||||||
// plug event resets battery settings
|
// plug event resets battery settings
|
||||||
self.events.iter_mut().for_each(|ev| ev.is_triggered = false);
|
self.events
|
||||||
self.set_charge_mode()
|
.iter_mut()
|
||||||
.map_err(|e| vec![e])
|
.for_each(|ev| ev.is_triggered = false);
|
||||||
},
|
self.set_charge_mode().map_err(|e| vec![e])
|
||||||
|
}
|
||||||
PowerMode::PluggedOut => {
|
PowerMode::PluggedOut => {
|
||||||
// plug event resets battery settings
|
// plug event resets battery settings
|
||||||
self.events.iter_mut().for_each(|ev| ev.is_triggered = false);
|
self.events
|
||||||
self.set_charge_mode()
|
.iter_mut()
|
||||||
.map_err(|e| vec![e])
|
.for_each(|ev| ev.is_triggered = false);
|
||||||
},
|
self.set_charge_mode().map_err(|e| vec![e])
|
||||||
PowerMode::BatteryCharge(_) => Ok(())
|
}
|
||||||
}.unwrap_or_else(|mut e| errors.append(&mut e));
|
PowerMode::BatteryCharge(_) => Ok(()),
|
||||||
|
}
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
for ev in &mut self.events {
|
for ev in &mut self.events {
|
||||||
ev.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
ev.on_power_event(new_mode)
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
}
|
}
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -424,12 +469,16 @@ impl OnPowerEvent for Battery {
|
||||||
impl TBattery for Battery {
|
impl TBattery for Battery {
|
||||||
fn limits(&self) -> crate::api::BatteryLimits {
|
fn limits(&self) -> crate::api::BatteryLimits {
|
||||||
crate::api::BatteryLimits {
|
crate::api::BatteryLimits {
|
||||||
charge_current: Some(RangeLimit{
|
charge_current: Some(RangeLimit {
|
||||||
min: self.limits.charge_rate.min,
|
min: self.limits.charge_rate.min,
|
||||||
max: self.limits.charge_rate.max
|
max: self.limits.charge_rate.max,
|
||||||
}),
|
}),
|
||||||
charge_current_step: 50,
|
charge_current_step: 50,
|
||||||
charge_modes: vec!["normal".to_owned(), "discharge".to_owned(), "idle".to_owned()],
|
charge_modes: vec![
|
||||||
|
"normal".to_owned(),
|
||||||
|
"discharge".to_owned(),
|
||||||
|
"idle".to_owned(),
|
||||||
|
],
|
||||||
charge_limit: Some(RangeLimit {
|
charge_limit: Some(RangeLimit {
|
||||||
min: 10.0,
|
min: 10.0,
|
||||||
max: 90.0,
|
max: 90.0,
|
||||||
|
@ -503,9 +552,12 @@ impl TBattery for Battery {
|
||||||
let index = self.find_limit_event();
|
let index = self.find_limit_event();
|
||||||
if let Some(index) = index {
|
if let Some(index) = index {
|
||||||
if let Some(limit) = limit {
|
if let Some(limit) = limit {
|
||||||
log::info!("Updating Steam Deck charge limit event instruction to >{}", limit);
|
log::info!(
|
||||||
|
"Updating Steam Deck charge limit event instruction to >{}",
|
||||||
|
limit
|
||||||
|
);
|
||||||
self.events[index] = EventInstruction {
|
self.events[index] = EventInstruction {
|
||||||
trigger: EventTrigger::BatteryAbove(limit/100.0),
|
trigger: EventTrigger::BatteryAbove(limit / 100.0),
|
||||||
charge_rate: None,
|
charge_rate: None,
|
||||||
charge_mode: Some(ChargeMode::Idle),
|
charge_mode: Some(ChargeMode::Idle),
|
||||||
is_triggered: false,
|
is_triggered: false,
|
||||||
|
@ -514,24 +566,28 @@ impl TBattery for Battery {
|
||||||
self.events.remove(index);
|
self.events.remove(index);
|
||||||
}
|
}
|
||||||
} else if let Some(limit) = limit {
|
} else if let Some(limit) = limit {
|
||||||
log::info!("Creating Steam Deck charge limit event instruction of >{}", limit);
|
log::info!(
|
||||||
self.events.push(
|
"Creating Steam Deck charge limit event instruction of >{}",
|
||||||
EventInstruction {
|
limit
|
||||||
trigger: EventTrigger::BatteryAbove(limit/100.0),
|
|
||||||
charge_rate: None,
|
|
||||||
charge_mode: Some(ChargeMode::Idle),
|
|
||||||
is_triggered: false,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
self.events.push(EventInstruction {
|
||||||
|
trigger: EventTrigger::BatteryAbove(limit / 100.0),
|
||||||
|
charge_rate: None,
|
||||||
|
charge_mode: Some(ChargeMode::Idle),
|
||||||
|
is_triggered: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// lower limit
|
// lower limit
|
||||||
let index = self.find_unlimit_event();
|
let index = self.find_unlimit_event();
|
||||||
if let Some(index) = index {
|
if let Some(index) = index {
|
||||||
if let Some(limit) = limit {
|
if let Some(limit) = limit {
|
||||||
let limit = (limit - 10.0).clamp(0.0, 100.0);
|
let limit = (limit - 10.0).clamp(0.0, 100.0);
|
||||||
log::info!("Updating Steam Deck charge limit event instruction to <{}", limit);
|
log::info!(
|
||||||
|
"Updating Steam Deck charge limit event instruction to <{}",
|
||||||
|
limit
|
||||||
|
);
|
||||||
self.events[index] = EventInstruction {
|
self.events[index] = EventInstruction {
|
||||||
trigger: EventTrigger::BatteryBelow(limit/100.0),
|
trigger: EventTrigger::BatteryBelow(limit / 100.0),
|
||||||
charge_rate: None,
|
charge_rate: None,
|
||||||
charge_mode: Some(ChargeMode::Normal),
|
charge_mode: Some(ChargeMode::Normal),
|
||||||
is_triggered: false,
|
is_triggered: false,
|
||||||
|
@ -541,15 +597,16 @@ impl TBattery for Battery {
|
||||||
}
|
}
|
||||||
} else if let Some(limit) = limit {
|
} else if let Some(limit) = limit {
|
||||||
let limit = (limit - 10.0).clamp(0.0, 100.0);
|
let limit = (limit - 10.0).clamp(0.0, 100.0);
|
||||||
log::info!("Creating Steam Deck charge limit event instruction of <{}", limit);
|
log::info!(
|
||||||
self.events.push(
|
"Creating Steam Deck charge limit event instruction of <{}",
|
||||||
EventInstruction {
|
limit
|
||||||
trigger: EventTrigger::BatteryBelow(limit/100.0),
|
|
||||||
charge_rate: None,
|
|
||||||
charge_mode: Some(ChargeMode::Normal),
|
|
||||||
is_triggered: false,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
self.events.push(EventInstruction {
|
||||||
|
trigger: EventTrigger::BatteryBelow(limit / 100.0),
|
||||||
|
charge_rate: None,
|
||||||
|
charge_mode: Some(ChargeMode::Normal),
|
||||||
|
is_triggered: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,24 +629,28 @@ impl TBattery for Battery {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
let mut events = Vec::new();
|
let mut events = Vec::new();
|
||||||
match (Self::read_charge_full(), Self::read_charge_now()) {
|
match (Self::read_charge_full(), Self::read_charge_now()) {
|
||||||
(Ok(full), Ok(now)) => events.push(PowerMode::BatteryCharge(now/full)),
|
(Ok(full), Ok(now)) => events.push(PowerMode::BatteryCharge(now / full)),
|
||||||
(Err(e1), Err(e2)) => {
|
(Err(e1), Err(e2)) => {
|
||||||
errors.push(e1);
|
errors.push(e1);
|
||||||
errors.push(e2);
|
errors.push(e2);
|
||||||
},
|
}
|
||||||
(Err(e), _) => errors.push(e),
|
(Err(e), _) => errors.push(e),
|
||||||
(_, Err(e)) => errors.push(e),
|
(_, Err(e)) => errors.push(e),
|
||||||
}
|
}
|
||||||
match Self::read_usb_voltage() {
|
match Self::read_usb_voltage() {
|
||||||
Ok(voltage) => {
|
Ok(voltage) => {
|
||||||
if voltage > 0.0 && self.state.charger_state != crate::state::steam_deck::ChargeState::PluggedIn {
|
if voltage > 0.0
|
||||||
|
&& self.state.charger_state != crate::state::steam_deck::ChargeState::PluggedIn
|
||||||
|
{
|
||||||
events.push(PowerMode::PluggedIn);
|
events.push(PowerMode::PluggedIn);
|
||||||
self.state.charger_state = crate::state::steam_deck::ChargeState::PluggedIn;
|
self.state.charger_state = crate::state::steam_deck::ChargeState::PluggedIn;
|
||||||
} else if voltage == 0.0 && self.state.charger_state != crate::state::steam_deck::ChargeState::Unplugged {
|
} else if voltage == 0.0
|
||||||
|
&& self.state.charger_state != crate::state::steam_deck::ChargeState::Unplugged
|
||||||
|
{
|
||||||
events.push(PowerMode::PluggedOut);
|
events.push(PowerMode::PluggedOut);
|
||||||
self.state.charger_state = crate::state::steam_deck::ChargeState::Unplugged;
|
self.state.charger_state = crate::state::steam_deck::ChargeState::Unplugged;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => errors.push(e),
|
Err(e) => errors.push(e),
|
||||||
}
|
}
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
|
|
||||||
use crate::api::RangeLimit;
|
use super::oc_limits::{CpuLimits, CpusLimits, OverclockLimits};
|
||||||
use crate::settings::{MinMax, min_max_from_json};
|
|
||||||
use crate::settings::{OnResume, OnSet, SettingError};
|
|
||||||
use crate::settings::{TCpus, TCpu};
|
|
||||||
use crate::persist::CpuJson;
|
|
||||||
use super::oc_limits::{OverclockLimits, CpusLimits, CpuLimits};
|
|
||||||
use super::POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT;
|
use super::POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT;
|
||||||
|
use crate::api::RangeLimit;
|
||||||
|
use crate::persist::CpuJson;
|
||||||
|
use crate::settings::{min_max_from_json, MinMax};
|
||||||
|
use crate::settings::{OnResume, OnSet, SettingError};
|
||||||
|
use crate::settings::{TCpu, TCpus};
|
||||||
|
|
||||||
const CPU_PRESENT_PATH: &str = "/sys/devices/system/cpu/present";
|
const CPU_PRESENT_PATH: &str = "/sys/devices/system/cpu/present";
|
||||||
const CPU_SMT_PATH: &str = "/sys/devices/system/cpu/smt/control";
|
const CPU_SMT_PATH: &str = "/sys/devices/system/cpu/smt/control";
|
||||||
|
@ -26,25 +26,19 @@ impl OnSet for Cpus {
|
||||||
if self.smt_capable {
|
if self.smt_capable {
|
||||||
// toggle SMT
|
// toggle SMT
|
||||||
if self.smt {
|
if self.smt {
|
||||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on").map_err(|e| {
|
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on")
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!("Failed to write `on` to `{}`: {}", CPU_SMT_PATH, e),
|
||||||
"Failed to write `on` to `{}`: {}",
|
|
||||||
CPU_SMT_PATH, e
|
|
||||||
),
|
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
} else {
|
} else {
|
||||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off").map_err(|e| {
|
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off")
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!("Failed to write `off` to `{}`: {}", CPU_SMT_PATH, e),
|
||||||
"Failed to write `off` to `{}`: {}",
|
|
||||||
CPU_SMT_PATH, e
|
|
||||||
),
|
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
|
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
|
||||||
|
@ -63,7 +57,8 @@ impl OnResume for Cpus {
|
||||||
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
|
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
for cpu in &self.cpus {
|
for cpu in &self.cpus {
|
||||||
cpu.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
cpu.on_resume()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
}
|
}
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -90,7 +85,7 @@ impl Cpus {
|
||||||
fn system_smt_capabilities() -> (bool, bool) {
|
fn system_smt_capabilities() -> (bool, bool) {
|
||||||
match usdpl_back::api::files::read_single::<_, String, _>(CPU_SMT_PATH) {
|
match usdpl_back::api::files::read_single::<_, String, _>(CPU_SMT_PATH) {
|
||||||
Ok(val) => (val.trim().to_lowercase() == "on", true),
|
Ok(val) => (val.trim().to_lowercase() == "on", true),
|
||||||
Err(_) => (false, false)
|
Err(_) => (false, false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,11 +93,22 @@ impl Cpus {
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.reset();
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.reset();
|
||||||
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
||||||
let oc_limits = oc_limits.cpus;
|
let oc_limits = oc_limits.cpus;
|
||||||
let driver = if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance };
|
let driver = if is_default {
|
||||||
|
crate::persist::DriverJson::SteamDeck
|
||||||
|
} else {
|
||||||
|
crate::persist::DriverJson::SteamDeckAdvance
|
||||||
|
};
|
||||||
if let Some(max_cpu) = Self::cpu_count() {
|
if let Some(max_cpu) = Self::cpu_count() {
|
||||||
let mut sys_cpus = Vec::with_capacity(max_cpu);
|
let mut sys_cpus = Vec::with_capacity(max_cpu);
|
||||||
for i in 0..max_cpu {
|
for i in 0..max_cpu {
|
||||||
sys_cpus.push(Cpu::system_default(i, oc_limits.cpus.get(i).map(|x| x.to_owned()).unwrap_or_default()));
|
sys_cpus.push(Cpu::system_default(
|
||||||
|
i,
|
||||||
|
oc_limits
|
||||||
|
.cpus
|
||||||
|
.get(i)
|
||||||
|
.map(|x| x.to_owned())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let (_, can_smt) = Self::system_smt_capabilities();
|
let (_, can_smt) = Self::system_smt_capabilities();
|
||||||
Self {
|
Self {
|
||||||
|
@ -128,7 +134,11 @@ impl Cpus {
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.reset();
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.reset();
|
||||||
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
||||||
let oc_limits = oc_limits.cpus;
|
let oc_limits = oc_limits.cpus;
|
||||||
let driver = if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance };
|
let driver = if is_default {
|
||||||
|
crate::persist::DriverJson::SteamDeck
|
||||||
|
} else {
|
||||||
|
crate::persist::DriverJson::SteamDeckAdvance
|
||||||
|
};
|
||||||
let (_, can_smt) = Self::system_smt_capabilities();
|
let (_, can_smt) = Self::system_smt_capabilities();
|
||||||
let mut result = Vec::with_capacity(other.len());
|
let mut result = Vec::with_capacity(other.len());
|
||||||
let max_cpus = Self::cpu_count();
|
let max_cpus = Self::cpu_count();
|
||||||
|
@ -140,7 +150,16 @@ impl Cpus {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let new_cpu = Cpu::from_json(cpu, version, i, oc_limits.cpus.get(i).map(|x| x.to_owned()).unwrap_or_default());
|
let new_cpu = Cpu::from_json(
|
||||||
|
cpu,
|
||||||
|
version,
|
||||||
|
i,
|
||||||
|
oc_limits
|
||||||
|
.cpus
|
||||||
|
.get(i)
|
||||||
|
.map(|x| x.to_owned())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
);
|
||||||
result.push(new_cpu);
|
result.push(new_cpu);
|
||||||
}
|
}
|
||||||
if let Some(max_cpus) = max_cpus {
|
if let Some(max_cpus) = max_cpus {
|
||||||
|
@ -170,11 +189,14 @@ impl TCpus for Cpus {
|
||||||
count: self.cpus.len(),
|
count: self.cpus.len(),
|
||||||
smt_capable: self.smt_capable,
|
smt_capable: self.smt_capable,
|
||||||
governors: if self.limits.global_governors {
|
governors: if self.limits.global_governors {
|
||||||
self.cpus.iter()
|
self.cpus
|
||||||
|
.iter()
|
||||||
.next()
|
.next()
|
||||||
.map(|x| x.governors())
|
.map(|x| x.governors())
|
||||||
.unwrap_or_else(|| Vec::with_capacity(0))
|
.unwrap_or_else(|| Vec::with_capacity(0))
|
||||||
} else { Vec::with_capacity(0) },
|
} else {
|
||||||
|
Vec::with_capacity(0)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,41 +266,52 @@ impl Cpu {
|
||||||
if let Some(clock_limits) = &self.clock_limits {
|
if let Some(clock_limits) = &self.clock_limits {
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(true, self.index);
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(true, self.index);
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
||||||
log::debug!("Setting CPU {} (min, max) clockspeed to ({}, {})", self.index, clock_limits.min, clock_limits.max);
|
log::debug!(
|
||||||
|
"Setting CPU {} (min, max) clockspeed to ({}, {})",
|
||||||
|
self.index,
|
||||||
|
clock_limits.min,
|
||||||
|
clock_limits.max
|
||||||
|
);
|
||||||
self.state.clock_limits_set = true;
|
self.state.clock_limits_set = true;
|
||||||
// max clock
|
// max clock
|
||||||
let payload_max = format!("p {} 1 {}\n", self.index / 2, clock_limits.max);
|
let payload_max = format!("p {} 1 {}\n", self.index / 2, clock_limits.max);
|
||||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max).map_err(
|
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
&payload_max, CPU_CLOCK_LIMITS_PATH, e
|
&payload_max, CPU_CLOCK_LIMITS_PATH, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
},
|
})
|
||||||
).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
// min clock
|
// min clock
|
||||||
let valid_min = if clock_limits.min < self.limits.clock_min.min {self.limits.clock_min.min} else {clock_limits.min};
|
let valid_min = if clock_limits.min < self.limits.clock_min.min {
|
||||||
|
self.limits.clock_min.min
|
||||||
|
} else {
|
||||||
|
clock_limits.min
|
||||||
|
};
|
||||||
let payload_min = format!("p {} 0 {}\n", self.index / 2, valid_min);
|
let payload_min = format!("p {} 0 {}\n", self.index / 2, valid_min);
|
||||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min).map_err(
|
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
&payload_min, CPU_CLOCK_LIMITS_PATH, e
|
&payload_min, CPU_CLOCK_LIMITS_PATH, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
},
|
})
|
||||||
).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n")
|
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|
||||||
.unwrap_or_else(|e| {
|
|e| {
|
||||||
errors.push(SettingError {
|
errors.push(SettingError {
|
||||||
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
|
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
} else if self.state.clock_limits_set ||
|
);
|
||||||
(self.state.is_resuming && !self.limits.skip_resume_reclock)
|
} else if self.state.clock_limits_set
|
||||||
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
|| (self.state.is_resuming && !self.limits.skip_resume_reclock)
|
||||||
|
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual()
|
||||||
|
{
|
||||||
self.state.clock_limits_set = false;
|
self.state.clock_limits_set = false;
|
||||||
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
||||||
|
@ -286,45 +319,51 @@ impl Cpu {
|
||||||
log::debug!("Setting CPU {} to default clockspeed", self.index);
|
log::debug!("Setting CPU {} to default clockspeed", self.index);
|
||||||
// max clock
|
// max clock
|
||||||
let payload_max = format!("p {} 1 {}\n", self.index / 2, self.limits.clock_max.max);
|
let payload_max = format!("p {} 1 {}\n", self.index / 2, self.limits.clock_max.max);
|
||||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max).map_err(
|
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
&payload_max, CPU_CLOCK_LIMITS_PATH, e
|
&payload_max, CPU_CLOCK_LIMITS_PATH, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
},
|
})
|
||||||
).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
// min clock
|
// min clock
|
||||||
let payload_min = format!("p {} 0 {}\n", self.index / 2, self.limits.clock_min.min);
|
let payload_min = format!("p {} 0 {}\n", self.index / 2, self.limits.clock_min.min);
|
||||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min).map_err(
|
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
&payload_min, CPU_CLOCK_LIMITS_PATH, e
|
&payload_min, CPU_CLOCK_LIMITS_PATH, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
},
|
})
|
||||||
).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n")
|
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|
||||||
.unwrap_or_else(|e| {
|
|e| {
|
||||||
errors.push(SettingError {
|
errors.push(SettingError {
|
||||||
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
|
msg: format!(
|
||||||
|
"Failed to write `c` to `{}`: {}",
|
||||||
|
CPU_CLOCK_LIMITS_PATH, e
|
||||||
|
),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(false, self.index);
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(false, self.index);
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level().unwrap_or_else(|mut e| errors.append(&mut e));
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||||
|
.enforce_level()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
}
|
}
|
||||||
// commit changes (if no errors have already occured)
|
// commit changes (if no errors have already occured)
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n").map_err(|e| {
|
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n").map_err(|e| {
|
||||||
vec![SettingError {
|
vec![SettingError {
|
||||||
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
|
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(errors)
|
Err(errors)
|
||||||
}
|
}
|
||||||
|
@ -333,14 +372,15 @@ impl Cpu {
|
||||||
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
|
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
// set cpu online/offline
|
// set cpu online/offline
|
||||||
if self.index != 0 && self.state.do_set_online { // cpu0 cannot be disabled
|
if self.index != 0 && self.state.do_set_online {
|
||||||
|
// cpu0 cannot be disabled
|
||||||
let online_path = cpu_online_path(self.index);
|
let online_path = cpu_online_path(self.index);
|
||||||
usdpl_back::api::files::write_single(&online_path, self.online as u8).map_err(|e| {
|
usdpl_back::api::files::write_single(&online_path, self.online as u8)
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!("Failed to write to `{}`: {}", &online_path, e),
|
msg: format!("Failed to write to `{}`: {}", &online_path, e),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set_force_performance_related()
|
self.set_force_performance_related()
|
||||||
|
@ -349,15 +389,15 @@ impl Cpu {
|
||||||
// set governor
|
// set governor
|
||||||
if self.index == 0 || self.online {
|
if self.index == 0 || self.online {
|
||||||
let governor_path = cpu_governor_path(self.index);
|
let governor_path = cpu_governor_path(self.index);
|
||||||
usdpl_back::api::files::write_single(&governor_path, &self.governor).map_err(|e| {
|
usdpl_back::api::files::write_single(&governor_path, &self.governor)
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
&self.governor, &governor_path, e
|
&self.governor, &governor_path, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -368,8 +408,12 @@ impl Cpu {
|
||||||
|
|
||||||
fn clamp_all(&mut self) {
|
fn clamp_all(&mut self) {
|
||||||
if let Some(clock_limits) = &mut self.clock_limits {
|
if let Some(clock_limits) = &mut self.clock_limits {
|
||||||
clock_limits.min = clock_limits.min.clamp(self.limits.clock_min.min, self.limits.clock_min.max);
|
clock_limits.min = clock_limits
|
||||||
clock_limits.max = clock_limits.max.clamp(self.limits.clock_max.min, self.limits.clock_max.max);
|
.min
|
||||||
|
.clamp(self.limits.clock_min.min, self.limits.clock_min.max);
|
||||||
|
clock_limits.max = clock_limits
|
||||||
|
.max
|
||||||
|
.clamp(self.limits.clock_max.min, self.limits.clock_max.max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,11 +444,11 @@ impl Cpu {
|
||||||
crate::api::CpuLimits {
|
crate::api::CpuLimits {
|
||||||
clock_min_limits: Some(RangeLimit {
|
clock_min_limits: Some(RangeLimit {
|
||||||
min: self.limits.clock_max.min, // allows min to be set by max (it's weird, blame the kernel)
|
min: self.limits.clock_max.min, // allows min to be set by max (it's weird, blame the kernel)
|
||||||
max: self.limits.clock_min.max
|
max: self.limits.clock_min.max,
|
||||||
}),
|
}),
|
||||||
clock_max_limits: Some(RangeLimit {
|
clock_max_limits: Some(RangeLimit {
|
||||||
min: self.limits.clock_max.min,
|
min: self.limits.clock_max.min,
|
||||||
max: self.limits.clock_max.max
|
max: self.limits.clock_max.max,
|
||||||
}),
|
}),
|
||||||
clock_step: self.limits.clock_step,
|
clock_step: self.limits.clock_step,
|
||||||
governors: self.governors(),
|
governors: self.governors(),
|
||||||
|
@ -413,13 +457,14 @@ impl Cpu {
|
||||||
|
|
||||||
fn governors(&self) -> Vec<String> {
|
fn governors(&self) -> Vec<String> {
|
||||||
// NOTE: this eats errors
|
// NOTE: this eats errors
|
||||||
let gov_str: String = match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) {
|
let gov_str: String =
|
||||||
Ok(s) => s,
|
match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) {
|
||||||
Err(e) => {
|
Ok(s) => s,
|
||||||
log::warn!("Error getting available CPU governors: {}", e);
|
Err(e) => {
|
||||||
return vec![];
|
log::warn!("Error getting available CPU governors: {}", e);
|
||||||
}
|
return vec![];
|
||||||
};
|
}
|
||||||
|
};
|
||||||
gov_str.split(' ').map(|s| s.to_owned()).collect()
|
gov_str.split(' ').map(|s| s.to_owned()).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -485,7 +530,6 @@ fn cpu_governor_path(index: usize) -> String {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cpu_available_governors_path(index: usize) -> String {
|
fn cpu_available_governors_path(index: usize) -> String {
|
||||||
format!(
|
format!(
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
|
|
||||||
use crate::api::RangeLimit;
|
use super::oc_limits::{GpuLimits, OverclockLimits};
|
||||||
use crate::settings::{MinMax, min_max_from_json};
|
|
||||||
use crate::settings::{OnResume, OnSet, SettingError};
|
|
||||||
use crate::settings::TGpu;
|
|
||||||
use crate::persist::GpuJson;
|
|
||||||
use super::oc_limits::{OverclockLimits, GpuLimits};
|
|
||||||
use super::POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT;
|
use super::POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT;
|
||||||
|
use crate::api::RangeLimit;
|
||||||
|
use crate::persist::GpuJson;
|
||||||
|
use crate::settings::TGpu;
|
||||||
|
use crate::settings::{min_max_from_json, MinMax};
|
||||||
|
use crate::settings::{OnResume, OnSet, SettingError};
|
||||||
|
|
||||||
const SLOW_PPT: u8 = 1;
|
const SLOW_PPT: u8 = 1;
|
||||||
const FAST_PPT: u8 = 2;
|
const FAST_PPT: u8 = 2;
|
||||||
|
@ -30,7 +30,11 @@ impl Gpu {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_json(other: GpuJson, version: u64) -> Self {
|
pub fn from_json(other: GpuJson, version: u64) -> Self {
|
||||||
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
||||||
let driver = if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance };
|
let driver = if is_default {
|
||||||
|
crate::persist::DriverJson::SteamDeck
|
||||||
|
} else {
|
||||||
|
crate::persist::DriverJson::SteamDeckAdvance
|
||||||
|
};
|
||||||
match version {
|
match version {
|
||||||
0 => Self {
|
0 => Self {
|
||||||
fast_ppt: other.fast_ppt,
|
fast_ppt: other.fast_ppt,
|
||||||
|
@ -62,70 +66,80 @@ impl Gpu {
|
||||||
self.state.clock_limits_set = true;
|
self.state.clock_limits_set = true;
|
||||||
// max clock
|
// max clock
|
||||||
let payload_max = format!("s 1 {}\n", clock_limits.max);
|
let payload_max = format!("s 1 {}\n", clock_limits.max);
|
||||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max).map_err(
|
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
&payload_max, GPU_CLOCK_LIMITS_PATH, e
|
&payload_max, GPU_CLOCK_LIMITS_PATH, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
setting: crate::settings::SettingVariant::Gpu,
|
||||||
},
|
})
|
||||||
).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
// min clock
|
// min clock
|
||||||
let payload_min = format!("s 0 {}\n", clock_limits.min);
|
let payload_min = format!("s 0 {}\n", clock_limits.min);
|
||||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min).map_err(
|
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
&payload_min, GPU_CLOCK_LIMITS_PATH, e
|
&payload_min, GPU_CLOCK_LIMITS_PATH, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
setting: crate::settings::SettingVariant::Gpu,
|
||||||
},
|
|
||||||
).unwrap_or_else(|e| errors.push(e));
|
|
||||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(|e| {
|
|
||||||
errors.push(SettingError {
|
|
||||||
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
|
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
|
||||||
})
|
})
|
||||||
});
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
} else if self.state.clock_limits_set ||
|
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|
||||||
(self.state.is_resuming && !self.limits.skip_resume_reclock)
|
|e| {
|
||||||
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
errors.push(SettingError {
|
||||||
|
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
|
||||||
|
setting: crate::settings::SettingVariant::Gpu,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else if self.state.clock_limits_set
|
||||||
|
|| (self.state.is_resuming && !self.limits.skip_resume_reclock)
|
||||||
|
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual()
|
||||||
|
{
|
||||||
self.state.clock_limits_set = false;
|
self.state.clock_limits_set = false;
|
||||||
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
||||||
// disable manual clock limits
|
// disable manual clock limits
|
||||||
// max clock
|
// max clock
|
||||||
let payload_max = format!("s 1 {}\n", self.limits.clock_max.max);
|
let payload_max = format!("s 1 {}\n", self.limits.clock_max.max);
|
||||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max).map_err(
|
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
&payload_max, GPU_CLOCK_LIMITS_PATH, e
|
&payload_max, GPU_CLOCK_LIMITS_PATH, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
setting: crate::settings::SettingVariant::Gpu,
|
||||||
},
|
})
|
||||||
).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
// min clock
|
// min clock
|
||||||
let payload_min = format!("s 0 {}\n", self.limits.clock_min.min);
|
let payload_min = format!("s 0 {}\n", self.limits.clock_min.min);
|
||||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min).map_err(
|
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||||
|e| SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
&payload_min, GPU_CLOCK_LIMITS_PATH, e
|
&payload_min, GPU_CLOCK_LIMITS_PATH, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
setting: crate::settings::SettingVariant::Gpu,
|
||||||
},
|
|
||||||
).unwrap_or_else(|e| errors.push(e));
|
|
||||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(|e| {
|
|
||||||
errors.push(SettingError {
|
|
||||||
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
|
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
|
||||||
})
|
})
|
||||||
});
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
|
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|
||||||
|
|e| {
|
||||||
|
errors.push(SettingError {
|
||||||
|
msg: format!(
|
||||||
|
"Failed to write `c` to `{}`: {}",
|
||||||
|
GPU_CLOCK_LIMITS_PATH, e
|
||||||
|
),
|
||||||
|
setting: crate::settings::SettingVariant::Gpu,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.slow_memory);
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.slow_memory);
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level().unwrap_or_else(|mut e| errors.append(&mut e));
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||||
|
.enforce_level()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
}
|
}
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -139,24 +153,28 @@ impl Gpu {
|
||||||
// enable/disable downclock of GPU memory (to 400Mhz?)
|
// enable/disable downclock of GPU memory (to 400Mhz?)
|
||||||
if self.slow_memory {
|
if self.slow_memory {
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(true);
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(true);
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level().unwrap_or_else(|mut e| errors.append(&mut e));
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||||
|
.enforce_level()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
usdpl_back::api::files::write_single(GPU_MEMORY_DOWNCLOCK_PATH, self.slow_memory as u8)
|
usdpl_back::api::files::write_single(GPU_MEMORY_DOWNCLOCK_PATH, self.slow_memory as u8)
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
errors.push(SettingError {
|
errors.push(SettingError {
|
||||||
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
|
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
setting: crate::settings::SettingVariant::Gpu,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
} else if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
} else if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||||
usdpl_back::api::files::write_single(GPU_MEMORY_DOWNCLOCK_PATH, self.slow_memory as u8)
|
usdpl_back::api::files::write_single(GPU_MEMORY_DOWNCLOCK_PATH, self.slow_memory as u8)
|
||||||
.unwrap_or_else(|e| {
|
.unwrap_or_else(|e| {
|
||||||
errors.push(SettingError {
|
errors.push(SettingError {
|
||||||
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
|
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
setting: crate::settings::SettingVariant::Gpu,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.clock_limits.is_some());
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.clock_limits.is_some());
|
||||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level().unwrap_or_else(|mut e| errors.append(&mut e));
|
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||||
|
.enforce_level()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
}
|
}
|
||||||
self.set_clocks()
|
self.set_clocks()
|
||||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
|
@ -182,28 +200,32 @@ impl Gpu {
|
||||||
// set fast PPT
|
// set fast PPT
|
||||||
if let Some(fast_ppt) = &self.fast_ppt {
|
if let Some(fast_ppt) = &self.fast_ppt {
|
||||||
let fast_ppt_path = gpu_power_path(FAST_PPT);
|
let fast_ppt_path = gpu_power_path(FAST_PPT);
|
||||||
usdpl_back::api::files::write_single(&fast_ppt_path, fast_ppt).map_err(|e| {
|
usdpl_back::api::files::write_single(&fast_ppt_path, fast_ppt)
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
fast_ppt, &fast_ppt_path, e
|
fast_ppt, &fast_ppt_path, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
setting: crate::settings::SettingVariant::Gpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| {errors.push(e);});
|
.unwrap_or_else(|e| {
|
||||||
|
errors.push(e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// set slow PPT
|
// set slow PPT
|
||||||
if let Some(slow_ppt) = &self.slow_ppt {
|
if let Some(slow_ppt) = &self.slow_ppt {
|
||||||
let slow_ppt_path = gpu_power_path(SLOW_PPT);
|
let slow_ppt_path = gpu_power_path(SLOW_PPT);
|
||||||
usdpl_back::api::files::write_single(&slow_ppt_path, slow_ppt).map_err(|e| {
|
usdpl_back::api::files::write_single(&slow_ppt_path, slow_ppt)
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
slow_ppt, &slow_ppt_path, e
|
slow_ppt, &slow_ppt_path, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Gpu,
|
setting: crate::settings::SettingVariant::Gpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| {errors.push(e);});
|
.unwrap_or_else(|e| {
|
||||||
|
errors.push(e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
self.set_force_performance_related()
|
self.set_force_performance_related()
|
||||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
|
@ -216,20 +238,18 @@ impl Gpu {
|
||||||
|
|
||||||
fn clamp_all(&mut self) {
|
fn clamp_all(&mut self) {
|
||||||
if let Some(fast_ppt) = &mut self.fast_ppt {
|
if let Some(fast_ppt) = &mut self.fast_ppt {
|
||||||
*fast_ppt = (*fast_ppt).clamp(
|
*fast_ppt = (*fast_ppt).clamp(self.limits.fast_ppt.min, self.limits.fast_ppt.max);
|
||||||
self.limits.fast_ppt.min,
|
|
||||||
self.limits.fast_ppt.max,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if let Some(slow_ppt) = &mut self.slow_ppt {
|
if let Some(slow_ppt) = &mut self.slow_ppt {
|
||||||
*slow_ppt = (*slow_ppt).clamp(
|
*slow_ppt = (*slow_ppt).clamp(self.limits.slow_ppt.min, self.limits.slow_ppt.max);
|
||||||
self.limits.slow_ppt.min,
|
|
||||||
self.limits.slow_ppt.max,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if let Some(clock_limits) = &mut self.clock_limits {
|
if let Some(clock_limits) = &mut self.clock_limits {
|
||||||
clock_limits.min = clock_limits.min.clamp(self.limits.clock_min.min, self.limits.clock_min.max);
|
clock_limits.min = clock_limits
|
||||||
clock_limits.max = clock_limits.max.clamp(self.limits.clock_max.min, self.limits.clock_max.max);
|
.min
|
||||||
|
.clamp(self.limits.clock_min.min, self.limits.clock_min.max);
|
||||||
|
clock_limits.max = clock_limits
|
||||||
|
.max
|
||||||
|
.clamp(self.limits.clock_max.min, self.limits.clock_max.max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +262,11 @@ impl Gpu {
|
||||||
slow_memory: false,
|
slow_memory: false,
|
||||||
limits: oc_limits.gpu,
|
limits: oc_limits.gpu,
|
||||||
state: crate::state::steam_deck::Gpu::default(),
|
state: crate::state::steam_deck::Gpu::default(),
|
||||||
driver_mode: if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance },
|
driver_mode: if is_default {
|
||||||
|
crate::persist::DriverJson::SteamDeck
|
||||||
|
} else {
|
||||||
|
crate::persist::DriverJson::SteamDeckAdvance
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,7 +338,10 @@ impl TGpu for Gpu {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_ppt(&self) -> (Option<u64>, Option<u64>) {
|
fn get_ppt(&self) -> (Option<u64>, Option<u64>) {
|
||||||
(self.fast_ppt.map(|x| x / self.limits.ppt_divisor), self.slow_ppt.map(|x| x / self.limits.ppt_divisor))
|
(
|
||||||
|
self.fast_ppt.map(|x| x / self.limits.ppt_divisor),
|
||||||
|
self.slow_ppt.map(|x| x / self.limits.ppt_divisor),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clock_limits(&mut self, limits: Option<MinMax<u64>>) {
|
fn clock_limits(&mut self, limits: Option<MinMax<u64>>) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use crate::settings::MinMax;
|
use crate::settings::MinMax;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
const OC_LIMITS_FILEPATH: &str = "pt_oc.json";
|
const OC_LIMITS_FILEPATH: &str = "pt_oc.json";
|
||||||
|
|
||||||
|
@ -29,22 +29,36 @@ impl OverclockLimits {
|
||||||
let mut file = match std::fs::File::open(&path) {
|
let mut file = match std::fs::File::open(&path) {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("Steam Deck limits file {} err: {} (using default fallback)", path.display(), e);
|
log::warn!(
|
||||||
|
"Steam Deck limits file {} err: {} (using default fallback)",
|
||||||
|
path.display(),
|
||||||
|
e
|
||||||
|
);
|
||||||
return (Self::default(), true);
|
return (Self::default(), true);
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
match serde_json::from_reader(&mut file) {
|
match serde_json::from_reader(&mut file) {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
log::debug!("Steam Deck limits file {} successfully loaded", path.display());
|
log::debug!(
|
||||||
|
"Steam Deck limits file {} successfully loaded",
|
||||||
|
path.display()
|
||||||
|
);
|
||||||
(result, false)
|
(result, false)
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("Steam Deck limits file {} json err: {} (using default fallback)", path.display(), e);
|
log::warn!(
|
||||||
|
"Steam Deck limits file {} json err: {} (using default fallback)",
|
||||||
|
path.display(),
|
||||||
|
e
|
||||||
|
);
|
||||||
(Self::default(), true)
|
(Self::default(), true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log::info!("Steam Deck limits file {} not found (using default fallback)", path.display());
|
log::info!(
|
||||||
|
"Steam Deck limits file {} not found (using default fallback)",
|
||||||
|
path.display()
|
||||||
|
);
|
||||||
(Self::default(), true)
|
(Self::default(), true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +72,10 @@ pub(super) struct BatteryLimits {
|
||||||
impl Default for BatteryLimits {
|
impl Default for BatteryLimits {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
charge_rate: MinMax { min: 250, max: 2500 },
|
charge_rate: MinMax {
|
||||||
|
min: 250,
|
||||||
|
max: 2500,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,8 +106,14 @@ pub(super) struct CpuLimits {
|
||||||
impl Default for CpuLimits {
|
impl Default for CpuLimits {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
clock_min: MinMax { min: 1400, max: 3500 },
|
clock_min: MinMax {
|
||||||
clock_max: MinMax { min: 400, max: 3500 },
|
min: 1400,
|
||||||
|
max: 3500,
|
||||||
|
},
|
||||||
|
clock_max: MinMax {
|
||||||
|
min: 400,
|
||||||
|
max: 3500,
|
||||||
|
},
|
||||||
clock_step: 100,
|
clock_step: 100,
|
||||||
skip_resume_reclock: false,
|
skip_resume_reclock: false,
|
||||||
}
|
}
|
||||||
|
@ -112,12 +135,24 @@ pub(super) struct GpuLimits {
|
||||||
impl Default for GpuLimits {
|
impl Default for GpuLimits {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
fast_ppt: MinMax { min: 1000000, max: 30_000_000 },
|
fast_ppt: MinMax {
|
||||||
slow_ppt: MinMax { min: 1000000, max: 29_000_000 },
|
min: 1000000,
|
||||||
|
max: 30_000_000,
|
||||||
|
},
|
||||||
|
slow_ppt: MinMax {
|
||||||
|
min: 1000000,
|
||||||
|
max: 29_000_000,
|
||||||
|
},
|
||||||
ppt_divisor: 1_000_000,
|
ppt_divisor: 1_000_000,
|
||||||
ppt_step: 1,
|
ppt_step: 1,
|
||||||
clock_min: MinMax { min: 400, max: 1600 },
|
clock_min: MinMax {
|
||||||
clock_max: MinMax { min: 400, max: 1600 },
|
min: 400,
|
||||||
|
max: 1600,
|
||||||
|
},
|
||||||
|
clock_max: MinMax {
|
||||||
|
min: 400,
|
||||||
|
max: 1600,
|
||||||
|
},
|
||||||
clock_step: 100,
|
clock_step: 100,
|
||||||
skip_resume_reclock: false,
|
skip_resume_reclock: false,
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,8 @@ use crate::settings::SettingError;
|
||||||
const DEFAULT_BITS: u64 = 0;
|
const DEFAULT_BITS: u64 = 0;
|
||||||
|
|
||||||
/// Global usage tracker for the sysfs file by the same name
|
/// Global usage tracker for the sysfs file by the same name
|
||||||
pub static POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT: PDFPLManager = PDFPLManager(AtomicU64::new(DEFAULT_BITS));
|
pub static POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT: PDFPLManager =
|
||||||
|
PDFPLManager(AtomicU64::new(DEFAULT_BITS));
|
||||||
|
|
||||||
pub struct PDFPLManager(AtomicU64);
|
pub struct PDFPLManager(AtomicU64);
|
||||||
|
|
||||||
|
@ -58,41 +59,45 @@ impl PDFPLManager {
|
||||||
pub fn enforce_level(&self) -> Result<(), Vec<SettingError>> {
|
pub fn enforce_level(&self) -> Result<(), Vec<SettingError>> {
|
||||||
let needs = self.needs_manual();
|
let needs = self.needs_manual();
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
let mode: String = usdpl_back::api::files::read_single(DPM_FORCE_LIMITS_PATH.to_owned()).map_err(|e| {
|
let mode: String = usdpl_back::api::files::read_single(DPM_FORCE_LIMITS_PATH.to_owned())
|
||||||
vec![SettingError {
|
.map_err(|e| {
|
||||||
msg: format!(
|
vec![SettingError {
|
||||||
"Failed to read `{}`: {}",
|
msg: format!("Failed to read `{}`: {}", DPM_FORCE_LIMITS_PATH, e),
|
||||||
DPM_FORCE_LIMITS_PATH, e
|
setting: crate::settings::SettingVariant::General,
|
||||||
),
|
}]
|
||||||
setting: crate::settings::SettingVariant::General,
|
})?;
|
||||||
}]
|
|
||||||
})?;
|
|
||||||
if mode != "manual" && needs {
|
if mode != "manual" && needs {
|
||||||
log::info!("Setting `{}` to manual", DPM_FORCE_LIMITS_PATH);
|
log::info!("Setting `{}` to manual", DPM_FORCE_LIMITS_PATH);
|
||||||
// set manual control
|
// set manual control
|
||||||
usdpl_back::api::files::write_single(DPM_FORCE_LIMITS_PATH, "manual").map_err(|e| {
|
usdpl_back::api::files::write_single(DPM_FORCE_LIMITS_PATH, "manual")
|
||||||
errors.push(SettingError {
|
.map_err(|e| {
|
||||||
msg: format!(
|
errors.push(SettingError {
|
||||||
"Failed to write `manual` to `{}`: {}",
|
msg: format!(
|
||||||
DPM_FORCE_LIMITS_PATH, e
|
"Failed to write `manual` to `{}`: {}",
|
||||||
),
|
DPM_FORCE_LIMITS_PATH, e
|
||||||
setting: crate::settings::SettingVariant::General,
|
),
|
||||||
|
setting: crate::settings::SettingVariant::General,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}).unwrap_or(());
|
.unwrap_or(());
|
||||||
} else if mode != "auto" && !needs {
|
} else if mode != "auto" && !needs {
|
||||||
log::info!("Setting `{}` to auto", DPM_FORCE_LIMITS_PATH);
|
log::info!("Setting `{}` to auto", DPM_FORCE_LIMITS_PATH);
|
||||||
// unset manual control
|
// unset manual control
|
||||||
usdpl_back::api::files::write_single(DPM_FORCE_LIMITS_PATH, "auto").map_err(|e| {
|
usdpl_back::api::files::write_single(DPM_FORCE_LIMITS_PATH, "auto")
|
||||||
errors.push(SettingError {
|
.map_err(|e| {
|
||||||
msg: format!(
|
errors.push(SettingError {
|
||||||
"Failed to write `auto` to `{}`: {}",
|
msg: format!(
|
||||||
DPM_FORCE_LIMITS_PATH, e
|
"Failed to write `auto` to `{}`: {}",
|
||||||
),
|
DPM_FORCE_LIMITS_PATH, e
|
||||||
setting: crate::settings::SettingVariant::General,
|
),
|
||||||
|
setting: crate::settings::SettingVariant::General,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}).unwrap_or(());
|
.unwrap_or(());
|
||||||
}
|
}
|
||||||
if let Ok(mode_now) = usdpl_back::api::files::read_single::<_, String, _>(DPM_FORCE_LIMITS_PATH.to_owned()) {
|
if let Ok(mode_now) =
|
||||||
|
usdpl_back::api::files::read_single::<_, String, _>(DPM_FORCE_LIMITS_PATH.to_owned())
|
||||||
|
{
|
||||||
log::debug!("Mode for `{}` is now `{}`", DPM_FORCE_LIMITS_PATH, mode_now);
|
log::debug!("Mode for `{}` is now `{}`", DPM_FORCE_LIMITS_PATH, mode_now);
|
||||||
} else {
|
} else {
|
||||||
log::debug!("Error getting new mode for debugging purposes");
|
log::debug!("Error getting new mode for debugging purposes");
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::{Error, Seek, SeekFrom, Read, Write};
|
use std::io::{Error, Read, Seek, SeekFrom, Write};
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write2(p0: u8, p1: u8) -> Result<usize, Error> {
|
fn write2(p0: u8, p1: u8) -> Result<usize, Error> {
|
||||||
|
@ -27,17 +27,13 @@ fn write_read(p0: u8) -> Result<u8, Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_to(location: u64, value: u8) -> Result<usize, Error> {
|
fn write_to(location: u64, value: u8) -> Result<usize, Error> {
|
||||||
let mut file = OpenOptions::new()
|
let mut file = OpenOptions::new().write(true).open("/dev/port")?;
|
||||||
.write(true)
|
|
||||||
.open("/dev/port")?;
|
|
||||||
file.seek(SeekFrom::Start(location))?;
|
file.seek(SeekFrom::Start(location))?;
|
||||||
file.write(&[value])
|
file.write(&[value])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_from(location: u64) -> Result<u8, Error> {
|
fn read_from(location: u64) -> Result<u8, Error> {
|
||||||
let mut file = OpenOptions::new()
|
let mut file = OpenOptions::new().read(true).open("/dev/port")?;
|
||||||
.read(true)
|
|
||||||
.open("/dev/port")?;
|
|
||||||
file.seek(SeekFrom::Start(location))?;
|
file.seek(SeekFrom::Start(location))?;
|
||||||
let mut buffer = [0];
|
let mut buffer = [0];
|
||||||
file.read(&mut buffer)?;
|
file.read(&mut buffer)?;
|
||||||
|
@ -61,21 +57,26 @@ fn wait_ready_for_read() -> Result<(), Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_led(red_unused: bool, green_aka_white: bool, blue_unused: bool) -> Result<usize, Error> {
|
pub fn set_led(red_unused: bool, green_aka_white: bool, blue_unused: bool) -> Result<usize, Error> {
|
||||||
let payload: u8 = 0x80 | (red_unused as u8 & 1) | ((green_aka_white as u8 & 1) << 1) | ((blue_unused as u8 & 1) << 2);
|
let payload: u8 = 0x80
|
||||||
|
| (red_unused as u8 & 1)
|
||||||
|
| ((green_aka_white as u8 & 1) << 1)
|
||||||
|
| ((blue_unused as u8 & 1) << 2);
|
||||||
//log::info!("Payload: {:b}", payload);
|
//log::info!("Payload: {:b}", payload);
|
||||||
write2(Setting::LEDStatus as _, payload)
|
write2(Setting::LEDStatus as _, payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
const THINGS: &[u8] = &[
|
const THINGS: &[u8] = &[
|
||||||
1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0,
|
||||||
1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1,
|
||||||
1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0,
|
||||||
|
0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
const TIME_UNIT: std::time::Duration = std::time::Duration::from_millis(200);
|
const TIME_UNIT: std::time::Duration = std::time::Duration::from_millis(200);
|
||||||
|
|
||||||
pub fn flash_led() {
|
pub fn flash_led() {
|
||||||
let old_led_state = write_read(Setting::LEDStatus as _).map_err(|e| log::error!("Failed to read LED status: {}", e));
|
let old_led_state = write_read(Setting::LEDStatus as _)
|
||||||
|
.map_err(|e| log::error!("Failed to read LED status: {}", e));
|
||||||
for &code in THINGS {
|
for &code in THINGS {
|
||||||
let on = code != 0;
|
let on = code != 0;
|
||||||
if let Err(e) = set_led(on, on, false) {
|
if let Err(e) = set_led(on, on, false) {
|
||||||
|
@ -85,7 +86,9 @@ pub fn flash_led() {
|
||||||
}
|
}
|
||||||
if let Ok(old_led_state) = old_led_state {
|
if let Ok(old_led_state) = old_led_state {
|
||||||
log::debug!("Restoring LED state to {:#02b}", old_led_state);
|
log::debug!("Restoring LED state to {:#02b}", old_led_state);
|
||||||
write2(Setting::LEDStatus as _, old_led_state).map_err(|e| log::error!("Failed to restore LED status: {}", e)).unwrap();
|
write2(Setting::LEDStatus as _, old_led_state)
|
||||||
|
.map_err(|e| log::error!("Failed to restore LED status: {}", e))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::fmt::Debug;
|
|
||||||
use super::SettingError;
|
|
||||||
use super::MinMax;
|
use super::MinMax;
|
||||||
|
use super::SettingError;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
pub trait OnSet {
|
pub trait OnSet {
|
||||||
fn on_set(&mut self) -> Result<(), Vec<SettingError>>;
|
fn on_set(&mut self) -> Result<(), Vec<SettingError>>;
|
||||||
|
@ -14,7 +14,7 @@ pub trait OnResume {
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum PowerMode {
|
pub enum PowerMode {
|
||||||
PluggedIn,
|
PluggedIn,
|
||||||
PluggedOut, // unplugged
|
PluggedOut, // unplugged
|
||||||
BatteryCharge(f64), // battery fill amount: 0 = empty, 1 = full
|
BatteryCharge(f64), // battery fill amount: 0 = empty, 1 = full
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ pub trait TBattery: OnSet + OnResume + OnPowerEvent + Debug + Send {
|
||||||
log::warn!("Power event check using default trait implementation");
|
log::warn!("Power event check using default trait implementation");
|
||||||
let mut events = Vec::new();
|
let mut events = Vec::new();
|
||||||
if let (Some(full), Some(now)) = (self.read_charge_full(), self.read_charge_now()) {
|
if let (Some(full), Some(now)) = (self.read_charge_full(), self.read_charge_now()) {
|
||||||
events.push(PowerMode::BatteryCharge(now/full));
|
events.push(PowerMode::BatteryCharge(now / full));
|
||||||
}
|
}
|
||||||
Ok(events)
|
Ok(events)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
|
|
||||||
use crate::settings::{OnResume, OnSet, SettingError};
|
|
||||||
use crate::settings::TBattery;
|
|
||||||
use crate::persist::BatteryJson;
|
use crate::persist::BatteryJson;
|
||||||
|
use crate::settings::TBattery;
|
||||||
|
use crate::settings::{OnResume, OnSet, SettingError};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Battery;
|
pub struct Battery;
|
||||||
|
@ -47,31 +47,39 @@ impl TBattery for Battery {
|
||||||
self.clone().into()
|
self.clone().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn charge_rate(&mut self, _rate: Option<u64>) {
|
fn charge_rate(&mut self, _rate: Option<u64>) {}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_charge_rate(&self) -> Option<u64> {
|
fn get_charge_rate(&self) -> Option<u64> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn charge_mode(&mut self, _rate: Option<String>) {
|
fn charge_mode(&mut self, _rate: Option<String>) {}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_charge_mode(&self) -> Option<String> {
|
fn get_charge_mode(&self) -> Option<String> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_charge_full(&self) -> Option<f64> { None }
|
fn read_charge_full(&self) -> Option<f64> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn read_charge_now(&self) -> Option<f64> { None }
|
fn read_charge_now(&self) -> Option<f64> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn read_charge_design(&self) -> Option<f64> { None }
|
fn read_charge_design(&self) -> Option<f64> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn read_current_now(&self) -> Option<f64> { None }
|
fn read_current_now(&self) -> Option<f64> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn charge_limit(&mut self, _limit: Option<f64>) {}
|
fn charge_limit(&mut self, _limit: Option<f64>) {}
|
||||||
|
|
||||||
fn get_charge_limit(&self) -> Option<f64> { None }
|
fn get_charge_limit(&self) -> Option<f64> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn provider(&self) -> crate::persist::DriverJson {
|
fn provider(&self) -> crate::persist::DriverJson {
|
||||||
crate::persist::DriverJson::Unknown
|
crate::persist::DriverJson::Unknown
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
|
|
||||||
|
use crate::persist::CpuJson;
|
||||||
use crate::settings::MinMax;
|
use crate::settings::MinMax;
|
||||||
use crate::settings::{OnResume, OnSet, SettingError};
|
use crate::settings::{OnResume, OnSet, SettingError};
|
||||||
use crate::settings::{TCpus, TCpu};
|
use crate::settings::{TCpu, TCpus};
|
||||||
use crate::persist::CpuJson;
|
|
||||||
|
|
||||||
const CPU_PRESENT_PATH: &str = "/sys/devices/system/cpu/present";
|
const CPU_PRESENT_PATH: &str = "/sys/devices/system/cpu/present";
|
||||||
const CPU_SMT_PATH: &str = "/sys/devices/system/cpu/smt/control";
|
const CPU_SMT_PATH: &str = "/sys/devices/system/cpu/smt/control";
|
||||||
|
@ -21,25 +21,23 @@ impl OnSet for Cpus {
|
||||||
if self.smt_capable {
|
if self.smt_capable {
|
||||||
// toggle SMT
|
// toggle SMT
|
||||||
if self.smt {
|
if self.smt {
|
||||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on").map_err(|e| {
|
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on")
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!("Failed to write `on` to `{}`: {}", CPU_SMT_PATH, e),
|
||||||
"Failed to write `on` to `{}`: {}",
|
|
||||||
CPU_SMT_PATH, e
|
|
||||||
),
|
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| {errors.push(e);});
|
.unwrap_or_else(|e| {
|
||||||
|
errors.push(e);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off").map_err(|e| {
|
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off")
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!("Failed to write `off` to `{}`: {}", CPU_SMT_PATH, e),
|
||||||
"Failed to write `off` to `{}`: {}",
|
|
||||||
CPU_SMT_PATH, e
|
|
||||||
),
|
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| {errors.push(e);});
|
.unwrap_or_else(|e| {
|
||||||
|
errors.push(e);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
|
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
|
||||||
|
@ -58,7 +56,8 @@ impl OnResume for Cpus {
|
||||||
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
|
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
for cpu in &self.cpus {
|
for cpu in &self.cpus {
|
||||||
cpu.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
cpu.on_resume()
|
||||||
|
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||||
}
|
}
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -87,7 +86,7 @@ impl Cpus {
|
||||||
fn system_smt_capabilities() -> (bool, bool) {
|
fn system_smt_capabilities() -> (bool, bool) {
|
||||||
match usdpl_back::api::files::read_single::<_, String, _>(CPU_SMT_PATH) {
|
match usdpl_back::api::files::read_single::<_, String, _>(CPU_SMT_PATH) {
|
||||||
Ok(val) => (val.trim().to_lowercase() == "on", true),
|
Ok(val) => (val.trim().to_lowercase() == "on", true),
|
||||||
Err(_) => (false, false)
|
Err(_) => (false, false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +182,6 @@ pub struct Cpu {
|
||||||
state: crate::state::steam_deck::Cpu,
|
state: crate::state::steam_deck::Cpu,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Cpu {
|
impl Cpu {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_json(other: CpuJson, version: u64, i: usize) -> Self {
|
pub fn from_json(other: CpuJson, version: u64, i: usize) -> Self {
|
||||||
|
@ -206,28 +204,29 @@ impl Cpu {
|
||||||
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
|
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
// set cpu online/offline
|
// set cpu online/offline
|
||||||
if self.index != 0 && self.state.do_set_online { // cpu0 cannot be disabled
|
if self.index != 0 && self.state.do_set_online {
|
||||||
|
// cpu0 cannot be disabled
|
||||||
let online_path = cpu_online_path(self.index);
|
let online_path = cpu_online_path(self.index);
|
||||||
usdpl_back::api::files::write_single(&online_path, self.online as u8).map_err(|e| {
|
usdpl_back::api::files::write_single(&online_path, self.online as u8)
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!("Failed to write to `{}`: {}", &online_path, e),
|
msg: format!("Failed to write to `{}`: {}", &online_path, e),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set governor
|
// set governor
|
||||||
if self.index == 0 || self.online {
|
if self.index == 0 || self.online {
|
||||||
let governor_path = cpu_governor_path(self.index);
|
let governor_path = cpu_governor_path(self.index);
|
||||||
usdpl_back::api::files::write_single(&governor_path, &self.governor).map_err(|e| {
|
usdpl_back::api::files::write_single(&governor_path, &self.governor)
|
||||||
SettingError {
|
.map_err(|e| SettingError {
|
||||||
msg: format!(
|
msg: format!(
|
||||||
"Failed to write `{}` to `{}`: {}",
|
"Failed to write `{}` to `{}`: {}",
|
||||||
&self.governor, &governor_path, e
|
&self.governor, &governor_path, e
|
||||||
),
|
),
|
||||||
setting: crate::settings::SettingVariant::Cpu,
|
setting: crate::settings::SettingVariant::Cpu,
|
||||||
}
|
})
|
||||||
}).unwrap_or_else(|e| errors.push(e));
|
.unwrap_or_else(|e| errors.push(e));
|
||||||
}
|
}
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -238,7 +237,8 @@ impl Cpu {
|
||||||
|
|
||||||
fn from_sys(cpu_index: usize) -> Self {
|
fn from_sys(cpu_index: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
online: usdpl_back::api::files::read_single(cpu_online_path(cpu_index)).unwrap_or(1u8) != 0,
|
online: usdpl_back::api::files::read_single(cpu_online_path(cpu_index)).unwrap_or(1u8)
|
||||||
|
!= 0,
|
||||||
governor: usdpl_back::api::files::read_single(cpu_governor_path(cpu_index))
|
governor: usdpl_back::api::files::read_single(cpu_governor_path(cpu_index))
|
||||||
.unwrap_or("schedutil".to_owned()),
|
.unwrap_or("schedutil".to_owned()),
|
||||||
index: cpu_index,
|
index: cpu_index,
|
||||||
|
@ -295,8 +295,7 @@ impl TCpu for Cpu {
|
||||||
&self.governor
|
&self.governor
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clock_limits(&mut self, _limits: Option<MinMax<u64>>) {
|
fn clock_limits(&mut self, _limits: Option<MinMax<u64>>) {}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_clock_limits(&self) -> Option<&MinMax<u64>> {
|
fn get_clock_limits(&self) -> Option<&MinMax<u64>> {
|
||||||
None
|
None
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
|
|
||||||
use crate::settings::MinMax;
|
|
||||||
use crate::settings::{OnResume, OnSet, SettingError};
|
|
||||||
use crate::settings::TGpu;
|
|
||||||
use crate::persist::GpuJson;
|
use crate::persist::GpuJson;
|
||||||
|
use crate::settings::MinMax;
|
||||||
|
use crate::settings::TGpu;
|
||||||
|
use crate::settings::{OnResume, OnSet, SettingError};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Gpu {
|
pub struct Gpu {
|
||||||
|
@ -13,15 +13,11 @@ pub struct Gpu {
|
||||||
impl Gpu {
|
impl Gpu {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_json(_other: GpuJson, _version: u64) -> Self {
|
pub fn from_json(_other: GpuJson, _version: u64) -> Self {
|
||||||
Self {
|
Self { slow_memory: false }
|
||||||
slow_memory: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn system_default() -> Self {
|
pub fn system_default() -> Self {
|
||||||
Self {
|
Self { slow_memory: false }
|
||||||
slow_memory: false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,15 +67,13 @@ impl TGpu for Gpu {
|
||||||
self.clone().into()
|
self.clone().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ppt(&mut self, _fast: Option<u64>, _slow: Option<u64>) {
|
fn ppt(&mut self, _fast: Option<u64>, _slow: Option<u64>) {}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_ppt(&self) -> (Option<u64>, Option<u64>) {
|
fn get_ppt(&self) -> (Option<u64>, Option<u64>) {
|
||||||
(None, None)
|
(None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clock_limits(&mut self, _limits: Option<MinMax<u64>>) {
|
fn clock_limits(&mut self, _limits: Option<MinMax<u64>>) {}
|
||||||
}
|
|
||||||
|
|
||||||
fn get_clock_limits(&self) -> Option<&MinMax<u64>> {
|
fn get_clock_limits(&self) -> Option<&MinMax<u64>> {
|
||||||
None
|
None
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
pub fn guess_smt(cpus: &Vec<crate::persist::CpuJson>) -> bool {
|
pub fn guess_smt(cpus: &Vec<crate::persist::CpuJson>) -> bool {
|
||||||
let mut guess = true;
|
let mut guess = true;
|
||||||
for i in (0..cpus.len()).step_by(2) {
|
for i in (0..cpus.len()).step_by(2) {
|
||||||
guess &= cpus[i].online == cpus[i+1].online;
|
guess &= cpus[i].online == cpus[i + 1].online;
|
||||||
}
|
}
|
||||||
guess
|
guess
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
//use std::sync::{LockResult, MutexGuard};
|
//use std::sync::{LockResult, MutexGuard};
|
||||||
//use std::fs::{Permissions, metadata};
|
//use std::fs::{Permissions, metadata};
|
||||||
|
use std::io::{Read, Write};
|
||||||
use std::os::unix::fs::PermissionsExt;
|
use std::os::unix::fs::PermissionsExt;
|
||||||
use std::io::{Write, Read};
|
|
||||||
|
|
||||||
pub fn unwrap_maybe_fatal<T: Sized, E: Display>(result: Result<T, E>, message: &str) -> T {
|
pub fn unwrap_maybe_fatal<T: Sized, E: Display>(result: Result<T, E>, message: &str) -> T {
|
||||||
match result {
|
match result {
|
||||||
|
@ -36,21 +36,36 @@ pub fn settings_dir() -> std::path::PathBuf {
|
||||||
pub fn chown_settings_dir() -> std::io::Result<()> {
|
pub fn chown_settings_dir() -> std::io::Result<()> {
|
||||||
let dir = settings_dir();
|
let dir = settings_dir();
|
||||||
#[cfg(feature = "decky")]
|
#[cfg(feature = "decky")]
|
||||||
let deck_user = usdpl_back::api::decky::user().map_err(|_| std::io::Error::new(std::io::ErrorKind::NotFound, "Decky missing deck user's username"))?;
|
let deck_user = usdpl_back::api::decky::user().map_err(|_| {
|
||||||
|
std::io::Error::new(
|
||||||
|
std::io::ErrorKind::NotFound,
|
||||||
|
"Decky missing deck user's username",
|
||||||
|
)
|
||||||
|
})?;
|
||||||
#[cfg(not(feature = "decky"))]
|
#[cfg(not(feature = "decky"))]
|
||||||
let deck_user = "deck".to_owned();
|
let deck_user = "deck".to_owned();
|
||||||
// FIXME this shouldn't need to invoke a command
|
// FIXME this shouldn't need to invoke a command
|
||||||
let output = std::process::Command::new("id")
|
let output = std::process::Command::new("id")
|
||||||
.args(["-u", &deck_user])
|
.args(["-u", &deck_user])
|
||||||
.output()?;
|
.output()?;
|
||||||
let uid: u32 = String::from_utf8_lossy(&output.stdout).parse().unwrap_or(1000);
|
let uid: u32 = String::from_utf8_lossy(&output.stdout)
|
||||||
log::info!("chmod/chown ~/.config/powertools for user `{}` ({})", deck_user, uid);
|
.parse()
|
||||||
|
.unwrap_or(1000);
|
||||||
|
log::info!(
|
||||||
|
"chmod/chown ~/.config/powertools for user `{}` ({})",
|
||||||
|
deck_user,
|
||||||
|
uid
|
||||||
|
);
|
||||||
let permissions = PermissionsExt::from_mode(0o755);
|
let permissions = PermissionsExt::from_mode(0o755);
|
||||||
std::fs::set_permissions(&dir, permissions)?;
|
std::fs::set_permissions(&dir, permissions)?;
|
||||||
// FIXME once merged into stable https://github.com/rust-lang/rust/issues/88989
|
// FIXME once merged into stable https://github.com/rust-lang/rust/issues/88989
|
||||||
//std::os::unix::fs::chown(&dir, Some(uid), Some(uid))
|
//std::os::unix::fs::chown(&dir, Some(uid), Some(uid))
|
||||||
std::process::Command::new("chown")
|
std::process::Command::new("chown")
|
||||||
.args(["-R", &format!("{}:{}", deck_user, deck_user), &dir.to_str().unwrap_or(".")])
|
.args([
|
||||||
|
"-R",
|
||||||
|
&format!("{}:{}", deck_user, deck_user),
|
||||||
|
&dir.to_str().unwrap_or("."),
|
||||||
|
])
|
||||||
.output()?;
|
.output()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -61,8 +76,7 @@ fn version_filepath() -> std::path::PathBuf {
|
||||||
|
|
||||||
pub fn save_version_file() -> std::io::Result<usize> {
|
pub fn save_version_file() -> std::io::Result<usize> {
|
||||||
let path = version_filepath();
|
let path = version_filepath();
|
||||||
std::fs::File::create(path)?
|
std::fs::File::create(path)?.write(crate::consts::PACKAGE_VERSION.as_bytes())
|
||||||
.write(crate::consts::PACKAGE_VERSION.as_bytes())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_version_file() -> String {
|
pub fn read_version_file() -> String {
|
||||||
|
@ -77,7 +91,7 @@ pub fn read_version_file() -> String {
|
||||||
crate::consts::PACKAGE_VERSION.to_owned()
|
crate::consts::PACKAGE_VERSION.to_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::warn!("Cannot read version file: {}", e);
|
log::warn!("Cannot read version file: {}", e);
|
||||||
crate::consts::PACKAGE_VERSION.to_owned()
|
crate::consts::PACKAGE_VERSION.to_owned()
|
||||||
|
|
Loading…
Reference in a new issue