mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Huawei: use specific table for temperature sync
This commit is contained in:
@@ -58,7 +58,7 @@ public class GBDaoGenerator {
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final Schema schema = new Schema(113, MAIN_PACKAGE + ".entities");
|
||||
final Schema schema = new Schema(114, MAIN_PACKAGE + ".entities");
|
||||
|
||||
Entity userAttributes = addUserAttributes(schema);
|
||||
Entity user = addUserInfo(schema, userAttributes);
|
||||
@@ -172,6 +172,7 @@ public class GBDaoGenerator {
|
||||
addHuaweiStressSample(schema, user, device);
|
||||
addHuaweiSleepStageSample(schema, user, device);
|
||||
addHuaweiSleepStatsSample(schema, user, device);
|
||||
addHuaweiTemperatureSample(schema, user, device);
|
||||
|
||||
addUltrahumanActivitySample(schema, user, device);
|
||||
addUltrahumanDeviceStateSample(schema, user, device);
|
||||
@@ -1589,6 +1590,16 @@ public class GBDaoGenerator {
|
||||
return sample;
|
||||
}
|
||||
|
||||
private static Entity addHuaweiTemperatureSample(Schema schema, Entity user, Entity device) {
|
||||
Entity sample = addEntity(schema, "HuaweiTemperatureSample");
|
||||
addCommonTimeSampleProperties("AbstractTemperatureSample", sample, user, device);
|
||||
sample.addLongProperty("lastTimestamp").notNull().index();
|
||||
sample.addFloatProperty(SAMPLE_TEMPERATURE).notNull().codeBeforeGetter(OVERRIDE);
|
||||
sample.addIntProperty(SAMPLE_TEMPERATURE_TYPE).notNull().primaryKey().codeBeforeGetter(OVERRIDE);
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
private static Entity addHuaweiWorkoutSummarySample(Schema schema, Entity user, Entity device) {
|
||||
Entity workoutSummary = addEntity(schema, "HuaweiWorkoutSummarySample");
|
||||
|
||||
|
||||
+1
-1
@@ -257,7 +257,7 @@ public abstract class HuaweiBRCoordinator extends AbstractBLClassicDeviceCoordin
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends TemperatureSample> getTemperatureSampleProvider(final GBDevice device, final DaoSession session) {
|
||||
return new HuaweiTemperatureSampleProvider(device, session);
|
||||
return new HuaweiCompatTemperatureSampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.devices.huawei;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import de.greenrobot.dao.query.QueryBuilder;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.TimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiDictData;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiDictDataDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiDictDataValues;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiDictDataValuesDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiTemperatureSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.TemperatureSample;
|
||||
|
||||
public class HuaweiCompatTemperatureSampleProvider implements TimeSampleProvider<HuaweiTemperatureSample> {
|
||||
|
||||
private final HuaweiTemperatureSampleProvider sp;
|
||||
|
||||
private final GBDevice device;
|
||||
private final DaoSession session;
|
||||
|
||||
public HuaweiCompatTemperatureSampleProvider(GBDevice device, DaoSession session) {
|
||||
this.device = device;
|
||||
this.session = session;
|
||||
sp = new HuaweiTemperatureSampleProvider(device, session);
|
||||
}
|
||||
|
||||
private double conv2Double(byte[] b) {
|
||||
return ByteBuffer.wrap(b).getDouble();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<HuaweiTemperatureSample> getAllSamples(long timestampFrom, long timestampTo) {
|
||||
|
||||
TemperatureSample newFirst = sp.getFirstSample();
|
||||
|
||||
if (newFirst != null && newFirst.getTimestamp() < timestampFrom) {
|
||||
return sp.getAllSamples(timestampFrom, timestampTo);
|
||||
}
|
||||
|
||||
List<HuaweiTemperatureSample> ret = sp.getAllSamples(timestampFrom, timestampTo);
|
||||
|
||||
long oldTo = timestampFrom;
|
||||
if (!ret.isEmpty()) {
|
||||
oldTo = ret.get(0).getTimestamp();
|
||||
}
|
||||
|
||||
Long userId = DBHelper.getUser(this.session).getId();
|
||||
Long deviceId = DBHelper.getDevice(this.device, this.session).getId();
|
||||
|
||||
if (deviceId == null || userId == null)
|
||||
return ret;
|
||||
|
||||
QueryBuilder<HuaweiDictData> qb = this.session.getHuaweiDictDataDao().queryBuilder();
|
||||
qb.where(HuaweiDictDataDao.Properties.DeviceId.eq(deviceId))
|
||||
.where(HuaweiDictDataDao.Properties.UserId.eq(userId))
|
||||
.where(HuaweiDictDataDao.Properties.DictClass.eq(HuaweiDictTypes.SKIN_TEMPERATURE_CLASS))
|
||||
.where(HuaweiDictDataDao.Properties.StartTimestamp.between(timestampFrom, oldTo));
|
||||
final List<HuaweiDictData> dictData = qb.build().list();
|
||||
|
||||
if (dictData.isEmpty())
|
||||
return ret;
|
||||
|
||||
List<Long> ids = dictData.stream().map(HuaweiDictData::getDictId).collect(Collectors.toList());
|
||||
|
||||
QueryBuilder<HuaweiDictDataValues> qbv = this.session.getHuaweiDictDataValuesDao().queryBuilder();
|
||||
|
||||
qbv.where(HuaweiDictDataValuesDao.Properties.DictType.eq(HuaweiDictTypes.SKIN_TEMPERATURE_VALUE)).where(HuaweiDictDataValuesDao.Properties.Tag.eq(10)).where(HuaweiDictDataValuesDao.Properties.DictId.in(ids));
|
||||
|
||||
final List<HuaweiDictDataValues> valuesData = qbv.build().list();
|
||||
|
||||
if (valuesData.isEmpty())
|
||||
return ret;
|
||||
|
||||
int idx = 0;
|
||||
for (HuaweiDictDataValues vl : valuesData) {
|
||||
double skinTemperature = conv2Double(vl.getValue());
|
||||
if (skinTemperature >= 20 && skinTemperature <= 42) {
|
||||
HuaweiTemperatureSample sample = new HuaweiTemperatureSample();
|
||||
sample.setTimestamp(vl.getHuaweiDictData().getStartTimestamp());
|
||||
sample.setTemperature((float) skinTemperature);
|
||||
sample.setTemperatureType(0);
|
||||
ret.add(idx++, sample);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSample(HuaweiTemperatureSample timeSample) {
|
||||
throw new UnsupportedOperationException("read-only sample provider");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSamples(List<HuaweiTemperatureSample> timeSamples) {
|
||||
throw new UnsupportedOperationException("read-only sample provider");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public HuaweiTemperatureSample createSample() {
|
||||
throw new UnsupportedOperationException("read-only sample provider");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public HuaweiTemperatureSample getLatestSample() {
|
||||
|
||||
HuaweiTemperatureSample newSample = sp.getLatestSample();
|
||||
if (newSample != null)
|
||||
return newSample;
|
||||
|
||||
Long userId = DBHelper.getUser(this.session).getId();
|
||||
Long deviceId = DBHelper.getDevice(this.device, this.session).getId();
|
||||
|
||||
if (deviceId == null || userId == null)
|
||||
return null;
|
||||
|
||||
QueryBuilder<HuaweiDictData> qb = this.session.getHuaweiDictDataDao().queryBuilder();
|
||||
qb.where(HuaweiDictDataDao.Properties.DeviceId.eq(deviceId))
|
||||
.where(HuaweiDictDataDao.Properties.UserId.eq(userId))
|
||||
.where(HuaweiDictDataDao.Properties.DictClass.eq(HuaweiDictTypes.SKIN_TEMPERATURE_CLASS));
|
||||
qb.orderDesc(HuaweiDictDataDao.Properties.StartTimestamp).limit(1);
|
||||
|
||||
final List<HuaweiDictData> data = qb.build().list();
|
||||
if (data.isEmpty())
|
||||
return null;
|
||||
|
||||
|
||||
QueryBuilder<HuaweiDictDataValues> qbv = this.session.getHuaweiDictDataValuesDao().queryBuilder();
|
||||
qbv.where(HuaweiDictDataValuesDao.Properties.DictType.eq(HuaweiDictTypes.SKIN_TEMPERATURE_VALUE)).where(HuaweiDictDataValuesDao.Properties.Tag.eq(10)).where(HuaweiDictDataValuesDao.Properties.DictId.eq(data.get(0).getDictId()));
|
||||
final List<HuaweiDictDataValues> valuesData = qbv.build().list();
|
||||
|
||||
if (valuesData.isEmpty())
|
||||
return null;
|
||||
|
||||
HuaweiTemperatureSample sample = new HuaweiTemperatureSample();
|
||||
sample.setTimestamp(valuesData.get(0).getHuaweiDictData().getStartTimestamp());
|
||||
sample.setTemperature((float) conv2Double(valuesData.get(0).getValue()));
|
||||
sample.setTemperatureType(0);
|
||||
return sample;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public HuaweiTemperatureSample getLatestSample(final long until) {
|
||||
|
||||
HuaweiTemperatureSample newSample = sp.getLatestSample(until);
|
||||
if (newSample != null)
|
||||
return newSample;
|
||||
|
||||
Long userId = DBHelper.getUser(this.session).getId();
|
||||
Long deviceId = DBHelper.getDevice(this.device, this.session).getId();
|
||||
|
||||
if (deviceId == null || userId == null)
|
||||
return null;
|
||||
|
||||
QueryBuilder<HuaweiDictData> qb = this.session.getHuaweiDictDataDao().queryBuilder();
|
||||
qb.where(HuaweiDictDataDao.Properties.StartTimestamp.le(until))
|
||||
.where(HuaweiDictDataDao.Properties.DeviceId.eq(deviceId))
|
||||
.where(HuaweiDictDataDao.Properties.UserId.eq(userId))
|
||||
.where(HuaweiDictDataDao.Properties.DictClass.eq(HuaweiDictTypes.SKIN_TEMPERATURE_CLASS));
|
||||
qb.orderDesc(HuaweiDictDataDao.Properties.StartTimestamp).limit(1);
|
||||
|
||||
final List<HuaweiDictData> data = qb.build().list();
|
||||
if (data.isEmpty())
|
||||
return null;
|
||||
|
||||
|
||||
QueryBuilder<HuaweiDictDataValues> qbv = this.session.getHuaweiDictDataValuesDao().queryBuilder();
|
||||
qbv.where(HuaweiDictDataValuesDao.Properties.DictType.eq(HuaweiDictTypes.SKIN_TEMPERATURE_VALUE)).where(HuaweiDictDataValuesDao.Properties.Tag.eq(10)).where(HuaweiDictDataValuesDao.Properties.DictId.eq(data.get(0).getDictId()));
|
||||
final List<HuaweiDictDataValues> valuesData = qbv.build().list();
|
||||
|
||||
if (valuesData.isEmpty())
|
||||
return null;
|
||||
|
||||
HuaweiTemperatureSample sample = new HuaweiTemperatureSample();
|
||||
sample.setTimestamp(valuesData.get(0).getHuaweiDictData().getStartTimestamp());
|
||||
sample.setTemperature((float) conv2Double(valuesData.get(0).getValue()));
|
||||
sample.setTemperatureType(0);
|
||||
return sample;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public HuaweiTemperatureSample getFirstSample() {
|
||||
Long userId = DBHelper.getUser(this.session).getId();
|
||||
Long deviceId = DBHelper.getDevice(this.device, this.session).getId();
|
||||
|
||||
if (deviceId == null || userId == null)
|
||||
return null;
|
||||
|
||||
QueryBuilder<HuaweiDictData> qb = this.session.getHuaweiDictDataDao().queryBuilder();
|
||||
qb.where(HuaweiDictDataDao.Properties.DeviceId.eq(deviceId))
|
||||
.where(HuaweiDictDataDao.Properties.UserId.eq(userId))
|
||||
.where(HuaweiDictDataDao.Properties.DictClass.eq(HuaweiDictTypes.SKIN_TEMPERATURE_CLASS));
|
||||
qb.orderAsc(HuaweiDictDataDao.Properties.StartTimestamp).limit(1);
|
||||
|
||||
final List<HuaweiDictData> data = qb.build().list();
|
||||
if (data.isEmpty())
|
||||
return sp.getFirstSample();
|
||||
|
||||
QueryBuilder<HuaweiDictDataValues> qbv = this.session.getHuaweiDictDataValuesDao().queryBuilder();
|
||||
qbv.where(HuaweiDictDataValuesDao.Properties.DictType.eq(HuaweiDictTypes.SKIN_TEMPERATURE_VALUE)).where(HuaweiDictDataValuesDao.Properties.Tag.eq(10)).where(HuaweiDictDataValuesDao.Properties.DictId.eq(data.get(0).getDictId()));
|
||||
final List<HuaweiDictDataValues> valuesData = qbv.build().list();
|
||||
|
||||
if (valuesData.isEmpty())
|
||||
return sp.getFirstSample();
|
||||
|
||||
HuaweiTemperatureSample sample = new HuaweiTemperatureSample();
|
||||
sample.setTimestamp(valuesData.get(0).getHuaweiDictData().getStartTimestamp());
|
||||
sample.setTemperature((float) conv2Double(valuesData.get(0).getValue()));
|
||||
sample.setTemperatureType(0);
|
||||
return sample;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -265,7 +265,7 @@ public abstract class HuaweiLECoordinator extends AbstractBLEDeviceCoordinator i
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends TemperatureSample> getTemperatureSampleProvider(final GBDevice device, final DaoSession session) {
|
||||
return new HuaweiTemperatureSampleProvider(device, session);
|
||||
return new HuaweiCompatTemperatureSampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+45
-172
@@ -27,203 +27,76 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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.AbstractTimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.TimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiDictData;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiDictDataDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiDictDataValues;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiDictDataValuesDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiSleepStageSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiSleepStageSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiSleepStatsSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiSleepStatsSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiTemperatureSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiTemperatureSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.TemperatureSample;
|
||||
|
||||
public class HuaweiTemperatureSampleProvider implements TimeSampleProvider<TemperatureSample> {
|
||||
public class HuaweiTemperatureSampleProvider extends AbstractTimeSampleProvider<HuaweiTemperatureSample> {
|
||||
|
||||
private final Logger LOG = LoggerFactory.getLogger(HuaweiTemperatureSampleProvider.class);
|
||||
|
||||
protected static class HuaweiTemperatureSample implements TemperatureSample {
|
||||
private final long timestamp;
|
||||
private final float temperature;
|
||||
|
||||
public HuaweiTemperatureSample(long timestamp, float temperature) {
|
||||
this.timestamp = timestamp;
|
||||
this.temperature = temperature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getTemperature() {
|
||||
return temperature;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTemperatureType() { return 0;}
|
||||
}
|
||||
|
||||
private final GBDevice device;
|
||||
private final DaoSession session;
|
||||
|
||||
public HuaweiTemperatureSampleProvider(GBDevice device, DaoSession session) {
|
||||
this.device = device;
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
private double conv2Double(byte[] b) {
|
||||
return ByteBuffer.wrap(b).getDouble();
|
||||
public HuaweiTemperatureSampleProvider(final GBDevice device, final DaoSession session) {
|
||||
super(device, session);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<TemperatureSample> getAllSamples(long timestampFrom, long timestampTo) {
|
||||
|
||||
List<TemperatureSample> ret = new ArrayList<>();
|
||||
|
||||
Long userId = DBHelper.getUser(this.session).getId();
|
||||
Long deviceId = DBHelper.getDevice(this.device, this.session).getId();
|
||||
|
||||
if (deviceId == null || userId == null)
|
||||
return ret;
|
||||
|
||||
QueryBuilder<HuaweiDictData> qb = this.session.getHuaweiDictDataDao().queryBuilder();
|
||||
qb.where(HuaweiDictDataDao.Properties.DeviceId.eq(deviceId))
|
||||
.where(HuaweiDictDataDao.Properties.UserId.eq(userId))
|
||||
.where(HuaweiDictDataDao.Properties.DictClass.eq(HuaweiDictTypes.SKIN_TEMPERATURE_CLASS))
|
||||
.where(HuaweiDictDataDao.Properties.StartTimestamp.between(timestampFrom, timestampTo));
|
||||
final List<HuaweiDictData> dictData = qb.build().list();
|
||||
|
||||
if (dictData.isEmpty())
|
||||
return ret;
|
||||
|
||||
List<Long> ids = dictData.stream().map(HuaweiDictData::getDictId).collect(Collectors.toList());
|
||||
|
||||
QueryBuilder<HuaweiDictDataValues> qbv = this.session.getHuaweiDictDataValuesDao().queryBuilder();
|
||||
|
||||
qbv.where(HuaweiDictDataValuesDao.Properties.DictType.eq(HuaweiDictTypes.SKIN_TEMPERATURE_VALUE)).where(HuaweiDictDataValuesDao.Properties.Tag.eq(10)).where(HuaweiDictDataValuesDao.Properties.DictId.in(ids));
|
||||
|
||||
final List<HuaweiDictDataValues> valuesData = qbv.build().list();
|
||||
|
||||
if (valuesData.isEmpty())
|
||||
return ret;
|
||||
|
||||
for(HuaweiDictDataValues vl: valuesData) {
|
||||
double skinTemperature = conv2Double(vl.getValue());
|
||||
if(skinTemperature >= 20 && skinTemperature <= 42) {
|
||||
ret.add(new HuaweiTemperatureSample(vl.getHuaweiDictData().getStartTimestamp(), (float) skinTemperature));
|
||||
}
|
||||
public AbstractDao<HuaweiTemperatureSample, ?> getSampleDao() {
|
||||
return getSession().getHuaweiTemperatureSampleDao();
|
||||
}
|
||||
|
||||
return ret;
|
||||
@NonNull
|
||||
@Override
|
||||
protected Property getTimestampSampleProperty() {
|
||||
return HuaweiTemperatureSampleDao.Properties.Timestamp;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Property getDeviceIdentifierSampleProperty() {
|
||||
return HuaweiTemperatureSampleDao.Properties.DeviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSample(TemperatureSample timeSample) {
|
||||
throw new UnsupportedOperationException("read-only sample provider");
|
||||
|
||||
public HuaweiTemperatureSample createSample() {
|
||||
return new HuaweiTemperatureSample();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSamples(List<TemperatureSample> timeSamples) {
|
||||
throw new UnsupportedOperationException("read-only sample provider");
|
||||
|
||||
public long getLastFetchTimestamp() {
|
||||
QueryBuilder<HuaweiTemperatureSample> qb = getSampleDao().queryBuilder();
|
||||
Device dbDevice = DBHelper.findDevice(getDevice(), getSession());
|
||||
if (dbDevice == null)
|
||||
return 0;
|
||||
final Property deviceProperty = HuaweiTemperatureSampleDao.Properties.DeviceId;
|
||||
final Property timestampProperty = HuaweiTemperatureSampleDao.Properties.LastTimestamp;
|
||||
|
||||
qb.where(deviceProperty.eq(dbDevice.getId()))
|
||||
.orderDesc(timestampProperty)
|
||||
.limit(1);
|
||||
|
||||
List<HuaweiTemperatureSample> samples = qb.build().list();
|
||||
if (samples.isEmpty())
|
||||
return 0;
|
||||
|
||||
HuaweiTemperatureSample sample = samples.get(0);
|
||||
return sample.getLastTimestamp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemperatureSample createSample() {
|
||||
throw new UnsupportedOperationException("read-only sample provider");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TemperatureSample getLatestSample() {
|
||||
Long userId = DBHelper.getUser(this.session).getId();
|
||||
Long deviceId = DBHelper.getDevice(this.device, this.session).getId();
|
||||
|
||||
if (deviceId == null || userId == null)
|
||||
return null;
|
||||
|
||||
QueryBuilder<HuaweiDictData> qb = this.session.getHuaweiDictDataDao().queryBuilder();
|
||||
qb.where(HuaweiDictDataDao.Properties.DeviceId.eq(deviceId))
|
||||
.where(HuaweiDictDataDao.Properties.UserId.eq(userId))
|
||||
.where(HuaweiDictDataDao.Properties.DictClass.eq(HuaweiDictTypes.SKIN_TEMPERATURE_CLASS));
|
||||
qb.orderDesc(HuaweiDictDataDao.Properties.StartTimestamp).limit(1);
|
||||
|
||||
final List<HuaweiDictData> data = qb.build().list();
|
||||
if (data.isEmpty())
|
||||
return null;
|
||||
|
||||
|
||||
QueryBuilder<HuaweiDictDataValues> qbv = this.session.getHuaweiDictDataValuesDao().queryBuilder();
|
||||
qbv.where(HuaweiDictDataValuesDao.Properties.DictType.eq(HuaweiDictTypes.SKIN_TEMPERATURE_VALUE)).where(HuaweiDictDataValuesDao.Properties.Tag.eq(10)).where(HuaweiDictDataValuesDao.Properties.DictId.eq(data.get(0).getDictId()));
|
||||
final List<HuaweiDictDataValues> valuesData = qbv.build().list();
|
||||
|
||||
if (valuesData.isEmpty())
|
||||
return null;
|
||||
|
||||
return new HuaweiTemperatureSample(valuesData.get(0).getHuaweiDictData().getStartTimestamp(), (float) conv2Double(valuesData.get(0).getValue()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TemperatureSample getLatestSample(final long until) {
|
||||
Long userId = DBHelper.getUser(this.session).getId();
|
||||
Long deviceId = DBHelper.getDevice(this.device, this.session).getId();
|
||||
|
||||
if (deviceId == null || userId == null)
|
||||
return null;
|
||||
|
||||
QueryBuilder<HuaweiDictData> qb = this.session.getHuaweiDictDataDao().queryBuilder();
|
||||
qb.where(HuaweiDictDataDao.Properties.StartTimestamp.le(until))
|
||||
.where(HuaweiDictDataDao.Properties.DeviceId.eq(deviceId))
|
||||
.where(HuaweiDictDataDao.Properties.UserId.eq(userId))
|
||||
.where(HuaweiDictDataDao.Properties.DictClass.eq(HuaweiDictTypes.SKIN_TEMPERATURE_CLASS));
|
||||
qb.orderDesc(HuaweiDictDataDao.Properties.StartTimestamp).limit(1);
|
||||
|
||||
final List<HuaweiDictData> data = qb.build().list();
|
||||
if (data.isEmpty())
|
||||
return null;
|
||||
|
||||
|
||||
QueryBuilder<HuaweiDictDataValues> qbv = this.session.getHuaweiDictDataValuesDao().queryBuilder();
|
||||
qbv.where(HuaweiDictDataValuesDao.Properties.DictType.eq(HuaweiDictTypes.SKIN_TEMPERATURE_VALUE)).where(HuaweiDictDataValuesDao.Properties.Tag.eq(10)).where(HuaweiDictDataValuesDao.Properties.DictId.eq(data.get(0).getDictId()));
|
||||
final List<HuaweiDictDataValues> valuesData = qbv.build().list();
|
||||
|
||||
if (valuesData.isEmpty())
|
||||
return null;
|
||||
|
||||
return new HuaweiTemperatureSample(valuesData.get(0).getHuaweiDictData().getStartTimestamp(), (float) conv2Double(valuesData.get(0).getValue()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TemperatureSample getFirstSample() {
|
||||
Long userId = DBHelper.getUser(this.session).getId();
|
||||
Long deviceId = DBHelper.getDevice(this.device, this.session).getId();
|
||||
|
||||
if (deviceId == null || userId == null)
|
||||
return null;
|
||||
|
||||
QueryBuilder<HuaweiDictData> qb = this.session.getHuaweiDictDataDao().queryBuilder();
|
||||
qb.where(HuaweiDictDataDao.Properties.DeviceId.eq(deviceId))
|
||||
.where(HuaweiDictDataDao.Properties.UserId.eq(userId))
|
||||
.where(HuaweiDictDataDao.Properties.DictClass.eq(HuaweiDictTypes.SKIN_TEMPERATURE_CLASS));
|
||||
qb.orderAsc(HuaweiDictDataDao.Properties.StartTimestamp).limit(1);
|
||||
|
||||
final List<HuaweiDictData> data = qb.build().list();
|
||||
if (data.isEmpty())
|
||||
return null;
|
||||
|
||||
QueryBuilder<HuaweiDictDataValues> qbv = this.session.getHuaweiDictDataValuesDao().queryBuilder();
|
||||
qbv.where(HuaweiDictDataValuesDao.Properties.DictType.eq(HuaweiDictTypes.SKIN_TEMPERATURE_VALUE)).where(HuaweiDictDataValuesDao.Properties.Tag.eq(10)).where(HuaweiDictDataValuesDao.Properties.DictId.eq(data.get(0).getDictId()));
|
||||
final List<HuaweiDictDataValues> valuesData = qbv.build().list();
|
||||
|
||||
if (valuesData.isEmpty())
|
||||
return null;
|
||||
|
||||
return new HuaweiTemperatureSample(valuesData.get(0).getHuaweiDictData().getStartTimestamp(), (float) conv2Double(valuesData.get(0).getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
+148
-129
@@ -27,6 +27,7 @@ import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.location.Location;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
@@ -39,6 +40,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -53,6 +55,7 @@ import de.greenrobot.dao.query.DeleteQuery;
|
||||
import de.greenrobot.dao.query.QueryBuilder;
|
||||
import kotlin.Triple;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBException;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||
@@ -77,6 +80,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiSleepStageSampl
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiSleepStatsSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiStressParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiStressSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTemperatureSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTruSleepParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTrueSleepSequenceDataParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.CameraRemote;
|
||||
@@ -95,6 +99,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiDictDataValuesDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiSleepStageSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiSleepStatsSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiStressSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiTemperatureSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutDataSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutDataSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuaweiWorkoutPaceSample;
|
||||
@@ -226,7 +231,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetT
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetWearLocationRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetWearMessagePushRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetNotificationCapabilitiesRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FitnessData;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetWorkModeRequest;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
@@ -952,7 +956,7 @@ public class HuaweiSupportProvider {
|
||||
huaweiDataSyncFindDevice = new HuaweiDataSyncFindDevice(HuaweiSupportProvider.this);
|
||||
}
|
||||
|
||||
if(getHuaweiCoordinator().supportsEmotion()) {
|
||||
if (getHuaweiCoordinator().supportsEmotion()) {
|
||||
huaweiDataSyncEmotion = new HuaweiDataSyncEmotion(HuaweiSupportProvider.this);
|
||||
}
|
||||
}
|
||||
@@ -1513,12 +1517,64 @@ public class HuaweiSupportProvider {
|
||||
HuaweiP2PDataDictionarySyncService P2PSyncService = HuaweiP2PDataDictionarySyncService.getRegisteredInstance(huaweiP2PManager);
|
||||
|
||||
if (P2PSyncService != null) {
|
||||
List<Integer> list = P2PSyncService.checkSupported(this.getHuaweiCoordinator(), Arrays.asList(HuaweiDictTypes.SKIN_TEMPERATURE_CLASS, HuaweiDictTypes.BLOOD_PRESSURE_CLASS));
|
||||
List<Integer> list = P2PSyncService.checkSupported(this.getHuaweiCoordinator(), Arrays.asList(HuaweiDictTypes.SKIN_TEMPERATURE_CLASS));
|
||||
if (!list.isEmpty()) {
|
||||
syncState.setP2pSync(true);
|
||||
P2PSyncService.startSync(list, complete -> {
|
||||
P2PSyncService.startSync(list, new HuaweiP2PDataDictionarySyncService.DictionarySyncCallback() {
|
||||
@Override
|
||||
public long onGetLastDataSyncTimestamp(int dictClass) {
|
||||
LOG.info("DictionarySyncCallback onGetLastDataDictLastTimestamp: {}", dictClass);
|
||||
if (dictClass == HuaweiDictTypes.SKIN_TEMPERATURE_CLASS) {
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
HuaweiTemperatureSampleProvider sleepStatsSampleProvider = new HuaweiTemperatureSampleProvider(gbDevice, db.getDaoSession());
|
||||
return sleepStatsSampleProvider.getLastFetchTimestamp();
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Exception for getting temperature start time", e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onData(int dictClass, List<HuaweiP2PDataDictionarySyncService.DictData> dictData) {
|
||||
LOG.info("DictionarySyncCallback onData: {}", dictClass);
|
||||
if (dictClass == HuaweiDictTypes.SKIN_TEMPERATURE_CLASS) {
|
||||
|
||||
List<HuaweiTemperatureSample> temperatureSamples = new ArrayList<>();
|
||||
|
||||
for (HuaweiP2PDataDictionarySyncService.DictData dt : dictData) {
|
||||
long timestamp = dt.getStartTimestamp();
|
||||
long lastTime = Math.max(dt.getEndTimestamp(), dt.getModifyTimestamp());
|
||||
for (HuaweiP2PDataDictionarySyncService.DictData.DictDataValue val : dt.getData()) {
|
||||
if (val.getTag() == 10 && val.getDataType() == HuaweiDictTypes.SKIN_TEMPERATURE_VALUE) {
|
||||
double skinTemperature = conv2Double(val.getValue());
|
||||
if (skinTemperature >= 20 && skinTemperature <= 42) {
|
||||
HuaweiTemperatureSample sample = new HuaweiTemperatureSample();
|
||||
sample.setTimestamp(timestamp);
|
||||
sample.setLastTimestamp(lastTime);
|
||||
sample.setTemperatureType(0);
|
||||
sample.setTemperature((float) skinTemperature);
|
||||
temperatureSamples.add(sample);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
final DaoSession session = db.getDaoSession();
|
||||
new HuaweiTemperatureSampleProvider(gbDevice, session).persistForDevice(context, gbDevice, temperatureSamples);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Cannot save skin temperature samples, continue");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(boolean complete) {
|
||||
LOG.info("Sync P2P Data complete");
|
||||
syncState.setP2pSync(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1761,6 +1817,7 @@ public class HuaweiSupportProvider {
|
||||
|
||||
/**
|
||||
* Add sleep activities
|
||||
*
|
||||
* @param data List of triples with [timestamp_start, timestamp_end, type]
|
||||
* @param source Source of the data
|
||||
*/
|
||||
@@ -2129,125 +2186,6 @@ public class HuaweiSupportProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public void addDictData(List<HuaweiP2PDataDictionarySyncService.DictData> dictData) {
|
||||
if (dictData.isEmpty())
|
||||
return;
|
||||
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
Long userId = DBHelper.getUser(db.getDaoSession()).getId();
|
||||
Long deviceId = DBHelper.getDevice(gbDevice, db.getDaoSession()).getId();
|
||||
|
||||
// TODO: Cache probably not necessary with an index on StartTimestamp
|
||||
// Assume it's in order, though we'll be fine if it is not
|
||||
// Note that SQLite BETWEEN is inclusive
|
||||
long cacheStartTime = dictData.get(0).getStartTimestamp();
|
||||
long cacheEndTime = dictData.get(dictData.size() - 1).getStartTimestamp();
|
||||
QueryBuilder<HuaweiDictData> qbCache = db.getDaoSession().getHuaweiDictDataDao().queryBuilder().where(
|
||||
HuaweiDictDataDao.Properties.UserId.eq(userId),
|
||||
HuaweiDictDataDao.Properties.DeviceId.eq(deviceId),
|
||||
HuaweiDictDataDao.Properties.StartTimestamp.between(cacheStartTime, cacheEndTime)
|
||||
);
|
||||
List<HuaweiDictData> cache = qbCache.build().list();
|
||||
|
||||
for (HuaweiP2PDataDictionarySyncService.DictData data : dictData) {
|
||||
// Avoid duplicates
|
||||
Long dictId = null;
|
||||
if (data.getStartTimestamp() >= cacheStartTime && data.getStartTimestamp() <= cacheEndTime) {
|
||||
// Cache hit - if it exists it will be in the cache
|
||||
for (HuaweiDictData d : cache) {
|
||||
if (d.getStartTimestamp() == data.getStartTimestamp() && d.getDictClass() == data.getDictClass()) {
|
||||
dictId = d.getDictId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Cache miss - check the database
|
||||
LOG.warn("P2P dedup cache miss");
|
||||
|
||||
// TODO: No index on StartTimestamp/DictClass, so terribly slow
|
||||
QueryBuilder<HuaweiDictData> qb = db.getDaoSession().getHuaweiDictDataDao().queryBuilder().where(
|
||||
HuaweiDictDataDao.Properties.UserId.eq(userId),
|
||||
HuaweiDictDataDao.Properties.DeviceId.eq(deviceId),
|
||||
HuaweiDictDataDao.Properties.DictClass.eq(data.getDictClass()),
|
||||
HuaweiDictDataDao.Properties.StartTimestamp.eq(data.getStartTimestamp())
|
||||
);
|
||||
List<HuaweiDictData> results = qb.build().list();
|
||||
if (!results.isEmpty())
|
||||
dictId = results.get(0).getDictId();
|
||||
}
|
||||
|
||||
HuaweiDictData dictSample = new HuaweiDictData(
|
||||
dictId,
|
||||
deviceId,
|
||||
userId,
|
||||
data.getDictClass(),
|
||||
data.getStartTimestamp(),
|
||||
data.getEndTimestamp(),
|
||||
data.getModifyTimestamp()
|
||||
);
|
||||
db.getDaoSession().getHuaweiDictDataDao().insertOrReplace(dictSample);
|
||||
addDictDataValue(dictSample.getDictId(), data.getData());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to add dict data", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addDictDataValue(Long dictId, List<HuaweiP2PDataDictionarySyncService.DictData.DictDataValue> dictDataValues) {
|
||||
if (dictId == null)
|
||||
return;
|
||||
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
HuaweiDictDataValuesDao dao = db.getDaoSession().getHuaweiDictDataValuesDao();
|
||||
|
||||
for (HuaweiP2PDataDictionarySyncService.DictData.DictDataValue dataValues : dictDataValues) {
|
||||
|
||||
HuaweiDictDataValues dictValue = new HuaweiDictDataValues(
|
||||
dictId,
|
||||
dataValues.getDataType(),
|
||||
dataValues.getTag(),
|
||||
dataValues.getValue()
|
||||
);
|
||||
dao.insertOrReplace(dictValue);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to add dict value to database", e);
|
||||
}
|
||||
}
|
||||
|
||||
public long getLastDataDictLastTimestamp(int dictClass) {
|
||||
long lastTimestamp = 0;
|
||||
if (dictClass == 0)
|
||||
return lastTimestamp;
|
||||
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
Long userId = DBHelper.getUser(db.getDaoSession()).getId();
|
||||
Long deviceId = DBHelper.getDevice(gbDevice, db.getDaoSession()).getId();
|
||||
|
||||
QueryBuilder<HuaweiDictData> qb = db.getDaoSession().getHuaweiDictDataDao().queryBuilder().where(
|
||||
HuaweiDictDataDao.Properties.UserId.eq(userId),
|
||||
HuaweiDictDataDao.Properties.DeviceId.eq(deviceId),
|
||||
HuaweiDictDataDao.Properties.DictClass.eq(dictClass)
|
||||
).orderRaw(
|
||||
// "max(MODIFY_TIMESTAMP, END_TIMESTAMP) DESC"
|
||||
String.format(
|
||||
"max(%s, %s) DESC",
|
||||
HuaweiDictDataDao.Properties.ModifyTimestamp.columnName,
|
||||
HuaweiDictDataDao.Properties.EndTimestamp.columnName
|
||||
)
|
||||
).limit(1);
|
||||
List<HuaweiDictData> results = qb.build().list();
|
||||
if (!results.isEmpty()) {
|
||||
lastTimestamp = Math.max(lastTimestamp, results.get(0).getModifyTimestamp());
|
||||
lastTimestamp = Math.max(lastTimestamp, results.get(0).getEndTimestamp());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Failed to select last timestamp value to database", e);
|
||||
}
|
||||
return lastTimestamp;
|
||||
}
|
||||
|
||||
|
||||
public void setWearLocation() {
|
||||
try {
|
||||
SetWearLocationRequest setWearLocationReq = new SetWearLocationRequest(this);
|
||||
@@ -2456,7 +2394,7 @@ public class HuaweiSupportProvider {
|
||||
}
|
||||
}
|
||||
|
||||
if(huaweiDataSyncEmotion != null && !automaticStressEnabled) {
|
||||
if (huaweiDataSyncEmotion != null && !automaticStressEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2872,7 +2810,7 @@ public class HuaweiSupportProvider {
|
||||
for (HuaweiSequenceDataParser.SequenceData sd : sequenceFileData.getSequenceDataList()) {
|
||||
LOG.info("SLEEP SequenceData: {}", sd);
|
||||
HuaweiTrueSleepSequenceDataParser.SleepSummary sleepDataSummary = HuaweiTrueSleepSequenceDataParser.parseSleepDataSummary(sequenceFileData, sd);
|
||||
if(sleepDataSummary == null) {
|
||||
if (sleepDataSummary == null) {
|
||||
LOG.warn("SLEEP DataSummary is null");
|
||||
continue;
|
||||
}
|
||||
@@ -2904,7 +2842,7 @@ public class HuaweiSupportProvider {
|
||||
LOG.info("SLEEP Time: {}", time);
|
||||
List<HuaweiTrueSleepSequenceDataParser.SleepStage> stages = HuaweiTrueSleepSequenceDataParser.parseSleepDetails(sd.getDetails(), time);
|
||||
LOG.info("SLEEP Stages: {}", stages);
|
||||
if(stages != null) {
|
||||
if (stages != null) {
|
||||
for (HuaweiTrueSleepSequenceDataParser.SleepStage st : stages) {
|
||||
HuaweiSleepStageSample sample = new HuaweiSleepStageSample();
|
||||
sample.setTimestamp(st.getTime() * 1000L);
|
||||
@@ -3183,12 +3121,93 @@ public class HuaweiSupportProvider {
|
||||
syncState.updateState(needSync);
|
||||
}
|
||||
|
||||
private double conv2Double(byte[] b) {
|
||||
return ByteBuffer.wrap(b).getDouble();
|
||||
}
|
||||
|
||||
public void onTestNewFunction() {
|
||||
gbDevice.setBusyTask(R.string.busy_task_downloading, getContext());
|
||||
gbDevice.sendDeviceUpdateIntent(getContext());
|
||||
|
||||
downloadDictTrueSleepData(0, (int) (System.currentTimeMillis() / 1000));
|
||||
AsyncTask.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long startTime = System.nanoTime();
|
||||
long count = 0;
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
DaoSession daoSession = db.getDaoSession();
|
||||
QueryBuilder<HuaweiDictDataValues> qbv1 = daoSession.getHuaweiDictDataValuesDao().queryBuilder();
|
||||
count = qbv1.count();
|
||||
|
||||
} catch (
|
||||
GBException e) {
|
||||
LOG.error("EX", e);
|
||||
} catch (
|
||||
Exception e) {
|
||||
LOG.error("EX2", e);
|
||||
}
|
||||
|
||||
int limit = 10000;
|
||||
int offset = 0;
|
||||
while (true) {
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
DaoSession daoSession = db.getDaoSession();
|
||||
|
||||
QueryBuilder<HuaweiDictDataValues> qbv = daoSession.getHuaweiDictDataValuesDao().queryBuilder();
|
||||
|
||||
qbv.where(HuaweiDictDataValuesDao.Properties.DictType.eq(HuaweiDictTypes.SKIN_TEMPERATURE_VALUE)).where(HuaweiDictDataValuesDao.Properties.Tag.eq(10)).limit(limit).offset(offset);
|
||||
|
||||
final List<HuaweiDictDataValues> valuesData = qbv.build().list();
|
||||
|
||||
if (valuesData.isEmpty())
|
||||
break;
|
||||
|
||||
|
||||
List<HuaweiTemperatureSample> res = new ArrayList<>();
|
||||
for (HuaweiDictDataValues vl : valuesData) {
|
||||
double skinTemperature = conv2Double(vl.getValue());
|
||||
if (skinTemperature >= 20 && skinTemperature <= 42) {
|
||||
res.add(new HuaweiTemperatureSample(vl.getHuaweiDictData().getStartTimestamp(), vl.getHuaweiDictData().getDeviceId(), vl.getHuaweiDictData().getUserId(), Math.max(vl.getHuaweiDictData().getModifyTimestamp(), vl.getHuaweiDictData().getEndTimestamp()), (float) skinTemperature, 0));
|
||||
}
|
||||
}
|
||||
daoSession.getHuaweiTemperatureSampleDao().insertInTx(res);
|
||||
offset += limit;
|
||||
LOG.info("Migrating: {}/{}", offset, count);
|
||||
} catch (GBException e) {
|
||||
LOG.error("EX", e);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
LOG.error("EX2", e);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Sleep error", e);
|
||||
}
|
||||
}
|
||||
|
||||
try (DBHandler db = GBApplication.acquireDB()) {
|
||||
DaoSession daoSession = db.getDaoSession();
|
||||
|
||||
final DeleteQuery<HuaweiDictDataValues> tableValuesDeleteQuery = daoSession.getHuaweiDictDataValuesDao().queryBuilder()
|
||||
.where(HuaweiDictDataValuesDao.Properties.DictType.eq(HuaweiDictTypes.SKIN_TEMPERATURE_VALUE))
|
||||
.buildDelete();
|
||||
tableValuesDeleteQuery.executeDeleteWithoutDetachingEntities();
|
||||
|
||||
final DeleteQuery<HuaweiDictData> tableDataDeleteQuery = daoSession.getHuaweiDictDataDao().queryBuilder()
|
||||
.where(HuaweiDictDataDao.Properties.DictClass.eq(HuaweiDictTypes.SKIN_TEMPERATURE_CLASS))
|
||||
.buildDelete();
|
||||
tableDataDeleteQuery.executeDeleteWithoutDetachingEntities();
|
||||
|
||||
} catch (
|
||||
GBException e) {
|
||||
LOG.error("EX", e);
|
||||
} catch (
|
||||
Exception e) {
|
||||
LOG.error("EX2", e);
|
||||
}
|
||||
LOG.info("Migrating took : {} ms", ((System.nanoTime() - startTime) / 1000000.0));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onMusicListReq() {
|
||||
|
||||
+39
-15
@@ -16,6 +16,8 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.p2p;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -37,12 +39,14 @@ public class HuaweiP2PDataDictionarySyncService extends HuaweiBaseP2PService {
|
||||
|
||||
public static final String MODULE = "hw.unitedevice.datadictionarysync";
|
||||
|
||||
private AtomicBoolean serviceAvailable = new AtomicBoolean(false);
|
||||
private final AtomicBoolean serviceAvailable = new AtomicBoolean(false);
|
||||
|
||||
|
||||
private List<Integer> classesToSync = null;
|
||||
|
||||
public interface DictionarySyncCallback {
|
||||
long onGetLastDataSyncTimestamp(int dictClass);
|
||||
void onData(int dictClass, List<HuaweiP2PDataDictionarySyncService.DictData> dictData);
|
||||
void onComplete(boolean complete);
|
||||
}
|
||||
|
||||
@@ -90,17 +94,25 @@ public class HuaweiP2PDataDictionarySyncService extends HuaweiBaseP2PService {
|
||||
|
||||
public void startSync(List<Integer> dictClasses, DictionarySyncCallback callback) {
|
||||
LOG.info("P2PDataDictionarySyncService startSync {}", dictClasses);
|
||||
if(callback == null) {
|
||||
LOG.error("P2PDataDictionarySyncService startSync callback is null");
|
||||
return;
|
||||
}
|
||||
classesToSync = dictClasses;
|
||||
if(classesToSync.isEmpty()) {
|
||||
callback.onComplete(false);
|
||||
return;
|
||||
}
|
||||
sendSyncRequest(classesToSync.remove(0), callback);
|
||||
sendSyncRequest(classesToSync.remove(0), 0, callback);
|
||||
}
|
||||
|
||||
private void sendSyncRequest(int dictClass, DictionarySyncCallback callback) {
|
||||
private void sendSyncRequest(int dictClass, long startTime, DictionarySyncCallback callback) {
|
||||
|
||||
LOG.info("P2PDataDictionarySyncService class {}", dictClass);
|
||||
if(callback == null) {
|
||||
LOG.error("P2PDataDictionarySyncService sendSyncRequest callback is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!serviceAvailable.get()) {
|
||||
LOG.info("P2PDataDictionarySyncService not available");
|
||||
@@ -113,8 +125,15 @@ public class HuaweiP2PDataDictionarySyncService extends HuaweiBaseP2PService {
|
||||
callback.onComplete(false);
|
||||
return;
|
||||
}
|
||||
if(startTime == 0) {
|
||||
startTime = callback.onGetLastDataSyncTimestamp(dictClass);
|
||||
}
|
||||
if(startTime < 0) {
|
||||
LOG.info("P2PDataDictionarySyncService start time is less then 0");
|
||||
callback.onComplete(false);
|
||||
return;
|
||||
}
|
||||
|
||||
long startTime = manager.getSupportProvider().getLastDataDictLastTimestamp(dictClass);
|
||||
if(startTime > 0) {
|
||||
startTime += 1000;
|
||||
}
|
||||
@@ -146,15 +165,11 @@ public class HuaweiP2PDataDictionarySyncService extends HuaweiBaseP2PService {
|
||||
|
||||
@Override
|
||||
public void registered() {
|
||||
sendPing(new HuaweiP2PCallback() {
|
||||
@Override
|
||||
public void onResponse(int code, byte[] data) {
|
||||
sendPing((code, data) -> {
|
||||
if ((byte) code != (byte) 0xca)
|
||||
return;
|
||||
serviceAvailable.set(true);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -186,6 +201,7 @@ public class HuaweiP2PDataDictionarySyncService extends HuaweiBaseP2PService {
|
||||
return value;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("HuaweiDictDataValue{");
|
||||
@@ -237,6 +253,7 @@ public class HuaweiP2PDataDictionarySyncService extends HuaweiBaseP2PService {
|
||||
return data;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("HuaweiDictSample{");
|
||||
@@ -255,12 +272,10 @@ public class HuaweiP2PDataDictionarySyncService extends HuaweiBaseP2PService {
|
||||
if (data[0] == 1) {
|
||||
DictionarySyncCallback callback = null;
|
||||
try {
|
||||
|
||||
|
||||
HuaweiTLV tlv = new HuaweiTLV();
|
||||
tlv.parse(data, 1, data.length - 1);
|
||||
|
||||
int operation = tlv.getInteger(0x01); ///???
|
||||
int operation = tlv.getInteger(0x01);
|
||||
int dictClass = tlv.getInteger(0x02);
|
||||
|
||||
if(!currentRequests.containsKey(dictClass)) {
|
||||
@@ -272,10 +287,18 @@ public class HuaweiP2PDataDictionarySyncService extends HuaweiBaseP2PService {
|
||||
return;
|
||||
}
|
||||
|
||||
if(operation != 1) {
|
||||
return;
|
||||
//I never see value differ from 1. So I don't know how to interpret others. Just ignore for now
|
||||
//callback.onComplete(true);
|
||||
}
|
||||
|
||||
//NOTE: all tags with high bit set should be parsed as container
|
||||
|
||||
List<DictData> result = new ArrayList<>();
|
||||
|
||||
long lastTimestamp = 0;
|
||||
|
||||
for (HuaweiTLV blockTlv : tlv.getObjects(0x83)) {
|
||||
for (HuaweiTLV l : blockTlv.getObjects(0x84)) {
|
||||
//5 - start time, 6 - end time, 0xc - modify time
|
||||
@@ -297,19 +320,20 @@ public class HuaweiP2PDataDictionarySyncService extends HuaweiBaseP2PService {
|
||||
}
|
||||
}
|
||||
result.add(new DictData(dictClass, startTimestamp, endTimestamp, modifyTimestamp, dataValues));
|
||||
lastTimestamp = Math.max(lastTimestamp, Math.max(endTimestamp, modifyTimestamp));
|
||||
}
|
||||
}
|
||||
|
||||
manager.getSupportProvider().addDictData(result);
|
||||
callback.onData(dictClass, result);
|
||||
|
||||
if (!result.isEmpty()) {
|
||||
sendSyncRequest(dictClass, callback);
|
||||
sendSyncRequest(dictClass, lastTimestamp, callback);
|
||||
} else {
|
||||
if(classesToSync.isEmpty()) {
|
||||
classesToSync = null;
|
||||
callback.onComplete(true);
|
||||
} else {
|
||||
sendSyncRequest(classesToSync.remove(0), callback);
|
||||
sendSyncRequest(classesToSync.remove(0), 0, callback);
|
||||
}
|
||||
}
|
||||
} catch (HuaweiPacket.MissingTagException e) {
|
||||
|
||||
Reference in New Issue
Block a user