From febeae485f9bbc4b15b90437849c4eeff193c060 Mon Sep 17 00:00:00 2001 From: Alija Sabic Date: Fri, 6 Dec 2019 00:00:34 +0100 Subject: [PATCH] Add port initialization and validation for SerialCommunicator 1. test all serial devices for AT COM support 1. proceed with first valid port --- webgui/src/flipmouse/js/flipcomm.js | 8 +- webgui/src/flipmouse/js/sercomm.js | 217 +++++++++++++--------------- 2 files changed, 106 insertions(+), 119 deletions(-) diff --git a/webgui/src/flipmouse/js/flipcomm.js b/webgui/src/flipmouse/js/flipcomm.js index 1da1db3..9c7029c 100644 --- a/webgui/src/flipmouse/js/flipcomm.js +++ b/webgui/src/flipmouse/js/flipcomm.js @@ -61,7 +61,7 @@ function FlipMouse(initFinished) { var _SLOT_CONSTANT = 'Slot:'; var _AT_CMD_BUSY_RESPONSE = 'BUSY'; var _AT_CMD_OK_RESPONSE = 'OK'; - var _AT_CMD_MIN_WAITTIME_MS = 5000; + var _AT_CMD_MIN_WAITTIME_MS = 50; var _timestampLastAtCmd = new Date().getTime(); var _atCmdQueue = []; var _sendingAtCmds = false; @@ -387,12 +387,12 @@ function FlipMouse(initFinished) { if (userAgent.indexOf(' electron/') > -1) { var promise = new Promise(function(resolve) { _communicator = new SerialCommunicator(); - resolve(); - return; + _communicator.init().then(function () { + resolve(); + }); }); } else { var promise = new Promise(function(resolve) { - if(window.location.href.indexOf('mock') > -1) { _communicator = new MockCommunicator(); resolve(); diff --git a/webgui/src/flipmouse/js/sercomm.js b/webgui/src/flipmouse/js/sercomm.js index 90a380d..328045d 100644 --- a/webgui/src/flipmouse/js/sercomm.js +++ b/webgui/src/flipmouse/js/sercomm.js @@ -1,8 +1,8 @@ function SerialCommunicator() { const SerialPort = require('serialport'); - const Readline = require('@serialport/parser-readline') - const Delimiter = require('@serialport/parser-delimiter') - const parser = new Delimiter({ delimiter: '\r\n' }) + const Readline = require('@serialport/parser-readline'); + const Delimiter = require('@serialport/parser-delimiter'); + const parser = new Delimiter({ delimiter: '\r\n' }); //serial port instance var _port; @@ -15,141 +15,129 @@ function SerialCommunicator() { this.setValueHandler = function (handler) { _valueHandler = handler; }; - - function ping(port_name){ - try { - const port = new SerialPort(port_name,{ - baudRate: 115200, - parser: new SerialPort.parsers.Readline('\n') - }); - port.on('open',function(){ - port.write("AT ID \r\n"); - data = port.read(); - //TODO: test for valid id - console.log(i + data); - port.close(); - }); - - return new Promise(resolve => port.on("close", resolve)); - } catch(err) { - console.log("Not a valid port"); - return new Promise(function (resolve, reject) { - reject(); - }); - } - - - } - - - this.connect = async function() { - - let portname = await this.getValidPort(); - - serialport = "/dev/ttyACM0"; - - - //})(); - - /*(async function() { - const portlist = await SerialPort.list(); - let serialport = ""; - for(const port of portlist) { - //open port - probePort = new SerialPort(port['comName'], {baudRate: 115200 }) - probePort.pipe(parser); - - //send data - - //await for feedback - - // if flipmouse -> set _port & return - }*/ - - - - //is port defined? - - //attach parser to serial port - _port = new SerialPort(serialport, { - baudRate: 115200 }) - _port.pipe(parser); - console.log("Found valid device @" + serialport); - - - //on a fully received line, - //check if the data is a reported raw value - //or returned data for a dedicated command (see sendData) - parser.on('data', function(data) { - console.log("data evt: " + data); + function isATCOM({ comName }, device = 'FABI v2.3') { + return new Promise((resolve, reject) => { + const port = new SerialPort( + comName, + { + baudRate: 115200, + parser: new SerialPort.parsers.Readline('\n') + }, + function(error) { + if (!error) { + let found = false; + port.on('data', chunk => { + const msg = chunk.toString(); + if (msg.startsWith(device)) { + found = true; + console.log( + `Found AT COM device at ${comName}` + ); + port.close(); + } else { + console.error(`No ${device} at ${comName}.`); + reject(); + } + }); + port.on('close', () => resolve(port)); + port.write('AT ID \r\n'); + setTimeout(() => { + if (!found) { + console.error( + `Serial device ${comName} is not responding.` + ); + reject(); + } + }, 2000); // Reject if serial port is not responding. + } else { + console.log(error.message); + reject(); + } + } + ); + }); + } - if (data && data.toString().indexOf(C.LIVE_VALUE_CONSTANT) > -1) { - if (L.isFunction(_valueHandler)) { - _valueHandler(data.toString()); - } - return; - } - - if(_internalValueFunction) { - _internalValueFunction(data); - } - }); - //})(); + this.init = function() { + return SerialPort.list().then(function(ports, errors) { + const device = 'FABI v2.3'; // Proper AT COM device name + console.log(`Searching for ${device} ...`); + if (typeof errors === 'undefined') { + // race to (first) success, cf. https://stackoverflow.com/a/37235274/5728717 + return Promise.all( + ports + .map(port => isATCOM(port, device)) + .map(port => { + return port.then( + resolve => Promise.reject(resolve), + reject => Promise.resolve(reject) + ); + }) + ) + .then( + resolve => Promise.reject(resolve), + reject => Promise.resolve(reject) + ) + .then(port => { + _port = port; + return Promise.resolve(); + }) + .catch(() => { + // throw 'No AT command capabale COM port found.'; + console.error('No AT command capabale COM port found.'); + }); + } else { + console.error(errors); + } + }); }; - - this.getValidPort = async function() { - const portlist = await SerialPort.list(); - for(let i = 0; i