{...}: { # CUPS printing + eSCL scanning for the networked EPSON ET-8550. # # Two queues, deliberately: # EPSON_ET_8550 driverless / IPP Everywhere. The default. PDF is # passed straight through and the printer's own RIP # does the work. 51 page sizes, 26 borderless, and the # only queue that can print CD/DVDs (MediaType Disc). # EPSON_ET_8550_Photo Epson ESC/P-R. Host rasterises to ESC/P-R at 360dpi. # 34 sizes, 12 borderless, no disc support - but it is # the only way to reach Epson's named media/quality # presets ("Epson Ultra Glossy-Max Quality" etc) that # IPP Everywhere cannot express. Kept for photo A/B. # # Note both PPDs are 360x360 HWResolution - escpr2 is not higher resolution. # # Both queues use the mDNS name, not 10.10.20.62, so a DHCP lease change # doesn't break them. services.avahi.nssmdns4 is what resolves it. # Port 9100 is closed on this printer, so socket:// is not an option. # # cups-browsed is off: it would auto-create a third duplicate queue for the # same printer. avahi stays on for mDNS resolution and scanner discovery. flake.nixosModules.printing = { config, lib, pkgs, ... }: { programs.system-config-printer.enable = true; services.avahi = { enable = true; nssmdns4 = true; }; services.printing = { enable = true; browsed.enable = false; drivers = with pkgs; [ epson-escpr2 ]; }; hardware.printers = { ensureDefaultPrinter = "EPSON_ET_8550"; ensurePrinters = [ { name = "EPSON_ET_8550"; description = "EPSON ET-8550 (driverless)"; location = "Network"; deviceUri = "ipp://EPSONA70973.local:631/ipp/print"; model = "everywhere"; } { name = "EPSON_ET_8550_Photo"; description = "EPSON ET-8550 (ESC/P-R photo presets)"; location = "Network"; deviceUri = "ipp://EPSONA70973.local:631/ipp/print"; model = "epson-inkjet-printer-escpr2/Epson-ET-8550_Series-epson-escpr2-en.ppd"; } ]; }; # hardware/printers.nix orders ensure-printers only after cups.service, but # our deviceUri is an mDNS name and the driverless queue queries the printer # while it is created. Run the generated script asynchronously so an offline # printer cannot fail boot or nixos-rebuild, then retry until it is reachable. systemd.services.ensure-printers = lib.mkIf (config.hardware.printers.ensurePrinters != [] && config.services.printing.enable) { after = [ "avahi-daemon.service" "network-online.target" "nss-lookup.target" ]; wants = [ "avahi-daemon.service" "network-online.target" ]; serviceConfig = { Type = lib.mkForce "simple"; Restart = "on-failure"; RestartSec = "1min"; }; }; # eSCL/AirScan. The printer advertises _uscan._tcp with rs=eSCL and # mopria-certified-scan=1.3, so sane-airscan drives it with no vendor # backend. No scanner/lp group needed - there's no local udev device. # # sane-backends ships its own `escl` backend which also claims eSCL # devices. Left enabled it double-lists the scanner and, worse, GETs the # printer's web root and dumps the HTML response onto scanimage's stdout. # Disabling it leaves sane-airscan as the only eSCL backend, which reports # a far better device string (airscan:e0:EPSON ET-8550 Series). hardware.sane = { enable = true; extraBackends = [pkgs.sane-airscan]; disabledDefaultBackends = ["escl"]; }; environment.systemPackages = with pkgs; [ simple-scan ]; }; }