173 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
		
		
			
		
	
	
			173 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
| 
								 | 
							
								{ config, lib, pkgs, ... }:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								let
							 | 
						||
| 
								 | 
							
								  cfg = config.services.hardware.lcd;
							 | 
						||
| 
								 | 
							
								  pkg = lib.getBin pkgs.lcdproc;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  serverCfg = pkgs.writeText "lcdd.conf" ''
							 | 
						||
| 
								 | 
							
								    [server]
							 | 
						||
| 
								 | 
							
								    DriverPath=${pkg}/lib/lcdproc/
							 | 
						||
| 
								 | 
							
								    ReportToSyslog=false
							 | 
						||
| 
								 | 
							
								    Bind=${cfg.serverHost}
							 | 
						||
| 
								 | 
							
								    Port=${toString cfg.serverPort}
							 | 
						||
| 
								 | 
							
								    ${cfg.server.extraConfig}
							 | 
						||
| 
								 | 
							
								  '';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  clientCfg = pkgs.writeText "lcdproc.conf" ''
							 | 
						||
| 
								 | 
							
								    [lcdproc]
							 | 
						||
| 
								 | 
							
								    Server=${cfg.serverHost}
							 | 
						||
| 
								 | 
							
								    Port=${toString cfg.serverPort}
							 | 
						||
| 
								 | 
							
								    ReportToSyslog=false
							 | 
						||
| 
								 | 
							
								    ${cfg.client.extraConfig}
							 | 
						||
| 
								 | 
							
								  '';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  serviceCfg = {
							 | 
						||
| 
								 | 
							
								    DynamicUser = true;
							 | 
						||
| 
								 | 
							
								    Restart = "on-failure";
							 | 
						||
| 
								 | 
							
								    Slice = "lcd.slice";
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								in with lib; {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  meta.maintainers = with maintainers; [ peterhoeg ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  options = with types; {
							 | 
						||
| 
								 | 
							
								    services.hardware.lcd = {
							 | 
						||
| 
								 | 
							
								      serverHost = mkOption {
							 | 
						||
| 
								 | 
							
								        type = str;
							 | 
						||
| 
								 | 
							
								        default = "localhost";
							 | 
						||
| 
								 | 
							
								        description = "Host on which LCDd is listening.";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      serverPort = mkOption {
							 | 
						||
| 
								 | 
							
								        type = int;
							 | 
						||
| 
								 | 
							
								        default = 13666;
							 | 
						||
| 
								 | 
							
								        description = "Port on which LCDd is listening.";
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      server = {
							 | 
						||
| 
								 | 
							
								        enable = mkOption {
							 | 
						||
| 
								 | 
							
								          type = bool;
							 | 
						||
| 
								 | 
							
								          default = false;
							 | 
						||
| 
								 | 
							
								          description = "Enable the LCD panel server (LCDd)";
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        openPorts = mkOption {
							 | 
						||
| 
								 | 
							
								          type = bool;
							 | 
						||
| 
								 | 
							
								          default = false;
							 | 
						||
| 
								 | 
							
								          description = "Open the ports in the firewall";
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        usbPermissions = mkOption {
							 | 
						||
| 
								 | 
							
								          type = bool;
							 | 
						||
| 
								 | 
							
								          default = false;
							 | 
						||
| 
								 | 
							
								          description = ''
							 | 
						||
| 
								 | 
							
								            Set group-write permissions on a USB device.
							 | 
						||
| 
								 | 
							
								            </para>
							 | 
						||
| 
								 | 
							
								            <para>
							 | 
						||
| 
								 | 
							
								            A USB connected LCD panel will most likely require having its
							 | 
						||
| 
								 | 
							
								            permissions modified for lcdd to write to it. Enabling this option
							 | 
						||
| 
								 | 
							
								            sets group-write permissions on the device identified by
							 | 
						||
| 
								 | 
							
								            <option>services.hardware.lcd.usbVid</option> and
							 | 
						||
| 
								 | 
							
								            <option>services.hardware.lcd.usbPid</option>. In order to find the
							 | 
						||
| 
								 | 
							
								            values, you can run the <command>lsusb</command> command. Example
							 | 
						||
| 
								 | 
							
								            output:
							 | 
						||
| 
								 | 
							
								            </para>
							 | 
						||
| 
								 | 
							
								            <para>
							 | 
						||
| 
								 | 
							
								            <literal>
							 | 
						||
| 
								 | 
							
								            Bus 005 Device 002: ID 0403:c630 Future Technology Devices International, Ltd lcd2usb interface
							 | 
						||
| 
								 | 
							
								            </literal>
							 | 
						||
| 
								 | 
							
								            </para>
							 | 
						||
| 
								 | 
							
								            <para>
							 | 
						||
| 
								 | 
							
								            In this case the vendor id is 0403 and the product id is c630.
							 | 
						||
| 
								 | 
							
								          '';
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        usbVid = mkOption {
							 | 
						||
| 
								 | 
							
								          type = str;
							 | 
						||
| 
								 | 
							
								          default = "";
							 | 
						||
| 
								 | 
							
								          description = "The vendor ID of the USB device to claim.";
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        usbPid = mkOption {
							 | 
						||
| 
								 | 
							
								          type = str;
							 | 
						||
| 
								 | 
							
								          default = "";
							 | 
						||
| 
								 | 
							
								          description = "The product ID of the USB device to claim.";
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        usbGroup = mkOption {
							 | 
						||
| 
								 | 
							
								          type = str;
							 | 
						||
| 
								 | 
							
								          default = "dialout";
							 | 
						||
| 
								 | 
							
								          description = "The group to use for settings permissions. This group must exist or you will have to create it.";
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        extraConfig = mkOption {
							 | 
						||
| 
								 | 
							
								          type = lines;
							 | 
						||
| 
								 | 
							
								          default = "";
							 | 
						||
| 
								 | 
							
								          description = "Additional configuration added verbatim to the server config.";
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      client = {
							 | 
						||
| 
								 | 
							
								        enable = mkOption {
							 | 
						||
| 
								 | 
							
								          type = bool;
							 | 
						||
| 
								 | 
							
								          default = false;
							 | 
						||
| 
								 | 
							
								          description = "Enable the LCD panel client (LCDproc)";
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        extraConfig = mkOption {
							 | 
						||
| 
								 | 
							
								          type = lines;
							 | 
						||
| 
								 | 
							
								          default = "";
							 | 
						||
| 
								 | 
							
								          description = "Additional configuration added verbatim to the client config.";
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        restartForever = mkOption {
							 | 
						||
| 
								 | 
							
								          type = bool;
							 | 
						||
| 
								 | 
							
								          default = true;
							 | 
						||
| 
								 | 
							
								          description = "Try restarting the client forever.";
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  config = mkIf (cfg.server.enable || cfg.client.enable) {
							 | 
						||
| 
								 | 
							
								    networking.firewall.allowedTCPPorts = mkIf (cfg.server.enable && cfg.server.openPorts) [ cfg.serverPort ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    services.udev.extraRules = mkIf (cfg.server.enable && cfg.server.usbPermissions) ''
							 | 
						||
| 
								 | 
							
								      ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="${cfg.server.usbVid}", ATTRS{idProduct}=="${cfg.server.usbPid}", MODE="660", GROUP="${cfg.server.usbGroup}"
							 | 
						||
| 
								 | 
							
								    '';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    systemd.services = {
							 | 
						||
| 
								 | 
							
								      lcdd = mkIf cfg.server.enable {
							 | 
						||
| 
								 | 
							
								        description = "LCDproc - server";
							 | 
						||
| 
								 | 
							
								        wantedBy = [ "lcd.target" ];
							 | 
						||
| 
								 | 
							
								        serviceConfig = serviceCfg // {
							 | 
						||
| 
								 | 
							
								          ExecStart = "${pkg}/bin/LCDd -f -c ${serverCfg}";
							 | 
						||
| 
								 | 
							
								          SupplementaryGroups = cfg.server.usbGroup;
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      lcdproc = mkIf cfg.client.enable {
							 | 
						||
| 
								 | 
							
								        description = "LCDproc - client";
							 | 
						||
| 
								 | 
							
								        after = [ "lcdd.service" ];
							 | 
						||
| 
								 | 
							
								        wantedBy = [ "lcd.target" ];
							 | 
						||
| 
								 | 
							
								        serviceConfig = serviceCfg // {
							 | 
						||
| 
								 | 
							
								          ExecStart = "${pkg}/bin/lcdproc -f -c ${clientCfg}";
							 | 
						||
| 
								 | 
							
								          # If the server is being restarted at the same time, the client will
							 | 
						||
| 
								 | 
							
								          # fail as it cannot connect, so space it out a bit.
							 | 
						||
| 
								 | 
							
								          RestartSec = "5";
							 | 
						||
| 
								 | 
							
								          # Allow restarting for eternity
							 | 
						||
| 
								 | 
							
								          StartLimitIntervalSec = lib.mkIf cfg.client.restartForever "0";
							 | 
						||
| 
								 | 
							
								          StartLimitBurst = lib.mkIf cfg.client.restartForever "0";
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    systemd.targets.lcd = {
							 | 
						||
| 
								 | 
							
								      description = "LCD client/server";
							 | 
						||
| 
								 | 
							
								      after = [ "lcdd.service" "lcdproc.service" ];
							 | 
						||
| 
								 | 
							
								      wantedBy = [ "multi-user.target" ];
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								}
							 |