Merge remote-tracking branch 'origin/main' into ls-mesh

# Conflicts:
#	tnc/static.py
This commit is contained in:
DJ2LS 2023-05-28 12:19:11 +02:00
commit 9d01fd75a0
15 changed files with 443 additions and 99 deletions

View file

@ -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,
},
],
});

View file

@ -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",\

View file

@ -1,6 +1,6 @@
{
"name": "FreeDATA",
"version": "0.9.2-alpha.5",
"version": "0.9.3-alpha.1",
"description": "FreeDATA ",
"main": "main.js",
"scripts": {

View file

@ -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;

View file

@ -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();
}
//Now start TNC
document.getElementById("startTNC").click();
}
}
setTimeout(() => {
autostart();
}, 5000);
function autostart_tnc() {
if (config.auto_start == 1) {
//Now start TNC
document.getElementById("startTNC").click();
}
}

View file

@ -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"

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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:
"""

View file

@ -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'))

View file

@ -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,10 +1096,12 @@ 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])
self.transmit(
mode=data[0], repeats=data[1], repeat_delay=data[2], frames=data[3]
)
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]
)
# self.modem_transmit_queue.task_done()
def worker_received(self) -> None:
@ -1148,25 +1228,31 @@ class RF:
- HamlibParam.hamlib_bandwidth
"""
while True:
# this looks weird, but is necessary for avoiding rigctld packet colission sock
threading.Event().wait(0.25)
HamlibParam.hamlib_frequency = self.radio.get_frequency()
threading.Event().wait(0.1)
HamlibParam.hamlib_mode = self.radio.get_mode()
threading.Event().wait(0.1)
HamlibParam.hamlib_bandwidth = self.radio.get_bandwidth()
threading.Event().wait(0.1)
HamlibParam.hamlib_status = self.radio.get_status()
threading.Event().wait(0.1)
if TNC.transmitting:
HamlibParam.alc = self.radio.get_alc()
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()
threading.Event().wait(0.1)
# HamlibParam.hamlib_rf = self.radio.get_level()
# threading.Event().wait(0.1)
HamlibParam.hamlib_strength = self.radio.get_strength()
# print(f"ALC: {HamlibParam.alc}, RF: {HamlibParam.hamlib_rf}, STRENGTH: {HamlibParam.hamlib_strength}")
HamlibParam.hamlib_mode = self.radio.get_mode()
threading.Event().wait(0.1)
HamlibParam.hamlib_bandwidth = self.radio.get_bandwidth()
threading.Event().wait(0.1)
HamlibParam.hamlib_status = self.radio.get_status()
threading.Event().wait(0.1)
if TNC.transmitting:
HamlibParam.alc = self.radio.get_alc()
threading.Event().wait(0.1)
# HamlibParam.hamlib_rf = self.radio.get_level()
# threading.Event().wait(0.1)
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

View file

@ -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)

View file

@ -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

View file

@ -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
)