-
Notifications
You must be signed in to change notification settings - Fork 50
Allow recording data-lake variables in the telemetry/sensor-logging/video-overlays #2406
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f0ba5a3
33196f7
92fc82d
2aa1cb3
0e1cd39
88089c8
11e308b
74db352
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,9 +7,11 @@ import { useAppInterfaceStore } from '@/stores/appInterface' | |
| import { useMainVehicleStore } from '@/stores/mainVehicle' | ||
| import { useMissionStore } from '@/stores/mission' | ||
|
|
||
| import { getDataLakeVariableData, getDataLakeVariableInfo } from './actions/data-lake' | ||
| import { settingsManager } from './settings-management' | ||
| import { unitAbbreviation } from './units' | ||
| import { degrees } from './utils' | ||
| import { findDataLakeInputsInString, replaceDataLakeInputsInString } from './utils-data-lake' | ||
|
|
||
| /** | ||
| * Variables data can be datalogged | ||
|
|
@@ -71,10 +73,6 @@ type VeryGenericData = { | |
| * Linux epoch stating when this value was last changed | ||
| */ | ||
| lastChanged?: number | ||
| /** | ||
| * Current view of the variable | ||
| */ | ||
| hideLabel?: boolean | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -88,7 +86,7 @@ export type ExtendedVariablesData = { | |
| [key: string]: { | ||
| value: string | ||
| lastChanged: number | ||
| hideLabel?: boolean | ||
| displayName: string | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -324,27 +322,30 @@ class DataLogger { | |
|
|
||
| /* eslint-disable vue/max-len, prettier/prettier, max-len */ | ||
| let variablesData: ExtendedVariablesData = { | ||
| [DatalogVariable.roll]: { value: `${degrees(vehicleStore.attitude.roll)?.toFixed(1)} °`, ...timeNowObj }, | ||
| [DatalogVariable.pitch]: { value: `${degrees(vehicleStore.attitude.pitch)?.toFixed(1)} °`, ...timeNowObj }, | ||
| [DatalogVariable.heading]: { value: `${degrees(vehicleStore.attitude.yaw)?.toFixed(1)} °`, ...timeNowObj }, | ||
| [DatalogVariable.depth]: { value: `${depthValue} ${depthUnit}`, ...timeNowObj }, | ||
| [DatalogVariable.mode]: { value: vehicleStore.mode || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.batteryVoltage]: { value: `${vehicleStore.powerSupply.voltage?.toFixed(2)} V` || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.batteryCurrent]: { value: `${vehicleStore.powerSupply.current?.toFixed(2)} A` || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.gpsVisibleSatellites]: { value: vehicleStore.statusGPS.visibleSatellites?.toFixed(0) || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.gpsFixType]: { value: vehicleStore.statusGPS.fixType, ...timeNowObj }, | ||
| [DatalogVariable.latitude]: { value: `${vehicleStore.coordinates.latitude?.toFixed(6)} °` || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.longitude]: { value: `${vehicleStore.coordinates.longitude?.toFixed(6)} °` || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.missionName]: { value: missionStore.missionName || 'Cockpit', hideLabel: true, ...timeNowObj }, | ||
| [DatalogVariable.time]: { value: format(timeNow, 'HH:mm:ss O'), hideLabel: true, ...timeNowObj }, | ||
| [DatalogVariable.date]: { value: format(timeNow, 'LLL dd, yyyy'), hideLabel: true, ...timeNowObj }, | ||
| [DatalogVariable.instantaneousPower]: { value: `${vehicleStore.instantaneousWatts?.toFixed(1)} W` || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.roll]: { displayName: DatalogVariable.roll, value: `${degrees(vehicleStore.attitude.roll)?.toFixed(1)} °`, ...timeNowObj }, | ||
| [DatalogVariable.pitch]: { displayName: DatalogVariable.pitch, value: `${degrees(vehicleStore.attitude.pitch)?.toFixed(1)} °`, ...timeNowObj }, | ||
| [DatalogVariable.heading]: { displayName: DatalogVariable.heading, value: `${degrees(vehicleStore.attitude.yaw)?.toFixed(1)} °`, ...timeNowObj }, | ||
| [DatalogVariable.depth]: { displayName: DatalogVariable.depth, value: `${depthValue} ${depthUnit}`, ...timeNowObj }, | ||
| [DatalogVariable.mode]: { displayName: DatalogVariable.mode, value: vehicleStore.mode || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.batteryVoltage]: { displayName: DatalogVariable.batteryVoltage, value: `${vehicleStore.powerSupply.voltage?.toFixed(2)} V` || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.batteryCurrent]: { displayName: DatalogVariable.batteryCurrent, value: `${vehicleStore.powerSupply.current?.toFixed(2)} A` || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.gpsVisibleSatellites]: { displayName: DatalogVariable.gpsVisibleSatellites, value: vehicleStore.statusGPS.visibleSatellites?.toFixed(0) || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.gpsFixType]: { displayName: DatalogVariable.gpsFixType, value: vehicleStore.statusGPS.fixType, ...timeNowObj }, | ||
| [DatalogVariable.latitude]: { displayName: DatalogVariable.latitude, value: `${vehicleStore.coordinates.latitude?.toFixed(6)} °` || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.longitude]: { displayName: DatalogVariable.longitude, value: `${vehicleStore.coordinates.longitude?.toFixed(6)} °` || 'Unknown', ...timeNowObj }, | ||
| [DatalogVariable.missionName]: { displayName: '', value: missionStore.missionName || 'Cockpit', ...timeNowObj }, | ||
| [DatalogVariable.time]: { displayName: '', value: format(timeNow, 'HH:mm:ss O'), ...timeNowObj }, | ||
| [DatalogVariable.date]: { displayName: '', value: format(timeNow, 'LLL dd, yyyy'), ...timeNowObj }, | ||
| [DatalogVariable.instantaneousPower]: { displayName: DatalogVariable.instantaneousPower, value: `${vehicleStore.instantaneousWatts?.toFixed(1)} W` || 'Unknown', ...timeNowObj }, | ||
| } | ||
|
|
||
| /* eslint-enable vue/max-len, prettier/prettier, max-len */ | ||
| const veryGenericData = this.collectVeryGenericData(timeNowObj) | ||
| variablesData = { ...variablesData, ...veryGenericData } | ||
|
|
||
| const dataLakeData = this.collectDataLakeData(variablesData, timeNowObj) | ||
| variablesData = { ...variablesData, ...dataLakeData } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this have conflicts/overrides? I think the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's what's causing the need for what you mentioned in the previous comment. Despite being desirable to enter at some point, the standardization is not a must here for this functionality. We can work step by step.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed that standardisation isn't a requirement for this, but while it isn't implemented it's likely worth at least a comment or an Issue mentioning we know it's a potential source of conflicts, just in case a user actually runs into issues with it down the line :-)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Definitely. |
||
|
|
||
| const logPoint: CockpitStandardLogPoint = { | ||
| epoch: timeNow.getTime(), | ||
| data: structuredClone(variablesData), | ||
|
|
@@ -372,12 +373,59 @@ class DataLogger { | |
| this.veryGenericIndicators.forEach((indicator) => { | ||
| result[indicator.displayName] = { | ||
| value: indicator.variableValue, | ||
| displayName: indicator.displayName, | ||
| lastChanged: data.lastChanged, | ||
| } | ||
| }) | ||
| return result | ||
| } | ||
|
|
||
| /** | ||
| * Collects data from data lake variables in the telemetry display grid that are not already covered | ||
| * by standard variables or VeryGenericIndicator data. | ||
| * Also resolves {{ variableId }} templates in custom messages. | ||
| * @param {ExtendedVariablesData} currentData - Already collected variables data (standard + VGI) | ||
| * @param {{ lastChanged: number }} timeInfo - Timestamp info for the log point | ||
| * @param {number} timeInfo.lastChanged - Linux epoch stating when this value was last changed | ||
| * @returns {ExtendedVariablesData} Resolved data lake variable values | ||
| */ | ||
| collectDataLakeData(currentData: ExtendedVariablesData, timeInfo: { lastChanged: number }): ExtendedVariablesData { | ||
| const result: ExtendedVariablesData = {} | ||
|
|
||
| for (const gridEntries of Object.values(this.telemetryDisplayData)) { | ||
| for (const entry of gridEntries) { | ||
| if (currentData[entry]) continue | ||
|
|
||
| if (findDataLakeInputsInString(entry).length > 0) { | ||
| result[entry] = { | ||
| value: replaceDataLakeInputsInString(entry), | ||
| displayName: '', | ||
| ...timeInfo, | ||
| } | ||
| continue | ||
| } | ||
|
|
||
| const variableInfo = getDataLakeVariableInfo(entry) | ||
| if (variableInfo) { | ||
| const value = getDataLakeVariableData(entry) | ||
| let displayName = variableInfo.name ?? entry | ||
|
|
||
| // If the variable is a MAVLink variable, remove the (MAVLink / System: <systemId> / Component: <componentId>) suffix | ||
| if (entry.includes('mavlink/') && displayName.includes('(')) { | ||
| displayName = displayName.substring(0, displayName.lastIndexOf('(')).trim() | ||
| } | ||
| result[entry] = { | ||
| value: value !== undefined ? String(value) : 'N/A', | ||
| displayName, | ||
| ...timeInfo, | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return result | ||
| } | ||
|
|
||
| /** | ||
| * Removes the requester from the log requesters list. If there are no requesters left, logging will stop. | ||
| * @param {string} requesterId The ID of the requester to stop | ||
|
|
@@ -572,7 +620,7 @@ Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text` | |
| .map((variable) => { | ||
| const variableData = logPoint.data[variable] | ||
| if (variableData) { | ||
| return `${variableData.hideLabel ? '' : `${variable}:`} ${variableData.value}` | ||
| return variableData.displayName ? `${variableData.displayName}: ${variableData.value}` : variableData.value | ||
| } else { | ||
| return `${variable}` | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we make this optional then if left unspecified it can default to the key, and if specified as an empty string it could replace the previous
hideLabel: trueusage (with the special behaviour of no name section being rendered).Not a blocker, just could make the code slightly cleaner / require fewer changes to the existing definitions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one I prefer to stay as it is. I believe the right approach is to remove all non-data-lake sensor/telemetry logging approaches.