254 lines
17 KiB
Markdown
254 lines
17 KiB
Markdown
# Framework Laptop Tools
|
||
|
||
Experimental native desktop/tray controls for **Framework Laptop 13 Pro
|
||
(Intel Core Ultra Series 3)**. Other Framework models are not yet validated.
|
||
Install `framework-laptop-tools`, then open **Framework Laptop Tools** from the
|
||
application menu or Fedora Tools settings. Installation changes no hardware
|
||
settings. Hardware changes require administrator authorisation.
|
||
|
||
The window has Monitor, Lighting, Cooling, Battery, CPU, Tray icon and Preferences
|
||
tabs.
|
||
Bounded hardware settings use sliders with numeric fields for precise entry.
|
||
All settings tabs share a **Save and Apply / Undo changes** bar. Editing stages
|
||
changes without writing hardware, tray settings, sampling intervals or autostart.
|
||
The bar stays visible across tabs. Save applies all pending settings with one
|
||
administrator authorisation for hardware changes; Undo discards all unsaved edits.
|
||
Successful saves become the new Undo baseline. If a hardware operation fails,
|
||
earlier operations may already have applied; remaining edits stay pending.
|
||
CPU slider bounds are read from Linux's hardware-frequency limits.
|
||
|
||
The Monitor page has CPU/GPU frequency, power, fan RPM, temperature and battery graphs.
|
||
The battery heading shows full capacity, health and cycle count when available.
|
||
Capacity calculated from charge capacity and nominal voltage is approximate.
|
||
Temperature labels distinguish CPU-area/board sensors from die readings;
|
||
raw sysfs paths remain available in tooltips. CPU frequency is Linux's reported
|
||
average across readable CPU policies, not an instantaneous measurement of every
|
||
core or a utilisation-weighted average. On detected Intel hybrid CPUs, separate
|
||
P-core and E-core averages are shown by default; the combined average remains
|
||
selectable. Each group also offers its highest reported frequency at each sample,
|
||
disabled by default. These are readings, not hardware limits or historical peaks.
|
||
All averages and maxima are also available as tray readings. Core membership uses
|
||
Linux's hybrid CPU lists, not clock-speed guesses. Without reliable grouping,
|
||
only the combined average is shown. AMD core-type grouping is not yet supported.
|
||
GPU GT domains are shown separately rather than assuming they are identical.
|
||
Click a coloured legend to toggle its series. Hidden series remain in the legend,
|
||
greyed out and crossed out. Main temperature sensors are shown first; additional
|
||
sensors are in a collapsed section that remembers their selections, not its open
|
||
state. NVMe composite is the drive's overall reported temperature; numbered NVMe
|
||
sensors are device-specific. Memory (SPD) measures the memory module, while EC
|
||
area sensors are separate from processor/module readings.
|
||
Each graph starts with blue. Further colours maximise their minimum OKLab distance
|
||
from enabled colours within a readable candidate palette. Enabling a line assigns
|
||
its colour; existing enabled lines keep theirs. Disabled colours are released.
|
||
|
||
Axes use round ticks and relative ages, with units below the vertical axes.
|
||
Hover draws a guide at the same timestamp on every graph, even when their
|
||
time spans differ. The popup describes only the graph under the pointer, stays
|
||
visible while hovering and follows new samples without needing mouse movement.
|
||
Hover for timestamps and the nearest
|
||
available readings; no readings are invented across gaps or sleep. Battery charge
|
||
uses the left percentage axis and rate the right watts axis (positive charging,
|
||
negative discharging). Blue-grey bands mark logind-observed sleep; faint red bands
|
||
mark observed charger connection. Plug changes during sleep are unknown, so AC
|
||
bands are not extended through sleep. There is no history from before app startup.
|
||
The Monitor history slider spans 5 minutes to 24 hours on a logarithmic scale.
|
||
Stretch available data fits shorter recordings to the graph width until the
|
||
selected span has been collected. These viewing controls take effect immediately
|
||
and are remembered; the default is 24 hours with stretching enabled.
|
||
All detected sensors retain 24 hours of readings in memory, even when hidden,
|
||
plus one boundary sample for clipping. Quitting the app clears this history.
|
||
Changing the sampling interval preserves older lines and hover readings at their
|
||
original cadence; missing readings and sleep remain gaps.
|
||
Monitor and tray graphs fill each pixel column from its time-weighted average
|
||
to its maximum when readings are compressed. With sparse readings, columns
|
||
follow straight lines between samples. Bands have a minimum vertical height of
|
||
two logical pixels, padded equally above and below; they never widen sideways.
|
||
Monitor columns align to physical pixels and the vertical minimum follows display
|
||
scaling. Plasma scales the tray's 64-pixel icon image to its chosen display size.
|
||
Missing data and sleep remain gaps. Hover readings report the original samples.
|
||
|
||
Power usage shows the detected RAPL domains (CPU package, cores, uncore and memory)
|
||
and hwmon power readings. Unvalidated platform power and ACPI fan power-table
|
||
entries are excluded; fan speed and duty cycle remain available separately.
|
||
These domains overlap and must not be added together. Uncore coverage depends
|
||
on the hardware; it is not labelled GPU power.
|
||
RAPL watts are energy-counter differences divided by elapsed monotonic time.
|
||
Wraparound is handled; missing reads, long gaps, detected resets and sleep restart
|
||
the baseline instead of producing a spike. MSR/MMIO duplicates are not plotted
|
||
twice. The counters must be readable; this app does not change their permissions.
|
||
Power readings are also available as tray metrics, using the same history.
|
||
|
||
Sampling choices are 0.5/1/2/4 seconds for frequencies, power, fan and temperatures, and
|
||
15/30/60/120 seconds for the battery graph. Tray autostart is optional.
|
||
Closing the window leaves monitoring in the tray; Quit exits the application.
|
||
The Tray icon tab supports one to ten independently configured icons, each showing
|
||
an application icon, a history graph, or a number. Number mode offers an optional
|
||
second reading, displayed beneath the first; **None** keeps a single number.
|
||
Settings cards wrap to fit the window. New icons default to the application icon;
|
||
your existing configuration
|
||
becomes Icon 1. Reducing the count keeps hidden drafts until Save and Apply;
|
||
saving retains only visible icons. The Move icon arrows swap all settings with
|
||
the adjacent icon while keeping the position numbers fixed. Undo restores the
|
||
saved set. All icons share
|
||
sensor sampling and history, and each has its own appearance and hover choices.
|
||
Sources
|
||
include CPU usage, CPU/GPU frequency, temperatures, charge level and battery rate.
|
||
Sensor graphs share Monitor's history, including gaps, regardless of which
|
||
sensor is selected for the tray. CPU usage also retains 24 hours. Switching
|
||
readings or resuming from sleep does not clear history. Frequency numbers use
|
||
GHz. The tray has optional
|
||
borders, a background colour with adjustable opacity, line and fill colours, and optional
|
||
area fill (including adjustable opacity). Frequency ceilings and temperature
|
||
ranges are saved per sensor; battery rate also has adjustable bounds (initially
|
||
−75–75 W), while percentages use 0–100.
|
||
Tray graphs show 10, 15, 20 or 30 seconds, or 1, 2 or 5 minutes, ending at now.
|
||
The default is one minute. History length is staged with the other tray settings.
|
||
Older readings are clipped, and unavailable history stays blank.
|
||
Outside readings can follow the inner edge, optionally in a different colour,
|
||
or be hidden. The line remains inside the border when a border is enabled.
|
||
Colour buttons show the opaque RGB swatch and label opacity separately, so a
|
||
translucent fill is not mistaken for a darker RGB colour.
|
||
Background opacity can be zero for full transparency; the former Transparent
|
||
background checkbox migrates to zero opacity without changing the RGB colour.
|
||
History and out-of-range controls are nested under the History graph display
|
||
choice. Hover information is configured separately: CPU usage; battery level
|
||
and remaining/full energy in mWh, followed by signed power and time to the charge
|
||
target; fan RPM and duty percentage; and the main CPU, memory, NVMe, battery and
|
||
board temperatures. Multiple temperatures have a heading and indented lines.
|
||
Detected power sensors have individual hover checkboxes, off by default. Multiple
|
||
selected power readings are grouped under a heading; battery power remains part
|
||
of the Battery option. Power, frequency and temperature readings use one decimal
|
||
between -10 and 10 (exclusive), and otherwise round to the nearest integer.
|
||
Numeric tray frequencies remain in GHz; graph readings retain their labelled units.
|
||
Missing sensors are unavailable in the settings page. Batteries reporting only
|
||
charge are converted to mWh using nominal voltage.
|
||
Choose zero to three top CPU applications, displayed below CPU usage in descending
|
||
order. Process sampling stops when no icon requests it; the previous checkbox migrates to zero or
|
||
one. Readable CPU counters are sampled while enabled. Processes are grouped by
|
||
application where identifiable, otherwise by executable. KDE's catalogue supplies
|
||
friendly names; ambiguous matches use executable names. Percentages use total
|
||
CPU capacity, matching the CPU line, rather than one core. Short-lived processes
|
||
between samples cannot be counted. No process history is written to disk.
|
||
Charging estimates to a reduced limit use the current charging rate and are
|
||
marked approximate. Hover choices use the shared Save and Apply / Undo controls.
|
||
Plasma applies its own hover highlight to tray icons; the app does not patch
|
||
the system tray to suppress that effect.
|
||
|
||
## Controls and limits
|
||
|
||
- Keyboard brightness: 0–100%. **Use Fn+Space to leave or enter Auto mode.**
|
||
The inspected 13 Pro firmware does not expose a host command to change that
|
||
mode; its ambient-light logic overrides manual percentage changes in Auto.
|
||
- Power-button brightness: 1–100%, or firmware Auto. This is the illuminated
|
||
power button surrounding the fingerprint reader, not its authentication.
|
||
The Automatic brightness checkbox disables the slider; both mode and brightness
|
||
are staged until Save and Apply. Unchecking it allows a fixed brightness to be selected.
|
||
- Fan: firmware Auto, manual duty, or a four-point curve. Manual values
|
||
range from 0–100%, including fan off. Manual speeds below 30% show a warning.
|
||
Saving manual or curve speeds below 30% also requires explicit confirmation.
|
||
Four editable temperatures must increase between 20 and 85 °C, reaching 100%
|
||
duty at the final point. Speeds between points are interpolated. The hottest EC sensor
|
||
drives the curve. Speed increases immediately and decreases gradually.
|
||
The privileged worker returns to Auto on suspend, reboot, a sensor fault,
|
||
high temperatures, watchdog timeout or service exit. It does not change
|
||
thermal warning/shutdown thresholds. Overrides remain active with the GUI closed.
|
||
Saving an override writes `/etc/framework-laptop-tools/fan.json` and enables
|
||
the worker at boot and after sleep. Sleep still stops the worker and restores
|
||
Auto first. Failure restores Auto without a restart loop;
|
||
saved settings are retried at the next boot/resume or explicit Save and Apply.
|
||
Legacy temporary overrides are still recognised until stopped, but newly saved
|
||
overrides always persist; installation itself does not enable them.
|
||
Selecting firmware Auto removes saved settings and disables automatic startup.
|
||
Do not combine with another fan controller.
|
||
- Battery charge limit: 50–100%, stored by the firmware. Charge-power settings
|
||
convert watts to a current limit using present battery voltage; actual watts
|
||
vary with voltage and system/charger limits. Zero restores firmware defaults.
|
||
This is **battery charging power**, not wall power or total laptop power.
|
||
Charge current has no read-back command in the interface used here.
|
||
The C-rate used by some other utilities expresses current relative to battery
|
||
capacity: 1 C means 4.64 A for a 4.64 Ah battery, not a fixed number of watts.
|
||
- CPU: minimum/maximum frequency, governor and energy preference, with optional
|
||
separate battery/AC profiles. Frequency bounds are clamped per policy: a
|
||
requested 4.5 GHz maximum does not restrict a P-core to a slower core's
|
||
3.3 GHz ceiling. These are bounds, not guaranteed clock speeds.
|
||
On Intel hybrid systems, kernel `cpu_core`/`cpu_atom` PMU membership identifies
|
||
P-core and E-core policy groups, each with independent overrides. E-core limits
|
||
clamp to each E-core's own ceiling, including lower-power E-cores. If the kernel
|
||
cannot identify the groups unambiguously, a single shared range is offered.
|
||
|
||
Lighting and battery readings refresh on entry and every two seconds while their
|
||
tab is visible. Unsaved edits are protected. Undo restores the unedited snapshot;
|
||
normal live refresh then resumes. Charge-current limits cannot be read back, so
|
||
their initial draft is firmware default, not a claim about current hardware state.
|
||
Graph legend toggles remain immediate viewing controls, separate from staged
|
||
settings tabs.
|
||
|
||
Battery time remaining/full uses UPower when available. Time to a custom charge
|
||
limit is approximate, based on present current; charging taper makes it less
|
||
accurate near full. No estimate is displayed when the needed readings are absent.
|
||
|
||
## Saved CPU profiles
|
||
|
||
CPU editing is staged. Splitting copies the shared values into both columns;
|
||
battery is on the left and AC on the right. Joining uses the battery column.
|
||
The hidden AC draft remains recoverable by splitting again until **Save and
|
||
apply** commits the joined profile. Shared configurations store only one copy.
|
||
**Undo changes** restores the last saved configuration. Background
|
||
firmware refreshes do not overwrite a dirty CPU draft.
|
||
|
||
Frequency bounds, governor and energy preference are independent. Frequency
|
||
overriding is unchecked by default, and both dropdowns default to **auto**.
|
||
Auto means this tool never writes that attribute; it is not a preset or reset.
|
||
Saving all-Auto profiles with frequency overriding off stops/disables the CPU
|
||
service. Existing CPU limits are left unchanged, including when giving up a
|
||
previous override, switching to an Auto power-source profile, or uninstalling.
|
||
There is no TuneD reload or blanket restoration that could disturb another
|
||
controller. Avoid assigning the same setting to multiple controllers.
|
||
|
||
The top of the CPU page always shows live Linux values, independently of the
|
||
draft below. The frequency sliders are disabled when their override is unchecked;
|
||
governor and EPP remain independently selectable. Tooltip explanations replace
|
||
the longer instructions formerly at the bottom of the page.
|
||
|
||
Explicit overrides apply at boot, resume, power-source changes and successful
|
||
TuneD profile changes after two seconds for the transition to settle. No TuneD
|
||
dependency is required. The service works with the GUI closed; configuration is
|
||
root-owned at `/etc/framework-laptop-tools/cpu.json`. Earlier all-or-nothing configurations
|
||
are converted to independent overrides while preserving whether they were enabled.
|
||
|
||
With active Intel HWP, the Performance governor forces performance EPP and rejects
|
||
other EPP values. For an explicitly selected Performance governor, this tool uses
|
||
Powersave when the selected EPP (or the live EPP when Auto) is incompatible. The
|
||
dropdown retains the user's choice and displays a warning. With EPP on Auto, the
|
||
service observes EPP changes and reevaluates that explicit governor choice.
|
||
|
||
If governor is Auto and the live Performance governor blocks an explicitly chosen
|
||
non-performance EPP, applying fails with a clear message: choose Powersave or leave
|
||
EPP on Auto. It does not silently take over the Auto governor. Explicit governor
|
||
changes can themselves affect EPP inside the kernel; Auto does not undo those
|
||
kernel side effects. Linux does not provide independent control of every combination.
|
||
|
||
Thermal, power and boost limits still apply. Powersave on active Intel HWP allows
|
||
dynamic clocks and boost; it does not mean locking the CPU at minimum frequency.
|
||
|
||
## Interfaces
|
||
|
||
No firmware patch, raw port I/O, downloaded executable, or third-party service
|
||
is used. Monitoring reads Linux sysfs and UPower. A restricted KAuth helper
|
||
uses sysfs and `/dev/cros_ec` for documented EC commands. Model checks are
|
||
repeated in the privileged helper, not just in the GUI.
|
||
|
||
References:
|
||
|
||
- [Framework's hardware library and CLI](https://github.com/FrameworkComputer/framework-system)
|
||
- [13 Pro keyboard firmware](https://github.com/FrameworkComputer/EmbeddedController/blob/fwk-sakura-20260429/zephyr/program/framework/src/keyboard_customization_13.c)
|
||
- [Framework LED commands](https://github.com/FrameworkComputer/EmbeddedController/blob/fwk-sakura-20260429/zephyr/program/framework/src/led.c)
|
||
- [Linux EC hardware monitor](https://www.kernel.org/doc/html/latest/hwmon/cros_ec_hwmon.html)
|
||
- [Linux CPU frequency controls](https://www.kernel.org/doc/html/latest/admin-guide/pm/cpufreq.html)
|
||
- [Intel governor and EPP behaviour](https://www.kernel.org/doc/html/latest/admin-guide/pm/intel_pstate.html)
|
||
- [TuneD profile documentation](https://tuned-project.org/docs/manual.html)
|
||
- [Linux battery units](https://www.kernel.org/doc/html/latest/power/power_supply_class.html)
|
||
- [Framework Control](https://github.com/ozturkkl/framework-control) and
|
||
[framework-tool-tui](https://github.com/grouzen/framework-tool-tui) provide
|
||
useful interface references; their code is not bundled here.
|