diff --git a/core/frontend/src/components/app/Alerter.vue b/core/frontend/src/components/app/Alerter.vue index e4ae31b40b..27a21b3fbb 100644 --- a/core/frontend/src/components/app/Alerter.vue +++ b/core/frontend/src/components/app/Alerter.vue @@ -1,21 +1,24 @@ + + diff --git a/core/frontend/src/libs/message-manager.ts b/core/frontend/src/libs/message-manager.ts index 8fbb5b8a7a..de7bd60bf2 100644 --- a/core/frontend/src/libs/message-manager.ts +++ b/core/frontend/src/libs/message-manager.ts @@ -48,6 +48,16 @@ class MessageManager { this.callbacks.push(callback) } + /** + * Remove a previously added callback + */ + removeCallback(callback:(level: MessageLevel, msg: string) => void): void { + const index = this.callbacks.indexOf(callback) + if (index !== -1) { + this.callbacks.splice(index, 1) + } + } + /** * Emit a new message to be used in all callbacks */ diff --git a/core/frontend/src/types/autopilot/parameter-fetcher.ts b/core/frontend/src/types/autopilot/parameter-fetcher.ts index 27eebd6f73..fe452b0f18 100644 --- a/core/frontend/src/types/autopilot/parameter-fetcher.ts +++ b/core/frontend/src/types/autopilot/parameter-fetcher.ts @@ -1,4 +1,6 @@ import mavlink2rest from '@/libs/MAVLink2Rest' +import message_manager, { MessageLevel } from '@/libs/message-manager' +import settings from '@/libs/settings' // eslint-disable-next-line import/no-cycle import ardupilot_data from '@/store/autopilot' import { AutopilotStore } from '@/store/autopilot' @@ -33,6 +35,10 @@ export default class ParameterFetcher { this.store = store } + allParametersLoaded(): boolean { + return this.total_params_count !== null && this.loaded_params_count >= this.total_params_count + } + reset(): void { this.loaded_params_count = 0 this.total_params_count = null @@ -57,9 +63,7 @@ export default class ParameterFetcher { } requestParamsWatchdog(): void { - if (this.total_params_count !== null - && this.loaded_params_count > 0 - && this.loaded_params_count >= this.total_params_count) { + if (this.loaded_params_count > 0 && this.allParametersLoaded()) { return } if (autopilot.restarting) { @@ -107,7 +111,13 @@ export default class ParameterFetcher { // We need this due to mismatches between js 64-bit floats and REAL32 in MAVLink const trimmed_value = Math.round(param_value * 10000) / 10000 if (param_index === 65535) { - this.parameter_table.updateParam(param_name, trimmed_value) + const change = this.parameter_table.updateParam(param_name, trimmed_value) + if (change && this.allParametersLoaded() && settings.is_dev_mode) { + message_manager.emitMessage( + MessageLevel.Info, + `Parameter ${param_name} changed: ${change.oldValue} → ${trimmed_value}`, + ) + } } else { this.parameter_table.addParam( { diff --git a/core/frontend/src/types/autopilot/parameter-table.ts b/core/frontend/src/types/autopilot/parameter-table.ts index e150a69264..ad1b3b1354 100644 --- a/core/frontend/src/types/autopilot/parameter-table.ts +++ b/core/frontend/src/types/autopilot/parameter-table.ts @@ -190,15 +190,21 @@ export default class ParametersTable { this.parametersDict[param.id] = param } - updateParam(param_name: string, param_value: number): void { + updateParam(param_name: string, param_value: number): { oldValue: number } | null { const index = Object.entries(this.parametersDict).find(([_key, value]) => value.name === param_name) if (!index) { // This is benign and will happen if we receive a parameter update before the parameters table // is fully populated. We can safely ignore it. console.info(`Unable to update param in store: ${param_name}. Parameter not yet loaded into ParametersTable.`) - return + return null + } + const paramKey = parseInt(index[0], 10) + const oldValue = this.parametersDict[paramKey].value + this.parametersDict[paramKey].value = param_value + if (oldValue !== param_value) { + return { oldValue } } - this.parametersDict[parseInt(index[0], 10)].value = param_value + return null } parameters(): Parameter[] {