mirror of
https://git.mirrors.martin98.com/https://github.com/luc-github/ESP3D.git
synced 2025-07-29 18:12:00 +08:00
687 lines
22 KiB
JavaScript
687 lines
22 KiB
JavaScript
const express = require("express");
|
|
const chalk = require("chalk");
|
|
let path = require("path");
|
|
const fs = require("fs");
|
|
const port = 8080;
|
|
/*
|
|
* Web Server for development
|
|
* Web Socket server for development
|
|
*/
|
|
const wscolor = chalk.cyan;
|
|
const expresscolor = chalk.green;
|
|
const commandcolor = chalk.white;
|
|
const WebSocket = require("ws");
|
|
let currentID = 0;
|
|
const app = express();
|
|
const fileUpload = require("express-fileupload");
|
|
let serverpath = path.normalize(__dirname + "/../server/public/");
|
|
let sdpath = path.normalize(__dirname + "/../server/sd/");
|
|
|
|
let WebSocketServer = require("ws").Server,
|
|
wss = new WebSocketServer({
|
|
port: 81,
|
|
handleProtocols: function (protocol) {
|
|
console.log("protocol received from client " + protocol);
|
|
return "webui-v3";
|
|
return null;
|
|
},
|
|
});
|
|
app.use(fileUpload({ preserveExtension: true, debug: false }));
|
|
app.listen(port, () =>
|
|
console.log(expresscolor(`[express] Listening on port ${port}!`))
|
|
);
|
|
|
|
//app.use(express.urlencoded({ extended: false }));
|
|
|
|
function SendBinary(text) {
|
|
const array = new Uint8Array(text.length);
|
|
for (let i = 0; i < array.length; ++i) {
|
|
array[i] = text.charCodeAt(i);
|
|
}
|
|
wss.clients.forEach(function each(client) {
|
|
if (client.readyState === WebSocket.OPEN) {
|
|
client.send(array);
|
|
}
|
|
});
|
|
}
|
|
|
|
app.post("/login", function (req, res) {
|
|
res.send("");
|
|
return;
|
|
});
|
|
|
|
app.get("/config", function (req, res) {
|
|
res.send(
|
|
"chip id: 56398\nCPU Freq: 240 Mhz<br/>" +
|
|
"CPU Temp: 58.3 C<br/>" +
|
|
"free mem: 212.36 KB<br/>" +
|
|
"SDK: v3.2.3-14-gd3e562907<br/>" +
|
|
"flash size: 4.00 MB<br/>" +
|
|
"size for update: 1.87 MB<br/>" +
|
|
"FS type: LittleFS<br/>" +
|
|
"FS usage: 104.00 KB/192.00 KB<br/>" +
|
|
"baud: 115200<br/>" +
|
|
"sleep mode: none<br/>" +
|
|
"wifi: ON<br/>" +
|
|
"hostname: esp3d<br/>" +
|
|
"HTTP port: 80<br/>" +
|
|
"Telnet port: 23<br/>" +
|
|
"WebDav port: 8383<br/>" +
|
|
"sta: ON<br/>" +
|
|
"mac: 80:7D:3A:C4:4E:DC<br/>" +
|
|
"SSID: WIFI_OFFICE_A2G<br/>" +
|
|
"signal: 100 %<br/>" +
|
|
"phy mode: 11n<br/>" +
|
|
"channel: 11<br/>" +
|
|
"ip mode: dhcp<br/>" +
|
|
"ip: 192.168.1.61<br/>" +
|
|
"gw: 192.168.1.1<br/>" +
|
|
"msk: 255.255.255.0<br/>" +
|
|
"DNS: 192.168.1.1<br/>" +
|
|
"ap: OFF<br/>" +
|
|
"mac: 80:7D:3A:C4:4E:DD<br/>" +
|
|
"serial: ON<br/>" +
|
|
"notification: OFF<br/>" +
|
|
"Target Fw: repetier<br/>" +
|
|
"FW ver: 3.0.0.a91<br/>" +
|
|
"FW arch: ESP32 "
|
|
);
|
|
return;
|
|
});
|
|
|
|
app.get("/command", function (req, res) {
|
|
console.log(commandcolor(`[server]/command params: ${req.query.cmd}`));
|
|
let url = req.query.cmd;
|
|
if (url.startsWith("[ESP800]json")) {
|
|
res.json({
|
|
cmd: "800",
|
|
status: "ok",
|
|
data: {
|
|
FWVersion: "3.0.0.a28",
|
|
FWTarget: 40,
|
|
SDConnection: "none",
|
|
Authentication: "Disabled",
|
|
WebCommunication: "Synchronous",
|
|
WebSocketIP: "localhost",
|
|
WebSocketPort: "81",
|
|
Hostname: "esp3d",
|
|
WiFiMode: "STA",
|
|
WebUpdate: "Enabled",
|
|
FlashFileSystem: "LittleFs",
|
|
HostPath: "/",
|
|
Time: "none",
|
|
Cam_ID: "4",
|
|
Cam_name: "ESP32 Cam",
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
if (url.indexOf("ESP111") != -1) {
|
|
res.send("192.168.1.111");
|
|
return;
|
|
}
|
|
if (url.indexOf("ESP420") != -1) {
|
|
res.json({
|
|
Status: [
|
|
{ id: "chip id", value: "38078" },
|
|
{ id: "CPU Freq", value: "240 Mhz" },
|
|
{ id: "CPU Temp", value: "50.6 C" },
|
|
{ id: "free mem", value: "217.50 KB" },
|
|
{ id: "SDK", value: "v3.3.1-61-g367c3c09c" },
|
|
{ id: "flash size", value: "4.00 MB" },
|
|
{ id: "size for update", value: "1.87 MB" },
|
|
{ id: "FS type", value: "SPIFFS" },
|
|
{ id: "FS usage", value: "39.95 KB/169.38 KB" },
|
|
{ id: "baud", value: "115200" },
|
|
{ id: "sleep mode", value: "none" },
|
|
{ id: "wifi", value: "ON" },
|
|
{ id: "hostname", value: "esp3d" },
|
|
{ id: "HTTP port", value: "80" },
|
|
{ id: "Telnet port", value: "23" },
|
|
{ id: "Ftp ports", value: "21, 20, 55600" },
|
|
{ id: "sta", value: "ON" },
|
|
{ id: "mac", value: "30:AE:A4:21:BE:94" },
|
|
{ id: "SSID", value: "WIFI_OFFICE_B2G" },
|
|
{ id: "signal", value: "100 %" },
|
|
{ id: "phy mode", value: "11n" },
|
|
{ id: "channel", value: "2" },
|
|
{ id: "ip mode", value: "dhcp" },
|
|
{ id: "ip", value: "192.168.1.43" },
|
|
{ id: "gw", value: "192.168.1.1" },
|
|
{ id: "msk", value: "255.255.255.0" },
|
|
{ id: "DNS", value: "192.168.1.1" },
|
|
{ id: "ap", value: "OFF" },
|
|
{ id: "mac", value: "30:AE:A4:21:BE:95" },
|
|
{ id: "serial", value: "ON" },
|
|
{ id: "notification", value: "OFF" },
|
|
{ id: "FW ver", value: "3.0.0.a28" },
|
|
{ id: "FW arch", value: "ESP32" },
|
|
],
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (url.indexOf("ESP410") != -1) {
|
|
res.json({
|
|
AP_LIST: [
|
|
{
|
|
SSID: "HP-Setup>71-M277 LaserJet",
|
|
SIGNAL: "92",
|
|
IS_PROTECTED: "0",
|
|
},
|
|
{ SSID: "WIFI_OFFICE_B2G", SIGNAL: "88", IS_PROTECTED: "1" },
|
|
{ SSID: "NETGEAR70", SIGNAL: "66", IS_PROTECTED: "1" },
|
|
{ SSID: "ZenFone6'luc", SIGNAL: "48", IS_PROTECTED: "1" },
|
|
{ SSID: "Livebox-EF01", SIGNAL: "20", IS_PROTECTED: "1" },
|
|
{ SSID: "orange", SIGNAL: "20", IS_PROTECTED: "0" },
|
|
],
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (url.indexOf("ESP400") != -1) {
|
|
res.json({
|
|
Settings: [
|
|
{
|
|
F: "network/network",
|
|
P: "130",
|
|
T: "S",
|
|
V: "esp3d",
|
|
H: "hostname",
|
|
S: "32",
|
|
M: "1",
|
|
},
|
|
{
|
|
F: "network/network",
|
|
P: "0",
|
|
T: "B",
|
|
V: "1",
|
|
H: "radio mode",
|
|
O: [{ none: "0" }, { sta: "1" }, { ap: "2" }],
|
|
},
|
|
{
|
|
F: "network/sta",
|
|
P: "1",
|
|
T: "S",
|
|
V: "WIFI_OFFICE_B2G",
|
|
S: "32",
|
|
H: "SSID",
|
|
M: "1",
|
|
},
|
|
{
|
|
F: "network/sta",
|
|
P: "34",
|
|
T: "S",
|
|
N: "1",
|
|
V: "********",
|
|
S: "64",
|
|
H: "pwd",
|
|
M: "8",
|
|
},
|
|
{
|
|
F: "network/sta",
|
|
P: "99",
|
|
T: "B",
|
|
V: "1",
|
|
H: "ip mode",
|
|
O: [{ dhcp: "1" }, { static: "0" }],
|
|
},
|
|
{
|
|
F: "network/sta",
|
|
P: "100",
|
|
T: "A",
|
|
V: "192.168.0.1",
|
|
H: "ip",
|
|
},
|
|
{
|
|
F: "network/sta",
|
|
P: "108",
|
|
T: "A",
|
|
V: "192.168.0.1",
|
|
H: "gw",
|
|
},
|
|
{
|
|
F: "network/sta",
|
|
P: "104",
|
|
T: "A",
|
|
V: "255.255.255.0",
|
|
H: "msk",
|
|
},
|
|
{
|
|
F: "network/ap",
|
|
P: "218",
|
|
T: "S",
|
|
V: "ESP3D",
|
|
S: "32",
|
|
H: "SSID",
|
|
M: "1",
|
|
},
|
|
{
|
|
F: "network/ap",
|
|
P: "251",
|
|
T: "S",
|
|
N: "1",
|
|
V: "********",
|
|
S: "64",
|
|
H: "pwd",
|
|
M: "8",
|
|
},
|
|
{
|
|
F: "network/ap",
|
|
P: "316",
|
|
T: "A",
|
|
V: "192.168.0.1",
|
|
H: "ip",
|
|
},
|
|
{
|
|
F: "network/ap",
|
|
P: "118",
|
|
T: "B",
|
|
V: "11",
|
|
H: "channel",
|
|
O: [
|
|
{ 1: "1" },
|
|
{ 2: "2" },
|
|
{ 3: "3" },
|
|
{ 4: "4" },
|
|
{ 5: "5" },
|
|
{ 6: "6" },
|
|
{ 7: "7" },
|
|
{ 8: "8" },
|
|
{ 9: "9" },
|
|
{ 10: "10" },
|
|
{ 11: "11" },
|
|
{ 12: "12" },
|
|
{ 13: "13" },
|
|
{ 14: "14" },
|
|
],
|
|
},
|
|
{
|
|
F: "service/http",
|
|
P: "328",
|
|
T: "B",
|
|
V: "1",
|
|
H: "enable",
|
|
O: [{ no: "0" }, { yes: "1" }],
|
|
},
|
|
{
|
|
F: "service/http",
|
|
P: "121",
|
|
T: "I",
|
|
V: "80",
|
|
H: "port",
|
|
S: "65001",
|
|
M: "1",
|
|
},
|
|
{
|
|
F: "service/telnetp",
|
|
P: "329",
|
|
T: "B",
|
|
V: "1",
|
|
H: "enable",
|
|
O: [{ no: "0" }, { yes: "1" }],
|
|
},
|
|
{
|
|
F: "service/telnetp",
|
|
P: "125",
|
|
T: "I",
|
|
V: "23",
|
|
H: "port",
|
|
S: "65001",
|
|
M: "1",
|
|
},
|
|
{
|
|
F: "service/ftp",
|
|
P: "1208",
|
|
T: "B",
|
|
V: "1",
|
|
H: "enable",
|
|
O: [{ no: "0" }, { yes: "1" }],
|
|
},
|
|
{
|
|
F: "service/ftp",
|
|
P: "1196",
|
|
T: "I",
|
|
V: "21",
|
|
H: "control port",
|
|
S: "65001",
|
|
M: "1",
|
|
},
|
|
{
|
|
F: "service/ftp",
|
|
P: "1200",
|
|
T: "I",
|
|
V: "20",
|
|
H: "active port",
|
|
S: "65001",
|
|
M: "1",
|
|
},
|
|
{
|
|
F: "service/ftp",
|
|
P: "1204",
|
|
T: "I",
|
|
V: "55600",
|
|
H: "passive port",
|
|
S: "65001",
|
|
M: "1",
|
|
},
|
|
{
|
|
F: "service/notification",
|
|
P: "1191",
|
|
T: "B",
|
|
V: "1",
|
|
H: "auto notif",
|
|
O: [{ no: "0" }, { yes: "1" }],
|
|
},
|
|
{
|
|
F: "service/notification",
|
|
P: "116",
|
|
T: "B",
|
|
V: "0",
|
|
H: "notification",
|
|
O: [
|
|
{ none: "0" },
|
|
{ pushover: "1" },
|
|
{ email: "2" },
|
|
{ line: "3" },
|
|
],
|
|
},
|
|
{
|
|
F: "service/notification",
|
|
P: "332",
|
|
T: "S",
|
|
V: "********",
|
|
S: "63",
|
|
H: "t1",
|
|
M: "0",
|
|
},
|
|
{
|
|
F: "service/notification",
|
|
P: "583",
|
|
T: "S",
|
|
V: "********",
|
|
S: "63",
|
|
H: "t2",
|
|
M: "0",
|
|
},
|
|
{
|
|
F: "service/notification",
|
|
P: "1042",
|
|
T: "S",
|
|
V: " ",
|
|
S: "127",
|
|
H: "ts",
|
|
M: "0",
|
|
},
|
|
{
|
|
F: "system/system",
|
|
P: "648",
|
|
T: "B",
|
|
V: "40",
|
|
H: "targetfw",
|
|
O: [
|
|
{ repetier: "50" },
|
|
{ marlin: "20" },
|
|
{ marlinkimbra: "35" },
|
|
{ smoothieware: "40" },
|
|
{ grbl: "10" },
|
|
{ unknown: "0" },
|
|
],
|
|
},
|
|
{
|
|
F: "system/system",
|
|
P: "112",
|
|
T: "I",
|
|
V: "115200",
|
|
H: "baud",
|
|
O: [
|
|
{ 9600: "9600" },
|
|
{ 19200: "19200" },
|
|
{ 38400: "38400" },
|
|
{ 57600: "57600" },
|
|
{ 74880: "74880" },
|
|
{ 115200: "115200" },
|
|
{ 230400: "230400" },
|
|
{ 250000: "250000" },
|
|
{ 500000: "500000" },
|
|
{ 921600: "921600" },
|
|
],
|
|
},
|
|
{
|
|
F: "system/system",
|
|
P: "320",
|
|
T: "I",
|
|
V: "10000",
|
|
H: "bootdelay",
|
|
S: "40000",
|
|
M: "0",
|
|
},
|
|
{
|
|
F: "system/system",
|
|
P: "129",
|
|
T: "F",
|
|
V: "255",
|
|
H: "outputmsg",
|
|
O: [{ M117: "16" }, { serial: "1" }, { telnet: "2" }],
|
|
},
|
|
],
|
|
});
|
|
return;
|
|
}
|
|
SendBinary("ok\n");
|
|
res.send("");
|
|
});
|
|
|
|
function fileSizeString(size) {
|
|
let s;
|
|
if (size < 1024) return size + " B";
|
|
if (size < 1024 * 1024) return (size / 1024).toFixed(2) + " KB";
|
|
if (size < 1024 * 1024 * 1024)
|
|
return (size / (1024 * 1024)).toFixed(2) + " MB";
|
|
if (size < 1024 * 1024 * 1024 * 1024)
|
|
return (size / (1024 * 1024 * 1024)).toFixed(2) + " GB";
|
|
return "X B";
|
|
}
|
|
|
|
function filesList(mypath, mainpath) {
|
|
let res = '{"files":[';
|
|
let nb = 0;
|
|
let total = sdpath == mainpath ? 4096 * 1024 * 1024 : 1.2 * 1024 * 1024;
|
|
let totalused = getTotalSize(mainpath);
|
|
let currentpath = path.normalize(mainpath + mypath);
|
|
console.log("[path]" + currentpath);
|
|
fs.readdirSync(currentpath).forEach((fileelement) => {
|
|
let fullpath = path.normalize(currentpath + "/" + fileelement);
|
|
let fst = fs.statSync(fullpath);
|
|
let fsize = -1;
|
|
|
|
if (fst.isFile()) {
|
|
fsize = fileSizeString(fst.size);
|
|
}
|
|
if (nb > 0) res += ",";
|
|
res += '{"name":"' + fileelement + '","size":"' + fsize + '"}';
|
|
nb++;
|
|
});
|
|
res +=
|
|
'],"path":"' +
|
|
mypath +
|
|
'","occupation":"' +
|
|
((100 * totalused) / total).toFixed(0) +
|
|
'","status":"ok","total":"' +
|
|
fileSizeString(total) +
|
|
'","used":"' +
|
|
fileSizeString(totalused) +
|
|
'"}';
|
|
return res;
|
|
}
|
|
|
|
const getAllFiles = function (dirPath, arrayOfFiles) {
|
|
let files = fs.readdirSync(dirPath);
|
|
|
|
arrayOfFiles = arrayOfFiles || [];
|
|
|
|
files.forEach(function (file) {
|
|
if (fs.statSync(dirPath + "/" + file).isDirectory()) {
|
|
arrayOfFiles = getAllFiles(dirPath + "/" + file, arrayOfFiles);
|
|
} else {
|
|
arrayOfFiles.push(dirPath + "/" + file);
|
|
}
|
|
});
|
|
|
|
return arrayOfFiles;
|
|
};
|
|
|
|
const getTotalSize = function (directoryPath) {
|
|
const arrayOfFiles = getAllFiles(directoryPath);
|
|
|
|
let totalSize = 0;
|
|
|
|
arrayOfFiles.forEach(function (filePath) {
|
|
totalSize += fs.statSync(filePath).size;
|
|
});
|
|
|
|
return totalSize;
|
|
};
|
|
|
|
function deleteFolderRecursive(path) {
|
|
if (fs.existsSync(path) && fs.lstatSync(path).isDirectory()) {
|
|
fs.readdirSync(path).forEach(function (file, index) {
|
|
let curPath = path + "/" + file;
|
|
|
|
if (fs.lstatSync(curPath).isDirectory()) {
|
|
// recurse
|
|
deleteFolderRecursive(curPath);
|
|
} else {
|
|
// delete file
|
|
fs.unlinkSync(curPath);
|
|
}
|
|
});
|
|
|
|
console.log(`[server]Deleting directory "${path}"...`);
|
|
if (fs.existsSync(path)) fs.rmdirSync(path);
|
|
} else console.log(`[server]No directory "${path}"...`);
|
|
}
|
|
|
|
app.all("/updatefw", function (req, res) {
|
|
res.send("ok");
|
|
});
|
|
|
|
app.all("/sdfiles", function (req, res) {
|
|
let mypath = req.query.path;
|
|
let url = req.originalUrl;
|
|
let filepath = path.normalize(sdpath + mypath + "/" + req.query.filename);
|
|
if (url.indexOf("action=deletedir") != -1) {
|
|
console.log("[server]delete directory " + filepath);
|
|
deleteFolderRecursive(filepath);
|
|
fs.readdirSync(mypath);
|
|
} else if (url.indexOf("action=delete") != -1) {
|
|
fs.unlinkSync(filepath);
|
|
console.log("[server]delete file " + filepath);
|
|
}
|
|
if (url.indexOf("action=createdir") != -1) {
|
|
fs.mkdirSync(filepath);
|
|
console.log("[server]new directory " + filepath);
|
|
}
|
|
if (typeof mypath == "undefined") {
|
|
if (typeof req.body.path == "undefined") {
|
|
console.log("[server]path is not defined");
|
|
mypath = "/";
|
|
} else {
|
|
mypath = (req.body.path == "/" ? "" : req.body.path) + "/";
|
|
}
|
|
}
|
|
console.log("[server]path is " + mypath);
|
|
if (!req.files || Object.keys(req.files).length === 0) {
|
|
return res.send(filesList(mypath, sdpath));
|
|
}
|
|
let myFile = req.files.myfiles;
|
|
if (typeof myFile.length == "undefined") {
|
|
let fullpath = path.normalize(sdpath + mypath + myFile.name);
|
|
console.log("[server]one file:" + fullpath);
|
|
myFile.mv(fullpath, function (err) {
|
|
if (err) return res.status(500).send(err);
|
|
res.send(filesList(mypath, sdpath));
|
|
});
|
|
return;
|
|
} else {
|
|
console.log(myFile.length + " files");
|
|
for (let i = 0; i < myFile.length; i++) {
|
|
let fullpath = path.normalize(sdpath + mypath + myFile[i].name);
|
|
console.log(fullpath);
|
|
myFile[i].mv(fullpath).then(() => {
|
|
if (i == myFile.length - 1) res.send(filesList(mypath, sdpath));
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
app.all("/files", function (req, res) {
|
|
let mypath = req.query.path;
|
|
let url = req.originalUrl;
|
|
let filepath = path.normalize(
|
|
serverpath + mypath + "/" + req.query.filename
|
|
);
|
|
if (url.indexOf("action=deletedir") != -1) {
|
|
console.log("[server]delete directory " + filepath);
|
|
deleteFolderRecursive(filepath);
|
|
fs.readdirSync(mypath);
|
|
} else if (url.indexOf("action=delete") != -1) {
|
|
fs.unlinkSync(filepath);
|
|
console.log("[server]delete file " + filepath);
|
|
}
|
|
if (url.indexOf("action=createdir") != -1) {
|
|
fs.mkdirSync(filepath);
|
|
console.log("[server]new directory " + filepath);
|
|
}
|
|
if (typeof mypath == "undefined") {
|
|
if (typeof req.body.path == "undefined") {
|
|
console.log("[server]path is not defined");
|
|
mypath = "/";
|
|
} else {
|
|
mypath = (req.body.path == "/" ? "" : req.body.path) + "/";
|
|
}
|
|
}
|
|
console.log("[server]path is " + mypath);
|
|
if (!req.files || Object.keys(req.files).length === 0) {
|
|
return res.send(filesList(mypath, serverpath));
|
|
}
|
|
let myFile = req.files.myfiles;
|
|
if (typeof myFile.length == "undefined") {
|
|
let fullpath = path.normalize(serverpath + mypath + myFile.name);
|
|
console.log("[server]one file:" + fullpath);
|
|
myFile.mv(fullpath, function (err) {
|
|
if (err) return res.status(500).send(err);
|
|
res.send(filesList(mypath, serverpath));
|
|
});
|
|
return;
|
|
} else {
|
|
console.log(myFile.length + " files");
|
|
for (let i = 0; i < myFile.length; i++) {
|
|
let fullpath = path.normalize(serverpath + mypath + myFile[i].name);
|
|
console.log(fullpath);
|
|
myFile[i].mv(fullpath).then(() => {
|
|
if (i == myFile.length - 1)
|
|
res.send(filesList(mypath, serverpath));
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
wss.on("connection", (socket, request) => {
|
|
console.log(wscolor("[ws] New connection"));
|
|
console.log(wscolor(`[ws] currentID:${currentID}`));
|
|
socket.send(`currentID:${currentID}`);
|
|
wss.clients.forEach(function each(client) {
|
|
if (client.readyState === WebSocket.OPEN) {
|
|
client.send(`activeID:${currentID}`);
|
|
}
|
|
});
|
|
currentID++;
|
|
socket.on("message", (message) => {
|
|
console.log(wscolor("[ws] received: %s", message));
|
|
});
|
|
});
|
|
wss.on("error", (error) => {
|
|
console.log(wscolor("[ws] Error: %s", error));
|
|
});
|