yourovo/README.md
type-two 3fa41ddbf7 docs(mac): patched CUPS PPD for the DYMO 450's 24x55mm price stock
macOS auto-adds a USB LabelWriter 450 with the GENERIC CUPS driver (dymo.ppd,
ModelName "DYMO Label Printer"), which has 10 fixed sizes and no CustomPageSize
block — so a custom paper size made in the page-setup dialog can never reach the
printer. CUPS falls back to w81h252 (Address, 28.6x88.9mm) and the 54x24mm design
prints rotated 90 degrees and shrunk. Cost a bench session to diagnose; the extension's
labels.js was never at fault.

Adds the stock in both feed orientations (pg55x25 / pg55x25L — John's price roll is
the landscape-feed one) plus patch_ppd.py to regenerate. Lives here because mac/dymo.py
drives the same printer.

Must be re-applied after any macOS update or after re-adding the printer, so the file
and the lpadmin invocation are both written down in the README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-24 13:40:30 +10:00

99 lines
4.9 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.

# pricegod-urovo-daemon
The **Windows** counterpart to the Mac `rfid-daemon`. Instead of a Chafon gun writing a
loose chip while a Dymo prints a separate sticker, this drives the **Urovo D812R+ (RFID)**
to **print the label AND encode the UHF chip in one pass** on the composite (paper+chip) rolls.
It listens on `http://localhost:7790/` with `CORS *`, so it's a drop-in for the PriceGod
extension's existing `daemon.js` client — same port, same JSON shape.
## Run it
Double-click **`start-daemon.cmd`** (leave the window open while you work). That's it —
no Node, no .NET SDK, no gitea clone. It's a self-contained `.exe`.
To rebuild after editing `daemon.cs`: double-click **`build.cmd`**.
## What's inside
- `daemon.cs` — the service (C#, .NET Framework 4.x).
- `pricegod-urovo-daemon.exe` — the compiled daemon.
- `GTSPL_SDK.dll`, `GTSPL_SDK_C.dll`, `zlib.net.dll` — the Gainscha/Urovo print SDK
(must sit beside the .exe). Copied from the vendor Windows SDK.
The print/encode sequence is a straight port of the proven `gtcheck.cs` `rfidgo` path:
`SET RIBBON OFF` → continuous geometry (`GAP 0`, RFID rolls blind the optical gap sensor)
`writeUHF` → draw text + QR → `printlabel` → read-back verify.
## Routes
| method | path | body | returns |
|---|---|---|---|
| GET | `/status` | — | `{ok, ready, status, statusText, printer}` |
| POST | `/print-encode` | `{sku, releaseId, artist?, title?, price?, condition?, w?, h?, gap?}` | `{ok, sku, releaseId, epc, verified, status}` |
| POST | `/write-tag` | alias of `/print-encode` (the daemon.js name) | same |
| GET | `/read-tag` | — | `{ok, epc, sku, releaseId, recognized}` |
| POST | `/calibrate` | — | RFID auto-calibration |
| POST | `/recover` | — | ribbon-off + one feed to clear a fault |
Quick test (PowerShell):
```powershell
Invoke-RestMethod http://localhost:7790/status
```
## SKU ↔ EPC scheme (⚠ verify)
The 96-bit EPC (12 bytes) is packed as: **6 bytes** 14-digit timestamp SKU · **4 bytes**
release_id · **2 bytes** `0xEC01` marker. This lives in the `Epc` class in `daemon.cs` and
is the **only** thing that needs to change if it must match a different (Mac/Chafon) layout —
nothing else depends on the byte order. Confirm by reading an existing tag: put a
Chafon-written record at the antenna and `GET /read-tag`.
## DYMO LabelWriter 450 on macOS — the PPD you will need again
Not the daemon, but it lives here because `mac/dymo.py` drives the same printer.
macOS auto-adds a USB LabelWriter 450 with the **generic** CUPS driver
(`*PCFileName: "dymo.ppd"`, `*ModelName: "DYMO Label Printer"`). That PPD ships 10 fixed
label sizes and **no** `CustomPageSize`/`VariablePaperSize` block — so a custom paper size
made in the macOS page-setup dialog can never reach the printer. CUPS silently falls back
to `w81h252` (Address, 28.6 × 88.9 mm), and a 54×24 mm label design comes out **rotated 90°
and shrunk**, with a big blank area. Nothing is wrong with the extension's `labels.js`.
`mac/dymo-24x55.ppd` is the generic PPD patched to add the shop's 24×55 mm price stock, in
both feed orientations, so the right one can be picked in the print dialog:
| PageSize | pt | mm | roll |
|---|---|---|---|
| `pg55x25` | 72 × 155 | 25.4 × 54.7 | ~25 mm wide, label runs 55 mm along the feed |
| `pg55x25L` | 155 × 72 | 54.7 × 25.4 | ~55 mm wide, label runs 25 mm along the feed |
**John's price roll is the landscape-feed kind → use `pg55x25L`.**
```sh
sudo lpadmin -p <queue> -P mac/dymo-24x55.ppd # apply (queue on JING5: make_it_soso)
sudo lpadmin -p <queue> -m drv:///sample.drv/dymo.ppd # revert to stock
```
**Re-apply after any macOS update or after re-adding the printer** — both revert the queue to
the generic driver and the symptom comes straight back.
Regenerate from the **pristine** driver PPD — once applied, the queue's own PPD is already
patched and `patch_ppd.py` will refuse it:
```sh
ppdc -d /tmp/ppdout /usr/share/cups/drv/sample.drv
python3 mac/patch_ppd.py mac/dymo-24x55.ppd /tmp/ppdout/dymo.ppd # byte-identical, PASSes cupstestppd
```
Two traps it handles: margins are set to 2 pt sides / 4 pt ends instead of the driver's
stock 14.9 pt, which would eat 10.5 mm of a 55 mm label; and every one of the 31 languages
in `*cupsLanguages` needs a translation string per new choice or `cupstestppd` FAILs.
Dead end for next time: `LabelPrinter-*.pkg` in `~/Documents` is **not** the DYMO driver —
it's the generic bundle for the PM-246S/Wagtail printers.
## Notes / open items
- Default label geometry is `65×37 mm`, continuous (`GAP 0`). Adjust to your actual RFID
roll via the `w`/`h`/`gap` fields, or change the `DEF_*` constants.
- The label layout (text lines + QR) is functional, not yet pixel-matched to the 51×19
Dymo design in the extension's `labels.js`.
- The Chafon gun is still needed for **reading a loose tag off a shelf** — the Urovo can
only read/write a tag physically inside the printer.