Update: WebSocket模式添加对Serial和Arduino编译上传的支持
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import os from 'node:os';
|
||||
import { ChildProcess } from 'node:child_process';
|
||||
import { exec } from 'node:child_process';
|
||||
import {
|
||||
SerialPort,
|
||||
ReadlineParser,
|
||||
ByteLengthParser
|
||||
} from 'serialport';
|
||||
import _ from 'lodash';
|
||||
import EventsBase from './events-base';
|
||||
import { CURRENT_PLANTFORM } from './config';
|
||||
|
||||
|
||||
export default class Serial extends EventsBase {
|
||||
@@ -18,17 +19,17 @@ export default class Serial extends EventsBase {
|
||||
|
||||
this.getPorts = async function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (os.platform() === 'linux') {
|
||||
ChildProcess.exec('ls /dev/ttyACM* /dev/tty*USB*', (_, stdout, stderr) => {
|
||||
let portsName = MArray.unique(stdout.split('\n'));
|
||||
if (CURRENT_PLANTFORM === 'linux') {
|
||||
exec('ls /dev/ttyACM* /dev/tty*USB*', (error, stdout) => {
|
||||
let portsName = _.uniq(stdout.split('\n'));
|
||||
let newPorts = [];
|
||||
for (let i = 0; i < portsName.length; i++) {
|
||||
if (!portsName[i]) {
|
||||
continue;
|
||||
}
|
||||
newPorts.push({
|
||||
vendorId: 'None',
|
||||
productId: 'None',
|
||||
vendorId: null,
|
||||
productId: null,
|
||||
name: portsName[i]
|
||||
});
|
||||
}
|
||||
@@ -56,19 +57,25 @@ export default class Serial extends EventsBase {
|
||||
#parserBytes_ = null;
|
||||
#parserLine_ = null;
|
||||
#port_ = null;
|
||||
#isOpened_ = false;
|
||||
|
||||
constructor(port) {
|
||||
super();
|
||||
this.#port_ = port;
|
||||
this.addEventsType(['buffer', 'String', 'error', 'open', 'close']);
|
||||
this.addEventsType(['buffer', 'string', 'error', 'open', 'close']);
|
||||
}
|
||||
|
||||
#addEventsListener_() {
|
||||
this.#parserBytes_.on('data', (buffer) => {
|
||||
this.runEvent('buffer', buffer);
|
||||
const arr = [];
|
||||
for (let i = 0; i < buffer.length; i++) {
|
||||
arr.push(buffer[i]);
|
||||
}
|
||||
this.runEvent('buffer', arr);
|
||||
});
|
||||
|
||||
this.#parserLine_.on('data', (str) => {
|
||||
this.runEvent('String', str);
|
||||
this.runEvent('string', str);
|
||||
});
|
||||
|
||||
this.#serialport_.on('error', (error) => {
|
||||
@@ -76,31 +83,42 @@ export default class Serial extends EventsBase {
|
||||
});
|
||||
|
||||
this.#serialport_.on('open', () => {
|
||||
this.#isOpened_ = true;
|
||||
this.runEvent('open');
|
||||
});
|
||||
|
||||
this.#serialport_.on('close', () => {
|
||||
this.#isOpened_ = false;
|
||||
this.runEvent('close');
|
||||
});
|
||||
}
|
||||
|
||||
isOpened() {
|
||||
return this.#isOpened_;
|
||||
}
|
||||
|
||||
getPortName() {
|
||||
return this.#port_;
|
||||
}
|
||||
|
||||
async open(baud) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.isOpened()) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
this.#serialport_ = new SerialPort({
|
||||
path: this.getPortName(),
|
||||
baudRate: baud, // 波特率
|
||||
dataBits: 8, // 数据位
|
||||
parity: 'none', // 奇偶校验
|
||||
stopBits: 1, // 停止位
|
||||
baudRate: baud,
|
||||
dataBits: 8,
|
||||
parity: 'none',
|
||||
stopBits: 1,
|
||||
flowControl: false,
|
||||
autoOpen: false // 不自动打开
|
||||
autoOpen: false
|
||||
}, false);
|
||||
this.#parserBytes_ = this.#serialport_.pipe(new ByteLengthParser({ length: 1 }));
|
||||
this.#parserLine_ = this.#serialport_.pipe(new ReadlineParser());
|
||||
this.#addEventsListener_();
|
||||
this.#serialport_.open((error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
@@ -108,12 +126,15 @@ export default class Serial extends EventsBase {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
this.#addEventsListener_();
|
||||
});
|
||||
}
|
||||
|
||||
async close() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isOpened()) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
this.#serialport_.close((error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
@@ -126,18 +147,26 @@ export default class Serial extends EventsBase {
|
||||
|
||||
async setBaudRate(baud) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isOpened()) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
this.#serialport_.update({ baudRate: baud }, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async send(data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isOpened()) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
this.#serialport_.write(data, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
@@ -150,18 +179,22 @@ export default class Serial extends EventsBase {
|
||||
|
||||
async setDTRAndRTS(dtr, rts) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isOpened()) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
this.#serialport_.set({ dtr, rts }, (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
super.setDTRAndRTS(dtr, rts);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
dispose() {
|
||||
async dispose() {
|
||||
await this.close();
|
||||
this.disposeEvent();
|
||||
this.#serialport_ = null;
|
||||
this.#parserBytes_ = null;
|
||||
|
||||
Reference in New Issue
Block a user