Added battery info to frontend

This commit is contained in:
Fabio Manganiello 2025-03-30 22:10:01 +02:00
parent aca1aeead4
commit 3eaf721ffd
Signed by: blacklight
GPG key ID: D90FBA7F76362774
3 changed files with 65 additions and 3 deletions

View file

@ -55,7 +55,7 @@
{{ device.name }} {{ device.name }}
</p> </p>
<p class="battery" :style="{ color: batteryColor }" v-if="point.battery"> <p class="battery" :style="{ color: batteryColor ?? 'initial' }" v-if="point.battery">
<font-awesome-icon :icon="batteryIconClass" /> <font-awesome-icon :icon="batteryIconClass" />
<span>{{ point.battery }}%</span> <span>{{ point.battery }}%</span>
</p> </p>

View file

@ -21,6 +21,13 @@
:title="(showMetrics.speed ? 'Hide' : 'Show') + ' speed'"> :title="(showMetrics.speed ? 'Hide' : 'Show') + ' speed'">
<font-awesome-icon icon="tachometer-alt" /> <font-awesome-icon icon="tachometer-alt" />
</button> </button>
<button @click="toggleMetric('battery')"
:class="{ selected: showMetrics.battery }"
:title="(showMetrics.battery ? 'Hide' : 'Show') + ' battery level'"
v-if="hasBatteryInfo">
<font-awesome-icon icon="battery-full" />
</button>
</div> </div>
<div class="page-button-container"> <div class="page-button-container">
@ -128,12 +135,25 @@ export default {
}) })
}, },
hasBatteryInfo(): boolean {
return this.points.some((point: GPSPoint) => point.battery != null)
},
battery(): (number | null)[] {
return this.points
.map((point: GPSPoint) => point.battery ?? null)
},
speed(): number[] { speed(): number[] {
if (!this.points.length) { if (!this.points.length) {
return [] return []
} }
return this.points.map((point: GPSPoint, index: number) => { return this.points.map((point: GPSPoint, index: number) => {
if (point.speed != null) {
return point.speed
}
if (index === 0) { if (index === 0) {
return 0 return 0
} }
@ -185,6 +205,19 @@ export default {
) )
} }
if (this.showMetrics.battery) {
datasets.push(
{
label: 'Battery (%)',
backgroundColor: '#0989f8',
borderColor: '#5959a8',
fill: false,
data: this.battery,
yAxisID: 'percentage',
}
)
}
return { return {
labels: this.points.map((point: GPSPoint) => point.timestamp), labels: this.points.map((point: GPSPoint) => point.timestamp),
datasets: datasets, datasets: datasets,
@ -242,6 +275,31 @@ export default {
} }
} }
if (this.showMetrics.battery) {
let position = 'left'
if (yAxes.meters || yAxes.speed) {
position = 'right'
}
yAxes.percentage = {
type: 'linear',
position: position,
display: true,
min: 0,
max: 100,
ticks: {
beginAtZero: true,
},
title: {
display: true,
text: 'Percentage',
},
grid: {
drawOnChartArea: false,
},
}
}
const xTicks = {} as { min?: Date, max?: Date } const xTicks = {} as { min?: Date, max?: Date }
if (this.points.length > 1) { if (this.points.length > 1) {
xTicks.min = this.points[0].timestamp xTicks.min = this.points[0].timestamp

View file

@ -2,13 +2,14 @@ class TimelineMetricsConfiguration {
public altitude: boolean = false; public altitude: boolean = false;
public distance: boolean = true; public distance: boolean = true;
public speed: boolean = false; public speed: boolean = false;
public battery: boolean = false;
constructor(data: any | null = null) { constructor(data: any | null = null) {
if (!data) { if (!data) {
return; return;
} }
for (const key of ['altitude', 'distance', 'speed']) { for (const key of ['altitude', 'distance', 'speed', 'battery']) {
const value = String( const value = String(
data[key] ?? data['show' + key.charAt(0).toUpperCase() + key.slice(1)] data[key] ?? data['show' + key.charAt(0).toUpperCase() + key.slice(1)]
) )
@ -39,13 +40,16 @@ class TimelineMetricsConfiguration {
case 'speed': case 'speed':
this.speed = !this.speed; this.speed = !this.speed;
break; break;
case 'battery':
this.battery = !this.battery;
break;
default: default:
throw new TypeError(`Invalid timeline metric: ${metric}`); throw new TypeError(`Invalid timeline metric: ${metric}`);
} }
} }
toQuery(): Record<string, string> { toQuery(): Record<string, string> {
return ['altitude', 'distance', 'speed'].reduce((acc: Record<string, string>, key: string) => { return ['altitude', 'distance', 'speed', 'battery'].reduce((acc: Record<string, string>, key: string) => {
acc['show' + key.charAt(0).toUpperCase() + key.slice(1)] = String((this as any)[key]); acc['show' + key.charAt(0).toUpperCase() + key.slice(1)] = String((this as any)[key]);
return acc; return acc;
}, {}); }, {});