support for different ways controlling the radio

#121 direct, rigctl (for windows), rigctld. Highly experimental. Just to save data.
This commit is contained in:
dj2ls 2022-01-18 19:38:05 +01:00
parent cc1c7e49b0
commit 10d3d5c53e
12 changed files with 730 additions and 538 deletions

View file

@ -140,7 +140,7 @@ exports.getDaemonState = function() {
// START TNC
// ` `== multi line string
exports.startTNC = function(mycall, mygrid, rx_audio, tx_audio, devicename, deviceport, pttprotocol, pttport, serialspeed, data_bits, stop_bits, handshake) {
exports.startTNC = function(mycall, mygrid, rx_audio, tx_audio, radiocontrol, devicename, deviceport, pttprotocol, pttport, serialspeed, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port) {
var json_command = JSON.stringify({
type: 'SET',
command: 'STARTTNC',
@ -149,6 +149,7 @@ exports.startTNC = function(mycall, mygrid, rx_audio, tx_audio, devicename, devi
mygrid: mygrid,
rx_audio: rx_audio,
tx_audio: tx_audio,
radiocontrol: radiocontrol,
devicename: devicename,
deviceport: deviceport,
pttprotocol: pttprotocol,
@ -156,8 +157,9 @@ exports.startTNC = function(mycall, mygrid, rx_audio, tx_audio, devicename, devi
serialspeed: serialspeed,
data_bits: data_bits,
stop_bits: stop_bits,
handshake: handshake
handshake: handshake,
rigctld_port: rigctld_port,
rigctld_ip: rigctld_ip
}]
})
@ -173,12 +175,13 @@ exports.stopTNC = function() {
}
// TEST HAMLIB
exports.testHamlib = function(devicename, deviceport, serialspeed, pttprotocol, pttport, data_bits, stop_bits, handshake) {
exports.testHamlib = function(radiocontrol, devicename, deviceport, serialspeed, pttprotocol, pttport, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port) {
var json_command = JSON.stringify({
type: 'GET',
command: 'TEST_HAMLIB',
parameter: [{
radiocontrol: radiocontrol,
devicename: devicename,
deviceport: deviceport,
pttprotocol: pttprotocol,
@ -186,8 +189,9 @@ exports.testHamlib = function(devicename, deviceport, serialspeed, pttprotocol,
serialspeed: serialspeed,
data_bits: data_bits,
stop_bits: stop_bits,
handshake: handshake
handshake: handshake,
rigctld_port: rigctld_port,
rigctld_ip: rigctld_ip
}]
})
console.log(json_command)

View file

@ -34,7 +34,15 @@ var configContent = `
"tnclocation": "localhost",
"stop_bits" : "1",
"data_bits" : "8",
"handshake" : "None"
"handshake" : "None",
"radiocontrol" : "direct",
"deviceport_rigctl" : "3",
"deviceid_rigctl" : "3",
"serialspeed_rigctl" : "9600",
"pttprotocol_rigctl" : "USB",
"rigctld_port" : "4532",
"rigctld_ip" : "127.0.0.1"
}
`;
if (!fs.existsSync(configPath)) {

View file

@ -24,22 +24,6 @@ setInterval(daemon.getDaemonState, 1000)
setInterval(sock.getTncState, 150)
setInterval(sock.getRxBuffer, 1000)
setInterval(sock.getMsgRxBuffer, 1000)
// UPDATE FFT DEMO
/*
updateFFT = function(fft) {
var fft = Array.from({
length: 2048
}, () => Math.floor(Math.random() * 10));
spectrum.addData(fft);
console.log(fft)
}
setInterval(updateFFT, 250)
*/
// WINDOW LISTENER
window.addEventListener('DOMContentLoaded', () => {
@ -67,18 +51,19 @@ window.addEventListener('DOMContentLoaded', () => {
document.getElementById("myCall").value = config.mycall
document.getElementById("myGrid").value = config.mygrid
//document.getElementById("audio_output_selectbox").value = config.tx_audio
//document.getElementById("audio_input_selectbox").value = config.rx_audio
document.getElementById('hamlib_deviceid').value = config.deviceid
//document.getElementById('hamlib_deviceport').value = config.deviceport
document.getElementById('hamlib_serialspeed').value = config.serialspeed
document.getElementById('hamlib_ptt_protocol').value = config.pttprotocol
//document.getElementById('hamlib_deviceport_advanced').value = config.deviceport
document.getElementById("hamlib_rigctld_ip").value = config.rigctld_ip
document.getElementById("hamlib_rigctld_port").value = config.rigctld_port
document.getElementById("hamlib_deviceid_rigctl").value = config.deviceid_rigctl
document.getElementById("hamlib_serialspeed_rigctl").value = config.serialspeed_rigctl
document.getElementById("hamlib_ptt_protocol_rigctl").value = config.pttprotocol_rigctl
document.getElementById('hamlib_serialspeed_advanced').value = config.serialspeed
document.getElementById('hamlib_ptt_protocol_advanced').value = config.pttprotocol
//document.getElementById('hamlib_ptt_port_advanced').value = config.pttport
document.getElementById('hamlib_databits_advanced').value = config.data_bits
document.getElementById('hamlib_stopbits_advanced').value = config.stop_bits
document.getElementById('hamlib_handshake_advanced').value = config.handshake
@ -101,6 +86,54 @@ window.addEventListener('DOMContentLoaded', () => {
document.getElementById("waterfall").style.height = '0px';
}
// radio control element
if (config.radiocontrol == 'rigctl') {
document.getElementById("radio-control-switch1").checked = false
document.getElementById("radio-control-switch2").checked = true
document.getElementById("radio-control-switch3").checked = false
document.getElementById("radio-control-direct").style.visibility = 'hidden';
document.getElementById("radio-control-rigctld").style.visibility = 'hidden';
document.getElementById("radio-control-direct").style.display = 'none';
document.getElementById("radio-control-rigctld").style.display = 'none';
document.getElementById("radio-control-rigctl").style.display = 'block';
document.getElementById("radio-control-rigctl").style.visibility = 'visible';
document.getElementById("radio-control-rigctl").style.height = '100%';
} else if (config.radiocontrol == 'rigctld') {
document.getElementById("radio-control-switch1").checked = false
document.getElementById("radio-control-switch2").checked = false
document.getElementById("radio-control-switch3").checked = true
document.getElementById("radio-control-direct").style.visibility = 'hidden';
document.getElementById("radio-control-rigctl").style.visibility = 'hidden';
document.getElementById("radio-control-direct").style.display = 'none';
document.getElementById("radio-control-rigctl").style.display = 'none';
document.getElementById("radio-control-rigctld").style.display = 'block';
document.getElementById("radio-control-rigctld").style.visibility = 'visible';
document.getElementById("radio-control-rigctld").style.height = '100%';
} else {
document.getElementById("radio-control-switch1").checked = true
document.getElementById("radio-control-switch2").checked = false
document.getElementById("radio-control-switch3").checked = false
document.getElementById("radio-control-rigctl").style.visibility = 'hidden';
document.getElementById("radio-control-rigctld").style.visibility = 'hidden';
document.getElementById("radio-control-rigctl").style.display = 'none';
document.getElementById("radio-control-rigctld").style.display = 'none';
document.getElementById("radio-control-direct").style.display = 'block';
document.getElementById("radio-control-direct").style.visibility = 'visible';
document.getElementById("radio-control-direct").style.height = '100%';
}
// remote tnc
if (config.tnclocation == 'remote') {
document.getElementById("local-remote-switch1").checked = false
@ -120,63 +153,48 @@ window.addEventListener('DOMContentLoaded', () => {
// on click radio control toggle view
// direct
document.getElementById("radio-control-switch1").addEventListener("click", () => {
document.getElementById("radio-control-rigctl").style.visibility = 'hidden';
document.getElementById("radio-control-rigctld").style.visibility = 'hidden';
document.getElementById("radio-control-rigctl").style.display = 'none';
document.getElementById("radio-control-rigctld").style.display = 'none';
// SETUP OF SCATTER DIAGRAM
/*
global.data = {
datasets: [{
label: 'Scatter Dataset',
data: [{
x: 0,
y: 0
}],
backgroundColor: 'rgb(255, 99, 132)'
}],
};
var ctx = document.getElementById('scatter').getContext('2d');
global.myChart = new Chart(ctx, {
type: 'scatter',
data: data,
options: {
animation: false,
legend: {
display: false
},
scales: {
display: false,
grid: {
display: false
},
x: {
type: 'linear',
position: 'bottom',
display: false,
min: -50,
max: 50
},
y: {
display: false,
min: -50,
max: 50
}
}
}
document.getElementById("radio-control-direct").style.display = 'block';
document.getElementById("radio-control-direct").style.visibility = 'visible';
document.getElementById("radio-control-direct").style.height = '100%';
config.radiocontrol = 'direct'
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
});
*/
// rigctl
document.getElementById("radio-control-switch2").addEventListener("click", () => {
document.getElementById("radio-control-direct").style.visibility = 'hidden';
document.getElementById("radio-control-rigctld").style.visibility = 'hidden';
document.getElementById("radio-control-direct").style.display = 'none';
document.getElementById("radio-control-rigctld").style.display = 'none';
/*
// advanced Hamlib Settings
document.getElementById("advancedHamlibSettingsButton").addEventListener("click", () => {
advancedHamlibSettingsModal
document.getElementById("radio-control-rigctl").style.display = 'block';
document.getElementById("radio-control-rigctl").style.visibility = 'visible';
document.getElementById("radio-control-rigctl").style.height = '100%';
config.radiocontrol = 'rigctl'
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
});
*/
// rigctld
document.getElementById("radio-control-switch3").addEventListener("click", () => {
document.getElementById("radio-control-direct").style.visibility = 'hidden';
document.getElementById("radio-control-rigctl").style.visibility = 'hidden';
document.getElementById("radio-control-direct").style.display = 'none';
document.getElementById("radio-control-rigctl").style.display = 'none';
document.getElementById("radio-control-rigctld").style.display = 'block';
document.getElementById("radio-control-rigctld").style.visibility = 'visible';
document.getElementById("radio-control-rigctld").style.height = '100%';
config.radiocontrol = 'rigctld'
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
});
// on click waterfall scatter toggle view
@ -294,15 +312,27 @@ advancedHamlibSettingsModal
// startTNC button clicked
document.getElementById("startTNC").addEventListener("click", () => {
var deviceid_rigctl = document.getElementById("hamlib_deviceid_rigctl").value
var deviceport_rigctl = document.getElementById("hamlib_deviceport_rigctl").value
var serialspeed_rigctl = document.getElementById("hamlib_serialspeed_rigctl").value
var pttprotocol_rigctl = document.getElementById("hamlib_ptt_protocol_rigctl").value
var rigctld_ip = document.getElementById("hamlib_rigctld_ip").value
var rigctld_port = document.getElementById("hamlib_rigctld_port").value
var deviceid = document.getElementById("hamlib_deviceid").value
var deviceport = document.getElementById("hamlib_deviceport").value
var serialspeed = document.getElementById("hamlib_serialspeed").value
var pttprotocol = document.getElementById("hamlib_ptt_protocol").value
var mycall = document.getElementById("myCall").value
mycall = mycall.toUpperCase()
var mygrid = document.getElementById("myGrid").value
var rx_audio = document.getElementById("audio_input_selectbox").value
var tx_audio = document.getElementById("audio_output_selectbox").value
var deviceid = document.getElementById("hamlib_deviceid").value
var deviceport = document.getElementById("hamlib_deviceport").value
var serialspeed = document.getElementById("hamlib_serialspeed").value
var pttprotocol = document.getElementById("hamlib_ptt_protocol").value
var pttport = document.getElementById("hamlib_ptt_port_advanced").value
var data_bits = document.getElementById('hamlib_databits_advanced').value
var stop_bits = document.getElementById('hamlib_stopbits_advanced').value
@ -329,6 +359,7 @@ advancedHamlibSettingsModal
}
}
config.radiocontrol = radiocontrol
config.mycall = mycall
config.mygrid = mygrid
config.deviceid = deviceid
@ -339,6 +370,14 @@ advancedHamlibSettingsModal
config.data_bits = data_bits
config.stop_bits = stop_bits
config.handshake = handshake
config.deviceid_rigctl = deviceid_rigctl
config.serialspeed_rigctl = serialspeed_rigctl
config.pttprotocol_rigctl = pttprotocol_rigctl
config.rigctld_port = rigctld_port
config.rigctld_ip = rigctld_ip
config.deviceport_rigctl = deviceport_rigctl
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
@ -352,9 +391,23 @@ advancedHamlibSettingsModal
collapseThirdRow.show()
var collapseFourthRow = new bootstrap.Collapse(document.getElementById('collapseFourthRow'), {toggle: false})
collapseFourthRow.show()
// overriding settings for rigctl / direct
if (document.getElementById("radio-control-switch2").checked){
var radiocontrol = 'rigctl'
var deviceid = document.getElementById("hamlib_deviceid_rigctl").value
var deviceport = document.getElementById("hamlib_deviceport_rigctl").value
var serialspeed = document.getElementById("hamlib_serialspeed_rigctl").value
var pttprotocol = document.getElementById("hamlib_ptt_protocol_rigctl").value
} else if (document.getElementById("radio-control-switch3").checked) {
var radiocontrol = 'rigctld'
daemon.startTNC(mycall, mygrid, rx_audio, tx_audio, deviceid, deviceport, pttprotocol, pttport, serialspeed, data_bits, stop_bits, handshake)
} else {
var radiocontrol = 'direct'
}
daemon.startTNC(mycall, mygrid, rx_audio, tx_audio, radiocontrol, deviceid, deviceport, pttprotocol, pttport, serialspeed, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port)
})
@ -402,43 +455,41 @@ advancedHamlibSettingsModal
// TEST HAMLIB
document.getElementById("testHamlib").addEventListener("click", () => {
var deviceid = document.getElementById("hamlib_deviceid").value
var deviceport = document.getElementById("hamlib_deviceport").value
var serialspeed = document.getElementById("hamlib_serialspeed").value
var pttprotocol = document.getElementById("hamlib_ptt_protocol").value
var data_bits = document.getElementById("hamlib_databits_advanced").value
var stop_bits = document.getElementById("hamlib_stopbits_advanced").value
var handshake = document.getElementById("hamlib_handshake_advanced").value
var pttport = document.getElementById("hamlib_ptt_port_advanced").value
daemon.testHamlib(deviceid, deviceport, serialspeed, pttprotocol, pttport, data_bits, stop_bits, handshake)
})
/* REMOVED FROM HTML
// TEST HAMLIB ADVANCED
document.getElementById("testHamlibAdvanced").addEventListener("click", () => {
var deviceid = document.getElementById("hamlib_deviceid").value
var deviceport = document.getElementById("hamlib_deviceport_advanced").value
document.getElementById("hamlib_deviceport").value = deviceport
var rigctld_ip = document.getElementById("hamlib_rigctld_ip").value
var rigctld_port = document.getElementById("hamlib_rigctld_port").value
var deviceid = document.getElementById("hamlib_deviceid").value
var deviceport = document.getElementById("hamlib_deviceport").value
var serialspeed = document.getElementById("hamlib_serialspeed").value
var pttprotocol = document.getElementById("hamlib_ptt_protocol").value
// overriding settings for rigctl / direct
if (document.getElementById("radio-control-switch2").checked){
var radiocontrol = 'rigctl'
var deviceid = document.getElementById("hamlib_deviceid_rigctl").value
var deviceport = document.getElementById("hamlib_deviceport_rigctl").value
var serialspeed = document.getElementById("hamlib_serialspeed_rigctl").value
var pttprotocol = document.getElementById("hamlib_ptt_protocol_rigctl").value
var serialspeed = document.getElementById("hamlib_serialspeed_advanced").value
document.getElementById("hamlib_serialspeed").value = serialspeed
var pttprotocol = document.getElementById("hamlib_ptt_protocol_advanced").value
document.getElementById("hamlib_ptt_protocol").value = pttprotocol
var pttport = document.getElementById("hamlib_deviceport").value
var data_bits = document.getElementById("hamlib_databits_advanced").value
var stop_bits = document.getElementById("hamlib_stopbits_advanced").value
var handshake = document.getElementById("hamlib_handshake_advanced").value
daemon.testHamlib(deviceid, deviceport, serialspeed, pttprotocol, pttport, data_bits, stop_bits, handshake)
})
*/
} else if (document.getElementById("radio-control-switch3").checked) {
var radiocontrol = 'rigctld'
} else {
var radiocontrol = 'direct'
}
daemon.testHamlib(radiocontrol, deviceid, deviceport, serialspeed, pttprotocol, pttport, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port)
})
// START TRANSMISSION
@ -1069,9 +1120,11 @@ ipcRenderer.on('action-update-daemon-state', (event, arg) => {
option.setAttribute('selected', true);
}
document.getElementById("hamlib_deviceport").add(option);
}
}
// advanced settings
if (document.getElementById("hamlib_deviceport_advanced").length != arg.serial_devices.length) {
document.getElementById("hamlib_deviceport_advanced").innerHTML = ""
for (i = 0; i < arg.serial_devices.length; i++) {
@ -1085,8 +1138,25 @@ ipcRenderer.on('action-update-daemon-state', (event, arg) => {
document.getElementById("hamlib_deviceport_advanced").add(option);
}
}
// rigctl settings
if (document.getElementById("hamlib_deviceport_rigctl").length != arg.serial_devices.length) {
document.getElementById("hamlib_deviceport_rigctl").innerHTML = ""
for (i = 0; i < arg.serial_devices.length; i++) {
var option = document.createElement("option");
option.text = arg.serial_devices[i]['DESCRIPTION'];
option.value = arg.serial_devices[i]['PORT'];
// set device from config if available
if(config.deviceport == option.value){
option.setAttribute('selected', true);
}
document.getElementById("hamlib_deviceport_rigctl").add(option);
}
}
}
if (arg.tnc_running_state == "stopped") {
if (document.getElementById("hamlib_ptt_port_advanced").length != arg.serial_devices.length) {
document.getElementById("hamlib_ptt_port_advanced").innerHTML = ""

View file

@ -12,7 +12,6 @@
<!-- Waterfall CSS -->
<link rel="stylesheet" type="text/css" href="waterfall/waterfall.css" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<title>FreeDATA</title>
</head>
@ -143,15 +142,13 @@
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
<!-- STOPPING TRANSMISSION -->
<!-- STOPPING TRANSMISSION -->
<div class="toast align-items-center text-white bg-danger border-0" id="toastTRANSMISSIONstopped" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
<div class="toast-body">Transmission stopped!</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
<!-- DATACHANNEL RECEIVED OPENER -->
<div class="toast align-items-center text-white bg-secondary border-0" id="toastDATACHANNELreceivedopener" role="alert" aria-live="assertive" aria-atomic="true">
<div class="d-flex">
@ -253,6 +250,17 @@
<path d="M14 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM2.5 6a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4Zm0 2a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4Z" />
<path fill-rule="evenodd" d="M0 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2 1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1H5a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1 2 2 0 0 1-2-2V6Zm2-1h12a1 1 0 0 1 1 1v3a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1Z" />
</svg> <strong>RADIO SETTINGS</strong>
<div class="btn-group btn-group-sm" role="group" aria-label="waterfall-scatter-switch toggle button group">
<input type="radio" class="btn-check" name="radio-control-switch" id="radio-control-switch1" autocomplete="off" checked>
<label class="btn btn-sm btn-outline-secondary" for="radio-control-switch1"><strong>direct</strong>
</label>
<input type="radio" class="btn-check" name="radio-control-switch" id="radio-control-switch2" autocomplete="off">
<label class="btn btn-sm btn-outline-secondary" for="radio-control-switch2"><strong>rigctl</strong>
</label>
<input type="radio" class="btn-check" name="radio-control-switch" id="radio-control-switch3" autocomplete="off">
<label class="btn btn-sm btn-outline-secondary" for="radio-control-switch3"><strong>rigctld</strong>
</label>
</div>
<div class="btn-group" role="group" data-bs-placement="bottom" data-bs-toggle="tooltip" data-bs-html="true" title="Set advanced hamlib settings like stop_bits and data_bits or a different port for a ptt device">
<button type="button" id="advancedHamlibSettingsButton" data-bs-toggle="modal" data-bs-target="#advancedHamlibSettingsModal" class="btn btn-sm btn-secondary">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-sliders" viewBox="0 0 16 16">
@ -265,373 +273,381 @@
</div>
</div>
<div class="card-body p-2">
<div class="input-group input-group-sm mb-1"> <span class="input-group-text" id="basic-addon1">
<div id="radio-control-direct">
<div class="input-group input-group-sm mb-1"> <span class="input-group-text" id="basic-addon1">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-projector-fill" viewBox="0 0 16 16">
<path d="M2 4a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2 1 1 0 0 0 1 1h1a1 1 0 0 0 1-1h6a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1 2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H2Zm.5 2h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1 0-1ZM14 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm-12 1a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1-.5-.5Z"/>
</svg>
</span>
<!--<select class="form-select form-select-sm" aria-label=".form-select-sm" id="hamlib_deviceid" style="width:7rem">-->
<input class="form-control" list="datalistOptions" id="hamlib_deviceid" placeholder="Search radio..." style="width:7rem">
<datalist id="datalistOptions">
<option value="RIG_MODEL_ADT_200A">ADAT www.adat.ch ADT-200A</option>
<option value="RIG_MODEL_DX77">Alinco DX-77</option>
<option value="RIG_MODEL_DXSR8">Alinco DX-SR8</option>
<option value="RIG_MODEL_DDS60">AmQRPDDS-60</option>
<option value="RIG_MODEL_FUNCUBEDONGLE">AMSAT-UK FUNcube Dongle</option>
<option value="RIG_MODEL_SI570PEABERRY1">AE9RBSi570 Peaberry V1</option>
<option value="RIG_MODEL_SI570PEABERRY2">AE9RBSi570 Peaberry V2</option>
<option value="RIG_MODEL_FUNCUBEDONGLEPLUS">AMSAT-UK FUNcube Dongle Pro+</option>
<option value="RIG_MODEL_AR8200">AOR AR8200</option>
<option value="RIG_MODEL_AR8000">AOR AR8000</option>
<option value="RIG_MODEL_AR7030">AOR AR7030</option>
<option value="RIG_MODEL_AR5000">AOR AR5000</option>
<option value="RIG_MODEL_AR3030">AOR AR3030</option>
<option value="RIG_MODEL_AR3000A">AOR AR3000A</option>
<option value="RIG_MODEL_AR2700">AOR AR2700</option>
<option value="RIG_MODEL_AR8600">AOR AR8600</option>
<option value="RIG_MODEL_AR5000A">AOR AR5000A</option>
<option value="RIG_MODEL_AR7030P">AOR AR7030 Plus</option>
<option value="RIG_MODEL_SR2200">AOR SR2200</option>
<option value="RIG_MODEL_BARRETT_2050">Barrett2050</option>
<option value="RIG_MODEL_BARRETT_950">Barrett950</option>
<option value="RIG_MODEL_DWT">Coding TechnologiesDigital World Travelle</option>
<option value="RIG_MODEL_DORJI_DRA818V">DorjiDRA818V</option>
<option value="RIG_MODEL_DORJI_DRA818U">DorjiDRA818U</option>
<option value="RIG_MODEL_DKR8A">DrakeR-8A</option>
<option value="RIG_MODEL_DKR8B">DrakeR-8B</option>
<option value="RIG_MODEL_DTTSP">DTTS Microwave Society DttSP IPC</option>
<option value="RIG_MODEL_DTTSP_UDP">DTTS Microwave Society DttSP UDP</option>
<option value="RIG_MODEL_ELAD_FDM_DUO">ELAD FDM-DUO</option>
<option value="RIG_MODEL_K2">Elecraft K2</option>
<option value="RIG_MODEL_K3">Elecraft K3</option>
<option value="RIG_MODEL_K4">Elecraft K4</option>
<option value="RIG_MODEL_XG3">Elecraft XG3</option>
<option value="RIG_MODEL_K3S">Elecraft K3S</option>
<option value="RIG_MODEL_KX2">Elecraft KX2</option>
<option value="RIG_MODEL_KX3">Elecraft KX3</option>
<option value="RIG_MODEL_ELEKTOR304">ElektorElektor 3/04</option>
<option value="RIG_MODEL_ELEKTOR507">ElektorElektor SDR-USB</option>
<option value="RIG_MODEL_FIFISDR">FiFi FiFi-SDR</option>
<option value="RIG_MODEL_POWERSDR">FlexRadio/ANAN PowerSDR/Thetis</option>
<option value="RIG_MODEL_F6K">FlexRadio6xxx</option>
<option value="RIG_MODEL_SDR1000">Flex-radio SDR-1000</option>
<option value="RIG_MODEL_FLRIG">FLRigFLRig</option>
<option value="RIG_MODEL_FASDR">FunkamateurFA-SDR</option>
<option value="RIG_MODEL_DUMMY">Hamlib Dummy</option>
<option value="RIG_MODEL_DUMMY_NOVFO">Hamlib Dummy No VFO</option>
<option value="RIG_MODEL_NETRIGCTL">Hamlib NET rigctl</option>
<option value="RIG_MODEL_RSHFIQ">HobbyPCB RS-HFIQ</option>
<option value="RIG_MODEL_PT8000A">Hilberling PT-8000A</option>
<option value="RIG_MODEL_IC1275">Icom IC-1275</option>
<option value="RIG_MODEL_IC271">Icom IC-271</option>
<option value="RIG_MODEL_IC275">Icom IC-275</option>
<option value="RIG_MODEL_IC471">Icom IC-471</option>
<option value="RIG_MODEL_IC475">Icom IC-475</option>
<option value="RIG_MODEL_IC575">Icom IC-575</option>
<option value="RIG_MODEL_IC706">Icom IC-706</option>
<option value="RIG_MODEL_IC706MKII">Icom IC-706MkII</option>
<option value="RIG_MODEL_IC706MKIIG">Icom IC-706MkIIG</option>
<option value="RIG_MODEL_IC707">Icom IC-707</option>
<option value="RIG_MODEL_IC718">Icom IC-718</option>
<option value="RIG_MODEL_IC725">Icom IC-725</option>
<option value="RIG_MODEL_IC726">Icom IC-726</option>
<option value="RIG_MODEL_IC728">Icom IC-728</option>
<option value="RIG_MODEL_IC729">Icom IC-729</option>
<option value="RIG_MODEL_IC735">Icom IC-735</option>
<option value="RIG_MODEL_IC736">Icom IC-736</option>
<option value="RIG_MODEL_IC737">Icom IC-737</option>
<option value="RIG_MODEL_IC738">Icom IC-738</option>
<option value="RIG_MODEL_IC746">Icom IC-746</option>
<option value="RIG_MODEL_IC751">Icom IC-751</option>
<option value="RIG_MODEL_IC756">Icom IC-756</option>
<option value="RIG_MODEL_IC756PRO">Icom IC-756PRO</option>
<option value="RIG_MODEL_IC761">Icom IC-761</option>
<option value="RIG_MODEL_IC765">Icom IC-765</option>
<option value="RIG_MODEL_IC775">Icom IC-775</option>
<option value="RIG_MODEL_IC781">Icom IC-781</option>
<option value="RIG_MODEL_IC820">Icom IC-820H</option>
<option value="RIG_MODEL_IC821H">Icom IC-821H</option>
<option value="RIG_MODEL_IC970">Icom IC-970</option>
<option value="RIG_MODEL_ICR10">Icom IC-R10</option>
<option value="RIG_MODEL_ICR71">Icom IC-R71</option>
<option value="RIG_MODEL_ICR72">Icom IC-R72</option>
<option value="RIG_MODEL_ICR75">Icom IC-R75</option>
<option value="RIG_MODEL_ICR7000">Icom IC-R7000</option>
<option value="RIG_MODEL_ICR7100">Icom IC-R7100</option>
<option value="RIG_MODEL_ICR8500">Icom ICR-8500</option>
<option value="RIG_MODEL_ICR9000">Icom IC-R9000</option>
<option value="RIG_MODEL_IC910">Icom IC-910</option>
<option value="RIG_MODEL_IC78">Icom IC-78</option>
<option value="RIG_MODEL_IC746PRO">Icom IC-746PRO</option>
<option value="RIG_MODEL_IC756PROII">Icom IC-756PROII</option>
<option value="RIG_MODEL_ICID1">Icom IC ID-1</option>
<option value="RIG_MODEL_IC703">Icom IC-703</option>
<option value="RIG_MODEL_IC7800">Icom IC-7800</option>
<option value="RIG_MODEL_IC756PROIII">Icom IC-756PROIII</option>
<option value="RIG_MODEL_ICR20">Icom IC-R20</option>
<option value="RIG_MODEL_IC7000">Icom IC-7000</option>
<option value="RIG_MODEL_IC7200">Icom IC-7200</option>
<option value="RIG_MODEL_IC7700">Icom IC-7700</option>
<option value="RIG_MODEL_IC7600">Icom IC-7600</option>
<option value="RIG_MODEL_DELTAII">Ten-TecDelta II</option>
<option value="RIG_MODEL_IC92D">Icom IC-92D</option>
<option value="RIG_MODEL_ICR9500">Icom IC-R9500</option>
<option value="RIG_MODEL_IC7410">Icom IC-7410</option>
<option value="RIG_MODEL_IC9100">Icom IC-9100</option>
<option value="RIG_MODEL_ICRX7">Icom IC-RX7</option>
<option value="RIG_MODEL_IC7100">Icom IC-7100</option>
<option value="RIG_MODEL_ID5100">Icom ID-5100</option>
<option value="RIG_MODEL_IC2730">Icom IC-2730</option>
<option value="RIG_MODEL_IC7300">Icom IC-7300</option>
<option value="RIG_MODEL_IC_M700PRO">Icom IC-M700PRO</option>
<option value="RIG_MODEL_IC_M802">Icom IC-M802</option>
<option value="RIG_MODEL_IC_M710">Icom IC-M710</option>
<option value="RIG_MODEL_IC_M803">Icom IC-M803</option>
<option value="RIG_MODEL_PERSEUS">Microtelecom Perseus</option>
<option value="RIG_MODEL_IC785x">Icom IC-785x</option>
<option value="RIG_MODEL_X108G">XeiguX108G</option>
<option value="RIG_MODEL_ICR6">Icom IC-R6</option>
<option value="RIG_MODEL_IC7610">Icom IC-7610</option>
<option value="RIG_MODEL_ICR8600">Icom IC-R8600</option>
<option value="RIG_MODEL_ICR30">Icom IC-R30</option>
<option value="RIG_MODEL_IC9700">Icom IC-9700</option>
<option value="RIG_MODEL_ID4100">Icom ID-4100</option>
<option value="RIG_MODEL_ID31">Icom ID-31</option>
<option value="RIG_MODEL_ID51">Icom ID-51</option>
<option value="RIG_MODEL_IC705">Icom IC-705</option>
<option value="RIG_MODEL_PCR1000">Icom IC-PCR1000</option>
<option value="RIG_MODEL_PCR100">Icom IC-PCR100</option>
<option value="RIG_MODEL_PCR1500">Icom IC-PCR1500</option>
<option value="RIG_MODEL_PCR2500">Icom IC-PCR2500</option>
<option value="RIG_MODEL_NRD525">JRCNRD-525</option>
<option value="RIG_MODEL_NRD535">JRCNRD-535D</option>
<option value="RIG_MODEL_NRD545">JRCNRD-545 DSP</option>
<option value="RIG_MODEL_505DSP">Kachina505DSP</option>
<option value="RIG_MODEL_SI570PICUSB">KTH-SDR kitSi570 PIC-USB</option>
<option value="RIG_MODEL_TS50">KenwoodTS-50S</option>
<option value="RIG_MODEL_TS440">KenwoodTS-440S</option>
<option value="RIG_MODEL_TS450S">KenwoodTS-450S</option>
<option value="RIG_MODEL_TS570D">KenwoodTS-570D</option>
<option value="RIG_MODEL_TS690S">KenwoodTS-690S</option>
<option value="RIG_MODEL_TS711">KenwoodTS-711</option>
<option value="RIG_MODEL_TS790">KenwoodTS-790</option>
<option value="RIG_MODEL_TS811">KenwoodTS-811</option>
<option value="RIG_MODEL_TS850">KenwoodTS-850</option>
<option value="RIG_MODEL_TS870S">KenwoodTS-870S</option>
<option value="RIG_MODEL_TS940">KenwoodTS-940S</option>
<option value="RIG_MODEL_TS950S">KenwoodTS-950S</option>
<option value="RIG_MODEL_TS950SDX">KenwoodTS-950SDX</option>
<option value="RIG_MODEL_TS2000">KenwoodTS-2000</option>
<option value="RIG_MODEL_R5000">KenwoodR-5000</option>
<option value="RIG_MODEL_TS570S">KenwoodTS-570S</option>
<option value="RIG_MODEL_THD7A">KenwoodTH-D7A</option>
<option value="RIG_MODEL_THF6A">KenwoodTH-F6A</option>
<option value="RIG_MODEL_THF7E">KenwoodTH-F7E</option>
<option value="RIG_MODEL_TS930">KenwoodTS-930</option>
<option value="RIG_MODEL_THG71">KenwoodTH-G71</option>
<option value="RIG_MODEL_TS680S">KenwoodTS-680S</option>
<option value="RIG_MODEL_TS140S">KenwoodTS-140S</option>
<option value="RIG_MODEL_TMD700">KenwoodTM-D700</option>
<option value="RIG_MODEL_TMV7">KenwoodTM-V7</option>
<option value="RIG_MODEL_TS480">KenwoodTS-480</option>
<option value="RIG_MODEL_TRC80">KenwoodTRC-80</option>
<option value="RIG_MODEL_TS590S">KenwoodTS-590S</option>
<option value="RIG_MODEL_TRANSFOX">SigFox Transfox</option>
<option value="RIG_MODEL_THD72A">KenwoodTH-D72A</option>
<option value="RIG_MODEL_TMD710">KenwoodTM-D710(G)</option>
<option value="RIG_MODEL_TS590SG">KenwoodTS-590SG</option>
<option value="RIG_MODEL_TS990S">KenwoodTS-990s</option>
<option value="RIG_MODEL_TS890S">KenwoodTS-890S</option>
<option value="RIG_MODEL_THD74">KenwoodTH-D74</option>
<option value="RIG_MODEL_HF235">Lowe HF-235</option>
<option value="RIG_MODEL_MALACHITE">MalachiteDSP</option>
<option value="RIG_MODEL_MINIVNA">mRSminiVNA</option>
<option value="RIG_MODEL_HIQSDR">N2ADRHiQSDR</option>
<option value="RIG_MODEL_OS535">OptoelectronicsOptoScan535</option>
<option value="RIG_MODEL_OS456">OptoelectronicsOptoScan456</option>
<option value="RIG_MODEL_HPSDR">OpenHPSDRPiHPSDR</option>
<option value="RIG_MODEL_PRM8060">Philips/Simoco PRM8060</option>
<option value="RIG_MODEL_RA6790">RacalRA6790/GM</option>
<option value="RIG_MODEL_RA3702">RacalRA3702</option>
<option value="RIG_MODEL_EKD500">RFTEKD-500</option>
<option value="RIG_MODEL_ESMC">Rohde&SchwarzESMC</option>
<option value="RIG_MODEL_EB200">Rohde&SchwarzEB200</option>
<option value="RIG_MODEL_XK2100">Rohde&SchwarzXK2100</option>
<option value="RIG_MODEL_TRP8000">Skanti TRP8000</option>
<option value="RIG_MODEL_TRP8255">Skanti TRP 8255 S R</option>
<option value="RIG_MODEL_DRT1">SAT-SchneiderDRT1</option>
<option value="RIG_MODEL_SI570AVRUSB">SoftRock Si570 AVR-USB</option>
<option value="RIG_MODEL_OMNIVIP">Ten-TecOmni VI Plus</option>
<option value="RIG_MODEL_TT550">Ten-TecTT-550</option>
<option value="RIG_MODEL_TT538">Ten-TecTT-538 Jupiter</option>
<option value="RIG_MODEL_RX320">Ten-TecRX-320</option>
<option value="RIG_MODEL_RX340">Ten-TecRX-340</option>
<option value="RIG_MODEL_RX350">Ten-TecRX-350</option>
<option value="RIG_MODEL_TT516">Ten-TecTT-516 Argonaut V</option>
<option value="RIG_MODEL_TT565">Ten-TecTT-565 Orion</option>
<option value="RIG_MODEL_TT585">Ten-TecTT-585 Paragon</option>
<option value="RIG_MODEL_TT588">Ten-TecTT-588 Omni VII</option>
<option value="RIG_MODEL_RX331">Ten-TecRX-331</option>
<option value="RIG_MODEL_TT599">Ten-TecTT-599 Eagle</option>
<option value="RIG_MODEL_DSP10">TAPR DSP-10</option>
<option value="RIG_MODEL_TRXMANAGER_RIG">TRXManager 5.7.630+</option>
<option value="RIG_MODEL_BC780">Uniden BC780xlt</option>
<option value="RIG_MODEL_BC245">Uniden BC245xlt</option>
<option value="RIG_MODEL_BC895">Uniden BC895xlt</option>
<option value="RIG_MODEL_PRO2052">Radio ShackPRO-2052</option>
<option value="RIG_MODEL_BC250">Uniden BC250D</option>
<option value="RIG_MODEL_BCD396T">Uniden BCD-396T</option>
<option value="RIG_MODEL_BCD996T">Uniden BCD-996T</option>
<option value="RIG_MODEL_BC898">Uniden BC898T</option>
<option value="RIG_MODEL_VX1700">Vertex StandardVX-1700</option>
<option value="RIG_MODEL_V4L">Video4LinuxSW/FM radio</option>
<option value="RIG_MODEL_V4L2">Video4Linux2 SW/FM radio</option>
<option value="RIG_MODEL_WJ8888">Watkins-JohnsonWJ-8888</option>
<option value="RIG_MODEL_WR1000">Winradio WR-1000</option>
<option value="RIG_MODEL_WR1500">Winradio WR-1500</option>
<option value="RIG_MODEL_WR1550">Winradio WR-1550</option>
<option value="RIG_MODEL_WR3100">Winradio WR-3100</option>
<option value="RIG_MODEL_WR3150">Winradio WR-3150</option>
<option value="RIG_MODEL_WR3500">Winradio WR-3500</option>
<option value="RIG_MODEL_WR3700">Winradio WR-3700</option>
<option value="RIG_MODEL_G313">Winradio WR-G313</option>
<option value="RIG_MODEL_FT847">Yaesu FT-847</option>
<option value="RIG_MODEL_FT1000D">Yaesu FT-1000D</option>
<option value="RIG_MODEL_FT1000MPMKV">YaesuMARK-V FT-1000MP</option>
<option value="RIG_MODEL_FT747">Yaesu FT-747GX</option>
<option value="RIG_MODEL_FT757">Yaesu FT-757GX</option>
<option value="RIG_MODEL_FT757GXII">Yaesu FT-757GXII</option>
<option value="RIG_MODEL_FT767">Yaesu FT-767GX</option>
<option value="RIG_MODEL_FT736R">Yaesu FT-736R</option>
<option value="RIG_MODEL_FT840">Yaesu FT-840</option>
<option value="RIG_MODEL_FT900">Yaesu FT-900</option>
<option value="RIG_MODEL_FT920">Yaesu FT-920</option>
<option value="RIG_MODEL_FT890">Yaesu FT-890</option>
<option value="RIG_MODEL_FT990">Yaesu FT-990</option>
<option value="RIG_MODEL_FRG100">Yaesu FRG-100</option>
<option value="RIG_MODEL_FRG9600">Yaesu FRG-9600</option>
<option value="RIG_MODEL_FRG8800">Yaesu FRG-8800</option>
<option value="RIG_MODEL_FT817">Yaesu FT-817</option>
<option value="RIG_MODEL_FT100">Yaesu FT-100</option>
<option value="RIG_MODEL_FT857">Yaesu FT-857</option>
<option value="RIG_MODEL_FT897">Yaesu FT-897</option>
<option value="RIG_MODEL_FT1000MP">Yaesu FT-1000MP</option>
<option value="RIG_MODEL_FT1000MPMKVFLD">Yaesu MARK-V Field FT-1000MP</option>
<option value="RIG_MODEL_VR5000">Yaesu VR-5000</option>
<option value="RIG_MODEL_FT450">Yaesu FT-450</option>
<option value="RIG_MODEL_FT950">Yaesu FT-950</option>
<option value="RIG_MODEL_FT2000">Yaesu FT-2000</option>
<option value="RIG_MODEL_FT9000">Yaesu FTDX-9000</option>
<option value="RIG_MODEL_FT980">Yaesu FT-980</option>
<option value="RIG_MODEL_FTDX5000">Yaesu FTDX-5000</option>
<option value="RIG_MODEL_FTDX1200">Yaesu FTDX-1200</option>
<option value="RIG_MODEL_FT991">Yaesu FT-991</option>
<option value="RIG_MODEL_FT891">Yaesu FT-891</option>
<option value="RIG_MODEL_FTDX3000">Yaesu FTDX-3000</option>
<option value="RIG_MODEL_FT847UNI">Yaesu FT-847UNI</option>
<option value="RIG_MODEL_FT600">Yaesu FT-600</option>
<option value="RIG_MODEL_FTDX101D">Yaesu FTDX-101D</option>
<option value="RIG_MODEL_FT818">Yaesu FT-818</option>
<option value="RIG_MODEL_FTDX10">Yaesu FTDX-10</option>
<option value="RIG_MODEL_FT897D">Yaesu FT-897D</option>
<option value="RIG_MODEL_FTDX101MP">Yaesu FTDX-101MP</option>
</datalist> <span class="input-group-text" id="basic-addon1">
<!--<select class="form-select form-select-sm" aria-label=".form-select-sm" id="hamlib_deviceid" style="width:7rem">-->
<input class="form-control" list="datalistOptions" id="hamlib_deviceid" placeholder="Search radio..." style="width:7rem">
<datalist id="datalistOptions">
<option value="RIG_MODEL_ADT_200A">ADAT www.adat.ch ADT-200A</option>
<option value="RIG_MODEL_DX77">Alinco DX-77</option>
<option value="RIG_MODEL_DXSR8">Alinco DX-SR8</option>
<option value="RIG_MODEL_DDS60">AmQRPDDS-60</option>
<option value="RIG_MODEL_FUNCUBEDONGLE">AMSAT-UK FUNcube Dongle</option>
<option value="RIG_MODEL_SI570PEABERRY1">AE9RBSi570 Peaberry V1</option>
<option value="RIG_MODEL_SI570PEABERRY2">AE9RBSi570 Peaberry V2</option>
<option value="RIG_MODEL_FUNCUBEDONGLEPLUS">AMSAT-UK FUNcube Dongle Pro+</option>
<option value="RIG_MODEL_AR8200">AOR AR8200</option>
<option value="RIG_MODEL_AR8000">AOR AR8000</option>
<option value="RIG_MODEL_AR7030">AOR AR7030</option>
<option value="RIG_MODEL_AR5000">AOR AR5000</option>
<option value="RIG_MODEL_AR3030">AOR AR3030</option>
<option value="RIG_MODEL_AR3000A">AOR AR3000A</option>
<option value="RIG_MODEL_AR2700">AOR AR2700</option>
<option value="RIG_MODEL_AR8600">AOR AR8600</option>
<option value="RIG_MODEL_AR5000A">AOR AR5000A</option>
<option value="RIG_MODEL_AR7030P">AOR AR7030 Plus</option>
<option value="RIG_MODEL_SR2200">AOR SR2200</option>
<option value="RIG_MODEL_BARRETT_2050">Barrett2050</option>
<option value="RIG_MODEL_BARRETT_950">Barrett950</option>
<option value="RIG_MODEL_DWT">Coding TechnologiesDigital World Travelle</option>
<option value="RIG_MODEL_DORJI_DRA818V">DorjiDRA818V</option>
<option value="RIG_MODEL_DORJI_DRA818U">DorjiDRA818U</option>
<option value="RIG_MODEL_DKR8A">DrakeR-8A</option>
<option value="RIG_MODEL_DKR8B">DrakeR-8B</option>
<option value="RIG_MODEL_DTTSP">DTTS Microwave Society DttSP IPC</option>
<option value="RIG_MODEL_DTTSP_UDP">DTTS Microwave Society DttSP UDP</option>
<option value="RIG_MODEL_ELAD_FDM_DUO">ELAD FDM-DUO</option>
<option value="RIG_MODEL_K2">Elecraft K2</option>
<option value="RIG_MODEL_K3">Elecraft K3</option>
<option value="RIG_MODEL_K4">Elecraft K4</option>
<option value="RIG_MODEL_XG3">Elecraft XG3</option>
<option value="RIG_MODEL_K3S">Elecraft K3S</option>
<option value="RIG_MODEL_KX2">Elecraft KX2</option>
<option value="RIG_MODEL_KX3">Elecraft KX3</option>
<option value="RIG_MODEL_ELEKTOR304">ElektorElektor 3/04</option>
<option value="RIG_MODEL_ELEKTOR507">ElektorElektor SDR-USB</option>
<option value="RIG_MODEL_FIFISDR">FiFi FiFi-SDR</option>
<option value="RIG_MODEL_POWERSDR">FlexRadio/ANAN PowerSDR/Thetis</option>
<option value="RIG_MODEL_F6K">FlexRadio6xxx</option>
<option value="RIG_MODEL_SDR1000">Flex-radio SDR-1000</option>
<option value="RIG_MODEL_FLRIG">FLRigFLRig</option>
<option value="RIG_MODEL_FASDR">FunkamateurFA-SDR</option>
<option value="RIG_MODEL_DUMMY">Hamlib Dummy</option>
<option value="RIG_MODEL_DUMMY_NOVFO">Hamlib Dummy No VFO</option>
<option value="RIG_MODEL_NETRIGCTL">Hamlib NET rigctl</option>
<option value="RIG_MODEL_RSHFIQ">HobbyPCB RS-HFIQ</option>
<option value="RIG_MODEL_PT8000A">Hilberling PT-8000A</option>
<option value="RIG_MODEL_IC1275">Icom IC-1275</option>
<option value="RIG_MODEL_IC271">Icom IC-271</option>
<option value="RIG_MODEL_IC275">Icom IC-275</option>
<option value="RIG_MODEL_IC471">Icom IC-471</option>
<option value="RIG_MODEL_IC475">Icom IC-475</option>
<option value="RIG_MODEL_IC575">Icom IC-575</option>
<option value="RIG_MODEL_IC706">Icom IC-706</option>
<option value="RIG_MODEL_IC706MKII">Icom IC-706MkII</option>
<option value="RIG_MODEL_IC706MKIIG">Icom IC-706MkIIG</option>
<option value="RIG_MODEL_IC707">Icom IC-707</option>
<option value="RIG_MODEL_IC718">Icom IC-718</option>
<option value="RIG_MODEL_IC725">Icom IC-725</option>
<option value="RIG_MODEL_IC726">Icom IC-726</option>
<option value="RIG_MODEL_IC728">Icom IC-728</option>
<option value="RIG_MODEL_IC729">Icom IC-729</option>
<option value="RIG_MODEL_IC735">Icom IC-735</option>
<option value="RIG_MODEL_IC736">Icom IC-736</option>
<option value="RIG_MODEL_IC737">Icom IC-737</option>
<option value="RIG_MODEL_IC738">Icom IC-738</option>
<option value="RIG_MODEL_IC746">Icom IC-746</option>
<option value="RIG_MODEL_IC751">Icom IC-751</option>
<option value="RIG_MODEL_IC756">Icom IC-756</option>
<option value="RIG_MODEL_IC756PRO">Icom IC-756PRO</option>
<option value="RIG_MODEL_IC761">Icom IC-761</option>
<option value="RIG_MODEL_IC765">Icom IC-765</option>
<option value="RIG_MODEL_IC775">Icom IC-775</option>
<option value="RIG_MODEL_IC781">Icom IC-781</option>
<option value="RIG_MODEL_IC820">Icom IC-820H</option>
<option value="RIG_MODEL_IC821H">Icom IC-821H</option>
<option value="RIG_MODEL_IC970">Icom IC-970</option>
<option value="RIG_MODEL_ICR10">Icom IC-R10</option>
<option value="RIG_MODEL_ICR71">Icom IC-R71</option>
<option value="RIG_MODEL_ICR72">Icom IC-R72</option>
<option value="RIG_MODEL_ICR75">Icom IC-R75</option>
<option value="RIG_MODEL_ICR7000">Icom IC-R7000</option>
<option value="RIG_MODEL_ICR7100">Icom IC-R7100</option>
<option value="RIG_MODEL_ICR8500">Icom ICR-8500</option>
<option value="RIG_MODEL_ICR9000">Icom IC-R9000</option>
<option value="RIG_MODEL_IC910">Icom IC-910</option>
<option value="RIG_MODEL_IC78">Icom IC-78</option>
<option value="RIG_MODEL_IC746PRO">Icom IC-746PRO</option>
<option value="RIG_MODEL_IC756PROII">Icom IC-756PROII</option>
<option value="RIG_MODEL_ICID1">Icom IC ID-1</option>
<option value="RIG_MODEL_IC703">Icom IC-703</option>
<option value="RIG_MODEL_IC7800">Icom IC-7800</option>
<option value="RIG_MODEL_IC756PROIII">Icom IC-756PROIII</option>
<option value="RIG_MODEL_ICR20">Icom IC-R20</option>
<option value="RIG_MODEL_IC7000">Icom IC-7000</option>
<option value="RIG_MODEL_IC7200">Icom IC-7200</option>
<option value="RIG_MODEL_IC7700">Icom IC-7700</option>
<option value="RIG_MODEL_IC7600">Icom IC-7600</option>
<option value="RIG_MODEL_DELTAII">Ten-TecDelta II</option>
<option value="RIG_MODEL_IC92D">Icom IC-92D</option>
<option value="RIG_MODEL_ICR9500">Icom IC-R9500</option>
<option value="RIG_MODEL_IC7410">Icom IC-7410</option>
<option value="RIG_MODEL_IC9100">Icom IC-9100</option>
<option value="RIG_MODEL_ICRX7">Icom IC-RX7</option>
<option value="RIG_MODEL_IC7100">Icom IC-7100</option>
<option value="RIG_MODEL_ID5100">Icom ID-5100</option>
<option value="RIG_MODEL_IC2730">Icom IC-2730</option>
<option value="RIG_MODEL_IC7300">Icom IC-7300</option>
<option value="RIG_MODEL_IC_M700PRO">Icom IC-M700PRO</option>
<option value="RIG_MODEL_IC_M802">Icom IC-M802</option>
<option value="RIG_MODEL_IC_M710">Icom IC-M710</option>
<option value="RIG_MODEL_IC_M803">Icom IC-M803</option>
<option value="RIG_MODEL_PERSEUS">Microtelecom Perseus</option>
<option value="RIG_MODEL_IC785x">Icom IC-785x</option>
<option value="RIG_MODEL_X108G">XeiguX108G</option>
<option value="RIG_MODEL_ICR6">Icom IC-R6</option>
<option value="RIG_MODEL_IC7610">Icom IC-7610</option>
<option value="RIG_MODEL_ICR8600">Icom IC-R8600</option>
<option value="RIG_MODEL_ICR30">Icom IC-R30</option>
<option value="RIG_MODEL_IC9700">Icom IC-9700</option>
<option value="RIG_MODEL_ID4100">Icom ID-4100</option>
<option value="RIG_MODEL_ID31">Icom ID-31</option>
<option value="RIG_MODEL_ID51">Icom ID-51</option>
<option value="RIG_MODEL_IC705">Icom IC-705</option>
<option value="RIG_MODEL_PCR1000">Icom IC-PCR1000</option>
<option value="RIG_MODEL_PCR100">Icom IC-PCR100</option>
<option value="RIG_MODEL_PCR1500">Icom IC-PCR1500</option>
<option value="RIG_MODEL_PCR2500">Icom IC-PCR2500</option>
<option value="RIG_MODEL_NRD525">JRCNRD-525</option>
<option value="RIG_MODEL_NRD535">JRCNRD-535D</option>
<option value="RIG_MODEL_NRD545">JRCNRD-545 DSP</option>
<option value="RIG_MODEL_505DSP">Kachina505DSP</option>
<option value="RIG_MODEL_SI570PICUSB">KTH-SDR kitSi570 PIC-USB</option>
<option value="RIG_MODEL_TS50">KenwoodTS-50S</option>
<option value="RIG_MODEL_TS440">KenwoodTS-440S</option>
<option value="RIG_MODEL_TS450S">KenwoodTS-450S</option>
<option value="RIG_MODEL_TS570D">KenwoodTS-570D</option>
<option value="RIG_MODEL_TS690S">KenwoodTS-690S</option>
<option value="RIG_MODEL_TS711">KenwoodTS-711</option>
<option value="RIG_MODEL_TS790">KenwoodTS-790</option>
<option value="RIG_MODEL_TS811">KenwoodTS-811</option>
<option value="RIG_MODEL_TS850">KenwoodTS-850</option>
<option value="RIG_MODEL_TS870S">KenwoodTS-870S</option>
<option value="RIG_MODEL_TS940">KenwoodTS-940S</option>
<option value="RIG_MODEL_TS950S">KenwoodTS-950S</option>
<option value="RIG_MODEL_TS950SDX">KenwoodTS-950SDX</option>
<option value="RIG_MODEL_TS2000">KenwoodTS-2000</option>
<option value="RIG_MODEL_R5000">KenwoodR-5000</option>
<option value="RIG_MODEL_TS570S">KenwoodTS-570S</option>
<option value="RIG_MODEL_THD7A">KenwoodTH-D7A</option>
<option value="RIG_MODEL_THF6A">KenwoodTH-F6A</option>
<option value="RIG_MODEL_THF7E">KenwoodTH-F7E</option>
<option value="RIG_MODEL_TS930">KenwoodTS-930</option>
<option value="RIG_MODEL_THG71">KenwoodTH-G71</option>
<option value="RIG_MODEL_TS680S">KenwoodTS-680S</option>
<option value="RIG_MODEL_TS140S">KenwoodTS-140S</option>
<option value="RIG_MODEL_TMD700">KenwoodTM-D700</option>
<option value="RIG_MODEL_TMV7">KenwoodTM-V7</option>
<option value="RIG_MODEL_TS480">KenwoodTS-480</option>
<option value="RIG_MODEL_TRC80">KenwoodTRC-80</option>
<option value="RIG_MODEL_TS590S">KenwoodTS-590S</option>
<option value="RIG_MODEL_TRANSFOX">SigFox Transfox</option>
<option value="RIG_MODEL_THD72A">KenwoodTH-D72A</option>
<option value="RIG_MODEL_TMD710">KenwoodTM-D710(G)</option>
<option value="RIG_MODEL_TS590SG">KenwoodTS-590SG</option>
<option value="RIG_MODEL_TS990S">KenwoodTS-990s</option>
<option value="RIG_MODEL_TS890S">KenwoodTS-890S</option>
<option value="RIG_MODEL_THD74">KenwoodTH-D74</option>
<option value="RIG_MODEL_HF235">Lowe HF-235</option>
<option value="RIG_MODEL_MALACHITE">MalachiteDSP</option>
<option value="RIG_MODEL_MINIVNA">mRSminiVNA</option>
<option value="RIG_MODEL_HIQSDR">N2ADRHiQSDR</option>
<option value="RIG_MODEL_OS535">OptoelectronicsOptoScan535</option>
<option value="RIG_MODEL_OS456">OptoelectronicsOptoScan456</option>
<option value="RIG_MODEL_HPSDR">OpenHPSDRPiHPSDR</option>
<option value="RIG_MODEL_PRM8060">Philips/Simoco PRM8060</option>
<option value="RIG_MODEL_RA6790">RacalRA6790/GM</option>
<option value="RIG_MODEL_RA3702">RacalRA3702</option>
<option value="RIG_MODEL_EKD500">RFTEKD-500</option>
<option value="RIG_MODEL_ESMC">Rohde&SchwarzESMC</option>
<option value="RIG_MODEL_EB200">Rohde&SchwarzEB200</option>
<option value="RIG_MODEL_XK2100">Rohde&SchwarzXK2100</option>
<option value="RIG_MODEL_TRP8000">Skanti TRP8000</option>
<option value="RIG_MODEL_TRP8255">Skanti TRP 8255 S R</option>
<option value="RIG_MODEL_DRT1">SAT-SchneiderDRT1</option>
<option value="RIG_MODEL_SI570AVRUSB">SoftRock Si570 AVR-USB</option>
<option value="RIG_MODEL_OMNIVIP">Ten-TecOmni VI Plus</option>
<option value="RIG_MODEL_TT550">Ten-TecTT-550</option>
<option value="RIG_MODEL_TT538">Ten-TecTT-538 Jupiter</option>
<option value="RIG_MODEL_RX320">Ten-TecRX-320</option>
<option value="RIG_MODEL_RX340">Ten-TecRX-340</option>
<option value="RIG_MODEL_RX350">Ten-TecRX-350</option>
<option value="RIG_MODEL_TT516">Ten-TecTT-516 Argonaut V</option>
<option value="RIG_MODEL_TT565">Ten-TecTT-565 Orion</option>
<option value="RIG_MODEL_TT585">Ten-TecTT-585 Paragon</option>
<option value="RIG_MODEL_TT588">Ten-TecTT-588 Omni VII</option>
<option value="RIG_MODEL_RX331">Ten-TecRX-331</option>
<option value="RIG_MODEL_TT599">Ten-TecTT-599 Eagle</option>
<option value="RIG_MODEL_DSP10">TAPR DSP-10</option>
<option value="RIG_MODEL_TRXMANAGER_RIG">TRXManager 5.7.630+</option>
<option value="RIG_MODEL_BC780">Uniden BC780xlt</option>
<option value="RIG_MODEL_BC245">Uniden BC245xlt</option>
<option value="RIG_MODEL_BC895">Uniden BC895xlt</option>
<option value="RIG_MODEL_PRO2052">Radio ShackPRO-2052</option>
<option value="RIG_MODEL_BC250">Uniden BC250D</option>
<option value="RIG_MODEL_BCD396T">Uniden BCD-396T</option>
<option value="RIG_MODEL_BCD996T">Uniden BCD-996T</option>
<option value="RIG_MODEL_BC898">Uniden BC898T</option>
<option value="RIG_MODEL_VX1700">Vertex StandardVX-1700</option>
<option value="RIG_MODEL_V4L">Video4LinuxSW/FM radio</option>
<option value="RIG_MODEL_V4L2">Video4Linux2 SW/FM radio</option>
<option value="RIG_MODEL_WJ8888">Watkins-JohnsonWJ-8888</option>
<option value="RIG_MODEL_WR1000">Winradio WR-1000</option>
<option value="RIG_MODEL_WR1500">Winradio WR-1500</option>
<option value="RIG_MODEL_WR1550">Winradio WR-1550</option>
<option value="RIG_MODEL_WR3100">Winradio WR-3100</option>
<option value="RIG_MODEL_WR3150">Winradio WR-3150</option>
<option value="RIG_MODEL_WR3500">Winradio WR-3500</option>
<option value="RIG_MODEL_WR3700">Winradio WR-3700</option>
<option value="RIG_MODEL_G313">Winradio WR-G313</option>
<option value="RIG_MODEL_FT847">Yaesu FT-847</option>
<option value="RIG_MODEL_FT1000D">Yaesu FT-1000D</option>
<option value="RIG_MODEL_FT1000MPMKV">YaesuMARK-V FT-1000MP</option>
<option value="RIG_MODEL_FT747">Yaesu FT-747GX</option>
<option value="RIG_MODEL_FT757">Yaesu FT-757GX</option>
<option value="RIG_MODEL_FT757GXII">Yaesu FT-757GXII</option>
<option value="RIG_MODEL_FT767">Yaesu FT-767GX</option>
<option value="RIG_MODEL_FT736R">Yaesu FT-736R</option>
<option value="RIG_MODEL_FT840">Yaesu FT-840</option>
<option value="RIG_MODEL_FT900">Yaesu FT-900</option>
<option value="RIG_MODEL_FT920">Yaesu FT-920</option>
<option value="RIG_MODEL_FT890">Yaesu FT-890</option>
<option value="RIG_MODEL_FT990">Yaesu FT-990</option>
<option value="RIG_MODEL_FRG100">Yaesu FRG-100</option>
<option value="RIG_MODEL_FRG9600">Yaesu FRG-9600</option>
<option value="RIG_MODEL_FRG8800">Yaesu FRG-8800</option>
<option value="RIG_MODEL_FT817">Yaesu FT-817</option>
<option value="RIG_MODEL_FT100">Yaesu FT-100</option>
<option value="RIG_MODEL_FT857">Yaesu FT-857</option>
<option value="RIG_MODEL_FT897">Yaesu FT-897</option>
<option value="RIG_MODEL_FT1000MP">Yaesu FT-1000MP</option>
<option value="RIG_MODEL_FT1000MPMKVFLD">Yaesu MARK-V Field FT-1000MP</option>
<option value="RIG_MODEL_VR5000">Yaesu VR-5000</option>
<option value="RIG_MODEL_FT450">Yaesu FT-450</option>
<option value="RIG_MODEL_FT950">Yaesu FT-950</option>
<option value="RIG_MODEL_FT2000">Yaesu FT-2000</option>
<option value="RIG_MODEL_FT9000">Yaesu FTDX-9000</option>
<option value="RIG_MODEL_FT980">Yaesu FT-980</option>
<option value="RIG_MODEL_FTDX5000">Yaesu FTDX-5000</option>
<option value="RIG_MODEL_FTDX1200">Yaesu FTDX-1200</option>
<option value="RIG_MODEL_FT991">Yaesu FT-991</option>
<option value="RIG_MODEL_FT891">Yaesu FT-891</option>
<option value="RIG_MODEL_FTDX3000">Yaesu FTDX-3000</option>
<option value="RIG_MODEL_FT847UNI">Yaesu FT-847UNI</option>
<option value="RIG_MODEL_FT600">Yaesu FT-600</option>
<option value="RIG_MODEL_FTDX101D">Yaesu FTDX-101D</option>
<option value="RIG_MODEL_FT818">Yaesu FT-818</option>
<option value="RIG_MODEL_FTDX10">Yaesu FTDX-10</option>
<option value="RIG_MODEL_FT897D">Yaesu FT-897D</option>
<option value="RIG_MODEL_FTDX101MP">Yaesu FTDX-101MP</option>
</datalist> <span class="input-group-text" id="basic-addon1">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-alt" viewBox="0 0 16 16">
<path d="M1 13.5a.5.5 0 0 0 .5.5h3.797a.5.5 0 0 0 .439-.26L11 3h3.5a.5.5 0 0 0 0-1h-3.797a.5.5 0 0 0-.439.26L5 13H1.5a.5.5 0 0 0-.5.5zm10 0a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 0-1h-3a.5.5 0 0 0-.5.5z"/>
</svg>
</span>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="hamlib_ptt_protocol" style="width: 0.5rem">
<option value="RIG">RIG</option>
<option value="USB">USB</option>
<option value="RTS">Serial RTS</option>
<option value="DTR-H">Serial DTR-High</option>
<option value="DTR-H">Serial DTR-Low</option>
<option value="PARALLEL">Rig PARALLEL</option>
<option value="MICDATA">Rig MICDATA</option>
<option value="CM108">Rig CM108</option>
</select>
</div>
<!--<hr class="m-1">-->
<div class="input-group input-group-sm mb-1"> <span class="input-group-text" id="basic-addon1">
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="hamlib_ptt_protocol" style="width: 0.5rem">
<option value="RIG">RIG</option>
<option value="USB">USB</option>
<option value="RTS">Serial RTS</option>
<option value="DTR-H">Serial DTR-High</option>
<option value="DTR-H">Serial DTR-Low</option>
<option value="PARALLEL">Rig PARALLEL</option>
<option value="MICDATA">Rig MICDATA</option>
<option value="CM108">Rig CM108</option>
</select>
</div>
<!--<hr class="m-1">-->
<div class="input-group input-group-sm mb-1"> <span class="input-group-text" id="basic-addon1">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-usb-symbol" viewBox="0 0 16 16">
<path d="m7.792.312-1.533 2.3A.25.25 0 0 0 6.467 3H7.5v7.319a2.5 2.5 0 0 0-.515-.298L5.909 9.56A1.5 1.5 0 0 1 5 8.18v-.266a1.5 1.5 0 1 0-1 0v.266a2.5 2.5 0 0 0 1.515 2.298l1.076.461a1.5 1.5 0 0 1 .888 1.129 2.001 2.001 0 1 0 1.021-.006v-.902a1.5 1.5 0 0 1 .756-1.303l1.484-.848A2.5 2.5 0 0 0 11.995 7h.755a.25.25 0 0 0 .25-.25v-2.5a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25v2.5c0 .138.112.25.25.25h.741a1.5 1.5 0 0 1-.747 1.142L8.76 8.99a2.584 2.584 0 0 0-.26.17V3h1.033a.25.25 0 0 0 .208-.389L8.208.312a.25.25 0 0 0-.416 0Z"/>
</svg>
</span>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="hamlib_deviceport" style="width:7rem">
<!--<option selected value="/dev/ttyUSB0">/dev/ttyUSB0</option>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="hamlib_deviceport" style="width:7rem">
<!--<option selected value="/dev/ttyUSB0">/dev/ttyUSB0</option>
<option value="/dev/ttyUSB1">/dev/ttyUSB1</option>-->
</select> <span class="input-group-text" id="basic-addon1">Speed</span>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="hamlib_serialspeed">
<option value="1200">1200</option>
<option value="2400">2400</option>
<option value="4800">4800</option>
<option selected value="9600">9600</option>
<option value="14400">14400</option>
<option value="19200">19200</option>
<option value="28800">28800</option>
<option value="38400">38400</option>
<option value="57600">57600</option>
<option value="115200">115200</option>
</select>
</select> <span class="input-group-text" id="basic-addon1">Speed</span>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="hamlib_serialspeed">
<option value="1200">1200</option>
<option value="2400">2400</option>
<option value="4800">4800</option>
<option selected value="9600">9600</option>
<option value="14400">14400</option>
<option value="19200">19200</option>
<option value="28800">28800</option>
<option value="38400">38400</option>
<option value="57600">57600</option>
<option value="115200">115200</option>
</select>
</div>
</div>
<div id="radio-control-rigctl">
<div class="input-group input-group-sm mb-1"> <span class="input-group-text" id="basic-addon1">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-projector-fill" viewBox="0 0 16 16">
<path d="M2 4a2 2 0 0 0-2 2v3a2 2 0 0 0 2 2 1 1 0 0 0 1 1h1a1 1 0 0 0 1-1h6a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1 2 2 0 0 0 2-2V6a2 2 0 0 0-2-2H2Zm.5 2h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1 0-1ZM14 7.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm-12 1a.5.5 0 0 1 .5-.5h4a.5.5 0 0 1 0 1h-4a.5.5 0 0 1-.5-.5Z"/>
</svg>
</span>
<input type="text" class="form-control" placeholder="Device id" id="hamlib_deviceid_rigctl" aria-label="Device ID" aria-describedby="basic-addon1"> <span class="input-group-text" id="basic-addon1">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-alt" viewBox="0 0 16 16">
<path d="M1 13.5a.5.5 0 0 0 .5.5h3.797a.5.5 0 0 0 .439-.26L11 3h3.5a.5.5 0 0 0 0-1h-3.797a.5.5 0 0 0-.439.26L5 13H1.5a.5.5 0 0 0-.5.5zm10 0a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 0-1h-3a.5.5 0 0 0-.5.5z"/>
</svg>
</span>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="hamlib_ptt_protocol_rigctl" style="width: 0.5rem">
<option value="RIG">RIG</option>
<option value="USB">USB</option>
<option value="RTS">Serial RTS</option>
<option value="DTR-H">Serial DTR-High</option>
<option value="DTR-H">Serial DTR-Low</option>
<option value="PARALLEL">Rig PARALLEL</option>
<option value="MICDATA">Rig MICDATA</option>
<option value="CM108">Rig CM108</option>
</select>
</div>
<div class="input-group input-group-sm mb-1"> <span class="input-group-text" id="basic-addon1">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-usb-symbol" viewBox="0 0 16 16">
<path d="m7.792.312-1.533 2.3A.25.25 0 0 0 6.467 3H7.5v7.319a2.5 2.5 0 0 0-.515-.298L5.909 9.56A1.5 1.5 0 0 1 5 8.18v-.266a1.5 1.5 0 1 0-1 0v.266a2.5 2.5 0 0 0 1.515 2.298l1.076.461a1.5 1.5 0 0 1 .888 1.129 2.001 2.001 0 1 0 1.021-.006v-.902a1.5 1.5 0 0 1 .756-1.303l1.484-.848A2.5 2.5 0 0 0 11.995 7h.755a.25.25 0 0 0 .25-.25v-2.5a.25.25 0 0 0-.25-.25h-2.5a.25.25 0 0 0-.25.25v2.5c0 .138.112.25.25.25h.741a1.5 1.5 0 0 1-.747 1.142L8.76 8.99a2.584 2.584 0 0 0-.26.17V3h1.033a.25.25 0 0 0 .208-.389L8.208.312a.25.25 0 0 0-.416 0Z"/>
</svg>
</span>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="hamlib_deviceport_rigctl" style="width:7rem">
<!--<option selected value="/dev/ttyUSB0">/dev/ttyUSB0</option>
<option value="/dev/ttyUSB1">/dev/ttyUSB1</option>-->
</select> <span class="input-group-text" id="basic-addon1">Speed</span>
<select class="form-select form-select-sm" aria-label=".form-select-sm" id="hamlib_serialspeed_rigctl">
<option value="1200">1200</option>
<option value="2400">2400</option>
<option value="4800">4800</option>
<option selected value="9600">9600</option>
<option value="14400">14400</option>
<option value="19200">19200</option>
<option value="28800">28800</option>
<option value="38400">38400</option>
<option value="57600">57600</option>
<option value="115200">115200</option>
</select>
</div>
</div>
<div id="radio-control-rigctld">
<div class="input-group input-group-sm mb-1">
<input type="text" class="form-control" placeholder="rigctld IP" id="hamlib_rigctld_ip" aria-label="Device IP" aria-describedby="basic-addon1">
<input type="text" class="form-control" placeholder="rigctld port" id="hamlib_rigctld_port" aria-label="Device Port" aria-describedby="basic-addon1">
</div>
</div>
</div>
<div class="card-footer text-muted small">Please select your radio settings. Starting the TNC saves them.</div>
</div>
</div>
<!--
<div class="col-3">
<div class="card text-dark bg-light mb-0" >
<div class="card-header p-1"><strong>TNC STATUS</strong></div>
<div class="card-body p-1 mb-1">
<div class="container p-1">
<div class="input-group input-group-sm mb-1">
<button type="button" id="startTNC"class="btn btn-success">Start</button>
<span class="input-group-text" id="tnc_running_state" style="width: 5rem">---</span>
<button type="button" id="stopTNC"class="btn btn-danger">STOP</button>
</div>
<div class="row">
<div class="col-md-auto">
CPU
</div>
<div class="col-8">
<div class="progress" style="height: 20px;" >
<div class="progress-bar progress-bar-striped bg-primary" id="progressbar_cpu" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
<p class="justify-content-center d-flex position-absolute w-100" id="progressbar_cpu_value"></p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-auto">
RAM
</div>
<div class="col-8">
<div class="progress" style="height: 20px;" >
<div class="progress-bar progress-bar-striped bg-primary" id="progressbar_ram" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
<p class="justify-content-center d-flex position-absolute w-100" id="progressbar_ram_value"></p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-auto">
TOE
</div>
<div class="col-md-auto">
<p class="text-start mb-0" id="toe"></p>
</div>
</div>
</div>
</div>
</div>
</div>
--></div>
</div>
<div class="row collapse multi-collapse show mt-2" id="collapseSecondRow">
<div class="col">
<div class="card text-dark mb-1">
@ -1128,4 +1144,4 @@
</div>
</body>
</html>
</html>

View file

@ -51,6 +51,7 @@ c_error_handler = ERROR_HANDLER_FUNC(py_error_handler)
@contextmanager
def noalsaerr():
asound = cdll.LoadLibrary('libasound.so')
asound.snd_lib_error_set_handler(c_error_handler)
yield
@ -82,7 +83,7 @@ def start_daemon():
class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
def handle(self):
def handle(self, hamlib_version = 0):
structlog.get_logger("structlog").debug("[DMN] Client connected", ip=self.client_address[0])
# loop through socket buffer until timeout is reached. then close buffer
@ -97,10 +98,9 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
# we need to loop through buffer until end of chunk is reached or timeout occured
while socketTimeout > time.time():
chunk = self.request.recv(45)
data += chunk
data += self.request.recv(64)
# or chunk.endswith(b'\n'):
if chunk.startswith(b'{"type"') and chunk.endswith(b'}\n'):
if data.startswith(b'{"type"') and data.endswith(b'}\n'):
break
data = data[:-1] # remove b'\n'
data = str(data, encoding)
@ -173,8 +173,9 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
data_bits = str(received_json["parameter"][0]["data_bits"])
stop_bits = str(received_json["parameter"][0]["stop_bits"])
handshake = str(received_json["parameter"][0]["handshake"])
radiocontrol = str(received_json["parameter"][0]["radiocontrol"])
rigctld_ip = str(received_json["parameter"][0]["rigctld_ip"])
rigctld_port = str(received_json["parameter"][0]["rigctld_port"])
structlog.get_logger("structlog").warning("[DMN] Starting TNC", rig=devicename, port=deviceport)
#print(received_json["parameter"][0])
@ -213,14 +214,14 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
options.append(stop_bits)
options.append('--handshake')
options.append(handshake)
if HAMLIB_USE_RIGCTL:
options.append('--rigctl')
options.append('--radiocontrol')
options.append(radiocontrol)
options.append('--rigctld_ip')
options.append(rigctld_ip)
options.append('--rigctld_port')
options.append(rigctld_port)
# try running tnc from binary, else run from source
# this helps running the tnc in a developer environment
@ -256,7 +257,7 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
static.TNCSTARTED = False
if received_json["type"] == 'GET' and received_json["command"] == 'DAEMON_STATE':
data = {
'COMMAND': 'DAEMON_STATE',
'DAEMON_STATE': [],
@ -279,7 +280,7 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
with noalsaerr(): # https://github.com/DJ2LS/FreeDATA/issues/22
p = pyaudio.PyAudio()
# else do it the default way
except:
except Exception as e:
p = pyaudio.PyAudio()
for i in range(0, p.get_device_count()):
@ -336,10 +337,25 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
data_bits = str(received_json["parameter"][0]["data_bits"])
stop_bits = str(received_json["parameter"][0]["stop_bits"])
handshake = str(received_json["parameter"][0]["handshake"])
radiocontrol = str(received_json["parameter"][0]["radiocontrol"])
rigctld_ip = str(received_json["parameter"][0]["rigctld_ip"])
rigctld_port = str(received_json["parameter"][0]["rigctld_port"])
# check how we want to control the radio
if radiocontrol == 'direct':
import rig
elif radiocontrol == 'rigctl':
import rigctl as rig
elif radiocontrol == 'rigctld':
import rigctld as rig
else:
raise NotImplementedError
hamlib = rig.radio()
hamlib.open_rig(devicename=devicename, deviceport=deviceport, hamlib_ptt_type=pttprotocol, serialspeed=serialspeed, pttport=pttport, data_bits=data_bits, stop_bits=stop_bits, handshake=handshake)
hamlib.open_rig(devicename=devicename, deviceport=deviceport, hamlib_ptt_type=pttprotocol, serialspeed=serialspeed, pttport=pttport, data_bits=data_bits, stop_bits=stop_bits, handshake=handshake, rigctld_ip=rigctld_ip, rigctld_port = rigctld_port)
hamlib_version = rig.hamlib_version
hamlib.set_ptt(True)
pttstate = hamlib.get_ptt()
@ -363,7 +379,6 @@ class CMDTCPRequestHandler(socketserver.BaseRequestHandler):
structlog.get_logger("structlog").error("[DMN] Hamlib: Can't open rig", e = sys.exc_info()[0], error=e)
except Exception as e:
#socketTimeout = 0
structlog.get_logger("structlog").error("[DMN] Network error", error=e)
structlog.get_logger("structlog").warning("[DMN] Closing client socket", ip=self.client_address[0], port=self.client_address[1])
@ -373,25 +388,10 @@ if __name__ == '__main__':
# --------------------------------------------GET PARAMETER INPUTS
PARSER = argparse.ArgumentParser(description='Simons TEST TNC')
PARSER.add_argument('--port', dest="socket_port",default=3001, help="Socket port", type=int)
PARSER.add_argument('--rigctl', dest="hamlib_use_rigctl",action="store_true", default=False, help="force using of rigctl")
ARGS = PARSER.parse_args()
PORT = ARGS.socket_port
HAMLIB_USE_RIGCTL = ARGS.hamlib_use_rigctl
# force use of rigctl when on windows
if sys.platform == 'win32' or sys.platform == 'win64':
HAMLIB_USE_RIGCTL = True
if HAMLIB_USE_RIGCTL:
structlog.get_logger("structlog").warning("[DMN] Using Hamlib rigctl module...")
hamlib_version = 0
import rigctl as rig
else:
structlog.get_logger("structlog").info("[DMN] Using Hamlib rig module...")
import rig
hamlib_version = rig.hamlib_version
# --------------------------------------------START CMD SERVER
DAEMON_THREAD = threading.Thread(target=start_daemon, name="daemon")

View file

@ -37,8 +37,12 @@ if __name__ == '__main__':
PARSER.add_argument('--data_bits', dest="hamlib_data_bits", default="8", help="Hamlib data bits", type=str)
PARSER.add_argument('--stop_bits', dest="hamlib_stop_bits", default="1", help="Hamlib stop bits", type=str)
PARSER.add_argument('--handshake', dest="hamlib_handshake", default="None", help="Hamlib handshake", type=str)
PARSER.add_argument('--rigctl', dest="hamlib_use_rigctl", action="store_true", default=False, help="force using of rigctl")
PARSER.add_argument('--radiocontrol', dest="hamlib_radiocontrol", default="direct", help="Set how you want to control your radio")
PARSER.add_argument('--rigctld_port', dest="rigctld_port", default="direct", help="Set rigctld port")
PARSER.add_argument('--rigctld_ip', dest="rigctld_ip", default="direct", help="Set rigctld ip")
ARGS = PARSER.parse_args()
@ -57,12 +61,9 @@ if __name__ == '__main__':
static.HAMLIB_DATA_BITS = ARGS.hamlib_data_bits
static.HAMLIB_STOP_BITS = ARGS.hamlib_stop_bits
static.HAMLIB_HANDSHAKE = ARGS.hamlib_handshake
static.HAMLIB_USE_RIGCTL = ARGS.hamlib_use_rigctl
print(ARGS.hamlib_use_rigctl)
# force use of rigctl when on windows
if sys.platform == 'win32' or sys.platform == 'win64':
HAMLIB_USE_RIGCTL = True
static.HAMLIB_RADIOCONTROL = ARGS.hamlib_radiocontrol
static.HAMLIB_RGICTLD_IP = ARGS.rigctld_ip
static.HAMLIB_RGICTLD_PORT = ARGS.rigctld_port
# we need to wait until we got all parameters from argparse first before we can load the other modules
import sock

View file

@ -23,16 +23,6 @@ import re
import queue
import codec2
if static.HAMLIB_USE_RIGCTL:
structlog.get_logger("structlog").warning("using rigctl....")
import rigctl as rig
else:
structlog.get_logger("structlog").warning("using rig.......")
import rig
# option for testing miniaudio instead of audioop for sample rate conversion
#import miniaudio
####################################################
# https://stackoverflow.com/questions/7088672/pyaudio-working-but-spits-out-error-messages-each-time
@ -189,9 +179,20 @@ class RF():
structlog.get_logger("structlog").error("[TNC] starting pyaudio callback failed", e=e)
# --------------------------------------------INIT AND OPEN HAMLIB
self.hamlib = rig.radio()
self.hamlib.open_rig(devicename=static.HAMLIB_DEVICE_NAME, deviceport=static.HAMLIB_DEVICE_PORT, hamlib_ptt_type=static.HAMLIB_PTT_TYPE, serialspeed=static.HAMLIB_SERIAL_SPEED, pttport=static.HAMLIB_PTT_PORT, data_bits=static.HAMLIB_DATA_BITS, stop_bits=static.HAMLIB_STOP_BITS, handshake=static.HAMLIB_HANDSHAKE)
# check how we want to control the radio
if static.HAMLIB_RADIOCONTROL == 'direct':
import rig
elif static.HAMLIB_RADIOCONTROL == 'rigctl':
import rigctl as rig
elif static.HAMLIB_RADIOCONTROL == 'rigctld':
import rigctld as rig
else:
raise NotImplementedError
self.hamlib = rig.radio()
self.hamlib.open_rig(devicename=static.HAMLIB_DEVICE_NAME, deviceport=static.HAMLIB_DEVICE_PORT, hamlib_ptt_type=static.HAMLIB_PTT_TYPE, serialspeed=static.HAMLIB_SERIAL_SPEED, pttport=static.HAMLIB_PTT_PORT, data_bits=static.HAMLIB_DATA_BITS, stop_bits=static.HAMLIB_STOP_BITS, handshake=static.HAMLIB_HANDSHAKE, rigctld_ip = static.HAMLIB_RGICTLD_IP, rigctld_port = static.HAMLIB_RGICTLD_PORT)
# --------------------------------------------START DECODER THREAD
fft_thread = threading.Thread(target=self.calculate_fft, name="FFT_THREAD")

View file

@ -7,6 +7,7 @@ import atexit
import subprocess
import os
# set global hamlib version
hamlib_version = 0
@ -25,7 +26,7 @@ try:
python_version = str(sys.version_info[0]) + "." + str(sys.version_info[1])
# installation path for Ubuntu 20.04 LTS python modules
sys.path.append('/usr/local/lib/python'+ python_version +'/site-packages')
#sys.path.append('/usr/local/lib/python'+ python_version +'/site-packages')
# installation path for Ubuntu 20.10 +
sys.path.append('/usr/local/lib/')
@ -37,10 +38,11 @@ try:
# this is not needed as python will be shipped with app bundle
sys.path.append('/usr/local/lib/python3.6/site-packages')
sys.path.append('/usr/local/lib/python3.7/site-packages')
sys.path.append('/usr/local/lib/python3.8/site-packages')
#sys.path.append('/usr/local/lib/python3.8/site-packages')
sys.path.append('/usr/local/lib/python3.9/site-packages')
sys.path.append('/usr/local/lib/python3.10/site-packages')
sys.path.append('lib/hamlib/linux/python3.8/site-packages')
import Hamlib
# https://stackoverflow.com/a/4703409
@ -85,7 +87,7 @@ class radio:
self.stop_bits = ''
self.handshake = ''
def open_rig(self, devicename, deviceport, hamlib_ptt_type, serialspeed, pttport, data_bits, stop_bits, handshake):
def open_rig(self, devicename, deviceport, hamlib_ptt_type, serialspeed, pttport, data_bits, stop_bits, handshake, rigctld_port, rigctld_ip):
self.devicename = devicename
self.deviceport = str(deviceport)
@ -106,7 +108,7 @@ class radio:
self.devicenumber = int(getattr(Hamlib, self.devicename))
print(self.devicenumber)
except:
structlog.get_logger("structlog").error("[DMN] Hamlib: rig not supported...")
structlog.get_logger("structlog").error("[RIG] Hamlib: rig not supported...")
self.devicenumber = 0
@ -177,11 +179,11 @@ class radio:
error = error[1]
if error == 'Permission denied':
structlog.get_logger("structlog").error("[DMN] Hamlib has no permissions", e = error)
structlog.get_logger("structlog").error("[RIG] Hamlib has no permissions", e = error)
help_url = 'https://github.com/DJ2LS/FreeDATA/wiki/UBUNTU-Manual-installation#1-permissions'
structlog.get_logger("structlog").error("[DMN] HELP:", check = help_url)
structlog.get_logger("structlog").error("[RIG] HELP:", check = help_url)
except:
structlog.get_logger("structlog").info("[DMN] Hamlib device openend", status='SUCCESS')
structlog.get_logger("structlog").info("[RIG] Hamlib device openend", status='SUCCESS')
# set ptt to false if ptt is stuck for some reason
@ -194,7 +196,7 @@ class radio:
return True
except Exception as e:
structlog.get_logger("structlog").error("[TNC] Hamlib - can't open rig", error=e, e=sys.exc_info()[0])
structlog.get_logger("structlog").error("[RIG] Hamlib - can't open rig", error=e, e=sys.exc_info()[0])
return False
def get_frequency(self):

View file

@ -1,5 +1,7 @@
#!/usr/bin/env python3
# Franco Spinelli, IW2DHW
# Intially created by Franco Spinelli, IW2DHW, 01/2022
# Updated by DJ2LS
#
#
# versione mia di rig.py per gestire Ft897D tramite rigctl e senza
# fare alcun riferimento alla configurazione
@ -13,6 +15,8 @@ import sys
import os
# for rig_model -> rig_number only
# set global hamlib version
hamlib_version = 0
class radio:
def __init__(self):
@ -28,7 +32,7 @@ class radio:
self.stop_bits = ''
self.handshake = ''
def open_rig(self, devicename, deviceport, hamlib_ptt_type, serialspeed, pttport, data_bits, stop_bits, handshake):
def open_rig(self, devicename, deviceport, hamlib_ptt_type, serialspeed, pttport, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port):
self.devicename = devicename
self.deviceport = deviceport
@ -56,8 +60,12 @@ class radio:
self.devicenumber = int(self.devicename)
else:
self.devicenumber = 6 #dummy
structlog.get_logger("structlog").warning("[TNC] RADIO NOT FOUND USING DUMMY!", error=e)
structlog.get_logger("structlog").warning("[RIGCTL] RADIO NOT FOUND USING DUMMY!", error=e)
# set deviceport to dummy port, if we selected dummy model
if self.devicenumber == 1 or self.devicenumber == 6:
self.deviceport = '/dev/ttyUSB0'
print(self.devicenumber, self.deviceport, self.serialspeed)

81
tnc/rigctld.py Normal file
View file

@ -0,0 +1,81 @@
#!/usr/bin/env python3
import socket
import logging
# class taken from darsidelemm
# rigctl - https://github.com/darksidelemm/rotctld-web-gui/blob/master/rotatorgui.py#L35
#
# modified and adjusted to FreeDATA needs by DJ2LS
# set global hamlib version
hamlib_version = 0
class radio():
""" rotctld (hamlib) communication class """
# Note: This is a massive hack.
def __init__(self, hostname="localhost", port=4532, poll_rate=5, timeout=5):
""" Open a connection to rotctld, and test it for validity """
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(timeout)
self.hostname = hostname
self.port = port
def open_rig(self, devicename, deviceport, hamlib_ptt_type, serialspeed, pttport, data_bits, stop_bits, handshake, rigctld_ip, rigctld_port):
self.connect()
logging.debug(f"Rigctl intialized")
return True
def connect(self):
""" Connect to rotctld instance """
self.sock.connect((self.hostname,self.port))
ptt = self.get_ptt()
if ptt == None:
# Timeout!
self.close()
raise Exception("Timeout!")
else:
return ptt
def close_rig(self):
self.sock.close()
def send_command(self, command):
""" Send a command to the connected rotctld instance,
and return the return value.
"""
self.sock.sendall(command+b'\n')
try:
return self.sock.recv(1024)
except:
return None
def get_mode(self):
data = self.send_command(b"m")
data = data.split(b'\n')
mode = data[0]
return mode.decode("utf-8")
def get_bandwith(self):
data = self.send_command(b"m")
data = data.split(b'\n')
bandwith = data[1]
return bandwith.decode("utf-8")
def get_frequency(self):
frequency = self.send_command(b"f")
return frequency.decode("utf-8")
def get_ptt(self):
return self.send_command(b"t")
def set_ptt(self, state):
if state:
self.send_command(b"T 1")
else:
self.send_command(b"T 0")
return state

View file

@ -56,11 +56,10 @@ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
# we need to loop through buffer until end of chunk is reached or timeout occured
while socketTimeout > time.time():
data += self.request.recv(64) # we keep amount of bytes short
chunk = self.request.recv(71) # we keep amount of bytes short
data += chunk
if chunk.startswith(b'{"type"') and chunk.endswith(b'}\n'):
if data.startswith(b'{"type"') and data.endswith(b'}\n'):
break
data = data[:-1] # remove b'\n'

View file

@ -45,8 +45,10 @@ HAMLIB_PTT_PORT = '/dev/ttyUSB0'
HAMLIB_STOP_BITS = '1'
HAMLIB_DATA_BITS = '8'
HAMLIB_HANDSHAKE = 'None'
HAMLIB_USE_RIGCTL = False
HAMLIB_RADIOCONTROL = 'direct'
HAMLIB_RGICTLD_IP = '127.0.0.1'
HAMLIB_RGICTLD_PORT = '4532'
HAMLIB_FREQUENCY = 0
HAMLIB_MODE = ''
HAMLIB_BANDWITH = 0