docs(wiki): USB printer cover-open field bug writeup; add art-docker-station lab box
Printer investigation (park-buzi): cover-open on the USB thermal printer wedges its status offline/faulty, surviving a full reboot, recoverable only via `docker restart server`. Traced sendRawUsb/ probeUsb end-to-end — no persistent handle in the app layer, so the leading theory is the container's /dev/usb directory bind-mount retaining a stale view across the printer's physical re-enumeration. Not yet confirmed on hardware; documented with repro/confirmation commands and ranked candidate fixes. Also registers a new lab bench box, "art-docker-station", as a Komodo Stack (dev tier, same shape as park-lab, its own isolated secret refs). Claude-Session: https://claude.ai/code/session_01FWncR69HgGPuei1dLrW3cU
This commit is contained in:
+37
@@ -2673,3 +2673,40 @@ the DS-2CD1047G3H-LIU units rather than carry an RTSP/ffmpeg workaround dependen
|
||||
DS-2CD1043G2-LIU (no such bug, ISAPI main-stream snapshot works natively) is the reference model
|
||||
going forward. RTSP main-stream capture remains documented as a proven, viable fallback if a G3H
|
||||
camera is ever unavoidable, but is not being built. Full sweep table + reasoning on [[lpr-camera]].
|
||||
|
||||
## [2026-08-30] update | Booth USB printer cover-open bug: leading theory is a stale container bind-mount, not a stale app-layer handle
|
||||
|
||||
Live troubleshooting request (park-buzi): opening the printer's paper-roll cover reliably wedges its
|
||||
status to offline/faulty, surviving a full appliance reboot; only `docker restart server` clears it.
|
||||
Traced `sendRawUsb`/`probeUsb` end-to-end in `printer-escpos.ts` plus both poll loops
|
||||
(`device-monitor.ts`, `printer-monitor.ts`): every print AND every poll does a fresh
|
||||
open→write/probe→close with no persistent fd/socket/driver instance anywhere — ruling out a naive
|
||||
"stale Node handle" explanation. Leading hypothesis instead: the cover-open microswitch cuts power
|
||||
to the printer's USB interface board, causing a real bus re-enumeration; the container's directory
|
||||
bind-mount of `/dev/usb` (chosen specifically to survive `lpN` renumbering) can retain a stale view
|
||||
of the old device node until the container's mount namespace is recreated — which `docker restart`
|
||||
does and a policy-driven reboot-time restart may not (boot-order race). Not yet confirmed on
|
||||
hardware (host-vs-container `stat`/inode comparison at the next occurrence is the next step); lab
|
||||
repro is blocked because the lab has a RONGTA, not the park-buzi unit's actual (still unidentified,
|
||||
"Generic (unknown)") model. Full writeup, confirmation commands, and candidate fixes on
|
||||
[[printer-usb-transport]].
|
||||
|
||||
## [2026-08-30] update | Backup status "Never" despite valid rotating backups — restart amnesia in BackupService, fixed
|
||||
|
||||
Admin noticed park-buzi's Backup screen showed "last successful backup: Never" despite 7 real,
|
||||
correctly-rotating encrypted backup files on disk, plus a 2-day gap since the last file. Traced
|
||||
both symptoms to the same cause: `BackupService` tracked last-success/last-error as PLAIN
|
||||
IN-PROCESS FIELDS (never written to the DB), and the daily schedule was a `setInterval(...,24h)`
|
||||
measured from PROCESS START, not wall-clock time since the last real backup — so any server
|
||||
restart (routine under `restart: always`: deploy/crash/OOM/host reboot) simultaneously wiped the
|
||||
visible status back to "Never" and reset the 24h countdown, independent of the actual
|
||||
file-writing/retention engine (`backup.ts`), which was working correctly the whole time and
|
||||
explains why files existed on disk despite the UI's contradictory-seeming status. Fix: four new
|
||||
nullable `site_config` columns (migration `0025_backup_last_status.sql`) persist last-success/
|
||||
error there instead of in memory; `BackupService.status()` reads them fresh each call so a new
|
||||
instance (= a restart) sees the prior instance's outcome; a new `isDue()` method computes
|
||||
schedule-due-ness from the persisted last-success timestamp; `server.ts`'s scheduler is now a
|
||||
15-minute poll gated by `isDue()` instead of a 24h `setInterval`, making the real cadence immune
|
||||
to restart timing. New test file `backup-service.test.ts` (6 tests) covers restart-durability and
|
||||
`isDue()` directly; full existing suite (319 tests) still green. No API/UI contract change. Not
|
||||
yet committed (holding per instruction). Full writeup on [[backup-recovery]].
|
||||
|
||||
Reference in New Issue
Block a user