1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.lirc;
9in
10{
11
12 ###### interface
13
14 options = {
15 services.lirc = {
16
17 enable = lib.mkEnableOption "the LIRC daemon, to receive and send infrared signals";
18
19 options = lib.mkOption {
20 type = lib.types.lines;
21 example = ''
22 [lircd]
23 nodaemon = False
24 '';
25 description = "LIRC default options described in man:lircd(8) ({file}`lirc_options.conf`)";
26 };
27
28 configs = lib.mkOption {
29 type = lib.types.listOf lib.types.lines;
30 description = "Configurations for lircd to load, see man:lircd.conf(5) for details ({file}`lircd.conf`)";
31 };
32
33 extraArguments = lib.mkOption {
34 type = lib.types.listOf lib.types.str;
35 default = [ ];
36 description = "Extra arguments to lircd.";
37 };
38 };
39 };
40
41 ###### implementation
42
43 config = lib.mkIf cfg.enable {
44
45 # Note: LIRC executables raises a warning, if lirc_options.conf do not exists
46 environment.etc."lirc/lirc_options.conf".text = cfg.options;
47
48 passthru.lirc.socket = "/run/lirc/lircd";
49
50 environment.systemPackages = [ pkgs.lirc ];
51
52 systemd.sockets.lircd = {
53 description = "LIRC daemon socket";
54 wantedBy = [ "sockets.target" ];
55 socketConfig = {
56 ListenStream = config.passthru.lirc.socket;
57 SocketUser = "lirc";
58 SocketMode = "0660";
59 };
60 };
61
62 systemd.services.lircd =
63 let
64 configFile = pkgs.writeText "lircd.conf" (builtins.concatStringsSep "\n" cfg.configs);
65 in
66 {
67 description = "LIRC daemon service";
68 after = [ "network.target" ];
69
70 unitConfig.Documentation = [ "man:lircd(8)" ];
71
72 serviceConfig = {
73 RuntimeDirectory = [
74 "lirc"
75 "lirc/lock"
76 ];
77
78 # Service runtime directory and socket share same folder.
79 # Following hacks are necessary to get everything right:
80
81 # 1. prevent socket deletion during stop and restart
82 RuntimeDirectoryPreserve = true;
83
84 # 2. fix runtime folder owner-ship, happens when socket activation
85 # creates the folder
86 PermissionsStartOnly = true;
87 ExecStartPre = [
88 "${pkgs.coreutils}/bin/chown lirc /run/lirc/"
89 ];
90
91 ExecStart = ''
92 ${pkgs.lirc}/bin/lircd --nodaemon \
93 ${lib.escapeShellArgs cfg.extraArguments} \
94 ${configFile}
95 '';
96 User = "lirc";
97 };
98 };
99
100 users.users.lirc = {
101 uid = config.ids.uids.lirc;
102 group = "lirc";
103 description = "LIRC user for lircd";
104 };
105
106 users.groups.lirc.gid = config.ids.gids.lirc;
107 };
108}