node-escpos / driver

🖨️ ESC/POS Printer driver for Node.js.
Other
280 stars 26 forks source link

Use without WinUsb driver #32

Open gauravbordoloi opened 1 year ago

gauravbordoloi commented 1 year ago

Can we use this package without installing the WinUSB driver or there is a way to silently install the WinUSB driver through code?

I tried using usb.useUsbDkBackend() from the node-usb package but no luck as mentioned in the readme.md section of https://github.com/node-usb/node-usb

Primarily, I don't want the client to do an extra WinUSB installation.

danjohnson95 commented 1 month ago

If it helps, I'm currently working around this by instructing to assign a "Virtual port" on the printer - the manufacturer driver of most printers includes this functionality.

Then you can use the @node-escpos/serialport-adapter adapter to connect.

tobiasbenkner commented 2 weeks ago

@danjohnson95 I am also interested in making it work with windows and not installed WinUSB directly. How did you do this? Do I need to install the driver for printer? Can you share more information about it?

In Python I was able to ship the driver within the application. I used following code. It would be nice if it also works with Node.

import usb.core
import usb.util
import libusb_package
import usb.backend.libusb1

def list_usb_devices():
    libusb1_backend = usb.backend.libusb1.get_backend(find_library=libusb_package.find_library)
    devices = usb.core.find(find_all=True,backend=libusb1_backend)    
    device_list = []    
    for device in devices:
        device_info = {
            "vendor_id": hex(device.idVendor),
            "product_id": hex(device.idProduct),
            "manufacturer": usb.util.get_string(device, device.iManufacturer),
            "product": usb.util.get_string(device, device.iProduct)
        }
        device_list.append(device_info)

    return device_list

def find_device(vendor_id, product_id):
    libusb1_backend = usb.backend.libusb1.get_backend(find_library=libusb_package.find_library)
    device = usb.core.find(idVendor=vendor_id, idProduct=product_id, backend=libusb1_backend)
    if device is None:
        raise ValueError('Printer not found.')
    return device

def open_cash_drawer(device):

    # Detach kernel driver if necessary
    if device.is_kernel_driver_active(0):
        device.detach_kernel_driver(0)

    # Set the active configuration
    device.set_configuration()

    # Get the endpoint instance
    cfg = device.get_active_configuration()
    intf = cfg[(0, 0)]

    ep = usb.util.find_descriptor(
        intf,
        # Match the first OUT endpoint
        custom_match = lambda e: 
            usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT
    )

    assert ep is not None

    open_drawer_command = b'\x1B\x70\x00\x19\xFA'
    ep.write(open_drawer_command)

def openCashDrawer():
    VENDOR_ID = int("0x1fc9", 16)
    PRODUCT_ID = int("0x2016", 16)

    printer = find_device(VENDOR_ID, PRODUCT_ID)
    open_cash_drawer(printer)

# devices = list_usb_devices()
# print(json.dumps(devices, indent=4))
# openCashDrawer()

usb.backend.libusb1.get_backend(find_library=libusb_package.find_library)

from escpos.printer import Usb

p = Usb(0x1fc9, 0x2016)
# p.text("Hello World\n")

# p.barcode('4006381333931', 'EAN13', 64, 2, '', '')
# p.text("\n")
# p.set("left", None, None, 0, 10, 10)
# p.text("hello world\n")
# p.set("right", None, None, 1, 2, 2, 2)
# p.text("hello world\n")
# p.cut()
# p.cashdraw(2)

p.set(double_height=False, double_width=False)
p.textln("Bla")

p.set(font="b")
p.textln("Bla")

# p.qr("was up?", size=6, center=True)
p.set(align="center", double_height=True, double_width=True)
p.cut()
danjohnson95 commented 1 week ago

@tobiasbenkner I did this with an Epson TM-T88V printer. I installed the standard manufacturer driver, which also comes with the "Epson TM Virtual Port Driver Assignment Tool". I then configured the printer to be available on COM1.

Here's some instructions that roughly explain the process: https://support.fidelitysystems.co.uk/portal/en/kb/articles/epson-printers-virtual-port-setup

Then, using the @node-escpos/serialport-adapter, I connected to COM1.

import { Printer, Image } from "@node-escpos/core";
import Serial from "@node-escpos/serialport-adapter";

const device = new Serial('COM1');

device.open(async function(err){
  let printer = new Printer(device);

  // ...
tobiasbenkner commented 1 week ago

Thank you @danjohnson95!! Now I understood. It's a great workaround. Maybe it's also possible without installing the printer driver. I will keep digging.

I will have a look to another virtual port mapping tool. The download from the epson site is not available anymore :/ There should also be a general application for it.

Thank-you for visiting epson-biz.com. This site has been closed since June 16, 2024.

danjohnson95 commented 1 week ago

You should be able to download it from here under Drivers: https://epson.com/Support/Point-of-Sale/Thermal-Printers/Epson-TM-T88V-Series/s/SPT_C31CA85011?review-filter=Windows+8+64-bit