1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 inherit (lib) mkIf mkOption types;
9
10 cfg = config.hardware.sensor.hddtemp;
11
12 script = ''
13 set -eEuo pipefail
14
15 file=/var/lib/hddtemp/hddtemp.db
16
17 raw_drives=""
18 ${lib.concatStringsSep "\n" (map (drives: "raw_drives+=\"${drives} \"") cfg.drives)}
19 drives=""
20 for i in $raw_drives; do
21 drives+=" $(realpath $i)"
22 done
23
24 cp ${pkgs.hddtemp}/share/hddtemp/hddtemp.db $file
25 ${lib.concatMapStringsSep "\n" (e: "echo ${lib.escapeShellArg e} >> $file") cfg.dbEntries}
26
27 ${pkgs.hddtemp}/bin/hddtemp ${lib.escapeShellArgs cfg.extraArgs} \
28 --daemon \
29 --unit=${cfg.unit} \
30 --file=$file \
31 $drives
32 '';
33
34in
35{
36 meta.maintainers = with lib.maintainers; [ peterhoeg ];
37
38 ###### interface
39
40 options = {
41 hardware.sensor.hddtemp = {
42 enable = mkOption {
43 description = ''
44 Enable this option to support HDD/SSD temperature sensors.
45 '';
46 type = types.bool;
47 default = false;
48 };
49
50 drives = mkOption {
51 description = "List of drives to monitor. If you pass /dev/disk/by-path/* entries the symlinks will be resolved as hddtemp doesn't like names with colons.";
52 type = types.listOf types.str;
53 };
54
55 unit = mkOption {
56 description = "Celsius or Fahrenheit";
57 type = types.enum [
58 "C"
59 "F"
60 ];
61 default = "C";
62 };
63
64 dbEntries = mkOption {
65 description = "Additional DB entries";
66 type = types.listOf types.str;
67 default = [ ];
68 };
69
70 extraArgs = mkOption {
71 description = "Additional arguments passed to the daemon.";
72 type = types.listOf types.str;
73 default = [ ];
74 };
75 };
76 };
77
78 ###### implementation
79
80 config = mkIf cfg.enable {
81 systemd.services.hddtemp = {
82 description = "HDD/SSD temperature";
83 documentation = [ "man:hddtemp(8)" ];
84 wantedBy = [ "multi-user.target" ];
85 inherit script;
86 serviceConfig = {
87 Type = "forking";
88 StateDirectory = "hddtemp";
89 PrivateTmp = true;
90 ProtectHome = "tmpfs";
91 ProtectSystem = "strict";
92 };
93 };
94 };
95}