mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-25 17:25:16 +03:00
Add manual connection option (#3703)
* Hide manual connection and refactor port_handler * Rebased
This commit is contained in:
parent
d354567129
commit
6105210e9e
5 changed files with 129 additions and 110 deletions
|
@ -55,6 +55,9 @@
|
|||
"portsSelectManual": {
|
||||
"message": "Manual Selection"
|
||||
},
|
||||
"portsSelectNone": {
|
||||
"message": "No connection available"
|
||||
},
|
||||
"portsSelectVirtual": {
|
||||
"message": "Virtual Mode (Experimental)",
|
||||
"description": "Configure a Virtual Flight Controller without the need of a physical FC."
|
||||
|
@ -113,6 +116,10 @@
|
|||
"message": "Use mDNS Browser Device discovery on network (experimental)",
|
||||
"description": "Enable mDNS Browser Device discovery in PortHandler (experimental)"
|
||||
},
|
||||
"showManualMode": {
|
||||
"message": "Enable manual connection mode",
|
||||
"description": "Text for the option to enable or disable manual connection mode"
|
||||
},
|
||||
"showVirtualMode": {
|
||||
"message": "Enable virtual connection mode",
|
||||
"description": "Text for the option to enable or disable the virtual FC"
|
||||
|
|
|
@ -5,7 +5,6 @@ import { generateVirtualApiVersions, getTextWidth } from './utils/common';
|
|||
import { get as getConfig } from "./ConfigStorage";
|
||||
import serial from "./serial";
|
||||
import MdnsDiscovery from "./mdns_discovery";
|
||||
import $ from 'jquery';
|
||||
import { isWeb } from "./utils/isWeb";
|
||||
|
||||
const TIMEOUT_CHECK = 500 ; // With 250 it seems that it produces a memory leak and slowdown in some versions, reason unknown
|
||||
|
@ -18,6 +17,7 @@ export const usbDevices = { filters: [
|
|||
] };
|
||||
|
||||
const PortHandler = new function () {
|
||||
this.currentPorts = [];
|
||||
this.initialPorts = false;
|
||||
this.port_detected_callbacks = [];
|
||||
this.port_removed_callbacks = [];
|
||||
|
@ -26,6 +26,7 @@ const PortHandler = new function () {
|
|||
this.showAllSerialDevices = false;
|
||||
this.useMdnsBrowser = false;
|
||||
this.showVirtualMode = false;
|
||||
this.showManualMode = false;
|
||||
};
|
||||
|
||||
PortHandler.initialize = function () {
|
||||
|
@ -56,6 +57,7 @@ PortHandler.reinitialize = function () {
|
|||
}
|
||||
|
||||
this.showVirtualMode = getConfig('showVirtualMode').showVirtualMode;
|
||||
this.showManualMode = getConfig('showManualMode').showManualMode;
|
||||
this.showAllSerialDevices = getConfig('showAllSerialDevices').showAllSerialDevices;
|
||||
this.useMdnsBrowser = getConfig('useMdnsBrowser').useMdnsBrowser;
|
||||
|
||||
|
@ -86,10 +88,10 @@ PortHandler.check_serial_devices = function () {
|
|||
const self = this;
|
||||
|
||||
serial.getDevices(function(cp) {
|
||||
let currentPorts = [];
|
||||
self.currentPorts = [];
|
||||
|
||||
if (self.useMdnsBrowser) {
|
||||
currentPorts = [
|
||||
self.currentPorts = [
|
||||
...cp,
|
||||
...(MdnsDiscovery.mdnsBrowser.services?.filter(s => s.txt?.vendor === 'elrs' && s.txt?.type === 'rx' && s.ready === true)
|
||||
.map(s => s.addresses.map(a => ({
|
||||
|
@ -101,36 +103,35 @@ PortHandler.check_serial_devices = function () {
|
|||
}))).flat() ?? []),
|
||||
].filter(Boolean);
|
||||
} else {
|
||||
currentPorts = cp;
|
||||
self.currentPorts = cp;
|
||||
}
|
||||
|
||||
// auto-select port (only during initialization)
|
||||
if (!self.initialPorts) {
|
||||
currentPorts = self.updatePortSelect(currentPorts);
|
||||
self.selectPort(currentPorts);
|
||||
self.initialPorts = currentPorts;
|
||||
self.updatePortSelect(self.currentPorts);
|
||||
self.selectActivePort();
|
||||
self.initialPorts = self.currentPorts;
|
||||
GUI.updateManualPortVisibility();
|
||||
} else {
|
||||
self.removePort(currentPorts);
|
||||
self.detectPort(currentPorts);
|
||||
self.removePort();
|
||||
self.detectPort();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
PortHandler.check_usb_devices = function (callback) {
|
||||
const self = this;
|
||||
|
||||
chrome.usb.getDevices(usbDevices, function (result) {
|
||||
|
||||
const dfuElement = self.portPickerElement.children("[value='DFU']");
|
||||
if (result.length) {
|
||||
// Found device in DFU mode, add it to the list
|
||||
if (!dfuElement.length) {
|
||||
self.portPickerElement.empty();
|
||||
let usbText;
|
||||
if (result[0].productName) {
|
||||
usbText = (`DFU - ${result[0].productName}`);
|
||||
} else {
|
||||
usbText = "DFU";
|
||||
}
|
||||
|
||||
const productName = result[0].productName;
|
||||
const usbText = productName ? `DFU - ${productName}` : 'DFU';
|
||||
|
||||
self.portPickerElement.append($('<option/>', {
|
||||
value: "DFU",
|
||||
|
@ -176,22 +177,18 @@ PortHandler.check_usb_devices = function (callback) {
|
|||
});
|
||||
};
|
||||
|
||||
PortHandler.removePort = function(currentPorts) {
|
||||
PortHandler.removePort = function() {
|
||||
const self = this;
|
||||
const removePorts = self.array_difference(self.initialPorts, currentPorts);
|
||||
const removePorts = self.array_difference(self.initialPorts, self.currentPorts);
|
||||
|
||||
if (removePorts.length) {
|
||||
console.log(`PortHandler - Removed: ${JSON.stringify(removePorts)}`);
|
||||
self.port_available = false;
|
||||
// disconnect "UI" - routine can't fire during atmega32u4 reboot procedure !!!
|
||||
if (GUI.connected_to) {
|
||||
for (let i = 0; i < removePorts.length; i++) {
|
||||
if (removePorts[i].path === GUI.connected_to) {
|
||||
if (removePorts.some(port => port.path === GUI.connected_to)) {
|
||||
$('div.connect_controls a.connect').click();
|
||||
$('div.connect_controls a.connect.active').click();
|
||||
}
|
||||
}
|
||||
}
|
||||
// trigger callbacks (only after initialization)
|
||||
for (let i = (self.port_removed_callbacks.length - 1); i >= 0; i--) {
|
||||
const obj = self.port_removed_callbacks[i];
|
||||
|
@ -208,26 +205,26 @@ PortHandler.removePort = function(currentPorts) {
|
|||
self.port_removed_callbacks.splice(index, 1);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < removePorts.length; i++) {
|
||||
self.initialPorts.splice(self.initialPorts.indexOf(removePorts[i]), 1);
|
||||
for (const port of removePorts) {
|
||||
self.initialPorts.splice(self.initialPorts.indexOf(port, 1));
|
||||
}
|
||||
self.updatePortSelect(self.initialPorts);
|
||||
self.portPickerElement.trigger('change');
|
||||
}
|
||||
};
|
||||
|
||||
PortHandler.detectPort = function(currentPorts) {
|
||||
PortHandler.detectPort = function() {
|
||||
const self = this;
|
||||
const newPorts = self.array_difference(currentPorts, self.initialPorts);
|
||||
const newPorts = self.array_difference(self.currentPorts, self.initialPorts);
|
||||
|
||||
if (newPorts.length) {
|
||||
currentPorts = self.updatePortSelect(currentPorts);
|
||||
self.updatePortSelect(self.currentPorts);
|
||||
console.log(`PortHandler - Found: ${JSON.stringify(newPorts)}`);
|
||||
|
||||
if (newPorts.length === 1) {
|
||||
self.portPickerElement.val(newPorts[0].path);
|
||||
} else if (newPorts.length > 1) {
|
||||
self.selectPort(currentPorts);
|
||||
self.selectActivePort();
|
||||
}
|
||||
|
||||
self.port_available = true;
|
||||
|
@ -239,12 +236,10 @@ PortHandler.detectPort = function(currentPorts) {
|
|||
self.portPickerElement.trigger('change');
|
||||
|
||||
// auto-connect if enabled
|
||||
if (GUI.auto_connect && !GUI.connecting_to && !GUI.connected_to) {
|
||||
if (GUI.auto_connect && !GUI.connecting_to && !GUI.connected_to && GUI.active_tab !== 'firmware_flasher') {
|
||||
// start connect procedure. We need firmware flasher protection over here
|
||||
if (GUI.active_tab !== 'firmware_flasher') {
|
||||
$('div.connect_controls a.connect').click();
|
||||
}
|
||||
}
|
||||
// trigger callbacks
|
||||
for (let i = (self.port_detected_callbacks.length - 1); i >= 0; i--) {
|
||||
const obj = self.port_detected_callbacks[i];
|
||||
|
@ -261,7 +256,7 @@ PortHandler.detectPort = function(currentPorts) {
|
|||
self.port_detected_callbacks.splice(index, 1);
|
||||
}
|
||||
}
|
||||
self.initialPorts = currentPorts;
|
||||
self.initialPorts = self.currentPorts;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -274,20 +269,24 @@ PortHandler.sortPorts = function(ports) {
|
|||
});
|
||||
};
|
||||
|
||||
PortHandler.addNoPortSelection = function() {
|
||||
if (!this.showVirtualMode && !this.showManualMode) {
|
||||
this.portPickerElement.append($("<option/>", {
|
||||
value: 'none',
|
||||
text: i18n.getMessage('portsSelectNone'),
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
PortHandler.updatePortSelect = function (ports) {
|
||||
ports = this.sortPorts(ports);
|
||||
this.portPickerElement.empty();
|
||||
|
||||
for (let i = 0; i < ports.length; i++) {
|
||||
let portText;
|
||||
if (ports[i].displayName) {
|
||||
portText = (`${ports[i].path} - ${ports[i].displayName}`);
|
||||
} else {
|
||||
portText = ports[i].path;
|
||||
}
|
||||
for (const port of ports) {
|
||||
const portText = port.displayName ? `${port.path} - ${port.displayName}` : port.path;
|
||||
|
||||
this.portPickerElement.append($("<option/>", {
|
||||
value: ports[i].path,
|
||||
value: port.path,
|
||||
text: portText,
|
||||
/**
|
||||
* @deprecated please avoid using `isDFU` and friends for new code.
|
||||
|
@ -307,6 +306,7 @@ PortHandler.updatePortSelect = function (ports) {
|
|||
}));
|
||||
}
|
||||
|
||||
if (this.showManualMode) {
|
||||
this.portPickerElement.append($("<option/>", {
|
||||
value: 'manual',
|
||||
text: i18n.getMessage('portsSelectManual'),
|
||||
|
@ -315,12 +315,18 @@ PortHandler.updatePortSelect = function (ports) {
|
|||
*/
|
||||
data: {isManual: true},
|
||||
}));
|
||||
}
|
||||
|
||||
if (!ports.length) {
|
||||
this.addNoPortSelection();
|
||||
}
|
||||
|
||||
this.setPortsInputWidth();
|
||||
return ports;
|
||||
this.currentPorts = ports;
|
||||
};
|
||||
|
||||
PortHandler.selectPort = function(ports) {
|
||||
PortHandler.selectActivePort = function() {
|
||||
const ports = this.currentPorts;
|
||||
const OS = GUI.operating_system;
|
||||
for (let i = 0; i < ports.length; i++) {
|
||||
const portName = ports[i].displayName;
|
||||
|
|
|
@ -55,18 +55,9 @@ export function initializeSerialBackend() {
|
|||
}
|
||||
const selected_port = $('#port').val();
|
||||
|
||||
if (selected_port === 'manual') {
|
||||
$('#port-override-option').show();
|
||||
}
|
||||
else {
|
||||
$('#port-override-option').hide();
|
||||
}
|
||||
if (selected_port === 'virtual') {
|
||||
$('#firmware-virtual-option').show();
|
||||
}
|
||||
else {
|
||||
$('#firmware-virtual-option').hide();
|
||||
}
|
||||
$('#port-override-option').toggle(selected_port === 'manual');
|
||||
|
||||
$('#firmware-virtual-option').toggle(selected_port === 'virtual');
|
||||
|
||||
$('#auto-connect-and-baud').toggle(selected_port !== 'DFU');
|
||||
};
|
||||
|
@ -97,7 +88,7 @@ export function initializeSerialBackend() {
|
|||
portName = String($('div#port-picker #port').val());
|
||||
}
|
||||
|
||||
if (!GUI.connect_lock) {
|
||||
if (!GUI.connect_lock && selectedPort !== 'none') {
|
||||
// GUI control overrides the user control
|
||||
|
||||
GUI.configuration_loaded = false;
|
||||
|
@ -107,7 +98,9 @@ export function initializeSerialBackend() {
|
|||
|
||||
if (selectedPort === 'DFU') {
|
||||
$('select#baud').hide();
|
||||
} else if (portName !== '0') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isConnected) {
|
||||
console.log(`Connecting to: ${portName}`);
|
||||
GUI.connecting_to = portName;
|
||||
|
@ -136,11 +129,7 @@ export function initializeSerialBackend() {
|
|||
|
||||
serial.connect({ baudRate });
|
||||
} else {
|
||||
serial.connect(
|
||||
portName,
|
||||
{ bitrate: selected_baud },
|
||||
onOpen,
|
||||
);
|
||||
serial.connect(portName, { bitrate: selected_baud }, onOpen);
|
||||
toggleStatus();
|
||||
}
|
||||
|
||||
|
@ -160,7 +149,6 @@ export function initializeSerialBackend() {
|
|||
mspHelper?.setArmingEnabled(true, false, onFinishCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('div.open_firmware_flasher a.flash').click(function () {
|
||||
|
|
|
@ -25,6 +25,7 @@ options.initialize = function (callback) {
|
|||
TABS.options.initShowAllSerialDevices();
|
||||
TABS.options.initUseMdnsBrowser();
|
||||
TABS.options.initShowVirtualMode();
|
||||
TABS.options.initUseManualConnection();
|
||||
TABS.options.initCordovaForceComputerUI();
|
||||
TABS.options.initDarkTheme();
|
||||
TABS.options.initShowDevToolsOnStartup();
|
||||
|
@ -145,6 +146,17 @@ options.initShowVirtualMode = function() {
|
|||
});
|
||||
};
|
||||
|
||||
options.initUseManualConnection = function() {
|
||||
const showManualModeElement = $('div.showManualMode input');
|
||||
const result = getConfig('showManualMode');
|
||||
showManualModeElement
|
||||
.prop('checked', !!result.showManualMode)
|
||||
.on('change', () => {
|
||||
setConfig({ showManualMode: showManualModeElement.is(':checked') });
|
||||
PortHandler.reinitialize();
|
||||
});
|
||||
};
|
||||
|
||||
options.initUseMdnsBrowser = function() {
|
||||
const useMdnsBrowserElement = $('div.useMdnsBrowser input');
|
||||
const result = getConfig('useMdnsBrowser');
|
||||
|
|
|
@ -41,6 +41,12 @@
|
|||
</div>
|
||||
<span class="freelabel" i18n="useMdnsBrowser"></span>
|
||||
</div>
|
||||
<div class="showManualMode margin-bottom">
|
||||
<div>
|
||||
<input type="checkbox" class="toggle" />
|
||||
</div>
|
||||
<span class="freelabel" i18n="showManualMode"></span>
|
||||
</div>
|
||||
<div class="showVirtualMode margin-bottom">
|
||||
<div>
|
||||
<input type="checkbox" class="toggle" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue