88f9c53fda
Build & push images / images (push) Successful in 2m55s
First live run on park-lab with the cover open reported "unexpected status page (missing coverOpen, paperEnd, offline)" — exactly the three fault cells. The board writes a fault as <FONT color=#ff0000>Yes</FONT> and a clear row as a bare padded No; the parser accepted only tag-free cells. Cell text is now read with inner tags stripped (row-anchored match). Tests pin the verbatim captured markup plus other shapes. Live after the fix: degraded "cover open, paper out, printer off-line"; cover closed → ready. Wiki: the markup on the K200L page; Periphery "not loaded after reboot" (unit never enabled → `systemctl --user enable --now periphery`) as a §7a gotcha in the provisioning runbook; log. Claude-Session: https://claude.ai/code/session_01FWncR69HgGPuei1dLrW3cU
108 lines
6.7 KiB
Markdown
108 lines
6.7 KiB
Markdown
---
|
||
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
|
||
```
|
||
|
||
A fault is written as **`<FONT color=#ff0000>Yes</FONT>`** while a clear row is a bare, space-padded
|
||
`No` — the first parser only accepted tag-free cells, so with the cover open the booth showed
|
||
*"unexpected status page (missing coverOpen, paperEnd, offline)"*: exactly the Yes cells. Fixed
|
||
the same day (cell text is read with inner tags stripped); the verbatim markup is pinned in the
|
||
driver's tests.
|
||
|
||
**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]]
|