feat: 完善 ATX 功能逻辑与控件样式

This commit is contained in:
mofeng-git
2026-07-07 00:21:54 +08:00
parent f6e97a06f5
commit e60152d38b
21 changed files with 1058 additions and 836 deletions

View File

@@ -1,7 +1,6 @@
//! ATX data types and structures
//!
//! Defines the configuration and state types for the flexible ATX power control system.
//! Each ATX action (power, reset) can be independently configured with different hardware.
//! Defines the configuration and state types for the ATX power control system.
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
@@ -15,6 +14,15 @@ pub enum PowerStatus {
Unknown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum HddStatus {
Active,
Inactive,
#[default]
Unknown,
}
#[typeshare]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
@@ -36,6 +44,56 @@ pub enum ActiveLevel {
}
#[typeshare]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(default)]
pub struct AtxOutputBinding {
pub enabled: bool,
pub device: String,
pub pin: u32,
pub active_level: ActiveLevel,
}
impl Default for AtxOutputBinding {
fn default() -> Self {
Self {
enabled: false,
device: String::new(),
pin: 1,
active_level: ActiveLevel::High,
}
}
}
impl AtxOutputBinding {
pub fn is_configured_for(&self, driver: AtxDriverType, top_level_device: &str) -> bool {
if !self.enabled || driver == AtxDriverType::None {
return false;
}
match driver {
AtxDriverType::Gpio => !self.device.trim().is_empty(),
AtxDriverType::UsbRelay | AtxDriverType::Serial => !top_level_device.trim().is_empty(),
AtxDriverType::None => false,
}
}
}
#[typeshare]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
#[serde(default)]
pub struct AtxInputBinding {
pub enabled: bool,
pub device: String,
pub pin: u32,
pub active_level: ActiveLevel,
}
impl AtxInputBinding {
pub fn is_configured(&self) -> bool {
self.enabled && !self.device.trim().is_empty()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(default)]
pub struct AtxKeyConfig {
@@ -64,29 +122,16 @@ impl AtxKeyConfig {
}
}
#[typeshare]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
#[serde(default)]
pub struct AtxLedConfig {
pub enabled: bool,
pub gpio_chip: String,
pub gpio_pin: u32,
pub inverted: bool,
}
impl AtxLedConfig {
pub fn is_configured(&self) -> bool {
self.enabled && !self.gpio_chip.is_empty()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct AtxState {
pub available: bool,
pub driver: AtxDriverType,
pub power_configured: bool,
pub reset_configured: bool,
pub power_status: PowerStatus,
pub led_supported: bool,
pub hdd_status: HddStatus,
pub hdd_supported: bool,
}
#[derive(Debug, Clone, Deserialize)]
@@ -139,6 +184,29 @@ mod tests {
assert_eq!(ActiveLevel::default(), ActiveLevel::High);
}
#[test]
fn test_atx_output_binding_default() {
let config = AtxOutputBinding::default();
assert!(!config.enabled);
assert!(config.device.is_empty());
assert_eq!(config.pin, 1);
assert!(!config.is_configured_for(AtxDriverType::Gpio, ""));
}
#[test]
fn test_atx_output_binding_is_configured() {
let mut config = AtxOutputBinding::default();
assert!(!config.is_configured_for(AtxDriverType::Gpio, ""));
config.enabled = true;
assert!(!config.is_configured_for(AtxDriverType::Gpio, ""));
config.device = "/dev/gpiochip0".to_string();
assert!(config.is_configured_for(AtxDriverType::Gpio, ""));
assert!(!config.is_configured_for(AtxDriverType::Serial, ""));
assert!(config.is_configured_for(AtxDriverType::Serial, "/dev/ttyUSB0"));
}
#[test]
fn test_atx_key_config_default() {
let config = AtxKeyConfig::default();
@@ -149,37 +217,22 @@ mod tests {
}
#[test]
fn test_atx_key_config_is_configured() {
let mut config = AtxKeyConfig::default();
assert!(!config.is_configured());
config.driver = AtxDriverType::Gpio;
assert!(!config.is_configured());
config.device = "/dev/gpiochip0".to_string();
assert!(config.is_configured());
config.driver = AtxDriverType::None;
assert!(!config.is_configured());
}
#[test]
fn test_atx_led_config_default() {
let config = AtxLedConfig::default();
fn test_atx_input_binding_default() {
let config = AtxInputBinding::default();
assert!(!config.enabled);
assert!(config.gpio_chip.is_empty());
assert!(config.device.is_empty());
assert!(!config.is_configured());
}
#[test]
fn test_atx_led_config_is_configured() {
let mut config = AtxLedConfig::default();
fn test_atx_input_binding_is_configured() {
let mut config = AtxInputBinding::default();
assert!(!config.is_configured());
config.enabled = true;
assert!(!config.is_configured());
config.gpio_chip = "/dev/gpiochip0".to_string();
config.device = "/dev/gpiochip0".to_string();
assert!(config.is_configured());
}
@@ -187,9 +240,12 @@ mod tests {
fn test_atx_state_default() {
let state = AtxState::default();
assert!(!state.available);
assert_eq!(state.driver, AtxDriverType::None);
assert!(!state.power_configured);
assert!(!state.reset_configured);
assert_eq!(state.power_status, PowerStatus::Unknown);
assert!(!state.led_supported);
assert_eq!(state.hdd_status, HddStatus::Unknown);
assert!(!state.hdd_supported);
}
}