Add Asus ROG Ally fan support (without interpolation)
This commit is contained in:
parent
dd0c3998f0
commit
364d9650f2
11 changed files with 191 additions and 117 deletions
2
backend-rs/Cargo.lock
generated
2
backend-rs/Cargo.lock
generated
|
@ -1243,7 +1243,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sysfuss"
|
name = "sysfuss"
|
||||||
version = "0.3.0"
|
version = "0.4.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
|
|
|
@ -19,7 +19,7 @@ nrpc = { version = "1.0", path = "../../nRPC/nrpc", features = ["async-trait"] }
|
||||||
prost = "0.11"
|
prost = "0.11"
|
||||||
tokio = { version = "1", features = ["sync", "rt"] }
|
tokio = { version = "1", features = ["sync", "rt"] }
|
||||||
|
|
||||||
sysfuss = { version = "0.3", features = ["derive"], path = "../../sysfs-nav" }
|
sysfuss = { version = "0.4", features = ["derive"], path = "../../sysfs-nav" }
|
||||||
|
|
||||||
# logging
|
# logging
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
|
@ -4,4 +4,7 @@ pub use dev_mode::DevModeFan;
|
||||||
mod steam_deck;
|
mod steam_deck;
|
||||||
pub use steam_deck::SteamDeckFan;
|
pub use steam_deck::SteamDeckFan;
|
||||||
|
|
||||||
|
mod rog_ally;
|
||||||
|
pub use rog_ally::RogAllyFan;
|
||||||
|
|
||||||
pub(self) use super::FanAdapter as Adapter;
|
pub(self) use super::FanAdapter as Adapter;
|
||||||
|
|
159
backend-rs/src/adapters/fans/rog_ally/adapter.rs
Normal file
159
backend-rs/src/adapters/fans/rog_ally/adapter.rs
Normal file
|
@ -0,0 +1,159 @@
|
||||||
|
use sysfuss::{BasicEntityPath, HwMonAttribute, HwMonAttributeItem, HwMonAttributeType, HwMonPath, SysAttributeExt};
|
||||||
|
use sysfuss::{SysPath, SysEntityAttributesExt};
|
||||||
|
|
||||||
|
use crate::datastructs::{Settings, GraphPoint};
|
||||||
|
|
||||||
|
const ASUS_CUSTOM_FAN_CURVE_HWMON_NAME: &str = "asus_custom_fan_curve";
|
||||||
|
const ASUS_REGULAR_HWMON_NAME: &str = "asus";
|
||||||
|
|
||||||
|
pub struct RogAllyFan {
|
||||||
|
hwmon_curve: HwMonPath,
|
||||||
|
hwmon_asus: HwMonPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RogAllyFan {
|
||||||
|
pub fn maybe_find() -> Option<Self> {
|
||||||
|
let syspath = SysPath::path(crate::sys::SYSFS_ROOT);
|
||||||
|
match syspath.hwmon_by_name(ASUS_CUSTOM_FAN_CURVE_HWMON_NAME)
|
||||||
|
{
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("sysfs hwmon iter error while finding Asus ROG Ally fan curve: {}", e);
|
||||||
|
None
|
||||||
|
},
|
||||||
|
Ok(hwmon_curve) => {
|
||||||
|
match syspath.hwmon_by_name(ASUS_REGULAR_HWMON_NAME) {
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("sysfs hwmon iter error while finding Asus fan: {}", e);
|
||||||
|
None
|
||||||
|
},
|
||||||
|
Ok(hwmon_asus) => {
|
||||||
|
Some(Self {
|
||||||
|
hwmon_curve,
|
||||||
|
hwmon_asus,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns true when the point probably doesn't exist at all
|
||||||
|
// (instead of it just running out of pwm# entries)
|
||||||
|
fn set_gp(gp_i: u64, gp: &GraphPoint, basic_curve: &BasicEntityPath) -> bool {
|
||||||
|
for pwm_i in 1..u64::MAX {
|
||||||
|
let temp_attr = pwm_point_temp(pwm_i, gp_i);
|
||||||
|
let pwm_attr = pwm_point_pwm(pwm_i, gp_i);
|
||||||
|
if !(temp_attr.exists(basic_curve) && pwm_attr.exists(basic_curve)) {
|
||||||
|
return pwm_i == 1;
|
||||||
|
}
|
||||||
|
let pwm_val = (gp.y * 255.0).round() as u8;
|
||||||
|
if let Err(e) = basic_curve.set(&pwm_attr as &str, pwm_val) {
|
||||||
|
let attr_path = pwm_attr.path(basic_curve);
|
||||||
|
log::error!("failed to write to {}: {}", attr_path.display(), e);
|
||||||
|
}
|
||||||
|
let temp_val = (gp.x * 100.0).round() as u8;
|
||||||
|
if let Err(e) = basic_curve.set(&temp_attr as &str, temp_val) {
|
||||||
|
let attr_path = temp_attr.path(basic_curve);
|
||||||
|
log::error!("failed to write to {}: {}", attr_path.display(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl super::super::Adapter for RogAllyFan {
|
||||||
|
fn on_enable_toggled(&self, settings: &Settings) {
|
||||||
|
let value_to_set = settings.enable as u8;
|
||||||
|
for i in 1..u64::MAX {
|
||||||
|
let attr = pwm_enable_attr_name(i);
|
||||||
|
if self.hwmon_curve.exists(&attr) {
|
||||||
|
if let Err(e) = self.hwmon_curve.set(attr, value_to_set) {
|
||||||
|
log::error!("failed to write to {}: {}", self.hwmon_curve.path_to(attr).display(), e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn control_fan(&self, settings: &Settings, _sensor: &crate::adapters::traits::SensorReading) {
|
||||||
|
let basic_curve = BasicEntityPath::new(self.hwmon_curve.as_ref());
|
||||||
|
if settings.curve.is_empty() {
|
||||||
|
for i in 1..u64::MAX {
|
||||||
|
let out_of_points = if i == 1 {
|
||||||
|
Self::set_gp(i as _, &GraphPoint { x: 0.0, y: 0.0 }, &basic_curve)
|
||||||
|
} else {
|
||||||
|
Self::set_gp(i as _, &GraphPoint { x: 1.0, y: 1.0 }, &basic_curve)
|
||||||
|
};
|
||||||
|
if out_of_points { break; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i, gp) in settings.curve.iter().enumerate() {
|
||||||
|
Self::set_gp(i as _, gp, &basic_curve);
|
||||||
|
}
|
||||||
|
// set remaining pwm points to highest in curve
|
||||||
|
for i in settings.curve.len()..usize::MAX {
|
||||||
|
if Self::set_gp(i as _, &GraphPoint { x: 1.0, y: 1.0 }, &basic_curve) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sensor<'a: 'b, 'b>(&'a self) -> Option<&'b dyn crate::adapters::SensorAdapter> {
|
||||||
|
Some(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl super::super::super::SensorAdapter for RogAllyFan {
|
||||||
|
fn read(&self) -> Result<crate::adapters::SensorReading, std::io::Error> {
|
||||||
|
let mut readings = Vec::new();
|
||||||
|
let mut last_error = None;
|
||||||
|
for i in 1..u64::MAX {
|
||||||
|
let attr = fan_reading_attr_name(i);
|
||||||
|
let reading = match self.hwmon_asus.attribute::<u64>(attr) {
|
||||||
|
Ok(reading) => reading,
|
||||||
|
Err(sysfuss::EitherErr2::First(e1)) => {
|
||||||
|
log::debug!("failed to read attribute {}: {} (ok; breaking loop...)", self.hwmon_asus.path_to(attr).display(), e1);
|
||||||
|
last_error = Some(e1);
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
Err(sysfuss::EitherErr2::Second(e2)) => {
|
||||||
|
log::debug!("failed to read attribute {}: {} (ok; breaking loop...)", self.hwmon_asus.path_to(attr).display(), e2);
|
||||||
|
last_error = Some(std::io::Error::other(e2));
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
readings.push(reading);
|
||||||
|
}
|
||||||
|
let mut reading_sum = 0;
|
||||||
|
for reading in readings.iter() {
|
||||||
|
reading_sum += *reading;
|
||||||
|
}
|
||||||
|
if readings.is_empty() {
|
||||||
|
Err(last_error.unwrap())
|
||||||
|
} else {
|
||||||
|
Ok(crate::adapters::SensorReading {
|
||||||
|
value: (reading_sum / (readings.len() as u64)) as f64,
|
||||||
|
meaning: crate::adapters::SensorType::Fan,
|
||||||
|
name: "ROG Ally Fan",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pwm_enable_attr_name(index: u64) -> HwMonAttribute {
|
||||||
|
HwMonAttribute::new(HwMonAttributeType::Pwm, index, HwMonAttributeItem::Enable)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fan_reading_attr_name(index: u64) -> HwMonAttribute {
|
||||||
|
HwMonAttribute::new(HwMonAttributeType::Fan, index, HwMonAttributeItem::Input)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pwm_point_temp(index: u64, point_index: u64) -> String {
|
||||||
|
format!("pwm{}_auto_point{}_temp", index, point_index)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pwm_point_pwm(index: u64, point_index: u64) -> String {
|
||||||
|
format!("pwm{}_auto_point{}_pwm", index, point_index)
|
||||||
|
}
|
2
backend-rs/src/adapters/fans/rog_ally/mod.rs
Normal file
2
backend-rs/src/adapters/fans/rog_ally/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
mod adapter;
|
||||||
|
pub use adapter::RogAllyFan;
|
|
@ -174,6 +174,10 @@ fn read_fan(hwmon: &HwMonPath) -> std::io::Result<u64> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fan_range() -> std::ops::Range<f64> {
|
||||||
|
1.0..7000.0
|
||||||
|
}
|
||||||
|
|
||||||
fn do_fan_control(settings: &Settings, hwmon: &HwMonPath, thermal_zone: f64) {
|
fn do_fan_control(settings: &Settings, hwmon: &HwMonPath, thermal_zone: f64) {
|
||||||
/*
|
/*
|
||||||
curve = self.settings["curve"]
|
curve = self.settings["curve"]
|
||||||
|
@ -193,8 +197,8 @@ fn do_fan_control(settings: &Settings, hwmon: &HwMonPath, thermal_zone: f64) {
|
||||||
fan_ratio = self.step_fan(self, index, temperature_ratio)
|
fan_ratio = self.step_fan(self, index, temperature_ratio)
|
||||||
set_fan_target(int((fan_ratio * FAN_MAXIMUM) + FAN_MINIMUM))
|
set_fan_target(int((fan_ratio * FAN_MAXIMUM) + FAN_MINIMUM))
|
||||||
*/
|
*/
|
||||||
let temperature_ratio = (((thermal_zone as f64)/1000.0) - settings.temperature_bounds.min)
|
let fan_bounds = fan_range();
|
||||||
/ (settings.temperature_bounds.max - settings.temperature_bounds.min);
|
let temperature_ratio = ((thermal_zone as f64)/1000.0) / 100.0 /* temperature range in C */;
|
||||||
let mut index = None;
|
let mut index = None;
|
||||||
for i in (0..settings.curve.len()).rev() {
|
for i in (0..settings.curve.len()).rev() {
|
||||||
if settings.curve[i].x < temperature_ratio {
|
if settings.curve[i].x < temperature_ratio {
|
||||||
|
@ -207,7 +211,7 @@ fn do_fan_control(settings: &Settings, hwmon: &HwMonPath, thermal_zone: f64) {
|
||||||
} else {
|
} else {
|
||||||
step_fan(settings, index, temperature_ratio)
|
step_fan(settings, index, temperature_ratio)
|
||||||
};
|
};
|
||||||
let fan_speed: u64 = ((fan_ratio * (settings.fan_bounds.max - settings.fan_bounds.min)) + settings.fan_bounds.min) as _;
|
let fan_speed: u64 = ((fan_ratio * (fan_bounds.end - fan_bounds.start)) + fan_bounds.start) as _;
|
||||||
if let Err(e) = write_fan_target(hwmon, fan_speed) {
|
if let Err(e) = write_fan_target(hwmon, fan_speed) {
|
||||||
log::error!("Failed to write to Steam Deck fan target file: {}", e);
|
log::error!("Failed to write to Steam Deck fan target file: {}", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,14 @@ impl ThermalZoneSensor {
|
||||||
pub fn new<P: AsRef<std::path::Path>>(zone_path: P) -> Self {
|
pub fn new<P: AsRef<std::path::Path>>(zone_path: P) -> Self {
|
||||||
Self { zone: BasicEntityPath::new(zone_path) }
|
Self { zone: BasicEntityPath::new(zone_path) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_if_exists<P: AsRef<std::path::Path>>(zone_path: P) -> Option<Self> {
|
||||||
|
if zone_path.as_ref().exists() {
|
||||||
|
Some(Self { zone: BasicEntityPath::new(zone_path) })
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl super::Adapter for ThermalZoneSensor {
|
impl super::Adapter for ThermalZoneSensor {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::default::Default;
|
||||||
use std::convert::{Into, From};
|
use std::convert::{Into, From};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use super::json::{SettingsJson, GraphPointJson, BoundsJson};
|
use super::json::{SettingsJson, GraphPointJson};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
|
@ -10,8 +10,6 @@ pub struct Settings {
|
||||||
pub enable: bool,
|
pub enable: bool,
|
||||||
pub interpolate: bool,
|
pub interpolate: bool,
|
||||||
pub curve: Vec<GraphPoint>,
|
pub curve: Vec<GraphPoint>,
|
||||||
pub fan_bounds: Bounds<f64>,
|
|
||||||
pub temperature_bounds: Bounds<f64>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
|
@ -28,42 +26,18 @@ impl From<SettingsJson> for Settings {
|
||||||
enable: other.enable,
|
enable: other.enable,
|
||||||
interpolate: other.interpolate,
|
interpolate: other.interpolate,
|
||||||
curve: other.curve.drain(..).map(|x| GraphPoint::from_json(x, other.version)).collect(),
|
curve: other.curve.drain(..).map(|x| GraphPoint::from_json(x, other.version)).collect(),
|
||||||
fan_bounds: Bounds {
|
|
||||||
min: 1.0,
|
|
||||||
max: 7000.0,
|
|
||||||
},
|
|
||||||
temperature_bounds: Bounds {
|
|
||||||
min: 0.0,
|
|
||||||
max: 100.0,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
1 => Self {
|
1 => Self {
|
||||||
version: 1,
|
version: 1,
|
||||||
enable: other.enable,
|
enable: other.enable,
|
||||||
interpolate: other.interpolate,
|
interpolate: other.interpolate,
|
||||||
curve: other.curve.drain(..).map(|x| GraphPoint::from_json(x, other.version)).collect(),
|
curve: other.curve.drain(..).map(|x| GraphPoint::from_json(x, other.version)).collect(),
|
||||||
fan_bounds: other.fan_bounds.map(|x| Bounds::<f64>::from_json(x, other.version)).unwrap_or(Bounds {
|
|
||||||
min: 1.0,
|
|
||||||
max: 7000.0,
|
|
||||||
}),
|
|
||||||
temperature_bounds: other.temperature_bounds.map(|x| Bounds::<f64>::from_json(x, other.version)).unwrap_or(Bounds {
|
|
||||||
min: 0.0,
|
|
||||||
max: 100.0,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
_ => Self {
|
_ => Self {
|
||||||
version: 1,
|
version: 1,
|
||||||
enable: other.enable,
|
enable: other.enable,
|
||||||
interpolate: other.interpolate,
|
interpolate: other.interpolate,
|
||||||
curve: other.curve.drain(..).map(|x| GraphPoint::from_json(x, other.version)).collect(),
|
curve: other.curve.drain(..).map(|x| GraphPoint::from_json(x, other.version)).collect(),
|
||||||
fan_bounds: Bounds {
|
|
||||||
min: 1.0,
|
|
||||||
max: 7000.0,
|
|
||||||
},
|
|
||||||
temperature_bounds: Bounds {
|
|
||||||
min: 0.0,
|
|
||||||
max: 100.0,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
result.sort_curve();
|
result.sort_curve();
|
||||||
|
@ -79,8 +53,6 @@ impl Into<SettingsJson> for Settings {
|
||||||
enable: self.enable,
|
enable: self.enable,
|
||||||
interpolate: self.interpolate,
|
interpolate: self.interpolate,
|
||||||
curve: self.curve.drain(..).map(|x| x.into()).collect(),
|
curve: self.curve.drain(..).map(|x| x.into()).collect(),
|
||||||
fan_bounds: Some(self.fan_bounds.into()),
|
|
||||||
temperature_bounds: Some(self.temperature_bounds.into()),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,72 +93,6 @@ impl Into<GraphPointJson> for GraphPoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Bounds<T: core::fmt::Debug + Clone> {
|
|
||||||
pub min: T,
|
|
||||||
pub max: T,
|
|
||||||
}
|
|
||||||
|
|
||||||
/*impl Bounds<usize> {
|
|
||||||
#[inline]
|
|
||||||
pub fn from_json(other: BoundsJson, version: u64) -> Self {
|
|
||||||
match version {
|
|
||||||
0 => Self {
|
|
||||||
min: other.min as _,
|
|
||||||
max: other.max as _,
|
|
||||||
},
|
|
||||||
1 => Self {
|
|
||||||
min: other.min as _,
|
|
||||||
max: other.max as _,
|
|
||||||
},
|
|
||||||
_ => Self {
|
|
||||||
min: other.min as _,
|
|
||||||
max: other.max as _,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
impl Bounds<f64> {
|
|
||||||
#[inline]
|
|
||||||
pub fn from_json(other: BoundsJson, version: u64) -> Self {
|
|
||||||
match version {
|
|
||||||
0 => Self {
|
|
||||||
min: other.min,
|
|
||||||
max: other.max,
|
|
||||||
},
|
|
||||||
1 => Self {
|
|
||||||
min: other.min,
|
|
||||||
max: other.max,
|
|
||||||
},
|
|
||||||
_ => Self {
|
|
||||||
min: other.min,
|
|
||||||
max: other.max,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*impl Into<BoundsJson> for Bounds<usize> {
|
|
||||||
#[inline]
|
|
||||||
fn into(self) -> BoundsJson {
|
|
||||||
BoundsJson {
|
|
||||||
min: self.min as _,
|
|
||||||
max: self.max as _,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
impl Into<BoundsJson> for Bounds<f64> {
|
|
||||||
#[inline]
|
|
||||||
fn into(self) -> BoundsJson {
|
|
||||||
BoundsJson {
|
|
||||||
min: self.min,
|
|
||||||
max: self.max,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub home: PathBuf,
|
pub home: PathBuf,
|
||||||
|
|
|
@ -11,8 +11,6 @@ pub struct SettingsJson {
|
||||||
pub enable: bool,
|
pub enable: bool,
|
||||||
pub interpolate: bool,
|
pub interpolate: bool,
|
||||||
pub curve: Vec<GraphPointJson>,
|
pub curve: Vec<GraphPointJson>,
|
||||||
pub fan_bounds: Option<BoundsJson>,
|
|
||||||
pub temperature_bounds: Option<BoundsJson>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
@ -21,12 +19,6 @@ pub struct GraphPointJson {
|
||||||
pub y: f64,
|
pub y: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
pub struct BoundsJson {
|
|
||||||
pub min: f64,
|
|
||||||
pub max: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for SettingsJson {
|
impl Default for SettingsJson {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -34,14 +26,6 @@ impl Default for SettingsJson {
|
||||||
enable: false,
|
enable: false,
|
||||||
interpolate: true,
|
interpolate: true,
|
||||||
curve: Vec::new(),
|
curve: Vec::new(),
|
||||||
fan_bounds: Some(BoundsJson {
|
|
||||||
min: 0.0,
|
|
||||||
max: 7000.0,
|
|
||||||
}),
|
|
||||||
temperature_bounds: Some(BoundsJson {
|
|
||||||
min: 0.0,
|
|
||||||
max: 100.0,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,17 @@ fn main() -> Result<(), ()> {
|
||||||
api::FanService::new(control::ControlRuntime::new_boxed(
|
api::FanService::new(control::ControlRuntime::new_boxed(
|
||||||
adapters::fans::SteamDeckFan::maybe_find()
|
adapters::fans::SteamDeckFan::maybe_find()
|
||||||
.map(|f| Box::new(f) as Box<dyn adapters::FanAdapter>)
|
.map(|f| Box::new(f) as Box<dyn adapters::FanAdapter>)
|
||||||
|
.or_else(
|
||||||
|
|| adapters::fans::RogAllyFan::maybe_find()
|
||||||
|
.map(|f| Box::new(f) as Box<dyn adapters::FanAdapter>)
|
||||||
|
)
|
||||||
.unwrap_or_else(|| Box::new(adapters::fans::DevModeFan)),
|
.unwrap_or_else(|| Box::new(adapters::fans::DevModeFan)),
|
||||||
adapters::fans::SteamDeckFan::maybe_find_thermal_zone()
|
adapters::fans::SteamDeckFan::maybe_find_thermal_zone()
|
||||||
.map(|t| Box::new(adapters::sensors::ThermalZoneSensor::new(t)) as Box<dyn adapters::SensorAdapter>)
|
.map(|t| Box::new(adapters::sensors::ThermalZoneSensor::new(t)) as Box<dyn adapters::SensorAdapter>)
|
||||||
|
.or_else(
|
||||||
|
|| adapters::sensors::ThermalZoneSensor::new_if_exists("/sys/thermal/thermal_zone0")
|
||||||
|
.map(|t| Box::new(t) as Box<dyn adapters::SensorAdapter>)
|
||||||
|
)
|
||||||
.unwrap_or_else(|| Box::new(adapters::sensors::DevModeSensor))
|
.unwrap_or_else(|| Box::new(adapters::sensors::DevModeSensor))
|
||||||
))
|
))
|
||||||
))
|
))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Fantastic",
|
"name": "Fantastic",
|
||||||
"version": "0.5.1-alpha1",
|
"version": "0.6.0-alpha1",
|
||||||
"description": "A template to quickly create decky plugins from scratch, based on TypeScript and webpack",
|
"description": "A template to quickly create decky plugins from scratch, based on TypeScript and webpack",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "shx rm -rf dist && rollup -c",
|
"build": "shx rm -rf dist && rollup -c",
|
||||||
|
|
Loading…
Reference in a new issue