feat: add direct car telemetry management

This commit is contained in:
2026-07-31 23:14:40 +02:00
parent 530162cbf7
commit e347a581e1
16 changed files with 447 additions and 57 deletions
+26 -4
View File
@@ -169,10 +169,15 @@ describe("ADB dashboard operations", () => {
await expect(launchAdbTarget(enabledConfig, { type: "component", value: "com.example/.Main;reboot" }, execute)).rejects.toThrow("INVALID_ADB_COMPONENT");
});
it("parses the verified MG4 live properties and marks SAIC-only data unavailable", async () => {
const execute: AdbExecutor = async (_executable, arguments_) => arguments_.includes("content")
? { stdout: "Result: Bundle[{status=ok, sampledAt=1785540000000, soc=73.5, rangeKm=286, speedKph=18.0, batteryVolts=397.4, totalConsumptionKwh=6.2, chargingStatus=0}]", stderr: "" }
: { stdout: "[arcsoft.avm.mCurCarSpeed]: [17]\n[arcsoft.avm.mCurCarGear]: [4]\n[arcsoft.avm.mCurCarWheelAngle]: [-12.5]\n", stderr: "" };
it("reads vehicle data through a pushed ADB probe without an installed companion app", async () => {
const calls: string[][] = [];
const execute: AdbExecutor = async (_executable, arguments_) => {
calls.push([...arguments_]);
if (arguments_.includes("app_process")) {
return { stdout: '{"status":"ok","soc":73.5,"rangeKm":286,"speedKph":18,"batteryVolts":397.4,"totalConsumptionKwh":6.2,"chargingStatus":0}\n', stderr: "" };
}
return { stdout: "[arcsoft.avm.mCurCarSpeed]: [17]\n[arcsoft.avm.mCurCarGear]: [4]\n[arcsoft.avm.mCurCarWheelAngle]: [-12.5]\n", stderr: "" };
};
await expect(collectCarTelemetry(enabledConfig, execute)).resolves.toMatchObject({
available: true,
speedKph: { available: true, value: 18 },
@@ -184,6 +189,23 @@ describe("ADB dashboard operations", () => {
totalConsumptionKwh: { available: true, value: 6.2 },
chargingStatus: { available: true, value: 0 }
});
expect(calls.some((call) => call[2] === "push" && call.at(-1) === "/data/local/tmp/pi-car-telemetry-probe.dex")).toBe(true);
expect(calls.some((call) => call.includes("app_process"))).toBe(true);
expect(calls.flat()).not.toContain("content://cloud.molberg.mgutility.vehicle");
await collectCarTelemetry(enabledConfig, execute);
expect(calls.filter((call) => call[2] === "push")).toHaveLength(1);
});
it("keeps direct properties available when the factory vehicle service cannot be sampled", async () => {
const execute: AdbExecutor = async (_executable, arguments_) => {
if (arguments_.includes("app_process")) throw new Error("service unavailable");
return { stdout: "[arcsoft.avm.mCurCarSpeed]: [17]\n[arcsoft.avm.mCurCarGear]: [4]\n[arcsoft.avm.mCurCarWheelAngle]: [-12.5]\n", stderr: "" };
};
await expect(collectCarTelemetry(enabledConfig, execute)).resolves.toMatchObject({
speedKph: { available: true, value: 17 },
batteryPercent: { available: false, reason: expect.stringContaining("factory vehicle service over ADB") }
});
});
it("accepts only ZIP-formatted APK payloads and removes the temporary file", async () => {