From b412900b4b293c6a70a6e4e70a2996e27e6b70dc Mon Sep 17 00:00:00 2001 From: James Pattinson Date: Fri, 6 Feb 2026 17:35:31 +0000 Subject: [PATCH] Robustness fixes --- Dockerfile | 6 +----- client.py | 34 ++++++++++++++++++++++++++++++++-- docker-compose.yml | 6 ++++-- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8de057d..b17f825 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,6 @@ ENV PYTHONUNBUFFERED=1 # Install system dependencies RUN apt-get update && apt-get install -y \ fonts-dejavu \ - usbutils \ && rm -rf /var/lib/apt/lists/* # Set working directory @@ -16,9 +15,6 @@ WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -# Copy the application -COPY client.py . -COPY templates.py . - +# Application files will be mounted via volume # Run the application CMD ["python", "client.py"] \ No newline at end of file diff --git a/client.py b/client.py index 89b8f3b..3bfe8ad 100644 --- a/client.py +++ b/client.py @@ -22,15 +22,22 @@ LABEL_SIZE_DEFAULT = os.getenv('LABEL_SIZE_DEFAULT', '29x90') def print_label(image, printer=PRINTER_DEVICE, model=PRINTER_MODEL, label=LABEL_SIZE_DEFAULT): """Print the label directly using brother_ql module""" + import os + try: + # Check if printer device exists + if not os.path.exists(printer): + raise Exception(f"Printer device {printer} not found. Make sure the printer is powered on and connected via USB.") + qlr = BrotherQLRaster(model) qlr.exception_on_warning = True # Convert the PIL image to instructions instructions = convert(qlr=qlr, images=[image], label=label, cut=True) - # Send to printer - status = send(instructions=instructions, printer_identifier=printer, backend_identifier='linux_kernel', blocking=True) + # Send to printer using linux_kernel backend + print(f"Sending to printer: {printer}") + status = send(instructions=instructions, printer_identifier=f"file://{printer}", backend_identifier='linux_kernel', blocking=True) return status except Exception as e: @@ -82,6 +89,29 @@ def on_message(client, userdata, msg): print("Printing label...") status = print_label(image, label=label_size) print(f"Print status: {status}") + + # Check for print errors + if not status.get('did_print', False): + printer_state = status.get('printer_state', {}) + status_type = printer_state.get('status_type', 'Unknown') + media_type = printer_state.get('media_type', 'Unknown') + media_width = printer_state.get('media_width', 'Unknown') + errors = printer_state.get('errors', []) + + error_details = { + "error": f"Print failed: {status_type}", + "status_type": status_type, + "media_type": media_type, + "media_width": media_width, + "errors": errors, + "outcome": status.get('outcome', 'unknown'), + "original_payload": raw_payload + } + + error_msg = f"Print failed: {status_type}. Media: {media_type} ({media_width}mm)" + print(error_msg) + client.publish(MQTT_TOPIC_PUB_ERRORS, json.dumps(error_details)) + raise Exception(error_msg) except json.JSONDecodeError as e: error_msg = f"Invalid JSON in message: {e}. Raw payload: {raw_payload}" diff --git a/docker-compose.yml b/docker-compose.yml index fdb2210..ec856a0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,8 +5,10 @@ services: build: . env_file: - .env - devices: - - /dev/usb/lp0:/dev/usb/lp0 + privileged: true # Required for /dev access when printer powers on/off volumes: - ./output:/app/output # For test PNGs + - ./client.py:/app/client.py # Mount source for live updates + - ./templates.py:/app/templates.py # Mount templates for live updates + - /dev:/dev # Mount /dev for dynamic device access restart: unless-stopped \ No newline at end of file