I'm using CUPS on an ARM single-board computer to share a USB printer over the network. To conserve power, the printer is usually powered off via a remote-controlled power outlet and only switched on via a web-interface when it is needed. When it is powered up, the printer takes about half a minute to initialize and become ready to accept print jobs.CUPS shows the printer as Idle and Ready even when it is powered off or still initializing, but lsusb doesn't show the printer while it is still in an unavailable state.I wanted a way to tell if the printer was powered on and initialized before sending it print jobs (that might hang or get dropped if the printer was unavailable).
How to make CUPS show a USB printer as disabled when it is disconnected?
udev;cups;printer
Turns out CUPS offers the commands cupsreject and cupsaccept to mark/unmark a printer as unusable (so it will appear greyed out in print dialogs). cupsreject also accepts an optional -r parameter with a string that gives a reason for the printer's unavailability.Combined with two udev rules that are executed when the printer is connected to the USB port (or powered on) and disconnected (powered off), this allows us to mark the printer as disconnected and have that status show up on all computers that access the printer via the network:/etc/udev/rules.d/usb-printer.rules:ACTION==add, SUBSYSTEM==usb, ENV{DEVTYPE}==usb_device, ENV{ID_VENDOR_ID}==03f0, ENV{ID_MODEL_ID}==0917, RUN+=/usr/sbin/cupsaccept HP_LaserJet_3330ACTION==remove, SUBSYSTEM==usb, ENV{DEVTYPE}==usb_device, ENV{ID_VENDOR_ID}==03f0, ENV{ID_MODEL_ID}==0917, RUN+=/usr/sbin/cupsreject -r 'udev: Printer not connected' HP_LaserJet_3330Some notes for anyone who wants to adapt this solution for their own system:The usb-printer part of the rule filename is arbitrary, but udev might ignore it if the filename doesn't end with .rules.  The USB vendor and product IDs (0x03f0 and 0x0917 in this case) have to be changed to the IDs of your printer, as shown by lsusb.The printer name given to the cupsaccept and cupsreject commands has to match the name used by CUPS. You can list installed printers with lpstat -v.