mirror of
https://github.com/DJ2LS/FreeDATA
synced 2024-05-14 08:04:33 +00:00
Merge remote-tracking branch 'origin/main' into ls-mesh
# Conflicts: # tnc/static.py
This commit is contained in:
commit
9d01fd75a0
15 changed files with 443 additions and 99 deletions
|
@ -225,7 +225,9 @@ exports.startTNC = function (
|
|||
enable_explorer,
|
||||
explorer_stats,
|
||||
auto_tune,
|
||||
tx_delay
|
||||
tx_delay,
|
||||
tci_ip,
|
||||
tci_port
|
||||
) {
|
||||
var json_command = JSON.stringify({
|
||||
type: "set",
|
||||
|
@ -260,6 +262,8 @@ exports.startTNC = function (
|
|||
enable_stats: explorer_stats,
|
||||
enable_auto_tune: auto_tune,
|
||||
tx_delay: tx_delay,
|
||||
tci_ip: tci_ip,
|
||||
tci_port: tci_port,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
|
@ -70,6 +70,8 @@ const configDefaultSettings =
|
|||
"hamlib_rigctld_path" : "",\
|
||||
"hamlib_rigctld_server_port" : "4532",\
|
||||
"hamlib_rigctld_custom_args": "",\
|
||||
"tci_port" : "50001",\
|
||||
"tci_ip" : "127.0.0.1",\
|
||||
"spectrum": "waterfall",\
|
||||
"tnclocation": "localhost",\
|
||||
"enable_scatter" : "False",\
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "FreeDATA",
|
||||
"version": "0.9.2-alpha.5",
|
||||
"version": "0.9.3-alpha.1",
|
||||
"description": "FreeDATA ",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
|
@ -1022,6 +1022,28 @@ update_chat = function (obj) {
|
|||
var attempt = obj.attempt;
|
||||
}
|
||||
|
||||
// add percent and bytes per minute if not existing
|
||||
console.log(obj.percent)
|
||||
if (typeof obj.percent == "undefined") {
|
||||
obj.percent = 0;
|
||||
obj.bytesperminute = 0;
|
||||
}
|
||||
|
||||
// check if wrong status message
|
||||
if (obj.status == "transmit" && obj.percent == 0) {
|
||||
var TimeDifference = (new Date().getTime()/1000) - obj.timestamp
|
||||
if (TimeDifference > 3600){
|
||||
db.upsert(obj._id, function (doc) {
|
||||
if (!doc.status) {
|
||||
doc.status = "failed";
|
||||
}
|
||||
return doc;
|
||||
});
|
||||
obj.status = "failed";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof config.max_retry_attempts == "undefined") {
|
||||
var max_retry_attempts = 3;
|
||||
} else {
|
||||
|
@ -1382,6 +1404,8 @@ update_chat = function (obj) {
|
|||
//console.log("Low graphics enabled for chat module");
|
||||
}
|
||||
|
||||
|
||||
|
||||
var new_message = `
|
||||
<div class="d-flex align-items-center">
|
||||
${controlarea_transmit}
|
||||
|
@ -1415,7 +1439,7 @@ update_chat = function (obj) {
|
|||
}%;" aria-valuenow="${
|
||||
obj.percent
|
||||
}" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
<p class="justify-content-center d-flex position-absolute m-0 p-0 w-100 text-white" style="font-size: xx-small" id="msg-${
|
||||
<p class="justify-content-center d-flex position-absolute m-0 p-0 w-100 text-white ${progressbar_bg}" style="font-size: xx-small" id="msg-${
|
||||
obj._id
|
||||
}-progress-information">${percent_value} % - ${
|
||||
obj.bytesperminute
|
||||
|
@ -1436,6 +1460,12 @@ update_chat = function (obj) {
|
|||
console.log("element already exists......");
|
||||
console.log(obj);
|
||||
|
||||
console.log(obj.status)
|
||||
console.log(obj.attempt)
|
||||
|
||||
|
||||
|
||||
|
||||
if (
|
||||
!obj.status == "broadcast_transmit" ||
|
||||
!obj.status == "broadcast_received"
|
||||
|
@ -1456,6 +1486,44 @@ update_chat = function (obj) {
|
|||
document.getElementById("msg-" + obj._id + "-attempts").innerHTML =
|
||||
obj.attempt + "/" + max_retry_attempts;
|
||||
}
|
||||
|
||||
|
||||
if (obj.status == "transmit") {
|
||||
|
||||
document.getElementById("msg-" + obj._id + "-status").innerHTML =
|
||||
get_icon_for_state(obj.status);
|
||||
|
||||
if (typeof obj.percent !== "undefined") {
|
||||
document
|
||||
.getElementById("msg-" + obj._id + "-progress")
|
||||
.setAttribute("aria-valuenow", obj.percent);
|
||||
document
|
||||
.getElementById("msg-" + obj._id + "-progress")
|
||||
.setAttribute("style", "width:" + obj.percent + "%;");
|
||||
document.getElementById(
|
||||
"msg-" + obj._id + "-progress-information"
|
||||
).innerHTML = obj.percent + "% - " + obj.bytesperminute + " Bpm";
|
||||
|
||||
} else {
|
||||
document
|
||||
.getElementById("msg-" + obj._id + "-progress")
|
||||
.setAttribute("aria-valuenow", 0);
|
||||
document
|
||||
.getElementById("msg-" + obj._id + "-progress")
|
||||
.setAttribute("style", "width:0%;");
|
||||
document.getElementById(
|
||||
"msg-" + obj._id + "-progress-information"
|
||||
).innerHTML = "0% - 0 Bpm";
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
document.getElementById("msg-" + obj._id + "-attempts").innerHTML =
|
||||
obj.attempt + "/" + max_retry_attempts;
|
||||
}
|
||||
|
||||
if (obj.status == "transmitted") {
|
||||
//document.getElementById('msg-' + obj._id + '-progress').classList.remove("progress-bar-striped");
|
||||
document
|
||||
|
@ -1496,9 +1564,15 @@ update_chat = function (obj) {
|
|||
.getElementById("msg-" + obj._id + "-progress")
|
||||
.classList.add("bg-danger");
|
||||
|
||||
console.log(document
|
||||
.getElementById("msg-" + obj._id + "-progress")
|
||||
.classList)
|
||||
|
||||
document.getElementById(
|
||||
"msg-" + obj._id + "-progress-information"
|
||||
).innerHTML = "TRANSMISSION FAILED - " + obj.bytesperminute + " Bpm";
|
||||
|
||||
|
||||
}
|
||||
|
||||
//document.getElementById(id).className = message_class;
|
||||
|
|
|
@ -40,6 +40,7 @@ const contrib = [
|
|||
"DF7MH",
|
||||
"G0HWW",
|
||||
"N1QM",
|
||||
"LA3QMA",
|
||||
];
|
||||
|
||||
//let elements = document.querySelectorAll('[id^="hamlib_"]'); // get all elements starting with...
|
||||
|
@ -70,6 +71,11 @@ var noise_level_raw = 0;
|
|||
//Global version variable
|
||||
var appVer = null;
|
||||
|
||||
//Track the number of times TNC has been started
|
||||
//So that warning is shown when using auto start and 2nd start
|
||||
//if hamlib is not running
|
||||
var tncStartCount = 0;
|
||||
|
||||
// START INTERVALL COMMAND EXECUTION FOR STATES
|
||||
//setInterval(sock.getRxBuffer, 1000);
|
||||
|
||||
|
@ -106,6 +112,25 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
};
|
||||
ipcRenderer.send("run-tnc-command", Data);
|
||||
});
|
||||
// save mode event listener
|
||||
document.getElementById("saveModeDIGU").addEventListener("click", () => {
|
||||
let Data = {
|
||||
type: "set",
|
||||
command: "mode",
|
||||
mode: "DIGU",
|
||||
};
|
||||
ipcRenderer.send("run-tnc-command", Data);
|
||||
});
|
||||
|
||||
// save mode event listener
|
||||
document.getElementById("saveModeDIGL").addEventListener("click", () => {
|
||||
let Data = {
|
||||
type: "set",
|
||||
command: "mode",
|
||||
mode: "DIGL",
|
||||
};
|
||||
ipcRenderer.send("run-tnc-command", Data);
|
||||
});
|
||||
|
||||
// save mode event listener
|
||||
document.getElementById("saveModeUSB").addEventListener("click", () => {
|
||||
|
@ -250,6 +275,9 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
document.getElementById("hamlib_rigctld_ip").value = config.hamlib_rigctld_ip;
|
||||
document.getElementById("hamlib_rigctld_port").value =
|
||||
config.hamlib_rigctld_port;
|
||||
document.getElementById("tci_ip").value = config.tci_ip;
|
||||
document.getElementById("tci_port").value = config.tci_port;
|
||||
|
||||
document.getElementById("hamlib_rigctld_path").value =
|
||||
config.hamlib_rigctld_path;
|
||||
document.getElementById("hamlib_rigctld_server_port").value =
|
||||
|
@ -444,24 +472,49 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
if (config.radiocontrol == "rigctld") {
|
||||
document.getElementById("radio-control-switch-disabled").checked = false;
|
||||
document.getElementById("radio-control-switch-rigctld").checked = true;
|
||||
document.getElementById("radio-control-switch-tci").checked = false;
|
||||
|
||||
document.getElementById("radio-control-disabled").style.visibility =
|
||||
"hidden";
|
||||
document.getElementById("radio-control-disabled").style.display = "none";
|
||||
|
||||
document.getElementById("radio-control-tci").style.display = "none";
|
||||
document.getElementById("radio-control-tci").style.visibility = "hidden";
|
||||
|
||||
document.getElementById("radio-control-help").style.visibility = "hidden";
|
||||
document.getElementById("radio-control-help").style.display = "none";
|
||||
|
||||
document.getElementById("radio-control-rigctld").style.visibility =
|
||||
"visible";
|
||||
document.getElementById("radio-control-rigctld").style.display = "block";
|
||||
} else if (config.radiocontrol == "tci") {
|
||||
document.getElementById("radio-control-switch-disabled").checked = false;
|
||||
document.getElementById("radio-control-switch-rigctld").checked = false;
|
||||
document.getElementById("radio-control-switch-tci").checked = true;
|
||||
|
||||
document.getElementById("radio-control-disabled").style.visibility =
|
||||
"hidden";
|
||||
document.getElementById("radio-control-disabled").style.display = "none";
|
||||
|
||||
document.getElementById("radio-control-help").style.visibility = "hidden";
|
||||
document.getElementById("radio-control-help").style.display = "none";
|
||||
document.getElementById("radio-control-rigctld").style.visibility =
|
||||
"hidden";
|
||||
document.getElementById("radio-control-rigctld").style.display = "none";
|
||||
|
||||
document.getElementById("radio-control-tci").style.visibility = "visible";
|
||||
document.getElementById("radio-control-tci").style.display = "block";
|
||||
} else {
|
||||
document.getElementById("radio-control-switch-disabled").checked = true;
|
||||
document.getElementById("radio-control-switch-rigctld").checked = false;
|
||||
document.getElementById("radio-control-switch-tci").checked = false;
|
||||
|
||||
document.getElementById("radio-control-help").style.display = "none";
|
||||
document.getElementById("radio-control-help").style.visibility = "hidden";
|
||||
|
||||
document.getElementById("radio-control-tci").style.display = "none";
|
||||
document.getElementById("radio-control-tci").style.visibility = "hidden";
|
||||
|
||||
document.getElementById("radio-control-rigctld").style.visibility =
|
||||
"hidden";
|
||||
document.getElementById("radio-control-rigctld").style.display = "none";
|
||||
|
@ -536,6 +589,8 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
document.getElementById("radio-control-disabled").style.display = "block";
|
||||
document.getElementById("radio-control-disabled").style.visibility =
|
||||
"visible";
|
||||
document.getElementById("radio-control-tci").style.display = "none";
|
||||
document.getElementById("radio-control-tci").style.visibility = "hidden";
|
||||
|
||||
document.getElementById("radio-control-help").style.display = "none";
|
||||
document.getElementById("radio-control-help").style.visibility = "hidden";
|
||||
|
@ -563,6 +618,9 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
document.getElementById("radio-control-help").style.display = "none";
|
||||
document.getElementById("radio-control-help").style.visibility = "hidden";
|
||||
|
||||
document.getElementById("radio-control-tci").style.display = "none";
|
||||
document.getElementById("radio-control-tci").style.visibility = "hidden";
|
||||
|
||||
document.getElementById("radio-control-rigctld").style.visibility =
|
||||
"visible";
|
||||
document.getElementById("radio-control-rigctld").style.display = "block";
|
||||
|
@ -572,6 +630,32 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
FD.saveConfig(config, configPath);
|
||||
});
|
||||
|
||||
// // radio settings 'rigctld' event listener
|
||||
document
|
||||
.getElementById("radio-control-switch-tci")
|
||||
.addEventListener("click", () => {
|
||||
//document.getElementById("hamlib_info_field").innerHTML =
|
||||
// "Edit your rigctld settings and start and stop rigctld .";
|
||||
|
||||
document.getElementById("radio-control-disabled").style.display = "none";
|
||||
document.getElementById("radio-control-disabled").style.visibility =
|
||||
"hidden";
|
||||
|
||||
document.getElementById("radio-control-rigctld").style.display = "none";
|
||||
document.getElementById("radio-control-rigctld").style.visibility =
|
||||
"hidden";
|
||||
|
||||
document.getElementById("radio-control-help").style.display = "none";
|
||||
document.getElementById("radio-control-help").style.visibility = "hidden";
|
||||
|
||||
document.getElementById("radio-control-tci").style.visibility = "visible";
|
||||
document.getElementById("radio-control-tci").style.display = "block";
|
||||
|
||||
config.radiocontrol = "tci";
|
||||
//fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
||||
FD.saveConfig(config, configPath);
|
||||
});
|
||||
|
||||
document
|
||||
.getElementById("btnHamlibCopyCommand")
|
||||
.addEventListener("click", () => {
|
||||
|
@ -1284,20 +1368,12 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
document.getElementById("wikiUrl").addEventListener("click", () => {
|
||||
shell.openExternal("https://wiki.freedata.app");
|
||||
});
|
||||
// Groups.io Link clicked
|
||||
document.getElementById("groupsioUrl").addEventListener("click", () => {
|
||||
shell.openExternal("https://groups.io/g/freedata");
|
||||
});
|
||||
|
||||
// Discord Link clicked
|
||||
document.getElementById("discordUrl").addEventListener("click", () => {
|
||||
shell.openExternal("https://discord.gg/jnADeDtxUF");
|
||||
});
|
||||
|
||||
//Track the number of times TNC has been started
|
||||
//So that warning is shown when using auto start and 2nd start
|
||||
//if hamlib is not running
|
||||
var tncStartCount = 0;
|
||||
|
||||
// startTNC button clicked
|
||||
document.getElementById("startTNC").addEventListener("click", () => {
|
||||
tncStartCount++;
|
||||
|
@ -1306,6 +1382,10 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
|
||||
var rigctld_ip = document.getElementById("hamlib_rigctld_ip").value;
|
||||
var rigctld_port = document.getElementById("hamlib_rigctld_port").value;
|
||||
|
||||
var tci_ip = document.getElementById("tci_ip").value;
|
||||
var tci_port = document.getElementById("tci_port").value;
|
||||
|
||||
var hamlib_rigctld_server_port = document.getElementById(
|
||||
"hamlib_rigctld_server_port"
|
||||
).value;
|
||||
|
@ -1406,8 +1486,10 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
}
|
||||
}
|
||||
|
||||
if (!document.getElementById("radio-control-switch-disabled").checked) {
|
||||
if (document.getElementById("radio-control-switch-rigctld").checked) {
|
||||
var radiocontrol = "rigctld";
|
||||
} else if (document.getElementById("radio-control-switch-tci").checked) {
|
||||
var radiocontrol = "tci";
|
||||
} else {
|
||||
var radiocontrol = "disabled";
|
||||
}
|
||||
|
@ -1441,6 +1523,8 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
config.explorer_stats = explorer_stats;
|
||||
config.auto_tune = auto_tune;
|
||||
config.tx_delay = tx_delay;
|
||||
config.tci_ip = tci_ip;
|
||||
config.tci_port = tci_port;
|
||||
|
||||
//fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
||||
FD.saveConfig(config, configPath);
|
||||
|
@ -1488,7 +1572,9 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
enable_explorer,
|
||||
explorer_stats,
|
||||
auto_tune,
|
||||
tx_delay
|
||||
tx_delay,
|
||||
tci_ip,
|
||||
tci_port
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -1644,6 +1730,8 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
sorthslTable(7);
|
||||
resetSortIcon();
|
||||
});
|
||||
|
||||
autostart_rigctld();
|
||||
});
|
||||
|
||||
function resetSortIcon() {
|
||||
|
@ -2317,7 +2405,15 @@ function updateHeardStations(arg) {
|
|||
timestampRaw = arg.stations[i]["timestamp"];
|
||||
|
||||
var datetime = new Date(timestampRaw * 1000).toLocaleString(
|
||||
navigator.language
|
||||
navigator.language,{
|
||||
hourCycle: 'h23',
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit"
|
||||
}
|
||||
);
|
||||
//var hours = date.getHours();
|
||||
//var minutes = "0" + date.getMinutes();
|
||||
|
@ -2555,6 +2651,9 @@ ipcRenderer.on("action-update-daemon-state", (event, arg) => {
|
|||
document.getElementById("audio_output_selectbox").add(option);
|
||||
}
|
||||
}
|
||||
//Once audio devices are populated, try starting TNC if it hasn't been started yet in this session
|
||||
//and if autostart is enabled
|
||||
if (tncStartCount <= 0) autostart_tnc();
|
||||
});
|
||||
|
||||
// ACTION UPDATE HAMLIB TEST
|
||||
|
@ -2635,6 +2734,9 @@ ipcRenderer.on("action-update-tnc-connection", (event, arg) => {
|
|||
|
||||
//Set tuning for fancy graphics mode (high/low CPU)
|
||||
set_CPU_mode();
|
||||
|
||||
//GUI will auto connect to TNC if already running, if that is the case increment start count if 0
|
||||
if (tncStartCount==0) tncStartCount++;
|
||||
} else {
|
||||
/*
|
||||
document.getElementById('hamlib_deviceid').disabled = false;
|
||||
|
@ -3642,18 +3744,18 @@ function sorthslTable(n) {
|
|||
}
|
||||
}
|
||||
|
||||
function autostart() {
|
||||
//Auto start stuff if option is enabled
|
||||
function autostart_rigctld() {
|
||||
if (config.auto_start == 1) {
|
||||
//Start rigctld if radiocontrol is in correct mode and is not active
|
||||
if (config.radiocontrol == "rigctld" && rigctldActive == false) {
|
||||
//console.log("Autostarting rigctld");
|
||||
document.getElementById("hamlib_rigctld_start").click();
|
||||
}
|
||||
}
|
||||
}
|
||||
function autostart_tnc() {
|
||||
if (config.auto_start == 1) {
|
||||
//Now start TNC
|
||||
document.getElementById("startTNC").click();
|
||||
}
|
||||
}
|
||||
setTimeout(() => {
|
||||
autostart();
|
||||
}, 5000);
|
||||
|
|
|
@ -407,6 +407,25 @@
|
|||
Hamlib
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="btn-group btn-group-sm"
|
||||
role="group"
|
||||
aria-label="radio-control-switch-tci"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
class="btn-check"
|
||||
name="radio-control-switch"
|
||||
id="radio-control-switch-tci"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<label
|
||||
class="btn btn-sm btn-outline-secondary"
|
||||
for="radio-control-switch-tci"
|
||||
>
|
||||
TCI
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -437,7 +456,7 @@
|
|||
</p>
|
||||
</div>
|
||||
|
||||
<!-- RADIO CONTROL RIGCTLD INFO-->
|
||||
<!-- RADIO CONTROL RIGCTLD -->
|
||||
<div id="radio-control-rigctld">
|
||||
<div class="input-group input-group-sm mb-1">
|
||||
<div class="input-group input-group-sm mb-1">
|
||||
|
@ -502,7 +521,35 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- RADIO CONTROL TCI-->
|
||||
<div id="radio-control-tci">
|
||||
<div class="input-group input-group-sm mb-1">
|
||||
<div class="input-group input-group-sm mb-1">
|
||||
<span class="input-group-text">TCI</span>
|
||||
<span class="input-group-text">Address</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
placeholder="tci IP"
|
||||
id="tci_ip"
|
||||
aria-label="Device IP"
|
||||
aria-describedby="basic-addon1"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="input-group input-group-sm mb-1">
|
||||
<span class="input-group-text">Port</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
placeholder="tci port"
|
||||
id="tci_port"
|
||||
aria-label="Device Port"
|
||||
aria-describedby="basic-addon1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- RADIO CONTROL HELP -->
|
||||
<div id="radio-control-help">
|
||||
<strong>VOX:</strong> Use rig control mode 'none'
|
||||
|
@ -1591,6 +1638,31 @@
|
|||
>
|
||||
PKTUSB
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-secondary"
|
||||
data-bs-placement="bottom"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-trigger="hover"
|
||||
data-bs-html="false"
|
||||
title="set DIGU"
|
||||
id="saveModeDIGU"
|
||||
>
|
||||
DIGU
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-secondary"
|
||||
data-bs-placement="bottom"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-trigger="hover"
|
||||
data-bs-html="false"
|
||||
title="set DIGL"
|
||||
id="saveModeDIGL"
|
||||
>
|
||||
DIGL
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
@ -3783,17 +3855,6 @@
|
|||
role="button"
|
||||
></i>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<i
|
||||
style="font-size: 1.5rem"
|
||||
class="btn bi bi-envelope-at"
|
||||
id="groupsioUrl"
|
||||
data-bs-toggle="tooltip"
|
||||
data-bs-trigger="hover"
|
||||
title="Groups.io"
|
||||
role="button"
|
||||
></i>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<i
|
||||
style="font-size: 1.5rem"
|
||||
|
|
|
@ -10,14 +10,14 @@ ssid_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|||
|
||||
[AUDIO]
|
||||
#audio settings
|
||||
rx = 0
|
||||
tx = 0
|
||||
rx = 6
|
||||
tx = 6
|
||||
txaudiolevel = 250
|
||||
auto_tune = False
|
||||
|
||||
[RADIO]
|
||||
#radio settings
|
||||
radiocontrol = disabled
|
||||
radiocontrol = tci
|
||||
rigctld_ip = 127.0.0.1
|
||||
rigctld_port = 4532
|
||||
|
||||
|
|
|
@ -79,6 +79,11 @@ class CONFIG:
|
|||
'fsk': data[13],
|
||||
'tx_delay': data[21]
|
||||
}
|
||||
self.config['TCI'] = {'#TCI settings': None,
|
||||
'ip': data[22],
|
||||
'port': data[23]
|
||||
}
|
||||
|
||||
try:
|
||||
with open(self.config_name, 'w') as configfile:
|
||||
self.config.write(configfile)
|
||||
|
|
|
@ -131,7 +131,6 @@ class DAEMON:
|
|||
# increase length of list for storing additional
|
||||
# parameters starting at entry 64
|
||||
data = data[:64] + [None] * (64 - len(data))
|
||||
print(data)
|
||||
# data[1] mycall
|
||||
# data[2] mygrid
|
||||
# data[3] rx_audio
|
||||
|
@ -168,8 +167,6 @@ class DAEMON:
|
|||
|
||||
def test_hamlib_ptt(self, data):
|
||||
radiocontrol = data[1]
|
||||
rigctld_ip = data[2]
|
||||
rigctld_port = data[3]
|
||||
|
||||
# check how we want to control the radio
|
||||
if radiocontrol == "direct":
|
||||
|
@ -180,8 +177,18 @@ class DAEMON:
|
|||
sys.exit(1)
|
||||
elif radiocontrol == "rigctld":
|
||||
import rigctld as rig
|
||||
rigctld_ip = data[2]
|
||||
rigctld_port = data[3]
|
||||
|
||||
elif radiocontrol == "tci":
|
||||
import tci as rig
|
||||
rigctld_ip = data[22]
|
||||
rigctld_port = data[23]
|
||||
|
||||
else:
|
||||
import rigdummy as rig
|
||||
rigctld_ip = '127.0.0.1'
|
||||
rigctld_port = '0'
|
||||
|
||||
hamlib = rig.radio()
|
||||
hamlib.open_rig(
|
||||
|
@ -193,7 +200,7 @@ class DAEMON:
|
|||
|
||||
hamlib.set_ptt(True)
|
||||
#Allow a little time for network based rig to register PTT is active
|
||||
time.sleep(.250);
|
||||
time.sleep(.250)
|
||||
if hamlib.get_ptt():
|
||||
self.log.info("[DMN] Hamlib PTT", status="SUCCESS")
|
||||
response = {"command": "test_hamlib", "result": "SUCCESS"}
|
||||
|
@ -236,6 +243,12 @@ class DAEMON:
|
|||
options.extend((data[6], "--rigctld_port"))
|
||||
options.append(data[7])
|
||||
|
||||
if data[5] == "tci":
|
||||
options.append("--tci-ip")
|
||||
options.extend((data[22], "--tci-port"))
|
||||
options.append(data[23])
|
||||
|
||||
|
||||
if data[8] == "True":
|
||||
options.append("--scatter")
|
||||
|
||||
|
@ -296,6 +309,7 @@ class DAEMON:
|
|||
command.append("freedata-tnc.exe")
|
||||
|
||||
command += options
|
||||
|
||||
proc = subprocess.Popen(command)
|
||||
|
||||
atexit.register(proc.kill)
|
||||
|
@ -312,7 +326,6 @@ class DAEMON:
|
|||
|
||||
command.append("main.py")
|
||||
command += options
|
||||
print(command)
|
||||
proc = subprocess.Popen(command)
|
||||
atexit.register(proc.kill)
|
||||
|
||||
|
|
|
@ -2856,6 +2856,9 @@ class DATA:
|
|||
self.enqueue_frame_for_tx([cq_frame], c2_mode=FREEDV_MODE.fsk_ldpc_0.value)
|
||||
else:
|
||||
self.enqueue_frame_for_tx([cq_frame], c2_mode=FREEDV_MODE.sig0.value, copies=1, repeat_delay=0)
|
||||
# FIXME: Remove or change this in later versions for full CW support
|
||||
# TNC.transmitting = True
|
||||
# modem.MODEM_TRANSMIT_QUEUE.put(["morse", 1, 0, "123"])
|
||||
|
||||
def received_cq(self, data_in: bytes) -> None:
|
||||
"""
|
||||
|
|
15
tnc/main.py
15
tnc/main.py
|
@ -127,7 +127,7 @@ if __name__ == "__main__":
|
|||
PARSER.add_argument(
|
||||
"--radiocontrol",
|
||||
dest="hamlib_radiocontrol",
|
||||
choices=["disabled", "direct", "rigctl", "rigctld"],
|
||||
choices=["disabled", "rigctld", "tci"],
|
||||
default="disabled",
|
||||
help="Set how you want to control your radio",
|
||||
)
|
||||
|
@ -222,13 +222,6 @@ if __name__ == "__main__":
|
|||
help="Enable publishing stats to https://freedata.app",
|
||||
)
|
||||
|
||||
PARSER.add_argument(
|
||||
"--tci",
|
||||
dest="audio_enable_tci",
|
||||
action="store_true",
|
||||
help="Enable TCI as audio source",
|
||||
)
|
||||
|
||||
PARSER.add_argument(
|
||||
"--tci-ip",
|
||||
dest="tci_ip",
|
||||
|
@ -240,7 +233,7 @@ if __name__ == "__main__":
|
|||
PARSER.add_argument(
|
||||
"--tci-port",
|
||||
dest="tci_port",
|
||||
default=9000,
|
||||
default=50001,
|
||||
type=int,
|
||||
help="Set tci destination port",
|
||||
)
|
||||
|
@ -303,7 +296,6 @@ if __name__ == "__main__":
|
|||
TNC.enable_explorer = ARGS.enable_explorer
|
||||
AudioParam.audio_auto_tune = ARGS.enable_audio_auto_tune
|
||||
TNC.enable_stats = ARGS.enable_stats
|
||||
AudioParam.audio_enable_tci = ARGS.audio_enable_tci
|
||||
TCIParam.ip = ARGS.tci_ip
|
||||
TCIParam.port = ARGS.tci_port
|
||||
ModemParam.tx_delay = ARGS.tx_delay
|
||||
|
@ -339,7 +331,7 @@ if __name__ == "__main__":
|
|||
AudioParam.audio_output_device = conf.get('AUDIO', 'tx', '0')
|
||||
|
||||
TNC.port = int(conf.get('NETWORK', 'tncport', '3000'))
|
||||
HamlibParam.hamlib_radiocontrol = conf.get('RADIO', 'radiocontrol', 'rigctld')
|
||||
HamlibParam.hamlib_radiocontrol = conf.get('RADIO', 'radiocontrol', 'disabled')
|
||||
HamlibParam.hamlib_rigctld_ip = conf.get('RADIO', 'rigctld_ip', '127.0.0.1')
|
||||
HamlibParam.hamlib_rigctld_port = str(conf.get('RADIO', 'rigctld_port', '4532'))
|
||||
ModemParam.enable_scatter = conf.get('TNC', 'scatter', 'True')
|
||||
|
@ -354,7 +346,6 @@ if __name__ == "__main__":
|
|||
TNC.enable_explorer = conf.get('TNC', 'explorer', 'False')
|
||||
AudioParam.audio_auto_tune = conf.get('AUDIO', 'auto_tune', 'False')
|
||||
TNC.enable_stats = conf.get('TNC', 'stats', 'False')
|
||||
AudioParam.audio_enable_tci = conf.get('AUDIO', 'enable_tci', 'False')
|
||||
TCIParam.ip = str(conf.get('TCI', 'tci_ip', 'localhost'))
|
||||
TCIParam.port = int(conf.get('TCI', 'tci_port', '50001'))
|
||||
ModemParam.tx_delay = int(conf.get('TNC', 'tx_delay', '0'))
|
||||
|
|
131
tnc/modem.py
131
tnc/modem.py
|
@ -28,6 +28,8 @@ from static import FRAME_TYPE
|
|||
import structlog
|
||||
import ujson as json
|
||||
import tci
|
||||
# FIXME: used for def transmit_morse
|
||||
# import cw
|
||||
from queues import DATA_QUEUE_RECEIVED, MODEM_RECEIVED_QUEUE, MODEM_TRANSMIT_QUEUE, RIGCTLD_COMMAND_QUEUE, \
|
||||
AUDIO_RECEIVED_QUEUE, AUDIO_TRANSMIT_QUEUE, MESH_RECEIVED_QUEUE
|
||||
|
||||
|
@ -73,7 +75,7 @@ class RF:
|
|||
|
||||
self.AUDIO_FRAMES_PER_BUFFER_RX = 2400 * 2 # 8192
|
||||
# 8192 Let's do some tests with very small chunks for TX
|
||||
self.AUDIO_FRAMES_PER_BUFFER_TX = 1200 if AudioParam.audio_enable_tci else 2400 * 2
|
||||
self.AUDIO_FRAMES_PER_BUFFER_TX = 1200 if HamlibParam.hamlib_radiocontrol in ["tci"] else 2400 * 2
|
||||
# 8 * (self.AUDIO_SAMPLE_RATE_RX/self.MODEM_SAMPLE_RATE) == 48
|
||||
self.AUDIO_CHANNELS = 1
|
||||
self.MODE = 0
|
||||
|
@ -178,7 +180,7 @@ class RF:
|
|||
self.freedv_ldpc1_tx = open_codec2_instance(codec2.FREEDV_MODE.fsk_ldpc_1.value)
|
||||
|
||||
# --------------------------------------------CREATE PORTAUDIO INSTANCE
|
||||
if not TESTMODE and not AudioParam.audio_enable_tci:
|
||||
if not TESTMODE and not HamlibParam.hamlib_radiocontrol in ["tci"]:
|
||||
try:
|
||||
self.stream = sd.RawStream(
|
||||
channels=1,
|
||||
|
@ -266,12 +268,12 @@ class RF:
|
|||
# Check how we want to control the radio
|
||||
if HamlibParam.hamlib_radiocontrol == "rigctld":
|
||||
import rigctld as rig
|
||||
elif AudioParam.audio_enable_tci:
|
||||
elif HamlibParam.hamlib_radiocontrol == "tci":
|
||||
self.radio = self.tci_module
|
||||
else:
|
||||
import rigdummy as rig
|
||||
|
||||
if not AudioParam.audio_enable_tci:
|
||||
if not HamlibParam.hamlib_radiocontrol in ["tci"]:
|
||||
self.radio = rig.radio()
|
||||
self.radio.open_rig(
|
||||
rigctld_ip=HamlibParam.hamlib_rigctld_ip,
|
||||
|
@ -674,7 +676,7 @@ class RF:
|
|||
alc_level=str(HamlibParam.alc))
|
||||
x = set_audio_volume(x, AudioParam.tx_audio_level)
|
||||
|
||||
if not AudioParam.audio_enable_tci:
|
||||
if not HamlibParam.hamlib_radiocontrol in ["tci"]:
|
||||
txbuffer_out = self.resampler.resample8_to_48(x)
|
||||
else:
|
||||
txbuffer_out = x
|
||||
|
@ -686,25 +688,14 @@ class RF:
|
|||
self.mod_out_locked = True
|
||||
|
||||
# -------------------------------
|
||||
chunk_length = self.AUDIO_FRAMES_PER_BUFFER_TX # 4800
|
||||
chunk = [
|
||||
txbuffer_out[i: i + chunk_length]
|
||||
for i in range(0, len(txbuffer_out), chunk_length)
|
||||
]
|
||||
for c in chunk:
|
||||
# Pad the chunk, if needed
|
||||
if len(c) < chunk_length:
|
||||
delta = chunk_length - len(c)
|
||||
delta_zeros = np.zeros(delta, dtype=np.int16)
|
||||
c = np.append(c, delta_zeros)
|
||||
# self.log.debug("[MDM] mod out shorter than audio buffer", delta=delta)
|
||||
self.modoutqueue.append(c)
|
||||
# add modulation to modout_queue
|
||||
self.enqueue_modulation(txbuffer_out)
|
||||
|
||||
# Release our mod_out_lock, so we can use the queue
|
||||
self.mod_out_locked = False
|
||||
|
||||
# we need to wait manually for tci processing
|
||||
if AudioParam.audio_enable_tci:
|
||||
if HamlibParam.hamlib_radiocontrol in ["tci"]:
|
||||
duration = len(txbuffer_out) / 8000
|
||||
timestamp_to_sleep = time.time() + duration
|
||||
self.log.debug("[MDM] TCI calculated duration", duration=duration)
|
||||
|
@ -717,7 +708,7 @@ class RF:
|
|||
tci_timeout_reached = True
|
||||
|
||||
while self.modoutqueue or not tci_timeout_reached:
|
||||
if AudioParam.audio_enable_tci:
|
||||
if HamlibParam.hamlib_radiocontrol in ["tci"]:
|
||||
if time.time() < timestamp_to_sleep:
|
||||
tci_timeout_reached = False
|
||||
else:
|
||||
|
@ -745,6 +736,93 @@ class RF:
|
|||
transmission_time = end_of_transmission - start_of_transmission
|
||||
self.log.debug("[MDM] ON AIR TIME", time=transmission_time)
|
||||
|
||||
def transmit_morse(self, repeats, repeat_delay, frames):
|
||||
TNC.transmitting = True
|
||||
# if we're transmitting FreeDATA signals, reset channel busy state
|
||||
ModemParam.channel_busy = False
|
||||
self.log.debug(
|
||||
"[MDM] TRANSMIT", mode="MORSE"
|
||||
)
|
||||
start_of_transmission = time.time()
|
||||
|
||||
txbuffer = cw.MorseCodePlayer().text_to_signal("DJ2LS-1")
|
||||
print(txbuffer)
|
||||
print(type(txbuffer))
|
||||
x = np.frombuffer(txbuffer, dtype=np.int16)
|
||||
print(type(x))
|
||||
txbuffer_out = x
|
||||
print(txbuffer_out)
|
||||
|
||||
#if not HamlibParam.hamlib_radiocontrol in ["tci"]:
|
||||
# txbuffer_out = self.resampler.resample8_to_48(x)
|
||||
#else:
|
||||
# txbuffer_out = x
|
||||
|
||||
self.mod_out_locked = True
|
||||
self.enqueue_modulation(txbuffer_out)
|
||||
self.mod_out_locked = False
|
||||
|
||||
# we need to wait manually for tci processing
|
||||
if HamlibParam.hamlib_radiocontrol in ["tci"]:
|
||||
duration = len(txbuffer_out) / 8000
|
||||
timestamp_to_sleep = time.time() + duration
|
||||
self.log.debug("[MDM] TCI calculated duration", duration=duration)
|
||||
tci_timeout_reached = False
|
||||
#while time.time() < timestamp_to_sleep:
|
||||
# threading.Event().wait(0.01)
|
||||
else:
|
||||
timestamp_to_sleep = time.time()
|
||||
# set tci timeout reached to True for overriding if not used
|
||||
tci_timeout_reached = True
|
||||
|
||||
while self.modoutqueue or not tci_timeout_reached:
|
||||
if HamlibParam.hamlib_radiocontrol in ["tci"]:
|
||||
if time.time() < timestamp_to_sleep:
|
||||
tci_timeout_reached = False
|
||||
else:
|
||||
tci_timeout_reached = True
|
||||
|
||||
threading.Event().wait(0.01)
|
||||
# if we're transmitting FreeDATA signals, reset channel busy state
|
||||
ModemParam.channel_busy = False
|
||||
|
||||
|
||||
|
||||
|
||||
HamlibParam.ptt_state = self.radio.set_ptt(False)
|
||||
|
||||
# Push ptt state to socket stream
|
||||
jsondata = {"ptt": "False"}
|
||||
data_out = json.dumps(jsondata)
|
||||
sock.SOCKET_QUEUE.put(data_out)
|
||||
|
||||
# After processing, set the locking state back to true to be prepared for next transmission
|
||||
self.mod_out_locked = True
|
||||
|
||||
self.modem_transmit_queue.task_done()
|
||||
TNC.transmitting = False
|
||||
threading.Event().set()
|
||||
|
||||
end_of_transmission = time.time()
|
||||
transmission_time = end_of_transmission - start_of_transmission
|
||||
self.log.debug("[MDM] ON AIR TIME", time=transmission_time)
|
||||
|
||||
def enqueue_modulation(self, txbuffer_out):
|
||||
chunk_length = self.AUDIO_FRAMES_PER_BUFFER_TX # 4800
|
||||
chunk = [
|
||||
txbuffer_out[i: i + chunk_length]
|
||||
for i in range(0, len(txbuffer_out), chunk_length)
|
||||
]
|
||||
for c in chunk:
|
||||
# Pad the chunk, if needed
|
||||
if len(c) < chunk_length:
|
||||
delta = chunk_length - len(c)
|
||||
delta_zeros = np.zeros(delta, dtype=np.int16)
|
||||
c = np.append(c, delta_zeros)
|
||||
# self.log.debug("[MDM] mod out shorter than audio buffer", delta=delta)
|
||||
self.modoutqueue.append(c)
|
||||
|
||||
|
||||
def demodulate_audio(
|
||||
self,
|
||||
audiobuffer: codec2.audio_buffer,
|
||||
|
@ -1018,7 +1096,9 @@ class RF:
|
|||
self.log.debug("[MDM] self.modem_transmit_queue", qsize=queuesize)
|
||||
data = self.modem_transmit_queue.get()
|
||||
|
||||
# self.log.debug("[MDM] worker_transmit", mode=data[0])
|
||||
if data[0] in ["morse"]:
|
||||
self.transmit_morse(repeats=data[1], repeat_delay=data[2], frames=data[3])
|
||||
else:
|
||||
self.transmit(
|
||||
mode=data[0], repeats=data[1], repeat_delay=data[2], frames=data[3]
|
||||
)
|
||||
|
@ -1148,6 +1228,7 @@ class RF:
|
|||
- HamlibParam.hamlib_bandwidth
|
||||
"""
|
||||
while True:
|
||||
try:
|
||||
# this looks weird, but is necessary for avoiding rigctld packet colission sock
|
||||
threading.Event().wait(0.25)
|
||||
HamlibParam.hamlib_frequency = self.radio.get_frequency()
|
||||
|
@ -1166,7 +1247,12 @@ class RF:
|
|||
HamlibParam.hamlib_strength = self.radio.get_strength()
|
||||
|
||||
# print(f"ALC: {HamlibParam.alc}, RF: {HamlibParam.hamlib_rf}, STRENGTH: {HamlibParam.hamlib_strength}")
|
||||
|
||||
except Exception as e:
|
||||
self.log.warning(
|
||||
"[MDM] error getting radio data",
|
||||
e=e,
|
||||
)
|
||||
threading.Event().wait(1)
|
||||
def calculate_fft(self) -> None:
|
||||
"""
|
||||
Calculate an average signal strength of the channel to assess
|
||||
|
@ -1408,3 +1494,4 @@ def get_modem_error_state():
|
|||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
|
|
@ -968,6 +968,8 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler):
|
|||
enable_auto_tune = str(helpers.return_key_from_object("False", startparam, "enable_auto_tune"))
|
||||
enable_stats = str(helpers.return_key_from_object("False", startparam, "enable_stats"))
|
||||
tx_delay = str(helpers.return_key_from_object("0", startparam, "tx_delay"))
|
||||
tci_ip = str(helpers.return_key_from_object("127.0.0.1", startparam, "tci_ip"))
|
||||
tci_port = str(helpers.return_key_from_object("50001", startparam, "tci_port"))
|
||||
try:
|
||||
# convert ssid list to python list
|
||||
ssid_list = str(helpers.return_key_from_object("0, 1, 2, 3, 4, 5, 6, 7, 8, 9", startparam, "ssid_list"))
|
||||
|
@ -1008,7 +1010,9 @@ class ThreadedTCPRequestHandler(socketserver.StreamRequestHandler):
|
|||
ssid_list,
|
||||
enable_auto_tune,
|
||||
enable_stats,
|
||||
tx_delay
|
||||
tx_delay,
|
||||
tci_ip,
|
||||
tci_port
|
||||
]
|
||||
)
|
||||
command_response("start_tnc", True)
|
||||
|
|
|
@ -55,8 +55,6 @@ class AudioParam:
|
|||
audio_record_file = ''
|
||||
buffer_overflow_counter = [0, 0, 0, 0, 0]
|
||||
audio_auto_tune: bool = False
|
||||
# Audio TCI Support
|
||||
audio_enable_tci: bool = False
|
||||
audio_dbfs: int = 0
|
||||
fft = []
|
||||
enable_fft: bool = True
|
||||
|
|
|
@ -155,7 +155,7 @@ class TCICtrl:
|
|||
|
||||
|
||||
|
||||
def on_error(self, error):
|
||||
def on_error(self, ws, error):
|
||||
self.log.error(
|
||||
"[TCI] Error FreeDATA to TCI rig!", ip=self.hostname, port=self.port, e=error
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue