mirror of
https://github.com/ItsDrike/nixdots
synced 2024-12-26 19:04:33 +00:00
Rework laptop battery/power optimization settings
This commit is contained in:
parent
dd00ed5f70
commit
a0bba2e225
47
system/roles/laptop/power/auto-cpufreq/default.nix
Normal file
47
system/roles/laptop/power/auto-cpufreq/default.nix
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
# This sets up power management using auto-cpufreq,
|
||||||
|
# alongside with upower and power-profiles-daemon.
|
||||||
|
# Together, this provides a complete alternative to TLP
|
||||||
|
{ pkgs, lib, config, ...}: let
|
||||||
|
inherit (lib) mkIf mkDefault;
|
||||||
|
deviceType = config.myOptions.device.roles.type;
|
||||||
|
acceptedTypes = ["laptop"];
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./power-profiles-daemon
|
||||||
|
];
|
||||||
|
|
||||||
|
config = mkIf (builtins.elem deviceType acceptedTypes) {
|
||||||
|
services = {
|
||||||
|
# superior power management
|
||||||
|
auto-cpufreq = {
|
||||||
|
enable = true;
|
||||||
|
settings = let
|
||||||
|
MHz = x: x * 1000;
|
||||||
|
in {
|
||||||
|
battery = {
|
||||||
|
governor = "powersave";
|
||||||
|
scaling_min_freq = mkDefault (MHz 1200);
|
||||||
|
scaling_max_freq = mkDefault (MHz 1800);
|
||||||
|
turbo = "never";
|
||||||
|
};
|
||||||
|
|
||||||
|
charger = {
|
||||||
|
governor = "performance";
|
||||||
|
scaling_min_freq = mkDefault (MHz 1800);
|
||||||
|
scaling_max_freq = mkDefault (MHz 3800);
|
||||||
|
turbo = "auto";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# DBus service that provides power management support to applications
|
||||||
|
upower = {
|
||||||
|
enable = true;
|
||||||
|
percentageLow = 15;
|
||||||
|
percentageCritical = 5;
|
||||||
|
percentageAction = 3;
|
||||||
|
criticalPowerAction = "Hibernate";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
# This sets up power management using auto-cpufreq,
|
||||||
|
# alongside with upower and power-profiles-daemon.
|
||||||
|
# Together, this provides a complete alternative to TLP
|
||||||
|
{ pkgs, lib, config, ...}: let
|
||||||
|
inherit (lib) mkIf;
|
||||||
|
inherit (lib.modules) mkForce;
|
||||||
|
inherit (lib.strings) makeBinPath;
|
||||||
|
deviceType = config.myOptions.device.roles.type;
|
||||||
|
acceptedTypes = ["laptop"];
|
||||||
|
in {
|
||||||
|
config = mkIf (builtins.elem deviceType acceptedTypes) {
|
||||||
|
# allows changing system behavior based upon user-selected power profiles
|
||||||
|
# (with `powerprofilesctl` command)
|
||||||
|
services.power-profiles-daemon.enable = true;
|
||||||
|
|
||||||
|
# Power state monitor. Switches power profiles based on charging state.
|
||||||
|
# Plugged in - performance (if available, falls back to balance)
|
||||||
|
# Unplugged - balanced, until below 50%, then power-saver
|
||||||
|
systemd.services."power-monitor" = let
|
||||||
|
dependencies = with pkgs; [
|
||||||
|
coreutils
|
||||||
|
power-profiles-daemon
|
||||||
|
inotify-tools
|
||||||
|
jaq
|
||||||
|
];
|
||||||
|
in {
|
||||||
|
description = "Power Monitoring Service";
|
||||||
|
environment.PATH = mkForce "/run/wrappers/bin:${makeBinPath dependencies}";
|
||||||
|
script = builtins.readFile ./scripts/power_monitor.sh;
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
Restart = "on-failure";
|
||||||
|
};
|
||||||
|
|
||||||
|
wants = ["power-profiles-daemon.service"];
|
||||||
|
wantedBy = ["default.target"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
BAT=$(echo /sys/class/power_supply/BAT*) # only supports single-battery systems
|
||||||
|
BAT_STATUS="$BAT/status"
|
||||||
|
BAT_CAP="$BAT/capacity"
|
||||||
|
|
||||||
|
POWER_SAVE_PERCENT=50 # Enter power-save mode if on bat and below this capacity
|
||||||
|
|
||||||
|
HAS_PERFORMANCE="$(powerprofilesctl list | grep performance)"
|
||||||
|
|
||||||
|
# monitor loop
|
||||||
|
prev=0
|
||||||
|
while true; do
|
||||||
|
# read the current state
|
||||||
|
status="$(cat "$BAT_STATUS")"
|
||||||
|
capacity="$(cat "$BAT_CAP")"
|
||||||
|
|
||||||
|
if [[ $status == "Discharging" ]]; then
|
||||||
|
if [[ $capacity -le $POWER_SAVE_PERCENT ]]; then
|
||||||
|
profile="power-saver"
|
||||||
|
else
|
||||||
|
profile="balanced"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [[ -n $HAS_PERFORMANCE ]]; then
|
||||||
|
profile="performance"
|
||||||
|
else
|
||||||
|
profile="balanced"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set the new profile
|
||||||
|
if [[ $profile != $prev ]]; then
|
||||||
|
echo -en "Setting power profile to ${profile}\n"
|
||||||
|
powerprofilesctl set $profile
|
||||||
|
prev=$profile
|
||||||
|
fi
|
||||||
|
|
||||||
|
# wait for changes in status or capacity files
|
||||||
|
# i.e. for the next power change event
|
||||||
|
inotifywait -qq "$BAT_STATUS" "$BAT_CAP"
|
||||||
|
done
|
|
@ -3,6 +3,10 @@
|
||||||
deviceType = config.myOptions.device.roles.type;
|
deviceType = config.myOptions.device.roles.type;
|
||||||
acceptedTypes = ["laptop"];
|
acceptedTypes = ["laptop"];
|
||||||
in {
|
in {
|
||||||
|
imports = [
|
||||||
|
./auto-cpufreq
|
||||||
|
];
|
||||||
|
|
||||||
config = mkIf (builtins.elem deviceType acceptedTypes) {
|
config = mkIf (builtins.elem deviceType acceptedTypes) {
|
||||||
hardware.acpilight.enable = true;
|
hardware.acpilight.enable = true;
|
||||||
|
|
||||||
|
@ -15,48 +19,11 @@ in {
|
||||||
# handle ACPI events
|
# handle ACPI events
|
||||||
acpid.enable = true;
|
acpid.enable = true;
|
||||||
|
|
||||||
# allows changing system behavior based upon user-selected power profiles
|
|
||||||
power-profiles-daemon.enable = true;
|
|
||||||
|
|
||||||
# temperature target on battery
|
# temperature target on battery
|
||||||
undervolt = {
|
undervolt = {
|
||||||
tempBat = 65; # deg C
|
tempBat = 65; # deg C
|
||||||
package = pkgs.undervolt;
|
package = pkgs.undervolt;
|
||||||
};
|
};
|
||||||
|
|
||||||
# superior power management
|
|
||||||
auto-cpufreq = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
# define the profiles
|
|
||||||
# (you can manually switch between profiles using `powerprofilesctl` cmd)
|
|
||||||
settings = let
|
|
||||||
MHz = x: x * 1000;
|
|
||||||
in {
|
|
||||||
battery = {
|
|
||||||
governor = "powersave";
|
|
||||||
scaling_min_freq = mkDefault (MHz 1200);
|
|
||||||
scaling_max_freq = mkDefault (MHz 1800);
|
|
||||||
turbo = "never";
|
|
||||||
};
|
|
||||||
|
|
||||||
charger = {
|
|
||||||
governor = "performance";
|
|
||||||
scaling_min_freq = mkDefault (MHz 1800);
|
|
||||||
scaling_max_freq = mkDefault (MHz 3800);
|
|
||||||
turbo = "auto";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# DBus service that provides power management support to applications
|
|
||||||
upower = {
|
|
||||||
enable = true;
|
|
||||||
percentageLow = 15;
|
|
||||||
percentageCritical = 5;
|
|
||||||
percentageAction = 3;
|
|
||||||
criticalPowerAction = "Hibernate";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
boot = {
|
boot = {
|
||||||
|
|
Loading…
Reference in a new issue