From 3a741079d6491636a033dc3b2f0f03b9c68c76d1 Mon Sep 17 00:00:00 2001 From: type-two Date: Fri, 4 Sep 2026 10:32:42 +1000 Subject: [PATCH] fix(daemon): move to 7791 so the label service and the gun daemon coexist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four devices, two daemons, one front door. This service drives the Urovo D812R+ and the Dymo LabelWriter over raw USB; the Node rfid-daemon on 7790 drives the Chafon H102 gun and the Dymo M25 scale, and is what the PriceGod extension is pointed at. Both were binding 7790. The port was not the whole problem. /status, /read-tag, /write-tag and /recover exist on BOTH services and mean different things — the gun in your hand versus the antenna inside the printer. Merging them into one flat namespace would let a "read-tag" land on whichever daemon answered, which is how you get a tag written by the wrong device. So this keeps its own names and the Node side proxies /printer/* here, leaving the extension with a single endpoint on 7790. They stay separate processes on purpose: this side needs libusb for a real bidirectional pipe (UHF READ replies as raw bytes on the bulk-IN endpoint, which is why CUPS 'lp -o raw' cannot drive it) and the other needs node-serialport and node-hid. Merging would mean porting one language's device stack to the other for no gain. --port still wins, UROVO_PORT overrides the default, and neither the launchd plist nor start-daemon.command pins a port, so install.sh needed no change. Co-Authored-By: Claude Opus 5 --- mac/README.md | 15 ++++++++++++++- mac/daemon.py | 11 ++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/mac/README.md b/mac/README.md index 8fd54a3..e7733e3 100644 --- a/mac/README.md +++ b/mac/README.md @@ -1,6 +1,19 @@ # pricegod label daemon (macOS) -One service on `localhost:7790` that drives **both** printers over raw USB: +One service on `localhost:7791` that drives **both** printers over raw USB: + +> **Port 7791, and you normally talk to 7790.** The Node `rfid-daemon` owns 7790 — it drives the +> Chafon gun and the Dymo scale, and it is what the PriceGod extension is configured against. It +> proxies `/printer/*` to this service, so the extension keeps ONE front door: `/printer/status`, +> `/printer/print-encode`, `/printer/recover` and so on land here. `GET /devices` on 7790 reports +> all four devices at once. +> +> They stay separate processes deliberately. This side needs libusb (UHF READ answers with raw +> bytes on the bulk-IN endpoint, so `lp -o raw` cannot drive it); the other needs node-serialport +> and node-hid. And they cannot share a flat namespace — `/status`, `/read-tag`, `/write-tag` and +> `/recover` exist on both and mean different things: the gun in your hand versus the antenna in +> the printer. The prefix is what keeps that unambiguous. + | device | role | how | |---|---|---| diff --git a/mac/daemon.py b/mac/daemon.py index 639befd..364258e 100644 --- a/mac/daemon.py +++ b/mac/daemon.py @@ -28,6 +28,7 @@ import json import sys import threading import time +import os from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from urllib.parse import urlparse, parse_qs @@ -356,7 +357,15 @@ class Handler(BaseHTTPRequestHandler): def main(): - port = 7790 + # 7791, not 7790. The Node rfid-daemon owns 7790: it is what the PriceGod extension talks to, + # it drives the Chafon gun and the Dymo scale, and it has the larger route surface. Both + # services binding one port is not the only clash either — /status, /read-tag, /write-tag and + # /recover exist on BOTH and mean different things (the gun versus this printer), so they can + # never be merged into one flat namespace safely. + # + # The Node daemon proxies /printer/* here instead, which keeps one front door on 7790 for the + # extension and leaves these route names unambiguous. Override with --port or UROVO_PORT. + port = int(os.environ.get('UROVO_PORT', 7791)) if '--port' in sys.argv: port = int(sys.argv[sys.argv.index('--port') + 1]) srv = ThreadingHTTPServer(('127.0.0.1', port), Handler)