Files
mixly3/common/modules/mixly-modules/electron/serial.js

263 lines
7.1 KiB
JavaScript

goog.loadJs('electron', () => {
goog.require('layui');
goog.require('Mixly.Serial');
goog.require('Mixly.Env');
goog.require('Mixly.Msg');
goog.require('Mixly.Debug');
goog.require('Mixly.MArray');
goog.require('Mixly.Electron');
goog.provide('Mixly.Electron.Serial');
const child_process = Mixly.require('node:child_process');
const serialport = Mixly.require('serialport');
const {
SerialPort,
ReadlineParser,
ByteLengthParser
} = serialport;
const {
Serial,
Env,
Msg,
Debug,
MArray,
Electron
} = Mixly;
const { form } = layui;
class ElectronSerial extends Serial {
static {
this.getConfig = function () {
return Serial.getConfig();
}
this.getSelectedPortName = function () {
return Serial.getSelectedPortName();
}
this.getCurrentPortsName = function () {
return Serial.getCurrentPortsName();
}
this.getPorts = async function () {
return new Promise((resolve, reject) => {
if (Env.currentPlatform === 'linux') {
child_process.exec('ls /dev/ttyACM* /dev/tty*USB*', (err, stdout, stderr) => {
let portsName = MArray.unique(stdout.split('\n'));
let newPorts = [];
for (let i = 0; i < portsName.length; i++) {
if (!portsName[i]) {
continue;
}
newPorts.push({
vendorId: 'None',
productId: 'None',
name: portsName[i]
});
}
resolve(newPorts);
});
} else {
SerialPort.list().then(ports => {
let newPorts = [];
for (let i = 0; i < ports.length; i++) {
let port = ports[i];
newPorts.push({
vendorId: port.vendorId,
productId: port.productId,
name: port.path
});
}
resolve(newPorts);
}).catch(reject);
}
});
}
this.refreshPorts = function () {
this.getPorts()
.then((ports) => {
Serial.renderSelectBox(ports);
})
.catch(Debug.error);
}
}
#serialport_ = null;
#parserBytes_ = null;
#parserLine_ = null;
constructor(port) {
super(port);
}
#addEventsListener_() {
this.#parserBytes_.on('data', (buffer) => {
this.onBuffer(buffer);
});
this.#parserLine_.on('data', (str) => {
this.onString(str);
});
this.#serialport_.on('error', (error) => {
this.onError(error);
this.onClose(1);
});
this.#serialport_.on('open', () => {
this.onOpen();
});
this.#serialport_.on('close', () => {
this.onClose(1);
});
}
async open(baud) {
return new Promise((resolve, reject) => {
const portsName = Serial.getCurrentPortsName();
const currentPort = this.getPortName();
if (!portsName.includes(currentPort)) {
reject('无可用串口');
return;
}
if (this.isOpened()) {
resolve();
return;
}
baud = baud ?? this.getBaudRate();
this.#serialport_ = new SerialPort({
path: currentPort,
baudRate: baud, // 波特率
dataBits: 8, // 数据位
parity: 'none', // 奇偶校验
stopBits: 1, // 停止位
flowControl: false,
autoOpen: false // 不自动打开
}, false);
this.#parserBytes_ = this.#serialport_.pipe(new ByteLengthParser({ length: 1 }));
this.#parserLine_ = this.#serialport_.pipe(new ReadlineParser());
this.#serialport_.open((error) => {
if (error) {
this.onError(error);
reject(error);
} else {
super.open(baud);
this.setBaudRate(baud);
resolve();
}
});
this.#addEventsListener_();
});
}
async close() {
return new Promise((resolve, reject) => {
if (!this.isOpened()) {
resolve();
return;
}
super.close();
this.#serialport_.close((error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
async setBaudRate(baud) {
return new Promise((resolve, reject) => {
if (!this.isOpened()
|| this.getBaudRate() === baud
|| !this.baudRateIsLegal(baud)) {
resolve();
return;
}
this.#serialport_.update({ baudRate: baud }, (error) => {
if (error) {
reject(error);
return;
}
super.setBaudRate(baud);
this.setDTRAndRTS(this.getDTR(), this.getRTS()).finally(resolve);
});
});
}
async send(data) {
return new Promise((resolve, reject) => {
if (!this.isOpened()) {
resolve();
return;
}
this.#serialport_.write(data, (error) => {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
async sendString(str) {
return this.send(str);
}
async sendBuffer(buffer) {
return this.send(buffer);
}
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();
}
});
});
}
async setDTR(dtr) {
return this.setDTRAndRTS(dtr, this.getRTS());
}
async setRTS(rts) {
return this.setDTRAndRTS(this.getDTR(), rts);
}
onBuffer(buffer) {
super.onBuffer(buffer);
for (let i = 0; i < buffer.length; i++) {
super.onByte(buffer[i]);
}
const string = this.decodeBuffer(buffer);
if (!string) {
return;
}
for (let char of string) {
super.onChar(char);
}
}
}
Electron.Serial = ElectronSerial;
});