Xiaomi: Persist daily summary

This commit is contained in:
José Rebelo 2023-12-12 20:26:55 +00:00
parent 2d89fdf11b
commit bddec00de1
2 changed files with 90 additions and 26 deletions

View File

@ -45,7 +45,7 @@ public class GBDaoGenerator {
public static void main(String[] args) throws Exception {
final Schema schema = new Schema(64, MAIN_PACKAGE + ".entities");
final Schema schema = new Schema(65, MAIN_PACKAGE + ".entities");
Entity userAttributes = addUserAttributes(schema);
Entity user = addUserInfo(schema, userAttributes);
@ -72,6 +72,7 @@ public class GBDaoGenerator {
addHuamiSleepRespiratoryRateSample(schema, user, device);
addXiaomiActivitySample(schema, user, device);
addXiaomiSleepTimeSamples(schema, user, device);
addXiaomiDailySummarySamples(schema, user, device);
addPebbleHealthActivitySample(schema, user, device);
addPebbleHealthActivityKindOverlay(schema, user, device);
addPebbleMisfitActivitySample(schema, user, device);
@ -347,6 +348,37 @@ public class GBDaoGenerator {
return sample;
}
private static Entity addXiaomiDailySummarySamples(Schema schema, Entity user, Entity device) {
Entity sample = addEntity(schema, "XiaomiDailySummarySample");
addCommonTimeSampleProperties("AbstractTimeSample", sample, user, device);
sample.addIntProperty("timezone");
sample.addIntProperty("steps");
sample.addIntProperty("hrResting");
sample.addIntProperty("hrMax");
sample.addIntProperty("hrMaxTs");
sample.addIntProperty("hrMin");
sample.addIntProperty("hrMinTs");
sample.addIntProperty("hrAvg");
sample.addIntProperty("stressAvg");
sample.addIntProperty("stressMax");
sample.addIntProperty("stressMin");
sample.addIntProperty("standing");
sample.addIntProperty("calories");
sample.addIntProperty("spo2Max");
sample.addIntProperty("spo2MaxTs");
sample.addIntProperty("spo2Min");
sample.addIntProperty("spo2MinTs");
sample.addIntProperty("spo2Avg");
sample.addIntProperty("trainingLoadDay");
sample.addIntProperty("trainingLoadWeek");
sample.addIntProperty("trainingLoadLevel");
sample.addIntProperty("vitalityIncreaseLight");
sample.addIntProperty("vitalityIncreaseModerate");
sample.addIntProperty("vitalityIncreaseHigh");
sample.addIntProperty("vitalityCurrent");
return sample;
}
private static void addHeartRateProperties(Entity activitySample) {
activitySample.addIntProperty(SAMPLE_HEART_RATE).notNull().codeBeforeGetterAndSetter(OVERRIDE);
}

View File

@ -16,12 +16,21 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.activity.impl;
import android.widget.Toast;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiDailySummarySampleProvider;
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.XiaomiDailySummarySample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.activity.XiaomiActivityFileId;
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.activity.XiaomiActivityParser;
@ -49,39 +58,62 @@ public class DailySummaryParser extends XiaomiActivityParser {
LOG.debug("Header: {}", GB.hexdump(header));
final int steps = buf.getInt();
final XiaomiDailySummarySample sample = new XiaomiDailySummarySample();
sample.setTimestamp(fileId.getTimestamp().getTime());
sample.setTimezone(fileId.getTimezone());
sample.setSteps(buf.getInt());
final int unk1 = buf.get() & 0xff; // 0
final int unk2 = buf.get() & 0xff; // 0
final int unk3 = buf.get() & 0xff; // 0
final int hrResting = buf.get() & 0xff;
final int hrMax = buf.get() & 0xff;
final int hrMaxTs = buf.getInt();
final int hrMin = buf.get() & 0xff;
final int hrMinTs = buf.getInt();
final int hrAvg = buf.get() & 0xff;
final int stressAvg = buf.get() & 0xff;
final int stressMax = buf.get() & 0xff;
final int stressMin = buf.get() & 0xff;
final int unk4 = buf.get() & 0xff; // 0
final int unk5 = buf.get() & 0xff; // 0
final int unk6 = buf.get() & 0xff; // 0
final int calories = buf.getShort();
sample.setHrResting(buf.get() & 0xff);
sample.setHrMax(buf.get() & 0xff);
sample.setHrMaxTs(buf.getInt());
sample.setHrMin(buf.get() & 0xff);
sample.setHrMinTs(buf.getInt());
sample.setHrAvg(buf.get() & 0xff);
sample.setStressAvg(buf.get() & 0xff);
sample.setStressMax(buf.get() & 0xff);
sample.setStressMin(buf.get() & 0xff);
final byte[] standingArr = new byte[3];
buf.get(standingArr);
// each bit represents one hour where the user was standing up for that day,
// starting at 00:00-01:00. Let's convert it to an int
int standing = (standingArr[0] | (standingArr[1] << 8) | (standingArr[2] << 16)) & 0x00FFFFFF;
sample.setStanding(standing);
sample.setCalories((int) buf.getShort());
final int unk7 = buf.get() & 0xff; // 0
final int unk8 = buf.get() & 0xff; // 0
final int unk9 = buf.get() & 0xff; // 0
final int spo2Max = buf.get() & 0xff;
final int spo2MaxTs = buf.getInt();
final int spo2Min = buf.get() & 0xff;
final int spo2MinTs = buf.getInt();
final int spo2Avg = buf.get() & 0xff;
final int trainingLoadMaybe1 = buf.getShort();
final int trainingLoadMaybe2 = buf.getShort();
final int trainingLoadMaybe3 = buf.get() & 0xff;
sample.setSpo2Max(buf.get() & 0xff);
sample.setSpo2MaxTs(buf.getInt());
sample.setSpo2Min(buf.get() & 0xff);
sample.setSpo2MinTs(buf.getInt());
sample.setSpo2Avg(buf.get() & 0xff);
sample.setTrainingLoadDay((int) buf.getShort());
sample.setTrainingLoadWeek((int) buf.getShort());
sample.setTrainingLoadLevel(buf.get() & 0xff); // TODO confirm - 1 for low training load level?
sample.setVitalityIncreaseLight(buf.get() & 0xff);
sample.setVitalityIncreaseModerate(buf.get() & 0xff);
sample.setVitalityIncreaseHigh(buf.get() & 0xff);
sample.setVitalityCurrent((int) buf.getShort());
// TODO vitality somewhere?
// TODO persist everything
LOG.debug("Persisting 1 daily summary sample");
LOG.warn("Persisting daily summary is not implemented");
try (DBHandler handler = GBApplication.acquireDB()) {
final DaoSession session = handler.getDaoSession();
final GBDevice device = support.getDevice();
sample.setDevice(DBHelper.getDevice(device, session));
sample.setUser(DBHelper.getUser(session));
final XiaomiDailySummarySampleProvider sampleProvider = new XiaomiDailySummarySampleProvider(device, session);
sampleProvider.addSample(sample);
} catch (final Exception e) {
GB.toast(support.getContext(), "Error saving daily summary", Toast.LENGTH_LONG, GB.ERROR);
LOG.error("Error saving daily summary", e);
return false;
}
return true;
}