diff --git a/package.json b/package.json index 23b6555..06f3245 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fm-dx-webserver", - "version": "1.2.8", + "version": "1.2.8.1", "description": "FM DX Webserver", "main": "index.js", "scripts": { diff --git a/server/datahandler.js b/server/datahandler.js index 6bfbf91..a9c0855 100644 --- a/server/datahandler.js +++ b/server/datahandler.js @@ -234,7 +234,9 @@ var dataToSend = { itu: '', dist: '', azi: '', - id: '' + id: '', + reg: '', + pi: '', }, country_name: '', country_iso: 'UN', @@ -294,6 +296,7 @@ function handleData(wss, receivedData, rdsWss) { initialData.freq = (parsedValue / 1000).toFixed(3); dataToSend.freq = (parsedValue / 1000).toFixed(3); dataToSend.pi = '?'; + dataToSend.txInfo.reg = false; rdsWss.clients.forEach((client) => { client.send("G:\r\nRESET-------\r\n\r\n"); @@ -401,7 +404,9 @@ function handleData(wss, receivedData, rdsWss) { itu: currentTx.itu, dist: currentTx.distance, azi: currentTx.azimuth, - id: currentTx.id + id: currentTx.id, + pi: currentTx.pi, + reg: currentTx.reg } } diff --git a/server/index.js b/server/index.js index 936126a..9438ed4 100644 --- a/server/index.js +++ b/server/index.js @@ -1,6 +1,3 @@ -// index.js - Mod by Highpoint -// Version for loading server-side plugins - // Library imports const express = require('express'); const endpoints = require('./endpoints'); @@ -15,7 +12,7 @@ const WebSocket = require('ws'); const wss = new WebSocket.Server({ noServer: true }); const chatWss = new WebSocket.Server({ noServer: true }); const rdsWss = new WebSocket.Server({ noServer: true }); -const ExtraWss = new WebSocket.Server({ noServer: true }); +const pluginsWss = new WebSocket.Server({ noServer: true }); const fs = require('fs'); const path = require('path'); const net = require('net'); @@ -537,14 +534,14 @@ rdsWss.on('connection', (ws, request) => { }); //additional web socket for using plugins -ExtraWss.on('connection', (ws, request) => { +pluginsWss.on('connection', (ws, request) => { ws.on('message', message => { const messageData = JSON.parse(message); const modifiedMessage = JSON.stringify(messageData); //Broadcast the message to all other clients - ExtraWss.clients.forEach(client => { + pluginsWss.clients.forEach(client => { if (client.readyState === WebSocket.OPEN) { client.send(modifiedMessage); // Send the message to all clients } @@ -582,10 +579,10 @@ httpServer.on('upgrade', (request, socket, head) => { rdsWss.emit('connection', ws, request); }); }); - } else if (request.url === '/extra') { + } else if (request.url === '/data_plugins') { sessionMiddleware(request, {}, () => { - ExtraWss.handleUpgrade(request, socket, head, (ws) => { - ExtraWss.emit('connection', ws, request); + pluginsWss.handleUpgrade(request, socket, head, (ws) => { + pluginsWss.emit('connection', ws, request); }); }); } else { @@ -599,25 +596,28 @@ app.use(express.static(path.join(__dirname, '../web'))); // Serve the entire web checkIPv6Support((isIPv6Supported) => { const ipv4Address = serverConfig.webserver.webserverIp === '0.0.0.0' ? 'localhost' : serverConfig.webserver.webserverIp; const ipv6Address = '::'; // This will bind to all available IPv6 interfaces - - if (isIPv6Supported) { - // Start server on both IPv4 and IPv6 addresses - httpServer.listen(serverConfig.webserver.webserverPort, ipv4Address, () => { - logInfo(`Web server has started on address \x1b[34mhttp://${ipv4Address}:${serverConfig.webserver.webserverPort}\x1b[0m.`); - }); + const port = serverConfig.webserver.webserverPort; - httpServer.listen(serverConfig.webserver.webserverPort, ipv6Address, () => { - logInfo(`Web server has started on address \x1b[34mhttp://[${ipv6Address}]:${serverConfig.webserver.webserverPort}\x1b[0m.`); - }); - } else { - // Start server only on IPv4 address - httpServer.listen(serverConfig.webserver.webserverPort, ipv4Address, () => { - if (configExists()) { - logInfo(`Web server has started on address \x1b[34mhttp://${ipv4Address}:${serverConfig.webserver.webserverPort}\x1b[0m.`); + const logServerStart = (address, isIPv6) => { + const formattedAddress = isIPv6 ? `[${address}]` : address; + logInfo(`Web server has started on address \x1b[34mhttp://${formattedAddress}:${port}\x1b[0m.`); + }; + + const startServer = (address, isIPv6) => { + httpServer.listen(port, address, () => { + if (!isIPv6 && !configExists()) { + logInfo(`Open your browser and proceed to \x1b[34mhttp://${address}:${port}\x1b[0m to continue with setup.`); } else { - logInfo(`Open your browser and proceed to \x1b[34mhttp://${ipv4Address}:${serverConfig.webserver.webserverPort}\x1b[0m to continue with setup.`); + logServerStart(address, isIPv6); } }); + }; + + if (isIPv6Supported) { + startServer(ipv4Address, false); // Start on IPv4 + startServer(ipv6Address, true); // Start on IPv6 + } else { + startServer(ipv4Address, false); // Start only on IPv4 } }); diff --git a/server/tx_search.js b/server/tx_search.js index c03f872..c39c1aa 100644 --- a/server/tx_search.js +++ b/server/tx_search.js @@ -50,42 +50,69 @@ function processData(data, piCode, rdsPs) { let txAzimuth; let maxDistance; let esMode = checkEs(); + let detectedByPireg = false; // To track if the station was found by pireg + // Helper function to calculate score and update matching station/city + function evaluateStation(station, city, distance) { + let weightDistance = distance.distanceKm; + if (esMode && distance.distanceKm > 500) { + weightDistance = Math.abs(distance.distanceKm - 1500); + } + let erp = station.erp && station.erp > 0 ? station.erp : 1; + const score = (10 * Math.log10(erp * 1000)) / weightDistance; // Calculate score + if (score > maxScore) { + maxScore = score; + txAzimuth = distance.azimuth; + matchingStation = station; + matchingCity = city; + maxDistance = distance.distanceKm; + } + } + + // First attempt: Try to match station using the piCode for (const cityId in data.locations) { const city = data.locations[cityId]; if (city.stations) { for (const station of city.stations) { if (station.pi === piCode.toUpperCase() && !station.extra && station.ps && station.ps.toLowerCase().includes(rdsPs.replace(/ /g, '_').replace(/^_*(.*?)_*$/, '$1').toLowerCase())) { const distance = haversine(serverConfig.identification.lat, serverConfig.identification.lon, city.lat, city.lon); - let weightDistance = distance.distanceKm - if (esMode && (distance.distanceKm > 500)) { - weightDistance = Math.abs(distance.distanceKm-1500); - } - let erp = (station.erp && station.erp > 0) ? station.erp : 1; - const score = (10*Math.log10(erp*1000)) / weightDistance; // Calculate score - if (score > maxScore) { - maxScore = score; - txAzimuth = distance.azimuth; - matchingStation = station; - matchingCity = city; - maxDistance = distance.distanceKm; + evaluateStation(station, city, distance); + detectedByPireg = false; // Detected by pi, not pireg + } + } + } + } + + // If no matching station is found, fallback to pireg + if (!matchingStation) { + for (const cityId in data.locations) { + const city = data.locations[cityId]; + if (city.stations) { + for (const station of city.stations) { + if (station.pireg && station.pireg.toUpperCase() === piCode.toUpperCase() && !station.extra && station.ps && station.ps.toLowerCase().includes(rdsPs.replace(/ /g, '_').replace(/^_*(.*?)_*$/, '$1').toLowerCase())) { + const distance = haversine(serverConfig.identification.lat, serverConfig.identification.lon, city.lat, city.lon); + evaluateStation(station, city, distance); + detectedByPireg = true; // Detected by pireg } } } } } + // Return the results if a station was found, otherwise return undefined if (matchingStation) { return { station: matchingStation.station.replace("R.", "Radio "), pol: matchingStation.pol.toUpperCase(), - erp: (matchingStation.erp && matchingStation.erp > 0) ? matchingStation.erp : '?', + erp: matchingStation.erp && matchingStation.erp > 0 ? matchingStation.erp : '?', city: matchingCity.name, itu: matchingCity.itu, distance: maxDistance.toFixed(0), azimuth: txAzimuth.toFixed(0), id: matchingStation.id, - foundStation: true + pi: matchingStation.pi, + foundStation: true, + reg: detectedByPireg // Indicates if it was detected by pireg }; } else { return; diff --git a/web/css/buttons.css b/web/css/buttons.css index cf9abfe..bb7dcfc 100644 --- a/web/css/buttons.css +++ b/web/css/buttons.css @@ -82,6 +82,10 @@ input[type="text"], textarea, input[type="password"] { caret-color: var(--color-4); } +input[type="password"]:not(#xdrd-password) { + border-radius: 15px 0 0 15px; +} + #tune-buttons input[type="text"] { width: 50%; height: 48px; diff --git a/web/favicon.png b/web/favicon.png index 5d3c093..0e104c3 100644 Binary files a/web/favicon.png and b/web/favicon.png differ diff --git a/web/index.ejs b/web/index.ejs index 82236da..43422b6 100644 --- a/web/index.ejs +++ b/web/index.ejs @@ -93,6 +93,9 @@

PI CODE

+
+   +
@@ -261,7 +264,7 @@ [] - kW [] km ° + kW [] km
@@ -395,7 +398,7 @@ <% } else { %>
-
@@ -436,7 +439,7 @@

FM-DX Webserver

-

by Noobish, kkonradpl & the OpenRadio community.

+

by FMDX.org

[Receiver Map]

diff --git a/web/js/init.js b/web/js/init.js index 8bc967f..6c3ef96 100644 --- a/web/js/init.js +++ b/web/js/init.js @@ -1,9 +1,9 @@ -var currentDate = new Date('Sep 11, 2024 23:50:00'); +var currentDate = new Date('Sep 12, 2024 21:30:00'); var day = currentDate.getDate(); var month = currentDate.getMonth() + 1; // Months are zero-indexed, so add 1 var year = currentDate.getFullYear(); var formattedDate = day + '/' + month + '/' + year; -var currentVersion = 'v1.2.8 [' + formattedDate + ']'; +var currentVersion = 'v1.2.8.1 [' + formattedDate + ']'; getInitialSettings(); removeUrlParameters(); // Call this function to remove URL parameters diff --git a/web/js/main.js b/web/js/main.js index 27d684b..ae7ee2b 100644 --- a/web/js/main.js +++ b/web/js/main.js @@ -827,7 +827,8 @@ const updateDataElements = throttle(function(parsedData) { updateTextIfChanged($('#data-station-itu'), parsedData.txInfo.itu); updateTextIfChanged($('#data-station-pol'), parsedData.txInfo.pol); updateTextIfChanged($('#data-station-distance'), parsedData.txInfo.dist); - updateTextIfChanged($('#data-station-azimuth'), parsedData.txInfo.azi); + updateHtmlIfChanged($('#data-station-azimuth'), parsedData.txInfo.azi + '°'); + updateHtmlIfChanged($('#data-regular-pi'), parsedData.txInfo.reg === true ? parsedData.txInfo.pi : ' '); $dataStationContainer.css('display', 'block'); } else { $dataStationContainer.removeAttr('style'); diff --git a/web/js/setup.js b/web/js/setup.js index 020454b..0386936 100644 --- a/web/js/setup.js +++ b/web/js/setup.js @@ -64,37 +64,8 @@ $(document).ready(function() { $('#tuner-wireless').hide(); $('#tuner-usb').show(); } -}); - - $('#login-form').submit(function (event) { - event.preventDefault(); - - // Perform an AJAX request to the /login endpoint - $.ajax({ - type: 'POST', - url: './login', - data: $(this).serialize(), - success: function (data) { - // Update the content on the page with the message from the response - $('#login-message').text(data.message); - setTimeout(function () { - location.reload(true); - }, 1750); - }, - error: function (xhr, status, error) { - // Handle error response - if (xhr.status === 403) { - // Update the content on the page with the message from the error response - $('#login-message').text(xhr.responseJSON.message); - } else { - // Handle other types of errors if needed - console.error('Error:', status, error); - } - } - }); - }); +}); - // Assuming you have an anchor tag with id 'logout-link' $('.logout-link').click(function (event) { event.preventDefault(); diff --git a/web/setup.ejs b/web/setup.ejs index e6a7010..59c1d32 100644 --- a/web/setup.ejs +++ b/web/setup.ejs @@ -20,7 +20,6 @@

[ADMIN PANEL]

-
+ diff --git a/web/wizard.ejs b/web/wizard.ejs index 6bc46a0..0b35d71 100644 --- a/web/wizard.ejs +++ b/web/wizard.ejs @@ -39,11 +39,11 @@

Leave the IP at 0.0.0.0 unless you explicitly know you have to change it.
Don't enter your public IP here.

- +
- +
@@ -56,7 +56,7 @@

Tuner type:

Settings a proper device type ensures that the correct interface and settings will load.

- +