Answers "can we direct print to the Dymo via CUPS, or is it the cmd-P dance?":
neither. The LW450 (0922:0020) is a bidirectional USB printer-class device just
like the Urovo, so its raster protocol goes straight to the bulk endpoint -- no
DYMO driver, no CUPS queue, no print dialog. Command set taken from DYMO's own
LabelWriter 450 Series Technical Reference Manual and documented in dymo.py.
Verified on the bench: revision 1750111r53, status 0x03 Ready, 283 raster lines
at 82 bytes/line accepted.
Also corrects an assumption inherited from daemon.cs: UHF WRITE commits
immediately and does NOT wait for PRINT. Confirmed by writing a chip and reading
it back with no PRINT sent. Two consequences:
- the Urovo can program a chip without printing or consuming a label, which is
what makes the Urovo-encodes/Dymo-prints split work at all;
- an encode can be verified BEFORE printing, so a failed write never costs a
label. /print-encode and /encode both do this now.
New routes: /devices (all three devices at a glance), /encode (chip only),
/print-paper (Dymo), /tag-and-print (Mode A in one call).
label.py is now resolution-aware (203 dpi Urovo / 300 dpi Dymo via profile(dpmm=))
and orientation-aware: the Urovo's 24mm web feeds narrow-edge-first so the design
rotates 90 degrees, while the Dymo's 57mm head is wider than the label so the same
design feeds landscape unrotated.
Also fixes tag read parsing: with dataFormat 'H' the printer replies in ASCII hex
TEXT, not raw bytes -- the old code hex-encoded it a second time. flush_in() now
drains fully, since a late reply to one command was being attributed to the next
and silently corrupting reads.
KNOWN ISSUE: the Node rfid-daemon (Chafon + scale + inventory) also binds :7790.
Both cannot run at once and this service does not implement its routes. Unresolved.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|---|---|---|
| mac | ||
| .gitignore | ||
| ASSESSMENT.md | ||
| build.cmd | ||
| chafcheck.cs | ||
| daemon.cs | ||
| GTSPL_SDK_C.dll | ||
| GTSPL_SDK.dll | ||
| hidapi.dll | ||
| PROGRESS.md | ||
| README.md | ||
| start-daemon.cmd | ||
| UHFPrimeReader.dll | ||
| zlib.net.dll | ||
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.
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.