Running a startup script in Nix OS
P/change_battery_threshold_nixos_boot
Playing with the laptop I wanted to change permanently
/sys/class/power_supply/BAT0/change_battery_end_threshold
to 80.
power-profiles-daemon
does not have an interface to it. This is an exploration
of the different methods I tried
TLP
TLP has a nix definition available. However it is incompatible with power-profiles-daemon, part of gnome.
services.tlp = {
enable = true;
settings = {
STOP_CHARGE_TRESH_BAT0=80;
START_CHARGE_THRESH_BAT0=40;
};
};
boot.kernel.sysctl
Adding a sysctl entry seems trivial.
boot.kernel.sysctl = { "class.power_supply.BAT0.charge_control_end_threshold" = 80;};
However boot.kernel.sysctl
only works for /proc/sys
https://discourse.nixos.org/t/setting-sysfs-parameters-in-nixos/14135
As a startup user service
I tried with a tiny user service. It didn’t work as it had no permissions
systemd.user.services.update_charge_control_threshold = {
description = "Update charge control threshold";
script = ''
echo 80 > /sys/class/power_supply/BAT0/charge_control_end_threshold
'';
wantedBy = [ "multi-user.target" ]; # starts after login
};
https://www.reddit.com/r/NixOS/comments/rezf0s/how_to_run_script_on_startup/?rdt=41534
activation script
Activation scripts are meant to run very early during the boot operations. Too early, in fact, the file is not there when I tried.
system.activationScripts.script.text = ''
echo 80 > /sys/class/power_supply/BAT0/charge_control_end_threshold
'';
https://discourse.nixos.org/t/system-activationscripts/22924
postboot command
Similar to activation scripts, the file wasn’t there:
boot.postBootCommands = ''
echo 80 > /sys/class/power_supply/BAT0/charge_control_end_threshold
'';
one shot guix service?
Similar to the user service, it has no root privileges so I got an error message.
systemd.services.set_battery_threshold = {
script = ''
echo 80 > /sys/class/power_supply/BAT0/charge_control_end_threshold
'';
wantedBy = ["multi-user.target"];
serviceConfig = {
Type = "oneshot";
};
};
https://www.reddit.com/r/NixOS/comments/jgfozg/how_to_run_arbitrary_setup_tasks_for_nixos/
udev rule
It worked. It waits until the module is loaded and then runs the code.
There are some restrictions so it won’t allow /bin/sh
https://wiki.archlinux.org/title/Laptop/ASUS
Cheating in nixos to call bash in the rule
https://unix.stackexchange.com/questions/186862/how-to-add-scripts-for-udev-to-run
The final result was:
services.udev.extraRules = ''
ACTION=="add", KERNEL=="asus-nb-wmi", RUN+="${pkgs.bash}/bin/bash -c 'echo 80 > /sys/class/power_supply/BAT?/charge_control_end_threshold'"
'';
- [[]]