1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-24 02:46:50 +01:00

Refactor database / sample access (#206)

We now have separate tables for each provider's samples but a common interface.
This commit is contained in:
Andreas Shimokawa 2016-07-27 23:34:13 +02:00
parent bce7a6c406
commit 8ea29e6e1d
12 changed files with 181 additions and 147 deletions

View File

@ -34,7 +34,7 @@ public class GBDaoGenerator {
private static final String VALID_BY_DATE = MODEL_PACKAGE + ".ValidByDate"; private static final String VALID_BY_DATE = MODEL_PACKAGE + ".ValidByDate";
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Schema schema = new Schema(8, MAIN_PACKAGE + ".entities"); Schema schema = new Schema(9, MAIN_PACKAGE + ".entities");
addActivityDescription(schema); addActivityDescription(schema);
@ -139,9 +139,7 @@ public class GBDaoGenerator {
} }
private static void addHeartRateProperties(Entity activitySample) { private static void addHeartRateProperties(Entity activitySample) {
activitySample.addImport(MODEL_PACKAGE + ".HeartRateSample"); activitySample.addIntProperty("heartRate").notNull();
activitySample.implementsInterface("HeartRateSample");
activitySample.addIntProperty("heartRate");
} }
private static Entity addPebbleActivitySample(Schema schema, Entity user, Entity device) { private static Entity addPebbleActivitySample(Schema schema, Entity user, Entity device) {
@ -163,9 +161,7 @@ public class GBDaoGenerator {
private static void addCommonActivitySampleProperties(String superClass, Entity activitySample, Entity user, Entity device) { private static void addCommonActivitySampleProperties(String superClass, Entity activitySample, Entity user, Entity device) {
activitySample.setSuperclass(superClass); activitySample.setSuperclass(superClass);
activitySample.addImport(MODEL_PACKAGE + ".ActivitySample");
activitySample.addImport(MAIN_PACKAGE + ".devices.SampleProvider"); activitySample.addImport(MAIN_PACKAGE + ".devices.SampleProvider");
activitySample.implementsInterface("ActivitySample");
activitySample.setJavaDoc( activitySample.setJavaDoc(
"This class represents a sample specific to the device. Values like activity kind or\n" + "This class represents a sample specific to the device. Values like activity kind or\n" +
"intensity, are device specific. Normalized values can be retrieved through the\n" + "intensity, are device specific. Normalized values can be retrieved through the\n" +

View File

@ -49,7 +49,6 @@ import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.HeartRateSample;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
@ -465,13 +464,13 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
colors.add(akActivity.color); colors.add(akActivity.color);
} }
activityEntries.add(createBarEntry(value, i)); activityEntries.add(createBarEntry(value, i));
if (hr && isValidHeartRateValue(((HeartRateSample)sample).getHeartRate())) { if (hr && isValidHeartRateValue(sample.getHeartRate())) {
if (lastHrSampleIndex > -1 && i - lastHrSampleIndex > HeartRateUtils.MAX_HR_MEASUREMENTS_GAP_MINUTES) { if (lastHrSampleIndex > -1 && i - lastHrSampleIndex > HeartRateUtils.MAX_HR_MEASUREMENTS_GAP_MINUTES) {
heartrateEntries.add(createLineEntry(0, lastHrSampleIndex + 1)); heartrateEntries.add(createLineEntry(0, lastHrSampleIndex + 1));
heartrateEntries.add(createLineEntry(0, i - 1)); heartrateEntries.add(createLineEntry(0, i - 1));
} }
heartrateEntries.add(createLineEntry(((HeartRateSample)sample).getHeartRate(), i)); heartrateEntries.add(createLineEntry(sample.getHeartRate(), i));
lastHrSampleIndex = i; lastHrSampleIndex = i;
} }

View File

@ -30,7 +30,6 @@ import nodomain.freeyourgadget.gadgetbridge.entities.UserAttributes;
import nodomain.freeyourgadget.gadgetbridge.entities.UserDao; import nodomain.freeyourgadget.gadgetbridge.entities.UserDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.HeartRateSample;
import nodomain.freeyourgadget.gadgetbridge.model.ValidByDate; import nodomain.freeyourgadget.gadgetbridge.model.ValidByDate;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
@ -383,9 +382,7 @@ public class DBHelper {
newSample.setSteps(cursor.getInt(colSteps)); newSample.setSteps(cursor.getInt(colSteps));
int hrValue = cursor.getInt(colCustomShort); int hrValue = cursor.getInt(colCustomShort);
if (newSample instanceof HeartRateSample) { newSample.setHeartRate(hrValue);
((HeartRateSample)newSample).setHeartRate(hrValue);
}
newSamples.add(newSample); newSamples.add(newSample);
} }
sampleProvider.getSampleDao().insertOrReplaceInTx(newSamples, true); sampleProvider.getSampleDao().insertOrReplaceInTx(newSamples, true);

View File

@ -1,30 +1,10 @@
package nodomain.freeyourgadget.gadgetbridge.database; package nodomain.freeyourgadget.gadgetbridge.database;
import android.content.Context; import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.database.schema.SchemaMigration; import nodomain.freeyourgadget.gadgetbridge.database.schema.SchemaMigration;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster; import nodomain.freeyourgadget.gadgetbridge.entities.DaoMaster;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.HeartRateSample;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_CUSTOM_SHORT;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_INTENSITY;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_STEPS;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_TIMESTAMP;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.KEY_TYPE;
import static nodomain.freeyourgadget.gadgetbridge.database.DBConstants.TABLE_GBACTIVITYSAMPLES;
public class DBOpenHelper extends DaoMaster.OpenHelper { public class DBOpenHelper extends DaoMaster.OpenHelper {
private final String updaterClassNamePrefix; private final String updaterClassNamePrefix;
@ -38,11 +18,13 @@ public class DBOpenHelper extends DaoMaster.OpenHelper {
@Override @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
DaoMaster.createAllTables(db, true);
new SchemaMigration(updaterClassNamePrefix).onUpgrade(db, oldVersion, newVersion); new SchemaMigration(updaterClassNamePrefix).onUpgrade(db, oldVersion, newVersion);
} }
@Override @Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
DaoMaster.createAllTables(db, true);
new SchemaMigration(updaterClassNamePrefix).onDowngrade(db, oldVersion, newVersion); new SchemaMigration(updaterClassNamePrefix).onDowngrade(db, oldVersion, newVersion);
} }

View File

@ -1,18 +1,30 @@
package nodomain.freeyourgadget.gadgetbridge.devices.pebble; package nodomain.freeyourgadget.gadgetbridge.devices.pebble;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.Property;
import de.greenrobot.dao.query.QueryBuilder;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSample;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class MisfitSampleProvider implements SampleProvider { public class MisfitSampleProvider implements SampleProvider<PebbleMisfitSample> {
private final DaoSession mSession;
private final GBDevice mDevice;
protected final float movementDivisor = 300f; protected final float movementDivisor = 300f;
public MisfitSampleProvider(GBDevice device, DaoSession session) { public MisfitSampleProvider(GBDevice device, DaoSession session) {
mSession = session;
mDevice = device;
} }
@Override @Override
@ -22,7 +34,7 @@ public class MisfitSampleProvider implements SampleProvider {
@Override @Override
public int toRawActivityKind(int activityKind) { public int toRawActivityKind(int activityKind) {
return (byte) activityKind; return activityKind;
} }
@Override @Override
@ -31,47 +43,7 @@ public class MisfitSampleProvider implements SampleProvider {
} }
@Override @Override
public List getAllActivitySamples(int timestamp_from, int timestamp_to) { public PebbleMisfitSample createActivitySample() {
return null;
}
@Override
public List getActivitySamples(int timestamp_from, int timestamp_to) {
return null;
}
@Override
public List getSleepSamples(int timestamp_from, int timestamp_to) {
return null;
}
@Override
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int kind) {
}
@Override
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind) {
}
@Override
public int fetchLatestTimestamp() {
return 0;
}
@Override
public void addGBActivitySample(AbstractActivitySample activitySample) {
}
@Override
public void addGBActivitySamples(AbstractActivitySample[] activitySamples) {
}
@Override
public AbstractActivitySample createActivitySample() {
return null; return null;
} }
@ -79,4 +51,83 @@ public class MisfitSampleProvider implements SampleProvider {
public int getID() { public int getID() {
return SampleProvider.PROVIDER_PEBBLE_MISFIT; return SampleProvider.PROVIDER_PEBBLE_MISFIT;
} }
@Override
public List<PebbleMisfitSample> getAllActivitySamples(int timestamp_from, int timestamp_to) {
return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ALL);
}
@Override
public List<PebbleMisfitSample> getActivitySamples(int timestamp_from, int timestamp_to) {
return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ACTIVITY);
}
@Override
public List<PebbleMisfitSample> getSleepSamples(int timestamp_from, int timestamp_to) {
return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_SLEEP);
}
@Override
public int fetchLatestTimestamp() {
QueryBuilder<PebbleMisfitSample> qb = getSampleDao().queryBuilder();
qb.orderDesc(getTimestampSampleProperty());
qb.limit(1);
List<PebbleMisfitSample> list = qb.build().list();
if (list.size() >= 1) {
return list.get(0).getTimestamp();
}
return -1;
}
@Override
public void addGBActivitySample(PebbleMisfitSample activitySample) {
getSampleDao().insertOrReplace(activitySample);
}
@Override
public void addGBActivitySamples(PebbleMisfitSample[] activitySamples) {
getSampleDao().insertOrReplaceInTx(activitySamples);
}
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int kind) {
}
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind) {
}
protected List<PebbleMisfitSample> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) {
QueryBuilder<PebbleMisfitSample> qb = getSampleDao().queryBuilder();
Property timestampProperty = getTimestampSampleProperty();
Device dbDevice = DBHelper.findDevice(mDevice, mSession);
if (dbDevice == null) {
// no device, no samples
return Collections.emptyList();
}
Property deviceProperty = getDeviceIdentifierSampleProperty();
qb.where(deviceProperty.eq(dbDevice.getId()), timestampProperty.ge(timestamp_from))
.where(timestampProperty.le(timestamp_to));
List<PebbleMisfitSample> samples = qb.build().list();
List<PebbleMisfitSample> filteredSamples = new ArrayList<>();
for (PebbleMisfitSample sample : samples) {
if ((sample.getRawKind() & activityType) != 0) {
sample.setProvider(this);
filteredSamples.add(sample);
}
}
return filteredSamples;
}
public AbstractDao<PebbleMisfitSample, ?> getSampleDao() {
return mSession.getPebbleMisfitSampleDao();
}
protected Property getTimestampSampleProperty() {
return PebbleMisfitSampleDao.Properties.Timestamp;
}
protected Property getDeviceIdentifierSampleProperty() {
return PebbleMisfitSampleDao.Properties.DeviceId;
}
} }

View File

@ -21,33 +21,61 @@ public abstract class AbstractActivitySample implements ActivitySample {
return getProvider().normalizeType(getRawKind()); return getProvider().normalizeType(getRawKind());
} }
@Override
public int getRawKind() {
return NOT_MEASURED;
}
@Override @Override
public float getIntensity() { public float getIntensity() {
return getProvider().normalizeIntensity(getRawIntensity()); return getProvider().normalizeIntensity(getRawIntensity());
} }
public abstract void setRawKind(int kind); public void setRawKind(int kind) {
}
public abstract void setRawIntensity(int intensity); public void setRawIntensity(int intensity) {
}
public abstract void setSteps(int steps); public void setSteps(int steps) {
}
public abstract void setTimestamp(int timestamp); public abstract void setTimestamp(int timestamp);
public abstract void setUserId(Long userId); public abstract void setUserId(Long userId);
public abstract Long getUserId(); @Override
public void setHeartRate(int heartRate) {
}
@Override
public int getHeartRate() {
return NOT_MEASURED;
}
public abstract void setDeviceId(Long deviceId); public abstract void setDeviceId(Long deviceId);
public abstract Long getDeviceId(); public abstract Long getDeviceId();
public abstract Long getUserId();
@Override
public int getRawIntensity() {
return NOT_MEASURED;
}
@Override
public int getSteps() {
return NOT_MEASURED;
}
@Override @Override
public String toString() { public String toString() {
return getClass().getSimpleName() + "{" + return getClass().getSimpleName() + "{" +
"timestamp=" + DateTimeUtils.formatDateTime(DateTimeUtils.parseTimeStamp(getTimestamp())) + "timestamp=" + DateTimeUtils.formatDateTime(DateTimeUtils.parseTimeStamp(getTimestamp())) +
", intensity=" + getIntensity() + ", intensity=" + getIntensity() +
", steps=" + getSteps() + ", steps=" + getSteps() +
", heartrate=" + getHeartRate() +
", type=" + getKind() + ", type=" + getKind() +
", userId=" + getUserId() + ", userId=" + getUserId() +
", deviceId=" + getDeviceId() + ", deviceId=" + getDeviceId() +

View File

@ -13,7 +13,7 @@ public class GBActivitySample implements ActivitySample {
private final int intensity; private final int intensity;
private final int steps; private final int steps;
private final int type; private final int type;
private final int customValue; private int customValue;
public GBActivitySample(SampleProvider provider, int timestamp, int intensity, int steps, int type) { public GBActivitySample(SampleProvider provider, int timestamp, int intensity, int steps, int type) {
this(provider, timestamp, intensity, steps, type, 0); this(provider, timestamp, intensity, steps, type, 0);
@ -69,6 +69,16 @@ public class GBActivitySample implements ActivitySample {
return steps; return steps;
} }
@Override
public int getHeartRate() {
return customValue;
}
@Override
public void setHeartRate(int value) {
customValue = value;
}
@Override @Override
public int getRawKind() { public int getRawKind() {
return type; return type;

View File

@ -5,6 +5,7 @@ import java.util.Arrays;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
public class ActivityKind { public class ActivityKind {
public static final int TYPE_NOT_MEASURED = -1;
public static final int TYPE_UNKNOWN = 0; public static final int TYPE_UNKNOWN = 0;
public static final int TYPE_ACTIVITY = 1; public static final int TYPE_ACTIVITY = 1;
public static final int TYPE_LIGHT_SLEEP = 2; public static final int TYPE_LIGHT_SLEEP = 2;

View File

@ -1,6 +1,18 @@
package nodomain.freeyourgadget.gadgetbridge.model; package nodomain.freeyourgadget.gadgetbridge.model;
public interface ActivitySample extends Sample { import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
public interface ActivitySample extends TimeStamped {
int NOT_MEASURED = -1;
/**
* Returns the provider of the data.
*
* @return who created the sample data
*/
SampleProvider getProvider();
/** /**
* Returns the raw activity kind value as recorded by the SampleProvider * Returns the raw activity kind value as recorded by the SampleProvider
*/ */
@ -27,4 +39,21 @@ public interface ActivitySample extends Sample {
* Returns the number of steps performed during the period of this sample * Returns the number of steps performed during the period of this sample
*/ */
int getSteps(); int getSteps();
/**
* Returns the heart rate measured at the corresponding timestamp.
* The value is returned in heart beats per minute, in the range from
* 0-255, where 255 is an illegal value (e.g. due to a bad measurement)
*
* @return the heart rate value in beats per minute, or -1 if none
*/
int getHeartRate();
/**
* Sets the heart rate value of this sample. Typically only used in
* generic db migration.
*
* @param value the value in bpm
*/
void setHeartRate(int value);
} }

View File

@ -1,18 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.model;
public interface HeartRateSample extends Sample {
/**
* Returns the heart rate measured at the corresponding timestamp.
* The value is returned in heart beats per minute, in the range from
* 0-255, where 255 is an illegal value (e.g. due to a bad measurement)
* @return the heart rate value in beats per minute, or null if none
*/
Integer getHeartRate();
/**
* Sets the heart rate value of this sample. Typically only used in
* generic db migration.
* @param value the value in bpm
*/
void setHeartRate(Integer value);
}

View File

@ -1,12 +0,0 @@
package nodomain.freeyourgadget.gadgetbridge.model;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
public interface Sample extends TimeStamped {
/**
* Returns the provider of the data.
*
* @return who created the sample data
*/
SampleProvider getProvider();
}

View File

@ -18,10 +18,8 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.MisfitSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.pebble.MisfitSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSample; import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs; import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
public class AppMessageHandlerMisfit extends AppMessageHandler { public class AppMessageHandlerMisfit extends AppMessageHandler {
@ -78,7 +76,6 @@ public class AppMessageHandlerMisfit extends AppMessageHandler {
LOG.info("got data from " + startDate + " to " + endDate); LOG.info("got data from " + startDate + " to " + endDate);
int totalSteps = 0; int totalSteps = 0;
PebbleActivitySample[] activitySamples = new PebbleActivitySample[samples];
PebbleMisfitSample[] misfitSamples = new PebbleMisfitSample[samples]; PebbleMisfitSample[] misfitSamples = new PebbleMisfitSample[samples];
try (DBHandler db = GBApplication.acquireDB()) { try (DBHandler db = GBApplication.acquireDB()) {
MisfitSampleProvider sampleProvider = new MisfitSampleProvider(device, db.getDaoSession()); MisfitSampleProvider sampleProvider = new MisfitSampleProvider(device, db.getDaoSession());
@ -86,42 +83,16 @@ public class AppMessageHandlerMisfit extends AppMessageHandler {
Long deviceId = DBHelper.getDevice(getDevice(), db.getDaoSession()).getId(); Long deviceId = DBHelper.getDevice(getDevice(), db.getDaoSession()).getId();
for (int i = 0; i < samples; i++) { for (int i = 0; i < samples; i++) {
short sample = buf.getShort(); short sample = buf.getShort();
int steps = 0; misfitSamples[i] = new PebbleMisfitSample(null, sample & 0xffff, timestamp + i * 60, userId, deviceId);
int intensity = 0; misfitSamples[i].setProvider(sampleProvider);
int activityKind = ActivityKind.TYPE_UNKNOWN; int steps = misfitSamples[i].getSteps();
if (((sample & 0x83ff) == 0x0001) && ((sample & 0xff00) <= 0x4800)) {
// sleep seems to be from 0x2401 to 0x4801 (0b0IIIII0000000001) where I = intensity ?
intensity = (sample & 0x7c00) >>> 10;
// 9-18 decimal after shift
if (intensity <= 13) {
activityKind = ActivityKind.TYPE_DEEP_SLEEP;
} else {
// FIXME: this leads to too much false positives, ignore for now
//activityKind = ActivityKind.TYPE_LIGHT_SLEEP;
//intensity *= 2; // better visual distinction
}
} else {
if ((sample & 0x0001) == 0) { // 16-??? steps encoded in bits 1-7
steps = (sample & 0x00fe);
} else { // 0-14 steps encoded in bits 1-3, most of the time fc71 bits are set in that case
steps = (sample & 0x000e);
}
intensity = steps;
activityKind = ActivityKind.TYPE_ACTIVITY;
}
totalSteps += steps; totalSteps += steps;
LOG.info("got steps for sample " + i + " : " + steps + "(" + Integer.toHexString(sample & 0xffff) + ")"); LOG.info("got steps for sample " + i + " : " + steps + "(" + Integer.toHexString(sample & 0xffff) + ")");
//activitySamples[i] = new PebbleActivitySample(null, timestamp + i * 60, intensity, steps, activityKind, userId, deviceId);
//activitySamples[i].setProvider(sampleProvider);
misfitSamples[i] = new PebbleMisfitSample(null, sample & 0xffff, timestamp + i * 60, userId, deviceId);
misfitSamples[i].setProvider(sampleProvider);
} }
LOG.info("total steps for above period: " + totalSteps); LOG.info("total steps for above period: " + totalSteps);
sampleProvider.addGBActivitySamples(activitySamples); sampleProvider.addGBActivitySamples(misfitSamples);
} catch (Exception e) { } catch (Exception e) {
LOG.error("Error acquiring database", e); LOG.error("Error acquiring database", e);
return null; return null;