Files
parking_solution/wiki/entities/k200l-printer.md
T
julian 88f9c53fda
Build & push images / images (push) Successful in 2m55s
fix(devices): K200L status parser reads a fault's Yes, which the board wraps in <FONT color=#ff0000>
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
2026-09-09 12:57:58 +02:00

108 lines
6.7 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
```
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]]