Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements the --follow option in the "serial monitor" command. #240

Merged
merged 3 commits into from Feb 7, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
107 changes: 95 additions & 12 deletions commands/SerialCommand.js
Expand Up @@ -68,7 +68,7 @@ SerialCommand.prototype = extend(BaseCommand.prototype, {

init: function () {
this.addOption('list', this.listDevices.bind(this), 'Show devices connected via serial to your computer');
this.addOption('monitor', this.monitorPort.bind(this), 'Connect and display messages from a device');
this.addOption('monitor', this.monitorSwitch.bind(this), 'Connect and display messages from a device');
this.addOption('identify', this.identifyDevice.bind(this), 'Ask for and display device ID via serial');
this.addOption('wifi', this.configureWifi.bind(this), 'Configure Wi-Fi credentials over serial');
this.addOption('mac', this.deviceMac.bind(this), 'Ask for and display MAC address via serial');
Expand Down Expand Up @@ -169,37 +169,120 @@ SerialCommand.prototype = extend(BaseCommand.prototype, {
}
},

// TODO: Unfortunately we have to use this switch function in order to remove
// the "--follow" argument before passing on to monitorPort.
// This follows FlashCommand's precedent, but we should create a universal
// way to handle this properly.
monitorSwitch: function(comPort) {
this.checkArguments(arguments);

var args = Array.prototype.slice.call(arguments);
if (this.options.follow) {
//trim

var idx = utilities.indexOf(args, '--follow');
args.splice(idx, 1);
}

return this.monitorPort.apply(this, args);
},

monitorPort: function (comPort) {
var cleaningUp = false;
var selectedDevice;
var serialPort;

var displayError = function (err) {
if (err) {
console.error('Serial err: ' + err);
console.error('Serial problems, please reconnect the device.');
}
};

// Called when port closes
var handleClose = function () {
if (self.options.follow && !cleaningUp) {
console.log(
chalk.bold.white(
'Serial connection closed. Attempting to reconnect...'));
reconnect();
} else {
console.log(chalk.bold.white('Serial connection closed.'));
}
};

// Handle interrupts and close the port gracefully
var handleInterrupt = function () {
if (!cleaningUp) {
console.log(chalk.bold.red('Caught Interrupt. Cleaning up.'));
cleaningUp = true;
if (serialPort && serialPort.isOpen()) {
serialPort.flush(function () {
serialPort.close();
})
}
}
}

// Called only when the port opens successfully
var handleOpen = function () {
console.log(chalk.bold.white('Serial monitor opened successfully:'));
};

var handlePortFn = function (device) {
if (!device) {
console.error('No serial device identified');
return;
if (self.options.follow) {
setTimeout(function () {
self.whatSerialPortDidYouMean(comPort, true, handlePortFn);
}, 5);
return;
} else {
console.error(chalk.bold.white('No serial device identified'));
return;
}
}

console.log('Opening serial monitor for com port: "' + device.port + '"');
selectedDevice = device;
openPort();
};

//TODO: listen for interrupts, close gracefully?
var serialPort = new SerialPort(device.port, {
var openPort = function () {
serialPort = new SerialPort(selectedDevice.port, {
baudrate: 9600
}, false);
serialPort.on('close', handleClose);
serialPort.on('data', function (data) {
process.stdout.write(data.toString());
});
serialPort.on('error', displayError);
serialPort.open(function (err) {
if (err) {
console.error('Serial err: ' + err);
console.error('Serial problems, please reconnect the device.');
if (err && self.options.follow) {
reconnect(selectedDevice);
} else if (err) {
displayError(err);
} else {
handleOpen();
}
});
};

this.checkArguments(arguments);
var reconnect = function () {
setTimeout(function () {
openPort(selectedDevice);
}, 5);
}

process.on('SIGINT', handleInterrupt);
process.on('SIGQUIT', handleInterrupt);
process.on('SIGTERM', handleInterrupt);
process.on('exit', handleInterrupt);

if (this.options.follow) {
//catch the serial port dying, and keep retrying forever
//TODO: needs serialPort error / close event / deferred
console.log('Polling for available serial device...');
}

var self = this;
this.whatSerialPortDidYouMean(comPort, true, handlePortFn);
},

Expand Down Expand Up @@ -1006,7 +1089,7 @@ SerialCommand.prototype = extend(BaseCommand.prototype, {
}

if (!devices || devices.length === 0) {
return self.error('No devices available via serial');
return callback(undefined);
}

inquirer.prompt([
Expand Down