python使用escpos库进行usb打印机通信(按usb序列号选择打印机)
之前写了一篇“windows下python实现usb收发通信”的文章,是使用底层库来实现python与usb的收发通信;如果你的热敏打印机支持标准的ESC/POS指令的话是可以使用python-escpos这个库(号称python下的打印机神器)进行打印机操作,这个库虽然连接、控制、打印都相对比较简单,但是如果相同型号的打印机连接到同一个电脑设备上,那么它可能只会随机地选择其中一台打印机打印,无法指定打印机!这也是为什么有了之前那边使用python直接与usb进行通信的文章。后来又研究了下escpos这个库的源码,发现其实可以对usb的open方法进行改造就可以实现通过usb设备序列号来区分相同型号的打印机了(有些打印机厂家可能usb序列号没有或者都一样,那么最好建议问厂家能不能给个改写序列号的软件/固件,或者是提供一个版本号查询方法通过版本号来区分打印机设备)
一、准备工作
1、我这里是python3.12(正常python3.x应该都行)
2、安装python-escpos,如果运行时提示缺少包那么就把缺失的安装一遍
pip install python-escpos
3、找到打印机的厂商ID和产品ID的设备(在设备管理器里面可以看到,我上面提到的文章里也有介绍,不会的百度)
4、找到你打印机的设备序列号,可以网上找下怎么查询usb序列号,也可以使用我下面提供的源码来进行查询
二、改造后的源码
注意设备厂商ID和产品ID要选对,否则匹配不上,另外设备序列号如果不知道怎么获取可以随便填写赋值serial_number,程序运行的时候会打印已知的序列号,打印出来后复制并替换serial_number值,然后重新再运行一遍程序即可。
import logging from typing import Optional, Type from escpos.printer.usb import dependency_usb from escpos.printer import Usb import usb.core import usb.util from escpos.exceptions import DeviceNotFoundError, USBNotFoundError # 重写usb连接方式调用 class CustomUSBPrinter(Usb): def __init__(self, vendor_id, product_id, serial_number=None, *args, **kwargs): self.serial_number = serial_number self.idVendor= vendor_id self.idProduct = product_id try: super().__init__(idVendor=vendor_id, idProduct=product_id, *args, **kwargs) except (USBNotFoundError, usb.core.USBError): # 静默捕获异常,不退出程序 print("USB device not found or error") pass @dependency_usb def open(self, raise_not_found: bool = True) -> None: """重写 open 方法,支持根据序列号筛选设备""" # 查找所有匹配厂商ID和产品ID的设备 #print('重写的方法usb') if self._device: self.close() # Open device try: if self.serial_number: #需要按序列号来查找设备 devs = usb.core.find(find_all=True, idVendor=self.idVendor, idProduct=self.idProduct) for dev in devs: try: current_serial = usb.util.get_string(dev, dev.iSerialNumber) print(f'已发现usb设备序列号:{current_serial}') # 如果列出发现的设备对应的序列号,可以复制后续使用 if current_serial == self.serial_number: self.device = dev break # 找第一个匹配的 except (usb.USBError, UnicodeDecodeError): print('发生了某些usb设备错误') continue else: # 原逻辑 self.device: Optional[Type[usb.core.Device]] = usb.core.find( **self.usb_args ) assert self.device, USBNotFoundError( f"Device {tuple(self.usb_args.values())} not found" + " or cable not plugged in." ) # 配置USB连接 self._check_driver() self._configure_usb() except (AssertionError, usb.core.USBError) as e: # Raise exception or log error and cancel self.device = None if raise_not_found: raise DeviceNotFoundError( f"Unable to open USB printer on {tuple(self.usb_args.values())}:" + f"n{e}" ) else: logging.error("USB device %s not found", tuple(self.usb_args.values())) return logging.info("USB printer enabled") # 下面是正式使用………… # 示例:连接指定厂商ID、产品ID和序列号的设备 idVendor = 0x5a5a idProduct = 0x8009 serial_number= '206035763031' # 序列号,如果已知idVendor、idProduct 序列号可以随便填,程序会打印出来,然后复制过来替换本序列号 in_ep= 0x81 # python库默认的是0x82 根据实际的来 out_ep= 0x01 # 有的是0x02 try: # 尝试连接打印机 printer = CustomUSBPrinter(vendor_id=idVendor,product_id=idProduct,serial_number=serial_number,in_ep=in_ep,out_ep=out_ep) #printer = CustomUSBPrinter(vendor_id=idVendor, product_id=idProduct, in_ep=in_ep, out_ep=out_ep) connected = printer.device is not None # 确认设备存在 except (DeviceNotFoundError, usb.core.USBError): printer = None connected = False # 检查连接状态 if connected: # 正常连接成功,还应该检测打印机状态; 部分打印机状态异常时也能接收到并缓存打印指令,打印机不断电情况下修复错误后会打印缓存中的指令! print("USB 打印机已连接") printer.text("--测试打印n") printer.qr(content='https://www.baidu.com',size=6) # 二维码 printer.barcode('6935103100088', 'EAN13', 64, 2, '', '') # 条码 img_src = "ticket_at.png" printer.image(img_src, impl="bitImageRaster") printer.close() else: print("USB 打印机未连接")
三、提示
充分利用好AI,问问文心一言、DeepSeek,他们也能解决很多代码片段问题!
基于互联网精神,在注明出处的前提下本站文章可自由转载!
本文链接:https://ranjuan.cn/python-escpos-usb-serialnum-printer/
赞赏
微信赞赏
支付宝赞赏
发表评论