Skip to content

Commit

Permalink
Implements multiple printers for the USB adapter, updates readme to e…
Browse files Browse the repository at this point in the history
…xplain how to use it
  • Loading branch information
jor3l committed Dec 12, 2016
1 parent 89dfe0f commit 1461468
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 23 deletions.
44 changes: 40 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ $ npm i escpos

if you use usb as an adapter :

+ On Linux, you'll need `libudev` to build libusb.
+ On Linux, you'll need `libudev` to build libusb.
+ On Ubuntu/Debian: `sudo apt-get install build-essential libudev-dev`.
+ On Windows, Use [Zadig](http://sourceforge.net/projects/libwdi/files/zadig/) to install the WinUSB driver for your USB device.
+ On Windows, Use [Zadig](http://sourceforge.net/projects/libwdi/files/zadig/) to install the WinUSB driver for your USB device.

Otherwise you will get `LIBUSB_ERROR_NOT_SUPPORTED` when attempting to open devices.

Expand All @@ -23,6 +23,7 @@ Otherwise you will get `LIBUSB_ERROR_NOT_SUPPORTED` when attempting to open devi
````javascript
const escpos = require('escpos');

// Select the adapter based on your printer type
const device = new escpos.USB();
// const device = new escpos.Network('localhost');
// const device = new escpos.Serial('/dev/usb/lp0');
Expand All @@ -48,8 +49,37 @@ device.open(function(){


````
----
## USB Adapter methods
### open(function calback)
Claims the current device USB, if the printer is already in use by other process this will fail.

## Documentation
By default, the USB adapter will set the first printer found, if you have multiple printers use `setDevice` and `getDevices` to switch between printers.

Triggers the callback function when done.

### openAll()
Claims all the printers connected to the machine, one by one. When done, sets the first printer found as the default device and triggers the callback function.

### getDevices()
Returns the number (N) of printers connected, if open is called you must open each device in order to use it.

The ID of the printer will be the number you want to set from 0 to N-1.

### setDevice(N)
Sets the index passed as the current device, N must be higher than 0 and lower than `getDevices()`.

This must be called before printing if you want to swtich between multiple printers connected to the same device.

### close(function callback)
Closes the current device and releases its USB interface.

### closeAll(function callback)
Similar to `close()` but loops through all the devices connected and closes them all.

----

## Printer methods

Escpos inherits its methods to the printers. the following methods are defined:

Expand Down Expand Up @@ -133,12 +163,16 @@ Partial cut is not implemented in all printers.
Sends a pulse to the cash drawer in the specified pin.

pin is a numeric value which defines the pin to be used to send the pulse, it could be 2 or 5.
Raises CashDrawerError()
Raises `CashDrawerError()``

----

## Thanks

+ Part of code from [@taoyuan](https://github.com/taoyuan)

----

## Contributing
- Fork this repo
- Clone your repo
Expand All @@ -148,6 +182,8 @@ Raises CashDrawerError()
- Make sure your features are fully tested
- Open a pull request, and enjoy <3

----

### MIT license
Copyright (c) 2015 lsong

Expand Down
122 changes: 104 additions & 18 deletions adapter/usb.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,46 @@ const IFACE_CLASS = {
*/
function USB(vid, pid){
var self = this;

this.device = null;
this.devices = [];

if(vid && pid){
this.device = usb.findByIds(vid, pid);
this.devices = [usb.findByIds(vid, pid)];
this.device = this.devices[0];
}else{
this.device = USB.findPrinter();
this.findPrinter();
}

if (!this.device)
throw new Error('Can not find printer');

usb.on('detach', function(device){
if(device == self.device){
self.emit('detach' , device);
self.emit('disconnect', device);
self.device = null;
self.emit('detach' , device);
self.emit('disconnect', device);

for(let i in self.devices) {
if(device == self.devices[i]) {
self.devices.splice(i, 1);
}
}

if(device == self.device) {
if(self.devices.length > 0) {
self.device = self.devices[0];
} else self.device = null;
}
});
EventEmitter.call(this);
EventEmitter.call(this);
return this;
};

/**
* [findPrinter description]
* @return {[type]} [description]
*/
USB.findPrinter = function(){
return usb.getDeviceList().filter(function(device){
USB.prototype.findPrinter = function(){
this.devices = usb.getDeviceList().filter(function(device){
try{
return device.configDescriptor.interfaces.filter(function(iface){
return iface.filter(function(conf){
Expand All @@ -58,7 +72,12 @@ USB.findPrinter = function(){
}catch(e){
return false;
}
})[0];
});

if(this.devices.length > 0) {
// Select first printer found by default
this.device = this.devices[0];
}
};

/**
Expand All @@ -71,28 +90,74 @@ util.inherits(USB, EventEmitter);
* @param {Function} callback [description]
* @return {[type]} [description]
*/
USB.prototype.open = function (callback){
var self = this, counter = 0;
USB.prototype.open = function (callback, i){
let self = this, counter = 0, index = i || 0;
this.device.open();
this.device.interfaces.forEach(function(iface){
(function(iface){
iface.setAltSetting(iface.altSetting, function(){
iface.claim(); // must be called before using any endpoints of this interface.
iface.endpoints.filter(function(endpoint){
if(endpoint.direction == 'out' && !self.endpoint){
if(endpoint.direction == 'out' && !self.endpoint) {
self.endpoint = endpoint;
self.emit('connect', self.device);
callback && callback(null, self);
self.devices[index]._endpoint = endpoint; // store each endpoint for later
}
});
if(++counter === this.device.interfaces.length && !self.endpoint){

if(self.endpoint) {
self.emit('connect', self.device);
callback && callback(null, self);
} else if(++counter === this.device.interfaces.length && !self.endpoint){
callback && callback(new Error('Can not find endpoint from printer'));
}
});
})(iface);
});

return this;
};

USB.prototype.openAll = function (callback) {
this.openNext(0, callback);
return this;
};

USB.prototype.openNext = function(index, callback) {
let self = this;

this.setDevice(index).open(function(err) {
if(err) {
console.log(err);
return;
}

if((index+1) == self.devices.length) {
callback && callback(null);
} else {
self.openNext(index+1, callback);
}
}, index);

return this;
}

USB.prototype.setDevice = function(i) {
if(this.devices[i]) {
this.device = this.devices[i];
if('_endpoint' in this.device) {
this.endpoint = this.device._endpoint;
} else {
this.endpoint = null;
}
}

return this;
};

USB.prototype.getDevices = function() {
return this.devices.length;
};

/**
* [function write]
* @param {[type]} data [description]
Expand All @@ -109,6 +174,27 @@ USB.prototype.close = function(callback){
return this;
};

USB.prototype.closeAll = function(callback){
let self = this;
self.closeNext(0, callback);
return this;
};

USB.prototype.closeNext = function(index, callback) {
let self = this;

self.setDevice(index).close(function() {
self.devices.splice(index, 1);
if(self.devices.length == 0) {
callback && callback(null);
} else {
self.closeNext(0, callback);
}
});

return this;
}

/**
* [exports description]
* @type {[type]}
Expand Down
23 changes: 23 additions & 0 deletions examples/multiple_usb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';
const escpos = require('../');

const device = new escpos.USB();
const printer = new escpos.Printer(device);

device.openAll(function(){
let devices = device.getDevices();

for(let i = 0; i < devices; i++) {
console.log('Printing on device', (i+1));
setTimeout(function() {
device.setDevice(i);
printer.font('a')
.align('ct')
.style('bu')
.size(1, 1)
.text('This is the printer #' + (i+1))
.cut();
}, 500*i);
}

});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "escpos",
"version": "2.3.0",
"version": "2.3.1",
"description": "ESC/POS Printer driver for nodejs",
"main": "index.js",
"scripts": {
Expand Down

0 comments on commit 1461468

Please sign in to comment.