diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/misc/klipper.nix')
-rw-r--r-- | nixpkgs/nixos/modules/services/misc/klipper.nix | 111 |
1 files changed, 80 insertions, 31 deletions
diff --git a/nixpkgs/nixos/modules/services/misc/klipper.nix b/nixpkgs/nixos/modules/services/misc/klipper.nix index 7b3780b5cc9f..34e9acc71929 100644 --- a/nixpkgs/nixos/modules/services/misc/klipper.nix +++ b/nixpkgs/nixos/modules/services/misc/klipper.nix @@ -5,9 +5,9 @@ let format = pkgs.formats.ini { # https://github.com/NixOS/nixpkgs/pull/121613#issuecomment-885241996 listToValue = l: - if builtins.length l == 1 then generators.mkValueStringDefault {} (head l) + if builtins.length l == 1 then generators.mkValueStringDefault { } (head l) else lib.concatMapStrings (s: "\n ${generators.mkValueStringDefault {} s}") l; - mkKeyValue = generators.mkKeyValueDefault {} ":"; + mkKeyValue = generators.mkKeyValueDefault { } ":"; }; in { @@ -20,31 +20,31 @@ in type = types.package; default = pkgs.klipper; defaultText = literalExpression "pkgs.klipper"; - description = "The Klipper package."; + description = lib.mdDoc "The Klipper package."; }; inputTTY = mkOption { type = types.path; default = "/run/klipper/tty"; - description = "Path of the virtual printer symlink to create."; + description = lib.mdDoc "Path of the virtual printer symlink to create."; }; apiSocket = mkOption { type = types.nullOr types.path; default = "/run/klipper/api"; - description = "Path of the API socket to create."; + description = lib.mdDoc "Path of the API socket to create."; }; octoprintIntegration = mkOption { type = types.bool; default = false; - description = "Allows Octoprint to control Klipper."; + description = lib.mdDoc "Allows Octoprint to control Klipper."; }; user = mkOption { type = types.nullOr types.str; default = null; - description = '' + description = lib.mdDoc '' User account under which Klipper runs. If null is specified (default), a temporary user will be created by systemd. @@ -54,7 +54,7 @@ in group = mkOption { type = types.nullOr types.str; default = null; - description = '' + description = lib.mdDoc '' Group account under which Klipper runs. If null is specified (default), a temporary user will be created by systemd. @@ -64,11 +64,29 @@ in settings = mkOption { type = format.type; default = { }; - description = '' - Configuration for Klipper. See the <link xlink:href="https://www.klipper3d.org/Overview.html#configuration-and-tuning-guides">documentation</link> + description = lib.mdDoc '' + Configuration for Klipper. See the [documentation](https://www.klipper3d.org/Overview.html#configuration-and-tuning-guides) for supported values. ''; }; + + firmwares = mkOption { + description = lib.mdDoc "Firmwares klipper should manage"; + default = { }; + type = with types; attrsOf + (submodule { + options = { + enable = mkEnableOption '' + building of firmware and addition of klipper-flash tools for manual flashing. + This will add `klipper-flash-$mcu` scripts to your environment which can be called to flash the firmware. + ''; + configFile = mkOption { + type = path; + description = "Path to firmware config which is generated using `klipper-genconf`"; + }; + }; + }); + }; }; }; @@ -83,6 +101,10 @@ in assertion = cfg.user != null -> cfg.group != null; message = "Option klipper.group is not set when a user is specified."; } + { + assertion = foldl (a: b: a && b) true (mapAttrsToList (mcu: _: mcu != null -> (hasAttrByPath [ "${mcu}" "serial" ] cfg.settings)) cfg.firmwares); + message = "Option klipper.settings.$mcu.serial must be set when klipper.firmware.$mcu is specified"; + } ]; environment.etc."klipper.cfg".source = format.generate "klipper.cfg" cfg.settings; @@ -92,26 +114,53 @@ in group = config.services.octoprint.group; }; - systemd.services.klipper = let - klippyArgs = "--input-tty=${cfg.inputTTY}" - + optionalString (cfg.apiSocket != null) " --api-server=${cfg.apiSocket}"; - in { - description = "Klipper 3D Printer Firmware"; - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - - serviceConfig = { - ExecStart = "${cfg.package}/lib/klipper/klippy.py ${klippyArgs} /etc/klipper.cfg"; - RuntimeDirectory = "klipper"; - SupplementaryGroups = [ "dialout" ]; - WorkingDirectory = "${cfg.package}/lib"; - } // (if cfg.user != null then { - Group = cfg.group; - User = cfg.user; - } else { - DynamicUser = true; - User = "klipper"; - }); - }; + systemd.services.klipper = + let + klippyArgs = "--input-tty=${cfg.inputTTY}" + + optionalString (cfg.apiSocket != null) " --api-server=${cfg.apiSocket}"; + in + { + description = "Klipper 3D Printer Firmware"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + + serviceConfig = { + ExecStart = "${cfg.package}/lib/klipper/klippy.py ${klippyArgs} /etc/klipper.cfg"; + RuntimeDirectory = "klipper"; + SupplementaryGroups = [ "dialout" ]; + WorkingDirectory = "${cfg.package}/lib"; + OOMScoreAdjust = "-999"; + CPUSchedulingPolicy = "rr"; + CPUSchedulingPriority = 99; + IOSchedulingClass = "realtime"; + IOSchedulingPriority = 0; + } // (if cfg.user != null then { + Group = cfg.group; + User = cfg.user; + } else { + DynamicUser = true; + User = "klipper"; + }); + }; + + environment.systemPackages = + with pkgs; + let + firmwares = filterAttrs (n: v: v!= null) (mapAttrs + (mcu: { enable, configFile }: if enable then pkgs.klipper-firmware.override { + mcu = lib.strings.sanitizeDerivationName mcu; + firmwareConfig = configFile; + } else null) + cfg.firmwares); + firmwareFlasher = mapAttrsToList + (mcu: firmware: pkgs.klipper-flash.override { + mcu = lib.strings.sanitizeDerivationName mcu; + klipper-firmware = firmware; + flashDevice = cfg.settings."${mcu}".serial; + firmwareConfig = cfg.firmwares."${mcu}".configFile; + }) + firmwares; + in + [ klipper-genconf ] ++ firmwareFlasher ++ attrValues firmwares; }; } |