From f87804de0af329777a74386c1a32e8a8bb714042 Mon Sep 17 00:00:00 2001 From: type-two Date: Fri, 4 Sep 2026 16:29:42 +1000 Subject: [PATCH] =?UTF-8?q?fix(urovo):=20encode=20before=20geometry=20?= =?UTF-8?q?=E2=80=94=20the=20print-setup=20burst=20silences=20the=20UHF=20?= =?UTF-8?q?module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every print-encode today failed its read-back with 'before: null' while a standalone /read-tag a second earlier read the chip every time, at the same media position. Bisected to the pre-read sequence itself: after the SIZE/GAP/TEAR/DIRECTION/CLS burst, UHF READ and QUERY return no bytes at all until a power-cycle. SET RIBBON OFF + FORMFEED provably do not do this. UHF WRITE commits immediately and needs no geometry, and printing works after geometry (print-test proved it), so read/write/verify now happen first on the untouched module and the print setup follows. Nothing feeds between, so the label at the antenna is the one printed. Co-Authored-By: Claude Opus 5 --- mac/daemon.py | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/mac/daemon.py b/mac/daemon.py index f1ddf6c..91f2084 100644 --- a/mac/daemon.py +++ b/mac/daemon.py @@ -67,20 +67,17 @@ def do_print(body, encode): return {'ok': False, 'error': str(e)} with LOCK, Urovo() as p: - # 1) direct thermal. Wait out transient busy states before feeding to clear, - # so we don't waste a label on a momentary post-print code. - p.ribbon_off() - time.sleep(0.4) - if p.wait_ready(3.0) != 0x00: - st = p.recover() - if st != 0x00: - return {'ok': False, 'error': 'printer not ready', - 'status': st, 'statusText': status_text(st)} - - # 2) geometry, then the artwork - geometry(p, prof) - p.cls() - + # ENCODE BEFORE GEOMETRY. Order matters on this firmware, and it cost most of a day: + # the SIZE/GAP/TEAR/DIRECTION/CLS burst that sets up a print silences the UHF module + # -- every UHF READ/QUERY afterwards returns no bytes at all until a power-cycle -- + # so an encode placed after it always failed its own read-back with "before: null", + # which looks exactly like a chip that never reached the antenna. It had. The module + # was fine right up until the geometry went out (a standalone /read-tag a second + # earlier read the chip every time; SET RIBBON OFF + FORMFEED provably do not kill + # it). UHF WRITE commits immediately and needs no geometry, and printing works fine + # AFTER geometry, so: read, write, verify on the untouched module first; only then + # set up the print. Nothing feeds in between, so the label at the antenna is the one + # that prints. before = verified = None if encode: # Deliberately NO `SET RFID` here. It was tried as an "arm the radio first" step and @@ -100,6 +97,18 @@ def do_print(body, encode): return {'ok': False, 'error': 'RFID encode failed verification', 'epc': epc, 'epcBefore': before, 'readBack': p.read_uhf(), 'note': 'nothing printed -- no label wasted'} + # 1) direct thermal. Wait out transient busy states before feeding to clear, + # so we don't waste a label on a momentary post-print code. + p.ribbon_off() + time.sleep(0.4) + if p.wait_ready(3.0) != 0x00: + st = p.recover() + if st != 0x00: + return {'ok': False, 'error': 'printer not ready', + 'status': st, 'statusText': status_text(st)} + # 2) geometry, then the artwork -- AFTER the encode, see above + geometry(p, prof) + p.cls() p.write(label.to_tspl(label.render(body, prof))) # 4) re-assert ribbon-off immediately before firing