nixpkgs/nixos/modules/services/hardware/lcd.nix
2018-04-25 22:16:07 +08:00

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" ];
};
};
}