rebase and fix
reference to https://github.com/cleanflight/cleanflight-configurator/pull/44510.3.x-maintenance
parent
a4da6240a1
commit
59e9f59887
|
@ -839,9 +839,6 @@
|
|||
"receiverRcInterpolationIntervalHelp": {
|
||||
"message": "Interpolation interval for manual RC interpolation mode in milliseconds"
|
||||
},
|
||||
"receiverRcInterpolation": {
|
||||
"message": "RC Interpolation"
|
||||
},
|
||||
"receiverRcInterpolationOff": {
|
||||
"message": "Off"
|
||||
},
|
||||
|
@ -1182,24 +1179,48 @@
|
|||
"transponderNotSupported": {
|
||||
"message": "Your flight controller's firmware does not support transponder functionality."
|
||||
},
|
||||
"transponderHelp": {
|
||||
"message": "Configure your transponder code here. Note: Only valid codes will be recognised by race timing systems. Valid transponder codes can be obtained from <a href=\"http://seriouslypro.com/transponder-codes\" target=\"_blank\">Seriously Pro</a>."
|
||||
},
|
||||
"transponderInformation": {
|
||||
"message": "Transponders systems allow race organizers to time your laps. The transponder is fitted to your aircraft and when your aircraft passes the timing gate the track-side receiver registers your code and records your laptime. When fitting an IR based transponder your should ensure that it points outward from your aircraft towards the track-side receivers and that the light beam is not obstructed by your airframe, battery-straps, cables, propellers, etc."
|
||||
},
|
||||
"transponderConfiguration": {
|
||||
"message": "Configuration"
|
||||
"transponderConfigurationType": {
|
||||
"message": "Transponder type"
|
||||
},
|
||||
"transponderData": {
|
||||
"transponderType0": {
|
||||
"message": "None"
|
||||
},
|
||||
"transponderType1": {
|
||||
"message": "iLap"
|
||||
},
|
||||
"transponderType2": {
|
||||
"message": "aRCiTimer"
|
||||
},
|
||||
"transponderConfiguration1": {
|
||||
"message": "Configuration iLap"
|
||||
},
|
||||
"transponderConfiguration2": {
|
||||
"message": "Configuration aRCiTimer"
|
||||
},
|
||||
"transponderData1": {
|
||||
"message": "Data"
|
||||
},
|
||||
"transponderDataHelp": {
|
||||
"transponderData2": {
|
||||
"message": "Transponder ID"
|
||||
},
|
||||
"transponderDataHelp1": {
|
||||
"message": "Hexadecimal digits only, 0-9, A-F"
|
||||
},
|
||||
"transponderHelp1": {
|
||||
"message": "Configure your transponder code here. Note: Only valid codes will be recognised by race timing systems. Valid transponder codes can be obtained from <a href=\"http://seriouslypro.com/transponder-codes\" target=\"_blank\">Seriously Pro</a>."
|
||||
},
|
||||
"transponderHelp2": {
|
||||
"message": "For more information please visit <a href=\"http://www.arcitimer.com/\" title=\"aRCiTimer\" target=\"_blank\">aRCiTimer site</a>"
|
||||
},
|
||||
"transponderButtonSave": {
|
||||
"message": "Save"
|
||||
},
|
||||
"transponderButtonSaveReboot": {
|
||||
"message": "Save and Reboot"
|
||||
},
|
||||
"transponderDataInvalid": {
|
||||
"message": "Transponder data is <span style=\"color: red\">invalid</span>"
|
||||
},
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<div class="tab-transponder toolbar_fixed_bottom">
|
||||
<div class="content_wrapper">
|
||||
|
||||
<div class="tab_title" i18n="tabTransponder">Transponder</div>
|
||||
|
||||
<div class="cf_doc_version_bt">
|
||||
<a id="button-documentation" href="https://github.com/betaflight/betaflight/releases" target="_blank"></a>
|
||||
</div>
|
||||
|
@ -12,31 +14,47 @@
|
|||
</div>
|
||||
|
||||
<div class="require-transponder-supported">
|
||||
|
||||
<div class="note" style="margin-bottom: 20px;">
|
||||
<div class="note_spacer">
|
||||
<p i18n="transponderHelp"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gui_box grey">
|
||||
<div class="gui_box_titlebar">
|
||||
<div class="spacer_box_title" i18n="transponderConfiguration"></div>
|
||||
</div>
|
||||
<div class="spacer_box">
|
||||
<div class="text transponderData">
|
||||
<div class="textspacer" >
|
||||
<input type="text" name="data" spellcheck="false"/>
|
||||
</div>
|
||||
<label for="failsafe_feature_new"><span i18n="transponderData"></span>
|
||||
</label>
|
||||
<div class="helpicon cf_tip" i18n_title="transponderDataHelp"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
<div class="spacer_box_title" i18n="transponderConfigurationType"></div>
|
||||
</div>
|
||||
|
||||
<div class="spacer_box">
|
||||
<div class="radio transponderType">
|
||||
<div class="textspacer-small" >
|
||||
<select id="transponder_type_select">
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="transponderHelpBox">
|
||||
<div class="clear-both"></div>
|
||||
<div class="note">
|
||||
<div class="note_spacer">
|
||||
<p id="transponderHelp"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="transponderConfiguration" class="gui_box grey">
|
||||
<!--<div class="spacer_box">
|
||||
<div class="text transponderData">
|
||||
<div class="textspacer" >
|
||||
<input class="transponder_input" type="text" spellcheck="false"/>
|
||||
</div>
|
||||
<label class="transponder_label">
|
||||
|
||||
</label>
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
<div class="note">
|
||||
<div class="note_spacer">
|
||||
<p i18n="transponderInformation"></p>
|
||||
|
@ -44,9 +62,13 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content_toolbar require-transponder-supported">
|
||||
<div class="btn save_btn">
|
||||
<div class="btn save_btn save_no_reboot">
|
||||
<a class="save" href="#" i18n="transponderButtonSave"></a>
|
||||
</div>
|
||||
<div class="btn save_btn save_reboot" style="display: none">
|
||||
<a class="save reboot" href="#" i18n="transponderButtonSaveReboot"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,19 +1,50 @@
|
|||
'use strict';
|
||||
|
||||
|
||||
TABS.transponder = {
|
||||
available: false
|
||||
};
|
||||
|
||||
TABS.transponder.initialize = function (callback, scrollPosition) {
|
||||
var self = this;
|
||||
|
||||
var dataTypes = {
|
||||
NONE : 0,
|
||||
TEXT : 1,
|
||||
LIST : 2,
|
||||
};
|
||||
|
||||
var transponderConfigurations = {
|
||||
0: {
|
||||
dataType: dataTypes.NONE // empty
|
||||
}, //NONE
|
||||
1: {
|
||||
dataType: dataTypes.TEXT //<input type="text">
|
||||
}, //ilap
|
||||
2: {
|
||||
dataType: dataTypes.LIST, // <select>...</select>
|
||||
dataOptions: {
|
||||
'ID 1' : 'E00370FC0FFE07E0FF',
|
||||
'ID 2' : '007C003EF800FC0FFE',
|
||||
'ID 3' : 'F8811FF8811FFFC7FF',
|
||||
'ID 4' : '007C003EF81F800FFE',
|
||||
'ID 5' : 'F00FFF00FFF00FF0FF',
|
||||
'ID 6' : '007CF0C1071F7C00F0',
|
||||
'ID 7' : 'E003F03F00FF03F0C1',
|
||||
'ID 8' : '00FC0FFE071F3E00FE',
|
||||
'ID 9' : 'E083BFF00F9E38C0FF',
|
||||
}
|
||||
}, //arcitimer
|
||||
};
|
||||
|
||||
if (GUI.active_tab != 'transponder') {
|
||||
GUI.active_tab = 'transponder';
|
||||
googleAnalytics.sendAppView('Transponder');
|
||||
}
|
||||
|
||||
// transponder supported added in MSP API Version 1.16.0
|
||||
if (CONFIG) {
|
||||
TABS.transponder.available = semver.gte(CONFIG.apiVersion, "1.16.0");
|
||||
|
||||
}
|
||||
//////////////
|
||||
if (!TABS.transponder.available) {
|
||||
load_html();
|
||||
return;
|
||||
|
@ -23,9 +54,7 @@ TABS.transponder.initialize = function (callback, scrollPosition) {
|
|||
$('#content').load("./tabs/transponder.html", process_html);
|
||||
}
|
||||
|
||||
// get the transponder data and a flag to see if transponder support is enabled on the FC
|
||||
MSP.send_message(MSPCodes.MSP_TRANSPONDER_CONFIG, false, false, load_html);
|
||||
|
||||
//HELPERS
|
||||
// Convert a hex string to a byte array
|
||||
function hexToBytes(hex) {
|
||||
for (var bytes = [], c = 0; c < hex.length; c += 2)
|
||||
|
@ -41,59 +70,199 @@ TABS.transponder.initialize = function (callback, scrollPosition) {
|
|||
// Convert a byte array to a hex string
|
||||
function bytesToHex(bytes) {
|
||||
for (var hex = [], i = 0; i < bytes.length; i++) {
|
||||
hex.push(pad(((~bytes[i]) & 0xFF).toString(16),2));
|
||||
hex.push(pad(((~bytes[i]) & 0xFF).toString(16), 2));
|
||||
}
|
||||
return hex.join("").toUpperCase();
|
||||
}
|
||||
function process_html() {
|
||||
// translate to user-selected language
|
||||
localize();
|
||||
/////////////
|
||||
|
||||
$(".tab-transponder")
|
||||
.toggleClass("transponder-supported", TABS.transponder.available && TRANSPONDER.supported);
|
||||
function fillByTransponderProviders(transponderProviders, transponderProviderID, toggleTransponderType){
|
||||
var transponderTypeSelect = $('#transponder_type_select');
|
||||
transponderTypeSelect.attr('data-defaultValue', transponderProviderID);
|
||||
transponderTypeSelect.off('change').change(toggleTransponderType);
|
||||
transponderTypeSelect.html('');
|
||||
|
||||
if (TABS.transponder.available) {
|
||||
//build radio buttons
|
||||
transponderTypeSelect.append(
|
||||
$('<option>').attr('value', 0).html(chrome.i18n.getMessage("transponderType0")) // NONE
|
||||
);
|
||||
|
||||
var data = bytesToHex(TRANSPONDER.data);
|
||||
for(var transponderProvidersKey in transponderProviders){
|
||||
var transponderProvider = transponderProviders[transponderProvidersKey];
|
||||
|
||||
$('input[name="data"]').val(data);
|
||||
$('input[name="data"]').prop('maxLength', data.length);
|
||||
if(transponderProvider.hasOwnProperty('id')){
|
||||
transponderTypeSelect.append(
|
||||
$('<option>').attr('value', transponderProvider.id).html(chrome.i18n.getMessage("transponderType" + transponderProvider.id))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$('a.save').click(function () {
|
||||
transponderTypeSelect.val(transponderProviderID);
|
||||
}
|
||||
|
||||
function buildDataBlockForTransponderProviders(transponderProvider, data, clearValue) {
|
||||
var clearValue = clearValue || false;
|
||||
$('#transponderConfiguration').html('');
|
||||
$('#transponderConfiguration').hide();
|
||||
$('#transponderHelpBox').hide();
|
||||
|
||||
// gather data that doesn't have automatic change event bound
|
||||
|
||||
var dataString = $('input[name="data"]').val();
|
||||
var expectedLength = TRANSPONDER.data.length;
|
||||
var hexRegExp = new RegExp('[0-9a-fA-F]{' + (expectedLength * 2) + '}', 'gi');
|
||||
if (!dataString.match(hexRegExp)) {
|
||||
GUI.log(chrome.i18n.getMessage('transponderDataInvalid'));
|
||||
if(!transponderProvider){
|
||||
return;
|
||||
}
|
||||
|
||||
var innerBlock = $('<div>').addClass('spacer_box');
|
||||
var dataBlock = $('<div>').addClass('text');
|
||||
var textspacer = $('<div>').addClass('textspacer');
|
||||
var tileBox = $('<div>').addClass('gui_box_titlebar');
|
||||
var title = $('<div>').addClass('spacer_box_title').html(chrome.i18n.getMessage("transponderData" + transponderProvider.id));
|
||||
var dataHelp = $('<span>').addClass('dataHelp').html(chrome.i18n.getMessage("transponderDataHelp" + transponderProvider.id));
|
||||
|
||||
|
||||
if(chrome.i18n.getMessage("transponderHelp" + transponderProvider.id).length){
|
||||
$('#transponderHelp').html(chrome.i18n.getMessage("transponderHelp" + transponderProvider.id));
|
||||
$('#transponderHelpBox').show();
|
||||
}
|
||||
|
||||
var transponderConfiguration = transponderConfigurations[transponderProvider.id];
|
||||
var dataInput = null;
|
||||
|
||||
switch (transponderConfiguration.dataType) {
|
||||
|
||||
case dataTypes.TEXT:
|
||||
dataInput = $('<input>').attr('type', 'text').attr('maxlength', parseInt(transponderProvider.dataLength) * 2);
|
||||
if(!clearValue){
|
||||
dataInput.val(data);
|
||||
}else{
|
||||
dataInput.val('');
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case dataTypes.LIST:
|
||||
dataInput = $('<select>');
|
||||
for (var dataOptionsKey in transponderConfiguration.dataOptions) {
|
||||
var dataOptions = transponderConfiguration.dataOptions[dataOptionsKey];
|
||||
dataInput.append($('<option>').val(dataOptions).html(dataOptionsKey));
|
||||
}
|
||||
|
||||
if(dataInput.find("option[value='"+data+"']").length > 0 && !clearValue){
|
||||
dataInput.val(data);
|
||||
}else{
|
||||
dataInput.val('');
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
var changedInputValue = function(){
|
||||
var dataString = $(this).val();
|
||||
var hexRegExp = new RegExp('[0-9a-fA-F]{' + (transponderProvider.dataLength * 2) + '}', 'gi');
|
||||
|
||||
if (!dataString.match(hexRegExp)) {
|
||||
TRANSPONDER.data = [];
|
||||
}else{
|
||||
TRANSPONDER.data = hexToBytes(dataString);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
dataInput.change(changedInputValue).keyup(changedInputValue);
|
||||
|
||||
tileBox.append(title);
|
||||
|
||||
textspacer.append(dataInput);
|
||||
dataBlock.append(dataHelp);
|
||||
dataBlock.append(textspacer);
|
||||
innerBlock.append(dataBlock);
|
||||
$('#transponderConfiguration').append(tileBox).append(innerBlock).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* this function is called from select click scope
|
||||
*/
|
||||
function toggleTransponderType(){
|
||||
|
||||
TRANSPONDER.provider = $(this).val();
|
||||
var defaultProvider = $(this).attr('data-defaultValue');
|
||||
if(defaultProvider == $(this).val())
|
||||
{
|
||||
$('.save_reboot').hide();
|
||||
$('.save_no_reboot').show();
|
||||
}else{
|
||||
$('.save_no_reboot').hide();
|
||||
$('.save_reboot').show();
|
||||
}
|
||||
|
||||
var clearValue = true
|
||||
buildDataBlockForTransponderProviders(TRANSPONDER.providers.find(function(provider){
|
||||
return provider.id == TRANSPONDER.provider;
|
||||
}), bytesToHex(TRANSPONDER.data), clearValue);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// send data to FC
|
||||
//
|
||||
function save_transponder_config() {
|
||||
MSP.send_message(MSPCodes.MSP_TRANSPONDER_CONFIG, false, false, load_html);
|
||||
|
||||
function process_html() {
|
||||
|
||||
$(".tab-transponder").toggleClass("transponder-supported", TABS.transponder.available && TRANSPONDER.supported);
|
||||
|
||||
|
||||
localize();
|
||||
|
||||
if (TABS.transponder.available && TRANSPONDER.providers.length > 0) {
|
||||
|
||||
fillByTransponderProviders(TRANSPONDER.providers, TRANSPONDER.provider, toggleTransponderType);
|
||||
buildDataBlockForTransponderProviders(TRANSPONDER.providers.find(function(provider){
|
||||
return provider.id == TRANSPONDER.provider;
|
||||
}), bytesToHex(TRANSPONDER.data));
|
||||
|
||||
|
||||
$('a.save').click(function () {
|
||||
var _this = this;
|
||||
|
||||
function save_transponder_data() {
|
||||
MSP.send_message(MSPCodes.MSP_SET_TRANSPONDER_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_TRANSPONDER_CONFIG), false, save_to_eeprom);
|
||||
}
|
||||
|
||||
function save_to_eeprom() {
|
||||
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, function () {
|
||||
MSP.send_message(MSPCodes.MSP_EEPROM_WRITE, false, false, function(){
|
||||
GUI.log(chrome.i18n.getMessage('transponderEepromSaved'));
|
||||
if($(_this).hasClass('reboot')){
|
||||
GUI.tab_switch_cleanup(function () {
|
||||
MSP.send_message(MSPCodes.MSP_SET_REBOOT, false, false, reinitialize);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
save_transponder_config();
|
||||
if(TRANSPONDER.data.length != TRANSPONDER.providers.find(function(provider){
|
||||
return provider.id == TRANSPONDER.provider;
|
||||
}).dataLength){
|
||||
GUI.log(chrome.i18n.getMessage('transponderDataInvalid'));
|
||||
}else{
|
||||
save_transponder_data();
|
||||
}
|
||||
});
|
||||
}
|
||||
// status data pulled via separate timer with static speed
|
||||
GUI.interval_add('status_pull', function status_pull() {
|
||||
MSP.send_message(MSPCodes.MSP_STATUS);
|
||||
}, 250, true);
|
||||
|
||||
function reinitialize() {
|
||||
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||
if (BOARD.find_board_definition(CONFIG.boardIdentifier).vcp) {
|
||||
$('a.connect').click();
|
||||
GUI.timeout_add('start_connection', function start_connection() {
|
||||
$('a.connect').click();
|
||||
}, 2500);
|
||||
} else {
|
||||
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
|
||||
MSP.send_message(MSPCodes.MSP_IDENT, false, false, function () {
|
||||
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
||||
TABS.configuration.initialize(false, $('#content').scrollTop());
|
||||
});
|
||||
}, 1500);
|
||||
}
|
||||
}
|
||||
|
||||
GUI.content_ready(callback);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue