1{ config, lib, pkgs, ... }:
2let
3 inherit (lib) mkIf mkOption types;
4
5 cfg = config.hardware.sensor.hddtemp;
6
7 wrapper = pkgs.writeShellScript "hddtemp-wrapper" ''
8 set -eEuo pipefail
9
10 file=/var/lib/hddtemp/hddtemp.db
11
12 drives=(${toString (map (e: ''$(realpath ${lib.escapeShellArg e}) '') cfg.drives)})
13
14 cp ${pkgs.hddtemp}/share/hddtemp/hddtemp.db $file
15 ${lib.concatMapStringsSep "\n" (e: "echo ${lib.escapeShellArg e} >> $file") cfg.dbEntries}
16
17 exec ${pkgs.hddtemp}/bin/hddtemp ${lib.escapeShellArgs cfg.extraArgs} \
18 --daemon \
19 --unit=${cfg.unit} \
20 --file=$file \
21 ''${drives[@]}
22 '';
23
24in
25{
26 meta.maintainers = with lib.maintainers; [ peterhoeg ];
27
28 ###### interface
29
30 options = {
31 hardware.sensor.hddtemp = {
32 enable = mkOption {
33 description = ''
34 Enable this option to support HDD/SSD temperature sensors.
35 '';
36 type = types.bool;
37 default = false;
38 };
39
40 drives = mkOption {
41 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.";
42 type = types.listOf types.str;
43 };
44
45 unit = mkOption {
46 description = "Celsius or Fahrenheit";
47 type = types.enum [ "C" "F" ];
48 default = "C";
49 };
50
51 dbEntries = mkOption {
52 description = "Additional DB entries";
53 type = types.listOf types.str;
54 default = [ ];
55 };
56
57 extraArgs = mkOption {
58 description = "Additional arguments passed to the daemon.";
59 type = types.listOf types.str;
60 default = [ ];
61 };
62 };
63 };
64
65 ###### implementation
66
67 config = mkIf cfg.enable {
68 systemd.services.hddtemp = {
69 description = "HDD/SSD temperature";
70 wantedBy = [ "multi-user.target" ];
71 serviceConfig = {
72 Type = "forking";
73 ExecStart = wrapper;
74 StateDirectory = "hddtemp";
75 PrivateTmp = true;
76 ProtectHome = "tmpfs";
77 ProtectSystem = "strict";
78 };
79 };
80 };
81}