123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- 'use strict'
- import { ipcRenderer } from 'electron';
- import SerialPort from 'serialport';
- const serials = {};
- const ids = ipcRenderer.sendSync('windowsid', 'already');
- /* ************ Functions ************ */
- /**
- * Parse a incoming a list of messages of ports, & divide into two parts, based
- * on connected boards.
- * @param {Array} list A list of messages of ports
- * @returns {Object} A object which contains two arrays
- */
- function parsePorts(list) {
- let result = { boards: [], wifi: [] };
- list.forEach(val => {
- let mf = val.manufacturer;
- if (mf) {
- // if (mf.indexOf('Arduino') > -1)
- // result.boards.push(val);
- if (mf.indexOf('ftdi') > -1)
- result.wifi.push(val);
- }
- });
- return result;
- }
- /**
- * Handle error, & send error back to the previous process.
- * @param {Error} err Incoming error
- * @param {string} event Event name
- * @param {Array<string|number>} data Data to send
- * @returns {void} void
- */
- function errorHandler(err, event, sid = '', data = []) {
- ipcRenderer.sendTo(ids[0], 'error', err, event, sid, data);
- return;
- }
- /**
- * Handle list event & return a set of messages of connected boards.
- * @returns {void} void
- */
- function listHandler() {
- SerialPort.list()
- .then(result => {
- let res = parsePorts(result);
- ipcRenderer.sendTo(ids[0], 'result_list', res);
- })
- .catch(err => errorHandler(err, 'list'));
- return;
- }
- /**
- * Handle open command, & receive messages from board.
- * @param {string} sid Socket's id
- * @param {string} comName Name of port
- * @param {number} baudRate Number of baud rate
- * @returns {void} void
- */
- function openHandler(e, sid, comName, baudRate = 9600) {
- const serial = new SerialPort(comName, { baudRate: baudRate }, err => {
- if (!err) {
- ipcRenderer.sendTo(ids[0], 'result_open', sid, comName, baudRate);
- serial.on('readable', () => {
- let str = serial.read();
- str instanceof Buffer ? str = str.toString('utf-8') : '';
- ipcRenderer.sendTo(ids[0], 'message', sid, str);
- })
- serials[sid] = serial;
- } else
- errorHandler(err, 'open', sid);
- });
- return;
- }
- /**
- * Handle close command, & close the communication.
- * @param {string} sid Socket's id
- * @returns {void} void
- */
- function closeHandler(e, sid) {
- const serial = serials[sid];
- if (serial && serial.isOpen)
- serial.close(err => {
- if (!err) {
- delete serials[sid];
- ipcRenderer.sendTo(ids[0], 'result_close', sid)
- } else
- errorHandler(err, 'close', sid);
- return;
- });
- }
- /**
- * Handle send command, & send a message to board.
- * @param {string} sid Socket's id
- * @param {string} msg Incoming message
- * @param {string} postfix Postfix of sending message
- * @returns {void} void
- */
- function sendHandler(e, sid, msg, postfix = '') {
- const serial = serials[sid];
- if (serial && serial.isOpen) {
- if (postfix === 'nl')
- postfix = '\n';
- else if (postfix === 'cr')
- postfix = '\r';
- else if (postfix === 'blc')
- postfix = '\n\r';
- msg += postfix;
- serial.write(msg, 'utf-8', e => console.warn(e));
- }
- return;
- }
- /**
- * Handle update command, & update the communication to a specific
- * baud rate.
- * @param {string} sid Socket's id
- * @param {number} baudRate Baud rate to update to
- * @returns {void} void
- */
- function updateHandler(e, sid, baudRate) {
- const serial = serials[sid];
- if (serial && serial.isOpen) {
- serial.update({ baudRate: baudRate }, err => {
- err ?
- errorHandler(err, 'update', sid, [baudRate]) :
- ipcRenderer.sendTo(ids[0], 'result_update', sid, baudRate);
- });
- }
- return;
- }
- /**
- * Parse a incoming a list of messages of ports, & compare with list map, &
- * check if it's get new boards connected.
- * @param {Array<string>} map An array with comNames
- * @returns {void} void
- */
- function detectListChange(map) {
- SerialPort.list()
- .then(result => {
- let is_changed = false, comNames = [], res = { boards: [], wifi: [] };
- result.forEach(val => {
- if (val.manufacturer) {
- if (val.manufacturer.toLocaleLowerCase().indexOf('ftdi') > -1)
- res.wifi.push(val);
- // else if (val.manufacturer.toLocaleLowerCase().indexOf('silicon') > -1)
- // res.wifi.push(val);
- comNames.push(val.comName);
- }
- });
- if (comNames.length !== map.length)
- is_changed = true;
- else {
- for (let i = 0; i < comNames.length; i++)
- if (map.indexOf(comNames[i]) < 0) {
- is_changed = true;
- break;
- }
- }
- if (is_changed) {
- ipcRenderer.sendTo(ids[0], 'result_list', res);
- map.length = 0;
- comNames.forEach(val => {
- map.push(val);
- });
- }
- })
- .catch(err => errorHandler(err, 'list'));
- return;
- }
- /**
- * Run detectListChange function every 3 secs.
- * @returns {void} void
- */
- function loopDetectListChange() {
- let listMap = [];
- setInterval(() => {
- detectListChange(listMap);
- }, 3000);
- }
- // ------ bind functions to ipcRenderer's events ------ //
- ipcRenderer.on('handle_list', listHandler);
- ipcRenderer.on('handle_open', openHandler);
- ipcRenderer.on('handle_close', closeHandler);
- ipcRenderer.on('handle_send', sendHandler);
- ipcRenderer.on('handle_update', updateHandler);
- ipcRenderer.on('disconnect', sid => {
- const serial = serials[sid];
- serial ? delete serials[sid] : '';
- return;
- });
- loopDetectListChange();
|