Files
parking_solution/wiki/entities/k200l-printer.md
T
julian 552d87d75b feat(devices): K200L printer driver — live cover/paper status from the J-Speed LAN board
The park-buzi printer is a K200L (Xprinter/ICS XP-K200L; its LAN board and USB
descriptor call it "POS-80"). Its board serves the Rongta's five-row status table
under /prt_status.htm — but the reply carries no HTTP status line or headers, which
node:http rejects, so the Rongta driver could never read it and the unit was filed
in July as "no status page → generic driver" (reachability only).

New `k200l` driver (printer-k200l.ts): prints through the generic ESC/POS device
(same bytes, TCP 9100 or usblp) and reads the page over a raw socket, tolerant of
both the headerless and a proper HTTP reply. Mapping mirrors the Rongta: board
unreachable → offline; page not understood → degraded, never ready; any fault →
degraded naming it; USB → reachability floor. The Rongta driver is untouched.
Tests replay the captured headerless page (devices suite 76). Live against the
lab unit: ready; with the cover open the board reports cover open, paper out,
off-line.

Wiki: new k200l-printer entity (names, network setup from factory
192.168.123.100, board quirks, status page, what it means for park-buzi — over
USB the app never saw cover/paper state at all), cross-links on the Rongta,
status-monitoring, USB-transport and WSL-networking pages (parking-net pinned to
eth1 while the LAN NIC is eth0), index.

Claude-Session: https://claude.ai/code/session_01FWncR69HgGPuei1dLrW3cU
2026-09-09 12:34:59 +02:00

102 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
type: entity
tags: [parking, hardware, printer, escpos, network, usb, status]
sources: []
updated: 2026-09-09
---
# K200L thermal printer (Xprinter / ICS "XP-K200L") — the park-buzi unit
An 80 mm ESC/POS receipt printer, **USB + LAN**, sold under several names. Bottom label:
*"THERMAL RECEIPT PRINTER — Model: K200L — Paper Width: 80mm — Print Speed: 200mm/s — Power
Input: 24V 2.5A — Cash Drawer: 24V 1A — Interface: USB+LAN — Command Support: ESC/POS"*, serial
`BLU2107080238`. Identified on the dev bench 2026-09-09; **it is the printer that "goes offline
after a paper reload" at park-buzi** ([[printer-usb-transport]] §Field bug). The lab's older
"ICS XP-K200L" (10.0.10.11, the 2026-07 USB truncation work) is the same family.
Three names for one device, all seen on the bench:
| Where | What it calls itself |
| --- | --- |
| bottom label | K200L |
| USB descriptor (`lsusb`) | `1fc9:2016 NXP Semiconductors Printer-80` / "Printer POS-80" (0x1fc9 = the NXP controller chip; no brand) |
| LAN board web UI | "J-Speed Ethernet Interface Module", "Ethernet WebConfig Version 1.02", copyright "POS" |
The app driver is **`k200l`** ("K200L 80mm thermal printer (Xprinter / ICS, USB+LAN)",
`packages/devices/src/drivers/printer-k200l.ts`). It prints through the shared generic ESC/POS
path (identical bytes, TCP 9100 or `usblp`) and **adds live status from the LAN board** — see
below. Before 2026-09-09 this unit ran on the generic `escpos` driver (reachability only), which is
why the app could never show its cover/paper state.
## Network setup (the evening that was never written down)
- **Factory address `192.168.123.100/24`, DHCP OFF.** Nothing announces it; the printer just sits
there on a subnet nobody uses. To reach it, give the workstation a second address in
`192.168.123.0/24` (Windows: adapter → IPv4 → Advanced → add `192.168.123.101`), then open
`http://192.168.123.100/`.
- The web configurator (port 80, **no authentication**) is a three-frame page: *Information*
(`ip_info.htm`: MAC, IP, mask, gateway, DHCP on/off, DHCP timeout), *Configuration*
(`ip_config.htm`: DHCP client on/off + timeout, fixed IP / mask / gateway as four octet fields,
**Save**, Restore Default, cancel), *Printer Status* (`prt_status.htm`), *Printer Test*
(`prt_test.htm`), and a **Restart** button in the menu.
- **Set a fixed address on the device VLAN** (park-lab: `10.0.10.7/24`, gateway `10.0.10.1`) →
Save → Restart; then remove the temporary `192.168.123.x` address from the workstation. Keep
DHCP off — the app addresses printers by IP ([[rongta-printer]] §Deployment).
- The self-test page (`prt_test.htm` / the "Print Test Page" button on the status page) prints
the current network settings, so a unit with a forgotten address can be read back that way.
- The board's HTTP server is **tiny**: the frameset reloads its frames every 1–3 s and the status
page every 5 s, and it holds very few connections. **Close the browser tab while the app is
polling**, or connections intermittently time out (seen on the bench: `ping` fine, port open,
every second HTTP connect hanging while the page was open in a browser).
> **WSL gotcha while doing this (2026-09-09):** the dev box then carried BOTH `192.168.123.101`
> and `10.0.10.203` on `eth0`, and WSL sourced 10.0.10.x traffic from the 192.168.123 address —
> the exact [[wsl-dev-networking]] source-address bug, except `parking-net.service` pins `eth1`
> and the mirrored LAN NIC is `eth0` now. Symptom: `ping` works, `curl` times out. Run the fix for
> `eth0`, or drop the temporary address once the printer is moved.
## Live status — the `/prt_status.htm` page
The LAN board serves a five-row table the printer has already decoded from its own sensors:
```
Cover Is Open Yes/No
Cutter Error Yes/No
Paper End Yes/No
Paper Near End Yes/No
Printer Off-Line Yes/No
```
**Same rows, same `<TD>label</TD><TD>Yes|No</TD>` shape as the Rongta board's `/prn_stat.htm`**
([[printer-status-monitoring]]) — only the path differs, which is why nobody found it in July
(the Rongta driver looked for `/prn_stat.htm`, got nothing, and the unit was filed as "serves no
status page → generic driver"). Verified on the bench: cover open → `Cover Is Open Yes`, `Paper End
Yes`, `Printer Off-Line Yes` within a refresh; cover closed → all `No`.
**Quirk that needs its own fetch code:** the board's HTTP reply has **no status line and no
headers** — the body starts at byte 0 (HTTP/0.9 style). Browsers render it; `curl` reports
`000` with an empty body; Node's `http` client rejects it with *"Parse Error: Expected HTTP/, RTSP/
or ICE/"*. So the `k200l` driver reads the page over a **raw TCP socket** (`GET … HTTP/1.0`, read
until the board closes) and accepts both the headerless reply and a proper one. This is the second
reason the K200L has its own driver rather than a path option on the Rongta one.
Status mapping (mirrors the Rongta driver, [[printer-status-monitoring]]): board unreachable /
timeout → **offline**; page reachable but not the table (non-200, the index page) → **degraded
"unexpected status page"**, never ready off a page we didn't read; any Yes → **degraded** naming
the faults ("cover open, paper out, printer off-line"); all No → **ready**. Over **USB** there is
no page: reachability floor only (ready/offline), same as a USB Rongta.
## What this means for the park-buzi bug
At park-buzi this unit ran **over USB** on the generic driver, i.e. monitored by "does
`/dev/usb/lpN` open". A cover-open / paper-out condition **never showed in the app at all** — the
badge stayed green. So the operators' "printer goes offline after reloading paper" was not the
cover state being reported; it was a genuine probe failure whose errno is still unread (site shut
down — [[printer-usb-transport]] §Field bug has the commands to pull first). Running the unit on
**LAN with the `k200l` driver** would give the booth a real amber "cover open / paper out" while
the roll is changed, and removes the `usblp` path from the equation altogether — a strong reason to
cable it to the device VLAN when the site reopens.
Related: [[rongta-printer]] · [[printer-status-monitoring]] · [[printer-usb-transport]] ·
[[printer-roles-failover]] · [[network-isolation]] · [[wsl-dev-networking]] · [[site-device-installation]]