Offene Werkstatt-Issues umsetzen
Some checks failed
Tests / test (push) Has been cancelled

This commit is contained in:
2026-10-15 10:12:29 +02:00
parent 9dc37d1ece
commit 31ac17dd41
8 changed files with 146 additions and 5 deletions

View File

@@ -31,6 +31,38 @@ fn exec(tool: &str, args: &[&str]) -> Result<String, String> {
Err(format!("{tool} ({})\n{log}", out.status))
}
}
fn mobile_chassis(value: &str) -> bool {
matches!(
value.trim(),
"8" | "9" | "10" | "11" | "14" | "30" | "31" | "32"
)
}
fn mobile_device() -> bool {
let chassis = fs::read_to_string("/sys/class/dmi/id/chassis_type")
.or_else(|_| fs::read_to_string("/run/csr-intake/chassis_type"))
.unwrap_or_default();
if mobile_chassis(&chassis) {
return true;
}
fs::read_dir("/sys/class/power_supply").is_ok_and(|entries| {
entries.flatten().any(|entry| {
fs::read_to_string(entry.path().join("type")).is_ok_and(|kind| kind.trim() == "Battery")
})
})
}
fn wired_link_active() -> bool {
fs::read_dir("/sys/class/net").is_ok_and(|entries| {
entries.flatten().any(|entry| {
let path = entry.path();
entry.file_name() != "lo"
&& !path.join("wireless").exists()
&& fs::read_to_string(path.join("carrier")).is_ok_and(|v| v.trim() == "1")
})
})
}
pub fn needs_lan_disconnect() -> bool {
mobile_device() && wired_link_active()
}
fn temps() -> Vec<(String, f64)> {
let mut values = Vec::new();
let Ok(chips) = fs::read_dir("/sys/class/hwmon") else {
@@ -316,7 +348,12 @@ fn run_legacy(tool: &str, settings: &crate::workflow::Settings) -> (bool, String
&["-f", "IN-USE,SSID,SIGNAL", "device", "wifi", "list"],
)
.unwrap_or_else(|e| e);
(true,format!("Status:\n{status}\nGeräte:\n{dev}\nNetze:\n{scan}\nLAN trennen und WLAN-Verbindung aktiv testen; Sichtbarkeit ist noch kein PASS."))
let lan = if needs_lan_disconnect() {
"\nWARNUNG: Mobiles Gerät mit aktiver LAN-Verbindung. LAN-Kabel vor dem WLAN-Test entfernen."
} else {
""
};
(true,format!("Status:\n{status}\nGeräte:\n{dev}\nNetze:\n{scan}{lan}\nWLAN-Verbindung aktiv testen; Sichtbarkeit ist noch kein PASS."))
}
}
}
@@ -479,4 +516,14 @@ mod tests {
);
assert_eq!(peak_temperature("PEAK_TEMPERATURE_C=NaN"), None);
}
#[test]
fn portable_chassis_types_are_recognized() {
for value in ["8", "9", "10", "11", "14", "30", "31", "32"] {
assert!(mobile_chassis(value));
}
for value in ["3", "7", "13", "15", "unknown"] {
assert!(!mobile_chassis(value));
}
}
}

View File

@@ -650,6 +650,15 @@ impl App {
));
if let Some(d) = &self.station_device {
ui.heading(format!("#{}", d["number"]));
match d["_registration"].as_str() {
Some("NEW") => {
ui.colored_label(GREEN, tr(en, "Neu im Inventory registriert", "Newly registered in inventory"));
}
Some("EXISTING") => {
ui.label(tr(en, "Bereits im Inventory vorhanden", "Existing inventory device"));
}
_ => {}
}
let stage = match d["stage"].as_str().unwrap_or("") {
"INTAKE" => "Eingang",
"INSPECTION" => "Inspektion",
@@ -912,6 +921,16 @@ impl App {
}
ui.add_enabled_ui(!conflict, |ui| {
if key == "wifi" {
if diagnostics::needs_lan_disconnect() {
ui.colored_label(
ORANGE,
tr(
en,
"LAN-Kabel entfernen: Bei diesem mobilen Gerät muss der WLAN-Test ohne aktive Kabelverbindung erfolgen.",
"Disconnect Ethernet: test Wi-Fi on this mobile device without an active wired connection.",
),
);
}
self.wifi.set_language(en);
let was_busy = self.wifi.busy();
self.wifi.ui(ui, self.receiver.is_some());
@@ -1437,6 +1456,29 @@ impl App {
ui.selectable_value(&mut self.settings_draft.language, "de".into(), "Deutsch");
ui.selectable_value(&mut self.settings_draft.language, "en".into(), "English");
});
ui.label(tr(en, "Tastaturbelegung", "Keyboard layout"));
egui::ComboBox::from_id_salt("keyboard-layout")
.selected_text(match self.settings_draft.keyboard_layout.as_str() {
"us" => "English (US)",
_ => "Deutsch (DE)",
})
.show_ui(ui, |ui| {
ui.selectable_value(
&mut self.settings_draft.keyboard_layout,
"de".into(),
"Deutsch (DE)",
);
ui.selectable_value(
&mut self.settings_draft.keyboard_layout,
"us".into(),
"English (US)",
);
});
ui.small(tr(
en,
"Die Tastaturbelegung wird beim nächsten Start des USB-Systems angewendet.",
"The keyboard layout is applied on the next USB-system boot.",
));
ui.label(tr(en, "WLAN-Testserver", "Wi-Fi test server"));
ui.text_edit_singleline(&mut self.settings_draft.test_url);
ui.horizontal(|ui| {

View File

@@ -86,6 +86,7 @@ pub fn init_index(data: &Path) -> Result<(), String> {
#[serde(default)]
pub struct Settings {
pub language: String,
pub keyboard_layout: String,
pub test_url: String,
pub stress_seconds: u64,
pub recording_seconds: u64,
@@ -98,6 +99,7 @@ impl Default for Settings {
fn default() -> Self {
Self {
language: "de".into(),
keyboard_layout: "de".into(),
test_url: "https://example.com".into(),
stress_seconds: 120,
recording_seconds: 5,
@@ -113,6 +115,9 @@ impl Settings {
if !["de", "en"].contains(&self.language.as_str()) {
return Err("Language must be de or en".into());
}
if !["de", "us"].contains(&self.keyboard_layout.as_str()) {
return Err("Keyboard layout must be de or us".into());
}
if !(self.test_url.starts_with("https://") || self.test_url.starts_with("http://"))
|| self.test_url.contains(['\n', '\r'])
{