1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-12-26 10:35:50 +01:00

Garmin: Fix monitoring sample timestamp16 handling

This commit is contained in:
José Rebelo 2024-09-24 19:23:02 +01:00 committed by José Rebelo
parent 5730e82380
commit ce387396fd
3 changed files with 26 additions and 16 deletions

View File

@ -73,7 +73,7 @@ public class FitImporter {
private final Context context;
private final GBDevice gbDevice;
private final SortedMap<Integer, List<FitMonitoring>> activitySamplesPerTimestamp = new TreeMap<>();
private final SortedMap<Long, List<FitMonitoring>> activitySamplesPerTimestamp = new TreeMap<>();
private final List<GarminStressSample> stressSamples = new ArrayList<>();
private final List<GarminBodyEnergySample> bodyEnergySamples = new ArrayList<>();
private final List<GarminSpo2Sample> spo2samples = new ArrayList<>();
@ -100,6 +100,8 @@ public class FitImporter {
final FitFile fitFile = FitFile.parseIncoming(file);
Long lastMonitoringTimestamp = null;
for (final RecordData record : fitFile.getRecords()) {
if (fileId != null && fileId.getType() == FileType.FILETYPE.ACTIVITY) {
if (workoutParser.handleRecord(record)) {
@ -160,10 +162,13 @@ public class FitImporter {
sleepStageSamples.add(sample);
} else if (record instanceof FitMonitoring) {
LOG.trace("Monitoring at {}: {}", ts, record);
if (!activitySamplesPerTimestamp.containsKey(ts.intValue())) {
activitySamplesPerTimestamp.put(ts.intValue(), new ArrayList<>());
final FitMonitoring monitoringRecord = (FitMonitoring) record;
final Long currentMonitoringTimestamp = monitoringRecord.computeTimestamp(lastMonitoringTimestamp);
if (!activitySamplesPerTimestamp.containsKey(currentMonitoringTimestamp)) {
activitySamplesPerTimestamp.put(currentMonitoringTimestamp, new ArrayList<>());
}
Objects.requireNonNull(activitySamplesPerTimestamp.get(ts.intValue())).add((FitMonitoring) record);
Objects.requireNonNull(activitySamplesPerTimestamp.get(currentMonitoringTimestamp)).add(monitoringRecord);
lastMonitoringTimestamp = currentMonitoringTimestamp;
} else if (record instanceof FitSpo2) {
final Integer spo2 = ((FitSpo2) record).getReadingSpo2();
if (spo2 == null || spo2 <= 0) {
@ -359,7 +364,7 @@ public class FitImporter {
int prevActivityKind = ActivityKind.UNKNOWN.getCode();
int prevTs = -1;
for (final int ts : activitySamplesPerTimestamp.keySet()) {
for (final long ts : activitySamplesPerTimestamp.keySet()) {
if (prevTs > 0 && ts - prevTs > 60) {
// Fill gaps between samples
LOG.debug("Filling gap between {} and {}", prevTs, ts);
@ -376,7 +381,7 @@ public class FitImporter {
final List<FitMonitoring> records = activitySamplesPerTimestamp.get(ts);
final GarminActivitySample sample = new GarminActivitySample();
sample.setTimestamp(ts);
sample.setTimestamp((int) ts);
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
sample.setRawIntensity(ActivitySample.NOT_MEASURED);
sample.setSteps(ActivitySample.NOT_MEASURED);
@ -413,7 +418,7 @@ public class FitImporter {
activitySamples.add(sample);
prevActivityKind = sample.getRawKind();
prevTs = ts;
prevTs = (int) ts;
}
LOG.debug("Will persist {} activity samples", activitySamples.size());

View File

@ -26,7 +26,13 @@ public class RecordData {
private final List<FieldData> fieldDataList;
protected ByteBuffer valueHolder;
private Long computedTimestamp = null;
/**
* The computed timestamp consists of the running timestamp for this record, which may come from
* a timestamp field 253, or from a compressed timestamp, or simply be the same timestamp as the
* previously seen sample. This does not take into account sample-specific timestamps such as
* timestamp16.
*/
public Long computedTimestamp = null;
public RecordData(final RecordDefinition recordDefinition, final RecordHeader recordHeader) {
if (null == recordDefinition.getFieldDefinitions())

View File

@ -75,16 +75,15 @@ public class FitMonitoring extends RecordData {
// manual changes below
@Override
public Long getComputedTimestamp() {
public Long computeTimestamp(final Long lastMonitoringTimestamp) {
final Integer timestamp16 = getTimestamp16();
final Long computedTimestamp = super.getComputedTimestamp();
if (timestamp16 != null && computedTimestamp != null) {
return (long) GarminTimeUtils.garminTimestampToUnixTime(
(GarminTimeUtils.unixTimeToGarminTimestamp(computedTimestamp.intValue()) & ~0xFFFF) | (timestamp16 & 0xFFFF)
);
if (timestamp16 != null && lastMonitoringTimestamp != null) {
final int referenceGarminTs = GarminTimeUtils.unixTimeToGarminTimestamp(lastMonitoringTimestamp.intValue());
return (long) (lastMonitoringTimestamp.intValue() + ((timestamp16 - (referenceGarminTs & 0xffff)) & 0xffff));
}
return computedTimestamp;
return getComputedTimestamp();
}
public Optional<Integer> getComputedActivityType() {