- New Server tab: server URL, ingest token and installation id, with
Save, Test connection (health, then a read-only token check) and the
config-file import that upstream removed (app folder / USB stick first,
document picker as fallback). Settings are kept encrypted and read on
every use, so the service picks up a change without a restart. Each
installation generates its own id; the inherited upstream UUID and
the baked-in CONSUMPTION_API_* build fields are gone.
- Live telemetry restored from before ea8032a (TelemetryPayload,
UploadCadence, UploadSettings, GPS) and sent in batches to
POST /v1/telemetry instead of ABRP; the server forwards to ABRP. Adds
ext_temp, voltage and current. Unsent samples queue in memory (about
8 h) while offline.
- Upload tab: the live-telemetry switch and cadence controls work again;
the dead service and autostart switches are removed.
- Manifest: location permissions and foreground service types.
- Unit tests compile again: 114 (stable) / 136 (unstable) pass. Tests
for the deleted AbrpApi and HeadUnitWeather removed; new tests for
ServerConfig and TelemetryQueue. Lint passes.
Not yet tried on the car.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
67 lines
2.9 KiB
Java
67 lines
2.9 KiB
Java
package com.evsuite.abrp;
|
|
|
|
/**
|
|
* Decides whether a given scheduler tick should actually upload.
|
|
*
|
|
* The service ticks at a fixed short rate; this class thins the uploads out. A car parked
|
|
* overnight and not charging does not need a sample every minute — that is wasted data and
|
|
* power — but nothing may be lost while driving or charging, where ABRP needs the
|
|
* resolution to keep a route plan accurate.
|
|
*
|
|
* Free of Android types so the policy can be unit-tested directly.
|
|
*/
|
|
final class UploadCadence {
|
|
|
|
/**
|
|
* Parked and not charging: one keep-alive sample every 15 minutes. The car is not
|
|
* moving and its SOC is not changing, so anything more is spent for nothing.
|
|
*/
|
|
static final long PARKED_INTERVAL_MS = 900_000L;
|
|
|
|
private UploadCadence() { }
|
|
|
|
/**
|
|
* @param nowMs current time
|
|
* @param lastUploadMs when the last upload was attempted, 0 if never
|
|
* @param parked null when the gear could not be read
|
|
* @param charging null when the charge port state could not be read
|
|
* @param socPercent null when the battery level could not be read
|
|
* @param stateChanged true if parked/charging differ from the previous tick
|
|
* @param settings user-configured cadence
|
|
*/
|
|
static boolean shouldUpload(long nowMs, long lastUploadMs,
|
|
Boolean parked, Boolean charging, Integer socPercent,
|
|
boolean stateChanged, UploadSettings settings) {
|
|
// Never uploaded yet: send immediately so ABRP sees the car come online.
|
|
if (lastUploadMs <= 0L) return true;
|
|
|
|
// A transition (just parked, plugged in, unplugged) is exactly what ABRP must
|
|
// learn straight away — never make it wait for the slow interval.
|
|
if (stateChanged) return true;
|
|
|
|
return nowMs - lastUploadMs >= intervalFor(parked, charging, socPercent, settings);
|
|
}
|
|
|
|
/**
|
|
* Interval that applies in the given state.
|
|
*
|
|
* Unknown state counts as active: if the gear or charge port could not be read we do
|
|
* not know the car is idle, and under-reporting a moving car is worse than a few
|
|
* extra requests from a stationary one.
|
|
*/
|
|
static long intervalFor(Boolean parked, Boolean charging, Integer socPercent,
|
|
UploadSettings settings) {
|
|
boolean idle = Boolean.TRUE.equals(parked) && Boolean.FALSE.equals(charging);
|
|
if (idle) return PARKED_INTERVAL_MS;
|
|
|
|
// Low battery: the driver is picking a charge stop and ABRP needs a tighter SOC
|
|
// curve to get the arrival estimate right. Only while actually in use — a car
|
|
// parked at 5 % is still parked and gains nothing from fast polling.
|
|
if (settings.boostLowSoc && socPercent != null
|
|
&& socPercent <= settings.lowSocPercent) {
|
|
return Math.min(settings.intervalMs(), UploadSettings.BOOSTED_INTERVAL_SEC * 1000L);
|
|
}
|
|
return settings.intervalMs();
|
|
}
|
|
}
|