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

View File

@ -26,7 +26,13 @@ public class RecordData {
private final List<FieldData> fieldDataList; private final List<FieldData> fieldDataList;
protected ByteBuffer valueHolder; 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) { public RecordData(final RecordDefinition recordDefinition, final RecordHeader recordHeader) {
if (null == recordDefinition.getFieldDefinitions()) if (null == recordDefinition.getFieldDefinitions())

View File

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