From d9d78c1864029ac2bfc24a90ed604ba940b2278b Mon Sep 17 00:00:00 2001 From: Francis Gulotta Date: Sat, 28 May 2016 21:33:52 -0400 Subject: [PATCH] Remove the openImmediatly flag in favor of the autoOpen option (#830) closes #809 --- .../packages/node-serialport/README.md | 54 +++++++++++-------- .../node-serialport/examples/opening.js | 2 +- .../node-serialport/lib/serialport.js | 20 +++---- .../node-serialport/test/integration-lite.js | 4 +- .../node-serialport/test/serialport.js | 40 ++++++++------ 5 files changed, 70 insertions(+), 50 deletions(-) diff --git a/packages/serialport-util/packages/node-serialport/README.md b/packages/serialport-util/packages/node-serialport/README.md index abc1d9bb5e..2b6b9f3ccf 100644 --- a/packages/serialport-util/packages/node-serialport/README.md +++ b/packages/serialport-util/packages/node-serialport/README.md @@ -21,7 +21,7 @@ You're reading the README for the master branch of serialport. You probably want *** -Imagine a world where you can write JavaScript to control blenders, lights, security systems, or even robots. Yes, I said robots. That world is here and now with node-serialport. It provides a very simple interface to the low level serial port code necessary to program [Arduino](http://www.arduino.cc/) chipsets, [X10](http://www.smarthome.com/manuals/protocol.txt) wireless communications, or even the rising [Z-Wave](http://www.z-wave.com/modules/ZwaveStart/) and [Zigbee](http://www.zigbee.org/) standards. The physical world is your oyster with this goodie. For a full break down of why we made this, please read [NodeBots - The Rise of JS Robotics](http://www.voodootikigod.com/nodebots-the-rise-of-js-robotics). +Imagine a world where you can write JavaScript to control blenders, lights, security systems, or even robots. Yes, I said robots. That world is here and now with node serialport. It provides a very simple interface to the low level serial port code necessary to program [Arduino](http://www.arduino.cc/) chipsets, [X10](http://www.smarthome.com/manuals/protocol.txt) wireless communications, or even the rising [Z-Wave](http://www.z-wave.com/modules/ZwaveStart/) and [Zigbee](http://www.zigbee.org/) standards. The physical world is your oyster with this goodie. For a full break down of why we made this, please read [NodeBots - The Rise of JS Robotics](http://www.voodootikigod.com/nodebots-the-rise-of-js-robotics). *** @@ -46,7 +46,7 @@ For getting started with node-serialport, we recommend you begin with the follow * [Listing Ports](#listing-ports) * [Parsers](#parsers) * [Methods](#methods) - * [SerialPort](#serialport-path-options-openimmediately-callback) + * [SerialPort](#serialport-path-options-opencallback) * [close()](#close-callback) * [drain()](#drain-callback) * [flush()](#flush-callback) @@ -177,54 +177,67 @@ When opening a serial port, you can specify (in this order). ### Opening a Port -Constructing a `SerialPort` object will open a port, eventually. You can bind events while the port is opening but you must wait until it is open to `write()` to it. (Most port functions require an open port.) You can call code when a port is opened in three ways. +Constructing a `SerialPort` object will open a port on `nextTick`. You can bind events while the port is opening but you must wait until it is open to `write()` to it. (Most port functions require an open port.) You can call code when a port is opened in three ways. - The `open` event is always emitted when the port is opened - - The constructor callback is called when the port is opened and you haven't disabled the `openImmediately` option, if you have disabled it, the callback is only used for errors. - - The `.open()` function takes a callback that is called when the port is opened. This can be used if you disabled the `openImmediately` option or have previously closed an open port. + - The constructor's openCallback is passed to `.open()` when the `autoOpen` option hasn't been disabled, if you have disabled it the callback is ignored. + - The `.open()` function takes a callback that is called after the port is opened. This can be used if you disabled the `autoOpen` option or have previously closed an open port. ```js var SerialPort = require('serialport'); var port = new SerialPort('/dev/tty-usbserial1'); -port.on('open', function () { +port.on('open', function() { port.write('main screen turn on', function(err) { if (err) { - return console.log('Error: ', err.message); + return console.log('Error on write: ', err.message); } console.log('message written'); }); }); + +// open errors will be emitted as an error event +port.on('error', function(err) { + console.log('Error: ', err.message); +}) ``` This could be moved to the constructor's callback. ```js var SerialPort = require('serialport'); -var port = new SerialPort('/dev/tty-usbserial1', function () { +var port = new SerialPort('/dev/tty-usbserial1', function (err) { + if (err) { + return console.log('Error: ', err.message); + } port.write('main screen turn on', function(err) { if (err) { - return console.log('Error: ', err.message); + return console.log('Error on write: ', err.message); } console.log('message written'); }); }); ``` -When disabling the `openImmediately` flag you'll need to open the port on your own. Note, in order to disable the `openImmediately` flag, we have to pass an options object. +When disabling the `autoOpen` option you'll need to open the port on your own. ```js var SerialPort = require('serialport'); -var port = new SerialPort('/dev/tty-usbserial1', {}, false); +var port = new SerialPort('/dev/tty-usbserial1', { autoOpen: false }); port.open(function (err) { if (err) { return console.log('Error opening port: ', err.message); } - // errors will be emitted on the port since there is no callback to write + // write errors will be emitted on the port since there is no callback to write port.write('main screen turn on'); }); + +// the open event will always be emitted +port.on('open', function() { + // open logic +}); ``` ### Listing Ports @@ -272,7 +285,7 @@ var port = new SerialPort('/dev/tty-usbserial1', { }); ``` -To use the raw parser, you just provide the function definition (or leave undefined): +To use the raw parser don't specify any parser, however if you really want to you can: ```js var SerialPort = require('serialport'); @@ -302,9 +315,9 @@ Enjoy and do cool things with this code. ## Methods -### SerialPort (path, options, openImmediately, openCallback) +### SerialPort (path, options, openCallback) -Create a new serial port on `path`. In the case of invalid arguments or invalid options constructing a new serialport will throw an error. If `openImmediately` is true (the default) the `openCallback` will be passed to `.open()` +Create a new serial port object for the `path`. In the case of invalid arguments or invalid options when constructing a new SerialPort it will throw an error. The port will open automatically by default which is the equivalent of calling `port.open(openCallback)` in the next tick. This can be disabled by setting the option `autoOpen` to false. **_path_** @@ -314,6 +327,7 @@ The system path of the serial port to open. For example, `/dev/tty` on Mac/Linux Port configuration options. +* `autoOpen` Automatically opens the port on `nextTick`, defaults to `true`. * `baudRate` Baud Rate, defaults to 9600. Should be one of: 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1800, 1200, 600, 300, 200, 150, 134, 110, 75, or 50. Custom rates as allowed by hardware is supported. Windows doesn't support custom baud rates. * `dataBits` Data Bits, defaults to 8. Must be one of: 8, 7, 6, or 5. * `stopBits` Stop Bits, defaults to 1. Must be one of: 1 or 2. @@ -333,15 +347,11 @@ These properties are ignored for windows. An object with the following propertie * `vmin` (default: 1) - see [`man termios`](http://linux.die.net/man/3/termios) * `vtime` (default: 0) - see [`man termios`](http://linux.die.net/man/3/termios) -**_openImmediately (optional)_** +**_`openCallback` (optional)_** -Attempts to open a connection to the serial port on `process.nextTick`. The default is `true`. If you've provided a `openCallback` it will be given to `open()`. Set to `false` to manually call `open()`. - -**_callback (optional)_** - -Called when a connection has been opened. The callback should be a function that looks like: `function (error) { ... }` +This function is passed to `.open()` and called when a connection has been opened. The callback should be a function that looks like: `function (error) { ... }` -**Note:** The callback will NOT be called if openImmediately is set to false as the open will not be performed. +**Note:** The callback will NOT be called if autoOpen is set to false as the open will not be performed. ### .open (callback) diff --git a/packages/serialport-util/packages/node-serialport/examples/opening.js b/packages/serialport-util/packages/node-serialport/examples/opening.js index 063d905b13..a449cd8cf6 100644 --- a/packages/serialport-util/packages/node-serialport/examples/opening.js +++ b/packages/serialport-util/packages/node-serialport/examples/opening.js @@ -31,7 +31,7 @@ // When disabling open immediately. // var SerialPort = require('serialport'); -// var port = new SerialPort('/dev/tty-usbserial1', {}, false); +// var port = new SerialPort('/dev/tty-usbserial1', { autoOpen: false }); // port.open(function (err) { // if (err) { diff --git a/packages/serialport-util/packages/node-serialport/lib/serialport.js b/packages/serialport-util/packages/node-serialport/lib/serialport.js index 198fcb2720..7e89caf986 100644 --- a/packages/serialport-util/packages/node-serialport/lib/serialport.js +++ b/packages/serialport-util/packages/node-serialport/lib/serialport.js @@ -34,6 +34,7 @@ var kMinPoolSpace = 128; var defaultSettings = { baudRate: 9600, + autoOpen: true, parity: 'none', xon: false, xoff: false, @@ -76,19 +77,18 @@ function correctOptions(options) { return options; } -function SerialPort(path, options, openImmediately, callback) { - var args = Array.prototype.slice.call(arguments); - callback = args.pop(); - if (typeof callback !== 'function') { - callback = null; +function SerialPort(path, options, callback) { + if (typeof callback === 'boolean') { + throw new TypeError('`openImmediately` is now called `autoOpen` and is a property of options'); } - options = (typeof options !== 'function') && options || {}; - - if (openImmediately === undefined || openImmediately === null) { - openImmediately = true; + if (typeof options === 'function') { + callback = options; + options = {}; } + options = options || {}; + stream.Stream.call(this); if (!path) { @@ -151,7 +151,7 @@ function SerialPort(path, options, openImmediately, callback) { this.options = settings; - if (openImmediately) { + if (this.options.autoOpen) { // is nextTick necessary? process.nextTick(this.open.bind(this, callback)); } diff --git a/packages/serialport-util/packages/node-serialport/test/integration-lite.js b/packages/serialport-util/packages/node-serialport/test/integration-lite.js index a12ec4b75e..20014e6a90 100644 --- a/packages/serialport-util/packages/node-serialport/test/integration-lite.js +++ b/packages/serialport-util/packages/node-serialport/test/integration-lite.js @@ -72,7 +72,7 @@ describe('SerialPort light integration', function() { }); it('cannot be opened twice', function(done) { - var port = new SerialPort(testPort, {}, false); + var port = new SerialPort(testPort, { autoOpen: false }); var calls = 0; var errors = 0; var spy = function(err) { @@ -92,7 +92,7 @@ describe('SerialPort light integration', function() { }); it('can open and close ports repetitively', function(done) { - var port = new SerialPort(testPort, {}, false); + var port = new SerialPort(testPort, { autoOpen: false }); port.open(function(err) { assert.isNull(err); port.close(function(err) { diff --git a/packages/serialport-util/packages/node-serialport/test/serialport.js b/packages/serialport-util/packages/node-serialport/test/serialport.js index 1efe83c186..8952a47bbc 100644 --- a/packages/serialport-util/packages/node-serialport/test/serialport.js +++ b/packages/serialport-util/packages/node-serialport/test/serialport.js @@ -25,10 +25,19 @@ describe('SerialPort', function() { sandbox.restore(); }); - describe('Legacy Constructor', function() { - it('still works', function(done){ + describe('Depreciated options', function() { + it('legacy constructor still works', function(done){ this.port = new SerialPort.SerialPort('/dev/exists', done); }); + + it('throws when `openImmediately` is set', function(done) { + try { + this.port = new SerialPort('/dev/exists', {}, false); + } catch (e) { + assert.instanceOf(e, TypeError); + done(); + } + }); }); describe('Constructor', function() { @@ -127,9 +136,10 @@ describe('SerialPort', function() { xon: true, xoff: true, xany: true, - rtscts: true + rtscts: true, + autoOpen: false }; - var port = new SerialPort('/dev/exists', options, false); + var port = new SerialPort('/dev/exists', options); assert.isTrue(port.options.xon); assert.isTrue(port.options.xoff); assert.isTrue(port.options.xany); @@ -146,7 +156,7 @@ describe('SerialPort', function() { describe('#open', function() { it('passes the port to the bindings', function(done) { var openSpy = sandbox.spy(bindings, 'open'); - var port = new SerialPort('/dev/exists', {}, false); + var port = new SerialPort('/dev/exists', { autoOpen: false }); expect(port.isOpen()).to.be.false; port.open(function(err) { expect(err).to.not.be.ok; @@ -175,12 +185,12 @@ describe('SerialPort', function() { assert.isFunction(cb); done(); }); - var port = new SerialPort('/dev/exists', {}, false); + var port = new SerialPort('/dev/exists', { autoOpen: false }); port.open(); }); it('calls back an error when opening an invalid port', function(done) { - var port = new SerialPort('/dev/unhappy', {}, false); + var port = new SerialPort('/dev/unhappy', { autoOpen: false }); port.open(function(err) { expect(err).to.be.ok; done(); @@ -212,7 +222,7 @@ describe('SerialPort', function() { }); it('cannot be opened twice', function(done) { - var port = new SerialPort('/dev/exists', {}, false); + var port = new SerialPort('/dev/exists', { autoOpen: false }); var calls = 0; var errors = 0; var spy = function(err) { @@ -265,7 +275,7 @@ describe('SerialPort', function() { }); it('emits an error event or error callback but not both', function(done) { - var port = new SerialPort('/dev/exists', false); + var port = new SerialPort('/dev/exists', { autoOpen: false }); var called = 0; var doneIfTwice = function(err) { assert.instanceOf(err, Error); @@ -294,7 +304,7 @@ describe('SerialPort', function() { it('errors when the port is not open', function(done) { var cb = function() {}; - var port = new SerialPort('/dev/exists', false, cb); + var port = new SerialPort('/dev/exists', { autoOpen: false }, cb); port.close(function(err) { assert.instanceOf(err, Error); done(); @@ -304,13 +314,13 @@ describe('SerialPort', function() { describe('#isOpen', function() { it('returns false when the port is created', function(done) { - var port = new SerialPort('/dev/exists', {}, false); + var port = new SerialPort('/dev/exists', { autoOpen: false }); assert.isFalse(port.isOpen()); done(); }); it('returns false when the port is opening', function(done) { - var port = new SerialPort('/dev/exists', {}, false); + var port = new SerialPort('/dev/exists', { autoOpen: false }); sandbox.stub(bindings, 'open', function() { assert.isTrue(port.opening); assert.isFalse(port.isOpen()); @@ -361,7 +371,7 @@ describe('SerialPort', function() { describe('#set', function() { it('errors when serialport not open', function(done) { var cb = function() {}; - var port = new SerialPort('/dev/exists', {}, false, cb); + var port = new SerialPort('/dev/exists', { autoOpen: false }, cb); port.set({}, function(err) { assert.instanceOf(err, Error); done(); @@ -432,7 +442,7 @@ describe('SerialPort', function() { it('flush errors when serialport not open', function(done) { var cb = function() {}; - var port = new SerialPort('/dev/exists', {}, false, cb); + var port = new SerialPort('/dev/exists', { autoOpen: false }, cb); port.flush(function(err) { assert.instanceOf(err, Error); done(); @@ -441,7 +451,7 @@ describe('SerialPort', function() { it('drain errors when serialport not open', function(done) { var cb = function() {}; - var port = new SerialPort('/dev/exists', {}, false, cb); + var port = new SerialPort('/dev/exists', { autoOpen: false }, cb); port.drain(function(err) { assert.instanceOf(err, Error); done();