App 2.3.0: Server tab, live telemetry to the car server
- 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>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user