#!/usr/bin/env python3 """ ZPL label generator and TCP send for Zebra label printer (標簽機). - Rotated 90° clockwise for ~53 mm media width - UTF-8 (^CI28) for Chinese - Large fonts, QR code mag 6 Standalone: python label_zpl.py Or import generate_zpl() / send_zpl() and call from Bag1. """ import socket # Default printer (override via args or Bag1 settings) DEFAULT_PRINTER_IP = "192.168.17.27" DEFAULT_PRINTER_PORT = 3008 SOCKET_TIMEOUT = 10 def generate_zpl( batch_no: str, item_code: str = "PP2238-02", chinese_desc: str = "(餐廳用)凍咖啡底P+10(0.91L包)", ) -> str: """ Generates ZPL label: - Rotated 90° clockwise to fit ~53 mm media width - UTF-8 mode (^CI28) for correct Chinese display - Larger fonts - Bigger QR code (mag 6) """ return f"""^XA ^PW420 ^# Fits ~53 mm width (~420 dots @ 203 dpi) ^LL780 ^# Taller label after rotation + bigger elements ^PO N ^# Normal — change to ^POI if upside-down ^CI28 ^# Enable UTF-8 / Unicode for Chinese (critical fix for boxes) ^FO70,70 ^A@R,60,60,E:SIMSUN.FNT^FD{chinese_desc}^FS ^# Very large Chinese text, rotated ^FO220,70 ^A0R,50,50^FD{item_code}^FS ^# Larger item code ^FO310,70 ^A0R,45,45^FDBatch: {batch_no}^FS ^# Larger batch text ^FO150,420 ^BQN,2,6^FDQA,{batch_no}^FS ^# Bigger QR code (magnification 6), lower position for space ^XZ""" def send_zpl( zpl: str, host: str = DEFAULT_PRINTER_IP, port: int = DEFAULT_PRINTER_PORT, timeout: float = SOCKET_TIMEOUT, ) -> None: """Send ZPL to printer over TCP. Raises on connection/send error.""" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout) sock.connect((host, port)) sock.sendall(zpl.encode("utf-8")) sock.close() # ──────────────────────────────────────────────── # Example usage — prints one label # ──────────────────────────────────────────────── if __name__ == "__main__": test_batch = "2025121209" zpl = generate_zpl(test_batch) print("Sending ZPL (90° rotated, UTF-8 Chinese, bigger QR):") print("-" * 90) print(zpl) print("-" * 90) try: send_zpl(zpl) print("Label sent successfully!") print("→ Check Chinese — should show real characters (not 口口 or symbols)") print("→ QR is now bigger (mag 6) — test scan with phone") print("→ If upside-down: edit ^PO N → ^POI") print("→ If still boxes: SimSun font may be missing — reinstall via Zebra Setup Utilities") except ConnectionRefusedError: print(f"Cannot connect to {DEFAULT_PRINTER_IP}:{DEFAULT_PRINTER_PORT} — printer off or wrong IP?") except socket.timeout: print("Connection timeout — check printer/network/port") except Exception as e: print(f"Error: {e}")