Add more configuration options to the printers

This commit is contained in:
n07070
2026-11-13 19:16:13 +01:00
parent d0f4ba8f01
commit b50b9abc22
2 changed files with 125 additions and 53 deletions

View File

@@ -107,7 +107,7 @@ class EscPosPrinter(Printer):
Create a new ESC/POS based printer. Create a new ESC/POS based printer.
""" """
def __init__(self, app, vendor_id, device_id): def __init__(self, app, vendor_id, device_id, configuration_file):
""" """
Create a connexion to a ESC/POS Printer via USB, Create a connexion to a ESC/POS Printer via USB,
Making sure the printer is alive, Making sure the printer is alive,
@@ -123,7 +123,7 @@ class EscPosPrinter(Printer):
try: try:
# This also calls open(), which we need to close() # This also calls open(), which we need to close()
# or else the device will appear as busy. # or else the device will appear as busy.
p = escpos.printer.Usb(self.vendor_id, self.device_id, 0, profile="TM-P80") p = escpos.printer.Usb(self.vendor_id, self.device_id, 0, profile=configuration_file["profile"])
except escpos.exceptions.DeviceNotFoundError as e: except escpos.exceptions.DeviceNotFoundError as e:
self.app.logger.error( self.app.logger.error(
"The USB device is not plugged in : %s", "The USB device is not plugged in : %s",
@@ -140,9 +140,21 @@ class EscPosPrinter(Printer):
except Exception as e: except Exception as e:
raise e raise e
self.printer_info = PrinterInfo(
identifier=configuration_file["profile"],
backend="pyusb",
model=configuration_file["profile"],
protocol="ESC/POS",
vendor_id=self.vendor_id,
product_id=self.device_id,
serial_number="",
label_type=configuration_file["label_type"],
)
# Setting up the printing options. # Setting up the printing options.
# TODO : Expose this to the web interface
p.set( p.set(
align="center", align=configuration_file["align_text"],
font="a", font="a",
bold=False, bold=False,
underline=0, underline=0,
@@ -287,22 +299,22 @@ class EscPosPrinter(Printer):
except Exception as e: except Exception as e:
self.app.logger.error(str(e)) self.app.logger.error(str(e))
raise RuntimeError("Could not print the picture") from e raise RuntimeError("Could not print the picture") from e
finally: # finally:
try: # try:
os.remove(path) # os.remove(path)
os.remove(processed_path) # os.remove(processed_path)
self.app.logger.debug("Removed image : " + str(processed_path)) # self.app.logger.debug("Removed image : " + str(processed_path))
self.app.logger.debug("Removed image : " + str(path)) # self.app.logger.debug("Removed image : " + str(path))
except OSError as e: # except OSError as e:
raise e # raise e
try: try:
self.printer.close() self.printer.close()
except Exception as e: except Exception as e:
self.app.logger.error( self.app.logger.error(
"Could not close the printer connexion %s", str(e) "Could not close the printer connexion %s", str(e)
) )
raise RuntimeError("Could not close the printer connexion. ") from e raise RuntimeError("Could not close the printer connexion. ") from e
self.app.logger.info("Printed a picture") self.app.logger.info("Printed a picture")
self.ready = True self.ready = True
@@ -391,7 +403,7 @@ class BrotherPrinter(Printer):
Manages connexion and capabilities of a BrotherQL Printer Manages connexion and capabilities of a BrotherQL Printer
""" """
def __init__(self, app, vendor_id, device_id): def __init__(self, app, vendor_id, device_id, configuration_file):
super().__init__(app, vendor_id, device_id, printer_type=PrinterType.BROTHER) super().__init__(app, vendor_id, device_id, printer_type=PrinterType.BROTHER)
self.printer = None self.printer = None
@@ -445,7 +457,7 @@ class BrotherPrinter(Printer):
vendor_id=vendor_id, vendor_id=vendor_id,
product_id=self.device_id, product_id=self.device_id,
serial_number=serial_number, serial_number=serial_number,
label_type="62", label_type=configuration_file["label_type"], # TODO: Implement automatic label type detection : https://framagit.org/stickoeur/diagnostickoeur/-/blob/no-masters/printit.py?ref_type=heads#L239
) )
self.app.logger.debug("Created a Brother printer !") self.app.logger.debug("Created a Brother printer !")
self.ready = True self.ready = True
@@ -461,10 +473,11 @@ class BrotherPrinter(Printer):
self._print_img(text_to_image(msg)) self._print_img(text_to_image(msg))
self._print_img(text_to_image(signature)) self._print_img(text_to_image(signature))
def _print_img(self, data, signature="", process=False): def _print_img(self, data, signature="", process=False,):
""" """
Print a raster image via a Brother QL printer Print a raster image via a Brother QL printer
""" """
self.app.logger.debug("Printing an image %s via Brother printer", data)
if process: if process:
try: try:
self.app.logger.debug("Proccessing the image") self.app.logger.debug("Proccessing the image")
@@ -477,6 +490,7 @@ class BrotherPrinter(Printer):
else: else:
processed_path = data processed_path = data
self.app.logger.warning("Not proccessing the image") self.app.logger.warning("Not proccessing the image")
try: try:
selected_backend = guess_backend(self.printer_info.identifier) selected_backend = guess_backend(self.printer_info.identifier)
BACKEND_CLASS = backend_factory(selected_backend)["backend_class"] BACKEND_CLASS = backend_factory(selected_backend)["backend_class"]
@@ -490,39 +504,95 @@ class BrotherPrinter(Printer):
try: try:
im = Image.open(processed_path) im = Image.open(processed_path)
qlr = BrotherQLRaster(self.printer_info.model) qlr = BrotherQLRaster(self.printer_info.model)
create_label(qlr, im, self.printer_info.label_type, cut=False, dither=True) # create_label(qlr, im, self.printer_info.label_type, cut=False, dither=True)
# noinspection PyCallingNonCallable # noinspection PyCallingNonCallable
be = BACKEND_CLASS(BACKEND_STRING_DESCR) # be = BACKEND_CLASS(BACKEND_STRING_DESCR)
be.write(qlr.data) # be.write(qlr.data)
be.dispose() # be.dispose()
del be # del be
instructions = convert(
qlr=qlr,
images=[im],
label=self.printer_info.label_type,
dither=True,
compress=False,
dpi_600=False,
cut=False,
)
success = send(
instructions=instructions,
printer_identifier=BACKEND_STRING_DESCR,
backend_identifier="pyusb",
blocking=False
)
self.app.logger.debug(str(success))
self.app.logger.debug("Printed image")
time.sleep(2)
except usb.core.USBError as e:
if "timeout error" in str(e):
self.app.logger.error("USB Timeout Error %s", str(e) )
except Exception as e: except Exception as e:
raise e raise e
finally: # finally:
try: # try:
os.remove(processed_path) # os.remove(processed_path)
self.app.logger.debug("Removed image : " + str(processed_path)) # self.app.logger.debug("Removed image : " + str(processed_path))
except OSError as e: # except OSError as e:
raise e # raise e
if signature != "": if signature != "":
self.app.logger.debug("Printing signature for the image %s", data)
try: try:
im = Image.open(text_to_image(signature)) signature_file = text_to_image(signature)
im = Image.open(signature_file)
qlr = BrotherQLRaster(self.printer_info.model) qlr = BrotherQLRaster(self.printer_info.model)
create_label( # create_label(
qlr, im, self.printer_info.label_type, cut=False, dither=True # qlr, im, self.printer_info.label_type, cut=False, dither=True
) # )
# noinspection PyCallingNonCallable # noinspection PyCallingNonCallable
be = BACKEND_CLASS(BACKEND_STRING_DESCR) # be = BACKEND_CLASS(BACKEND_STRING_DESCR)
be.write(qlr.data) # be.write(qlr.data)
be.dispose() # be.dispose()
del be # del be
instructions = convert(
qlr=qlr,
images=[signature_file],
label=self.printer_info.label_type,
dither=True,
compress=False,
dpi_600=False,
cut=False,
)
success = send(
instructions=instructions,
printer_identifier=BACKEND_STRING_DESCR,
backend_identifier="pyusb",
blocking=False
)
self.app.logger.debug(str(success))
self.app.logger.debug("Printed signature")
time.sleep(2)
except Exception as e: except Exception as e:
raise e raise e
finally:
try:
# os.remove(signature_file)
self.app.logger.debug("Removed image : " + str(signature_file))
except OSError as e:
raise e
def _cut(self): def _cut(self):
self.app.logger.debug("Cutting via Brother Printer")
try: try:
selected_backend = guess_backend(self.printer_info.identifier) selected_backend = guess_backend(self.printer_info.identifier)
BACKEND_CLASS = backend_factory(selected_backend)["backend_class"] BACKEND_CLASS = backend_factory(selected_backend)["backend_class"]
@@ -546,12 +616,14 @@ class BrotherPrinter(Printer):
be.write(qlr.data) be.write(qlr.data)
be.dispose() be.dispose()
del be del be
self.app.logger.debug("Finished cutting via Brother Printer")
except Exception as e: except Exception as e:
raise e raise e
def _qr(self): def _qr(self):
# This should not be reached by a print on a BrotherQL # This should not be reached by a print on a BrotherQL
raise NotImplementedError raise NotImplementedError()
def print_task(self, task_type, data): def print_task(self, task_type, data):
"""Execute actual print based on task type""" """Execute actual print based on task type"""

View File

@@ -18,11 +18,12 @@ class Printers:
Finds and creates a set of Printer that can be used by the Workers to print. Finds and creates a set of Printer that can be used by the Workers to print.
""" """
def __init__(self, app): def __init__(self, app, configuration_file):
""" """
Discovers printers connected to the computer Discovers printers connected to the computer
""" """
self.app = app self.app = app
self.configuration_file = configuration_file
self.printers = list(self._discover_printers()) self.printers = list(self._discover_printers())
self._lock = threading.Lock() self._lock = threading.Lock()
@@ -42,8 +43,7 @@ class Printers:
printers = set() printers = set()
# TODO : this could go in the config ? waiting_time_for_printer = self.configuration_file["printer"]["waiting_time"]
waiting_time_for_printer = 5
while True: while True:
# Find all connected USB devices # Find all connected USB devices
@@ -97,9 +97,7 @@ class Printers:
self.app.logger.debug("Trying to create a new EPSON printer") self.app.logger.debug("Trying to create a new EPSON printer")
prid = dev.idProduct prid = dev.idProduct
vendir = dev.idVendor vendir = dev.idVendor
escpos_printer = EscPosPrinter( escpos_printer = EscPosPrinter(self.app, vendir, prid, self.configuration_file["printer"]["epson"] )
self.app, vendor_id=vendir, device_id=prid
)
except Exception as e: except Exception as e:
raise e raise e
@@ -111,9 +109,7 @@ class Printers:
# We create a new BrotherPrinter() # We create a new BrotherPrinter()
self.app.logger.debug("Trying to create a new BROTHER printer") self.app.logger.debug("Trying to create a new BROTHER printer")
brother_printer = BrotherPrinter( brother_printer = BrotherPrinter(self.app, dev.idVendor, dev.idProduct, self.configuration_file["printer"]["brother"] )
self.app, vendor_id=dev.idVendor, device_id=dev.idProduct
)
except Exception as e: except Exception as e:
self.app.logger.error( self.app.logger.error(
"Could not create a %s printer class with %s:%s", "Could not create a %s printer class with %s:%s",
@@ -148,6 +144,8 @@ class Printers:
return None return None
with self._lock: with self._lock:
# So don't always look at the first printer available if need be
# this allows for a round-robin lookup
for offset in range(len(printers)): for offset in range(len(printers)):
index = (start_index + offset) % len(printers) index = (start_index + offset) % len(printers)
printer = printers[index] printer = printers[index]
@@ -158,9 +156,11 @@ class Printers:
return None return None
def printers_info(self): # def printers_info(self):
"""Return the current list of printers""" # """Return the current list of printers"""
return self.printers # printers_info_list = {}
# for i in self.printers
# return self.printers
class _FindClass: class _FindClass: