Skip to content

Commit

Permalink
Remove the openImmediatly flag in favor of the autoOpen option (#830)
Browse files Browse the repository at this point in the history
closes #809
  • Loading branch information
reconbot committed Jul 24, 2018
1 parent 1f48920 commit d9d78c1
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 50 deletions.
54 changes: 32 additions & 22 deletions packages/serialport-util/packages/node-serialport/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

***

Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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');
Expand Down Expand Up @@ -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_**

Expand All @@ -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.
Expand All @@ -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)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
20 changes: 10 additions & 10 deletions packages/serialport-util/packages/node-serialport/lib/serialport.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var kMinPoolSpace = 128;

var defaultSettings = {
baudRate: 9600,
autoOpen: true,
parity: 'none',
xon: false,
xoff: false,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand All @@ -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());
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand Down

0 comments on commit d9d78c1

Please sign in to comment.