at 23.11-pre 3.8 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.acpid; 7 8 canonicalHandlers = { 9 powerEvent = { 10 event = "button/power.*"; 11 action = cfg.powerEventCommands; 12 }; 13 14 lidEvent = { 15 event = "button/lid.*"; 16 action = cfg.lidEventCommands; 17 }; 18 19 acEvent = { 20 event = "ac_adapter.*"; 21 action = cfg.acEventCommands; 22 }; 23 }; 24 25 acpiConfDir = pkgs.runCommand "acpi-events" { preferLocalBuild = true; } 26 '' 27 mkdir -p $out 28 ${ 29 # Generate a configuration file for each event. (You can't have 30 # multiple events in one config file...) 31 let f = name: handler: 32 '' 33 fn=$out/${name} 34 echo "event=${handler.event}" > $fn 35 echo "action=${pkgs.writeShellScriptBin "${name}.sh" handler.action }/bin/${name}.sh '%e'" >> $fn 36 ''; 37 in concatStringsSep "\n" (mapAttrsToList f (canonicalHandlers // cfg.handlers)) 38 } 39 ''; 40 41in 42 43{ 44 45 ###### interface 46 47 options = { 48 49 services.acpid = { 50 51 enable = mkEnableOption (lib.mdDoc "the ACPI daemon"); 52 53 logEvents = mkOption { 54 type = types.bool; 55 default = false; 56 description = lib.mdDoc "Log all event activity."; 57 }; 58 59 handlers = mkOption { 60 type = types.attrsOf (types.submodule { 61 options = { 62 event = mkOption { 63 type = types.str; 64 example = literalExpression ''"button/power.*" "button/lid.*" "ac_adapter.*" "button/mute.*" "button/volumedown.*" "cd/play.*" "cd/next.*"''; 65 description = lib.mdDoc "Event type."; 66 }; 67 68 action = mkOption { 69 type = types.lines; 70 description = lib.mdDoc "Shell commands to execute when the event is triggered."; 71 }; 72 }; 73 }); 74 75 description = lib.mdDoc '' 76 Event handlers. 77 78 ::: {.note} 79 Handler can be a single command. 80 ::: 81 ''; 82 default = {}; 83 example = { 84 ac-power = { 85 event = "ac_adapter/*"; 86 action = '' 87 vals=($1) # space separated string to array of multiple values 88 case ''${vals[3]} in 89 00000000) 90 echo unplugged >> /tmp/acpi.log 91 ;; 92 00000001) 93 echo plugged in >> /tmp/acpi.log 94 ;; 95 *) 96 echo unknown >> /tmp/acpi.log 97 ;; 98 esac 99 ''; 100 }; 101 }; 102 }; 103 104 powerEventCommands = mkOption { 105 type = types.lines; 106 default = ""; 107 description = lib.mdDoc "Shell commands to execute on a button/power.* event."; 108 }; 109 110 lidEventCommands = mkOption { 111 type = types.lines; 112 default = ""; 113 description = lib.mdDoc "Shell commands to execute on a button/lid.* event."; 114 }; 115 116 acEventCommands = mkOption { 117 type = types.lines; 118 default = ""; 119 description = lib.mdDoc "Shell commands to execute on an ac_adapter.* event."; 120 }; 121 122 }; 123 124 }; 125 126 127 ###### implementation 128 129 config = mkIf cfg.enable { 130 131 systemd.services.acpid = { 132 description = "ACPI Daemon"; 133 documentation = [ "man:acpid(8)" ]; 134 135 wantedBy = [ "multi-user.target" ]; 136 137 serviceConfig = { 138 ExecStart = escapeShellArgs 139 ([ "${pkgs.acpid}/bin/acpid" 140 "--foreground" 141 "--netlink" 142 "--confdir" "${acpiConfDir}" 143 ] ++ optional cfg.logEvents "--logevents" 144 ); 145 }; 146 unitConfig = { 147 ConditionVirtualization = "!systemd-nspawn"; 148 ConditionPathExists = [ "/proc/acpi" ]; 149 }; 150 151 }; 152 153 }; 154 155}