Releases: HorizonUnix/UXTU4Linux
v0.7.0
What's new?
Added
- On Resume: Configure a preset to apply automatically each time the system wakes from sleep or suspend
OnResumeconfig key for resume preset selectionVariantconfig key to support Framework Laptop hardware detection and dedicated premade presets
Improved
- Switched to the official musl static ryzenadj binary, replacing the manylinux build
- Consolidated 25 individual preset files from the
Presets/folder into a singlepresets.pymodule for easier maintenance - Added descriptions for AC and DC presets
- Renamed
custom_presets.jsontocustom.json - Various bug fixes
- Minor UI refinements
- General codebase cleanup
v0.6.02
What's New
Custom Preset Editor
Build your own power preset from scratch using a keyboard-driven editor. Tune temperature limits, power limits, VRM current limits, and iGPU clock speeds. All with real-time hints explaining what each setting does. Presets are saved by name and show up alongside the built-in presets everywhere in the app.
Automations (Override)
Set a different preset for AC and battery automatically. When you plug in, the AC preset kicks in. When you unplug, the battery preset takes over. The daemon watches for power state changes in the background. Each slot is optional; leaving one as (None) just uses whatever preset you picked in Power Management for that state.
Improvements
- Preset descriptions: hovering over Eco, Balance, Performance, or Extreme now shows a short description of what that preset does.
- Hardware Information now has a proper title and cleaner section layout.
- Daemon logs are cleaner and more readable in
journalctl. - Version updates now correctly rank
0.6.1as newer than0.6.01. - Updates preserve your settings: both
config.iniand your custom presets are backed up and restored automatically during an update.
Removed
- Dynamic Mode has been replaced by Automations. It was limited to Extreme on AC and Eco on battery with no flexibility.
v0.6.01
What's New?
New
- Hardware Information now includes a Battery section
- Reads directly from kernel sysfs (/sys/class/power_supply/)
- Shows status, charge level, health, cycle count, full charge, design capacity, and charge rate
- Supports energy-based (µWh), charge × voltage, and raw mAh reporting depending on driver
- Capacity reported in mWh where voltage data is available, mAh otherwise
- Correctly identifies system battery over peripheral batteries (e.g. Logitech HID devices)
Fixed
- TUI and Daemon now prevent duplicate instances
- Redundant startup log lines removed
- Debug setting changes in Settings now reload instantly in the running daemon without a restart
Improved
- Daemon logging level now follows the Debug setting at startup (DEBUG vs INFO)
- Debug mode in the daemon now logs the ryzenadj command and per-loop tick state
- Secure Boot and ryzen_smu check moved to daemon startup
- Adjusted presets for AMDCPU
- Minor UI refinements
v0.6.0
What's new?
Introduce a background daemon-based architecture for applying Ryzen power presets, modernize the terminal UI.
New Features:
- Add a systemd-managed background daemon with IPC for applying, looping, and dynamically switching RyzenAdj presets.
- Introduce a richer terminal menu UI with keyboard navigation, status-aware menus, and an About screen with update integration.
- Add system checks for Secure Boot blocking ryzen_smu and for dmidecode availability, guiding users with troubleshooting output.
Bug Fixes:
- Ensure preset and dynamic mode state is sourced from the daemon where possible, reducing drift between UI and applied settings.
- Harden handling of missing or invalid saved presets by falling back to the setup wizard or reporting clear errors.
- Validate RyzenAdj arguments in the daemon to avoid applying malformed or unsafe command payloads.
Enhancements:
- Refactor power management flow to use the daemon for all SMU operations, simplifying apply/reapply logic and centralizing dynamic mode handling.
- Improve hardware info parsing and presentation, including better dmidecode access via the daemon and clearer, styled output.
- Streamline settings into a single menu with toggleable options and an interval editor that immediately re-applies saved presets when changed.
- Update startup logic to verify and repair the systemd service path, auto-apply presets only when no mode is active, and enforce Linux-only support.
- Simplify and modernize config handling, version metadata, and menu structures across modules.
Updating from v0.5.x may cause issues. Please refer to Linux Installation Guide
v0.6.0 Beta 05
- Removed
keyring
curl -fsSL https://raw.githubusercontent.com/HorizonUnix/UXTU4Unix/main/install.sh | bash0.6.0Beta04
curl -fsSL https://raw.githubusercontent.com/HorizonUnix/UXTU4Unix/main/install.sh | bashv0.6.0 Beta 03
What's new?
- Brand new TUI experience
install.sh (Beta) - Run at your own risks!
curl -fsSL https://raw.githubusercontent.com/HorizonUnix/UXTU4Unix/main/install.sh | sh2026-05-03.20-47-45.mp4
IPC Architecture
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ systemd · manages daemon lifecycle / restarts on crash / starts on boot │
└──────────────────────┬───────────────────────────────────────────────────────────────┬───────────────────┘
│ │
┌─────────────▼──────────────┐ ┌────────────────▼───────────┐
│ CLI PROCESS │ │ DAEMON PROCESS │
│ │ │ │
│ ┌──────────────────────┐ │ │ ┌──────────────────────┐ │
│ │ UXTU4Unix.py │ │ │ │ PowerDaemon │ │
│ │ (entry point) │ │ │ │ (class) │ │
│ └──────────────────────┘ │ │ └──────────────────────┘ │
│ │ │ │
│ Assets/Modules/ │ │ ┌──────────────────────┐ │
│ ┌──────────┬───────────┐ │ │ │ run() │ │
│ │ ui.py │ config.py │ │ │ │ ZMQ REP socket │ │
│ ├──────────┼───────────┤ │ │ └──────────────────────┘ │
│ │hardware │ updater │ │ │ │
│ │ .py │ .py │ │ ┌─────────────────────┐ │ ┌──────────────────────┐ │
│ ├──────────┼───────────┤ │ │ ZMQ IPC BRIDGE │ │ │ handle() │ │
│ │settings │ setup.py │ │ │ /run/uxtu4unix.sock│ │ │ + _DISPATCH │ │
│ │ .py │ │ │ │ │ │ └──────────────────────┘ │
│ ├──────────┴───────────┤ │ │ → ping │ │ │
│ │ power.py │ │ │ → apply │ │ command handlers: │
│ ├──────────────────────┤ │ │ → apply_loop │ │ ┌──────────┬───────────┐ │
│ │ keyring.py │ │ │ → stop_loop │ │ │ ping │ apply │ │
│ └──────────────────────┘ │ │ → status │ │ ├──────────┴───────────┤ │
│ - - - - - - - - - - - - │ │ → apply_saved │ │ │ apply_loop │ │
│ IPC bridge │ │ → shutdown │ │ ├──────────────────────┤ │
│ ┌──────────────────────┐ │ │ │ │ │ stop_loop │ │
│ │ ipc.py │ │ │ ← {"ok": true, …} │ │ ├──────────────────────┤ │
│ │ DaemonClient ├──┼──►│ ← {"ok": false, …} ├────►│ │ status │ │
│ │ ZMQ REQ socket │◄─┼───│ ← null (timeout) │◄────┤ ├──────────────────────┤ │
│ │ 5 s RCVTIMEO │ │ │ │ │ │ apply_saved │ │
│ │ LINGER = 0 │ │ │ new socket per call│ │ ├──────────────────────┤ │
│ └──────────────────────┘ │ │ 5 s timeout │ │ │ shutdown │ │
│ │ └─────────────────────┘ │ └──────────────────────┘ │
│ Assets/Presets/ │ │ - - - - - - - - - - - - │
│ ┌──────────────────────┐ │ │ ┌──────────────────────┐ │
│ │ AMD*.py │ │ │ │ _run_ryzenadj() │ │
│ │ (PRESETS dict) │ │ │ └──────────────────────┘ │
│ └──────────────────────┘ │ │ ┌──────────┬───────────┐ │
│ │ │ │ _on_ac() │ reapply │ │
│ ┌──────────────────────┐ │ │ │ │ loop │ │
│ │ Assets/config.toml │ │ │ │ │ thread │ │
│ └──────────────────────┘ │ │ └──────────┴───────────┘ │
│ │ │ │
│ ┌──────────────────────┐ │ │ Assets/Presets/ │
│ │ Assets/Linux/ │ │ │ ┌──────────────────────┐ │
│ │ ryzenadj (binary) │ │ │ │ AMD*.py │ │
│ └──────────────────────┘ │ │ │ (PRESETS dict) │ │
│ │ │ └──────────────────────┘ │
└────────────────────────────┘ │ │
│ ┌──────────────────────┐ │
│ │ Assets/config.toml │ │
│ └──────────────────────┘ │
│ │
│ ┌──────────────────────┐ │
│ │ Assets/Linux/ │ │
│ │ ryzenadj (binary) │ │
│ └──────────────────────┘ │
└────────────────────────────┘
v0.5.22
macOS Deprecation Notice
v0.5.22will be the last version to support the macOS branch.
0.6Beta02
What's new?
- Removed macOS branch
- Minor tweaks to daemon
┌─────────────────────────────────────────────────────────────────┐
│ systemd (Linux) │
│ manages lifecycle: start on boot, restart on crash │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────────┐ │
│ │ daemon.py (background, headless) │ │
│ │ │ │
│ │ owns the ryzenadj subprocess calls │ │
│ │ runs the auto-reapply loop in a thread │ │
│ │ handles dynamic AC/battery switching │ │
│ │ binds ZMQ REP socket │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ ipc:///tmp/uxtu4unix-{uid}.sock │
│ │ (or $XDG_RUNTIME_DIR on Linux) │
│ ┌──────────────────────▼───────────────────────┐ │
│ │ daemon_client.py (ZMQ REQ) │ │
│ └──────────────────────▲───────────────────────┘ │
│ │ │
│ ┌──────────────────────┴───────────────────────┐ │
│ │ UXTU4Unix.py (CLI) │ │
│ │ │ │
│ │ menus, settings, hardware info │ │
│ │ starts daemon subprocess if not running │ │
│ │ sends commands, displays output │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
v0.5.21
- Resolve issue #23 by implementing a robust search path for the
dmidecodebinary (_find_dmidecode) and storing its absolute path to preventPATHresolution errors withinsudosubshells (thx @kstutz01). - Minor tweaks to
about.pyandpower.py. - Always
chmod +xbinaries when starting. - Default sleep time is now
3s instead of30s.