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>
4.9 KiB
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):
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.
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:
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 thew/h/gapfields, or change theDEF_*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.