Add persistent car performance analytics

This commit is contained in:
2026-07-31 22:44:51 +02:00
parent 0e4ce931ec
commit 6998e8bdb7
12 changed files with 916 additions and 29 deletions
+66
View File
@@ -122,6 +122,64 @@ export type CarTelemetry = {
wheelAngleDegrees: Availability<number>;
batteryPercent: Availability<number>;
rangeKm: Availability<number>;
batteryVoltage: Availability<number>;
totalConsumptionKwh: Availability<number>;
chargingStatus: Availability<number>;
};
export type TelemetryPeriod = "24h" | "7d" | "30d" | "1y" | "all";
export type TelemetryHistoryPoint = {
timestamp: number;
speedKph: number | null;
peakSpeedKph: number | null;
batteryPercent: number | null;
rangeKm: number | null;
chargingPowerKw: number | null;
};
export type CarStatistics = {
latest: {
recordedAt: number;
speedKph: number | null;
wheelAngleDegrees: number | null;
batteryPercent: number | null;
rangeKm: number | null;
batteryVoltage: number | null;
totalConsumptionKwh: number | null;
chargingStatus: number | null;
chargingPowerKw: number | null;
} | null;
records: {
peakSpeedKph: number | null;
peakSpeedAt: number | null;
peakChargingPowerKw: number | null;
peakChargingPowerAt: number | null;
maxObservedRangeKm: number | null;
maxObservedRangeAt: number | null;
};
lifetime: {
firstSampleAt: number | null;
lastSampleAt: number | null;
sampleCount: number;
trackedDistanceKm: number;
drivingSeconds: number;
chargingSeconds: number;
chargeSessions: number;
socUsedPercent: number;
averageMovingSpeedKph: number | null;
ownRangeEstimateKm: number | null;
};
storage: {
rawSamples: number;
hourlyRollups: number;
oldestRawAt: number | null;
oldestRollupAt: number | null;
estimatedBytes: number;
rawRetentionDays: number;
rollupRetentionYears: number;
rawSampleCap: number;
};
};
type ErrorResponse = { error?: { code?: string; message?: string } };
@@ -216,3 +274,11 @@ export async function deleteAdbShortcut(id: number, csrfToken: string): Promise<
export async function getCarTelemetry(): Promise<CarTelemetry> {
return parseResponse<CarTelemetry>(await fetch("/api/car/telemetry", { credentials: "same-origin" }));
}
export async function getCarHistory(period: TelemetryPeriod): Promise<{ period: TelemetryPeriod; points: TelemetryHistoryPoint[] }> {
return parseResponse(await fetch(`/api/car/history?period=${period}`, { credentials: "same-origin" }));
}
export async function getCarStatistics(): Promise<CarStatistics> {
return parseResponse<CarStatistics>(await fetch("/api/car/statistics", { credentials: "same-origin" }));
}