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/
赞赏
微信赞赏
支付宝赞赏
发表评论