Update: 更新socket工作模式
This commit is contained in:
@@ -1,20 +1,12 @@
|
|||||||
import os from 'node:os';
|
import os from 'node:os';
|
||||||
|
import CONFIG from '../user/config.json';
|
||||||
|
|
||||||
export const DEBUG = true;
|
|
||||||
export const ARDUINO = {
|
export const DEBUG = CONFIG.debug;
|
||||||
path: {
|
export const ARDUINO = CONFIG.arduino;
|
||||||
folder: 'D:/gitee/arduino-cli-win32/arduino-cli',
|
export const MICROPYTHON = CONFIG.micropython;
|
||||||
cli: 'D:/gitee/arduino-cli-win32/arduino-cli/arduino-cli.exe',
|
export const PYTHON = CONFIG.python;
|
||||||
libraries: ['D:/gitee/arduino-cli-win32/arduino-cli/libraries'],
|
|
||||||
cache: 'D:/gitee/arduino-cli-win32/arduino-cli/cache',
|
|
||||||
config: 'D:/gitee/arduino-cli-win32/arduino-cli/arduino-cli.json',
|
|
||||||
build: 'D:/gitee/mixly3-server/temp/web-socket',
|
|
||||||
code: ''
|
|
||||||
},
|
|
||||||
key: '',
|
|
||||||
port: '',
|
|
||||||
code: ''
|
|
||||||
};
|
|
||||||
export const CURRENT_PLANTFORM = os.platform();
|
export const CURRENT_PLANTFORM = os.platform();
|
||||||
export const WEB_SOCKT_TEMP_PATH = '';
|
export const WEB_SOCKT_TEMP_PATH = CONFIG.webSocketTempPath;
|
||||||
export const WEB_COMPILER_TEMP_PATH = '';
|
export const WEB_COMPILER_TEMP_PATH = CONFIG.webSocketTempPath;
|
||||||
|
export const CLIENT_PATH = CONFIG.clientPath;
|
||||||
26
src/common/mstring.js
Normal file
26
src/common/mstring.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
const MString = {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function 使用传入值替换字符串中{xxx}
|
||||||
|
* @param str {string} 传入字符串
|
||||||
|
* @param obj {object}
|
||||||
|
* obj = {
|
||||||
|
* xxx: value1,
|
||||||
|
* xxx: value2
|
||||||
|
* }
|
||||||
|
* 使用value替换{xxx}
|
||||||
|
* @return {string} 返回处理后的字符串
|
||||||
|
**/
|
||||||
|
MString.tpl = (str, obj) => {
|
||||||
|
if (!(typeof str === 'string' && obj instanceof Object)) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
for (let key in obj) {
|
||||||
|
let re = new RegExp(`{*${key}*}`, 'gim');
|
||||||
|
str = str.replace(re, obj[key]);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MString;
|
||||||
@@ -79,7 +79,7 @@ export default class Serial extends EventsBase {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.#serialport_.on('error', (error) => {
|
this.#serialport_.on('error', (error) => {
|
||||||
this.runEvent('error', error);
|
this.runEvent('error', error.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
this.#serialport_.on('open', () => {
|
this.#serialport_.on('open', () => {
|
||||||
@@ -121,7 +121,7 @@ export default class Serial extends EventsBase {
|
|||||||
this.#addEventsListener_();
|
this.#addEventsListener_();
|
||||||
this.#serialport_.open((error) => {
|
this.#serialport_.open((error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error.toString());
|
||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ export default class Serial extends EventsBase {
|
|||||||
}
|
}
|
||||||
this.#serialport_.close((error) => {
|
this.#serialport_.close((error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error.toString());
|
||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
@@ -153,7 +153,7 @@ export default class Serial extends EventsBase {
|
|||||||
}
|
}
|
||||||
this.#serialport_.update({ baudRate: baud }, (error) => {
|
this.#serialport_.update({ baudRate: baud }, (error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error.toString());
|
||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,7 @@ export default class Serial extends EventsBase {
|
|||||||
}
|
}
|
||||||
this.#serialport_.write(data, (error) => {
|
this.#serialport_.write(data, (error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error.toString());
|
||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ export default class Serial extends EventsBase {
|
|||||||
}
|
}
|
||||||
this.#serialport_.set({ dtr, rts }, (error) => {
|
this.#serialport_.set({ dtr, rts }, (error) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(error);
|
reject(error.toString());
|
||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import path from 'node:path';
|
||||||
|
import Shell from './shell';
|
||||||
|
import MString from './mstring';
|
||||||
|
import { MICROPYTHON, PYTHON, CLIENT_PATH } from './config';
|
||||||
|
|
||||||
|
|
||||||
|
export default class ShellMicroPython extends Shell {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
async burn(config) {
|
||||||
|
const info = {
|
||||||
|
indexPath: path.resolve(CLIENT_PATH, config.boardDirPath),
|
||||||
|
esptool: `${PYTHON.path.cli}" "${MICROPYTHON.path.esptool}`,
|
||||||
|
com: config.port
|
||||||
|
};
|
||||||
|
const command = MString.tpl(config.command, info);
|
||||||
|
return this.exec(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
async upload(config) {
|
||||||
|
const info = {
|
||||||
|
indexPath: path.resolve(CLIENT_PATH, config.boardDirPath),
|
||||||
|
ampy: `${PYTHON.path.cli}" "${MICROPYTHON.path.ampy}`,
|
||||||
|
com: config.port
|
||||||
|
};
|
||||||
|
const command = MString.tpl(config.command, info);
|
||||||
|
return this.exec(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
import { execFile, exec } from 'node:child_process';
|
import { execFile, exec } from 'node:child_process';
|
||||||
import * as iconv_lite from 'iconv-lite';
|
import * as iconv_lite from 'iconv-lite';
|
||||||
// import duration from 'dayjs/plugin/duration';
|
|
||||||
import Debug from './debug';
|
import Debug from './debug';
|
||||||
import EventsBase from './events-base';
|
import EventsBase from './events-base';
|
||||||
import { CURRENT_PLANTFORM } from './config';
|
import { CURRENT_PLANTFORM } from './config';
|
||||||
@@ -52,7 +51,7 @@ export default class Shell extends EventsBase {
|
|||||||
lines[i] = iconv_lite.decode(Buffer.from(lines[i], 'binary'), encoding);
|
lines[i] = iconv_lite.decode(Buffer.from(lines[i], 'binary'), encoding);
|
||||||
}
|
}
|
||||||
data = lines.join('\n');
|
data = lines.join('\n');
|
||||||
data = this.#decode_(data);
|
// data = this.#decode_(data);
|
||||||
this.runEvent('error', data);
|
this.runEvent('error', data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"debug": true,
|
||||||
|
"arduino": {
|
||||||
|
"path": {
|
||||||
|
"folder": "D:/gitee/mixly/arduino-cli",
|
||||||
|
"cli": "D:/gitee/mixly/arduino-cli/arduino-cli.exe",
|
||||||
|
"libraries": [
|
||||||
|
"D:/gitee/mixly/arduino-cli/libraries"
|
||||||
|
],
|
||||||
|
"cache": "D:/gitee/mixly/arduino-cli/cache",
|
||||||
|
"config": "D:/gitee/mixly/arduino-cli/arduino-cli.json"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"micropython": {
|
||||||
|
"path": {
|
||||||
|
"ampy": "D:/gitee/mixly3-resource/mixly3.0-win32-x64/resources/app/src/tools/python/ampy/cli.py",
|
||||||
|
"esptool": "D:/gitee/mixly3-resource/mixly3.0-win32-x64/resources/app/src/tools/python/esptool/__init__.py"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"python": {
|
||||||
|
"path": {
|
||||||
|
"cli": "D:/gitee/mixly3-resource/mixly3.0-win32-x64/mixpyBuild/win_python3/python3.exe"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webSocketTempPath": "D:/gitee/mixly3-resource/mixly3-server/temp/web-socket",
|
||||||
|
"webCompilerTempPath": "D:/gitee/mixly3-resource/mixly3-server/temp/web-compiler",
|
||||||
|
"clientPath": "D:/gitee/mixly3-resource/mixly3.0-win32-x64/resources/app/src"
|
||||||
|
}
|
||||||
@@ -3,17 +3,19 @@ import to from 'await-to-js';
|
|||||||
import { usb } from 'usb';
|
import { usb } from 'usb';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import fsExtra from 'fs-extra';
|
import fsExtra from 'fs-extra';
|
||||||
import fsPlus from 'fs-plus';
|
|
||||||
import Serial from '../common/serial';
|
import Serial from '../common/serial';
|
||||||
import Debug from '../common/debug';
|
import Debug from '../common/debug';
|
||||||
import Registry from '../common/registry';
|
import Registry from '../common/registry';
|
||||||
import ShellArduino from '../common/shell-arduino';
|
import ShellArduino from '../common/shell-arduino';
|
||||||
import { ARDUINO } from '../common/config';
|
import ShellMicroPython from '../common/shell-micropython';
|
||||||
|
import MString from '../common/mstring';
|
||||||
|
import { WEB_SOCKT_TEMP_PATH, CLIENT_PATH } from '../common/config';
|
||||||
|
|
||||||
|
|
||||||
export default class Socket {
|
export default class Socket {
|
||||||
#io_ = null;
|
#io_ = null;
|
||||||
#serialRegistry_ = new Registry();
|
#serialRegistry_ = new Registry();
|
||||||
|
#shellMicroPython_ = new ShellMicroPython();
|
||||||
#shellArduino_ = new ShellArduino();
|
#shellArduino_ = new ShellArduino();
|
||||||
|
|
||||||
constructor(httpsServer, options) {
|
constructor(httpsServer, options) {
|
||||||
@@ -29,6 +31,60 @@ export default class Socket {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#addEventsListener_(socket) {
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
for (let key of this.#serialRegistry_.keys()) {
|
||||||
|
const serial = this.#serialRegistry_.getItem(key);
|
||||||
|
serial.dispose().catch(Debug.error);
|
||||||
|
this.#serialRegistry_.unregister(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.#addEventsListenerForMicroPython_(socket);
|
||||||
|
this.#addEventsListenerForArduino_(socket);
|
||||||
|
this.#addEventsListenerForSerial_(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
#addEventsListenerForMicroPython_(socket) {
|
||||||
|
this.#shellMicroPython_.bind('data', (data) => {
|
||||||
|
socket.emit('arduino.dataEvent', data);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.#shellMicroPython_.bind('error', (data) => {
|
||||||
|
socket.emit('arduino.errorEvent', data);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.#shellMicroPython_.bind('close', (code, time) => {
|
||||||
|
socket.emit('arduino.closeEvent', code, time);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('micropython.burn', async (config, callback) => {
|
||||||
|
const [error, result] = await to(this.#shellMicroPython_.burn(config));
|
||||||
|
error && Debug.error(error);
|
||||||
|
callback([error, result]);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('micropython.upload', async (config, callback) => {
|
||||||
|
let { filePath = '' } = config;
|
||||||
|
filePath = MString.tpl(filePath, {
|
||||||
|
indexPath: path.resolve(CLIENT_PATH, config.boardDirPath)
|
||||||
|
});
|
||||||
|
let [error1,] = await to(fsExtra.ensureDir(path.dirname(filePath)));
|
||||||
|
error1 && Debug.error(error1);
|
||||||
|
let [error2,] = await to(fsExtra.outputFile(filePath, config.code));
|
||||||
|
error2 && Debug.error(error2);
|
||||||
|
const [error, result] = await to(this.#shellMicroPython_.upload(config));
|
||||||
|
error && Debug.error(error);
|
||||||
|
callback([error, result]);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('micropython.kill', async (callback) => {
|
||||||
|
const [error, result] = await to(this.#shellMicroPython_.kill());
|
||||||
|
error && Debug.error(error);
|
||||||
|
callback([error, result]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#addEventsListenerForArduino_(socket) {
|
#addEventsListenerForArduino_(socket) {
|
||||||
this.#shellArduino_.bind('data', (data) => {
|
this.#shellArduino_.bind('data', (data) => {
|
||||||
socket.emit('arduino.dataEvent', data);
|
socket.emit('arduino.dataEvent', data);
|
||||||
@@ -43,11 +99,9 @@ export default class Socket {
|
|||||||
});
|
});
|
||||||
|
|
||||||
socket.on('arduino.compile', async (config, callback) => {
|
socket.on('arduino.compile', async (config, callback) => {
|
||||||
let { build } = ARDUINO.path;
|
|
||||||
let user = path.resolve(build, socket.id);
|
|
||||||
config.path = config?.path ?? {};
|
config.path = config?.path ?? {};
|
||||||
config.path.build = path.resolve(user, 'build');
|
config.path.build = path.resolve(WEB_SOCKT_TEMP_PATH, 'build');
|
||||||
config.path.code = path.resolve(user, 'testArduino/testArduino.ino');
|
config.path.code = path.resolve(WEB_SOCKT_TEMP_PATH, 'testArduino/testArduino.ino');
|
||||||
let [error1,] = await to(fsExtra.ensureDir(config.path.build));
|
let [error1,] = await to(fsExtra.ensureDir(config.path.build));
|
||||||
error1 && Debug.error(error1);
|
error1 && Debug.error(error1);
|
||||||
let [error2,] = await to(fsExtra.outputFile(config.path.code, config.code));
|
let [error2,] = await to(fsExtra.outputFile(config.path.code, config.code));
|
||||||
@@ -58,11 +112,9 @@ export default class Socket {
|
|||||||
});
|
});
|
||||||
|
|
||||||
socket.on('arduino.upload', async (config, callback) => {
|
socket.on('arduino.upload', async (config, callback) => {
|
||||||
let { build } = ARDUINO.path;
|
|
||||||
let user = path.resolve(build, socket.id);
|
|
||||||
config.path = config?.path ?? {};
|
config.path = config?.path ?? {};
|
||||||
config.path.build = path.resolve(user, 'build');
|
config.path.build = path.resolve(WEB_SOCKT_TEMP_PATH, 'build');
|
||||||
config.path.code = path.resolve(user, 'testArduino/testArduino.ino');
|
config.path.code = path.resolve(WEB_SOCKT_TEMP_PATH, 'testArduino/testArduino.ino');
|
||||||
let [error1,] = await to(fsExtra.ensureDir(config.path.build));
|
let [error1,] = await to(fsExtra.ensureDir(config.path.build));
|
||||||
error1 && Debug.error(error1);
|
error1 && Debug.error(error1);
|
||||||
let [error2,] = await to(fsExtra.outputFile(config.path.code, config.code));
|
let [error2,] = await to(fsExtra.outputFile(config.path.code, config.code));
|
||||||
@@ -150,24 +202,6 @@ export default class Socket {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#addEventsListener_(socket) {
|
|
||||||
socket.on('disconnect', () => {
|
|
||||||
let { build } = ARDUINO.path;
|
|
||||||
let user = path.resolve(build, socket.id);
|
|
||||||
if (fsPlus.isDirectorySync(user)) {
|
|
||||||
fsExtra.remove(user);
|
|
||||||
}
|
|
||||||
for (let key of this.#serialRegistry_.keys()) {
|
|
||||||
const serial = this.#serialRegistry_.getItem(key);
|
|
||||||
serial.dispose().catch(Debug.error);
|
|
||||||
this.#serialRegistry_.unregister(key);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.#addEventsListenerForArduino_(socket);
|
|
||||||
this.#addEventsListenerForSerial_(socket);
|
|
||||||
}
|
|
||||||
|
|
||||||
getIO() {
|
getIO() {
|
||||||
return this.#io_;
|
return this.#io_;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user