diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java index db7c21fe5..2e4e12732 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthOverlayData.java @@ -4,6 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -44,18 +45,13 @@ class DatalogSessionHealthOverlayData extends DatalogSessionPebbleHealth { int recordCount = length / itemSize; OverlayRecord[] overlayRecords = new OverlayRecord[recordCount]; + byte[] tempRecord = new byte[itemSize]; for (int recordIdx = 0; recordIdx < recordCount; recordIdx++) { beginOfRecordPosition = initialPosition + recordIdx * itemSize; datalogMessage.position(beginOfRecordPosition);//we may not consume all the bytes of a record - recordVersion = datalogMessage.getShort(); - if ((recordVersion != 1) && (recordVersion != 3)) - return false;//we don't know how to deal with the data TODO: this is not ideal because we will get the same message again and again since we NACK it - - datalogMessage.getShort();//throwaway, unknown - recordType = datalogMessage.getShort(); - - overlayRecords[recordIdx] = new OverlayRecord(recordType, datalogMessage.getInt(), datalogMessage.getInt(), datalogMessage.getInt()); + datalogMessage.get(tempRecord); + overlayRecords[recordIdx] = new OverlayRecord(tempRecord); } store(overlayRecords); @@ -72,7 +68,7 @@ class DatalogSessionHealthOverlayData extends DatalogSessionPebbleHealth { List overlayList = new ArrayList<>(); for (OverlayRecord overlayRecord : overlayRecords) { - overlayList.add(new PebbleHealthActivityOverlay(overlayRecord.timestampStart, overlayRecord.timestampStart + overlayRecord.durationSeconds, overlayRecord.type, deviceId, userId, null)); + overlayList.add(new PebbleHealthActivityOverlay(overlayRecord.timestampStart, overlayRecord.timestampStart + overlayRecord.durationSeconds, overlayRecord.type, deviceId, userId, overlayRecord.rawData)); } overlayDao.insertOrReplaceInTx(overlayList); } catch (Exception ex) { @@ -81,16 +77,26 @@ class DatalogSessionHealthOverlayData extends DatalogSessionPebbleHealth { } private class OverlayRecord { + byte[] knownVersions = {1, 3}; + short version; int type; //1=sleep, 2=deep sleep int offsetUTC; //probably int timestampStart; int durationSeconds; + byte[] rawData; - public OverlayRecord(int type, int offsetUTC, int timestampStart, int durationSeconds) { - this.type = type; - this.offsetUTC = offsetUTC; - this.timestampStart = timestampStart; - this.durationSeconds = durationSeconds; + public OverlayRecord(byte[] rawData) { + this.rawData = rawData; + ByteBuffer record = ByteBuffer.wrap(rawData); + record.order(ByteOrder.LITTLE_ENDIAN); + + this.version = record.getShort(); + //TODO: check supported versions? + record.getShort();//throwaway, unknown + this.type = record.getShort(); + this.offsetUTC = record.getInt(); + this.timestampStart = record.getInt(); + this.durationSeconds = record.getInt(); } } } \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java index 5115be5b5..7fca543eb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSleep.java @@ -4,6 +4,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -43,18 +44,14 @@ class DatalogSessionHealthSleep extends DatalogSessionPebbleHealth { int recordCount = length / itemSize; SleepRecord[] sleepRecords = new SleepRecord[recordCount]; + byte[] tempRecord = new byte[itemSize]; for (int recordIdx = 0; recordIdx < recordCount; recordIdx++) { beginOfRecordPosition = initialPosition + recordIdx * itemSize; datalogMessage.position(beginOfRecordPosition);//we may not consume all the bytes of a record - recordVersion = datalogMessage.getShort(); - if (recordVersion != 1) - return false;//we don't know how to deal with the data TODO: this is not ideal because we will get the same message again and again since we NACK it + datalogMessage.get(tempRecord); - sleepRecords[recordIdx] = new SleepRecord(datalogMessage.getInt(), - datalogMessage.getInt(), - datalogMessage.getInt(), - datalogMessage.getInt()); + sleepRecords[recordIdx] = new SleepRecord(tempRecord); } store(sleepRecords); @@ -71,7 +68,8 @@ class DatalogSessionHealthSleep extends DatalogSessionPebbleHealth { List overlayList = new ArrayList<>(); for (SleepRecord sleepRecord : sleepRecords) { - overlayList.add(new PebbleHealthActivityOverlay(sleepRecord.bedTimeStart, sleepRecord.bedTimeEnd, sleepRecord.type, deviceId, userId, null)); + //TODO: check the firmware version and don't use the sleep record if overlay is available? + overlayList.add(new PebbleHealthActivityOverlay(sleepRecord.bedTimeStart, sleepRecord.bedTimeEnd, sleepRecord.type, deviceId, userId, sleepRecord.rawData)); } overlayDao.insertOrReplaceInTx(overlayList); } catch (Exception ex) { @@ -80,17 +78,27 @@ class DatalogSessionHealthSleep extends DatalogSessionPebbleHealth { } private class SleepRecord { + byte[] knownVersions = {1}; + short version; int type = 1; //sleep, hardcoded as we don't get other info int offsetUTC; //probably int bedTimeStart; int bedTimeEnd; int deepSleepSeconds; + byte[] rawData; - public SleepRecord(int offsetUTC, int bedTimeStart, int bedTimeEnd, int deepSleepSeconds) { - this.offsetUTC = offsetUTC; - this.bedTimeStart = bedTimeStart; - this.bedTimeEnd = bedTimeEnd; - this.deepSleepSeconds = deepSleepSeconds; + public SleepRecord(byte[] rawData) { + this.rawData = rawData; + ByteBuffer record = ByteBuffer.wrap(rawData); + record.order(ByteOrder.LITTLE_ENDIAN); + + + this.version = record.getShort(); + //TODO: check supported versions? + this.offsetUTC = record.getInt(); + this.bedTimeStart = record.getInt(); + this.bedTimeEnd = record.getInt(); + this.deepSleepSeconds = record.getInt(); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java index f6b661c3c..ef85faba3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/DatalogSessionHealthSteps.java @@ -5,6 +5,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -59,10 +60,12 @@ public class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth { beginOfRecordPosition = datalogMessage.position(); StepsRecord[] stepsRecords = new StepsRecord[recordNum]; + byte[] tempRecord = new byte[recordLength]; for (int recordIdx = 0; recordIdx < recordNum; recordIdx++) { datalogMessage.position(beginOfRecordPosition + recordIdx * recordLength); //we may not consume all the bytes of a record - stepsRecords[recordIdx] = new StepsRecord(timestamp, datalogMessage.get() & 0xff, datalogMessage.get() & 0xff, datalogMessage.getShort() & 0xffff, datalogMessage.get() & 0xff); + datalogMessage.get(tempRecord); + stepsRecords[recordIdx] = new StepsRecord(timestamp, recordVersion, tempRecord); timestamp += 60; } @@ -84,7 +87,7 @@ public class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth { samples[j] = new PebbleHealthActivitySample( stepsRecord.timestamp, userId, deviceId, - null, // raw data here + stepsRecord.rawData, stepsRecord.intensity, stepsRecord.steps ); @@ -98,18 +101,28 @@ public class DatalogSessionHealthSteps extends DatalogSessionPebbleHealth { } private class StepsRecord { + byte[] knownVersions = {5, 6}; + short version; int timestamp; int steps; int orientation; int intensity; int light_intensity; + byte[] rawData; - public StepsRecord(int timestamp, int steps, int orientation, int intensity, int light_intensity) { + public StepsRecord(int timestamp, short version, byte[] rawData) { this.timestamp = timestamp; - this.steps = steps; - this.orientation = orientation; - this.intensity = intensity; - this.light_intensity = light_intensity; + this.rawData = rawData; + ByteBuffer record = ByteBuffer.wrap(rawData); + record.order(ByteOrder.LITTLE_ENDIAN); + + this.version = version; + //TODO: check supported versions? + + this.steps = record.get() & 0xff; + this.orientation = record.get() & 0xff; + this.intensity = record.getShort() & 0xffff; + this.light_intensity = record.get() & 0xff; } }