fix(devices): K200L status parser reads a fault's Yes, which the board wraps in <FONT color=#ff0000>
Build & push images / images (push) Successful in 2m55s
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
This commit is contained in:
@@ -57,6 +57,26 @@ describe("parseStatusPage", () => {
|
||||
it("leaves unknown pages empty rather than guessing", () => {
|
||||
expect(parseStatusPage(INDEX)).toEqual({});
|
||||
});
|
||||
it("reads a fault's Yes, which the board wraps in <FONT color=#ff0000> (captured live, cover open)", () => {
|
||||
// Verbatim from the unit on 2026-09-09 with the cover open: the three fault cells carry
|
||||
// markup the No cells don't — the first parser rejected them ("missing coverOpen,
|
||||
// paperEnd, offline" on the booth) while the No cells parsed.
|
||||
const page = boardPage()
|
||||
.replace("Cover Is Open</TD><TD style=\"width: 23px\">No ", "Cover Is Open</TD><TD style=\"width: 23px\"><FONT color=#ff0000>Yes</FONT> ")
|
||||
.replace("Paper End</TD><TD style=\"width: 23px\">No ", "Paper End</TD><TD style=\"width: 23px\"><FONT color=#ff0000>Yes</FONT> ")
|
||||
.replace("Printer Off-Line</TD><TD style=\"width: 23px\">No ", "Printer Off-Line</TD><TD style=\"width: 23px\"><FONT color=#ff0000>Yes</FONT> ");
|
||||
expect(parseStatusPage(page)).toEqual({ coverOpen: true, cutterError: false, paperEnd: true, paperNearEnd: false, offline: true });
|
||||
});
|
||||
it("tolerates other markup shapes around a value", () => {
|
||||
const page = boardPage()
|
||||
.replace("Paper End</TD><TD style=\"width: 23px\">No ", "Paper End</TD><TD style=\"width: 23px\"><B><FONT color=\"#ff0000\">Yes </FONT></B>")
|
||||
.replace("Printer Off-Line</TD><TD style=\"width: 23px\">No ", "Printer Off-Line</TD>\r\n<TD style=\"width: 23px\">\r\n<font>Yes</font>\r\n");
|
||||
expect(parseStatusPage(page)).toEqual({ coverOpen: false, cutterError: false, paperEnd: true, paperNearEnd: false, offline: true });
|
||||
});
|
||||
it("reads labels wrapped in markup too", () => {
|
||||
const page = boardPage({ nearEnd: "Yes" }).replace("<TD>Paper Near End</TD>", "<TD><B>Paper Near End</B></TD>");
|
||||
expect(parseStatusPage(page).paperNearEnd).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("k200lDriver.readStatus over TCP", () => {
|
||||
|
||||
@@ -107,21 +107,33 @@ export function parseRawReply(raw: string): { status: number; body: string } {
|
||||
return { status: Number(m[1]), body };
|
||||
}
|
||||
|
||||
/** A cell's visible text: inner tags stripped (the board wraps a "Yes" in markup the
|
||||
* "No" cells don't carry), entities and padding normalised, lowercased. */
|
||||
function cellText(inner: string): string {
|
||||
return inner
|
||||
.replace(/<[^>]*>/g, "")
|
||||
.replace(/ /gi, " ")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the status table into boolean flags. Each fault is a `<TD>label</TD>
|
||||
* <TD>Yes|No</TD>` pair (the board pads the value with spaces). Returns only the
|
||||
* <TD>Yes|No</TD>` pair (the board pads the value with spaces, and may wrap a fault's
|
||||
* "Yes" in its own tags — 2026-09-09, seen live as "missing coverOpen, paperEnd,
|
||||
* offline" with the cover open, i.e. exactly the Yes cells). Returns only the
|
||||
* recognised fields; a missing field stays undefined so the caller can detect an
|
||||
* unexpected page (fail safe, not a false "ok").
|
||||
*/
|
||||
export function parseStatusPage(html: string): StatusFlags {
|
||||
const out: StatusFlags = {};
|
||||
const rowRe = /<TD[^>]*>([^<]*?)<\/TD>\s*<TD[^>]*>([^<]*?)<\/TD>/gi;
|
||||
const rowRe = /<TR[^>]*>\s*<TD[^>]*>([\s\S]*?)<\/TD>\s*<TD[^>]*>([\s\S]*?)<\/TD>/gi;
|
||||
let m: RegExpExecArray | null;
|
||||
while ((m = rowRe.exec(html))) {
|
||||
if (m[1] === undefined || m[2] === undefined) continue;
|
||||
const label = m[1].replace(/ /gi, " ").replace(/\s+/g, " ").trim().toLowerCase();
|
||||
const value = m[2].replace(/ /gi, " ").trim().toLowerCase();
|
||||
const key = STATUS_FIELDS[label];
|
||||
const key = STATUS_FIELDS[cellText(m[1])];
|
||||
const value = cellText(m[2]);
|
||||
if (key && (value === "yes" || value === "no")) out[key] = value === "yes";
|
||||
}
|
||||
return out;
|
||||
|
||||
@@ -314,6 +314,12 @@ sudo loginctl enable-linger admin # so the user service starts at boot witho
|
||||
**Verify:** `systemctl --user status periphery` → active; the server **`park-buzi`** appears and
|
||||
goes **OK/green** in Core → Servers. Then **delete the onboarding key**.
|
||||
|
||||
> **After a reboot: `Unit periphery.service not loaded` (park-lab, 2026-09-09).** The unit
|
||||
> existed but had never been **enabled**, so nothing started it at boot and `reset-failed` /
|
||||
> `restart` had nothing to act on. Fix: `systemctl --user daemon-reload && systemctl --user enable
|
||||
> --now periphery`. Add `enable --now` to the install sequence above whenever the installer's own
|
||||
> enable did not stick (check with `systemctl --user is-enabled periphery` before leaving).
|
||||
|
||||
**➜ Next step is §7b below — the Stack itself is not deployed yet.** A green Server in Core just
|
||||
means the agent connected; it runs nothing until you add the Registry/Git accounts and deploy.
|
||||
|
||||
|
||||
@@ -67,6 +67,12 @@ 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
|
||||
|
||||
+11
@@ -3297,3 +3297,14 @@ factory reset), radar (idle level → activeLow), printers (K200L / Rongta / Cas
|
||||
USB; "Test" probes, print a card to verify), the on-site order of work, and the gaps still
|
||||
unrecorded (Cashino/Rongta factory addresses, the reader tool screens, camera activation, where
|
||||
the site record lives). Linked from [[appliance-provisioning]] and [[k200l-printer]]; indexed.
|
||||
|
||||
## [2026-09-09] fix | K200L status parser — a fault's "Yes" is wrapped in <FONT color=#ff0000>
|
||||
First live run on park-lab (driver `k200l`, LAN, cover open) showed *degraded — unexpected status
|
||||
page (missing coverOpen, paperEnd, offline)*: precisely the three Yes cells. Captured the raw page
|
||||
with the cover open: the board writes `<FONT color=#ff0000>Yes</FONT>` for a fault and a bare
|
||||
padded `No` otherwise; the parser accepted only tag-free cells. Fix: cell text is read with inner
|
||||
tags stripped (row-anchored regex); tests pin the verbatim markup plus other shapes (devices 79).
|
||||
Live after the fix: degraded "cover open, paper out, printer off-line"; closed → ready. User:
|
||||
"we are good using the network with this printer." Also: park-lab Periphery was "not loaded"
|
||||
after a reboot — the unit had never been enabled; `systemctl --user enable --now periphery`
|
||||
recorded as a §7a gotcha on [[appliance-provisioning]]. Pages: [[k200l-printer]].
|
||||
|
||||
Reference in New Issue
Block a user