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:
parent
bce7a6c406
commit
8ea29e6e1d
@ -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" +
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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() +
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
@ -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();
|
|
||||||
}
|
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user