647 lines
No EOL
15 KiB
JavaScript
647 lines
No EOL
15 KiB
JavaScript
//https://www.dontpanicblog.co.uk/2016/04/17/websocket-push-notifications-with-node-js/
|
|
|
|
//!!!!!!!!!!!!!!!!
|
|
//!!! if express server is running, but it's not servig pages - try to unblock PORT
|
|
//!!!!!!!!!!!!!!!!
|
|
|
|
let wss = undefined;
|
|
let startWebSocketServer = false;
|
|
//startWebSocketServer = false;//KONSBERG
|
|
|
|
if(startWebSocketServer)
|
|
{
|
|
var WebSocketServer = require('ws').Server;
|
|
wss = new WebSocketServer({ port: 9090 });
|
|
}
|
|
|
|
const express = require("express");
|
|
const bodyParser = require('body-parser');
|
|
const app = express(); // create express app
|
|
|
|
//const SerialPort = require('serialport');
|
|
const { exec } = require('child_process');
|
|
|
|
const { crc8, crc16, crc32 } = require('easy-crc');
|
|
const http = require('http');
|
|
const status = require('http-status');
|
|
|
|
const username = "admin";
|
|
const password = "admin";
|
|
|
|
const decodeValue = require('./decodeValue.js');
|
|
const { openPort, runSyncExec, writeData } = require('./serialport_helper.js');
|
|
|
|
//const hostname = "10.0.0.5";
|
|
const hostname = "localhost";
|
|
|
|
process.on('uncaughtException', function(error) {
|
|
// do something clever here
|
|
|
|
//TODO send message to services!!!
|
|
|
|
console.log("errors", error); // do NOT do this for real!
|
|
});
|
|
|
|
|
|
|
|
function httpRequest(params, postData) {
|
|
return new Promise(function(resolve, reject) {
|
|
|
|
console.log(params);
|
|
var req = http.request(params, function(res) {
|
|
// reject on bad status
|
|
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
return reject(new Error(res.statusCode + " " + status[res.statusCode]));
|
|
}
|
|
// cumulate data
|
|
var body = [];
|
|
res.on('data', function(chunk) {
|
|
body.push(chunk);
|
|
});
|
|
// resolve on end
|
|
res.on('end', function() {
|
|
try {
|
|
console.log("body", body);
|
|
body = JSON.parse(Buffer.concat(body).toString());
|
|
} catch(e) {
|
|
reject(e);
|
|
}
|
|
resolve(body);
|
|
});
|
|
});
|
|
|
|
// reject on request error
|
|
req.on('error', function(err) {
|
|
// This is not a "Second reject", just a different sort of failure
|
|
reject(err);
|
|
});
|
|
|
|
if (postData) {
|
|
req.write(postData);
|
|
}
|
|
// IMPORTANT
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
//terminal----------------------------------
|
|
function detectIfResponseIsValid(bytes)
|
|
{
|
|
let type = "RESPONSE";
|
|
if(bytes[4] == 0) type = "RESPONSE";
|
|
else if(bytes[4] == 1) type = "ERROR";
|
|
else if(bytes[4] == 2) type = "EVENT";
|
|
else type = "UNKNOWN";
|
|
|
|
let crc = crc16('ARC', bytes.slice(0, 9));
|
|
let c1 = (crc >> 8) & 0xFF;
|
|
let c2 = crc & 0xFF;
|
|
|
|
let message = "OK";
|
|
let error = "";
|
|
if(c1 != bytes[9])
|
|
{
|
|
//CRC_ERROR
|
|
message = "NOK";
|
|
error = "CRC_ERROR c1";
|
|
}
|
|
|
|
if(c2 != bytes[10])
|
|
{
|
|
//CRC_ERROR
|
|
message = "NOK";
|
|
error = "CRC_ERROR c2";
|
|
}
|
|
|
|
//crc error
|
|
if(type != "RESPONSE")
|
|
{
|
|
message = "NOK";
|
|
}
|
|
|
|
return {message: message, type: type, error: error};
|
|
}
|
|
|
|
handleResponse = (bytes, cmd) =>
|
|
{
|
|
|
|
console.log("handleResponse");
|
|
|
|
let result = detectIfResponseIsValid(bytes);
|
|
let message = result.message;
|
|
let type = result.type;
|
|
let error = result.error;
|
|
|
|
if(message != "OK")
|
|
{
|
|
return {type: type, message: message + " " + error + " " + bytes.join(", "), 'date': (new Date()).getTime()};
|
|
}
|
|
|
|
let add = (bytes[0] >> 24) | (bytes[1] >> 16) | (bytes[2] >> 8) | bytes[3];
|
|
|
|
let decodedValue = "cmd: " + cmd;
|
|
if(cmd >= 0x8000)
|
|
{
|
|
return decodeValue(add, cmd, bytes[5],bytes[6],bytes[7],bytes[8]);
|
|
}
|
|
|
|
return {type: type, message: message + " " + bytes.join(", "), 'date': (new Date()).getTime()};
|
|
}
|
|
|
|
com_generic = (adresa, rec, rw, register, name, byte1, byte2, byte3, byte4) =>{
|
|
let resp = [];
|
|
|
|
let cmd = register;
|
|
|
|
if (rw === 0)
|
|
{
|
|
cmd = cmd + 0x8000;
|
|
}
|
|
|
|
if (rec === 3)
|
|
{
|
|
resp.push(0xFF);
|
|
resp.push(0xFF);
|
|
resp.push(0xFF);
|
|
resp.push(0xFF);
|
|
resp.push( adresa & 0xFF );//band
|
|
}
|
|
else
|
|
{
|
|
resp.push( (adresa >> 24) & 0xFF);//rshift
|
|
resp.push( (adresa >> 16) & 0xFF);
|
|
resp.push( (adresa >> 8) & 0xFF);
|
|
resp.push( adresa & 0xFF );
|
|
|
|
if (rec === 2)
|
|
{
|
|
resp.push(0xFF);
|
|
}
|
|
else resp.push(0);
|
|
}
|
|
|
|
resp.push( (cmd >> 8) & 0xFF);//rshift
|
|
resp.push( cmd & 0xFF );//band
|
|
resp.push( byte1 & 0xFF );//band
|
|
resp.push( byte2 & 0xFF );//band
|
|
resp.push( byte3 & 0xFF );//band
|
|
resp.push( byte4 & 0xFF );//band
|
|
|
|
//let data = '12345';
|
|
let crc = crc16('ARC', resp);
|
|
let c1 = (crc >> 8) & 0xFF;
|
|
let c2 = crc & 0xFF;
|
|
|
|
resp.push(c1);
|
|
resp.push(c2);
|
|
|
|
console.log("checksum", crc);
|
|
console.log("resp", resp);
|
|
|
|
return resp;
|
|
|
|
}
|
|
//-------------
|
|
|
|
//https://expressjs.com/en/resources/middleware/cors.html
|
|
var cors = require('cors');
|
|
const { report } = require("process");
|
|
app.use(cors());
|
|
app.use(bodyParser.urlencoded({ extended: true }));
|
|
app.use(bodyParser.json());
|
|
|
|
// add middleware
|
|
//app.use(express.static("public"));
|
|
app.use(express.static(__dirname + "/public"));
|
|
|
|
app.get('/restart', function (req, res) {
|
|
console.log('restart');
|
|
|
|
exec(`service nodejs restart`, (err, stdout, stderr) => {
|
|
if (err || stderr) {
|
|
console.log("failed to restart nodejs");
|
|
console.error(err);
|
|
console.log(stderr);
|
|
|
|
let response = {"message": "failed to restart nodejs " + err};
|
|
res.json(response);
|
|
|
|
} else {
|
|
console.log(stdout);
|
|
console.log(`Successfully restarted service nodejs ${stdout}`);
|
|
|
|
let response = {"message": "restarted"};
|
|
res.json(response);
|
|
}
|
|
});
|
|
|
|
//res.sendStatus(200);
|
|
});
|
|
|
|
|
|
//KONBERG
|
|
// Broadcast updates to all WebSocketServer clients
|
|
//app.post('/notify', function (req, res) {
|
|
app.get('/notify', function (req, res) {
|
|
if(wss == undefined)
|
|
{
|
|
res.sendStatus(200);
|
|
return;
|
|
}
|
|
|
|
console.log('Event: notify');
|
|
wss.clients.forEach(function each(client) {
|
|
client.send("broadcast: updated");
|
|
|
|
//console.log('broadcast', client);
|
|
});
|
|
res.sendStatus(200);
|
|
});
|
|
|
|
|
|
//---general
|
|
app.get('/db', function(req, res) {
|
|
//res.sendStatus(404);
|
|
|
|
let params = {table: "settings", action: "read"};
|
|
const data = JSON.stringify(params);
|
|
|
|
let h = hostname;
|
|
|
|
const httpRequestParams = {
|
|
hostname: h,
|
|
port: 12345,
|
|
path: '/db_connector',
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Content-Length': data.length
|
|
}
|
|
}
|
|
|
|
httpRequest(httpRequestParams, data).then(function(body) {
|
|
console.log("response", body);
|
|
|
|
let response = {"data": body.data};
|
|
res.json(response);
|
|
|
|
|
|
}).catch(function (e) {
|
|
//console.log(e);
|
|
|
|
//messages.push({type: "ERROR", message: e.message});
|
|
|
|
let response = {"message": e.message, "type": "ERROR"};
|
|
res.json(response);
|
|
// and so on
|
|
});
|
|
});
|
|
|
|
app.post('/db', function(req, res) {
|
|
//res.sendStatus(404);
|
|
|
|
console.log("request", req.body);
|
|
|
|
//let params = {table: req.body.table, action: req.body.action};
|
|
let params = req.body;
|
|
const data = JSON.stringify(params);
|
|
|
|
let h = hostname;
|
|
if(req.body.hostname !== undefined) h = req.body.hostname;
|
|
|
|
const httpRequestParams = {
|
|
hostname: h,
|
|
port: 12345,
|
|
path: '/db_connector',
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Content-Length': data.length
|
|
}
|
|
}
|
|
|
|
httpRequest(httpRequestParams, data).then(function(body) {
|
|
console.log("response", body.data);
|
|
|
|
//let response = {"data": body.data};
|
|
let response = body.data;
|
|
//res.sendStatus(200);
|
|
res.json(response);
|
|
return;
|
|
|
|
|
|
}).catch(function (e) {
|
|
//console.log(e);
|
|
|
|
let response = {"message": e.message, "type": "ERROR"};
|
|
res.json(response);
|
|
// and so on
|
|
});
|
|
|
|
});
|
|
|
|
app.post('/validate', function(req, res) {
|
|
|
|
let response = {"valid": false};
|
|
if(username === req.body.username && password === req.body.password)
|
|
{
|
|
response.valid = true;
|
|
}
|
|
|
|
res.json(response);
|
|
});
|
|
|
|
//--terminal
|
|
app.get('/cmd', function(req, res) {
|
|
//console.log('GET: Got body:', req.body);
|
|
//res.send("error: use POST request instead");
|
|
res.sendStatus(501);
|
|
});
|
|
|
|
|
|
//https://zellwk.com/blog/async-await-express/
|
|
app.post('/cmd', async(req, res, next) => {
|
|
console.log('POST: Got body:', req.body);
|
|
|
|
if(username != req.body.username && password != req.body.password)
|
|
{
|
|
res.sendStatus(501);
|
|
return;
|
|
}
|
|
|
|
let message = "";//TODO remove
|
|
let messages = [];
|
|
let makeHttpRequest = true;
|
|
|
|
//make http request
|
|
let params = req.body.command;
|
|
let cmd = params.register;
|
|
|
|
//hostname: req.body.hostname,
|
|
let h = hostname;
|
|
if(req.body.hostname !== undefined) h = req.body.hostname;
|
|
|
|
if(makeHttpRequest)
|
|
{
|
|
const data = JSON.stringify(params);
|
|
|
|
const httpRequestParams = {
|
|
hostname: h,
|
|
port: 12345,
|
|
path: '/terminal',
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Content-Length': data.length
|
|
}
|
|
}
|
|
|
|
await httpRequest(httpRequestParams, data).then(function(body) {
|
|
|
|
if (params.rw === 0)
|
|
{
|
|
cmd = cmd + 0x8000;
|
|
}
|
|
|
|
let bytes = body.bytes;
|
|
console.log("body", body, bytes, typeof body);
|
|
|
|
let type = "RESPONSE";
|
|
if(bytes === undefined)
|
|
{
|
|
if(typeof body === 'object')
|
|
{
|
|
type = body.type;
|
|
messages.push({type: "ERROR", message: body.message});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(bytes[4] == 0) type = "RESPONSE";
|
|
else if(bytes[4] == 1) type = "ERROR";
|
|
else if(bytes[4] == 2) type = "EVENT";
|
|
else type = "UNKNOWN";
|
|
|
|
//ake data sme zapisali?
|
|
message = bytes.join(", ");
|
|
messages.push({type: type, message: "RESP: " + message});
|
|
|
|
let result = handleResponse(bytes, cmd);
|
|
if(result == undefined) messages.push({type: "ERROR", message: "ERROR: handleResponse undefined", 'date': (new Date()).getTime()});
|
|
|
|
if(Array.isArray(result))
|
|
{
|
|
messages = messages.concat(result);
|
|
}
|
|
else
|
|
{
|
|
messages.push({type: "RESPONSE", message: result});
|
|
//messages.push(result);
|
|
}
|
|
}
|
|
|
|
if(cmd >= 0x8000)
|
|
{
|
|
console.log("params.register", params.register);
|
|
}
|
|
|
|
let response = {"message": message, messages: messages, hostname: h, "type": "SUCESS"};
|
|
res.json(response);
|
|
|
|
}).catch(function (e) {
|
|
|
|
console.log(e, new Date());
|
|
|
|
messages.push({type: "ERROR", message: "express exception: " + e.message});
|
|
|
|
let response = {"message": message, messages: messages, hostname: h, "type": "ERROR"};
|
|
res.json(response);
|
|
// and so on
|
|
});
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//if we want to use serial port directly
|
|
|
|
let portOpened = false;
|
|
let error = false;
|
|
let port = "/dev/ttymxc4";
|
|
|
|
try {
|
|
|
|
const rsPort = new SerialPort(port, { autoOpen: false });
|
|
|
|
/*
|
|
await runSyncExec("ping localhost").then(function (status) {
|
|
console.log("Promise Resolved:", status);
|
|
message = status;
|
|
}).catch(function (reason) {
|
|
console.log("Promise Rejected:", reason);
|
|
|
|
error = true;
|
|
message = reason;
|
|
|
|
});
|
|
*/
|
|
|
|
messages.push({type: "INFO", message: "trying to open port directly (express.js): " + port, 'date': (new Date()).getTime()});
|
|
|
|
await openPort(rsPort).then(function (status) {
|
|
console.log("Promise Resolved:", status, new Date());
|
|
|
|
portOpened = true;
|
|
message = status;
|
|
//messages.push(message);
|
|
|
|
|
|
}).catch(function (reason) {
|
|
console.log("Promise Rejected:", reason);
|
|
|
|
error = true;
|
|
message = reason;
|
|
|
|
messages.push({type: "ERROR", message: message, 'date': (new Date()).getTime()});
|
|
|
|
});
|
|
|
|
|
|
if(!error)
|
|
{
|
|
await runSyncExec("stty -F /dev/ttymxc4 115200 min 1 time 5 ignbrk -brkint -icrnl -imaxbel -opost -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke").then(function (status) {
|
|
console.log("Promise Resolved:", status, new Date());
|
|
|
|
//message = status;
|
|
}).catch(function (reason) {
|
|
console.log("Promise Rejected:", reason);
|
|
|
|
error = true;
|
|
//message = escapeSpecialChars(reason);
|
|
if(typeof reason == "object")
|
|
{
|
|
message = JSON.stringify(reason);
|
|
|
|
messages.push({type: "ERROR", message: message, 'date': (new Date()).getTime()});
|
|
}
|
|
});
|
|
}
|
|
|
|
//WRITE DATA & READ RESPONSE
|
|
/*
|
|
if(error)
|
|
{
|
|
|
|
//print(P.decodeValue(add, L.last_cmd, bytes[6],bytes[7],bytes[8],bytes[9]).."<br>")
|
|
let decodedValue = decodeValue(1, 5,0, 0, 0, 0 );
|
|
console.log(decodedValue);
|
|
|
|
let params = req.body.command;
|
|
let resp = com_generic(params.address, params.recipient, params.rw, params.register, params.name, params.byte1, params.byte2, params.byte3, params.byte4);
|
|
|
|
//messages.push("WRITE: " + resp.join(", "));
|
|
messages.push({type: "INFO", message: "TEST WRITE " + resp.join(", "), 'date': (new Date()).getTime()});
|
|
}
|
|
*/
|
|
|
|
if(!error)
|
|
{
|
|
let params = req.body.command;
|
|
|
|
let cmd = params.register;
|
|
if (params.rw === 0)
|
|
{
|
|
//cmd = cmd + 0x8000;
|
|
}
|
|
|
|
let resp = com_generic(params.address, params.recipient, params.rw, cmd, params.name, params.byte1, params.byte2, params.byte3, params.byte4);
|
|
//messages.push({type: "WRITE", message: "WRITE " + resp.join(", "), 'date': (new Date()).getTime()});
|
|
|
|
await writeData(rsPort, resp, 11).then(function (data) {
|
|
console.log("Promise Resolved:", data, new Date());
|
|
|
|
//process data
|
|
/*
|
|
RESPONSE = 0,
|
|
ERROR = 1,
|
|
EVENT = 2,
|
|
TIMEOUT = 3,
|
|
CRC_ERROR = 4
|
|
*/
|
|
|
|
let bytes = data.slice(0);
|
|
|
|
let type = "RESPONSE";
|
|
if(bytes[4] == 0) type = "RESPONSE";
|
|
else if(bytes[4] == 1) type = "ERROR";
|
|
else if(bytes[4] == 2) type = "EVENT";
|
|
else type = "UNKNOWN";
|
|
|
|
//ake data sme zapisali?
|
|
message = data.join(", ");
|
|
messages.push({type: type, message: "RESP: " + message});
|
|
|
|
if(cmd >= 0x8000)
|
|
{
|
|
console.log("params.register", params.register);
|
|
}
|
|
|
|
let result = handleResponse(bytes, cmd);
|
|
if(result == undefined) messages.push({type: "ERROR", message: "ERROR: handleResponse undefined", 'date': (new Date()).getTime()});
|
|
|
|
console.log("handleResponse: ", result);
|
|
|
|
if(Array.isArray(result))
|
|
{
|
|
messages = messages.concat(result);
|
|
}
|
|
else
|
|
{
|
|
messages.push({type: "RESPONSE", message: result});
|
|
//messages.push(result);
|
|
}
|
|
|
|
}).catch(function (reason) {
|
|
console.log("Promise Rejected:", reason, new Date());
|
|
|
|
error = true;
|
|
message = reason;
|
|
|
|
messages.push({type: "ERROR", message: message, 'date': (new Date()).getTime()});
|
|
|
|
});
|
|
}
|
|
|
|
if(portOpened) rsPort.close();
|
|
|
|
}
|
|
catch(err) {
|
|
console.log("Exception", err.message);
|
|
|
|
error = true;
|
|
message = err.message;
|
|
|
|
messages.push({type: "ERROR", message: message, 'date': (new Date()).getTime()});
|
|
}
|
|
|
|
console.log("END", new Date());
|
|
|
|
if(!error)
|
|
{
|
|
//let response = {"message": "OK" + JSON.stringify(req.body)};
|
|
let response = {"message": message, messages: messages, "type": "SUCESS"};
|
|
res.json(response);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
let response = {"message": message, messages: messages, "type": "ERROR"};
|
|
res.json(response);
|
|
}
|
|
|
|
});
|
|
|
|
// start express server on port 5000
|
|
app.listen(5000, () => {
|
|
console.log("server started on port 5000");
|
|
}); |