at 23.11-pre 5.1 kB view raw
1{ config, lib, pkgs, ... }: 2 3let 4 cfg = config.services.hardware.lcd; 5 pkg = lib.getBin pkgs.lcdproc; 6 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 ''; 15 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 ''; 23 24 serviceCfg = { 25 DynamicUser = true; 26 Restart = "on-failure"; 27 Slice = "lcd.slice"; 28 }; 29 30in with lib; { 31 32 meta.maintainers = with maintainers; [ peterhoeg ]; 33 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 }; 41 42 serverPort = mkOption { 43 type = int; 44 default = 13666; 45 description = lib.mdDoc "Port on which LCDd is listening."; 46 }; 47 48 server = { 49 enable = mkOption { 50 type = bool; 51 default = false; 52 description = lib.mdDoc "Enable the LCD panel server (LCDd)"; 53 }; 54 55 openPorts = mkOption { 56 type = bool; 57 default = false; 58 description = lib.mdDoc "Open the ports in the firewall"; 59 }; 60 61 usbPermissions = mkOption { 62 type = bool; 63 default = false; 64 description = lib.mdDoc '' 65 Set group-write permissions on a USB device. 66 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: 74 75 ``` 76 Bus 005 Device 002: ID 0403:c630 Future Technology Devices International, Ltd lcd2usb interface 77 ``` 78 79 In this case the vendor id is 0403 and the product id is c630. 80 ''; 81 }; 82 83 usbVid = mkOption { 84 type = str; 85 default = ""; 86 description = lib.mdDoc "The vendor ID of the USB device to claim."; 87 }; 88 89 usbPid = mkOption { 90 type = str; 91 default = ""; 92 description = lib.mdDoc "The product ID of the USB device to claim."; 93 }; 94 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 }; 100 101 extraConfig = mkOption { 102 type = lines; 103 default = ""; 104 description = lib.mdDoc "Additional configuration added verbatim to the server config."; 105 }; 106 }; 107 108 client = { 109 enable = mkOption { 110 type = bool; 111 default = false; 112 description = lib.mdDoc "Enable the LCD panel client (LCDproc)"; 113 }; 114 115 extraConfig = mkOption { 116 type = lines; 117 default = ""; 118 description = lib.mdDoc "Additional configuration added verbatim to the client config."; 119 }; 120 121 restartForever = mkOption { 122 type = bool; 123 default = true; 124 description = lib.mdDoc "Try restarting the client forever."; 125 }; 126 }; 127 }; 128 }; 129 130 config = mkIf (cfg.server.enable || cfg.client.enable) { 131 networking.firewall.allowedTCPPorts = mkIf (cfg.server.enable && cfg.server.openPorts) [ cfg.serverPort ]; 132 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 ''; 136 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 }; 146 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 }; 161 162 systemd.targets.lcd = { 163 description = "LCD client/server"; 164 after = [ "lcdd.service" "lcdproc.service" ]; 165 wantedBy = [ "multi-user.target" ]; 166 }; 167 }; 168}