feat(setup): USB printer discovery — pick a real /dev/usb device
Build desktop / desktop (push) Successful in 4m21s
CI / check (push) Successful in 50s
Build & push images / images (push) Successful in 2m54s

The kernel numbers usblp nodes by plug/boot order (park-buzi's printer
is lp1); the wizard hardcoded lp0 in labels/default and the admin had to
shell in and `ls /dev/usb`. Now:

- GET /api/setup/usb-printers enumerates /dev/usb/lpN (visible via the
  compose bind-mount) and enriches each with the printer's self-reported
  make/model from sysfs ieee1284_id (readable through Docker's ro /sys).
- The wizard's devicePath becomes a SELECT of printers actually present
  ("/dev/usb/lp1 — Xprinter XP-K200L"): a fresh form preselects the
  first real device; a saved-but-unplugged path stays selectable,
  flagged "saved — not present now"; zero found falls back to free text
  + a check-the-cable hint.
- Transport option label no longer hardcodes lp0.

Wiki: printer-usb-transport marked HARDWARE-VERIFIED (lab 2026-07-07:
full slip + feed + cut over USB — parity with TCP).

Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
2026-07-07 11:35:25 +02:00
parent 011fe5a4c4
commit cd3b534e51
8 changed files with 118 additions and 3 deletions
+13
View File
@@ -121,6 +121,19 @@ completion signal, but Node cannot poll an arbitrary char-device fd without a na
hold-back + drain gets the same guarantee for all but the final byte, whose packet the printer
ACKs immediately after having just freed its buffer.)
**✅ HARDWARE-VERIFIED (lab bench, 2026-07-07):** with both fixes, the ICS XP-K200L over USB
prints the complete slip, feeds, and CUTS — parity with TCP. The USB transport is done.
**Device discovery (2026-07-07).** The kernel numbers usblp nodes by plug/boot order — park-buzi's
printer is `lp1`, and the admin had to shell in and `ls /dev/usb` to learn that. The wizard now
lists REAL printers: `GET /api/setup/usb-printers` enumerates `/dev/usb/lpN` (visible via the
compose bind-mount) and enriches each with the printer's self-reported make/model from sysfs
(`/sys/class/usbmisc/lpN/device/ieee1284_id` — readable through Docker's default ro `/sys`). The
devicePath field becomes a SELECT ("/dev/usb/lp1 — Xprinter XP-K200L") with a fresh form
preselecting the first present device; a saved-but-unplugged path stays selectable, flagged
"saved — not present now"; zero devices found falls back to the free-text path + a check-the-cable
hint. The transport option label no longer hardcodes lp0.
> Driver-choice note for this clone: the ICS XP-K200L does NOT serve the Rongta `/prn_stat.htm`
> status page (checked on hardware at 10.0.10.11 — print socket 9100 open, status page absent),
> so on NETWORK the honest driver is **cashino** (reachability-only monitoring); under `rongta`
+9
View File
@@ -2496,3 +2496,12 @@ close. writeAllUsb now holds back the FINAL byte as its own write — usblp's on
acceptance a completion certificate for everything before it — then drains 300ms for that single
packet before close. Tests updated (+ final-byte-alone assertion). [[printer-usb-transport]] has
the full kernel-level account.
## [2026-07-07] update | USB printing HARDWARE-VERIFIED; wizard lists real /dev/usb devices
Lab retest after the close-cancel fix: full slip + feed + CUT over USB — parity with TCP; the
transport is done. Follow-up UX (operator had to `ls /dev/usb` to find lp1 on park-buzi): new
GET /api/setup/usb-printers enumerates /dev/usb/lpN + sysfs ieee1284_id make/model; the wizard's
devicePath is now a select of PRESENT printers (fresh form preselects the first; a saved-but-
absent path stays selectable, flagged; none found → free-text + hint). Transport option label no
longer hardcodes lp0. Details on [[printer-usb-transport]].