1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.mbpfan;
9 verbose = lib.optionalString cfg.verbose "v";
10 format = pkgs.formats.ini { };
11 cfgfile = format.generate "mbpfan.ini" cfg.settings;
12
13in
14{
15 options.services.mbpfan = {
16 enable = lib.mkEnableOption "mbpfan, fan controller daemon for Apple Macs and MacBooks";
17 package = lib.mkPackageOption pkgs "mbpfan" { };
18
19 verbose = lib.mkOption {
20 type = lib.types.bool;
21 default = false;
22 description = "If true, sets the log level to verbose.";
23 };
24
25 aggressive = lib.mkOption {
26 type = lib.types.bool;
27 default = true;
28 description = "If true, favors higher default fan speeds.";
29 };
30
31 settings = lib.mkOption {
32 default = { };
33 description = "INI configuration for Mbpfan.";
34 type = lib.types.submodule {
35 freeformType = format.type;
36
37 options.general.low_temp = lib.mkOption {
38 type = lib.types.int;
39 default = (if cfg.aggressive then 55 else 63);
40 defaultText = lib.literalExpression "55";
41 description = "If temperature is below this, fans will run at minimum speed.";
42 };
43 options.general.high_temp = lib.mkOption {
44 type = lib.types.int;
45 default = (if cfg.aggressive then 58 else 66);
46 defaultText = lib.literalExpression "58";
47 description = "If temperature is above this, fan speed will gradually increase.";
48 };
49 options.general.max_temp = lib.mkOption {
50 type = lib.types.int;
51 default = (if cfg.aggressive then 78 else 86);
52 defaultText = lib.literalExpression "78";
53 description = "If temperature is above this, fans will run at maximum speed.";
54 };
55 options.general.polling_interval = lib.mkOption {
56 type = lib.types.int;
57 default = 1;
58 description = "The polling interval.";
59 };
60 };
61 };
62 };
63
64 imports = [
65 (lib.mkRenamedOptionModule
66 [ "services" "mbpfan" "pollingInterval" ]
67 [ "services" "mbpfan" "settings" "general" "polling_interval" ]
68 )
69 (lib.mkRenamedOptionModule
70 [ "services" "mbpfan" "maxTemp" ]
71 [ "services" "mbpfan" "settings" "general" "max_temp" ]
72 )
73 (lib.mkRenamedOptionModule
74 [ "services" "mbpfan" "lowTemp" ]
75 [ "services" "mbpfan" "settings" "general" "low_temp" ]
76 )
77 (lib.mkRenamedOptionModule
78 [ "services" "mbpfan" "highTemp" ]
79 [ "services" "mbpfan" "settings" "general" "high_temp" ]
80 )
81 (lib.mkRenamedOptionModule
82 [ "services" "mbpfan" "minFanSpeed" ]
83 [ "services" "mbpfan" "settings" "general" "min_fan1_speed" ]
84 )
85 (lib.mkRenamedOptionModule
86 [ "services" "mbpfan" "maxFanSpeed" ]
87 [ "services" "mbpfan" "settings" "general" "max_fan1_speed" ]
88 )
89 ];
90
91 config = lib.mkIf cfg.enable {
92 boot.kernelModules = [
93 "coretemp"
94 "applesmc"
95 ];
96 environment.systemPackages = [ cfg.package ];
97 environment.etc."mbpfan.conf".source = cfgfile;
98
99 systemd.services.mbpfan = {
100 description = "A fan manager daemon for MacBook Pro";
101 wantedBy = [ "sysinit.target" ];
102 after = [ "sysinit.target" ];
103 restartTriggers = [ config.environment.etc."mbpfan.conf".source ];
104
105 serviceConfig = {
106 Type = "simple";
107 ExecStart = "${cfg.package}/bin/mbpfan -f${verbose}";
108 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
109 PIDFile = "/run/mbpfan.pid";
110 Restart = "always";
111 };
112 };
113 };
114}