diff --git a/index.js b/index.js index 7ad3e91..f3fcd25 100644 --- a/index.js +++ b/index.js @@ -24,6 +24,7 @@ const client = new net.Socket(); // Other files and libraries const crypto = require('crypto'); const fs = require('fs'); +const { SerialPort } = require('serialport') const commandExists = require('command-exists-promise'); const dataHandler = require('./datahandler'); const fmdxList = require('./fmdx_list'); @@ -57,6 +58,7 @@ let currentUsers = 0; let connectedUsers = []; let streamEnabled = false; let incompleteDataBuffer = ''; +let serialport; app.use(bodyParser.urlencoded({ extended: true })); const sessionMiddleware = session({ @@ -96,10 +98,40 @@ function authenticateWithXdrd(client, salt, password) { } connectToXdrd(); +connectToSerial(); + +// Serial Connection +function connectToSerial() { + if (serverConfig.xdrd.wirelessConnection === false) { + + serialport = new SerialPort({path: serverConfig.xdrd.comPort, baudRate: 115200 }); + + serialport.on('open', () => { + logInfo('Using COM device: ' + serverConfig.xdrd.comPort); + serialport.write('x\n'); + if(serverConfig.defaultFreq) { + serialport.write('T' + Math.round(serverConfig.defaultFreq * 1000) +'\n'); + } else { + serialport.write('T87500\n'); + } + serialport.write('G00\n'); + + serialport.on('data', (data) => { + resolveDataBuffer(data); + }); + }); + + serialport.on('error', (error) => { + logError(error.message); + }); + + return serialport; + } +} // xdrd connection function connectToXdrd() { - if (serverConfig.xdrd.xdrdPassword.length > 1) { + if (serverConfig.xdrd.wirelessConnection === true) { client.connect(serverConfig.xdrd.xdrdPort, serverConfig.xdrd.xdrdIp, () => { logInfo('Connection to xdrd established successfully.'); @@ -157,12 +189,16 @@ function connectToXdrd() { dataHandler.dataToSend.ims = 0; break; } + } else if (line.startsWith('Z')) { + let modifiedLine = line.slice(1); + dataHandler.initialData.ant = modifiedLine; + dataHandler.dataToSend.ant = modifiedLine; } if (authFlags.authMsg && authFlags.firstClient) { client.write('x\n'); if(serverConfig.defaultFreq) { - client.write('T' + Math.round(serverConfig.defaultFreq * 1000) +'\n') + client.write('T' + Math.round(serverConfig.defaultFreq * 1000) +'\n'); } else { client.write('T87500\n'); } @@ -176,29 +212,7 @@ function connectToXdrd() { }; client.on('data', (data) => { - var receivedData = incompleteDataBuffer + data.toString(); - const isIncomplete = (receivedData.slice(-1) != '\n'); - - if (isIncomplete) { - const position = receivedData.lastIndexOf('\n'); - if (position < 0) { - incompleteDataBuffer = receivedData; - receivedData = ''; - } else { - incompleteDataBuffer = receivedData.slice(position + 1); - receivedData = receivedData.slice(0, position + 1); - } - } else { - incompleteDataBuffer = ''; - } - - if (receivedData.length) { - wss.clients.forEach((client) => { - if (client.readyState === WebSocket.OPEN) { - dataHandler.handleData(client, receivedData); - } - }); - } + resolveDataBuffer(data); }); client.on('data', authDataHandler); @@ -293,6 +307,32 @@ const authenticate = (req, res, next) => { app.set('view engine', 'ejs'); // Set EJS as the template engine app.set('views', path.join(__dirname, '/web')) +function resolveDataBuffer(data) { + var receivedData = incompleteDataBuffer + data.toString(); + const isIncomplete = (receivedData.slice(-1) != '\n'); + + if (isIncomplete) { + const position = receivedData.lastIndexOf('\n'); + if (position < 0) { + incompleteDataBuffer = receivedData; + receivedData = ''; + } else { + incompleteDataBuffer = receivedData.slice(position + 1); + receivedData = receivedData.slice(0, position + 1); + } + } else { + incompleteDataBuffer = ''; + } + + if (receivedData.length) { + wss.clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) { + dataHandler.handleData(client, receivedData); + } + }); + } +} + function parseMarkdown(parsed) { parsed = parsed.replace(/<\/?[^>]+(>|$)/g, ''); @@ -333,12 +373,24 @@ function removeMarkdown(parsed) { app.get('/', (req, res) => { if (!fs.existsSync(configName + '.json')) { - parseAudioDevice((result) => { - res.render('wizard', { - isAdminAuthenticated: true, - videoDevices: result.audioDevices, - audioDevices: result.videoDevices }); + let serialPorts; + + SerialPort.list() + .then((deviceList) => { + serialPorts = deviceList.map(port => ({ + path: port.path, + friendlyName: port.friendlyName, + })); + + parseAudioDevice((result) => { + res.render('wizard', { + isAdminAuthenticated: req.session.isAdminAuthenticated, + videoDevices: result.audioDevices, + audioDevices: result.videoDevices, + serialPorts: serialPorts + }); }); + }) } else { res.render('index', { isAdminAuthenticated: req.session.isAdminAuthenticated, @@ -359,30 +411,54 @@ app.get('/', (req, res) => { }); app.get('/wizard', (req, res) => { + let serialPorts; + + SerialPort.list() + .then((deviceList) => { + serialPorts = deviceList.map(port => ({ + path: port.path, + friendlyName: port.friendlyName, + })); + parseAudioDevice((result) => { - res.render('wizard', { + res.render('wizard', { isAdminAuthenticated: req.session.isAdminAuthenticated, videoDevices: result.audioDevices, - audioDevices: result.videoDevices }); + audioDevices: result.videoDevices, + serialPorts: serialPorts }); + }); + }) }) app.get('/setup', (req, res) => { - parseAudioDevice((result) => { - const processUptimeInSeconds = Math.floor(process.uptime()); - const formattedProcessUptime = formatUptime(processUptimeInSeconds); + let serialPorts; + + SerialPort.list() + .then((deviceList) => { + serialPorts = deviceList.map(port => ({ + path: port.path, + friendlyName: port.friendlyName, + })); + + parseAudioDevice((result) => { + const processUptimeInSeconds = Math.floor(process.uptime()); + const formattedProcessUptime = formatUptime(processUptimeInSeconds); + + res.render('setup', { + isAdminAuthenticated: req.session.isAdminAuthenticated, + videoDevices: result.audioDevices, + audioDevices: result.videoDevices, + serialPorts: serialPorts, + memoryUsage: (process.memoryUsage.rss() / 1024 / 1024).toFixed(1) + ' MB', + processUptime: formattedProcessUptime, + consoleOutput: consoleCmd.logs, + onlineUsers: dataHandler.dataToSend.users, + connectedUsers: connectedUsers + }); + }); + }) - res.render('setup', { - isAdminAuthenticated: req.session.isAdminAuthenticated, - videoDevices: result.audioDevices, - audioDevices: result.videoDevices, - memoryUsage: (process.memoryUsage.rss() / 1024 / 1024).toFixed(1) + ' MB', - processUptime: formattedProcessUptime, - consoleOutput: consoleCmd.logs, - onlineUsers: dataHandler.dataToSend.users, - connectedUsers: connectedUsers - }); - }); }); app.get('/api', (req, res) => { @@ -491,7 +567,7 @@ wss.on('connection', (ws, request) => { currentUsers++; dataHandler.showOnlineUsers(currentUsers); if(currentUsers === 1 && serverConfig.autoShutdown === true) { - connectToXdrd(); + serverConfig.xdrd.wirelessConnection === true ? connectToXdrd() : serialport.write('x\n'); } // Use ipinfo.io API to get geolocation information @@ -549,12 +625,12 @@ wss.on('connection', (ws, request) => { if(serverConfig.lockToAdmin === true) { if(request.session && request.session.isAdminAuthenticated === true) { - client.write(command + "\n"); + serverConfig.xdrd.wirelessConnection === true ? client.write(command + "\n") : serialport.write(command + "\n"); } else { return; } } else { - client.write(command + "\n"); + serverConfig.xdrd.wirelessConnection === true ? client.write(command + "\n") : serialport.write(command + "\n"); } } }); @@ -569,17 +645,17 @@ wss.on('connection', (ws, request) => { connectedUsers.splice(index, 1); // Remove the user's data from connectedUsers array } - if (currentUsers === 0 && serverConfig.defaultFreq && serverConfig.enableDefaultFreq && serverConfig.enableDefaultFreq === true) { + if (currentUsers === 0 && serverConfig.enableDefaultFreq === true && serverConfig.autoShutdown !== true && serverConfig.xdrd.wirelessConnection === true) { setTimeout(function() { if(currentUsers === 0) { client.write('T' + Math.round(serverConfig.defaultFreq * 1000) +'\n'); - //dataHandler.resetToDefault(); + dataHandler.resetToDefault(dataHandler.dataToSend); dataHandler.dataToSend.freq = Number(serverConfig.defaultFreq).toFixed(3); } }, 10000) } - if (currentUsers === 0 && serverConfig.autoShutdown === true) { + if (currentUsers === 0 && serverConfig.autoShutdown === true && serverConfig.xdrd.wirelessConnection === true) { client.write('X\n'); } diff --git a/package-lock.json b/package-lock.json index 76f025d..c422591 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "fm-dx-webserver", - "version": "1.0.8", + "version": "1.1.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "fm-dx-webserver", - "version": "1.0.8", + "version": "1.1.3", "license": "ISC", "dependencies": { "@mapbox/node-pre-gyp": "^1.0.11", @@ -20,6 +20,7 @@ "https": "1.0.0", "koffi": "2.7.2", "net": "1.0.2", + "serialport": "^12.0.0", "websocket": "1.0.34", "wrtc": "^0.4.7", "ws": "^8.14.2" @@ -44,6 +45,268 @@ "node-pre-gyp": "bin/node-pre-gyp" } }, + "node_modules/@serialport/binding-mock": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz", + "integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==", + "dependencies": { + "@serialport/bindings-interface": "^1.2.1", + "debug": "^4.3.3" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@serialport/binding-mock/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@serialport/binding-mock/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@serialport/bindings-cpp": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-12.0.1.tgz", + "integrity": "sha512-r2XOwY2dDvbW7dKqSPIk2gzsr6M6Qpe9+/Ngs94fNaNlcTRCV02PfaoDmRgcubpNVVcLATlxSxPTIDw12dbKOg==", + "hasInstallScript": true, + "dependencies": { + "@serialport/bindings-interface": "1.2.2", + "@serialport/parser-readline": "11.0.0", + "debug": "4.3.4", + "node-addon-api": "7.0.0", + "node-gyp-build": "4.6.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-delimiter": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-11.0.0.tgz", + "integrity": "sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-readline": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-11.0.0.tgz", + "integrity": "sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==", + "dependencies": { + "@serialport/parser-delimiter": "11.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/bindings-cpp/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@serialport/bindings-cpp/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@serialport/bindings-cpp/node_modules/node-gyp-build": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/@serialport/bindings-interface": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz", + "integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==", + "engines": { + "node": "^12.22 || ^14.13 || >=16" + } + }, + "node_modules/@serialport/parser-byte-length": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-12.0.0.tgz", + "integrity": "sha512-0ei0txFAj+s6FTiCJFBJ1T2hpKkX8Md0Pu6dqMrYoirjPskDLJRgZGLqoy3/lnU1bkvHpnJO+9oJ3PB9v8rNlg==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-cctalk": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-12.0.0.tgz", + "integrity": "sha512-0PfLzO9t2X5ufKuBO34DQKLXrCCqS9xz2D0pfuaLNeTkyGUBv426zxoMf3rsMRodDOZNbFblu3Ae84MOQXjnZw==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-delimiter": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-12.0.0.tgz", + "integrity": "sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-inter-byte-timeout": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-12.0.0.tgz", + "integrity": "sha512-GnCh8K0NAESfhCuXAt+FfBRz1Cf9CzIgXfp7SdMgXwrtuUnCC/yuRTUFWRvuzhYKoAo1TL0hhUo77SFHUH1T/w==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-packet-length": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-12.0.0.tgz", + "integrity": "sha512-p1hiCRqvGHHLCN/8ZiPUY/G0zrxd7gtZs251n+cfNTn+87rwcdUeu9Dps3Aadx30/sOGGFL6brIRGK4l/t7MuQ==", + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@serialport/parser-readline": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-12.0.0.tgz", + "integrity": "sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==", + "dependencies": { + "@serialport/parser-delimiter": "12.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-ready": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-12.0.0.tgz", + "integrity": "sha512-ygDwj3O4SDpZlbrRUraoXIoIqb8sM7aMKryGjYTIF0JRnKeB1ys8+wIp0RFMdFbO62YriUDextHB5Um5cKFSWg==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-regex": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-12.0.0.tgz", + "integrity": "sha512-dCAVh4P/pZrLcPv9NJ2mvPRBg64L5jXuiRxIlyxxdZGH4WubwXVXY/kBTihQmiAMPxbT3yshSX8f2+feqWsxqA==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-slip-encoder": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-12.0.0.tgz", + "integrity": "sha512-0APxDGR9YvJXTRfY+uRGhzOhTpU5akSH183RUcwzN7QXh8/1jwFsFLCu0grmAUfi+fItCkR+Xr1TcNJLR13VNA==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/parser-spacepacket": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-12.0.0.tgz", + "integrity": "sha512-dozONxhPC/78pntuxpz/NOtVps8qIc/UZzdc/LuPvVsqCoJXiRxOg6ZtCP/W58iibJDKPZPAWPGYeZt9DJxI+Q==", + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/stream": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-12.0.0.tgz", + "integrity": "sha512-9On64rhzuqKdOQyiYLYv2lQOh3TZU/D3+IWCR5gk0alPel2nwpp4YwDEGiUBfrQZEdQ6xww0PWkzqth4wqwX3Q==", + "dependencies": { + "@serialport/bindings-interface": "1.2.2", + "debug": "4.3.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/@serialport/stream/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@serialport/stream/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -1118,6 +1381,11 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, + "node_modules/node-addon-api": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz", + "integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==" + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -1390,6 +1658,54 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/serialport": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/serialport/-/serialport-12.0.0.tgz", + "integrity": "sha512-AmH3D9hHPFmnF/oq/rvigfiAouAKyK/TjnrkwZRYSFZxNggJxwvbAbfYrLeuvq7ktUdhuHdVdSjj852Z55R+uA==", + "dependencies": { + "@serialport/binding-mock": "10.2.2", + "@serialport/bindings-cpp": "12.0.1", + "@serialport/parser-byte-length": "12.0.0", + "@serialport/parser-cctalk": "12.0.0", + "@serialport/parser-delimiter": "12.0.0", + "@serialport/parser-inter-byte-timeout": "12.0.0", + "@serialport/parser-packet-length": "12.0.0", + "@serialport/parser-readline": "12.0.0", + "@serialport/parser-ready": "12.0.0", + "@serialport/parser-regex": "12.0.0", + "@serialport/parser-slip-encoder": "12.0.0", + "@serialport/parser-spacepacket": "12.0.0", + "@serialport/stream": "12.0.0", + "debug": "4.3.4" + }, + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/serialport/donate" + } + }, + "node_modules/serialport/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/serialport/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", diff --git a/package.json b/package.json index 59de4b2..41e24cb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fm-dx-webserver", - "version": "1.1.2", + "version": "1.1.3", "description": "", "main": "index.js", "scripts": { @@ -23,6 +23,7 @@ "https": "1.0.0", "koffi": "2.7.2", "net": "1.0.2", + "serialport": "^12.0.0", "websocket": "1.0.34", "wrtc": "^0.4.7", "ws": "^8.14.2" diff --git a/server_config.js b/server_config.js index 6b8772f..a98360b 100644 --- a/server_config.js +++ b/server_config.js @@ -18,6 +18,8 @@ let serverConfig = { chatEnabled: true }, xdrd: { + wirelessConnection: "", + comPort: "", xdrdIp: "127.0.0.1", xdrdPort: 7373, xdrdPassword: "" diff --git a/tx_search.js b/tx_search.js index b3c0d25..b9800ea 100644 --- a/tx_search.js +++ b/tx_search.js @@ -1,5 +1,4 @@ const fetch = require('node-fetch'); -var fs = require('fs'); const { serverConfig } = require('./server_config') let cachedData = {}; diff --git a/web/css/breadcrumbs.css b/web/css/breadcrumbs.css index 062f26c..a1ff0b6 100644 --- a/web/css/breadcrumbs.css +++ b/web/css/breadcrumbs.css @@ -212,6 +212,9 @@ label { text-transform: uppercase; } + #tuner-wireless { + display: none; + } @media (max-width: 768px) { canvas, #flags-container { display: none; @@ -340,6 +343,6 @@ label { height: 225px !important; } .chatbutton { - height: 86px !important; + height: 88px !important; } } \ No newline at end of file diff --git a/web/css/buttons.css b/web/css/buttons.css index fe37328..abbdacc 100644 --- a/web/css/buttons.css +++ b/web/css/buttons.css @@ -190,6 +190,7 @@ input[type="range"]::-moz-range-thumb { width: 100%; border-radius: 25px; font-weight: bold; + background-color: var(--color-2); } .toggleSwitch * { -webkit-box-sizing: border-box; diff --git a/web/index.ejs b/web/index.ejs index 815c409..64da018 100644 --- a/web/index.ejs +++ b/web/index.ejs @@ -119,7 +119,7 @@
You can set up your connection settings here. Changing these settings requires a server restart.
If you are connecting your tuner wirelessly, enter the tuner IP.
If you use xdrd, use 127.0.0.1 as your IP.
If you are connecting your tuner wirelessly, enter the tuner IP.
If you use xdrd, use 127.0.0.1 as your IP.
Leave the IP at 0.0.0.0 unless you explicitly know you have to change it.
Don't enter your public IP here.
Audio channel count.
- 1: Mono • 2: Stereo
+ Choose between Mono / Stereo.