1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-14 20:10:13 +03:00

Added version information to Unified Targets when they are flashed.

This commit is contained in:
mikeller 2020-03-29 04:07:03 +13:00
parent 3faab9cedc
commit 153fa2b486
7 changed files with 155 additions and 95 deletions

View file

@ -2704,7 +2704,7 @@
"message": "Release info" "message": "Release info"
}, },
"firmwareFlasherReleaseManufacturer": { "firmwareFlasherReleaseManufacturer": {
"message": "Manufacturer:" "message": "Manufacturer ID:"
}, },
"firmwareFlasherReleaseVersion": { "firmwareFlasherReleaseVersion": {
"message": "Version:" "message": "Version:"
@ -2724,8 +2724,14 @@
"firmwareFlasherReleaseFile": { "firmwareFlasherReleaseFile": {
"message": "Binary:" "message": "Binary:"
}, },
"firmwareFlasherReleaseStatusReleaseCandidate": { "firmwareFlasherUnifiedTargetName": {
"message": "<span class=\"message-negative\">IMPORTANT: This firmware release is currently marked as a release candidate. Please report any issues immediately.</span>" "message": "Unified Target:"
},
"firmwareFlasherUnifiedTargetFileUrl": {
"message": "Show config."
},
"firmwareFlasherUnifiedTargetDate": {
"message": "Date:"
}, },
"firmwareFlasherReleaseFileUrl": { "firmwareFlasherReleaseFileUrl": {
"message": "Download manually." "message": "Download manually."

27
src/js/GitHubApi.js Normal file
View file

@ -0,0 +1,27 @@
'use strict';
const GitHubApi = function ()
{
const self = this;
self.GITHUB_API_URL = "https://api.github.com/";
};
GitHubApi.prototype.getFileLastCommitInfo = function (project, branch, filename, callback)
{
const self = this;
$.getJSON(`${self.GITHUB_API_URL}repos/${encodeURI(project)}/commits?sha=${encodeURIComponent(branch)}&path=${encodeURIComponent(filename)}`, function (commits) {
const result = {};
try {
result.commitHash = commits[0].sha.substring(0, 8);
result.date = commits[0].commit.author.date;
} catch (exception) {
console.log(`Error while parsing commit: ${exception}`);
}
console.log(`Found commit info for file ${filename}:`, result);
callback(result);
});
};

View file

@ -7,8 +7,6 @@ var ReleaseChecker = function (releaseName, releaseUrl) {
self._releaseDataTag = `${self._releaseName}ReleaseData`; self._releaseDataTag = `${self._releaseName}ReleaseData`;
self._releaseLastUpdateTag = `${self._releaseName}ReleaseLastUpdate` self._releaseLastUpdateTag = `${self._releaseName}ReleaseLastUpdate`
self._releaseUrl = releaseUrl; self._releaseUrl = releaseUrl;
} }
ReleaseChecker.prototype.loadReleaseData = function (processFunction) { ReleaseChecker.prototype.loadReleaseData = function (processFunction) {

View file

@ -4,14 +4,13 @@ TABS.firmware_flasher = {
releases: null, releases: null,
releaseChecker: new ReleaseChecker('firmware', 'https://api.github.com/repos/betaflight/betaflight/releases'), releaseChecker: new ReleaseChecker('firmware', 'https://api.github.com/repos/betaflight/betaflight/releases'),
jenkinsLoader: new JenkinsLoader('https://ci.betaflight.tech'), jenkinsLoader: new JenkinsLoader('https://ci.betaflight.tech'),
gitHubApi: new GitHubApi(),
localFirmwareLoaded: false, localFirmwareLoaded: false,
selectedBoard: undefined, selectedBoard: undefined,
intel_hex: undefined, // standard intel hex in string format intel_hex: undefined, // standard intel hex in string format
parsed_hex: undefined, // parsed raw hex in array format parsed_hex: undefined, // parsed raw hex in array format
unifiedTargetConfig: undefined, // the Unified Target configuration to be spliced into the configuration unifiedTarget: {}, // the Unified Target configuration to be spliced into the configuration
unifiedTargetConfigName: undefined,
isConfigLocal: false, // Set to true if the user loads one locally isConfigLocal: false, // Set to true if the user loads one locally
remoteUnifiedTargetConfig: undefined, // Unified target configuration loaded from the menu, used when throwing out a local config
developmentFirmwareLoaded: false, // Is the firmware to be flashed from the development branch? developmentFirmwareLoaded: false, // Is the firmware to be flashed from the development branch?
}; };
@ -64,30 +63,35 @@ TABS.firmware_flasher.initialize = function (callback) {
self.enableFlashing(true); self.enableFlashing(true);
let targetName = TABS.firmware_flasher.selectedBoard; if (self.unifiedTarget.manufacturerId) {
const TARGET_REGEXP = /^([^+-]+)(?:\+(.{1,4})|-legacy)?$/; $('div.release_info #manufacturer').text(self.unifiedTarget.manufacturerId);
let targetParts = targetName.match(TARGET_REGEXP);
if (targetParts) {
targetName = targetParts[1];
if (targetParts[2]) {
$('div.release_info #manufacturerInfo').show(); $('div.release_info #manufacturerInfo').show();
$('div.release_info #manufacturer').text(targetParts[2]);
} else { } else {
$('div.release_info #manufacturerInfo').hide(); $('div.release_info #manufacturerInfo').hide();
} }
} $('div.release_info .target').text(TABS.firmware_flasher.selectedBoard);
$('div.release_info .target').text(targetName);
$('div.release_info .name').text(summary.version).prop('href', summary.releaseUrl); $('div.release_info .name').text(summary.version).prop('href', summary.releaseUrl);
$('div.release_info .date').text(summary.date); $('div.release_info .date').text(summary.date);
$('div.release_info .file').text(summary.file).prop('href', summary.url); $('div.release_info .file').text(summary.file).prop('href', summary.url);
if (Object.keys(self.unifiedTarget).length > 0) {
$('div.release_info #unifiedTargetInfo').show();
$('div.release_info #unifiedTargetFile').text(self.unifiedTarget.fileName).prop('href', self.unifiedTarget.fileUrl);
$('div.release_info #unifiedTargetDate').text(self.unifiedTarget.date);
} else {
$('div.release_info #unifiedTargetInfo').hide();
}
var formattedNotes = summary.notes.replace(/#(\d+)/g, '[#$1](https://github.com/betaflight/betaflight/pull/$1)'); var formattedNotes = summary.notes.replace(/#(\d+)/g, '[#$1](https://github.com/betaflight/betaflight/pull/$1)');
formattedNotes = marked(formattedNotes); formattedNotes = marked(formattedNotes);
$('div.release_info .notes').html(formattedNotes); $('div.release_info .notes').html(formattedNotes);
$('div.release_info .notes').find('a').each(function() { $('div.release_info .notes').find('a').each(function() {
$(this).attr('target', '_blank'); $(this).attr('target', '_blank');
}); });
$('div.release_info').slideDown(); $('div.release_info').slideDown();
$('.tab-firmware_flasher .content_wrapper').animate({ scrollTop: $('div.release_info').position().top }, 1000);
} }
function process_hex(data, summary) { function process_hex(data, summary) {
@ -102,7 +106,7 @@ TABS.firmware_flasher.initialize = function (callback) {
if (!FirmwareCache.has(summary)) { if (!FirmwareCache.has(summary)) {
FirmwareCache.put(summary, self.intel_hex); FirmwareCache.put(summary, self.intel_hex);
} }
show_loaded_hex(summary) show_loaded_hex(summary);
} else { } else {
self.flashingMessage(i18n.getMessage('firmwareFlasherHexCorrupted'), self.FLASH_MESSAGE_TYPES.INVALID); self.flashingMessage(i18n.getMessage('firmwareFlasherHexCorrupted'), self.FLASH_MESSAGE_TYPES.INVALID);
@ -240,7 +244,7 @@ TABS.firmware_flasher.initialize = function (callback) {
const storageTag = 'unifiedSourceCache'; const storageTag = 'unifiedSourceCache';
chrome.storage.local.get(storageTag, function (result) { chrome.storage.local.get(storageTag, function (result) {
let storageObj = result[storageTag]; let storageObj = result[storageTag];
if(!storageObj || !storageObj.lastUpdate || checkTime - storageObj.lastUpdate > expirationPeriod ) { if(!storageObj || !storageObj.lastUpdate || checkTime - storageObj.lastUpdate > expirationPeriod) {
console.log('go get', unifiedSource); console.log('go get', unifiedSource);
$.get(unifiedSource, function(data, textStatus, jqXHR) { $.get(unifiedSource, function(data, textStatus, jqXHR) {
// Cache the information for later use. // Cache the information for later use.
@ -290,7 +294,7 @@ TABS.firmware_flasher.initialize = function (callback) {
const manufacturerId = targetParts[1]; const manufacturerId = targetParts[1];
items[targetName] = { }; items[targetName] = { };
unifiedConfigs[targetName] = (unifiedConfigs[targetName] || {}); unifiedConfigs[targetName] = (unifiedConfigs[targetName] || {});
unifiedConfigs[targetName][manufacturerId] = target.download_url; unifiedConfigs[targetName][manufacturerId] = target;
}); });
var boards_e = $('select[name="board"]'); var boards_e = $('select[name="board"]');
var versions_e = $('select[name="firmware_version"]'); var versions_e = $('select[name="firmware_version"]');
@ -502,29 +506,23 @@ TABS.firmware_flasher.initialize = function (callback) {
return bareBoard; return bareBoard;
} }
function setUnifiedConfig(target, configText, bareBoard) { function setUnifiedConfig(target, bareBoard, targetConfig, manufacturerId, fileName, fileUrl, date) {
// a target might request a firmware with the same name, remove configuration in this case. // a target might request a firmware with the same name, remove configuration in this case.
if (bareBoard == target) { if (bareBoard == target) {
if (!self.isConfigLocal) { self.unifiedTarget = {};
self.unifiedTargetConfig = undefined;
self.unifiedTargetConfigName = undefined;
self.remoteUnifiedTargetConfig = undefined;
} else { } else {
self.remoteUnifiedTargetConfig = undefined; self.unifiedTarget.config = targetConfig;
} self.unifiedTarget.manufacturerId = manufacturerId;
} else { self.unifiedTarget.fileName = fileName;
self.unifiedTargetConfig = configText; self.unifiedTarget.fileUrl = fileUrl;
self.unifiedTargetConfigName = `${target}.config`; self.unifiedTarget.date = date;
self.isConfigLocal = false; self.isConfigLocal = false;
self.remoteUnifiedTargetConfig = configText;
} }
} }
function clearBufferedFirmware() { function clearBufferedFirmware() {
self.isConfigLocal = false; self.isConfigLocal = false;
self.unifiedTargetConfig = undefined; self.unifiedTarget = {};
self.unifiedTargetConfigName = undefined;
self.remoteUnifiedTargetConfig = undefined;
self.intel_hex = undefined; self.intel_hex = undefined;
self.parsed_hex = undefined; self.parsed_hex = undefined;
self.localFirmwareLoaded = false; self.localFirmwareLoaded = false;
@ -540,8 +538,7 @@ TABS.firmware_flasher.initialize = function (callback) {
if (self.isConfigLocal) { if (self.isConfigLocal) {
console.log('Board changed, unloading local config'); console.log('Board changed, unloading local config');
self.isConfigLocal = false; self.isConfigLocal = false;
self.unifiedTargetConfig = undefined; self.unifiedTarget = {};
self.unifiedTargetConfigName = undefined;
} }
} }
ConfigStorage.set({'selected_board': target}); ConfigStorage.set({'selected_board': target});
@ -589,9 +586,9 @@ TABS.firmware_flasher.initialize = function (callback) {
var checkTime = Math.floor(Date.now() / 1000); // Lets deal in seconds. var checkTime = Math.floor(Date.now() / 1000); // Lets deal in seconds.
chrome.storage.local.get(storageTag, function (result) { chrome.storage.local.get(storageTag, function (result) {
let storageObj = result[storageTag]; let storageObj = result[storageTag];
const unifiedConfigBoard = TABS.firmware_flasher.unifiedConfigs[target]; const unifiedConfigList = TABS.firmware_flasher.unifiedConfigs[target];
const duplicateName = Object.keys(unifiedConfigBoard).length > 1; const manufacturerIds = Object.keys(unifiedConfigList);
const manufacturerIds = Object.keys(unifiedConfigBoard); const duplicateName = manufacturerIds.length > 1;
const processManufacturer = function(index) { const processManufacturer = function(index) {
const processNext = function () { const processNext = function () {
@ -605,41 +602,53 @@ TABS.firmware_flasher.initialize = function (callback) {
const manufacturerId = manufacturerIds[index]; const manufacturerId = manufacturerIds[index];
const targetId = `${target}+${manufacturerId}`; const targetId = `${target}+${manufacturerId}`;
// Check to see if the cached configuration is the one we want. // Check to see if the cached configuration is the one we want.
if (!storageObj || !storageObj.target || storageObj.target !== targetId if (!storageObj || !storageObj.targetId || storageObj.targetId !== targetId
|| !storageObj.lastUpdate || checkTime - storageObj.lastUpdate > expirationPeriod) { || !storageObj.lastUpdate || checkTime - storageObj.lastUpdate > expirationPeriod
|| !storageObj.unifiedTarget) {
const unifiedConfig = unifiedConfigList[manufacturerId];
// Have to go and try and get the unified config, and then do stuff // Have to go and try and get the unified config, and then do stuff
$.get(unifiedConfigBoard[manufacturerId], function(response) { $.get(unifiedConfig.download_url, function(targetConfig) {
console.log('got unified config'); console.log('got unified config');
const bareBoard = grabBuildNameFromConfig(targetConfig);
TABS.firmware_flasher.bareBoard = bareBoard;
self.gitHubApi.getFileLastCommitInfo('betaflight/unified-targets', 'master', unifiedConfig.path, function (commitInfo) {
targetConfig = self.injectTargetInfo(targetConfig, target, manufacturerId, commitInfo);
setUnifiedConfig(target, bareBoard, targetConfig, manufacturerId, unifiedConfig.name, unifiedConfig.download_url, commitInfo.date);
// cache it for later // cache it for later
let tempObj = {};
tempObj['data'] = response;
tempObj['target'] = targetId;
tempObj['lastUpdate'] = checkTime;
let newStorageObj = {}; let newStorageObj = {};
newStorageObj[storageTag] = tempObj; newStorageObj[storageTag] = {
unifiedTarget: self.unifiedTarget,
targetId: targetId,
lastUpdate: checkTime,
};
chrome.storage.local.set(newStorageObj); chrome.storage.local.set(newStorageObj);
const bareBoard = grabBuildNameFromConfig(response);
TABS.firmware_flasher.bareBoard = bareBoard;
setUnifiedConfig(target, response, bareBoard);
populateBuilds(builds, target, manufacturerId, duplicateName, TABS.firmware_flasher.releases[bareBoard], processNext); populateBuilds(builds, target, manufacturerId, duplicateName, TABS.firmware_flasher.releases[bareBoard], processNext);
});
}).fail(xhr => { }).fail(xhr => {
//TODO error, populate nothing? //TODO error, populate nothing?
self.unifiedTargetConfig = undefined; self.unifiedTarget = {};
self.unifiedTargetConfigName = undefined;
self.isConfigLocal = false; self.isConfigLocal = false;
self.remoteUnifiedTargetConfig = undefined; const baseFileName = unifiedConfig.download_url;
const baseFileName = unifiedConfigBoard[manufacturerId].reverse()[0]; GUI.log(i18n.getMessage('firmwareFlasherFailedToLoadUnifiedConfig', { remote_file: baseFileName }));
GUI.log(i18n.getMessage('firmwareFlasherFailedToLoadUnifiedConfig',
{remote_file: baseFileName}));
}); });
} else { } else {
console.log('We have the config cached for', targetId); console.log('We have the config cached for', targetId);
var data = storageObj.data; const unifiedTarget = storageObj.unifiedTarget;
const bareBoard = grabBuildNameFromConfig(data); const bareBoard = grabBuildNameFromConfig(unifiedTarget.config);
TABS.firmware_flasher.bareBoard = bareBoard; TABS.firmware_flasher.bareBoard = bareBoard;
setUnifiedConfig(target, data, bareBoard);
if (target === bareBoard) {
self.unifiedTarget = {};
} else {
self.unifiedTarget = unifiedTarget;
}
populateBuilds(builds, target, manufacturerId, duplicateName, TABS.firmware_flasher.releases[bareBoard], processNext); populateBuilds(builds, target, manufacturerId, duplicateName, TABS.firmware_flasher.releases[bareBoard], processNext);
} }
}; };
@ -647,7 +656,7 @@ TABS.firmware_flasher.initialize = function (callback) {
processManufacturer(0); processManufacturer(0);
}); });
} else { } else {
setUnifiedConfig(target, null, target); self.unifiedTarget = {};
finishPopulatingBuilds(); finishPopulatingBuilds();
} }
} }
@ -719,7 +728,7 @@ TABS.firmware_flasher.initialize = function (callback) {
baud = parseInt($('#flash_manual_baud_rate').val()); baud = parseInt($('#flash_manual_baud_rate').val());
} }
analytics.sendEvent(analytics.EVENT_CATEGORIES.FLASHING, 'Flashing', self.unifiedTargetConfigName || null); analytics.sendEvent(analytics.EVENT_CATEGORIES.FLASHING, 'Flashing', self.unifiedTarget.fileName || null);
STM32.connect(port, baud, firmware, options); STM32.connect(port, baud, firmware, options);
} else { } else {
@ -727,7 +736,7 @@ TABS.firmware_flasher.initialize = function (callback) {
GUI.log(i18n.getMessage('firmwareFlasherNoValidPort')); GUI.log(i18n.getMessage('firmwareFlasherNoValidPort'));
} }
} else { } else {
analytics.sendEvent(analytics.EVENT_CATEGORIES.FLASHING, 'Flashing', self.unifiedTargetConfigName || null); analytics.sendEvent(analytics.EVENT_CATEGORIES.FLASHING, 'Flashing', self.unifiedTarget.fileName || null);
STM32DFU.connect(usbDevices, firmware, options); STM32DFU.connect(usbDevices, firmware, options);
} }
@ -867,8 +876,8 @@ TABS.firmware_flasher.initialize = function (callback) {
} else { } else {
clearBufferedFirmware(); clearBufferedFirmware();
try { try {
self.unifiedTargetConfig = cleanUnifiedConfigFile(e.target.result); self.unifiedTarget.config = cleanUnifiedConfigFile(e.target.result);
self.unifiedTargetConfigName = file.name; self.unifiedTarget.fileName = file.name;
self.isConfigLocal = true; self.isConfigLocal = true;
flashingMessageLocal(); flashingMessageLocal();
} catch(err) { } catch(err) {
@ -1058,16 +1067,15 @@ TABS.firmware_flasher.initialize = function (callback) {
if (!GUI.connect_lock) { // button disabled while flashing is in progress if (!GUI.connect_lock) { // button disabled while flashing is in progress
if (self.parsed_hex) { if (self.parsed_hex) {
try { try {
if (self.unifiedTargetConfig && !self.parsed_hex.configInserted) { if (self.unifiedTarget.config && !self.parsed_hex.configInserted) {
var configInserter = new ConfigInserter(); var configInserter = new ConfigInserter();
if (configInserter.insertConfig(self.parsed_hex, self.unifiedTargetConfig)) { if (configInserter.insertConfig(self.parsed_hex, self.unifiedTarget.config)) {
self.parsed_hex.configInserted = true; self.parsed_hex.configInserted = true;
} else { } else {
console.log('Firmware does not support custom defaults.'); console.log('Firmware does not support custom defaults.');
self.unifiedTargetConfig = undefined; self.unifiedTarget = {};
self.unifiedTargetConfigName = undefined;
} }
} }
@ -1247,3 +1255,15 @@ TABS.firmware_flasher.flashProgress = function(value) {
return this; return this;
}; };
TABS.firmware_flasher.injectTargetInfo = function (targetConfig, targetName, manufacturerId, commitInfo) {
const targetInfoLineRegex = /^# config: manufacturer_id: .*, board_name: .*, version: .*$, date: .*\n/gm;
const config = targetConfig.replace(targetInfoLineRegex, '');
const targetInfo = `# config: manufacturer_id: ${manufacturerId}, board_name: ${targetName}, version: ${commitInfo.commitHash}, date: ${commitInfo.date}`;
const lines = config.split('\n');
lines.splice(1, 0, targetInfo);
return lines.join('\n');
};

View file

@ -1970,11 +1970,11 @@ OSD.msp = {
} }
for (var i = 0; i < warningCount; i++) { for (var i = 0; i < warningCount; i++) {
const enabled = (warningFlags & (1 << i)) !== 0;
// Known warning field // Known warning field
if (i < OSD.constants.WARNINGS.length) { if (i < OSD.constants.WARNINGS.length) {
d.warnings.push($.extend(OSD.constants.WARNINGS[i], { d.warnings.push($.extend(OSD.constants.WARNINGS[i], { enabled: enabled }));
enabled: (warningFlags & (1 << i)) !== 0,
}));
// Push Unknown Warning field // Push Unknown Warning field
} else { } else {
@ -1983,7 +1983,7 @@ OSD.msp = {
name: 'UNKNOWN', name: 'UNKNOWN',
text: ['osdWarningTextUnknown', warningNumber], text: ['osdWarningTextUnknown', warningNumber],
desc: 'osdWarningUnknown', desc: 'osdWarningUnknown',
enabled: (warningFlags & (1 << i)) !== 0, enabled: enabled,
}); });
} }
@ -2168,8 +2168,6 @@ TABS.osd = {
}; };
TABS.osd.initialize = function (callback) { TABS.osd.initialize = function (callback) {
var self = this;
if (GUI.active_tab != 'osd') { if (GUI.active_tab != 'osd') {
GUI.active_tab = 'osd'; GUI.active_tab = 'osd';
} }

View file

@ -93,6 +93,7 @@
<script type="text/javascript" src="./js/release_checker.js"></script> <script type="text/javascript" src="./js/release_checker.js"></script>
<script type="text/javascript" src="./js/jenkins_loader.js"></script> <script type="text/javascript" src="./js/jenkins_loader.js"></script>
<script type="text/javascript" src="./js/Analytics.js"></script> <script type="text/javascript" src="./js/Analytics.js"></script>
<script type="text/javascript" src="./js/GitHubApi.js"></script>
<script type="text/javascript" src="./js/main.js"></script> <script type="text/javascript" src="./js/main.js"></script>
<script type="text/javascript" src="./js/Clipboard.js"></script> <script type="text/javascript" src="./js/Clipboard.js"></script>
<script type="text/javascript" src="./js/tabs/static_tab.js"></script> <script type="text/javascript" src="./js/tabs/static_tab.js"></script>

View file

@ -88,6 +88,7 @@
i18n="firmwareFlasherReleaseSummaryHead"></div> i18n="firmwareFlasherReleaseSummaryHead"></div>
</div> </div>
<div class="spacer" style="margin-bottom: 10px;"> <div class="spacer" style="margin-bottom: 10px;">
<div class="margin-bottom">
<strong i18n="firmwareFlasherReleaseTarget"></strong> <strong i18n="firmwareFlasherReleaseTarget"></strong>
<span class="target"></span> <span class="target"></span>
<br /> <br />
@ -105,6 +106,15 @@
<strong i18n="firmwareFlasherReleaseDate"></strong> <strong i18n="firmwareFlasherReleaseDate"></strong>
<span class="date"></span> <span class="date"></span>
<br /> <br />
</div>
<div class="margin-bottom" id="unifiedTargetInfo">
<strong i18n="firmwareFlasherUnifiedTargetName"></strong>
<a i18n_title="firmwareFlasherUnifiedTargetFileUrl" id="unifiedTargetFile" href="#" target="_blank"></a>
<br />
<strong i18n="firmwareFlasherUnifiedTargetDate"></strong>
<span id="unifiedTargetDate"></span>
<br />
</div>
<strong i18n="firmwareFlasherReleaseNotes"></strong> <strong i18n="firmwareFlasherReleaseNotes"></strong>
<div class=notes></div> <div class=notes></div>
</div> </div>