More WIP, but we're getting closer

current state:
- storing samples works (tested only mi band)
- charts work
master
cpfeiffer 2016-05-16 23:00:04 +02:00
parent 6e44ddaee6
commit 3e0bc16741
25 changed files with 319 additions and 281 deletions

View File

@ -57,10 +57,10 @@ public class GBApplication extends Application {
//if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version //if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below; see http://stackoverflow.com/questions/16397848/how-can-i-migrate-android-preferences-with-a-new-version
private static final int CURRENT_PREFS_VERSION = 2; private static final int CURRENT_PREFS_VERSION = 2;
private static LimitedQueue mIDSenderLookup = new LimitedQueue(16); private static LimitedQueue mIDSenderLookup = new LimitedQueue(16);
private static DaoSession daoSession;
private static Appender<ILoggingEvent> fileLogger; private static Appender<ILoggingEvent> fileLogger;
private static Prefs prefs; private static Prefs prefs;
private static GBPrefs gbPrefs; private static GBPrefs gbPrefs;
private static DBHandler lockHandler;
public static final String ACTION_QUIT public static final String ACTION_QUIT
= "nodomain.freeyourgadget.gadgetbridge.gbapplication.action.quit"; = "nodomain.freeyourgadget.gadgetbridge.gbapplication.action.quit";
@ -206,11 +206,7 @@ public class GBApplication extends Application {
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "test-db", null); DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "test-db", null);
SQLiteDatabase db = helper.getWritableDatabase(); SQLiteDatabase db = helper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(db); DaoMaster daoMaster = new DaoMaster(db);
daoSession = daoMaster.newSession(); lockHandler = new LockHandler(daoMaster.newSession());
}
public static DaoSession getDaoSession() {
return daoSession;
} }
public static Context getContext() { public static Context getContext() {
@ -238,10 +234,10 @@ public class GBApplication extends Application {
* @see #releaseDB() * @see #releaseDB()
*/ */
public static DBHandler acquireDB() throws GBException { public static DBHandler acquireDB() throws GBException {
// TODO: implement locking with greendao?
try { try {
if (dbLock.tryLock(30, TimeUnit.SECONDS)) { if (dbLock.tryLock(30, TimeUnit.SECONDS)) {
return mActivityDatabaseHandler; return lockHandler;
// return mActivityDatabaseHandler;
} }
} catch (InterruptedException ex) { } catch (InterruptedException ex) {
Log.i(TAG, "Interrupted while waiting for DB lock"); Log.i(TAG, "Interrupted while waiting for DB lock");

View File

@ -1,12 +1,15 @@
package nodomain.freeyourgadget.gadgetbridge.database; package nodomain.freeyourgadget.gadgetbridge;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
import java.util.List; import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
/** /**
@ -15,13 +18,19 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
*/ */
public class LockHandler implements DBHandler { public class LockHandler implements DBHandler {
@Override private final DaoSession session;
public void release() {
public LockHandler(DaoSession daoSession) {
session = daoSession;
} }
@Override @Override
public void close() { public void close() {
GBApplication.releaseDB();
}
@Override
public void closeDb() {
} }
@ -32,22 +41,31 @@ public class LockHandler implements DBHandler {
@Override @Override
public List<ActivitySample> getAllActivitySamples(int tsFrom, int tsTo, SampleProvider provider) { public List<ActivitySample> getAllActivitySamples(int tsFrom, int tsTo, SampleProvider provider) {
return null; return provider.getAllActivitySamples(tsFrom, tsTo);
} }
@Override @Override
public List<ActivitySample> getActivitySamples(int tsFrom, int tsTo, SampleProvider provider) { public List<ActivitySample> getActivitySamples(int tsFrom, int tsTo, SampleProvider provider) {
return null; return provider.getActivitySamples(tsFrom, tsTo);
} }
@Override @Override
public List<ActivitySample> getSleepSamples(int tsFrom, int tsTo, SampleProvider provider) { public List<ActivitySample> getSleepSamples(int tsFrom, int tsTo, SampleProvider provider) {
return null; return provider.getSleepSamples(tsFrom, tsTo);
}
@Override
public int fetchLatestTimestamp(SampleProvider provider) {
return provider.fetchLatestTimestamp();
}
@Override
public DaoSession getDaoSession() {
return session;
} }
@Override @Override
public void addGBActivitySample(AbstractActivitySample sample) { public void addGBActivitySample(AbstractActivitySample sample) {
} }
@Override @Override
@ -69,9 +87,4 @@ public class LockHandler implements DBHandler {
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind, SampleProvider provider) { public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind, SampleProvider provider) {
} }
@Override
public int fetchLatestTimestamp(SampleProvider provider) {
return 0;
}
} }

View File

@ -237,19 +237,13 @@ public class DebugActivity extends GBActivity {
} }
private void exportDB() { private void exportDB() {
DBHandler dbHandler = null; try (DBHandler dbHandler = GBApplication.acquireDB()) {
try {
dbHandler = GBApplication.acquireDB();
DBHelper helper = new DBHelper(this); DBHelper helper = new DBHelper(this);
File dir = FileUtils.getExternalFilesDir(); File dir = FileUtils.getExternalFilesDir();
File destFile = helper.exportDB(dbHandler.getHelper(), dir); File destFile = helper.exportDB(dbHandler.getHelper(), dir);
GB.toast(this, "Exported to: " + destFile.getAbsolutePath(), Toast.LENGTH_LONG, GB.INFO); GB.toast(this, "Exported to: " + destFile.getAbsolutePath(), Toast.LENGTH_LONG, GB.INFO);
} catch (Exception ex) { } catch (Exception ex) {
GB.toast(this, "Error exporting DB: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex); GB.toast(this, "Error exporting DB: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex);
} finally {
if (dbHandler != null) {
dbHandler.release();
}
} }
} }
@ -261,9 +255,7 @@ public class DebugActivity extends GBActivity {
.setPositiveButton("Overwrite", new DialogInterface.OnClickListener() { .setPositiveButton("Overwrite", new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
DBHandler dbHandler = null; try (DBHandler dbHandler = GBApplication.acquireDB()) {
try {
dbHandler = GBApplication.acquireDB();
DBHelper helper = new DBHelper(DebugActivity.this); DBHelper helper = new DBHelper(DebugActivity.this);
File dir = FileUtils.getExternalFilesDir(); File dir = FileUtils.getExternalFilesDir();
SQLiteOpenHelper sqLiteOpenHelper = dbHandler.getHelper(); SQLiteOpenHelper sqLiteOpenHelper = dbHandler.getHelper();
@ -273,10 +265,6 @@ public class DebugActivity extends GBActivity {
GB.toast(DebugActivity.this, "Import successful.", Toast.LENGTH_LONG, GB.INFO); GB.toast(DebugActivity.this, "Import successful.", Toast.LENGTH_LONG, GB.INFO);
} catch (Exception ex) { } catch (Exception ex) {
GB.toast(DebugActivity.this, "Error importing DB: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex); GB.toast(DebugActivity.this, "Error importing DB: " + ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex);
} finally {
if (dbHandler != null) {
dbHandler.release();
}
} }
} }
}) })

View File

@ -20,8 +20,4 @@ public class GBActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
} }
protected DaoSession getDAOSession() {
return GBApplication.getDaoSession();
}
} }

View File

@ -293,9 +293,9 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
return akActivity.color; return akActivity.color;
} }
protected SampleProvider getProvider(GBDevice device) { protected SampleProvider getProvider(DBHandler db, GBDevice device) {
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device); DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(device);
return coordinator.getSampleProvider(); return coordinator.getSampleProvider(db);
} }
/** /**
@ -307,7 +307,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
* @param tsTo * @param tsTo
*/ */
protected List<ActivitySample> getAllSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) { protected List<ActivitySample> getAllSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
SampleProvider provider = getProvider(device); SampleProvider provider = getProvider(db, device);
return db.getAllActivitySamples(tsFrom, tsTo, provider); return db.getAllActivitySamples(tsFrom, tsTo, provider);
} }
@ -316,13 +316,13 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
} }
protected List<ActivitySample> getActivitySamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) { protected List<ActivitySample> getActivitySamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
SampleProvider provider = getProvider(device); SampleProvider provider = getProvider(db, device);
return db.getActivitySamples(tsFrom, tsTo, provider); return db.getActivitySamples(tsFrom, tsTo, provider);
} }
protected List<ActivitySample> getSleepSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) { protected List<ActivitySample> getSleepSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
SampleProvider provider = getProvider(device); SampleProvider provider = getProvider(db, device);
return db.getSleepSamples(tsFrom, tsTo, provider); return db.getSleepSamples(tsFrom, tsTo, provider);
} }
@ -334,7 +334,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
tsTo = (int) ((cal.getTimeInMillis() / 1000)); tsTo = (int) ((cal.getTimeInMillis() / 1000));
tsFrom = tsTo - (24 * 60 * 60); tsFrom = tsTo - (24 * 60 * 60);
SampleProvider provider = getProvider(device); SampleProvider provider = getProvider(db, device);
return db.getAllActivitySamples(tsFrom, tsTo, provider); return db.getAllActivitySamples(tsFrom, tsTo, provider);
} }

View File

@ -18,6 +18,7 @@ import nodomain.freeyourgadget.gadgetbridge.database.schema.ActivityDBCreationSc
import nodomain.freeyourgadget.gadgetbridge.database.schema.SchemaMigration; import nodomain.freeyourgadget.gadgetbridge.database.schema.SchemaMigration;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample; import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
@ -155,13 +156,13 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl
} }
@Override @Override
public SQLiteOpenHelper getHelper() { public void closeDb() {
return this; GBApplication.releaseDB();
} }
@Override @Override
public void release() { public SQLiteOpenHelper getHelper() {
GBApplication.releaseDB(); return this;
} }
public ArrayList<ActivitySample> getAllActivitySamples(int timestamp_from, int timestamp_to, SampleProvider provider) { public ArrayList<ActivitySample> getAllActivitySamples(int timestamp_from, int timestamp_to, SampleProvider provider) {
@ -275,4 +276,9 @@ public class ActivityDatabaseHandler extends SQLiteOpenHelper implements DBHandl
} }
return -1; return -1;
} }
@Override
public DaoSession getDaoSession() {
return null;
}
} }

View File

@ -26,16 +26,10 @@ public abstract class DBAccess extends AsyncTask {
@Override @Override
protected Object doInBackground(Object[] params) { protected Object doInBackground(Object[] params) {
DBHandler handler = null; try (DBHandler db = GBApplication.acquireDB()) {
try { doInBackground(db);
handler = GBApplication.acquireDB();
doInBackground(handler);
} catch (Exception e) { } catch (Exception e) {
mError = e; mError = e;
} finally {
if (handler != null) {
handler.release();
}
} }
return null; return null;
} }

View File

@ -8,13 +8,14 @@ import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
public interface DBHandler { public interface DBHandler extends AutoCloseable {
/** /**
* Closes the database. * Closes the database.
*/ */
void close(); void closeDb();
SQLiteOpenHelper getHelper(); SQLiteOpenHelper getHelper();
@ -22,7 +23,7 @@ public interface DBHandler {
* Releases the DB handler. No access may be performed after calling this method. * Releases the DB handler. No access may be performed after calling this method.
* Same as calling {@link GBApplication#releaseDB()} * Same as calling {@link GBApplication#releaseDB()}
*/ */
void release(); void close() throws Exception;
List<ActivitySample> getAllActivitySamples(int tsFrom, int tsTo, SampleProvider provider); List<ActivitySample> getAllActivitySamples(int tsFrom, int tsTo, SampleProvider provider);
@ -42,4 +43,5 @@ public interface DBHandler {
int fetchLatestTimestamp(SampleProvider provider); int fetchLatestTimestamp(SampleProvider provider);
DaoSession getDaoSession();
} }

View File

@ -116,8 +116,7 @@ public class DBHelper {
return ""; return "";
} }
public static User getUser() { public static User getUser(DaoSession session) {
DaoSession session = GBApplication.getDaoSession();
UserDao userDao = session.getUserDao(); UserDao userDao = session.getUserDao();
List<User> users = userDao.loadAll(); List<User> users = userDao.loadAll();
if (users.isEmpty()) { if (users.isEmpty()) {
@ -148,8 +147,7 @@ public class DBHelper {
return user; return user;
} }
public static Device getDevice(GBDevice gbDevice) { public static Device getDevice(GBDevice gbDevice, DaoSession session) {
DaoSession session = GBApplication.getDaoSession();
DeviceDao deviceDao = session.getDeviceDao(); DeviceDao deviceDao = session.getDeviceDao();
Query<Device> query = deviceDao.queryBuilder().where(DeviceDao.Properties.Identifier.eq(gbDevice.getAddress())).build(); Query<Device> query = deviceDao.queryBuilder().where(DeviceDao.Properties.Identifier.eq(gbDevice.getAddress())).build();
List<Device> devices = query.list(); List<Device> devices = query.list();

View File

@ -16,7 +16,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
public abstract class AbstractSampleProvider<T extends ActivitySample> implements SampleProvider, DBHandler { public abstract class AbstractSampleProvider<T extends ActivitySample> implements SampleProvider {
private static final WhereCondition[] NO_CONDITIONS = new WhereCondition[0]; private static final WhereCondition[] NO_CONDITIONS = new WhereCondition[0];
private final DaoSession mSession; private final DaoSession mSession;
@ -28,47 +28,31 @@ public abstract class AbstractSampleProvider<T extends ActivitySample> implement
return mSession; return mSession;
} }
@Override
public List<T> getAllActivitySamples(int timestamp_from, int timestamp_to) { public List<T> getAllActivitySamples(int timestamp_from, int timestamp_to) {
return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ALL); return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ALL);
} }
@Override
public List<T> getActivitySamples(int timestamp_from, int timestamp_to) { public List<T> getActivitySamples(int timestamp_from, int timestamp_to) {
return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ACTIVITY); return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ACTIVITY);
} }
@Override
public List<T> getSleepSamples(int timestamp_from, int timestamp_to) { public List<T> getSleepSamples(int timestamp_from, int timestamp_to) {
return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_SLEEP); return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_SLEEP);
} }
@Override @Override
public void close() { public int fetchLatestTimestamp() {
// TESTING: NOOP QueryBuilder<T> qb = getSampleDao().queryBuilder();
} qb.orderDesc(MiBandActivitySampleDao.Properties.Timestamp);
qb.limit(1);
@Override List<T> list = qb.build().list();
public SQLiteOpenHelper getHelper() { if (list.size() >= 1) {
// TESTING: NOOP return list.get(0).getTimestamp();
return null; }
} return -1;
@Override
public void release() {
// TESTING: NOOP
}
@Override
public List<ActivitySample> getAllActivitySamples(int tsFrom, int tsTo, SampleProvider provider) {
return (List<ActivitySample>) getGBActivitySamples(tsFrom, tsTo, ActivityKind.TYPE_ALL);
}
@Override
public List<ActivitySample> getActivitySamples(int tsFrom, int tsTo, SampleProvider provider) {
return (List<ActivitySample>) getGBActivitySamples(tsFrom, tsTo, ActivityKind.TYPE_ACTIVITY);
}
@Override
public List<ActivitySample> getSleepSamples(int tsFrom, int tsTo, SampleProvider provider) {
return (List<ActivitySample>) getGBActivitySamples(tsFrom, tsTo, ActivityKind.TYPE_SLEEP);
} }
@Override @Override
@ -81,42 +65,77 @@ public abstract class AbstractSampleProvider<T extends ActivitySample> implement
getSampleDao().insertInTx((T[]) activitySamples); getSampleDao().insertInTx((T[]) activitySamples);
} }
@Override // @Override
public SQLiteDatabase getWritableDatabase() { // public void close() {
// TESTING: NOOP // // TESTING: NOOP
return null; // }
} //
// @Override
@Override // public SQLiteOpenHelper getHelper() {
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int kind, SampleProvider provider) { // // TESTING: NOOP
// return null;
} // }
//
@Override // @Override
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind, SampleProvider provider) { // public void release() {
// // TESTING: NOOP
} // }
//
@Override // @Override
public int fetchLatestTimestamp(SampleProvider provider) { // public List<ActivitySample> getAllActivitySamples(int tsFrom, int tsTo, SampleProvider provider) {
return 0; // return (List<ActivitySample>) getGBActivitySamples(tsFrom, tsTo, ActivityKind.TYPE_ALL);
} // }
//
// SQLiteDatabase getWritableDatabase(); // @Override
// public List<ActivitySample> getActivitySamples(int tsFrom, int tsTo, SampleProvider provider) {
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int kind) { // return (List<ActivitySample>) getGBActivitySamples(tsFrom, tsTo, ActivityKind.TYPE_ACTIVITY);
// TODO: implement // }
} //
// @Override
public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind) { // public List<ActivitySample> getSleepSamples(int tsFrom, int tsTo, SampleProvider provider) {
// TODO: implement // return (List<ActivitySample>) getGBActivitySamples(tsFrom, tsTo, ActivityKind.TYPE_SLEEP);
} // }
//
// @Override
// public SQLiteDatabase getWritableDatabase() {
// // TESTING: NOOP
// return null;
// }
//
// @Override
// public void changeStoredSamplesType(int timestampFrom, int timestampTo, int kind, SampleProvider provider) {
//
// }
//
// @Override
// public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind, SampleProvider provider) {
//
// }
//
// @Override
// public int fetchLatestTimestamp(SampleProvider provider) {
// return 0;
// }
//
//// SQLiteDatabase getWritableDatabase();
//
// public void changeStoredSamplesType(int timestampFrom, int timestampTo, int kind) {
// // TODO: implement
// }
//
// public void changeStoredSamplesType(int timestampFrom, int timestampTo, int fromKind, int toKind) {
// // TODO: implement
// }
protected List<T> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) { protected List<T> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) {
QueryBuilder<T> qb = getSampleDao().queryBuilder(); QueryBuilder<T> qb = getSampleDao().queryBuilder();
qb.where(MiBandActivitySampleDao.Properties.Timestamp.ge(timestamp_from)) qb.where(MiBandActivitySampleDao.Properties.Timestamp.ge(timestamp_from))
.where(MiBandActivitySampleDao.Properties.Timestamp.le(timestamp_to), getClauseForActivityType(qb, activityType)); .where(MiBandActivitySampleDao.Properties.Timestamp.le(timestamp_to), getClauseForActivityType(qb, activityType));
return qb.build().list(); List<T> samples = qb.build().list();
for (T sample : samples) {
((AbstractActivitySample) sample).setProvider(this);
}
return samples;
} }
private WhereCondition[] getClauseForActivityType(QueryBuilder qb, int activityTypes) { private WhereCondition[] getClauseForActivityType(QueryBuilder qb, int activityTypes) {
@ -153,16 +172,5 @@ public abstract class AbstractSampleProvider<T extends ActivitySample> implement
trailingConditions); trailingConditions);
} }
public int fetchLatestTimestamp() {
QueryBuilder<T> qb = getSampleDao().queryBuilder();
qb.orderDesc(MiBandActivitySampleDao.Properties.Timestamp);
qb.limit(1);
List<T> list = qb.build().list();
if (list.size() >= 1) {
return list.get(0).getTimestamp();
}
return -1;
}
protected abstract AbstractDao<T,?> getSampleDao(); protected abstract AbstractDao<T,?> getSampleDao();
} }

View File

@ -4,6 +4,7 @@ import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
@ -82,7 +83,7 @@ public interface DeviceCoordinator {
* *
* @return * @return
*/ */
SampleProvider getSampleProvider(); SampleProvider getSampleProvider(DBHandler db);
/** /**
* Finds an install handler for the given uri that can install the given * Finds an install handler for the given uri that can install the given

View File

@ -1,6 +1,11 @@
package nodomain.freeyourgadget.gadgetbridge.devices; package nodomain.freeyourgadget.gadgetbridge.devices;
public interface SampleProvider { import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
public interface SampleProvider<T extends ActivitySample> {
int PROVIDER_MIBAND = 0; int PROVIDER_MIBAND = 0;
int PROVIDER_PEBBLE_MORPHEUZ = 1; int PROVIDER_PEBBLE_MORPHEUZ = 1;
int PROVIDER_PEBBLE_GADGETBRIDGE = 2; int PROVIDER_PEBBLE_GADGETBRIDGE = 2;
@ -15,5 +20,17 @@ public interface SampleProvider {
float normalizeIntensity(int rawIntensity); float normalizeIntensity(int rawIntensity);
List<T> getAllActivitySamples(int timestamp_from, int timestamp_to);
List<T> getActivitySamples(int timestamp_from, int timestamp_to);
List<T> getSleepSamples(int timestamp_from, int timestamp_to);
int fetchLatestTimestamp();
void addGBActivitySample(AbstractActivitySample activitySample);
void addGBActivitySamples(AbstractActivitySample[] activitySamples);
int getID(); int getID();
} }

View File

@ -4,14 +4,17 @@ import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter; import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator { public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
private final UnknownSampleProvider sampleProvider;
private static final class UnknownSampleProvider implements SampleProvider { private static final class UnknownSampleProvider implements SampleProvider {
@Override @Override
@ -29,6 +32,34 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
return 0; return 0;
} }
@Override
public List getAllActivitySamples(int timestamp_from, int timestamp_to) {
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 int fetchLatestTimestamp() {
return 0;
}
@Override
public void addGBActivitySample(AbstractActivitySample activitySample) {
}
@Override
public void addGBActivitySamples(AbstractActivitySample[] activitySamples) {
}
@Override @Override
public int getID() { public int getID() {
return PROVIDER_UNKNOWN; return PROVIDER_UNKNOWN;
@ -36,7 +67,6 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
} }
public UnknownDeviceCoordinator() { public UnknownDeviceCoordinator() {
sampleProvider = new UnknownSampleProvider();
} }
@Override @Override
@ -65,8 +95,8 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
} }
@Override @Override
public SampleProvider getSampleProvider() { public SampleProvider getSampleProvider(DBHandler db) {
return sampleProvider; return new UnknownSampleProvider();
} }
@Override @Override

View File

@ -10,6 +10,7 @@ import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity; import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
@ -21,10 +22,8 @@ import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
public class MiBandCoordinator extends AbstractDeviceCoordinator { public class MiBandCoordinator extends AbstractDeviceCoordinator {
private static final Logger LOG = LoggerFactory.getLogger(MiBandCoordinator.class); private static final Logger LOG = LoggerFactory.getLogger(MiBandCoordinator.class);
private final MiBandSampleProvider sampleProvider;
public MiBandCoordinator() { public MiBandCoordinator() {
sampleProvider = new MiBandSampleProvider(GBApplication.getDaoSession());
} }
@Override @Override
@ -54,8 +53,8 @@ public class MiBandCoordinator extends AbstractDeviceCoordinator {
} }
@Override @Override
public SampleProvider getSampleProvider() { public SampleProvider getSampleProvider(DBHandler db) {
return sampleProvider; return new MiBandSampleProvider(db.getDaoSession());
} }
@Override @Override

View File

@ -7,6 +7,7 @@ import android.net.Uri;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.AppManagerActivity; import nodomain.freeyourgadget.gadgetbridge.activities.AppManagerActivity;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractDeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
@ -45,9 +46,9 @@ public class PebbleCoordinator extends AbstractDeviceCoordinator {
} }
@Override @Override
public SampleProvider getSampleProvider() { public SampleProvider getSampleProvider(DBHandler db) {
Prefs prefs = GBApplication.getPrefs(); Prefs prefs = GBApplication.getPrefs();
DaoSession session = GBApplication.getDaoSession(); DaoSession session = db.getDaoSession();
int activityTracker = prefs.getInt("pebble_activitytracker", SampleProvider.PROVIDER_PEBBLE_HEALTH); int activityTracker = prefs.getInt("pebble_activitytracker", SampleProvider.PROVIDER_PEBBLE_HEALTH);
switch (activityTracker) { switch (activityTracker) {
case SampleProvider.PROVIDER_PEBBLE_HEALTH: case SampleProvider.PROVIDER_PEBBLE_HEALTH:

View File

@ -18,6 +18,7 @@ import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
@ -26,8 +27,10 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandService;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample; 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.MiBandActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySampleDao; import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample; import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
@ -311,10 +314,10 @@ public class FetchActivityOperation extends AbstractMiBandOperation {
LOG.debug("flushing activity data samples: " + activityStruct.activityDataHolderProgress / bpm); LOG.debug("flushing activity data samples: " + activityStruct.activityDataHolderProgress / bpm);
byte category, intensity, steps, heartrate = 0; byte category, intensity, steps, heartrate = 0;
DBHandler dbHandler = null; try (DBHandler dbHandler = GBApplication.acquireDB()){
try { MiBandSampleProvider provider = new MiBandSampleProvider(dbHandler.getDaoSession());
// dbHandler = GBApplication.acquireDB(); Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId();
dbHandler = new MiBandSampleProvider(GBApplication.getDaoSession()); Long deviceId = DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId();
int minutes = 0; int minutes = 0;
try (SQLiteDatabase db = dbHandler.getWritableDatabase()) { // explicitly keep the db open while looping over the samples try (SQLiteDatabase db = dbHandler.getWritableDatabase()) { // explicitly keep the db open while looping over the samples
int timestampInSeconds = (int) (activityStruct.activityDataTimestampProgress.getTimeInMillis() / 1000); int timestampInSeconds = (int) (activityStruct.activityDataTimestampProgress.getTimeInMillis() / 1000);
@ -333,10 +336,6 @@ public class FetchActivityOperation extends AbstractMiBandOperation {
LOG.debug("heartrate received: " + (heartrate & 0xff)); LOG.debug("heartrate received: " + (heartrate & 0xff));
} }
// TODO: user and device id
Long userId = null;
Long deviceId = null;
samples[minutes] = new MiBandActivitySample( samples[minutes] = new MiBandActivitySample(
null, null,
timestampInSeconds, timestampInSeconds,
@ -352,16 +351,12 @@ public class FetchActivityOperation extends AbstractMiBandOperation {
minutes++; minutes++;
timestampInSeconds += 60; timestampInSeconds += 60;
} }
dbHandler.addGBActivitySamples(samples); provider.addGBActivitySamples(samples);
} finally { } finally {
activityStruct.bufferFlushed(minutes); activityStruct.bufferFlushed(minutes);
} }
} catch (Exception ex) { } catch (Exception ex) {
GB.toast(getContext(), ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex); GB.toast(getContext(), ex.getMessage(), Toast.LENGTH_LONG, GB.ERROR, ex);
} finally {
if (dbHandler != null) {
dbHandler.release();
}
} }
} }

View File

@ -6,8 +6,13 @@ import android.util.Pair;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.UUID; import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.PebbleActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
public class AppMessageHandler { public class AppMessageHandler {
protected final PebbleProtocol mPebbleProtocol; protected final PebbleProtocol mPebbleProtocol;
@ -30,10 +35,11 @@ public class AppMessageHandler {
return null; return null;
} }
protected PebbleActivitySample createSample(int timestamp, int intensity, int steps, int type) { protected PebbleActivitySample createSample(int timestamp, int intensity, int steps, int type, User user, Device device) {
// TODO: user and device id return new PebbleActivitySample(null, timestamp, intensity, steps, type, user.getId(), device.getId());
Long userId = null; }
Long deviceId = null;
return new PebbleActivitySample(null, timestamp, intensity, steps, type, userId, deviceId); protected GBDevice getDevice() {
return mPebbleProtocol.getDevice();
} }
} }

View File

@ -15,11 +15,15 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
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.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleGadgetBridgeSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleGadgetBridgeSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
public class AppMessageHandlerGBPebble extends AppMessageHandler { public class AppMessageHandlerGBPebble extends AppMessageHandler {
@ -50,10 +54,10 @@ public class AppMessageHandlerGBPebble extends AppMessageHandler {
int samples_remaining = samples.length / 2; int samples_remaining = samples.length / 2;
LOG.info("got " + samples_remaining + " samples"); LOG.info("got " + samples_remaining + " samples");
int offset_seconds = 0; int offset_seconds = 0;
DBHandler db = null; try (DBHandler db = GBApplication.acquireDB()) {
try { User user = DBHelper.getUser(db.getDaoSession());
// db = GBApplication.acquireDB(); Device device = DBHelper.getDevice(getDevice(), db.getDaoSession());
db = new PebbleGadgetBridgeSampleProvider(GBApplication.getDaoSession()); PebbleGadgetBridgeSampleProvider sampleProvider = new PebbleGadgetBridgeSampleProvider(db.getDaoSession());
AbstractActivitySample[] activitySamples = new AbstractActivitySample[samples_remaining]; AbstractActivitySample[] activitySamples = new AbstractActivitySample[samples_remaining];
int i = 0; int i = 0;
while (samples_remaining-- > 0) { while (samples_remaining-- > 0) {
@ -61,16 +65,12 @@ public class AppMessageHandlerGBPebble extends AppMessageHandler {
int type = ((sample & 0xe000) >>> 13); int type = ((sample & 0xe000) >>> 13);
int intensity = ((sample & 0x1f80) >>> 7); int intensity = ((sample & 0x1f80) >>> 7);
int steps = (sample & 0x007f); int steps = (sample & 0x007f);
activitySamples[i++] = createSample(timestamp + offset_seconds, intensity, steps, type); activitySamples[i++] = createSample(timestamp + offset_seconds, intensity, steps, type, user, device);
offset_seconds += 60; offset_seconds += 60;
} }
db.addGBActivitySamples(activitySamples); sampleProvider.addGBActivitySamples(activitySamples);
// } catch (GBException e) { } catch (Exception e) {
// LOG.error("Error acquiring database", e); LOG.error("Error acquiring database", e);
} finally {
if (db != null) {
db.release();
}
} }
break; break;
default: default:

View File

@ -15,6 +15,7 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
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;
@ -41,8 +42,6 @@ public class AppMessageHandlerMisfit extends AppMessageHandler {
super(uuid, pebbleProtocol); super(uuid, pebbleProtocol);
} }
private final MisfitSampleProvider sampleProvider = new MisfitSampleProvider(GBApplication.getDaoSession());
@Override @Override
public GBDeviceEvent[] handleMessage(ArrayList<Pair<Integer, Object>> pairs) { public GBDeviceEvent[] handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
for (Pair<Integer, Object> pair : pairs) { for (Pair<Integer, Object> pair : pairs) {
@ -73,55 +72,48 @@ public class AppMessageHandlerMisfit extends AppMessageHandler {
int totalSteps = 0; int totalSteps = 0;
AbstractActivitySample[] activitySamples = new AbstractActivitySample[samples]; AbstractActivitySample[] activitySamples = new AbstractActivitySample[samples];
// TODO: user and device id try (DBHandler db = GBApplication.acquireDB()) {
Long userId = null; Long userId = DBHelper.getUser(db.getDaoSession()).getId();
Long deviceId = null; 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; int steps = 0;
int intensity = 0; int intensity = 0;
int activityKind = ActivityKind.TYPE_UNKNOWN; int activityKind = ActivityKind.TYPE_UNKNOWN;
if (((sample & 0x83ff) == 0x0001) && ((sample & 0xff00) <= 0x4800)) { if (((sample & 0x83ff) == 0x0001) && ((sample & 0xff00) <= 0x4800)) {
// sleep seems to be from 0x2401 to 0x4801 (0b0IIIII0000000001) where I = intensity ? // sleep seems to be from 0x2401 to 0x4801 (0b0IIIII0000000001) where I = intensity ?
intensity = (sample & 0x7c00) >>> 10; intensity = (sample & 0x7c00) >>> 10;
// 9-18 decimal after shift // 9-18 decimal after shift
if (intensity <= 13) { if (intensity <= 13) {
activityKind = ActivityKind.TYPE_DEEP_SLEEP; 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 { } else {
// FIXME: this leads to too much false positives, ignore for now if ((sample & 0x0001) == 0) { // 16-??? steps encoded in bits 1-7
//activityKind = ActivityKind.TYPE_LIGHT_SLEEP; steps = (sample & 0x00fe);
//intensity *= 2; // better visual distinction } 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;
} }
} else {
if ((sample & 0x0001) == 0) { // 16-??? steps encoded in bits 1-7 totalSteps += steps;
steps = (sample & 0x00fe); LOG.info("got steps for sample " + i + " : " + steps + "(" + Integer.toHexString(sample & 0xffff) + ")");
} else { // 0-14 steps encoded in bits 1-3, most of the time fc71 bits are set in that case
steps = (sample & 0x000e); activitySamples[i] = new PebbleActivitySample(null, timestamp + i * 60, intensity, steps, activityKind, userId, deviceId);
}
intensity = steps;
activityKind = ActivityKind.TYPE_ACTIVITY;
} }
LOG.info("total steps for above period: " + totalSteps);
totalSteps += steps; MisfitSampleProvider sampleProvider = new MisfitSampleProvider(db.getDaoSession());
LOG.info("got steps for sample " + i + " : " + steps + "(" + Integer.toHexString(sample & 0xffff) + ")"); sampleProvider.addGBActivitySamples(activitySamples);
} catch (Exception e) {
activitySamples[i] = new PebbleActivitySample(null, timestamp + i * 60, intensity, steps, activityKind, userId, deviceId); LOG.error("Error acquiring database", e);
} return null;
LOG.info("total steps for above period: " + totalSteps);
DBHandler db = null;
try {
// db = GBApplication.acquireDB();
db = sampleProvider;
db.addGBActivitySamples(activitySamples);
// } catch (GBException e) {
// LOG.error("Error acquiring database", e);
// return null;
} finally {
if (db != null) {
db.release();
}
} }
break; break;
default: default:

View File

@ -13,11 +13,15 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
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.deviceevents.GBDeviceEventSleepMonitorResult; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSleepMonitorResult;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.MorpheuzSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.pebble.MorpheuzSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
public class AppMessageHandlerMorpheuz extends AppMessageHandler { public class AppMessageHandlerMorpheuz extends AppMessageHandler {
@ -90,17 +94,13 @@ public class AppMessageHandlerMorpheuz extends AppMessageHandler {
type = MorpheuzSampleProvider.TYPE_LIGHT_SLEEP; type = MorpheuzSampleProvider.TYPE_LIGHT_SLEEP;
} }
if (index >= 0) { if (index >= 0) {
DBHandler db = null; try (DBHandler db = GBApplication.acquireDB()) {
try { User user = DBHelper.getUser(db.getDaoSession());
// db = GBApplication.acquireDB(); Device device = DBHelper.getDevice(getDevice(), db.getDaoSession());
db = new MorpheuzSampleProvider(GBApplication.getDaoSession()); MorpheuzSampleProvider sampleProvider = new MorpheuzSampleProvider(db.getDaoSession());
db.addGBActivitySample(createSample(recording_base_timestamp + index * 600, intensity, 0, type)); sampleProvider.addGBActivitySample(createSample(recording_base_timestamp + index * 600, intensity, 0, type, user, device));
// } catch (GBException e) { } catch (Exception e) {
// LOG.error("Error acquiring database", e); LOG.error("Error acquiring database", e);
} finally {
if (db != null) {
db.release();
}
} }
} }

View File

@ -66,10 +66,8 @@ class DatalogSessionHealthSleep extends DatalogSession {
} }
private boolean store84(SleepRecord84[] sleepRecords) { private boolean store84(SleepRecord84[] sleepRecords) {
DBHandler dbHandler = null; try (DBHandler dbHandler = GBApplication.acquireDB()) {
SampleProvider sampleProvider = new HealthSampleProvider(GBApplication.getDaoSession()); SampleProvider sampleProvider = new HealthSampleProvider(dbHandler.getDaoSession());
try {
dbHandler = GBApplication.acquireDB();
int latestTimestamp = dbHandler.fetchLatestTimestamp(sampleProvider); int latestTimestamp = dbHandler.fetchLatestTimestamp(sampleProvider);
for (SleepRecord84 sleepRecord : sleepRecords) { for (SleepRecord84 sleepRecord : sleepRecords) {
if (latestTimestamp < (sleepRecord.timestampStart + sleepRecord.durationSeconds)) if (latestTimestamp < (sleepRecord.timestampStart + sleepRecord.durationSeconds))
@ -83,10 +81,6 @@ class DatalogSessionHealthSleep extends DatalogSession {
} }
} catch (Exception ex) { } catch (Exception ex) {
LOG.debug(ex.getMessage()); LOG.debug(ex.getMessage());
} finally {
if (dbHandler != null) {
dbHandler.release();
}
} }
return true; return true;
} }
@ -119,11 +113,9 @@ class DatalogSessionHealthSleep extends DatalogSession {
} }
private boolean store83(SleepRecord83[] sleepRecords) { private boolean store83(SleepRecord83[] sleepRecords) {
DBHandler dbHandler = null; try (DBHandler dbHandler = GBApplication.acquireDB()) {
SampleProvider sampleProvider = new HealthSampleProvider(GBApplication.getDaoSession()); SampleProvider sampleProvider = new HealthSampleProvider(dbHandler.getDaoSession());
GB.toast("Deep sleep is supported only from firmware 3.11 onwards.", Toast.LENGTH_LONG, GB.INFO); GB.toast("Deep sleep is supported only from firmware 3.11 onwards.", Toast.LENGTH_LONG, GB.INFO);
try {
dbHandler = GBApplication.acquireDB();
int latestTimestamp = dbHandler.fetchLatestTimestamp(sampleProvider); int latestTimestamp = dbHandler.fetchLatestTimestamp(sampleProvider);
for (SleepRecord83 sleepRecord : sleepRecords) { for (SleepRecord83 sleepRecord : sleepRecords) {
if (latestTimestamp < sleepRecord.bedTimeEnd) if (latestTimestamp < sleepRecord.bedTimeEnd)
@ -132,10 +124,6 @@ class DatalogSessionHealthSleep extends DatalogSession {
} }
} catch (Exception ex) { } catch (Exception ex) {
LOG.debug(ex.getMessage()); LOG.debug(ex.getMessage());
} finally {
if (dbHandler != null) {
dbHandler.release();
}
} }
return true; return true;
} }

View File

@ -9,11 +9,13 @@ import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.HealthSampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.pebble.HealthSampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleActivitySample; import nodomain.freeyourgadget.gadgetbridge.entities.PebbleActivitySample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample; import nodomain.freeyourgadget.gadgetbridge.impl.GBActivitySample;
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.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GB;
@ -21,10 +23,12 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class DatalogSessionHealthSteps extends DatalogSession { public class DatalogSessionHealthSteps extends DatalogSession {
private static final Logger LOG = LoggerFactory.getLogger(DatalogSessionHealthSteps.class); private static final Logger LOG = LoggerFactory.getLogger(DatalogSessionHealthSteps.class);
private final GBDevice device;
public DatalogSessionHealthSteps(byte id, UUID uuid, int tag, byte item_type, short item_size) { public DatalogSessionHealthSteps(byte id, UUID uuid, int tag, byte item_type, short item_size, GBDevice device) {
super(id, uuid, tag, item_type, item_size); super(id, uuid, tag, item_type, item_size);
taginfo = "(health - steps)"; taginfo = "(health - steps)";
this.device = device;
} }
@Override @Override
@ -72,34 +76,26 @@ public class DatalogSessionHealthSteps extends DatalogSession {
private void store(StepsRecord[] stepsRecords) { private void store(StepsRecord[] stepsRecords) {
HealthSampleProvider sampleProvider = new HealthSampleProvider(GBApplication.getDaoSession()); try (DBHandler dbHandler = GBApplication.acquireDB()) {
DBHandler dbHandler = sampleProvider; HealthSampleProvider sampleProvider = new HealthSampleProvider(dbHandler.getDaoSession());
AbstractActivitySample[] samples = new AbstractActivitySample[stepsRecords.length];
// TODO: user and device
Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId();
Long deviceId = DBHelper.getDevice(device, dbHandler.getDaoSession()).getId();
for (int j = 0; j < stepsRecords.length; j++) {
StepsRecord stepsRecord = stepsRecords[j];
samples[j] = new PebbleActivitySample(
null,
stepsRecord.timestamp,
stepsRecord.intensity,
stepsRecord.steps,
sampleProvider.toRawActivityKind(ActivityKind.TYPE_ACTIVITY),
userId, deviceId);
}
AbstractActivitySample[] samples = new AbstractActivitySample[stepsRecords.length]; sampleProvider.addGBActivitySamples(samples);
// TODO: user and device
Long userId = null;
Long deviceId = null;
for (int j = 0; j < stepsRecords.length; j++) {
StepsRecord stepsRecord = stepsRecords[j];
samples[j] = new PebbleActivitySample(
null,
stepsRecord.timestamp,
stepsRecord.intensity,
stepsRecord.steps,
sampleProvider.toRawActivityKind(ActivityKind.TYPE_ACTIVITY),
userId, deviceId);
}
try {
// dbHandler = GBApplication.acquireDB();
dbHandler = sampleProvider;
dbHandler.addGBActivitySamples(samples);
} catch (Exception ex) { } catch (Exception ex) {
LOG.debug(ex.getMessage()); LOG.debug(ex.getMessage());
} finally {
if (dbHandler != null) {
dbHandler.release();
}
} }
} }

View File

@ -31,6 +31,7 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleColor; import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleColor;
import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleIconID; import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleIconID;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser; import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec; import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
@ -361,16 +362,16 @@ public class PebbleProtocol extends GBDeviceProtocol {
private static final UUID UUID_PEBSTYLE = UUID.fromString("da05e84d-e2a2-4020-a2dc-9cdcf265fcdd"); private static final UUID UUID_PEBSTYLE = UUID.fromString("da05e84d-e2a2-4020-a2dc-9cdcf265fcdd");
private static final UUID UUID_ZERO = new UUID(0, 0); private static final UUID UUID_ZERO = new UUID(0, 0);
private static final Map<UUID, AppMessageHandler> mAppMessageHandlers = new HashMap<>(); private final Map<UUID, AppMessageHandler> mAppMessageHandlers = new HashMap<>();
{ public PebbleProtocol(GBDevice device) {
super(device);
mAppMessageHandlers.put(UUID_GBPEBBLE, new AppMessageHandlerGBPebble(UUID_GBPEBBLE, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_GBPEBBLE, new AppMessageHandlerGBPebble(UUID_GBPEBBLE, PebbleProtocol.this));
mAppMessageHandlers.put(UUID_MORPHEUZ, new AppMessageHandlerMorpheuz(UUID_MORPHEUZ, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_MORPHEUZ, new AppMessageHandlerMorpheuz(UUID_MORPHEUZ, PebbleProtocol.this));
mAppMessageHandlers.put(UUID_WHETHERNEAT, new AppMessageHandlerWeatherNeat(UUID_WHETHERNEAT, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_WHETHERNEAT, new AppMessageHandlerWeatherNeat(UUID_WHETHERNEAT, PebbleProtocol.this));
mAppMessageHandlers.put(UUID_MISFIT, new AppMessageHandlerMisfit(UUID_MISFIT, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_MISFIT, new AppMessageHandlerMisfit(UUID_MISFIT, PebbleProtocol.this));
mAppMessageHandlers.put(UUID_PEBBLE_TIMESTYLE, new AppMessageHandlerTimeStylePebble(UUID_PEBBLE_TIMESTYLE, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_PEBBLE_TIMESTYLE, new AppMessageHandlerTimeStylePebble(UUID_PEBBLE_TIMESTYLE, PebbleProtocol.this));
mAppMessageHandlers.put(UUID_PEBSTYLE, new AppMessageHandlerPebStyle(UUID_PEBSTYLE, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_PEBSTYLE, new AppMessageHandlerPebStyle(UUID_PEBSTYLE, PebbleProtocol.this));
} }
private final HashMap<Byte, DatalogSession> mDatalogSessions = new HashMap<>(); private final HashMap<Byte, DatalogSession> mDatalogSessions = new HashMap<>();
@ -1880,7 +1881,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
LOG.info("DATALOG OPENSESSION. id=" + (id & 0xff) + ", App UUID=" + uuid.toString() + ", log_tag=" + log_tag + ", item_type=" + item_type + ", itemSize=" + item_size); LOG.info("DATALOG OPENSESSION. id=" + (id & 0xff) + ", App UUID=" + uuid.toString() + ", log_tag=" + log_tag + ", item_type=" + item_type + ", itemSize=" + item_size);
if (!mDatalogSessions.containsKey(id)) { if (!mDatalogSessions.containsKey(id)) {
if (uuid.equals(UUID_ZERO) && log_tag == 81) { if (uuid.equals(UUID_ZERO) && log_tag == 81) {
mDatalogSessions.put(id, new DatalogSessionHealthSteps(id, uuid, log_tag, item_type, item_size)); mDatalogSessions.put(id, new DatalogSessionHealthSteps(id, uuid, log_tag, item_type, item_size, getDevice()));
} else if (uuid.equals(UUID_ZERO) && (log_tag == 83 || log_tag == 84)) { } else if (uuid.equals(UUID_ZERO) && (log_tag == 83 || log_tag == 84)) {
mDatalogSessions.put(id, new DatalogSessionHealthSleep(id, uuid, log_tag, item_type, item_size)); mDatalogSessions.put(id, new DatalogSessionHealthSleep(id, uuid, log_tag, item_type, item_size));
} else { } else {

View File

@ -29,7 +29,7 @@ public class PebbleSupport extends AbstractSerialDeviceSupport {
@Override @Override
protected GBDeviceProtocol createDeviceProtocol() { protected GBDeviceProtocol createDeviceProtocol() {
return new PebbleProtocol(); return new PebbleProtocol(getDevice());
} }
@Override @Override

View File

@ -3,10 +3,17 @@ package nodomain.freeyourgadget.gadgetbridge.service.serial;
import java.util.UUID; import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
public abstract class GBDeviceProtocol { public abstract class GBDeviceProtocol {
private GBDevice mDevice;
protected GBDeviceProtocol(GBDevice device) {
mDevice = device;
}
public byte[] encodeNotification(NotificationSpec notificationSpec) { public byte[] encodeNotification(NotificationSpec notificationSpec) {
return null; return null;
} }
@ -68,4 +75,8 @@ public abstract class GBDeviceProtocol {
public GBDeviceEvent[] decodeResponse(byte[] responseData) { public GBDeviceEvent[] decodeResponse(byte[] responseData) {
return null; return null;
} }
public GBDevice getDevice() {
return mDevice;
}
} }