josie / alder-tools

TUI: auto-scaling bars for vCore & pkg power (session peak + margin, static floor)

0f53d389d8cf5c1c9b72104f543d1401fcc489d0
josie <administrator@josie-c.com> · 2026-08-29T12:36 · browse files at this commit

parents: c5ccef7

diff --git a/src/ui.rs b/src/ui.rs
index c2a2019..aab61be 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -20,11 +20,13 @@ const VCORE_MARGIN: f64 = 0.05;
 /// Safety limit, volts. User-tunable config value. Intel max Vcore
 /// spec default for the 12600KF.
 const VCORE_LIMIT: f64 = 1.403;
-const VCORE_BAR_MAX: f64 = 1.50;
+const VCORE_BAR_MAX: f64 = 1.50; // default; auto-scaled above by peak
 const TEMP_WARN: f64 = 80.0;
 const TEMP_CRIT: f64 = 95.0;
-/// Package power bar scale, watts (dGPU PPT ceiling as a sane display max).
+/// Package power bar scale, watts (default; auto-scaled above by peak).
 const POWER_BAR_MAX: f64 = 200.0;
+/// Auto-scale headroom above the session peak, as a fraction.
+const SCALE_MARGIN: f64 = 0.05;
 /// Temp bar scale, °C.
 const TEMP_BAR_MAX: f64 = 100.0;
 
@@ -33,7 +35,11 @@ pub struct App {
     vcore_peak: Option<f64>,
     /// (timestamp, volts) per-tick maxima inside the 5-min peak window
     peak_ring: Vec<(Instant, f64)>,
+    /// Highest vCore ever seen this session (auto-scale anchor)
+    vcore_all_time_peak: f64,
     package_watts: Option<f64>,
+    /// Highest pkg watts ever seen this session (auto-scale anchor)
+    watts_all_time_peak: f64,
     package_temp: Option<f64>,
     /// Per physical core: label (coretemp "Core N"), freq kHz, bar-max kHz
     /// (that core's cpuinfo_max_freq), temperature °C.
@@ -41,6 +47,12 @@ pub struct App {
     last_pkg_energy: Option<(u64, Instant)>,
 }
 
+/// Bar max = static default, or last peak + margin once the peak exceeds it.
+/// The margin keeps the value text off the bar's right edge at the peak.
+fn dynamic_max(peak: f64, static_max: f64, margin: f64) -> f64 {
+    (peak * (1.0 + margin)).max(static_max)
+}
+
 /// One physical core's row in the per-core section.
 struct CoreRow {
     label: String,
@@ -57,7 +69,9 @@ impl App {
             vcore: None,
             vcore_peak: None,
             peak_ring: Vec::new(),
+            vcore_all_time_peak: 0.0,
             package_watts: None,
+            watts_all_time_peak: 0.0,
             package_temp: None,
             cores: Vec::new(),
             last_pkg_energy: None,
@@ -77,6 +91,7 @@ impl App {
                     .map(|(_, v)| *v)
                     .fold(f64::MIN, f64::max),
             );
+            self.vcore_all_time_peak = self.vcore_all_time_peak.max(v);
         }
 
         if let Some(chip) = sensors::discover_chips()
@@ -146,8 +161,12 @@ impl App {
                     Some((prev, t0)) => {
                         let dt = t0.elapsed().as_secs_f64();
                         if dt > 0.0 && e >= prev {
-                            self.package_watts =
-                                Some((e - prev) as f64 / 1_000_000.0 / dt);
+                            let w = (e - prev) as f64 / 1_000_000.0 / dt;
+                            self.package_watts = Some(w);
+                            if w.is_finite() {
+                                self.watts_all_time_peak =
+                                    self.watts_all_time_peak.max(w);
+                            }
                         }
                         Some((e, Instant::now()))
                     }
@@ -285,13 +304,18 @@ pub fn draw(f: &mut Frame, app: &App) {
         "vCore",
         Style::default().fg(Color::Cyan).add_modifier(Modifier::BOLD),
     )));
+    // Bar maxima auto-scale: session all-time peak + margin, floored at the
+    // static defaults. OC'ing past a default compresses the bar to fit.
+    let vc_max = dynamic_max(app.vcore_all_time_peak, VCORE_BAR_MAX, SCALE_MARGIN);
+    let watt_max = dynamic_max(app.watts_all_time_peak, POWER_BAR_MAX, SCALE_MARGIN);
+
     lines.push(meter_line(
         "",
         &hero_text,
-        app.vcore.map(|v| v / VCORE_BAR_MAX),
+        app.vcore.map(|v| v / vc_max),
         vc_color,
         w,
-        Some(VCORE_LIMIT / VCORE_BAR_MAX),
+        Some(VCORE_LIMIT / vc_max),
     ));
     lines.push(Line::from(""));
 
@@ -299,7 +323,7 @@ pub fn draw(f: &mut Frame, app: &App) {
     lines.push(meter_line(
         "Pkg power",
         &fmt_opt_watts(app.package_watts),
-        app.package_watts.map(|v| v / POWER_BAR_MAX),
+        app.package_watts.map(|v| v / watt_max),
         Color::Blue,
         w,
         None,