547 lines
12 KiB
JavaScript
547 lines
12 KiB
JavaScript
|
|
'use strict';
|
|||
|
|
|
|||
|
|
const path = require('path');
|
|||
|
|
const fs = require('fs');
|
|||
|
|
const { exec } = require('child_process');
|
|||
|
|
const { Controller } = require('ee-core');
|
|||
|
|
const { app: electronApp, shell } = require('electron');
|
|||
|
|
const dayjs = require('dayjs');
|
|||
|
|
const Ps = require('ee-core/ps');
|
|||
|
|
const Log = require('ee-core/log');
|
|||
|
|
const Services = require('ee-core/services');
|
|||
|
|
const Conf = require('ee-core/config');
|
|||
|
|
const Addon = require('ee-core/addon');
|
|||
|
|
const EE = require('ee-core/ee');
|
|||
|
|
const { getNetworkIFaceOne, getMac, getAllMac, getAllPhysicsMac } = require('@lzwme/get-physical-address');
|
|||
|
|
const os = require('os');
|
|||
|
|
// 网络
|
|||
|
|
const net = require('net');
|
|||
|
|
// 串口
|
|||
|
|
const { SerialPort } = require('serialport')
|
|||
|
|
// 保存串口实例
|
|||
|
|
var GlobalSeriaPortIns = undefined;
|
|||
|
|
/**
|
|||
|
|
* electron-egg framework - 功能demo
|
|||
|
|
* @class
|
|||
|
|
*/
|
|||
|
|
class FrameworkController extends Controller {
|
|||
|
|
|
|||
|
|
constructor(ctx) {
|
|||
|
|
super(ctx);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 所有方法接收两个参数
|
|||
|
|
* @param args 前端传的参数
|
|||
|
|
* @param event - ipc通信时才有值。详情见:控制器文档
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 发送串口消息
|
|||
|
|
* @param {*} seriaPort 串口实例
|
|||
|
|
*/
|
|||
|
|
sendSeriaPort(args) {
|
|||
|
|
const port = GlobalSeriaPortIns;
|
|||
|
|
const msg = args.msg;
|
|||
|
|
port.write(msg, 'hex')
|
|||
|
|
// console.log('测试发送消息'+msg);
|
|||
|
|
}
|
|||
|
|
/**
|
|||
|
|
* 连接串口 只执行一次
|
|||
|
|
* @param {*} options 串口参数
|
|||
|
|
* @param {*} event 回调.
|
|||
|
|
*/
|
|||
|
|
connectSeriaPort(options, event) {
|
|||
|
|
|
|||
|
|
// 保证执行一次
|
|||
|
|
if (GlobalSeriaPortIns != undefined) {
|
|||
|
|
console.log("SerialPort is have");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const channel = 'controller.hardware.connectSeriaPort';
|
|||
|
|
const port = new SerialPort(options, (e) => {
|
|||
|
|
console.log("SerialPort open");
|
|||
|
|
console.log(e);
|
|||
|
|
if (e === null) {
|
|||
|
|
// 打开成功 把串口发送出去
|
|||
|
|
let data2 = {
|
|||
|
|
type: 'connect'
|
|||
|
|
}
|
|||
|
|
event.reply(`${channel}`, data2)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
port.on('data', (data) => {
|
|||
|
|
let data2 = {
|
|||
|
|
type: 'received',
|
|||
|
|
data: data
|
|||
|
|
}
|
|||
|
|
console.log(`Received data: ${data2}`)
|
|||
|
|
event.reply(`${channel}`, data2)
|
|||
|
|
})
|
|||
|
|
setInterval(() => {
|
|||
|
|
// console.log('setInterval')
|
|||
|
|
if (!port.isOpen) {
|
|||
|
|
// console.log('setInterval open')
|
|||
|
|
port.open();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}, 1000)
|
|||
|
|
port.on('close', () => {
|
|||
|
|
let data2 = {
|
|||
|
|
type: 'close'
|
|||
|
|
}
|
|||
|
|
console.log(`SerialPort close: ${data2}`)
|
|||
|
|
event.reply(`${channel}`, data2)
|
|||
|
|
})
|
|||
|
|
port.on('error', (e) => {
|
|||
|
|
let data2 = {
|
|||
|
|
type: 'error'
|
|||
|
|
}
|
|||
|
|
console.log(`SerialPort error: ${e}`)
|
|||
|
|
event.reply(`${channel}`, data2)
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
GlobalSeriaPortIns = port;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 发送tcp 消息
|
|||
|
|
* @param {*} args 包含host port msg type { 1 hex, 2 ascii}
|
|||
|
|
* @param {*} event
|
|||
|
|
*/
|
|||
|
|
sendTcpSocket(args, event) {
|
|||
|
|
const channel = 'controller.example.sendTcpSocket';
|
|||
|
|
console.log("tcp params")
|
|||
|
|
console.log(args);
|
|||
|
|
const client = new net.Socket();
|
|||
|
|
// client.setEncoding('ascii');
|
|||
|
|
const HOST = args.host;
|
|||
|
|
const PORT = args.port;
|
|||
|
|
const msg = args.msg;
|
|||
|
|
|
|||
|
|
// const HOST = '192.168.5.134';
|
|||
|
|
// const PORT = 9080;
|
|||
|
|
client.connect(PORT, HOST, function () {
|
|||
|
|
console.log('Connected to: ' + HOST + ':' + PORT);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
client.on('data', function (data) {
|
|||
|
|
console.log('Received: ' + data);
|
|||
|
|
event.sender.send(`${channel}`, data);
|
|||
|
|
});
|
|||
|
|
//两种码的发送 ok
|
|||
|
|
// client.write('Hello, server!','ascii');
|
|||
|
|
if (args.type == 1) {
|
|||
|
|
client.write(msg, 'hex');
|
|||
|
|
} else {
|
|||
|
|
client.write(msg, 'ascii');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
client.on('close', function () {
|
|||
|
|
console.log('Connection closed');
|
|||
|
|
});
|
|||
|
|
client.end();
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取extraResources 目录下的json 配置文件
|
|||
|
|
* @param {*} name 配置文件名
|
|||
|
|
* @returns 返回json 字符传
|
|||
|
|
*/
|
|||
|
|
getExResConfig(name) {
|
|||
|
|
let configPath = path.join(Ps.getExtraResourcesDir(), name);;
|
|||
|
|
|
|||
|
|
console.log(configPath)
|
|||
|
|
// let configJSON = null;
|
|||
|
|
let dataString = null;
|
|||
|
|
try {
|
|||
|
|
// 同步读取配置文件
|
|||
|
|
dataString = fs.readFileSync(configPath, 'utf8');
|
|||
|
|
|
|||
|
|
// 解析 JSON 格式的配置数据
|
|||
|
|
// configJSON = JSON.parse(data);
|
|||
|
|
// console.log('读取到的配置:', configJSON);
|
|||
|
|
|
|||
|
|
// 在这里可以根据需要使用配置数据进行操作
|
|||
|
|
} catch (err) {
|
|||
|
|
console.error('无法读取配置文件:', err);
|
|||
|
|
}
|
|||
|
|
return dataString;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* json数据库操作
|
|||
|
|
*/
|
|||
|
|
async jsondbOperation(args) {
|
|||
|
|
const { action, info, delete_name, update_name, update_age, search_age, data_dir } = args;
|
|||
|
|
|
|||
|
|
const data = {
|
|||
|
|
action,
|
|||
|
|
result: null,
|
|||
|
|
all_list: []
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
switch (action) {
|
|||
|
|
case 'add':
|
|||
|
|
data.result = await Services.get('database.jsondb').addTestData(info);
|
|||
|
|
break;
|
|||
|
|
case 'del':
|
|||
|
|
data.result = await Services.get('database.jsondb').delTestData(delete_name);
|
|||
|
|
break;
|
|||
|
|
case 'update':
|
|||
|
|
data.result = await Services.get('database.jsondb').updateTestData(update_name, update_age);
|
|||
|
|
break;
|
|||
|
|
case 'get':
|
|||
|
|
data.result = await Services.get('database.jsondb').getTestData(search_age);
|
|||
|
|
break;
|
|||
|
|
case 'getDataDir':
|
|||
|
|
data.result = await Services.get('database.jsondb').getDataDir();
|
|||
|
|
break;
|
|||
|
|
case 'setDataDir':
|
|||
|
|
data.result = await Services.get('database.jsondb').setCustomDataDir(data_dir);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
data.all_list = await Services.get('database.jsondb').getAllTestData();
|
|||
|
|
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* sqlite数据库操作
|
|||
|
|
*/
|
|||
|
|
async sqlitedbOperation(args) {
|
|||
|
|
const { action, info, delete_name, update_name, update_age, search_age, data_dir } = args;
|
|||
|
|
|
|||
|
|
const data = {
|
|||
|
|
action,
|
|||
|
|
result: null,
|
|||
|
|
all_list: [],
|
|||
|
|
code: 0
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
// test
|
|||
|
|
Services.get('database.sqlitedb').getDataDir();
|
|||
|
|
} catch (err) {
|
|||
|
|
console.log(err);
|
|||
|
|
data.code = -1;
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
switch (action) {
|
|||
|
|
case 'add':
|
|||
|
|
data.result = await Services.get('database.sqlitedb').addTestDataSqlite(info);;
|
|||
|
|
break;
|
|||
|
|
case 'del':
|
|||
|
|
data.result = await Services.get('database.sqlitedb').delTestDataSqlite(delete_name);;
|
|||
|
|
break;
|
|||
|
|
case 'update':
|
|||
|
|
data.result = await Services.get('database.sqlitedb').updateTestDataSqlite(update_name, update_age);
|
|||
|
|
break;
|
|||
|
|
case 'get':
|
|||
|
|
data.result = await Services.get('database.sqlitedb').getTestDataSqlite(search_age);
|
|||
|
|
break;
|
|||
|
|
case 'getDataDir':
|
|||
|
|
data.result = await Services.get('database.sqlitedb').getDataDir();
|
|||
|
|
break;
|
|||
|
|
case 'setDataDir':
|
|||
|
|
data.result = await Services.get('database.sqlitedb').setCustomDataDir(data_dir);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
data.all_list = await Services.get('database.sqlitedb').getAllTestDataSqlite();
|
|||
|
|
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 调用其它程序(exe、bash等可执行程序)
|
|||
|
|
*/
|
|||
|
|
openSoftware(softName) {
|
|||
|
|
if (!softName) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let softwarePath = path.join(Ps.getExtraResourcesDir(), softName);
|
|||
|
|
Log.info('[openSoftware] softwarePath:', softwarePath);
|
|||
|
|
|
|||
|
|
// 检查程序是否存在
|
|||
|
|
if (!fs.existsSync(softwarePath)) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
// 命令行字符串 并 执行
|
|||
|
|
let cmdStr = 'start ' + softwarePath;
|
|||
|
|
exec(cmdStr);
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查是否有新版本
|
|||
|
|
*/
|
|||
|
|
checkForUpdater() {
|
|||
|
|
Addon.get('autoUpdater').checkUpdate();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 下载新版本
|
|||
|
|
*/
|
|||
|
|
downloadApp() {
|
|||
|
|
Addon.get('autoUpdater').download();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检测http服务是否开启
|
|||
|
|
*/
|
|||
|
|
async checkHttpServer() {
|
|||
|
|
const httpServerConfig = Conf.getValue('httpServer');
|
|||
|
|
const url = httpServerConfig.protocol + httpServerConfig.host + ':' + httpServerConfig.port;
|
|||
|
|
|
|||
|
|
const data = {
|
|||
|
|
enable: httpServerConfig.enable,
|
|||
|
|
server: url
|
|||
|
|
}
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 一个http请求访问此方法
|
|||
|
|
*/
|
|||
|
|
async doHttpRequest() {
|
|||
|
|
const { CoreApp } = EE;
|
|||
|
|
// http方法
|
|||
|
|
const method = CoreApp.request.method;
|
|||
|
|
// http get 参数
|
|||
|
|
let params = CoreApp.request.query;
|
|||
|
|
params = (params instanceof Object) ? params : JSON.parse(JSON.stringify(params));
|
|||
|
|
// http post 参数
|
|||
|
|
const body = CoreApp.request.body;
|
|||
|
|
|
|||
|
|
const httpInfo = {
|
|||
|
|
method,
|
|||
|
|
params,
|
|||
|
|
body
|
|||
|
|
}
|
|||
|
|
Log.info('httpInfo:', httpInfo);
|
|||
|
|
|
|||
|
|
if (!body.id) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
const dir = electronApp.getPath(body.id);
|
|||
|
|
shell.openPath(dir);
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 一个socket io请求访问此方法
|
|||
|
|
*/
|
|||
|
|
async doSocketRequest(args) {
|
|||
|
|
if (!args.id) {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
const dir = electronApp.getPath(args.id);
|
|||
|
|
shell.openPath(dir);
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 异步消息类型
|
|||
|
|
*/
|
|||
|
|
async ipcInvokeMsg(args, event) {
|
|||
|
|
let timeNow = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
|||
|
|
const data = args + ' - ' + timeNow;
|
|||
|
|
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 同步消息类型
|
|||
|
|
*/
|
|||
|
|
async ipcSendSyncMsg(args) {
|
|||
|
|
let timeNow = dayjs().format('YYYY-MM-DD HH:mm:ss');
|
|||
|
|
const data = args + ' - ' + timeNow;
|
|||
|
|
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 双向异步通信
|
|||
|
|
*/
|
|||
|
|
async ipcSendMsg(args, event) {
|
|||
|
|
const { type, content } = args;
|
|||
|
|
const data = await Services.get('framework').bothWayMessage(type, content, event);
|
|||
|
|
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 不建议使用,请使用electron的api来获取文件的本机路径,然后读取并上传
|
|||
|
|
* 使用http的files属性,实际上多余拷贝一次文件
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
async uploadFile() {
|
|||
|
|
const { CoreApp } = EE;
|
|||
|
|
let tmpDir = Ps.getLogDir();
|
|||
|
|
const files = CoreApp.request.files;
|
|||
|
|
let file = files.file;
|
|||
|
|
|
|||
|
|
let tmpFilePath = path.join(tmpDir, file.originalFilename);
|
|||
|
|
try {
|
|||
|
|
let tmpFile = fs.readFileSync(file.filepath);
|
|||
|
|
fs.writeFileSync(tmpFilePath, tmpFile);
|
|||
|
|
} finally {
|
|||
|
|
await fs.unlink(file.filepath, function () { });
|
|||
|
|
}
|
|||
|
|
const fileStream = fs.createReadStream(tmpFilePath);
|
|||
|
|
const uploadRes = await Services.get('framework').uploadFileToSMMS(fileStream);
|
|||
|
|
|
|||
|
|
return uploadRes;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 启动java项目
|
|||
|
|
*/
|
|||
|
|
async startJavaServer() {
|
|||
|
|
let data = {
|
|||
|
|
code: 0,
|
|||
|
|
msg: '',
|
|||
|
|
server: ''
|
|||
|
|
}
|
|||
|
|
const javaCfg = Conf.getValue('addons.javaServer') || {};
|
|||
|
|
if (!javaCfg.enable) {
|
|||
|
|
data.code = -1;
|
|||
|
|
data.msg = 'addon not enabled!';
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
await Addon.get('javaServer').createServer();
|
|||
|
|
|
|||
|
|
data.server = 'http://localhost:' + javaCfg.port;
|
|||
|
|
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 关闭java项目
|
|||
|
|
*/
|
|||
|
|
async closeJavaServer() {
|
|||
|
|
let data = {
|
|||
|
|
code: 0,
|
|||
|
|
msg: '',
|
|||
|
|
}
|
|||
|
|
const javaCfg = Conf.getValue('addons.javaServer') || {};
|
|||
|
|
if (!javaCfg.enable) {
|
|||
|
|
data.code = -1;
|
|||
|
|
data.msg = 'addon not enabled!';
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
await Addon.get('javaServer').kill();
|
|||
|
|
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* java运行状态
|
|||
|
|
*/
|
|||
|
|
async runStatus() {
|
|||
|
|
let data = {
|
|||
|
|
code: 0,
|
|||
|
|
msg: '',
|
|||
|
|
flag: false
|
|||
|
|
}
|
|||
|
|
const flag = await Addon.get('javaServer').check();
|
|||
|
|
//Log.info("[FrameworkController:runStatus] flag-----------"+flag);
|
|||
|
|
data.flag = flag;
|
|||
|
|
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 任务
|
|||
|
|
*/
|
|||
|
|
someJob(args, event) {
|
|||
|
|
let jobId = args.id;
|
|||
|
|
let action = args.action;
|
|||
|
|
|
|||
|
|
let result;
|
|||
|
|
switch (action) {
|
|||
|
|
case 'create':
|
|||
|
|
result = Services.get('framework').doJob(jobId, action, event);
|
|||
|
|
break;
|
|||
|
|
case 'close':
|
|||
|
|
Services.get('framework').doJob(jobId, action, event);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let data = {
|
|||
|
|
jobId,
|
|||
|
|
action,
|
|||
|
|
result
|
|||
|
|
}
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 创建任务池
|
|||
|
|
*/
|
|||
|
|
async createPool(args, event) {
|
|||
|
|
let num = args.number;
|
|||
|
|
Services.get('framework').doCreatePool(num, event);
|
|||
|
|
|
|||
|
|
// test monitor
|
|||
|
|
Services.get('framework').monitorJob();
|
|||
|
|
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 通过进程池执行任务
|
|||
|
|
*/
|
|||
|
|
someJobByPool(args, event) {
|
|||
|
|
let jobId = args.id;
|
|||
|
|
let action = args.action;
|
|||
|
|
|
|||
|
|
let result;
|
|||
|
|
switch (action) {
|
|||
|
|
case 'run':
|
|||
|
|
result = Services.get('framework').doJobByPool(jobId, action, event);
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let data = {
|
|||
|
|
jobId,
|
|||
|
|
action,
|
|||
|
|
result
|
|||
|
|
}
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 测试接口
|
|||
|
|
*/
|
|||
|
|
hello(args) {
|
|||
|
|
Log.info('hello ', args);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FrameworkController.toString = () => '[class FrameworkController]';
|
|||
|
|
module.exports = FrameworkController;
|