1
0
mirror of https://github.com/KubaPro010/fm-dx-webserver.git synced 2026-02-27 06:23:53 +01:00

ui, rds changes, bugfixes

This commit is contained in:
NoobishSVK
2024-02-18 23:33:08 +01:00
parent 3dd0977ac1
commit e11ecdfcc3
8 changed files with 116 additions and 34 deletions

View File

@@ -204,9 +204,11 @@ const clientUpdateIntervals = new Map(); // Store update intervals for each clie
// Initialize the data object // Initialize the data object
var dataToSend = { var dataToSend = {
pi: '?', pi: '?',
freq: 87.500.toFixed(3), freq: 87.500,
previousFreq: 87.500,
signal: 0, signal: 0,
st: false, st: false,
st_forced: false,
ps: '', ps: '',
tp: false, tp: false,
ta: 0, ta: 0,
@@ -243,7 +245,6 @@ function handleData(ws, receivedData) {
const currentTime = Date.now(); const currentTime = Date.now();
let modifiedData, parsedValue; let modifiedData, parsedValue;
const receivedLines = receivedData.split('\n'); const receivedLines = receivedData.split('\n');
for (const receivedLine of receivedLines) { for (const receivedLine of receivedLines) {
switch (true) { switch (true) {
case receivedLine.startsWith('P'): case receivedLine.startsWith('P'):
@@ -261,6 +262,7 @@ function handleData(ws, receivedData) {
parsedValue = parseFloat(modifiedData); parsedValue = parseFloat(modifiedData);
if (!isNaN(parsedValue)) { if (!isNaN(parsedValue)) {
initialData.freq = (parsedValue / 1000).toFixed(3);
dataToSend.freq = (parsedValue / 1000).toFixed(3); dataToSend.freq = (parsedValue / 1000).toFixed(3);
dataToSend.pi = '?'; dataToSend.pi = '?';
} }
@@ -300,6 +302,9 @@ function handleData(ws, receivedData) {
modifiedData = receivedLine.substring(2); modifiedData = receivedLine.substring(2);
parsedValue = parseFloat(modifiedData); parsedValue = parseFloat(modifiedData);
dataToSend.st = false; dataToSend.st = false;
dataToSend.st_forced = false;
initialData.st = false;
initialData.st_forced = false;
if (!isNaN(parsedValue)) { if (!isNaN(parsedValue)) {
dataToSend.signal = parsedValue.toFixed(2); dataToSend.signal = parsedValue.toFixed(2);
@@ -310,13 +315,41 @@ function handleData(ws, receivedData) {
modifiedData = receivedData.substring(2); modifiedData = receivedData.substring(2);
parsedValue = parseFloat(modifiedData); parsedValue = parseFloat(modifiedData);
dataToSend.st = true; dataToSend.st = true;
dataToSend.st_forced = false;
initialData.st = true;
initialData.st_forced = false;
if (!isNaN(parsedValue)) { if (!isNaN(parsedValue)) {
dataToSend.signal = parsedValue.toFixed(2); dataToSend.signal = parsedValue.toFixed(2);
initialData.signal = parsedValue.toFixed(2); initialData.signal = parsedValue.toFixed(2);
} }
break; break;
case receivedData.startsWith('SS'):
modifiedData = receivedData.substring(2);
parsedValue = parseFloat(modifiedData);
dataToSend.st = true;
dataToSend.st_forced = true;
initialData.st = true;
initialData.st_forced = true;
if (!isNaN(parsedValue)) {
dataToSend.signal = parsedValue.toFixed(2);
initialData.signal = parsedValue.toFixed(2);
}
break;
case receivedData.startsWith('SM'):
modifiedData = receivedData.substring(2);
parsedValue = parseFloat(modifiedData);
dataToSend.st = false;
dataToSend.st_forced = true;
initialData.st = false;
initialData.st_forced = true;
if (!isNaN(parsedValue)) {
dataToSend.signal = parsedValue.toFixed(2);
initialData.signal = parsedValue.toFixed(2);
}
break;
case receivedLine.startsWith('R'): case receivedLine.startsWith('R'):
modifiedData = receivedLine.slice(1); modifiedData = receivedLine.slice(1);

View File

@@ -1,6 +1,6 @@
{ {
"name": "fm-dx-webserver", "name": "fm-dx-webserver",
"version": "1.0.6", "version": "1.0.8",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@@ -54,7 +54,7 @@ function parseAudioDevice(options, callback) {
} }
}); });
} else { } else {
console.log('No matches found.'); logWarn('No audio devices have been found.');
} }
}); });
break; break;

View File

@@ -23,7 +23,7 @@ function fetchTx(freq, piCode, rdsPs) {
return processData(cachedData[freq], piCode, rdsPs); return processData(cachedData[freq], piCode, rdsPs);
} }
const url = "https://maps.fmdx.pl/controller.php?freq=" + freq; const url = "https://maps.fmdx.pl/api?freq=" + freq;
return fetch(url) return fetch(url)
.then(response => response.json()) .then(response => response.json())
@@ -40,8 +40,9 @@ function fetchTx(freq, piCode, rdsPs) {
function processData(data, piCode, rdsPs) { function processData(data, piCode, rdsPs) {
let matchingStation = null; let matchingStation = null;
let matchingCity = null; let matchingCity = null;
let minDistance = Infinity; let maxScore = -Infinity; // Initialize maxScore with a very low value
let txAzimuth; let txAzimuth;
let maxDistance;
for (const cityId in data.locations) { for (const cityId in data.locations) {
const city = data.locations[cityId]; const city = data.locations[cityId];
@@ -49,11 +50,13 @@ function processData(data, piCode, rdsPs) {
for (const station of city.stations) { for (const station of city.stations) {
if (station.pi === piCode && !station.extra && station.ps && station.ps.toLowerCase().includes(rdsPs.replace(/ /g, '_').replace(/^_*(.*?)_*$/, '$1').toLowerCase())) { if (station.pi === piCode && !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); const distance = haversine(serverConfig.identification.lat, serverConfig.identification.lon, city.lat, city.lon);
if (distance.distanceKm < minDistance) { const score = station.erp / distance.distanceKm; // Calculate score
minDistance = distance.distanceKm; if (score > maxScore) {
maxScore = score;
txAzimuth = distance.azimuth; txAzimuth = distance.azimuth;
matchingStation = station; matchingStation = station;
matchingCity = city; matchingCity = city;
maxDistance = distance.distanceKm;
} }
} }
} }
@@ -67,7 +70,7 @@ function processData(data, piCode, rdsPs) {
erp: matchingStation.erp, erp: matchingStation.erp,
city: matchingCity.name, city: matchingCity.name,
itu: matchingCity.itu, itu: matchingCity.itu,
distance: minDistance.toFixed(0), distance: maxDistance.toFixed(0),
azimuth: txAzimuth.toFixed(0), azimuth: txAzimuth.toFixed(0),
foundStation: true foundStation: true
}; };

View File

@@ -94,10 +94,11 @@
.modal-panel-content { .modal-panel-content {
flex: 1; flex: 1;
position: relative; position: relative;
overflow-y: auto;
} }
.modal-panel-content .version-info { .modal-panel-content .version-info {
margin-top: 75px; margin-top: 20px;
width: 100%; width: 100%;
} }

View File

@@ -229,10 +229,19 @@
<li class="option" data-value="dbm">dBm</li> <li class="option" data-value="dbm">dBm</li>
</ul> </ul>
</div> </div>
</div><br>
<div class="form-group checkbox">
<input type="checkbox" id="extended-frequency-range">
<label for="extended-frequency-range">Add decimals manually</label>
</div>
<div class="form-group checkbox">
<input type="checkbox" id="ps-underscores">
<label for="ps-underscores">Add undercores to RDS PS</label>
</div> </div>
<div class="form-group bottom-20 hide-desktop" style="float: none;"> <div class="form-group bottom-20 hide-desktop" style="float: none;">
<label for="themes"><i class="fa-solid fa-user"></i> Users online:</label> <label for="users-online"><i class="fa-solid fa-user"></i> Users online:</label>
<span class="users-online" name="users-online">0</span> <span class="users-online" name="users-online">0</span>
</div> </div>
@@ -259,7 +268,7 @@
<div class="version-info"> <div class="version-info">
<p class="text-small">FM-DX WebServer <br>by <a href="https://noobish.eu" target="_blank">Noobish</a> & the OpenRadio community.</p> <p class="text-small">FM-DX WebServer <br>by <a href="https://noobish.eu" target="_blank">Noobish</a> & the OpenRadio community.</p>
<span style="color: var(--color-3);">v1.0.6 [16/2/2024]</span> <span style="color: var(--color-3);">v1.0.7 [18/2/2024]</span>
<p class="text-small bottom-50"> <p class="text-small bottom-50">
<span class="text-smaller">librds & maps.fmdx.pl by <a href="https://fmdx.pl" target="_blank">Konrad Kosmatka</a></span><br> <span class="text-smaller">librds & maps.fmdx.pl by <a href="https://fmdx.pl" target="_blank">Konrad Kosmatka</a></span><br>
<span class="text-smaller">3LAS by <a href="https://github.com/JoJoBond/3LAS" target="_blank">JoJoBond</a></span><br> <span class="text-smaller">3LAS by <a href="https://github.com/JoJoBond/3LAS" target="_blank">JoJoBond</a></span><br>

View File

@@ -2,9 +2,8 @@ var url = new URL('text', window.location.href);
url.protocol = url.protocol.replace('http', 'ws'); url.protocol = url.protocol.replace('http', 'ws');
var socketAddress = url.href; var socketAddress = url.href;
var socket = new WebSocket(socketAddress); var socket = new WebSocket(socketAddress);
var parsedData; var parsedData, signalChart, previousFreq;
var data = []; var data = [];
let signalChart;
let updateCounter = 0; let updateCounter = 0;
const europe_programmes = [ const europe_programmes = [
@@ -71,7 +70,8 @@ $(document).ready(function () {
}); });
textInput.on('keyup', function (event) { textInput.on('keyup', function (event) {
if (event.key !== 'Backspace') {
if (event.key !== 'Backspace' && localStorage.getItem('extendedFreqRange') != "true") {
let inputValue = textInput.val(); let inputValue = textInput.val();
inputValue = inputValue.replace(/[^0-9.]/g, ''); inputValue = inputValue.replace(/[^0-9.]/g, '');
@@ -174,17 +174,13 @@ function getInitialSettings() {
} }
function getLocalizedTime(serverTime) { function getLocalizedTime(serverTime) {
// Convert server time to a Date object
const serverDate = new Date(serverTime); const serverDate = new Date(serverTime);
// Calculate local time by adding the offset // Format server time using options for local time formatting
const localTime = new Date(serverDate.getTime());
// Format local time
const options = { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false }; const options = { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false };
const formattedLocalTime = localTime.toLocaleString(navigator.language ? navigator.language : 'en-US', options); const formattedServerTime = serverDate.toLocaleString(navigator.language ? navigator.language : 'en-US', options);
return formattedLocalTime; return formattedServerTime;
} }
function getServerTime() { function getServerTime() {
@@ -192,12 +188,8 @@ function getServerTime() {
url: './server_time', url: './server_time',
dataType: 'json', dataType: 'json',
success: function (data) { success: function (data) {
// Convert server time to local time format $('#server-time').text(getLocalizedTime(data.serverTime));
const localizedTimeServer = getLocalizedTime(data.serverTime); $('#client-time').text(getLocalizedTime(new Date()));
const localizedTimeClient = getLocalizedTime(new Date().toISOString());
$('#server-time').text(localizedTimeServer);
$('#client-time').text(localizedTimeClient);
}, },
error: function (error) { error: function (error) {
console.error('Error:', error); console.error('Error:', error);
@@ -389,6 +381,9 @@ function checkKey(e) {
if (socket.readyState === WebSocket.OPEN) { if (socket.readyState === WebSocket.OPEN) {
switch (e.keyCode) { switch (e.keyCode) {
case 66: // Back to previous frequency
socket.send("T" + (previousFreq * 1000));
break;
case 82: // RDS Reset (R key) case 82: // RDS Reset (R key)
socket.send("T" + (currentFreq.toFixed(1) * 1000)); socket.send("T" + (currentFreq.toFixed(1) * 1000));
break; break;
@@ -408,6 +403,7 @@ function checkKey(e) {
// Handle default case if needed // Handle default case if needed
break; break;
} }
previousFreq = currentFreq;
} }
} }
@@ -571,6 +567,9 @@ function updateDataElements(parsedData) {
$('#data-frequency').text(parsedData.freq); $('#data-frequency').text(parsedData.freq);
$("#commandinput").attr("aria-label", "Current frequency: " + parsedData.freq); $("#commandinput").attr("aria-label", "Current frequency: " + parsedData.freq);
$('#data-pi').html(parsedData.pi === '?' ? "<span class='opacity-half'>?</span>" : parsedData.pi); $('#data-pi').html(parsedData.pi === '?' ? "<span class='opacity-half'>?</span>" : parsedData.pi);
if (localStorage.getItem('psUnderscores') === 'true') {
parsedData.ps = parsedData.ps.replace(/\s/g, '_');
}
$('#data-ps').html(parsedData.ps === '?' ? "<span class='opacity-half'>?</span>" : processString(parsedData.ps, parsedData.ps_errors)); $('#data-ps').html(parsedData.ps === '?' ? "<span class='opacity-half'>?</span>" : processString(parsedData.ps, parsedData.ps_errors));
$('.data-tp').html(parsedData.tp === false ? "<span class='opacity-half'>TP</span>" : "TP"); $('.data-tp').html(parsedData.tp === false ? "<span class='opacity-half'>TP</span>" : "TP");
$('.data-ta').html(parsedData.ta === 0 ? "<span class='opacity-half'>TA</span>" : "TA"); $('.data-ta').html(parsedData.ta === 0 ? "<span class='opacity-half'>TA</span>" : "TA");
@@ -582,15 +581,30 @@ function updateDataElements(parsedData) {
) )
); );
$('.data-pty').html(europe_programmes[parsedData.pty]); $('.data-pty').html(europe_programmes[parsedData.pty]);
$('.data-st').html(parsedData.st === false ? "<span class='text-gray'>ST</span>" : "ST");
if(parsedData.st === true) {
if (parsedData.st_forced == true) {
$('.data-st').html("<span class='opacity-full'>MO</span>");
} else {
$('.data-st').html("<span class='opacity-full'>ST</span>");
}
} else {
if (parsedData.st_forced == true) {
$('.data-st').html("<span class='opacity-half'>MO</span>");
} else {
$('.data-st').html("<span class='opacity-half'>ST</span>");
}
}
console.log(parsedData.st, parsedData.st_forced);
$('#data-rt0').html(processString(parsedData.rt0, parsedData.rt0_errors)); $('#data-rt0').html(processString(parsedData.rt0, parsedData.rt0_errors));
$('#data-rt1').html(processString(parsedData.rt1, parsedData.rt1_errors)); $('#data-rt1').html(processString(parsedData.rt1, parsedData.rt1_errors));
$('.data-flag').html(`<i title="${parsedData.country_name}" class="flag-sm flag-sm-${parsedData.country_iso}"></i>`); $('.data-flag').html(`<i title="${parsedData.country_name}" class="flag-sm flag-sm-${parsedData.country_iso}"></i>`);
$('#data-ant input').val($('#data-ant li[data-value="' + parsedData.ant + '"]').text()); $('#data-ant input').val($('#data-ant li[data-value="' + parsedData.ant + '"]').text());
if (parsedData.txInfo.station.length > 1) { if (parsedData.txInfo.station.length > 1) {
const sanitizedStation = parsedData.txInfo.station.replace(/%/g, '%25'); $('#data-station-name').text(parsedData.txInfo.station.replace(/%/g, '%25'));
$('#data-station-name').text(decodeURIComponent(sanitizedStation.replace(/\u009e/g, '\u017E')));
$('#data-station-erp').text(parsedData.txInfo.erp); $('#data-station-erp').text(parsedData.txInfo.erp);
$('#data-station-city').text(parsedData.txInfo.city); $('#data-station-city').text(parsedData.txInfo.city);
$('#data-station-itu').text(parsedData.txInfo.itu); $('#data-station-itu').text(parsedData.txInfo.itu);

View File

@@ -104,6 +104,28 @@
}); });
}); });
var extendedFreqRange = localStorage.getItem("extendedFreqRange");
if (extendedFreqRange === "true") {
$("#extended-frequency-range").prop("checked", true);
}
// Save the value of the checkbox into local storage when its state changes
$("#extended-frequency-range").change(function() {
var isChecked = $(this).is(":checked");
localStorage.setItem("extendedFreqRange", isChecked);
});
var extendedFreqRange = localStorage.getItem("psUnderscores");
if (extendedFreqRange === "true") {
$("#ps-underscores").prop("checked", true);
}
// Save the value of the checkbox into local storage when its state changes
$("#ps-underscores").change(function() {
var isChecked = $(this).is(":checked");
localStorage.setItem("psUnderscores", isChecked);
});
}); });