From cb18e436ca197d8bbd35787dcaab8440ad13884d Mon Sep 17 00:00:00 2001 From: Dominik Polakovics Date: Sun, 19 Oct 2025 12:01:45 +0200 Subject: [PATCH] feat: nb battery improvement --- hosts/nb/configuration.nix | 11 ++++-- hosts/nb/hardware-configuration.nix | 4 +++ hosts/nb/modules/battery-brightness.nix | 15 ++++++++ hosts/nb/modules/desktop/default.nix | 45 ++++++++++++++++++++++-- hosts/nb/modules/development/default.nix | 5 ++- hosts/nb/modules/ollama.nix | 5 ++- hosts/nb/modules/qdrant.nix | 5 +-- hosts/nb/modules/sway/sway.conf | 6 ++-- 8 files changed, 83 insertions(+), 13 deletions(-) create mode 100644 hosts/nb/modules/battery-brightness.nix diff --git a/hosts/nb/configuration.nix b/hosts/nb/configuration.nix index 7651327..4f42a9c 100644 --- a/hosts/nb/configuration.nix +++ b/hosts/nb/configuration.nix @@ -29,6 +29,7 @@ in { ./modules/mcp-global.nix ./modules/ollama.nix ./modules/qdrant.nix + ./modules/battery-brightness.nix ./cachix.nix ./users @@ -74,7 +75,8 @@ in { users.defaultUserShell = pkgs.zsh; services.fwupd.enable = true; - services.irqbalance.enable = true; + # Disable irqbalance to save battery (not critical for laptop workloads) + services.irqbalance.enable = false; swapDevices = [ { device = "/nix/persist/swapfile"; @@ -87,6 +89,11 @@ in { "vm.dirty_ratio" = 10; "vm.dirty_background_ratio" = 5; "vm.vfs_cache_pressure" = 50; + # Battery optimization - increase dirty writeback time to batch writes + "vm.dirty_writeback_centisecs" = 3000; # 30 seconds (default: 500 = 5s) + "vm.dirty_expire_centisecs" = 3000; # 30 seconds (default: 3000) + # Enable laptop mode for aggressive disk power management + "vm.laptop_mode" = 5; }; # nixos cross building qemu @@ -112,7 +119,7 @@ in { }; hardware.bluetooth.enable = true; - hardware.bluetooth.powerOnBoot = true; + hardware.bluetooth.powerOnBoot = false; # Save battery - enable manually when needed hardware.bluetooth.settings = { General = { ControllerMode = "bredr"; }; }; diff --git a/hosts/nb/hardware-configuration.nix b/hosts/nb/hardware-configuration.nix index d412040..f2d08c3 100644 --- a/hosts/nb/hardware-configuration.nix +++ b/hosts/nb/hardware-configuration.nix @@ -20,11 +20,15 @@ # AMD Ryzen 7 7840U optimizations boot.kernelParams = [ "amd_pstate=active" + "amd_pstate.shared_mem=1" "amdgpu.dcdebugmask=0x10" "amdgpu.dc=1" + "amdgpu.ppfeaturemask=0xffffffff" + "amdgpu.gpu_recovery=1" "snd_hda_intel.power_save=1" "transparent_hugepage=madvise" "pcie_aspm=force" + "nvme.noacpi=1" ]; fileSystems."/" = { diff --git a/hosts/nb/modules/battery-brightness.nix b/hosts/nb/modules/battery-brightness.nix new file mode 100644 index 0000000..e057236 --- /dev/null +++ b/hosts/nb/modules/battery-brightness.nix @@ -0,0 +1,15 @@ +{ config, pkgs, lib, ... }: + +{ + # Udev rules for battery optimizations + services.udev.extraRules = '' + # Reduce brightness to 40% when switching to battery + SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="${pkgs.light}/bin/light -S 40" + + # AMD GPU power management - force battery profile when unplugged + SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="${pkgs.bash}/bin/bash -c 'echo battery > /sys/class/drm/card*/device/power_dpm_force_performance_level'" + + # AMD GPU power management - auto when plugged in + SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="${pkgs.bash}/bin/bash -c 'echo auto > /sys/class/drm/card*/device/power_dpm_force_performance_level'" + ''; +} diff --git a/hosts/nb/modules/desktop/default.nix b/hosts/nb/modules/desktop/default.nix index 01b260a..e7e7005 100644 --- a/hosts/nb/modules/desktop/default.nix +++ b/hosts/nb/modules/desktop/default.nix @@ -96,7 +96,8 @@ in { services.gnome.gnome-keyring.enable = true; services.gvfs.enable = true; - virtualisation.virtualbox.host.enable = true; + # VirtualBox disabled by default to save battery - enable manually if needed + # virtualisation.virtualbox.host.enable = true; users.extraGroups.vboxusers.members = [ "dominik" ]; fonts.packages = with pkgs; [ @@ -111,7 +112,7 @@ in { programs.light.enable = true; hardware.bluetooth.enable = true; - hardware.bluetooth.powerOnBoot = true; + hardware.bluetooth.powerOnBoot = false; # Save battery - enable manually when needed hardware.bluetooth.settings = { General = { ControllerMode = "bredr"; }; }; @@ -123,14 +124,52 @@ in { CPU_SCALING_GOVERNOR_ON_BAT = "powersave"; CPU_ENERGY_PERF_POLICY_ON_AC = "performance"; - CPU_ENERGY_PERF_POLICY_ON_BAT = "balance_power"; + CPU_ENERGY_PERF_POLICY_ON_BAT = "power"; CPU_BOOST_ON_AC = 1; CPU_BOOST_ON_BAT = 0; + CPU_MIN_PERF_ON_AC = 0; + CPU_MAX_PERF_ON_AC = 100; + CPU_MIN_PERF_ON_BAT = 0; + CPU_MAX_PERF_ON_BAT = 30; + RUNTIME_PM_ON_AC = "auto"; RUNTIME_PM_ON_BAT = "auto"; + # WiFi power saving + WIFI_PWR_ON_AC = "off"; + WIFI_PWR_ON_BAT = "on"; + + # Disable wake on LAN on battery + WOL_DISABLE = "Y"; + + # SATA aggressive link power management + SATA_LINKPWR_ON_AC = "med_power_with_dipm"; + SATA_LINKPWR_ON_BAT = "min_power"; + + # PCIe Active State Power Management + PCIE_ASPM_ON_AC = "default"; + PCIE_ASPM_ON_BAT = "powersupersave"; + + # USB autosuspend + USB_AUTOSUSPEND = 1; + USB_EXCLUDE_AUDIO = 1; + USB_EXCLUDE_BTUSB = 0; + USB_EXCLUDE_PHONE = 0; + USB_EXCLUDE_PRINTER = 1; + USB_EXCLUDE_WWAN = 0; + + # Audio power saving + SOUND_POWER_SAVE_ON_AC = 0; + SOUND_POWER_SAVE_ON_BAT = 1; + SOUND_POWER_SAVE_CONTROLLER = "Y"; + + # Disk idle timeout + DISK_IDLE_SECS_ON_AC = 0; + DISK_IDLE_SECS_ON_BAT = 2; + + # Battery charge thresholds (Framework 13 recommendation) START_CHARGE_THRESH_BAT0 = 60; STOP_CHARGE_THRESH_BAT0 = 80; }; diff --git a/hosts/nb/modules/development/default.nix b/hosts/nb/modules/development/default.nix index 4a61b51..6e6adb9 100644 --- a/hosts/nb/modules/development/default.nix +++ b/hosts/nb/modules/development/default.nix @@ -47,7 +47,10 @@ in { virtualisation.docker.enable = true; virtualisation.libvirtd = { - enable = true; # Turn on the libvirtd daemon + enable = true; + # Socket activation - only start when needed to save battery + onBoot = "ignore"; + onShutdown = "shutdown"; qemu = { ovmf = { enable = true; # Enable OVMF firmware support diff --git a/hosts/nb/modules/ollama.nix b/hosts/nb/modules/ollama.nix index e3940ca..6811d65 100644 --- a/hosts/nb/modules/ollama.nix +++ b/hosts/nb/modules/ollama.nix @@ -7,9 +7,8 @@ port = 11434; openFirewall = false; acceleration = "rocm"; - loadModels = [ - "mxbai-embed-large" - ]; + # Don't preload models - start on-demand to save battery + loadModels = [ ]; }; # ROCm GPU configuration for AMD Ryzen 7 7840U (gfx1103) diff --git a/hosts/nb/modules/qdrant.nix b/hosts/nb/modules/qdrant.nix index 8a63a2e..bfb4fea 100644 --- a/hosts/nb/modules/qdrant.nix +++ b/hosts/nb/modules/qdrant.nix @@ -4,8 +4,9 @@ services.qdrant = { enable = true; settings = { - storage.performance.max_search_threads = 8; - storage.optimizers.default_segment_number = 4; + # Reduced thread count for better battery life + storage.performance.max_search_threads = 4; + storage.optimizers.default_segment_number = 2; }; }; } \ No newline at end of file diff --git a/hosts/nb/modules/sway/sway.conf b/hosts/nb/modules/sway/sway.conf index f060e9e..89a190b 100644 --- a/hosts/nb/modules/sway/sway.conf +++ b/hosts/nb/modules/sway/sway.conf @@ -302,8 +302,10 @@ exec cryptomator exec swayidle \ before-sleep 'loginctl lock-session $XDG_SESSION_ID' \ lock 'swaylock -c 252525 -s center -i ~/.wallpaper.png' \ - timeout 300 'swaylock -c 252525 -s center -i ~/.wallpaper.png' \ - timeout 1800 'systemctl suspend' + timeout 120 'light -O && light -S 10' \ + resume 'light -I' \ + timeout 180 'swaylock -c 252525 -s center -i ~/.wallpaper.png' \ + timeout 600 'systemctl suspend' exec dunst #exec --no-startup-id swaybg -c "#000000" -m fill -i ~/.config/wallpaper/wot.jpg # exec --no-startup-id gnome-keyring-daemon --start --components=pkcs11,secrets,ssh