nixos/preload: init
[NixPkgs.git] / nixos / modules / services / hardware / lcd.nix
blob8d682d137f44c39499a9f6c0e30e55b0ffbda050
1 { config, lib, pkgs, ... }:
3 let
4   cfg = config.services.hardware.lcd;
5   pkg = lib.getBin pkgs.lcdproc;
7   serverCfg = pkgs.writeText "lcdd.conf" ''
8     [server]
9     DriverPath=${pkg}/lib/lcdproc/
10     ReportToSyslog=false
11     Bind=${cfg.serverHost}
12     Port=${toString cfg.serverPort}
13     ${cfg.server.extraConfig}
14   '';
16   clientCfg = pkgs.writeText "lcdproc.conf" ''
17     [lcdproc]
18     Server=${cfg.serverHost}
19     Port=${toString cfg.serverPort}
20     ReportToSyslog=false
21     ${cfg.client.extraConfig}
22   '';
24   serviceCfg = {
25     DynamicUser = true;
26     Restart = "on-failure";
27     Slice = "lcd.slice";
28   };
30 in with lib; {
32   meta.maintainers = with maintainers; [ peterhoeg ];
34   options = with types; {
35     services.hardware.lcd = {
36       serverHost = mkOption {
37         type = str;
38         default = "localhost";
39         description = lib.mdDoc "Host on which LCDd is listening.";
40       };
42       serverPort = mkOption {
43         type = int;
44         default = 13666;
45         description = lib.mdDoc "Port on which LCDd is listening.";
46       };
48       server = {
49         enable = mkOption {
50           type = bool;
51           default = false;
52           description = lib.mdDoc "Enable the LCD panel server (LCDd)";
53         };
55         openPorts = mkOption {
56           type = bool;
57           default = false;
58           description = lib.mdDoc "Open the ports in the firewall";
59         };
61         usbPermissions = mkOption {
62           type = bool;
63           default = false;
64           description = lib.mdDoc ''
65             Set group-write permissions on a USB device.
67             A USB connected LCD panel will most likely require having its
68             permissions modified for lcdd to write to it. Enabling this option
69             sets group-write permissions on the device identified by
70             {option}`services.hardware.lcd.usbVid` and
71             {option}`services.hardware.lcd.usbPid`. In order to find the
72             values, you can run the {command}`lsusb` command. Example
73             output:
75             ```
76             Bus 005 Device 002: ID 0403:c630 Future Technology Devices International, Ltd lcd2usb interface
77             ```
79             In this case the vendor id is 0403 and the product id is c630.
80           '';
81         };
83         usbVid = mkOption {
84           type = str;
85           default = "";
86           description = lib.mdDoc "The vendor ID of the USB device to claim.";
87         };
89         usbPid = mkOption {
90           type = str;
91           default = "";
92           description = lib.mdDoc "The product ID of the USB device to claim.";
93         };
95         usbGroup = mkOption {
96           type = str;
97           default = "dialout";
98           description = lib.mdDoc "The group to use for settings permissions. This group must exist or you will have to create it.";
99         };
101         extraConfig = mkOption {
102           type = lines;
103           default = "";
104           description = lib.mdDoc "Additional configuration added verbatim to the server config.";
105         };
106       };
108       client = {
109         enable = mkOption {
110           type = bool;
111           default = false;
112           description = lib.mdDoc "Enable the LCD panel client (LCDproc)";
113         };
115         extraConfig = mkOption {
116           type = lines;
117           default = "";
118           description = lib.mdDoc "Additional configuration added verbatim to the client config.";
119         };
121         restartForever = mkOption {
122           type = bool;
123           default = true;
124           description = lib.mdDoc "Try restarting the client forever.";
125         };
126       };
127     };
128   };
130   config = mkIf (cfg.server.enable || cfg.client.enable) {
131     networking.firewall.allowedTCPPorts = mkIf (cfg.server.enable && cfg.server.openPorts) [ cfg.serverPort ];
133     services.udev.extraRules = mkIf (cfg.server.enable && cfg.server.usbPermissions) ''
134       ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="${cfg.server.usbVid}", ATTRS{idProduct}=="${cfg.server.usbPid}", MODE="660", GROUP="${cfg.server.usbGroup}"
135     '';
137     systemd.services = {
138       lcdd = mkIf cfg.server.enable {
139         description = "LCDproc - server";
140         wantedBy = [ "lcd.target" ];
141         serviceConfig = serviceCfg // {
142           ExecStart = "${pkg}/bin/LCDd -f -c ${serverCfg}";
143           SupplementaryGroups = cfg.server.usbGroup;
144         };
145       };
147       lcdproc = mkIf cfg.client.enable {
148         description = "LCDproc - client";
149         after = [ "lcdd.service" ];
150         wantedBy = [ "lcd.target" ];
151         # Allow restarting for eternity
152         startLimitIntervalSec = lib.mkIf cfg.client.restartForever 0;
153         serviceConfig = serviceCfg // {
154           ExecStart = "${pkg}/bin/lcdproc -f -c ${clientCfg}";
155           # If the server is being restarted at the same time, the client will
156           # fail as it cannot connect, so space it out a bit.
157           RestartSec = "5";
158         };
159       };
160     };
162     systemd.targets.lcd = {
163       description = "LCD client/server";
164       after = [ "lcdd.service" "lcdproc.service" ];
165       wantedBy = [ "multi-user.target" ];
166     };
167   };