| @@ -213,15 +213,12 @@ def generate_zpl_dataflex( | |||
| lot_no: Optional[str] = None, | |||
| font_regular: str = "E:STXihei.ttf", | |||
| font_bold: str = "E:STXihei.ttf", | |||
| reset_counter_first: bool = False, | |||
| ) -> str: | |||
| """ | |||
| Row 1 (from zero): QR code, then item name (rotated 90°). | |||
| Row 2: Batch/lot (left), item code (right). | |||
| Label and QR use lotNo from API when present, else batch_no (Bxxxxx). | |||
| When reset_counter_first is True, Zebra counter reset commands (~RO1, ~RO2) are inserted after ^XA | |||
| in the *same* label job. Many printers ignore a separate reset-only TCP job. | |||
| Job counter reset (~RO) is sent separately via [send_dataflex_job_counter_reset] before labels. | |||
| """ | |||
| desc = _zpl_escape((item_name or "—").strip()) | |||
| code = _zpl_escape((item_code or "—").strip()) | |||
| @@ -233,9 +230,8 @@ def generate_zpl_dataflex( | |||
| else: | |||
| qr_payload = label_line if label_line else batch_no.strip() | |||
| qr_value = _zpl_escape(qr_payload) | |||
| counter_lines = _zpl_dataflex_counter_reset_lines() if reset_counter_first else "" | |||
| return f"""^XA | |||
| {counter_lines}^CI28 | |||
| ^CI28 | |||
| ^PW700 | |||
| ^LL500 | |||
| ^PO N | |||
| @@ -250,13 +246,23 @@ def generate_zpl_dataflex( | |||
| ^XZ""" | |||
| def _zpl_dataflex_counter_reset_lines() -> str: | |||
| def send_dataflex_job_counter_reset(ip: str, port: int) -> None: | |||
| """ | |||
| Zebra ZPL counter reset (tilde commands), embedded after ^XA on the first label of each job: | |||
| ~RO1 = reset counter 1, ~RO2 = reset counter 2. | |||
| See Zebra ZPL / printer manual; add ~RO3 etc. if your model exposes more counters. | |||
| Reset printer job / label counters when switching to a new job (new row). | |||
| Zebra: ~RO1 / ~RO2 reset counters 1 and 2. Sent as a *standalone* TCP write *before* any ^XA…^XZ | |||
| label, because many firmwares ignore ~ commands inside a format block. | |||
| Uses CRLF line endings (common Zebra expectation). Raises on TCP error like [send_zpl_to_dataflex]. | |||
| """ | |||
| return "~RO1\n~RO2\n" | |||
| raw = "~RO1\r\n~RO2\r\n".encode("ascii") | |||
| sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |||
| sock.settimeout(DATAFLEX_SEND_TIMEOUT) | |||
| try: | |||
| sock.connect((ip, port)) | |||
| sock.sendall(raw) | |||
| finally: | |||
| sock.close() | |||
| def generate_zpl_label_small( | |||
| @@ -563,7 +569,7 @@ def send_image_to_label_printer(printer_name: str, pil_image: "Image.Image") -> | |||
| def send_zpl_to_dataflex(ip: str, port: int, zpl: str) -> None: | |||
| """Send ZPL to DataFlex printer via TCP. Raises on connection/send error.""" | |||
| """Send ZPL label (^XA…^XZ) to DataFlex printer via TCP. Raises on connection/send error.""" | |||
| sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |||
| sock.settimeout(DATAFLEX_SEND_TIMEOUT) | |||
| try: | |||
| @@ -1628,16 +1634,6 @@ def main() -> None: | |||
| item_id=item_id, | |||
| stock_in_line_id=stock_in_line_id, | |||
| lot_no=lot_no, | |||
| reset_counter_first=False, | |||
| ) | |||
| zpl_first_job = generate_zpl_dataflex( | |||
| b, | |||
| item_code, | |||
| item_name, | |||
| item_id=item_id, | |||
| stock_in_line_id=stock_in_line_id, | |||
| lot_no=lot_no, | |||
| reset_counter_first=True, | |||
| ) | |||
| label_text = (lot_no or b).strip() | |||
| if continuous: | |||
| @@ -1648,9 +1644,9 @@ def main() -> None: | |||
| printed = 0 | |||
| error_shown = False | |||
| try: | |||
| send_dataflex_job_counter_reset(ip, port) | |||
| while not stop_ev.is_set(): | |||
| payload = zpl_first_job if printed == 0 else zpl | |||
| send_zpl_to_dataflex(ip, port, payload) | |||
| send_zpl_to_dataflex(ip, port, zpl) | |||
| printed += 1 | |||
| _sleep_interruptible(stop_ev, 2.0) | |||
| except ConnectionRefusedError: | |||
| @@ -1718,12 +1714,9 @@ def main() -> None: | |||
| threading.Thread(target=dflex_worker, daemon=True).start() | |||
| else: | |||
| try: | |||
| send_dataflex_job_counter_reset(ip, port) | |||
| for i in range(n): | |||
| send_zpl_to_dataflex( | |||
| ip, | |||
| port, | |||
| zpl_first_job if i == 0 else zpl, | |||
| ) | |||
| send_zpl_to_dataflex(ip, port, zpl) | |||
| if i < n - 1: | |||
| time.sleep(2) | |||
| set_status_message(f"已送出列印:批次 {label_text} x {n} 張", is_error=False) | |||