Skip to content

Commit df946c9

Browse files
fan2go.nix
1 parent 51df916 commit df946c9

File tree

6 files changed

+1500
-2
lines changed

6 files changed

+1500
-2
lines changed

desktop/l/configuration.nix

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,17 @@
3838
# clickhouse
3939
./clickhouse-service.nix
4040
# GPU fan control
41-
./gpu-fan-control.nix
41+
#./gpu-fan-control.nix
4242
# Corsair fan control
43-
./corsair-fan-control.nix
43+
#./corsair-fan-control.nix
4444
#./docker-compose.nix
4545
./docker-daemon.nix
4646
#./smokeping.nix
4747
#./distributed-builds.nix
4848
#./hyprland.nix
4949
./nginx.nix
5050
./ollama-service.nix
51+
./fan2go.nix
5152
];
5253

5354
boot = {

desktop/l/fan2go.nix

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#
2+
# fan2go.nix
3+
#
4+
# sudo systemctl status fan2go
5+
# sudo ls /var/lib/fan2go
6+
#
7+
# See also: https://github.com/arnarg/config/blob/8de65cf5f1649a4fe6893102120ede4363de9bfa/hosts/terra/fan2go.nix
8+
#
9+
{
10+
lib,
11+
config,
12+
pkgs,
13+
...
14+
}:
15+
let
16+
cfg = config.hardware.fan2go;
17+
18+
fan2goConfig = pkgs.writeText "fan2go.yaml" ''
19+
#
20+
# fan2go.yaml
21+
#
22+
dbPath: ${cfg.dbPath}
23+
24+
fans:
25+
# Define the fan to be controlled. This is Fan 1 on the Corsair Commander Core XT.
26+
- id: corsair_fan1
27+
# Use liquidctl to set the fan speed.
28+
# The fan type for external commands is `cmd`.
29+
# Assumes the Corsair Commander Core XT is the first device liquidctl finds.
30+
cmd:
31+
# The `setPwm` command is required. It receives a value from 0-255.
32+
# We use a shell command to convert the 0-255 PWM value from fan2go
33+
# into a 0-100 percentage for liquidctl.
34+
setPwm:
35+
exec: "/run/current-system/sw/bin/bash"
36+
args: ["-c", "percent=$((%pwm% * 100 / 255)); /run/current-system/sw/bin/liquidctl set fan1 speed $percent"]
37+
# The `getPwm` command is optional but good practice.
38+
# It should return a value from 0-255.
39+
getPwm:
40+
exec: "/run/current-system/sw/bin/bash"
41+
args: ["-c", "percent=$(/run/current-system/sw/bin/liquidctl status --json | ${pkgs.jq}/bin/jq '.[0].status[] | select(.key == \"Fan speed 1\").value | tonumber'); echo $((percent * 255 / 100))"]
42+
# Fan speed is a percentage for liquidctl
43+
min: 20
44+
max: 100
45+
## Ensures the fan never fully stops, maintaining minimum airflow.
46+
#neverStop: true
47+
# The curve ID that should be used to determine the speed of this fan.
48+
curve: gpu_cooling_curve
49+
50+
sensors:
51+
# Define the temperature sensor to monitor. This is the Radeon Pro VII/MI50.
52+
# From `fan2go detect`, this is platform `amdgpu-pci-04400`.
53+
# The sensor type is `hwmon`.
54+
- id: gpu_mi50_temp
55+
hwmon:
56+
platform: amdgpu-pci-04400
57+
# Use the junction temperature (temp2_input) as it's a good indicator of core heat.
58+
index: 2
59+
60+
curves:
61+
# Link the GPU temperature to the case fan speed.
62+
- id: gpu_cooling_curve
63+
# Use a linear interpolation curve based on the defined points.
64+
linear:
65+
# The sensor ID to use as a temperature input for this curve.
66+
sensor: gpu_mi50_temp
67+
# Define the temperature-to-fan-speed mapping.
68+
# Temps are in Celsius, fan speed is in percent.
69+
points:
70+
- [40, 20] # At 40°C, run fan at 20%
71+
- [50, 40] # At 50°C, run fan at 40%
72+
- [60, 60] # At 60°C, run fan at 60%
73+
- [70, 80] # At 70°C, run fan at 80%
74+
- [80, 100] # At 80°C and above, run fan at 100%
75+
76+
statistics:
77+
# Whether to enable the prometheus exporter or not
78+
enabled: true
79+
# The port to expose the exporter on
80+
port: 9900
81+
'';
82+
in
83+
{
84+
options.hardware.fan2go = with lib; {
85+
enable = mkEnableOption "fan2go";
86+
87+
dbPath = mkOption {
88+
type = types.str;
89+
default = "/var/lib/fan2go/fan2go.db";
90+
description = "The path of the database file";
91+
};
92+
};
93+
94+
config = lib.mkIf cfg.enable {
95+
systemd.services.fan2go = {
96+
description = "A simple daemon providing dynamic fan speed control based on temperature sensors";
97+
wantedBy = [ "multi-user.target" ];
98+
after = [ "lm_sensors.service" ];
99+
100+
serviceConfig = {
101+
ExecStart = lib.concatStringsSep " " [
102+
"${pkgs.fan2go}/bin/fan2go"
103+
"-c"
104+
"${fan2goConfig}"
105+
"--no-style"
106+
];
107+
LimitNOFILE = 8192;
108+
};
109+
};
110+
};
111+
}

desktop/l/fan2go.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# fan2go configuration for controlling a Corsair case fan based on the
2+
# temperature of the Radeon Pro VII / Instinct MI50 GPU, which has no fan.
3+
4+
fans:
5+
# Define the fan to be controlled. This is Fan 1 on the Corsair Commander Core XT.
6+
- id: corsair_fan1
7+
# Use liquidctl to set the fan speed.
8+
# The fan type for external commands is `cmd`.
9+
# Assumes the Corsair Commander Core XT is the first device liquidctl finds.
10+
cmd:
11+
# The `setPwm` command is required. It receives a value from 0-255.
12+
# We use a shell command to convert the 0-255 PWM value from fan2go
13+
# into a 0-100 percentage for liquidctl.
14+
setPwm:
15+
exec: "/run/current-system/sw/bin/bash"
16+
args: ["-c", "percent=$((%pwm% * 100 / 255)); /run/current-system/sw/bin/liquidctl set fan1 speed $percent"]
17+
# The `getPwm` command is optional but good practice.
18+
# It should return a value from 0-255.
19+
getPwm:
20+
exec: "/run/current-system/sw/bin/bash"
21+
args: ["-c", "percent=$(/run/current-system/sw/bin/liquidctl status --json | ${pkgs.jq}/bin/jq '.[0].status[] | select(.key == \"Fan speed 1\").value | tonumber'); echo $((percent * 255 / 100))"]
22+
# Fan speed is a percentage for liquidctl
23+
min: 20
24+
max: 100
25+
# Ensures the fan never fully stops, maintaining minimum airflow.
26+
neverStop: true
27+
# The curve ID that should be used to determine the speed of this fan.
28+
curve: gpu_cooling_curve
29+
30+
sensors:
31+
# Define the temperature sensor to monitor. This is the Radeon Pro VII/MI50.
32+
# From `fan2go detect`, this is platform `amdgpu-pci-04400`.
33+
# The sensor type is `hwmon`.
34+
- id: gpu_mi50_temp
35+
hwmon:
36+
platform: amdgpu-pci-04400
37+
# Use the junction temperature (temp2_input) as it's a good indicator of core heat.
38+
index: 2
39+
40+
curves:
41+
# Link the GPU temperature to the case fan speed.
42+
- id: gpu_cooling_curve
43+
# Use a linear interpolation curve based on the defined points.
44+
linear:
45+
# The sensor ID to use as a temperature input for this curve.
46+
sensor: gpu_mi50_temp
47+
# Define the temperature-to-fan-speed mapping.
48+
# Temps are in Celsius, fan speed is in percent.
49+
points:
50+
- [40, 20] # At 40°C, run fan at 20%
51+
- [50, 40] # At 50°C, run fan at 40%
52+
- [60, 60] # At 60°C, run fan at 60%
53+
- [70, 80] # At 70°C, run fan at 80%
54+
- [80, 100] # At 80°C and above, run fan at 100%
55+
56+
statistics:
57+
# Whether to enable the prometheus exporter or not
58+
enabled: true
59+
# The port to expose the exporter on
60+
port: 9900
61+

0 commit comments

Comments
 (0)