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 @@
-
- {{ message }}
-
-
-
+
+
- Close
-
-
-
+ {{ alert.message }}
+
+
+
+
+
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[] {