From 5344781de2e9f3800e3a76dbb50b768b0cea3edd Mon Sep 17 00:00:00 2001 From: Mark Haslinghuis Date: Mon, 10 Apr 2023 01:42:03 +0200 Subject: [PATCH] Fix battery status and optimize and fix status pull (#3397) * Fix status * Remove duplicate status requests * Add clearInterval * Cleanup * Remove more duplicate status polling --- src/js/fc.js | 6 +-- src/js/gui.js | 2 +- src/js/msp/MSPHelper.js | 2 +- src/js/serial_backend.js | 89 +++++++++++++++++++------------------- src/js/tabs/adjustments.js | 5 --- src/js/tabs/failsafe.js | 5 --- src/js/tabs/gps.js | 7 --- src/js/tabs/motors.js | 8 +--- src/js/tabs/pid_tuning.js | 8 ++-- src/js/tabs/receiver.js | 5 --- src/js/tabs/setup.js | 47 +++++++++----------- 11 files changed, 75 insertions(+), 109 deletions(-) diff --git a/src/js/fc.js b/src/js/fc.js index fc19d195..28e05bb6 100644 --- a/src/js/fc.js +++ b/src/js/fc.js @@ -55,7 +55,7 @@ const INITIAL_ANALOG = { mAhdrawn: 0, rssi: 0, amperage: 0, - last_received_timestamp: Date.now(), // FIXME this code lies, it's never been received at this point + last_received_timestamp: 0, }; const INITIAL_BATTERY_CONFIG = { @@ -74,7 +74,7 @@ const FC = { ADJUSTMENT_RANGES: null, ADVANCED_TUNING: null, ADVANCED_TUNING_ACTIVE: null, - ANALOG: {...INITIAL_CONFIG}, + ANALOG: {...INITIAL_ANALOG}, ARMING_CONFIG: null, AUX_CONFIG: null, AUX_CONFIG_IDS: null, @@ -170,7 +170,7 @@ const FC = { // Using `Object.assign` instead of reassigning to // trigger the updates on the Vue side Object.assign(this.CONFIG, INITIAL_CONFIG); - Object.assign(this.ANALOG, INITIAL_CONFIG); + Object.assign(this.ANALOG, INITIAL_ANALOG); Object.assign(this.BATTERY_CONFIG, INITIAL_BATTERY_CONFIG); this.BF_CONFIG = { diff --git a/src/js/gui.js b/src/js/gui.js index 49b03722..3c085fb8 100644 --- a/src/js/gui.js +++ b/src/js/gui.js @@ -219,7 +219,7 @@ class GuiControl { } }, timeout); - this.timeout_array.push(data); // push to primary timeout array + self.timeout_array.push(data); // push to primary timeout array return data; } diff --git a/src/js/msp/MSPHelper.js b/src/js/msp/MSPHelper.js index 63669de2..77109063 100644 --- a/src/js/msp/MSPHelper.js +++ b/src/js/msp/MSPHelper.js @@ -319,7 +319,7 @@ MspHelper.prototype.process_data = function(dataHandler) { FC.ANALOG.rssi = data.readU16(); // 0-1023 FC.ANALOG.amperage = data.read16() / 100; // A FC.ANALOG.voltage = data.readU16() / 100; - FC.ANALOG.last_received_timestamp = Date.now(); + FC.ANALOG.last_received_timestamp = performance.now(); break; case MSPCodes.MSP_VOLTAGE_METERS: FC.VOLTAGE_METERS = []; diff --git a/src/js/serial_backend.js b/src/js/serial_backend.js index 9b622e28..304c937b 100644 --- a/src/js/serial_backend.js +++ b/src/js/serial_backend.js @@ -28,6 +28,7 @@ import BuildApi from "./BuildApi"; let mspHelper; let connectionTimestamp; let clicks = false; +let liveDataRefreshTimerId = false; export function initializeSerialBackend() { GUI.updateManualPortVisibility = function() { @@ -119,7 +120,7 @@ export function initializeSerialBackend() { mspHelper.setArmingEnabled(true, false, onFinishCallback); } } - } + } }); $('div.open_firmware_flasher a.flash').click(function () { @@ -604,9 +605,6 @@ function onConnect() { MSP.send_message(MSPCodes.MSP_FEATURE_CONFIG, false, false); MSP.send_message(MSPCodes.MSP_BATTERY_CONFIG, false, false); - - getStatus(); - MSP.send_message(MSPCodes.MSP_DATAFLASH_SUMMARY, false, false); if (FC.CONFIG.boardType === 0 || FC.CONFIG.boardType === 2) { @@ -647,6 +645,8 @@ function onClosed(result) { const battery = $('#quad-status_wrapper'); battery.hide(); + clearLiveDataRefreshTimer(); + MSP.clearListeners(); CONFIGURATOR.connectionValid = false; @@ -668,27 +668,15 @@ export function read_serial(info) { } } -function startLiveDataRefreshTimer() { - // live data refresh - GUI.timeout_add('data_refresh', update_live_status, 100); -} - -async function getStatus() { - return MSP.promise(MSPCodes.MSP_STATUS_EX); -} - async function update_live_status() { const statuswrapper = $('#quad-status_wrapper'); if (GUI.active_tab !== 'cli' && GUI.active_tab !== 'presets') { - await MSP.promise(MSPCodes.MSP_BOXNAMES); - await getStatus(); - if (have_sensor(FC.CONFIG.activeSensors, 'gps')) { - await MSP.promise(MSPCodes.MSP_RAW_GPS); - } await MSP.promise(MSPCodes.MSP_ANALOG); + await MSP.promise(MSPCodes.MSP_BOXNAMES); + await MSP.promise(MSPCodes.MSP_STATUS_EX); - const active = ((Date.now() - FC.ANALOG.last_received_timestamp) < 300); + const active = (performance.now() - FC.ANALOG.last_received_timestamp) < 300; for (let i = 0; i < FC.AUX_CONFIG.length; i++) { if (FC.AUX_CONFIG[i] === 'ARM') { @@ -699,31 +687,33 @@ async function update_live_status() { } } - if (FC.ANALOG != undefined) { - let nbCells = Math.floor(FC.ANALOG.voltage / FC.BATTERY_CONFIG.vbatmaxcellvoltage) + 1; + let nbCells = Math.floor(FC.ANALOG.voltage / FC.BATTERY_CONFIG.vbatmaxcellvoltage) + 1; - if (FC.ANALOG.voltage == 0) { - nbCells = 1; + if (FC.ANALOG.voltage === 0) { + nbCells = 1; + } + + const min = FC.BATTERY_CONFIG.vbatmincellvoltage * nbCells; + const max = FC.BATTERY_CONFIG.vbatmaxcellvoltage * nbCells; + const warn = FC.BATTERY_CONFIG.vbatwarningcellvoltage * nbCells; + + const NO_BATTERY_VOLTAGE_MAXIMUM = 1.8; // Maybe is better to add a call to MSP_BATTERY_STATE but is not available for all versions + + if (FC.ANALOG.voltage < min && FC.ANALOG.voltage > NO_BATTERY_VOLTAGE_MAXIMUM) { + $(".battery-status").addClass('state-empty').removeClass('state-ok').removeClass('state-warning'); + $(".battery-status").css({ width: "100%" }); + } else { + $(".battery-status").css({ width: `${((FC.ANALOG.voltage - min) / (max - min) * 100)}%` }); + + if (FC.ANALOG.voltage < warn) { + $(".battery-status").addClass('state-warning').removeClass('state-empty').removeClass('state-ok'); + } else { + $(".battery-status").addClass('state-ok').removeClass('state-warning').removeClass('state-empty'); } + } - const min = FC.BATTERY_CONFIG.vbatmincellvoltage * nbCells; - const max = FC.BATTERY_CONFIG.vbatmaxcellvoltage * nbCells; - const warn = FC.BATTERY_CONFIG.vbatwarningcellvoltage * nbCells; - - const NO_BATTERY_VOLTAGE_MAXIMUM = 1.8; // Maybe is better to add a call to MSP_BATTERY_STATE but is not available for all versions - - if (FC.ANALOG.voltage < min && FC.ANALOG.voltage > NO_BATTERY_VOLTAGE_MAXIMUM) { - $(".battery-status").addClass('state-empty').removeClass('state-ok').removeClass('state-warning'); - $(".battery-status").css({ width: "100%" }); - } else { - $(".battery-status").css({ width: `${((FC.ANALOG.voltage - min) / (max - min) * 100)}%` }); - - if (FC.ANALOG.voltage < warn) { - $(".battery-status").addClass('state-warning').removeClass('state-empty').removeClass('state-ok'); - } else { - $(".battery-status").addClass('state-ok').removeClass('state-warning').removeClass('state-empty'); - } - } + if (have_sensor(FC.CONFIG.activeSensors, 'gps')) { + await MSP.promise(MSPCodes.MSP_RAW_GPS); } sensor_status(FC.CONFIG.activeSensors, FC.GPS_DATA.fix); @@ -731,11 +721,22 @@ async function update_live_status() { $(".linkicon").toggleClass('active', active); statuswrapper.show(); - GUI.timeout_remove('data_refresh'); - startLiveDataRefreshTimer(); } } +function clearLiveDataRefreshTimer() { + if (liveDataRefreshTimerId) { + clearInterval(liveDataRefreshTimerId); + liveDataRefreshTimerId = false; + } +} + +function startLiveDataRefreshTimer() { + // live data refresh + clearLiveDataRefreshTimer(); + liveDataRefreshTimerId = setInterval(update_live_status, 250); +} + export function reinitializeConnection(callback) { // Close connection gracefully if it still exists. @@ -758,8 +759,8 @@ export function reinitializeConnection(callback) { if (connectionTimestamp !== previousTimeStamp && CONFIGURATOR.connectionValid) { console.log(`Serial connection available after ${attempts / 10} seconds`); clearInterval(reconnect); - getStatus(); gui_log(i18n.getMessage('deviceReady')); + if (callback === typeof('function')) { callback(); } diff --git a/src/js/tabs/adjustments.js b/src/js/tabs/adjustments.js index eb577c05..5de1e01d 100644 --- a/src/js/tabs/adjustments.js +++ b/src/js/tabs/adjustments.js @@ -281,11 +281,6 @@ adjustments.initialize = function (callback) { // enable data pulling GUI.interval_add('aux_data_pull', get_rc_data, 50); - // status data pulled via separate timer with static speed - GUI.interval_add('status_pull', function () { - MSP.send_message(MSPCodes.MSP_STATUS); - }, 250, true); - GUI.content_ready(callback); } }; diff --git a/src/js/tabs/failsafe.js b/src/js/tabs/failsafe.js index b0ba835b..57c8d59f 100644 --- a/src/js/tabs/failsafe.js +++ b/src/js/tabs/failsafe.js @@ -385,11 +385,6 @@ failsafe.initialize = function (callback) { // translate to user-selected language i18n.localizePage(); - // 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); - GUI.content_ready(callback); } }; diff --git a/src/js/tabs/gps.js b/src/js/tabs/gps.js index 51bf2431..0209cc3e 100644 --- a/src/js/tabs/gps.js +++ b/src/js/tabs/gps.js @@ -19,7 +19,6 @@ gps.initialize = async function (callback) { await MSP.promise(MSPCodes.MSP_FEATURE_CONFIG); await MSP.promise(MSPCodes.MSP_GPS_CONFIG); - await MSP.promise(MSPCodes.MSP_STATUS); const hasMag = have_sensor(FC.CONFIG.activeSensors, 'mag'); @@ -308,12 +307,6 @@ gps.initialize = async function (callback) { get_raw_gps_data(); }, 75, true); - // 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); - - //check for internet connection on load if (navigator.onLine) { console.log('Online'); diff --git a/src/js/tabs/motors.js b/src/js/tabs/motors.js index 35f59eb5..532453f9 100644 --- a/src/js/tabs/motors.js +++ b/src/js/tabs/motors.js @@ -83,7 +83,6 @@ motors.initialize = async function (callback) { GUI.active_tab = 'motors'; - await MSP.promise(MSPCodes.MSP_STATUS); await MSP.promise(MSPCodes.MSP_PID_ADVANCED); await MSP.promise(MSPCodes.MSP_FEATURE_CONFIG); await MSP.promise(MSPCodes.MSP_MIXER_CONFIG); @@ -1023,11 +1022,6 @@ motors.initialize = async function (callback) { // data pulling functions used inside interval timer - function getStatus() { - // status needed for arming flag - MSP.send_message(MSPCodes.MSP_STATUS, false, false, get_motor_data); - } - function get_motor_data() { MSP.send_message(MSPCodes.MSP_MOTOR, false, false, get_motor_telemetry_data); } @@ -1177,7 +1171,7 @@ motors.initialize = async function (callback) { $('a.stop').on('click', () => motorsEnableTestModeElement.prop('checked', false).trigger('change')); // enable Status and Motor data pulling - GUI.interval_add('motor_and_status_pull', getStatus, 50, true); + GUI.interval_add('motor_and_status_pull', get_motor_data, 50, true); setup_motor_output_reordering_dialog(SetupEscDshotDirectionDialogCallback, zeroThrottleValue); diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js index 6f1b3d1d..41781d82 100644 --- a/src/js/tabs/pid_tuning.js +++ b/src/js/tabs/pid_tuning.js @@ -54,9 +54,7 @@ pid_tuning.initialize = function (callback) { const FILTER_DEFAULT = FC.getFilterDefaults(); const PID_DEFAULT = FC.getPidDefaults(); - // requesting MSP_STATUS manually because it contains FC.CONFIG.profile - MSP.promise(MSPCodes.MSP_STATUS) - .then(() => MSP.promise(MSPCodes.MSP_PID_CONTROLLER)) + MSP.promise(MSPCodes.MSP_PID_CONTROLLER) .then(() => MSP.promise(MSPCodes.MSP_PIDNAMES)) .then(() => MSP.promise(MSPCodes.MSP_PID)) .then(() => MSP.promise(MSPCodes.MSP_PID_ADVANCED)) @@ -2286,8 +2284,8 @@ pid_tuning.initialize = function (callback) { GUI.interval_add('receiver_pull', self.getReceiverData, 250, true); // status data pulled via separate timer with static speed - GUI.interval_add('status_pull', function status_pull() { - MSP.send_message(MSPCodes.MSP_STATUS_EX, false, false, self.checkUpdateProfile(true)); + GUI.interval_add('update_profile', function update_profile() { + self.checkUpdateProfile(true); }, 500, true); self.analyticsChanges = {}; diff --git a/src/js/tabs/receiver.js b/src/js/tabs/receiver.js index 2c513189..21501e83 100644 --- a/src/js/tabs/receiver.js +++ b/src/js/tabs/receiver.js @@ -850,11 +850,6 @@ receiver.initialize = function (callback) { // TODO: Combine two polls together GUI.interval_add('receiver_pull_for_model_preview', tab.getReceiverData, 33, false); - // 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); - GUI.content_ready(callback); } }; diff --git a/src/js/tabs/setup.js b/src/js/tabs/setup.js index c11f0830..9fb75af1 100644 --- a/src/js/tabs/setup.js +++ b/src/js/tabs/setup.js @@ -401,36 +401,31 @@ setup.initialize = function (callback) { function get_slow_data() { - MSP.send_message(MSPCodes.MSP_STATUS_EX, false, false, function() { + // Status info is acquired in the background using update_live_status() in serial_backend.js - $('#initialSetupArmingAllowed').toggle(FC.CONFIG.armingDisableFlags == 0); + $('#initialSetupArmingAllowed').toggle(FC.CONFIG.armingDisableFlags === 0); - for (let i = 0; i < FC.CONFIG.armingDisableCount; i++) { - $(`#initialSetupArmingDisableFlags${i}`).css('display',(FC.CONFIG.armingDisableFlags & (1 << i)) == 0 ? 'none':'inline-block'); - } - - }); - - // GPS info - if (have_sensor(FC.CONFIG.activeSensors, 'gps')) { - MSP.send_message(MSPCodes.MSP_RAW_GPS, false, false, function () { - gpsFix_e.html((FC.GPS_DATA.fix) ? i18n.getMessage('gpsFixTrue') : i18n.getMessage('gpsFixFalse')); - gpsSats_e.text(FC.GPS_DATA.numSat); - gpsLat_e.text(`${(FC.GPS_DATA.lat / 10000000).toFixed(4)} deg`); - gpsLon_e.text(`${(FC.GPS_DATA.lon / 10000000).toFixed(4)} deg`); - }); + for (let i = 0; i < FC.CONFIG.armingDisableCount; i++) { + $(`#initialSetupArmingDisableFlags${i}`).css('display',(FC.CONFIG.armingDisableFlags & (1 << i)) === 0 ? 'none':'inline-block'); } - // System info - MSP.send_message(MSPCodes.MSP_ANALOG, false, false, function () { - bat_voltage_e.text(i18n.getMessage('initialSetupBatteryValue', [FC.ANALOG.voltage])); - bat_mah_drawn_e.text(i18n.getMessage('initialSetupBatteryMahValue', [FC.ANALOG.mAhdrawn])); - bat_mah_drawing_e.text(i18n.getMessage('initialSetupBatteryAValue', [FC.ANALOG.amperage.toFixed(2)])); - rssi_e.text(i18n.getMessage('initialSetupRSSIValue', [((FC.ANALOG.rssi / 1023) * 100).toFixed(0)])); - if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_46)) { - cputemp_e.html(`${FC.CONFIG.cpuTemp.toFixed(0)} ℃`); - } - }); + // System info is acquired in the background using update_live_status() in serial_backend.js + + bat_voltage_e.text(i18n.getMessage('initialSetupBatteryValue', [FC.ANALOG.voltage])); + bat_mah_drawn_e.text(i18n.getMessage('initialSetupBatteryMahValue', [FC.ANALOG.mAhdrawn])); + bat_mah_drawing_e.text(i18n.getMessage('initialSetupBatteryAValue', [FC.ANALOG.amperage.toFixed(2)])); + rssi_e.text(i18n.getMessage('initialSetupRSSIValue', [((FC.ANALOG.rssi / 1023) * 100).toFixed(0)])); + + if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_46) && FC.CONFIG.cpuTemp) { + cputemp_e.html(`${FC.CONFIG.cpuTemp.toFixed(0)} ℃`); + } + + // GPS info is acquired in the background using update_live_status() in serial_backend.js + + gpsFix_e.html((FC.GPS_DATA.fix) ? i18n.getMessage('gpsFixTrue') : i18n.getMessage('gpsFixFalse')); + gpsSats_e.text(FC.GPS_DATA.numSat); + gpsLat_e.text(`${(FC.GPS_DATA.lat / 10000000).toFixed(4)} deg`); + gpsLon_e.text(`${(FC.GPS_DATA.lon / 10000000).toFixed(4)} deg`); } function get_fast_data() {