1{ config, lib, pkgs, ... }:
2
3with lib;
4
5let
6
7 canonicalHandlers = {
8 powerEvent = {
9 event = "button/power.*";
10 action = config.services.acpid.powerEventCommands;
11 };
12
13 lidEvent = {
14 event = "button/lid.*";
15 action = config.services.acpid.lidEventCommands;
16 };
17
18 acEvent = {
19 event = "ac_adapter.*";
20 action = config.services.acpid.acEventCommands;
21 };
22 };
23
24 acpiConfDir = pkgs.runCommand "acpi-events" {}
25 ''
26 mkdir -p $out
27 ${
28 # Generate a configuration file for each event. (You can't have
29 # multiple events in one config file...)
30 let f = name: handler:
31 ''
32 fn=$out/${name}
33 echo "event=${handler.event}" > $fn
34 echo "action=${pkgs.writeScript "${name}.sh" (concatStringsSep "\n" [ "#! ${pkgs.bash}/bin/sh" handler.action ])}" >> $fn
35 '';
36 in concatStringsSep "\n" (mapAttrsToList f (canonicalHandlers // config.services.acpid.handlers))
37 }
38 '';
39
40in
41
42{
43
44 ###### interface
45
46 options = {
47
48 services.acpid = {
49
50 enable = mkOption {
51 type = types.bool;
52 default = false;
53 description = "Whether to enable the ACPI daemon.";
54 };
55
56 handlers = mkOption {
57 type = types.attrsOf (types.submodule {
58 options = {
59 event = mkOption {
60 type = types.str;
61 example = [ "button/power.*" "button/lid.*" "ac_adapter.*" "button/mute.*" "button/volumedown.*" "cd/play.*" "cd/next.*" ];
62 description = "Event type.";
63 };
64
65 action = mkOption {
66 type = types.lines;
67 description = "Shell commands to execute when the event is triggered.";
68 };
69 };
70 });
71
72 description = "Event handlers.";
73 default = {};
74 example = { mute = { event = "button/mute.*"; action = "amixer set Master toggle"; }; };
75
76
77 };
78
79 powerEventCommands = mkOption {
80 type = types.lines;
81 default = "";
82 description = "Shell commands to execute on a button/power.* event.";
83 };
84
85 lidEventCommands = mkOption {
86 type = types.lines;
87 default = "";
88 description = "Shell commands to execute on a button/lid.* event.";
89 };
90
91 acEventCommands = mkOption {
92 type = types.lines;
93 default = "";
94 description = "Shell commands to execute on an ac_adapter.* event.";
95 };
96
97 };
98
99 };
100
101
102 ###### implementation
103
104 config = mkIf config.services.acpid.enable {
105
106 systemd.services.acpid = {
107 description = "ACPI Daemon";
108
109 wantedBy = [ "multi-user.target" ];
110 after = [ "systemd-udev-settle.service" ];
111
112 path = [ pkgs.acpid ];
113
114 serviceConfig = {
115 Type = "forking";
116 };
117
118 unitConfig = {
119 ConditionVirtualization = "!systemd-nspawn";
120 ConditionPathExists = [ "/proc/acpi" ];
121 };
122
123 script = "acpid --confdir ${acpiConfDir}";
124 };
125
126 };
127
128}