mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-09 03:37:03 +01:00
Refactor ActivityKind into an enum
This commit is contained in:
parent
8c7cc98d36
commit
34378a4a11
@ -46,9 +46,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
|||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -75,8 +72,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
|||||||
public class ActivitySummariesActivity extends AbstractListActivity<BaseActivitySummary> {
|
public class ActivitySummariesActivity extends AbstractListActivity<BaseActivitySummary> {
|
||||||
static final int ACTIVITY_FILTER = 1;
|
static final int ACTIVITY_FILTER = 1;
|
||||||
static final int ACTIVITY_DETAIL = 11;
|
static final int ACTIVITY_DETAIL = 11;
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ActivitySummariesActivity.class);
|
HashMap<String, ActivityKind> activityKindMap = new HashMap<>(0);
|
||||||
HashMap<String, Integer> activityKindMap = new HashMap<>(0);
|
|
||||||
int activityFilter = 0;
|
int activityFilter = 0;
|
||||||
long dateFromFilter = 0;
|
long dateFromFilter = 0;
|
||||||
long dateToFilter = 0;
|
long dateToFilter = 0;
|
||||||
@ -326,15 +322,14 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LinkedHashMap fillKindMap() {
|
private LinkedHashMap<String, ActivityKind> fillKindMap() {
|
||||||
LinkedHashMap<String, Integer> newMap = new LinkedHashMap<>(0); //reset
|
LinkedHashMap<String, ActivityKind> newMap = new LinkedHashMap<>(0); //reset
|
||||||
|
|
||||||
newMap.put(getString(R.string.activity_summaries_all_activities), 0);
|
newMap.put(getString(R.string.activity_summaries_all_activities), ActivityKind.UNKNOWN);
|
||||||
for (BaseActivitySummary item : getItemAdapter().getItems()) {
|
for (BaseActivitySummary item : getItemAdapter().getItems()) {
|
||||||
String activityName = ActivityKind.asString(item.getActivityKind(), this);
|
String activityName = ActivityKind.fromCode(item.getActivityKind()).getLabel(this);
|
||||||
if (!newMap.containsKey(activityName) && item.getActivityKind() != 0) {
|
if (!newMap.containsKey(activityName) && item.getActivityKind() != 0) {
|
||||||
newMap.put(activityName, item.getActivityKind());
|
newMap.put(activityName, ActivityKind.fromCode(item.getActivityKind()));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newMap;
|
return newMap;
|
||||||
@ -395,7 +390,7 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
|
|||||||
uris.add(FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".screenshot_provider", file));
|
uris.add(FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".screenshot_provider", file));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uris.size() > 0) {
|
if (!uris.isEmpty()) {
|
||||||
final Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
|
final Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
|
||||||
intent.setType("application/gpx+xml");
|
intent.setType("application/gpx+xml");
|
||||||
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
|
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
|
||||||
|
@ -75,7 +75,7 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
|
|||||||
long dateFromFilter = 0;
|
long dateFromFilter = 0;
|
||||||
long dateToFilter = 0;
|
long dateToFilter = 0;
|
||||||
String nameContainsFilter;
|
String nameContainsFilter;
|
||||||
HashMap<String, Integer> activityKindMap = new HashMap<>(1);
|
HashMap<String, ActivityKind> activityKindMap = new HashMap<>(1);
|
||||||
List<Long> itemsFilter;
|
List<Long> itemsFilter;
|
||||||
long deviceFilter;
|
long deviceFilter;
|
||||||
long initial_deviceFilter;
|
long initial_deviceFilter;
|
||||||
@ -87,7 +87,7 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
Bundle bundle = this.getIntent().getExtras();
|
Bundle bundle = this.getIntent().getExtras();
|
||||||
|
|
||||||
activityKindMap = (HashMap<String, Integer>) bundle.getSerializable("activityKindMap");
|
activityKindMap = (HashMap<String, ActivityKind>) bundle.getSerializable("activityKindMap");
|
||||||
itemsFilter = (List<Long>) bundle.getSerializable("itemsFilter");
|
itemsFilter = (List<Long>) bundle.getSerializable("itemsFilter");
|
||||||
activityFilter = bundle.getInt("activityFilter", 0);
|
activityFilter = bundle.getInt("activityFilter", 0);
|
||||||
dateFromFilter = bundle.getLong("dateFromFilter", 0);
|
dateFromFilter = bundle.getLong("dateFromFilter", 0);
|
||||||
@ -120,13 +120,13 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
|
|||||||
final Spinner filterKindSpinner = findViewById(R.id.select_kind);
|
final Spinner filterKindSpinner = findViewById(R.id.select_kind);
|
||||||
ArrayList<SpinnerWithIconItem> kindArray = new ArrayList<>();
|
ArrayList<SpinnerWithIconItem> kindArray = new ArrayList<>();
|
||||||
|
|
||||||
for (Map.Entry<String, Integer> item : activityKindMap.entrySet()) {
|
for (Map.Entry<String, ActivityKind> item : activityKindMap.entrySet()) {
|
||||||
if (item.getValue() == 0) continue; //do not put here All devices, but we do need them in the array
|
if (item.getValue() == ActivityKind.UNKNOWN) continue; //do not put here All devices, but we do need them in the array
|
||||||
kindArray.add(new SpinnerWithIconItem(item.getKey(), new Long(item.getValue()), ActivityKind.getIconId(item.getValue())));
|
kindArray.add(new SpinnerWithIconItem(item.getKey(), (long) item.getValue().getCode(), item.getValue().getIcon()));
|
||||||
}
|
}
|
||||||
|
|
||||||
//ensure that all items is always first in the list, this is an issue on old android
|
//ensure that all items is always first in the list, this is an issue on old android
|
||||||
SpinnerWithIconItem allActivities = new SpinnerWithIconItem(getString(R.string.activity_summaries_all_activities), new Long(0), ActivityKind.getIconId(0));
|
SpinnerWithIconItem allActivities = new SpinnerWithIconItem(getString(R.string.activity_summaries_all_activities), (long) ActivityKind.UNKNOWN.getCode(), ActivityKind.UNKNOWN.getIcon());
|
||||||
kindArray.add(0, allActivities);
|
kindArray.add(0, allActivities);
|
||||||
|
|
||||||
SpinnerWithIconAdapter adapter = new SpinnerWithIconAdapter(this,
|
SpinnerWithIconAdapter adapter = new SpinnerWithIconAdapter(this,
|
||||||
@ -407,12 +407,14 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
|
|||||||
return newMap;
|
return newMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpinnerWithIconItem getKindByValue(Integer value) {
|
public SpinnerWithIconItem getKindByValue(int value) {
|
||||||
for (Map.Entry<String, Integer> entry : activityKindMap.entrySet()) {
|
for (Map.Entry<String, ActivityKind> entry : activityKindMap.entrySet()) {
|
||||||
if (Objects.equals(value, entry.getValue())) {
|
if (value == entry.getValue().getCode()) {
|
||||||
return new SpinnerWithIconItem(entry.getKey(),
|
return new SpinnerWithIconItem(
|
||||||
new Long(entry.getValue()),
|
entry.getKey(),
|
||||||
ActivityKind.getIconId(entry.getValue()));
|
(long) entry.getValue().getCode(),
|
||||||
|
entry.getValue().getIcon()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -434,7 +436,7 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
|
|||||||
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
|
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
|
||||||
SpinnerWithIconItem selectedItem = (SpinnerWithIconItem) parent.getItemAtPosition(pos);
|
SpinnerWithIconItem selectedItem = (SpinnerWithIconItem) parent.getItemAtPosition(pos);
|
||||||
String activity = selectedItem.getText();
|
String activity = selectedItem.getText();
|
||||||
activityFilter = activityKindMap.get(activity);
|
activityFilter = activityKindMap.get(activity).getCode();
|
||||||
update_filter_fields();
|
update_filter_fields();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
|
|||||||
|
|
||||||
private void makeSummaryHeader(BaseActivitySummary item) {
|
private void makeSummaryHeader(BaseActivitySummary item) {
|
||||||
//make view of data from main part of item
|
//make view of data from main part of item
|
||||||
String activitykindname = ActivityKind.asString(item.getActivityKind(), getApplicationContext());
|
String activitykindname = ActivityKind.fromCode(item.getActivityKind()).getLabel(getApplicationContext());
|
||||||
String activityname = item.getName();
|
String activityname = item.getName();
|
||||||
Date starttime = item.getStartTime();
|
Date starttime = item.getStartTime();
|
||||||
Date endtime = item.getEndTime();
|
Date endtime = item.getEndTime();
|
||||||
@ -354,7 +354,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
|
|||||||
String durationhms = DateTimeUtils.formatDurationHoursMinutes((endtime.getTime() - starttime.getTime()), TimeUnit.MILLISECONDS);
|
String durationhms = DateTimeUtils.formatDurationHoursMinutes((endtime.getTime() - starttime.getTime()), TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
ImageView activity_icon = findViewById(R.id.item_image);
|
ImageView activity_icon = findViewById(R.id.item_image);
|
||||||
activity_icon.setImageResource(ActivityKind.getIconId(item.getActivityKind()));
|
activity_icon.setImageResource(ActivityKind.fromCode(item.getActivityKind()).getIcon());
|
||||||
|
|
||||||
TextView activity_kind = findViewById(R.id.activitykind);
|
TextView activity_kind = findViewById(R.id.activitykind);
|
||||||
activity_kind.setText(activitykindname);
|
activity_kind.setText(activitykindname);
|
||||||
@ -594,7 +594,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
|
|||||||
int height = layout.getChildAt(0).getWidth();
|
int height = layout.getChildAt(0).getWidth();
|
||||||
Bitmap screenShot = getScreenShot(layout, width, height, context);
|
Bitmap screenShot = getScreenShot(layout, width, height, context);
|
||||||
|
|
||||||
String fileName = FileUtils.makeValidFileName("Screenshot-" + ActivityKind.asString(currentItem.getActivityKind(), context).toLowerCase() + "-" + DateTimeUtils.formatIso8601(currentItem.getStartTime()) + ".png");
|
String fileName = FileUtils.makeValidFileName("Screenshot-" + ActivityKind.fromCode(currentItem.getActivityKind()).getLabel(context).toLowerCase() + "-" + DateTimeUtils.formatIso8601(currentItem.getStartTime()) + ".png");
|
||||||
try {
|
try {
|
||||||
File targetFile = new File(FileUtils.getExternalFilesDir(), fileName);
|
File targetFile = new File(FileUtils.getExternalFilesDir(), fileName);
|
||||||
FileOutputStream fOut = new FileOutputStream(targetFile);
|
FileOutputStream fOut = new FileOutputStream(targetFile);
|
||||||
|
@ -261,7 +261,7 @@ public class ControlCenterv2 extends AppCompatActivity
|
|||||||
// Signal DeviceCommunicationService to fetch activity for all connected devices
|
// Signal DeviceCommunicationService to fetch activity for all connected devices
|
||||||
Intent intent = new Intent(getApplicationContext(), DeviceCommunicationService.class);
|
Intent intent = new Intent(getApplicationContext(), DeviceCommunicationService.class);
|
||||||
intent.setAction(DeviceService.ACTION_FETCH_RECORDED_DATA)
|
intent.setAction(DeviceService.ACTION_FETCH_RECORDED_DATA)
|
||||||
.putExtra(DeviceService.EXTRA_RECORDED_DATA_TYPES, ActivityKind.TYPE_ACTIVITY);
|
.putExtra(DeviceService.EXTRA_RECORDED_DATA_TYPES, ActivityKind.ACTIVITY);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
// Hide 'refreshing' animation immediately if no health devices are connected
|
// Hide 'refreshing' animation immediately if no health devices are connected
|
||||||
List<GBDevice> devices1 = GBApplication.app().getDeviceManager().getDevices();
|
List<GBDevice> devices1 = GBApplication.app().getDeviceManager().getDevices();
|
||||||
|
@ -63,6 +63,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardSleepW
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardStepsWidget;
|
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardStepsWidget;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardTodayWidget;
|
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardTodayWidget;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DashboardUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.DashboardUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||||
@ -422,11 +423,11 @@ public class DashboardFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class GeneralizedActivity implements Serializable {
|
public static class GeneralizedActivity implements Serializable {
|
||||||
public int activityKind;
|
public ActivityKind activityKind;
|
||||||
public long timeFrom;
|
public long timeFrom;
|
||||||
public long timeTo;
|
public long timeTo;
|
||||||
|
|
||||||
public GeneralizedActivity(int activityKind, long timeFrom, long timeTo) {
|
public GeneralizedActivity(ActivityKind activityKind, long timeFrom, long timeTo) {
|
||||||
this.activityKind = activityKind;
|
this.activityKind = activityKind;
|
||||||
this.timeFrom = timeFrom;
|
this.timeFrom = timeFrom;
|
||||||
this.timeTo = timeTo;
|
this.timeTo = timeTo;
|
||||||
|
@ -45,12 +45,13 @@ import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||||
|
|
||||||
public abstract class AbstractActivityChartFragment<D extends ChartsData> extends AbstractChartFragment<D> {
|
public abstract class AbstractActivityChartFragment<D extends ChartsData> extends AbstractChartFragment<D> {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractActivityChartFragment.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AbstractActivityChartFragment.class);
|
||||||
|
|
||||||
|
public static final float Y_VALUE_DEEP_SLEEP = 0.01f;
|
||||||
|
|
||||||
public boolean supportsHeartrate(GBDevice device) {
|
public boolean supportsHeartrate(GBDevice device) {
|
||||||
DeviceCoordinator coordinator = device.getDeviceCoordinator();
|
DeviceCoordinator coordinator = device.getDeviceCoordinator();
|
||||||
return coordinator != null && coordinator.supportsHeartRateMeasurement(device);
|
return coordinator != null && coordinator.supportsHeartRateMeasurement(device);
|
||||||
@ -62,11 +63,11 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected static final class ActivityConfig {
|
protected static final class ActivityConfig {
|
||||||
public final int type;
|
public final ActivityKind type;
|
||||||
public final String label;
|
public final String label;
|
||||||
public final Integer color;
|
public final Integer color;
|
||||||
|
|
||||||
public ActivityConfig(int kind, String label, Integer color) {
|
public ActivityConfig(ActivityKind kind, String label, Integer color) {
|
||||||
this.type = kind;
|
this.type = kind;
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
@ -122,22 +123,22 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
|
|||||||
HEARTRATE_LABEL = getContext().getString(R.string.charts_legend_heartrate);
|
HEARTRATE_LABEL = getContext().getString(R.string.charts_legend_heartrate);
|
||||||
HEARTRATE_AVERAGE_LABEL = getContext().getString(R.string.charts_legend_heartrate_average);
|
HEARTRATE_AVERAGE_LABEL = getContext().getString(R.string.charts_legend_heartrate_average);
|
||||||
|
|
||||||
akActivity = new ActivityConfig(ActivityKind.TYPE_ACTIVITY, getString(R.string.abstract_chart_fragment_kind_activity), AK_ACTIVITY_COLOR);
|
akActivity = new ActivityConfig(ActivityKind.ACTIVITY, getString(R.string.abstract_chart_fragment_kind_activity), AK_ACTIVITY_COLOR);
|
||||||
akLightSleep = new ActivityConfig(ActivityKind.TYPE_LIGHT_SLEEP, getString(R.string.abstract_chart_fragment_kind_light_sleep), AK_LIGHT_SLEEP_COLOR);
|
akLightSleep = new ActivityConfig(ActivityKind.LIGHT_SLEEP, getString(R.string.abstract_chart_fragment_kind_light_sleep), AK_LIGHT_SLEEP_COLOR);
|
||||||
akDeepSleep = new ActivityConfig(ActivityKind.TYPE_DEEP_SLEEP, getString(R.string.abstract_chart_fragment_kind_deep_sleep), AK_DEEP_SLEEP_COLOR);
|
akDeepSleep = new ActivityConfig(ActivityKind.DEEP_SLEEP, getString(R.string.abstract_chart_fragment_kind_deep_sleep), AK_DEEP_SLEEP_COLOR);
|
||||||
akRemSleep = new ActivityConfig(ActivityKind.TYPE_REM_SLEEP, getString(R.string.abstract_chart_fragment_kind_rem_sleep), AK_REM_SLEEP_COLOR);
|
akRemSleep = new ActivityConfig(ActivityKind.REM_SLEEP, getString(R.string.abstract_chart_fragment_kind_rem_sleep), AK_REM_SLEEP_COLOR);
|
||||||
akNotWorn = new ActivityConfig(ActivityKind.TYPE_NOT_WORN, getString(R.string.abstract_chart_fragment_kind_not_worn), AK_NOT_WORN_COLOR);
|
akNotWorn = new ActivityConfig(ActivityKind.NOT_WORN, getString(R.string.abstract_chart_fragment_kind_not_worn), AK_NOT_WORN_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Integer getColorFor(int activityKind) {
|
protected Integer getColorFor(ActivityKind activityKind) {
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
return akDeepSleep.color;
|
return akDeepSleep.color;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
return akLightSleep.color;
|
return akLightSleep.color;
|
||||||
case ActivityKind.TYPE_REM_SLEEP:
|
case REM_SLEEP:
|
||||||
return akRemSleep.color;
|
return akRemSleep.color;
|
||||||
case ActivityKind.TYPE_ACTIVITY:
|
case ACTIVITY:
|
||||||
return akActivity.color;
|
return akActivity.color;
|
||||||
}
|
}
|
||||||
return akActivity.color;
|
return akActivity.color;
|
||||||
@ -166,12 +167,6 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
|
|||||||
return provider.getActivitySamples(tsFrom, tsTo);
|
return provider.getActivitySamples(tsFrom, tsTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected List<? extends ActivitySample> getSleepSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
|
|
||||||
SampleProvider<? extends ActivitySample> provider = getProvider(db, device);
|
|
||||||
return provider.getSleepSamples(tsFrom, tsTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DefaultChartsData<LineData> refresh(GBDevice gbDevice, List<? extends ActivitySample> samples) {
|
public DefaultChartsData<LineData> refresh(GBDevice gbDevice, List<? extends ActivitySample> samples) {
|
||||||
// Calendar cal = GregorianCalendar.getInstance();
|
// Calendar cal = GregorianCalendar.getInstance();
|
||||||
// cal.clear();
|
// cal.clear();
|
||||||
@ -187,7 +182,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
|
|||||||
boolean annotate = true;
|
boolean annotate = true;
|
||||||
boolean use_steps_as_movement;
|
boolean use_steps_as_movement;
|
||||||
|
|
||||||
int last_type = ActivityKind.TYPE_UNKNOWN;
|
ActivityKind last_type = ActivityKind.UNKNOWN;
|
||||||
|
|
||||||
int numEntries = samples.size();
|
int numEntries = samples.size();
|
||||||
List<Entry> activityEntries = new ArrayList<>(numEntries);
|
List<Entry> activityEntries = new ArrayList<>(numEntries);
|
||||||
@ -203,7 +198,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
|
|||||||
|
|
||||||
for (int i = 0; i < numEntries; i++) {
|
for (int i = 0; i < numEntries; i++) {
|
||||||
ActivitySample sample = samples.get(i);
|
ActivitySample sample = samples.get(i);
|
||||||
int type = sample.getKind();
|
ActivityKind type = sample.getKind();
|
||||||
int ts = tsTranslation.shorten(sample.getTimestamp());
|
int ts = tsTranslation.shorten(sample.getTimestamp());
|
||||||
|
|
||||||
// System.out.println(ts);
|
// System.out.println(ts);
|
||||||
@ -223,7 +218,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
|
|||||||
|
|
||||||
float value = movement;
|
float value = movement;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
if (last_type != type) { //FIXME: this is ugly but it works (repeated in each case)
|
if (last_type != type) { //FIXME: this is ugly but it works (repeated in each case)
|
||||||
deepSleepEntries.add(createLineEntry(0, ts - 1));
|
deepSleepEntries.add(createLineEntry(0, ts - 1));
|
||||||
|
|
||||||
@ -232,9 +227,9 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
|
|||||||
notWornEntries.add(createLineEntry(0, ts));
|
notWornEntries.add(createLineEntry(0, ts));
|
||||||
activityEntries.add(createLineEntry(0, ts));
|
activityEntries.add(createLineEntry(0, ts));
|
||||||
}
|
}
|
||||||
deepSleepEntries.add(createLineEntry(value + SleepUtils.Y_VALUE_DEEP_SLEEP, ts));
|
deepSleepEntries.add(createLineEntry(value + Y_VALUE_DEEP_SLEEP, ts));
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
if (last_type != type) {
|
if (last_type != type) {
|
||||||
lightSleepEntries.add(createLineEntry(0, ts - 1));
|
lightSleepEntries.add(createLineEntry(0, ts - 1));
|
||||||
|
|
||||||
@ -245,7 +240,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
|
|||||||
}
|
}
|
||||||
lightSleepEntries.add(createLineEntry(value, ts));
|
lightSleepEntries.add(createLineEntry(value, ts));
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_REM_SLEEP:
|
case REM_SLEEP:
|
||||||
if (last_type != type) {
|
if (last_type != type) {
|
||||||
remSleepEntries.add(createLineEntry(0, ts - 1));
|
remSleepEntries.add(createLineEntry(0, ts - 1));
|
||||||
|
|
||||||
@ -256,7 +251,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
|
|||||||
}
|
}
|
||||||
remSleepEntries.add(createLineEntry(value, ts));
|
remSleepEntries.add(createLineEntry(value, ts));
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_NOT_WORN:
|
case NOT_WORN:
|
||||||
if (last_type != type) {
|
if (last_type != type) {
|
||||||
notWornEntries.add(createLineEntry(0, ts - 1));
|
notWornEntries.add(createLineEntry(0, ts - 1));
|
||||||
|
|
||||||
@ -265,7 +260,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
|
|||||||
remSleepEntries.add(createLineEntry(0, ts));
|
remSleepEntries.add(createLineEntry(0, ts));
|
||||||
activityEntries.add(createLineEntry(0, ts));
|
activityEntries.add(createLineEntry(0, ts));
|
||||||
}
|
}
|
||||||
notWornEntries.add(createLineEntry(SleepUtils.Y_VALUE_DEEP_SLEEP, ts)); //a small value, just to show something on the graphs
|
notWornEntries.add(createLineEntry(Y_VALUE_DEEP_SLEEP, ts)); //a small value, just to show something on the graphs
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// short steps = sample.getSteps();
|
// short steps = sample.getSteps();
|
||||||
@ -284,7 +279,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
|
|||||||
}
|
}
|
||||||
activityEntries.add(createLineEntry(value, ts));
|
activityEntries.add(createLineEntry(value, ts));
|
||||||
}
|
}
|
||||||
if (hr && sample.getKind() != ActivityKind.TYPE_NOT_WORN && heartRateUtilsInstance.isValidHeartRateValue(sample.getHeartRate())) {
|
if (hr && sample.getKind() != ActivityKind.NOT_WORN && heartRateUtilsInstance.isValidHeartRateValue(sample.getHeartRate())) {
|
||||||
if (lastHrSampleIndex > -1 && ts - lastHrSampleIndex > 1800*HeartRateUtils.MAX_HR_MEASUREMENTS_GAP_MINUTES) {
|
if (lastHrSampleIndex > -1 && ts - lastHrSampleIndex > 1800*HeartRateUtils.MAX_HR_MEASUREMENTS_GAP_MINUTES) {
|
||||||
heartrateEntries.add(createLineEntry(0, lastHrSampleIndex + 1));
|
heartrateEntries.add(createLineEntry(0, lastHrSampleIndex + 1));
|
||||||
heartrateEntries.add(createLineEntry(0, ts - 1));
|
heartrateEntries.add(createLineEntry(0, ts - 1));
|
||||||
|
@ -37,30 +37,30 @@ public class ActivityAnalysis {
|
|||||||
private int maxSpeed = 0;
|
private int maxSpeed = 0;
|
||||||
|
|
||||||
public ActivityAmounts calculateActivityAmounts(List<? extends ActivitySample> samples) {
|
public ActivityAmounts calculateActivityAmounts(List<? extends ActivitySample> samples) {
|
||||||
ActivityAmount deepSleep = new ActivityAmount(ActivityKind.TYPE_DEEP_SLEEP);
|
ActivityAmount deepSleep = new ActivityAmount(ActivityKind.DEEP_SLEEP);
|
||||||
ActivityAmount lightSleep = new ActivityAmount(ActivityKind.TYPE_LIGHT_SLEEP);
|
ActivityAmount lightSleep = new ActivityAmount(ActivityKind.LIGHT_SLEEP);
|
||||||
ActivityAmount remSleep = new ActivityAmount(ActivityKind.TYPE_REM_SLEEP);
|
ActivityAmount remSleep = new ActivityAmount(ActivityKind.REM_SLEEP);
|
||||||
ActivityAmount notWorn = new ActivityAmount(ActivityKind.TYPE_NOT_WORN);
|
ActivityAmount notWorn = new ActivityAmount(ActivityKind.NOT_WORN);
|
||||||
ActivityAmount activity = new ActivityAmount(ActivityKind.TYPE_ACTIVITY);
|
ActivityAmount activity = new ActivityAmount(ActivityKind.ACTIVITY);
|
||||||
|
|
||||||
ActivityAmount previousAmount = null;
|
ActivityAmount previousAmount = null;
|
||||||
ActivitySample previousSample = null;
|
ActivitySample previousSample = null;
|
||||||
for (ActivitySample sample : samples) {
|
for (ActivitySample sample : samples) {
|
||||||
ActivityAmount amount;
|
ActivityAmount amount;
|
||||||
switch (sample.getKind()) {
|
switch (sample.getKind()) {
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
amount = deepSleep;
|
amount = deepSleep;
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
amount = lightSleep;
|
amount = lightSleep;
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_REM_SLEEP:
|
case REM_SLEEP:
|
||||||
amount = remSleep;
|
amount = remSleep;
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_NOT_WORN:
|
case NOT_WORN:
|
||||||
amount = notWorn;
|
amount = notWorn;
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_ACTIVITY:
|
case ACTIVITY:
|
||||||
default:
|
default:
|
||||||
amount = activity;
|
amount = activity;
|
||||||
break;
|
break;
|
||||||
@ -82,7 +82,7 @@ public class ActivityAnalysis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add time
|
// add time
|
||||||
if (steps > 0 && sample.getKind() == ActivityKind.TYPE_ACTIVITY) {
|
if (steps > 0 && sample.getKind() == ActivityKind.ACTIVITY) {
|
||||||
if (steps > maxSpeed) {
|
if (steps > maxSpeed) {
|
||||||
maxSpeed = steps;
|
maxSpeed = steps;
|
||||||
}
|
}
|
||||||
|
@ -254,7 +254,7 @@ public class ActivityListingAdapter extends AbstractActivityListingAdapter<Activ
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getActivityName(ActivitySession item) {
|
protected String getActivityName(ActivitySession item) {
|
||||||
return ActivityKind.asString(item.getActivityKind(), getContext());
|
return item.getActivityKind().getLabel(getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -354,6 +354,6 @@ public class ActivityListingAdapter extends AbstractActivityListingAdapter<Activ
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getIcon(ActivitySession item) {
|
protected int getIcon(ActivitySession item) {
|
||||||
return ActivityKind.getIconId(item.getActivityKind());
|
return item.getActivityKind().getIcon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,11 +59,11 @@ public class SleepAnalysis {
|
|||||||
|
|
||||||
if (previousSample != null) {
|
if (previousSample != null) {
|
||||||
long durationSinceLastSample = sample.getTimestamp() - previousSample.getTimestamp();
|
long durationSinceLastSample = sample.getTimestamp() - previousSample.getTimestamp();
|
||||||
if (sample.getKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
if (sample.getKind() == ActivityKind.LIGHT_SLEEP) {
|
||||||
lightSleepDuration += durationSinceLastSample;
|
lightSleepDuration += durationSinceLastSample;
|
||||||
} else if (sample.getKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
} else if (sample.getKind() == ActivityKind.DEEP_SLEEP) {
|
||||||
deepSleepDuration += durationSinceLastSample;
|
deepSleepDuration += durationSinceLastSample;
|
||||||
} else if (sample.getKind() == ActivityKind.TYPE_REM_SLEEP) {
|
} else if (sample.getKind() == ActivityKind.REM_SLEEP) {
|
||||||
remSleepDuration += durationSinceLastSample;
|
remSleepDuration += durationSinceLastSample;
|
||||||
} else {
|
} else {
|
||||||
durationSinceLastSleep += durationSinceLastSample;
|
durationSinceLastSleep += durationSinceLastSample;
|
||||||
@ -88,9 +88,9 @@ public class SleepAnalysis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSleep(ActivitySample sample) {
|
private boolean isSleep(ActivitySample sample) {
|
||||||
return sample.getKind() == ActivityKind.TYPE_DEEP_SLEEP ||
|
return sample.getKind() == ActivityKind.DEEP_SLEEP ||
|
||||||
sample.getKind() == ActivityKind.TYPE_LIGHT_SLEEP ||
|
sample.getKind() == ActivityKind.LIGHT_SLEEP ||
|
||||||
sample.getKind() == ActivityKind.TYPE_REM_SLEEP;
|
sample.getKind() == ActivityKind.REM_SLEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date getDateFromSample(ActivitySample sample) {
|
private Date getDateFromSample(ActivitySample sample) {
|
||||||
|
@ -144,12 +144,12 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
|||||||
if (!sleepSessions.isEmpty()) {
|
if (!sleepSessions.isEmpty()) {
|
||||||
entries.add(new PieEntry(lightSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_light_sleep)));
|
entries.add(new PieEntry(lightSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_light_sleep)));
|
||||||
entries.add(new PieEntry(deepSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_deep_sleep)));
|
entries.add(new PieEntry(deepSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_deep_sleep)));
|
||||||
colors.add(getColorFor(ActivityKind.TYPE_LIGHT_SLEEP));
|
colors.add(getColorFor(ActivityKind.LIGHT_SLEEP));
|
||||||
colors.add(getColorFor(ActivityKind.TYPE_DEEP_SLEEP));
|
colors.add(getColorFor(ActivityKind.DEEP_SLEEP));
|
||||||
|
|
||||||
if (supportsRemSleep(mGBDevice)) {
|
if (supportsRemSleep(mGBDevice)) {
|
||||||
entries.add(new PieEntry(remSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_rem_sleep)));
|
entries.add(new PieEntry(remSleepDuration, getActivity().getString(R.string.abstract_chart_fragment_kind_rem_sleep)));
|
||||||
colors.add(getColorFor(ActivityKind.TYPE_REM_SLEEP));
|
colors.add(getColorFor(ActivityKind.REM_SLEEP));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -266,7 +266,7 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
|||||||
List<Integer> heartRateValues = new ArrayList<>();
|
List<Integer> heartRateValues = new ArrayList<>();
|
||||||
HeartRateUtils heartRateUtilsInstance = HeartRateUtils.getInstance();
|
HeartRateUtils heartRateUtilsInstance = HeartRateUtils.getInstance();
|
||||||
for (ActivitySample sample : samples) {
|
for (ActivitySample sample : samples) {
|
||||||
if (sample.getKind() == ActivityKind.TYPE_LIGHT_SLEEP || sample.getKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
if (sample.getKind() == ActivityKind.LIGHT_SLEEP || sample.getKind() == ActivityKind.DEEP_SLEEP) {
|
||||||
int heartRate = sample.getHeartRate();
|
int heartRate = sample.getHeartRate();
|
||||||
if (heartRateUtilsInstance.isValidHeartRateValue(heartRate)) {
|
if (heartRateUtilsInstance.isValidHeartRateValue(heartRate)) {
|
||||||
heartRateValues.add(heartRate);
|
heartRateValues.add(heartRate);
|
||||||
@ -309,7 +309,7 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
|||||||
List<Float> allIntensities = new ArrayList<>();
|
List<Float> allIntensities = new ArrayList<>();
|
||||||
|
|
||||||
for (ActivitySample s : samples) {
|
for (ActivitySample s : samples) {
|
||||||
if (s.getKind() == ActivityKind.TYPE_LIGHT_SLEEP || s.getKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
if (s.getKind() == ActivityKind.LIGHT_SLEEP || s.getKind() == ActivityKind.DEEP_SLEEP) {
|
||||||
float intensity = s.getIntensity();
|
float intensity = s.getIntensity();
|
||||||
allIntensities.add(intensity);
|
allIntensities.add(intensity);
|
||||||
}
|
}
|
||||||
@ -477,7 +477,6 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
|
|||||||
@Override
|
@Override
|
||||||
protected List<? extends ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
|
protected List<? extends ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
|
||||||
// temporary fix for totally wrong sleep amounts
|
// temporary fix for totally wrong sleep amounts
|
||||||
// return super.getSleepSamples(db, device, tsFrom, tsTo);
|
|
||||||
return super.getAllSamples(db, device, tsFrom, tsTo);
|
return super.getAllSamples(db, device, tsFrom, tsTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
/* Copyright (C) 2015-2024 Carsten Pfeiffer
|
|
||||||
|
|
||||||
This file is part of Gadgetbridge.
|
|
||||||
|
|
||||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published
|
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Gadgetbridge is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
|
||||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|
||||||
|
|
||||||
public class SleepUtils {
|
|
||||||
public static final float Y_VALUE_DEEP_SLEEP = 0.01f;
|
|
||||||
public static final float Y_VALUE_LIGHT_SLEEP = 0.016f;
|
|
||||||
|
|
||||||
public static boolean isSleep(byte type) {
|
|
||||||
return type == ActivityKind.TYPE_DEEP_SLEEP || type == ActivityKind.TYPE_LIGHT_SLEEP;
|
|
||||||
}
|
|
||||||
}
|
|
@ -79,7 +79,7 @@ public class SpeedZonesFragment extends AbstractActivityChartFragment<ChartsData
|
|||||||
|
|
||||||
BarDataSet set = new BarDataSet(entries, "");
|
BarDataSet set = new BarDataSet(entries, "");
|
||||||
set.setValueTextColor(CHART_TEXT_COLOR);
|
set.setValueTextColor(CHART_TEXT_COLOR);
|
||||||
set.setColors(getColorFor(ActivityKind.TYPE_ACTIVITY));
|
set.setColors(getColorFor(ActivityKind.ACTIVITY));
|
||||||
//set.setDrawValues(false);
|
//set.setDrawValues(false);
|
||||||
//data.setBarWidth(0.1f);
|
//data.setBarWidth(0.1f);
|
||||||
data.addDataSet(set);
|
data.addDataSet(set);
|
||||||
|
@ -52,7 +52,7 @@ public class StepAnalysis {
|
|||||||
int activeSteps = 0; //steps that we count
|
int activeSteps = 0; //steps that we count
|
||||||
int stepsBetweenActivePeriods = 0; //steps during time when we maybe take a rest but then restart
|
int stepsBetweenActivePeriods = 0; //steps during time when we maybe take a rest but then restart
|
||||||
int durationSinceLastActiveStep = 0;
|
int durationSinceLastActiveStep = 0;
|
||||||
int activityKind;
|
ActivityKind activityKind;
|
||||||
|
|
||||||
List<Integer> heartRateSum = new ArrayList<>();
|
List<Integer> heartRateSum = new ArrayList<>();
|
||||||
List<Integer> heartRateBetweenActivePeriodsSum = new ArrayList<>();
|
List<Integer> heartRateBetweenActivePeriodsSum = new ArrayList<>();
|
||||||
@ -67,7 +67,7 @@ public class StepAnalysis {
|
|||||||
totalDailySteps += steps;
|
totalDailySteps += steps;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sample.getKind() != ActivityKind.TYPE_SLEEP //anything but sleep counts
|
if (!ActivityKind.isSleep(sample.getKind()) //anything but sleep counts
|
||||||
&& !(sample instanceof TrailingActivitySample)) { //trailing samples have wrong date and make trailing activity have 0 duration
|
&& !(sample instanceof TrailingActivitySample)) { //trailing samples have wrong date and make trailing activity have 0 duration
|
||||||
|
|
||||||
if (sessionStart == null) {
|
if (sessionStart == null) {
|
||||||
@ -178,7 +178,7 @@ public class StepAnalysis {
|
|||||||
endTime = new Date(durationSum);
|
endTime = new Date(durationSum);
|
||||||
|
|
||||||
ActivitySession stepSessionSummary = new ActivitySession(startTime, endTime,
|
ActivitySession stepSessionSummary = new ActivitySession(startTime, endTime,
|
||||||
stepsSum, heartRateAverage, intensitySum, distanceSum, 0);
|
stepsSum, heartRateAverage, intensitySum, distanceSum, ActivityKind.UNKNOWN);
|
||||||
|
|
||||||
stepSessionSummary.setSessionCount(sessionCount);
|
stepSessionSummary.setSessionCount(sessionCount);
|
||||||
stepSessionSummary.setSessionType(ActivitySession.SESSION_SUMMARY);
|
stepSessionSummary.setSessionType(ActivitySession.SESSION_SUMMARY);
|
||||||
@ -207,19 +207,19 @@ public class StepAnalysis {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int detect_activity_kind(int session_length, int activeSteps, int heartRateAverage, float intensity) {
|
private ActivityKind detect_activity_kind(int session_length, int activeSteps, int heartRateAverage, float intensity) {
|
||||||
final int MIN_STEPS_PER_MINUTE_FOR_RUN = GBApplication.getPrefs().getInt("chart_list_min_steps_per_minute_for_run", 120);
|
final int MIN_STEPS_PER_MINUTE_FOR_RUN = GBApplication.getPrefs().getInt("chart_list_min_steps_per_minute_for_run", 120);
|
||||||
int spm = (int) (activeSteps / (session_length / 60));
|
int spm = (int) (activeSteps / (session_length / 60));
|
||||||
if (spm > MIN_STEPS_PER_MINUTE_FOR_RUN) {
|
if (spm > MIN_STEPS_PER_MINUTE_FOR_RUN) {
|
||||||
return ActivityKind.TYPE_RUNNING;
|
return ActivityKind.RUNNING;
|
||||||
}
|
}
|
||||||
if (activeSteps > 200) {
|
if (activeSteps > 200) {
|
||||||
return ActivityKind.TYPE_WALKING;
|
return ActivityKind.WALKING;
|
||||||
}
|
}
|
||||||
if (heartRateAverage > 90 && intensity > 15) { //needs tuning
|
if (heartRateAverage > 90 && intensity > 15) { //needs tuning
|
||||||
return ActivityKind.TYPE_EXERCISE;
|
return ActivityKind.EXERCISE;
|
||||||
}
|
}
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date getDateFromSample(ActivitySample sample) {
|
private Date getDateFromSample(ActivitySample sample) {
|
||||||
|
@ -197,9 +197,9 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
|||||||
long balance = 0;
|
long balance = 0;
|
||||||
|
|
||||||
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
||||||
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP ||
|
if (amount.getActivityKind() == ActivityKind.DEEP_SLEEP ||
|
||||||
amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP ||
|
amount.getActivityKind() == ActivityKind.LIGHT_SLEEP ||
|
||||||
amount.getActivityKind() == ActivityKind.TYPE_REM_SLEEP) {
|
amount.getActivityKind() == ActivityKind.REM_SLEEP) {
|
||||||
balance += amount.getTotalSeconds();
|
balance += amount.getTotalSeconds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,11 +224,11 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
|||||||
long totalSecondsLightSleep = 0;
|
long totalSecondsLightSleep = 0;
|
||||||
long totalSecondsRemSleep = 0;
|
long totalSecondsRemSleep = 0;
|
||||||
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
||||||
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
if (amount.getActivityKind() == ActivityKind.DEEP_SLEEP) {
|
||||||
totalSecondsDeepSleep += amount.getTotalSeconds();
|
totalSecondsDeepSleep += amount.getTotalSeconds();
|
||||||
} else if (amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
} else if (amount.getActivityKind() == ActivityKind.LIGHT_SLEEP) {
|
||||||
totalSecondsLightSleep += amount.getTotalSeconds();
|
totalSecondsLightSleep += amount.getTotalSeconds();
|
||||||
} else if (amount.getActivityKind() == ActivityKind.TYPE_REM_SLEEP) {
|
} else if (amount.getActivityKind() == ActivityKind.REM_SLEEP) {
|
||||||
totalSecondsRemSleep += amount.getTotalSeconds();
|
totalSecondsRemSleep += amount.getTotalSeconds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,27 +246,27 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
}
|
}
|
||||||
float start_angle = startAngle + (activity.timeFrom - dashboardData.timeFrom) / degreeFactor;
|
float start_angle = startAngle + (activity.timeFrom - dashboardData.timeFrom) / degreeFactor;
|
||||||
float sweep_angle = (activity.timeTo - activity.timeFrom) / degreeFactor;
|
float sweep_angle = (activity.timeTo - activity.timeFrom) / degreeFactor;
|
||||||
if (activity.activityKind == ActivityKind.TYPE_NOT_MEASURED) {
|
if (activity.activityKind == ActivityKind.NOT_MEASURED) {
|
||||||
paint.setStrokeWidth(barWidth / 3f);
|
paint.setStrokeWidth(barWidth / 3f);
|
||||||
paint.setColor(color_worn);
|
paint.setColor(color_worn);
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else if (activity.activityKind == ActivityKind.TYPE_NOT_WORN) {
|
} else if (activity.activityKind == ActivityKind.NOT_WORN) {
|
||||||
paint.setStrokeWidth(barWidth / 3f);
|
paint.setStrokeWidth(barWidth / 3f);
|
||||||
paint.setColor(color_not_worn);
|
paint.setColor(color_not_worn);
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else if (activity.activityKind == ActivityKind.TYPE_LIGHT_SLEEP || activity.activityKind == ActivityKind.TYPE_SLEEP) {
|
} else if (activity.activityKind == ActivityKind.LIGHT_SLEEP || activity.activityKind == ActivityKind.SLEEP_ANY) {
|
||||||
paint.setStrokeWidth(barWidth);
|
paint.setStrokeWidth(barWidth);
|
||||||
paint.setColor(color_light_sleep);
|
paint.setColor(color_light_sleep);
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else if (activity.activityKind == ActivityKind.TYPE_REM_SLEEP) {
|
} else if (activity.activityKind == ActivityKind.REM_SLEEP) {
|
||||||
paint.setStrokeWidth(barWidth);
|
paint.setStrokeWidth(barWidth);
|
||||||
paint.setColor(color_rem_sleep);
|
paint.setColor(color_rem_sleep);
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else if (activity.activityKind == ActivityKind.TYPE_DEEP_SLEEP) {
|
} else if (activity.activityKind == ActivityKind.DEEP_SLEEP) {
|
||||||
paint.setStrokeWidth(barWidth);
|
paint.setStrokeWidth(barWidth);
|
||||||
paint.setColor(color_deep_sleep);
|
paint.setColor(color_deep_sleep);
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
} else if (activity.activityKind == ActivityKind.TYPE_EXERCISE) {
|
} else if (activity.activityKind == ActivityKind.EXERCISE) {
|
||||||
paint.setStrokeWidth(barWidth);
|
paint.setStrokeWidth(barWidth);
|
||||||
paint.setColor(color_exercise);
|
paint.setColor(color_exercise);
|
||||||
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
canvas.drawArc(margin, margin, width - margin, height - margin, start_angle, sweep_angle, false, paint);
|
||||||
@ -334,9 +334,9 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class FillDataAsyncTask extends AsyncTask<Void, Void, Void> {
|
private class FillDataAsyncTask extends AsyncTask<Void, Void, Void> {
|
||||||
private final TreeMap<Long, Integer> activityTimestamps = new TreeMap<>();
|
private final TreeMap<Long, ActivityKind> activityTimestamps = new TreeMap<>();
|
||||||
|
|
||||||
private void addActivity(long timeFrom, long timeTo, int activityKind) {
|
private void addActivity(long timeFrom, long timeTo, ActivityKind activityKind) {
|
||||||
for (long i = timeFrom; i<=timeTo; i++) {
|
for (long i = timeFrom; i<=timeTo; i++) {
|
||||||
// If the current timestamp isn't saved yet, do so immediately
|
// If the current timestamp isn't saved yet, do so immediately
|
||||||
if (activityTimestamps.get(i) == null) {
|
if (activityTimestamps.get(i) == null) {
|
||||||
@ -346,36 +346,36 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
// If the current timestamp is already saved, compare the activity kinds and
|
// If the current timestamp is already saved, compare the activity kinds and
|
||||||
// keep the most 'important' one
|
// keep the most 'important' one
|
||||||
switch (activityTimestamps.get(i)) {
|
switch (activityTimestamps.get(i)) {
|
||||||
case ActivityKind.TYPE_EXERCISE:
|
case EXERCISE:
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_ACTIVITY:
|
case ACTIVITY:
|
||||||
if (activityKind == ActivityKind.TYPE_EXERCISE)
|
if (activityKind == ActivityKind.EXERCISE)
|
||||||
activityTimestamps.put(i, activityKind);
|
activityTimestamps.put(i, activityKind);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
if (activityKind == ActivityKind.TYPE_EXERCISE ||
|
if (activityKind == ActivityKind.EXERCISE ||
|
||||||
activityKind == ActivityKind.TYPE_ACTIVITY)
|
activityKind == ActivityKind.ACTIVITY)
|
||||||
activityTimestamps.put(i, activityKind);
|
activityTimestamps.put(i, activityKind);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
if (activityKind == ActivityKind.TYPE_EXERCISE ||
|
if (activityKind == ActivityKind.EXERCISE ||
|
||||||
activityKind == ActivityKind.TYPE_ACTIVITY ||
|
activityKind == ActivityKind.ACTIVITY ||
|
||||||
activityKind == ActivityKind.TYPE_DEEP_SLEEP)
|
activityKind == ActivityKind.DEEP_SLEEP)
|
||||||
activityTimestamps.put(i, activityKind);
|
activityTimestamps.put(i, activityKind);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_REM_SLEEP:
|
case REM_SLEEP:
|
||||||
if (activityKind == ActivityKind.TYPE_EXERCISE ||
|
if (activityKind == ActivityKind.EXERCISE ||
|
||||||
activityKind == ActivityKind.TYPE_ACTIVITY ||
|
activityKind == ActivityKind.ACTIVITY ||
|
||||||
activityKind == ActivityKind.TYPE_DEEP_SLEEP ||
|
activityKind == ActivityKind.DEEP_SLEEP ||
|
||||||
activityKind == ActivityKind.TYPE_LIGHT_SLEEP)
|
activityKind == ActivityKind.LIGHT_SLEEP)
|
||||||
activityTimestamps.put(i, activityKind);
|
activityTimestamps.put(i, activityKind);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_SLEEP:
|
case SLEEP_ANY:
|
||||||
if (activityKind == ActivityKind.TYPE_EXERCISE ||
|
if (activityKind == ActivityKind.EXERCISE ||
|
||||||
activityKind == ActivityKind.TYPE_ACTIVITY ||
|
activityKind == ActivityKind.ACTIVITY ||
|
||||||
activityKind == ActivityKind.TYPE_DEEP_SLEEP ||
|
activityKind == ActivityKind.DEEP_SLEEP ||
|
||||||
activityKind == ActivityKind.TYPE_LIGHT_SLEEP ||
|
activityKind == ActivityKind.LIGHT_SLEEP ||
|
||||||
activityKind == ActivityKind.TYPE_REM_SLEEP)
|
activityKind == ActivityKind.REM_SLEEP)
|
||||||
activityTimestamps.put(i, activityKind);
|
activityTimestamps.put(i, activityKind);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -395,7 +395,7 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
if (lastTimestamp == 0) lastTimestamp = sample.getTimestamp();
|
if (lastTimestamp == 0) lastTimestamp = sample.getTimestamp();
|
||||||
if ((sample.getHeartRate() < 10 || sample.getTimestamp() > lastTimestamp + dashboardData.hrIntervalSecs) && firstTimestamp != lastTimestamp) {
|
if ((sample.getHeartRate() < 10 || sample.getTimestamp() > lastTimestamp + dashboardData.hrIntervalSecs) && firstTimestamp != lastTimestamp) {
|
||||||
LOG.debug("Registered worn session from {} to {}", firstTimestamp, lastTimestamp);
|
LOG.debug("Registered worn session from {} to {}", firstTimestamp, lastTimestamp);
|
||||||
addActivity(firstTimestamp, lastTimestamp, ActivityKind.TYPE_NOT_MEASURED);
|
addActivity(firstTimestamp, lastTimestamp, ActivityKind.NOT_MEASURED);
|
||||||
if (sample.getHeartRate() < 10) {
|
if (sample.getHeartRate() < 10) {
|
||||||
firstTimestamp = 0;
|
firstTimestamp = 0;
|
||||||
lastTimestamp = 0;
|
lastTimestamp = 0;
|
||||||
@ -409,16 +409,16 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
}
|
}
|
||||||
if (firstTimestamp != lastTimestamp) {
|
if (firstTimestamp != lastTimestamp) {
|
||||||
LOG.debug("Registered worn session from {} to {}", firstTimestamp, lastTimestamp);
|
LOG.debug("Registered worn session from {} to {}", firstTimestamp, lastTimestamp);
|
||||||
addActivity(firstTimestamp, lastTimestamp, ActivityKind.TYPE_NOT_MEASURED);
|
addActivity(firstTimestamp, lastTimestamp, ActivityKind.NOT_MEASURED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createGeneralizedActivities() {
|
private void createGeneralizedActivities() {
|
||||||
DashboardFragment.DashboardData.GeneralizedActivity previous = null;
|
DashboardFragment.DashboardData.GeneralizedActivity previous = null;
|
||||||
long midDaySecond = dashboardData.timeFrom + (12 * 60 * 60);
|
long midDaySecond = dashboardData.timeFrom + (12 * 60 * 60);
|
||||||
for (Map.Entry<Long, Integer> activity : activityTimestamps.entrySet()) {
|
for (Map.Entry<Long, ActivityKind> activity : activityTimestamps.entrySet()) {
|
||||||
long timestamp = activity.getKey();
|
long timestamp = activity.getKey();
|
||||||
int activityKind = activity.getValue();
|
ActivityKind activityKind = activity.getValue();
|
||||||
if (previous == null || previous.activityKind != activityKind || (!mode_24h && timestamp == midDaySecond) || previous.timeTo < timestamp - 60) {
|
if (previous == null || previous.activityKind != activityKind || (!mode_24h && timestamp == midDaySecond) || previous.timeTo < timestamp - 60) {
|
||||||
previous = new DashboardFragment.DashboardData.GeneralizedActivity(activityKind, timestamp, timestamp);
|
previous = new DashboardFragment.DashboardData.GeneralizedActivity(activityKind, timestamp, timestamp);
|
||||||
dashboardData.generalizedActivities.add(previous);
|
dashboardData.generalizedActivities.add(previous);
|
||||||
@ -457,18 +457,18 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
|
|||||||
// Integrate various data from multiple devices
|
// Integrate various data from multiple devices
|
||||||
for (ActivitySample sample : allActivitySamples) {
|
for (ActivitySample sample : allActivitySamples) {
|
||||||
// Handle only TYPE_NOT_WORN and TYPE_SLEEP (including variants) here
|
// Handle only TYPE_NOT_WORN and TYPE_SLEEP (including variants) here
|
||||||
if (sample.getKind() != ActivityKind.TYPE_NOT_WORN && (sample.getKind() == ActivityKind.TYPE_NOT_MEASURED || (sample.getKind() & ActivityKind.TYPE_SLEEP) == 0))
|
if (sample.getKind() != ActivityKind.NOT_WORN && (sample.getKind() == ActivityKind.NOT_MEASURED || !ActivityKind.isSleep(sample.getKind())))
|
||||||
continue;
|
continue;
|
||||||
// Add to day results
|
// Add to day results
|
||||||
addActivity(sample.getTimestamp(), sample.getTimestamp() + 60, sample.getKind());
|
addActivity(sample.getTimestamp(), sample.getTimestamp() + 60, sample.getKind());
|
||||||
}
|
}
|
||||||
if (activitySummaries != null) {
|
if (activitySummaries != null) {
|
||||||
for (BaseActivitySummary baseActivitySummary : activitySummaries) {
|
for (BaseActivitySummary baseActivitySummary : activitySummaries) {
|
||||||
addActivity(baseActivitySummary.getStartTime().getTime() / 1000, baseActivitySummary.getEndTime().getTime() / 1000, ActivityKind.TYPE_EXERCISE);
|
addActivity(baseActivitySummary.getStartTime().getTime() / 1000, baseActivitySummary.getEndTime().getTime() / 1000, ActivityKind.EXERCISE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ActivitySession session : stepSessions) {
|
for (ActivitySession session : stepSessions) {
|
||||||
addActivity(session.getStartTime().getTime() / 1000, session.getEndTime().getTime() / 1000, ActivityKind.TYPE_ACTIVITY);
|
addActivity(session.getStartTime().getTime() / 1000, session.getEndTime().getTime() / 1000, ActivityKind.ACTIVITY);
|
||||||
}
|
}
|
||||||
createGeneralizedActivities();
|
createGeneralizedActivities();
|
||||||
return null;
|
return null;
|
||||||
|
@ -235,13 +235,15 @@ public class ActivitySummariesAdapter extends AbstractActivityListingAdapter<Bas
|
|||||||
activitiesCountView.setText(String.valueOf(activitiesCount));
|
activitiesCountView.setText(String.valueOf(activitiesCount));
|
||||||
String activityName = context.getString(R.string.activity_summaries_all_activities);
|
String activityName = context.getString(R.string.activity_summaries_all_activities);
|
||||||
if (gettActivityKindFilter() != 0) {
|
if (gettActivityKindFilter() != 0) {
|
||||||
activityName = ActivityKind.asString(gettActivityKindFilter(), context);
|
ActivityKind activityKind = ActivityKind.fromCode(gettActivityKindFilter());
|
||||||
activityIconView.setImageResource(ActivityKind.getIconId(gettActivityKindFilter()));
|
activityName = activityKind.getLabel(context);
|
||||||
activityIconBigView.setImageResource(ActivityKind.getIconId(gettActivityKindFilter()));
|
activityIconView.setImageResource(activityKind.getIcon());
|
||||||
|
activityIconBigView.setImageResource(activityKind.getIcon());
|
||||||
} else {
|
} else {
|
||||||
if (activitySame) {
|
if (activitySame) {
|
||||||
activityIconView.setImageResource(ActivityKind.getIconId(activityIcon));
|
ActivityKind activityKind = ActivityKind.fromCode(activityIcon);
|
||||||
activityIconBigView.setImageResource(ActivityKind.getIconId(activityIcon));
|
activityIconView.setImageResource(activityKind.getIcon());
|
||||||
|
activityIconBigView.setImageResource(activityKind.getIcon());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,7 +310,7 @@ public class ActivitySummariesAdapter extends AbstractActivityListingAdapter<Bas
|
|||||||
separator = "";
|
separator = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
String activityKindName = ActivityKind.asString(item.getActivityKind(), getContext());
|
String activityKindName = ActivityKind.fromCode(item.getActivityKind()).getLabel(getContext());
|
||||||
return String.format("%s%s %s", activityKindName, separator, activityLabel);
|
return String.format("%s%s %s", activityKindName, separator, activityLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,7 +395,7 @@ public class ActivitySummariesAdapter extends AbstractActivityListingAdapter<Bas
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getIcon(BaseActivitySummary item) {
|
protected int getIcon(BaseActivitySummary item) {
|
||||||
return ActivityKind.getIconId(item.getActivityKind());
|
return ActivityKind.fromCode(item.getActivityKind()).getIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBackgroundColor(int backgroundColor) {
|
public void setBackgroundColor(int backgroundColor) {
|
||||||
|
@ -30,6 +30,7 @@ import java.util.Calendar;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import de.greenrobot.dao.AbstractDao;
|
import de.greenrobot.dao.AbstractDao;
|
||||||
import de.greenrobot.dao.Property;
|
import de.greenrobot.dao.Property;
|
||||||
@ -71,34 +72,16 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public List<T> getActivitySamples(int timestamp_from, int timestamp_to) {
|
public List<T> getActivitySamples(int timestamp_from, int timestamp_to) {
|
||||||
if (getRawKindSampleProperty() != null) {
|
if (getRawKindSampleProperty() != null) {
|
||||||
return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ACTIVITY);
|
return getGBActivitySamples(timestamp_from, timestamp_to);
|
||||||
} else {
|
} else {
|
||||||
return getActivitySamplesByActivityFilter(timestamp_from, timestamp_to, ActivityKind.TYPE_ACTIVITY);
|
return getActivitySamplesByActivityFilter(timestamp_from, timestamp_to, Collections.singleton(ActivityKind.ACTIVITY));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public List<T> getSleepSamples(int timestamp_from, int timestamp_to) {
|
|
||||||
final DeviceCoordinator coordinator = getDevice().getDeviceCoordinator();
|
|
||||||
|
|
||||||
// If the device does not support REM sleep, we need to exclude its bit from the activity type
|
|
||||||
int sleepActivityType = ActivityKind.TYPE_SLEEP;
|
|
||||||
if (!coordinator.supportsRemSleep()) {
|
|
||||||
sleepActivityType &= ~ActivityKind.TYPE_REM_SLEEP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getRawKindSampleProperty() != null) {
|
|
||||||
return getGBActivitySamples(timestamp_from, timestamp_to, sleepActivityType);
|
|
||||||
} else {
|
|
||||||
return getActivitySamplesByActivityFilter(timestamp_from, timestamp_to, sleepActivityType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,11 +135,7 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
|
|||||||
return sample;
|
return sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<T> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) {
|
protected List<T> getGBActivitySamples(int timestamp_from, int timestamp_to) {
|
||||||
if (getRawKindSampleProperty() == null && activityType != ActivityKind.TYPE_ALL) {
|
|
||||||
// if we do not have a raw kind property we cannot query anything else then TYPE_ALL
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
QueryBuilder<T> qb = getSampleDao().queryBuilder();
|
QueryBuilder<T> qb = getSampleDao().queryBuilder();
|
||||||
Property timestampProperty = getTimestampSampleProperty();
|
Property timestampProperty = getTimestampSampleProperty();
|
||||||
Device dbDevice = DBHelper.findDevice(getDevice(), getSession());
|
Device dbDevice = DBHelper.findDevice(getDevice(), getSession());
|
||||||
@ -166,7 +145,7 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
|
|||||||
}
|
}
|
||||||
Property deviceProperty = getDeviceIdentifierSampleProperty();
|
Property deviceProperty = getDeviceIdentifierSampleProperty();
|
||||||
qb.where(deviceProperty.eq(dbDevice.getId()), timestampProperty.ge(timestamp_from))
|
qb.where(deviceProperty.eq(dbDevice.getId()), timestampProperty.ge(timestamp_from))
|
||||||
.where(timestampProperty.le(timestamp_to), getClauseForActivityType(qb, activityType));
|
.where(timestampProperty.le(timestamp_to));
|
||||||
List<T> samples = qb.build().list();
|
List<T> samples = qb.build().list();
|
||||||
for (T sample : samples) {
|
for (T sample : samples) {
|
||||||
sample.setProvider(this);
|
sample.setProvider(this);
|
||||||
@ -185,51 +164,12 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
|
|||||||
getSampleDao().detachAll();
|
getSampleDao().detachAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private WhereCondition[] getClauseForActivityType(QueryBuilder<T> qb, int activityTypes) {
|
private List<T> getActivitySamplesByActivityFilter(int timestamp_from, int timestamp_to, Set<ActivityKind> activityFilter) {
|
||||||
if (activityTypes == ActivityKind.TYPE_ALL) {
|
|
||||||
return NO_CONDITIONS;
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] dbActivityTypes = ActivityKind.mapToDBActivityTypes(activityTypes, this);
|
|
||||||
WhereCondition activityTypeCondition = getActivityTypeConditions(qb, dbActivityTypes);
|
|
||||||
return new WhereCondition[] { activityTypeCondition };
|
|
||||||
}
|
|
||||||
|
|
||||||
private WhereCondition getActivityTypeConditions(QueryBuilder<T> qb, int[] dbActivityTypes) {
|
|
||||||
// What a crappy QueryBuilder API ;-( QueryBuilder.or(WhereCondition[]) with a runtime array length
|
|
||||||
// check would have worked just fine.
|
|
||||||
if (dbActivityTypes.length == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Property rawKindProperty = getRawKindSampleProperty();
|
|
||||||
if (rawKindProperty == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dbActivityTypes.length == 1) {
|
|
||||||
return rawKindProperty.eq(dbActivityTypes[0]);
|
|
||||||
}
|
|
||||||
if (dbActivityTypes.length == 2) {
|
|
||||||
return qb.or(rawKindProperty.eq(dbActivityTypes[0]),
|
|
||||||
rawKindProperty.eq(dbActivityTypes[1]));
|
|
||||||
}
|
|
||||||
final int offset = 2;
|
|
||||||
int len = dbActivityTypes.length - offset;
|
|
||||||
WhereCondition[] trailingConditions = new WhereCondition[len];
|
|
||||||
for (int i = 0; i < len; i++) {
|
|
||||||
trailingConditions[i] = rawKindProperty.eq(dbActivityTypes[i + offset]);
|
|
||||||
}
|
|
||||||
return qb.or(rawKindProperty.eq(dbActivityTypes[0]),
|
|
||||||
rawKindProperty.eq(dbActivityTypes[1]),
|
|
||||||
trailingConditions);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<T> getActivitySamplesByActivityFilter(int timestamp_from, int timestamp_to, int activityFilter) {
|
|
||||||
List<T> samples = getAllActivitySamples(timestamp_from, timestamp_to);
|
List<T> samples = getAllActivitySamples(timestamp_from, timestamp_to);
|
||||||
List<T> filteredSamples = new ArrayList<>();
|
List<T> filteredSamples = new ArrayList<>();
|
||||||
|
|
||||||
for (T sample : samples) {
|
for (T sample : samples) {
|
||||||
if ((sample.getKind() & activityFilter) != 0) {
|
if (activityFilter.contains(sample.getKind())) {
|
||||||
filteredSamples.add(sample);
|
filteredSamples.add(sample);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,7 +264,7 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
|
|||||||
for (int ts = timestamp_from; ts <= firstTimestamp + 60; ts += 60) {
|
for (int ts = timestamp_from; ts <= firstTimestamp + 60; ts += 60) {
|
||||||
final T dummySample = createActivitySample();
|
final T dummySample = createActivitySample();
|
||||||
dummySample.setTimestamp(ts);
|
dummySample.setTimestamp(ts);
|
||||||
dummySample.setRawKind(ActivityKind.TYPE_UNKNOWN);
|
dummySample.setRawKind(ActivityKind.UNKNOWN.getCode());
|
||||||
dummySample.setRawIntensity(ActivitySample.NOT_MEASURED);
|
dummySample.setRawIntensity(ActivitySample.NOT_MEASURED);
|
||||||
dummySample.setSteps(ActivitySample.NOT_MEASURED);
|
dummySample.setSteps(ActivitySample.NOT_MEASURED);
|
||||||
dummySample.setProvider(this);
|
dummySample.setProvider(this);
|
||||||
@ -338,7 +278,7 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
|
|||||||
for (int ts = lastTimestamp + 60; ts <= timestamp_to; ts += 60) {
|
for (int ts = lastTimestamp + 60; ts <= timestamp_to; ts += 60) {
|
||||||
final T dummySample = createActivitySample();
|
final T dummySample = createActivitySample();
|
||||||
dummySample.setTimestamp(ts);
|
dummySample.setTimestamp(ts);
|
||||||
dummySample.setRawKind(ActivityKind.TYPE_UNKNOWN);
|
dummySample.setRawKind(ActivityKind.UNKNOWN.getCode());
|
||||||
dummySample.setRawIntensity(ActivitySample.NOT_MEASURED);
|
dummySample.setRawIntensity(ActivitySample.NOT_MEASURED);
|
||||||
dummySample.setSteps(ActivitySample.NOT_MEASURED);
|
dummySample.setSteps(ActivitySample.NOT_MEASURED);
|
||||||
dummySample.setProvider(this);
|
dummySample.setProvider(this);
|
||||||
@ -356,7 +296,7 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
|
|||||||
for (int ts = previousSample.getTimestamp() + 60; ts < sample.getTimestamp(); ts += 60) {
|
for (int ts = previousSample.getTimestamp() + 60; ts < sample.getTimestamp(); ts += 60) {
|
||||||
final T dummySample = createActivitySample();
|
final T dummySample = createActivitySample();
|
||||||
dummySample.setTimestamp(ts);
|
dummySample.setTimestamp(ts);
|
||||||
dummySample.setRawKind(ActivityKind.TYPE_UNKNOWN);
|
dummySample.setRawKind(ActivityKind.UNKNOWN.getCode());
|
||||||
dummySample.setRawIntensity(ActivitySample.NOT_MEASURED);
|
dummySample.setRawIntensity(ActivitySample.NOT_MEASURED);
|
||||||
dummySample.setSteps(ActivitySample.NOT_MEASURED);
|
dummySample.setSteps(ActivitySample.NOT_MEASURED);
|
||||||
dummySample.setProvider(this);
|
dummySample.setProvider(this);
|
||||||
|
@ -22,6 +22,7 @@ import java.util.List;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface to retrieve samples from the database, and also create and add samples to the database.
|
* Interface to retrieve samples from the database, and also create and add samples to the database.
|
||||||
@ -38,9 +39,9 @@ public interface SampleProvider<T extends AbstractActivitySample> {
|
|||||||
int PROVIDER_PEBBLE_MISFIT = 3;
|
int PROVIDER_PEBBLE_MISFIT = 3;
|
||||||
int PROVIDER_PEBBLE_HEALTH = 4;
|
int PROVIDER_PEBBLE_HEALTH = 4;
|
||||||
|
|
||||||
int normalizeType(int rawType);
|
ActivityKind normalizeType(int rawType);
|
||||||
|
|
||||||
int toRawActivityKind(int activityKind);
|
int toRawActivityKind(ActivityKind activityKind);
|
||||||
|
|
||||||
float normalizeIntensity(int rawIntensity);
|
float normalizeIntensity(int rawIntensity);
|
||||||
|
|
||||||
@ -63,16 +64,6 @@ public interface SampleProvider<T extends AbstractActivitySample> {
|
|||||||
@NonNull
|
@NonNull
|
||||||
List<T> getActivitySamples(int timestamp_from, int timestamp_to);
|
List<T> getActivitySamples(int timestamp_from, int timestamp_to);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the list of all samples that represent "sleeping", within the
|
|
||||||
* given time span.
|
|
||||||
* @param timestamp_from the start timestamp
|
|
||||||
* @param timestamp_to the end timestamp
|
|
||||||
* @return the list of samples of type sleep
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
List<T> getSleepSamples(int timestamp_from, int timestamp_to);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the given sample to the database. An existing sample with the same
|
* Adds the given sample to the database. An existing sample with the same
|
||||||
* timestamp will be overwritten.
|
* timestamp will be overwritten.
|
||||||
|
@ -45,12 +45,12 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
|
|||||||
|
|
||||||
private static final class UnknownSampleProvider implements SampleProvider {
|
private static final class UnknownSampleProvider implements SampleProvider {
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,11 +69,6 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List getSleepSamples(int timestamp_from, int timestamp_to) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addGBActivitySample(AbstractActivitySample activitySample) {
|
public void addGBActivitySample(AbstractActivitySample activitySample) {
|
||||||
}
|
}
|
||||||
|
@ -66,17 +66,17 @@ public class BangleJSSampleProvider extends AbstractSampleProvider<BangleJSActiv
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case TYPE_ACTIVITY:
|
case TYPE_ACTIVITY:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
default: // fall through
|
default: // fall through
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return TYPE_ACTIVITY;
|
return TYPE_ACTIVITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,8 +97,7 @@ public class BangleJSSampleProvider extends AbstractSampleProvider<BangleJSActiv
|
|||||||
public void upsertSample(final BangleJSActivitySample sample) {
|
public void upsertSample(final BangleJSActivitySample sample) {
|
||||||
final List<BangleJSActivitySample> nearSamples = getGBActivitySamples(
|
final List<BangleJSActivitySample> nearSamples = getGBActivitySamples(
|
||||||
sample.getTimestamp() - 60 * 2,
|
sample.getTimestamp() - 60 * 2,
|
||||||
sample.getTimestamp() + 60 * 2,
|
sample.getTimestamp() + 60 * 2
|
||||||
normalizeType(sample.getRawKind())
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (nearSamples.isEmpty()) {
|
if (nearSamples.isEmpty()) {
|
||||||
|
@ -19,11 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.casio.gbx100;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import de.greenrobot.dao.AbstractDao;
|
import de.greenrobot.dao.AbstractDao;
|
||||||
import de.greenrobot.dao.Property;
|
import de.greenrobot.dao.Property;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
||||||
@ -31,22 +26,21 @@ import nodomain.freeyourgadget.gadgetbridge.entities.CasioGBX100ActivitySample;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.CasioGBX100ActivitySampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.CasioGBX100ActivitySampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class CasioGBX100SampleProvider extends AbstractSampleProvider<CasioGBX100ActivitySample> {
|
public class CasioGBX100SampleProvider extends AbstractSampleProvider<CasioGBX100ActivitySample> {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(CasioGBX100SampleProvider.class);
|
|
||||||
|
|
||||||
public CasioGBX100SampleProvider(GBDevice device, DaoSession session) {
|
public CasioGBX100SampleProvider(GBDevice device, DaoSession session) {
|
||||||
super(device, session);
|
super(device, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -83,17 +77,4 @@ public class CasioGBX100SampleProvider extends AbstractSampleProvider<CasioGBX10
|
|||||||
protected Property getDeviceIdentifierSampleProperty() {
|
protected Property getDeviceIdentifierSampleProperty() {
|
||||||
return CasioGBX100ActivitySampleDao.Properties.DeviceId;
|
return CasioGBX100ActivitySampleDao.Properties.DeviceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public List<CasioGBX100ActivitySample> getActivitySamples(int timestamp_from, int timestamp_to) {
|
|
||||||
return super.getActivitySamples(timestamp_from, timestamp_to);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public List<CasioGBX100ActivitySample> getAllActivitySamples(int timestamp_from, int timestamp_to) {
|
|
||||||
return super.getActivitySamples(timestamp_from, timestamp_to);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -72,13 +72,13 @@ public class CmfActivitySampleProvider extends AbstractSampleProvider<CmfActivit
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(final int rawType) {
|
public ActivityKind normalizeType(final int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(final int activityKind) {
|
public int toRawActivityKind(final ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -92,17 +92,16 @@ public class CmfActivitySampleProvider extends AbstractSampleProvider<CmfActivit
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<CmfActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to, final int activityType) {
|
protected List<CmfActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to) {
|
||||||
LOG.trace(
|
LOG.trace(
|
||||||
"Getting cmf activity samples for {} between {} and {}",
|
"Getting cmf activity samples between {} and {}",
|
||||||
String.format("0x%08x", activityType),
|
|
||||||
timestamp_from,
|
timestamp_from,
|
||||||
timestamp_to
|
timestamp_to
|
||||||
);
|
);
|
||||||
|
|
||||||
final long nanoStart = System.nanoTime();
|
final long nanoStart = System.nanoTime();
|
||||||
|
|
||||||
final List<CmfActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to, activityType);
|
final List<CmfActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to);
|
||||||
|
|
||||||
if (!samples.isEmpty()) {
|
if (!samples.isEmpty()) {
|
||||||
convertCumulativeSteps(samples, CmfActivitySampleDao.Properties.Steps);
|
convertCumulativeSteps(samples, CmfActivitySampleDao.Properties.Steps);
|
||||||
@ -165,17 +164,17 @@ public class CmfActivitySampleProvider extends AbstractSampleProvider<CmfActivit
|
|||||||
sampleByTs.put(i, sample);
|
sampleByTs.put(i, sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
final int sleepRawKind = sleepStageToActivityKind(sleepStageSample.getStage());
|
final ActivityKind sleepRawKind = sleepStageToActivityKind(sleepStageSample.getStage());
|
||||||
sample.setRawKind(sleepRawKind);
|
sample.setRawKind(sleepRawKind.getCode());
|
||||||
|
|
||||||
switch (sleepRawKind) {
|
switch (sleepRawKind) {
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
sample.setRawIntensity(20);
|
sample.setRawIntensity(20);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
sample.setRawIntensity(30);
|
sample.setRawIntensity(30);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_REM_SLEEP:
|
case REM_SLEEP:
|
||||||
sample.setRawIntensity(40);
|
sample.setRawIntensity(40);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -183,16 +182,16 @@ public class CmfActivitySampleProvider extends AbstractSampleProvider<CmfActivit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final int sleepStageToActivityKind(final int sleepStage) {
|
final ActivityKind sleepStageToActivityKind(final int sleepStage) {
|
||||||
switch (sleepStage) {
|
switch (sleepStage) {
|
||||||
case 1:
|
case 1:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
case 2:
|
case 2:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
case 3:
|
case 3:
|
||||||
return ActivityKind.TYPE_REM_SLEEP;
|
return ActivityKind.REM_SLEEP;
|
||||||
default:
|
default:
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,9 +57,9 @@ public class CmfWorkoutSummaryParser implements ActivitySummaryParser {
|
|||||||
|
|
||||||
final CmfActivityType cmfActivityType = CmfActivityType.fromCode(workoutType);
|
final CmfActivityType cmfActivityType = CmfActivityType.fromCode(workoutType);
|
||||||
if (cmfActivityType != null) {
|
if (cmfActivityType != null) {
|
||||||
summary.setActivityKind(cmfActivityType.getActivityKind());
|
summary.setActivityKind(cmfActivityType.getActivityKind().getCode());
|
||||||
} else {
|
} else {
|
||||||
summary.setActivityKind(ActivityKind.TYPE_UNKNOWN);
|
summary.setActivityKind(ActivityKind.UNKNOWN.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
summaryData.add(ACTIVE_SECONDS, duration, UNIT_SECONDS);
|
summaryData.add(ACTIVE_SECONDS, duration, UNIT_SECONDS);
|
||||||
|
@ -43,28 +43,27 @@ public class FitProSampleProvider extends AbstractSampleProvider<FitProActivityS
|
|||||||
// as per FitProDeviceSupport.rawActivityKindToUniqueKind
|
// as per FitProDeviceSupport.rawActivityKindToUniqueKind
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case 1:
|
case 1:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case 11:
|
case 11:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
case 12:
|
case 12:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
default:
|
default:
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_ACTIVITY:
|
case DEEP_SLEEP:
|
||||||
return 1;
|
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
|
||||||
return 11;
|
return 11;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
return 12;
|
return 12;
|
||||||
|
case ACTIVITY:
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -68,13 +68,13 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(final int rawType) {
|
public ActivityKind normalizeType(final int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(final int activityKind) {
|
public int toRawActivityKind(final ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -88,10 +88,9 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<GarminActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to, final int activityType) {
|
protected List<GarminActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to) {
|
||||||
LOG.trace(
|
LOG.trace(
|
||||||
"Getting garmin activity samples for {} between {} and {}",
|
"Getting garmin activity samples between {} and {}",
|
||||||
String.format("0x%08x", activityType),
|
|
||||||
timestamp_from,
|
timestamp_from,
|
||||||
timestamp_to
|
timestamp_to
|
||||||
);
|
);
|
||||||
@ -99,7 +98,7 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
|
|||||||
final long nanoStart = System.nanoTime();
|
final long nanoStart = System.nanoTime();
|
||||||
|
|
||||||
final List<GarminActivitySample> samples = fillGaps(
|
final List<GarminActivitySample> samples = fillGaps(
|
||||||
super.getGBActivitySamples(timestamp_from, timestamp_to, activityType),
|
super.getGBActivitySamples(timestamp_from, timestamp_to),
|
||||||
timestamp_from,
|
timestamp_from,
|
||||||
timestamp_to
|
timestamp_to
|
||||||
);
|
);
|
||||||
@ -121,7 +120,7 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
|
|||||||
|
|
||||||
public void overlaySleep(final List<GarminActivitySample> samples, final int timestamp_from, final int timestamp_to) {
|
public void overlaySleep(final List<GarminActivitySample> samples, final int timestamp_from, final int timestamp_to) {
|
||||||
// The samples provided by Garmin are upper-bound timestamps of the sleep stage
|
// The samples provided by Garmin are upper-bound timestamps of the sleep stage
|
||||||
final RangeMap<Long, Integer> stagesMap = new RangeMap<>(RangeMap.Mode.UPPER_BOUND);
|
final RangeMap<Long, ActivityKind> stagesMap = new RangeMap<>(RangeMap.Mode.UPPER_BOUND);
|
||||||
|
|
||||||
final GarminEventSampleProvider eventSampleProvider = new GarminEventSampleProvider(getDevice(), getSession());
|
final GarminEventSampleProvider eventSampleProvider = new GarminEventSampleProvider(getDevice(), getSession());
|
||||||
final List<GarminEventSample> sleepEventSamples = eventSampleProvider.getSleepEvents(
|
final List<GarminEventSample> sleepEventSamples = eventSampleProvider.getSleepEvents(
|
||||||
@ -134,7 +133,7 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
|
|||||||
switch (event.getEventType()) {
|
switch (event.getEventType()) {
|
||||||
case 0: // start
|
case 0: // start
|
||||||
// We only need the start event as an upper-bound timestamp (anything before it is unknown)
|
// We only need the start event as an upper-bound timestamp (anything before it is unknown)
|
||||||
stagesMap.put(event.getTimestamp(), ActivityKind.TYPE_UNKNOWN);
|
stagesMap.put(event.getTimestamp(), ActivityKind.UNKNOWN);
|
||||||
case 1: // stop
|
case 1: // stop
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
@ -170,18 +169,18 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
|
|||||||
if (!stagesMap.isEmpty()) {
|
if (!stagesMap.isEmpty()) {
|
||||||
for (final GarminActivitySample sample : samples) {
|
for (final GarminActivitySample sample : samples) {
|
||||||
final long ts = sample.getTimestamp() * 1000L;
|
final long ts = sample.getTimestamp() * 1000L;
|
||||||
final Integer sleepType = stagesMap.get(ts);
|
final ActivityKind sleepType = stagesMap.get(ts);
|
||||||
if (sleepType != null && !sleepType.equals(ActivityKind.TYPE_UNKNOWN)) {
|
if (sleepType != null && !sleepType.equals(ActivityKind.UNKNOWN)) {
|
||||||
sample.setRawKind(sleepType);
|
sample.setRawKind(sleepType.getCode());
|
||||||
|
|
||||||
switch (sleepType) {
|
switch (sleepType) {
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
sample.setRawIntensity(20);
|
sample.setRawIntensity(20);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
sample.setRawIntensity(30);
|
sample.setRawIntensity(30);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_REM_SLEEP:
|
case REM_SLEEP:
|
||||||
sample.setRawIntensity(40);
|
sample.setRawIntensity(40);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -190,22 +189,22 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int toActivityKind(final GarminSleepStageSample stageSample) {
|
private ActivityKind toActivityKind(final GarminSleepStageSample stageSample) {
|
||||||
final FieldDefinitionSleepStage.SleepStage sleepStage = FieldDefinitionSleepStage.SleepStage.fromId(stageSample.getStage());
|
final FieldDefinitionSleepStage.SleepStage sleepStage = FieldDefinitionSleepStage.SleepStage.fromId(stageSample.getStage());
|
||||||
if (sleepStage == null) {
|
if (sleepStage == null) {
|
||||||
LOG.error("Unknown sleep stage for {}", stageSample.getStage());
|
LOG.error("Unknown sleep stage for {}", stageSample.getStage());
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sleepStage) {
|
switch (sleepStage) {
|
||||||
case LIGHT:
|
case LIGHT:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
case DEEP:
|
case DEEP:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
case REM:
|
case REM:
|
||||||
return ActivityKind.TYPE_REM_SLEEP;
|
return ActivityKind.REM_SLEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
package nodomain.freeyourgadget.gadgetbridge.devices.hplus;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -28,6 +28,7 @@ import java.util.GregorianCalendar;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import de.greenrobot.dao.AbstractDao;
|
import de.greenrobot.dao.AbstractDao;
|
||||||
import de.greenrobot.dao.Property;
|
import de.greenrobot.dao.Property;
|
||||||
import de.greenrobot.dao.query.QueryBuilder;
|
import de.greenrobot.dao.query.QueryBuilder;
|
||||||
@ -45,36 +46,28 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.hplus.HPlusDataRecord;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.hplus.HPlusDataRecord;
|
||||||
|
|
||||||
public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealthActivitySample> {
|
public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealthActivitySample> {
|
||||||
|
|
||||||
private GBDevice mDevice;
|
|
||||||
private DaoSession mSession;
|
|
||||||
|
|
||||||
public HPlusHealthSampleProvider(GBDevice device, DaoSession session) {
|
public HPlusHealthSampleProvider(GBDevice device, DaoSession session) {
|
||||||
super(device, session);
|
super(device, session);
|
||||||
|
|
||||||
mSession = session;
|
|
||||||
mDevice = device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case HPlusDataRecord.TYPE_DAY_SLOT:
|
case HPlusDataRecord.TYPE_DAY_SLOT:
|
||||||
case HPlusDataRecord.TYPE_DAY_SUMMARY:
|
case HPlusDataRecord.TYPE_DAY_SUMMARY:
|
||||||
case HPlusDataRecord.TYPE_REALTIME:
|
case HPlusDataRecord.TYPE_REALTIME:
|
||||||
case HPlusDataRecord.TYPE_SLEEP:
|
case HPlusDataRecord.TYPE_SLEEP:
|
||||||
case HPlusDataRecord.TYPE_UNKNOWN:
|
case HPlusDataRecord.TYPE_UNKNOWN:
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
default:
|
default:
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
switch (activityKind){
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
case LIGHT_SLEEP:
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
return activityKind.getCode();
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
|
||||||
default:
|
default:
|
||||||
return HPlusDataRecord.TYPE_DAY_SLOT;
|
return HPlusDataRecord.TYPE_DAY_SLOT;
|
||||||
}
|
}
|
||||||
@ -113,20 +106,10 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
return getSession().getHPlusHealthActivitySampleDao();
|
return getSession().getHPlusHealthActivitySampleDao();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<HPlusHealthActivitySample> getActivityamples(int timestamp_from, int timestamp_to) {
|
|
||||||
return getAllActivitySamples(timestamp_from, timestamp_to);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public List<HPlusHealthActivitySample> getSleepSamples(int timestamp_from, int timestamp_to) {
|
|
||||||
return getAllActivitySamples(timestamp_from, timestamp_to);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public List<HPlusHealthActivitySample> getAllActivitySamples(int timestamp_from, int timestamp_to) {
|
public List<HPlusHealthActivitySample> getAllActivitySamples(int timestamp_from, int timestamp_to) {
|
||||||
List<HPlusHealthActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ALL);
|
List<HPlusHealthActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to);
|
||||||
|
|
||||||
Device dbDevice = DBHelper.findDevice(getDevice(), getSession());
|
Device dbDevice = DBHelper.findDevice(getDevice(), getSession());
|
||||||
if (dbDevice == null) {
|
if (dbDevice == null) {
|
||||||
@ -143,7 +126,6 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
List<HPlusHealthActivityOverlay> overlayRecords = qb.build().list();
|
List<HPlusHealthActivityOverlay> overlayRecords = qb.build().list();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Apply Overlays
|
//Apply Overlays
|
||||||
for (HPlusHealthActivityOverlay overlay : overlayRecords) {
|
for (HPlusHealthActivityOverlay overlay : overlayRecords) {
|
||||||
|
|
||||||
@ -167,22 +149,22 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
|
|
||||||
long nonSleepTimeEnd = 0;
|
long nonSleepTimeEnd = 0;
|
||||||
for (HPlusHealthActivitySample sample : samples) {
|
for (HPlusHealthActivitySample sample : samples) {
|
||||||
if (sample.getRawKind() == ActivityKind.TYPE_NOT_WORN)
|
if (sample.getRawKind() == ActivityKind.NOT_WORN.getCode())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (sample.getTimestamp() >= overlay.getTimestampFrom() && sample.getTimestamp() < overlay.getTimestampTo()) {
|
if (sample.getTimestamp() >= overlay.getTimestampFrom() && sample.getTimestamp() < overlay.getTimestampTo()) {
|
||||||
if (overlay.getRawKind() == ActivityKind.TYPE_NOT_WORN || overlay.getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP || overlay.getRawKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
if (overlay.getRawKind() == ActivityKind.NOT_WORN.getCode() || overlay.getRawKind() == ActivityKind.LIGHT_SLEEP.getCode() || overlay.getRawKind() == ActivityKind.DEEP_SLEEP.getCode()) {
|
||||||
if (sample.getRawKind() == HPlusDataRecord.TYPE_DAY_SLOT && sample.getSteps() > 0){
|
if (sample.getRawKind() == HPlusDataRecord.TYPE_DAY_SLOT && sample.getSteps() > 0) {
|
||||||
nonSleepTimeEnd = sample.getTimestamp() + 10 * 60; // 10 minutes
|
nonSleepTimeEnd = sample.getTimestamp() + 10 * 60; // 10 minutes
|
||||||
continue;
|
continue;
|
||||||
}else if(sample.getRawKind() == HPlusDataRecord.TYPE_REALTIME && sample.getTimestamp() <= nonSleepTimeEnd){
|
} else if (sample.getRawKind() == HPlusDataRecord.TYPE_REALTIME && sample.getTimestamp() <= nonSleepTimeEnd) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overlay.getRawKind() == ActivityKind.TYPE_NOT_WORN)
|
if (overlay.getRawKind() == ActivityKind.NOT_WORN.getCode())
|
||||||
sample.setHeartRate(0);
|
sample.setHeartRate(0);
|
||||||
|
|
||||||
if (sample.getRawKind() != ActivityKind.TYPE_NOT_WORN)
|
if (sample.getRawKind() != ActivityKind.NOT_WORN.getCode())
|
||||||
sample.setRawKind(overlay.getRawKind());
|
sample.setRawKind(overlay.getRawKind());
|
||||||
|
|
||||||
sample.setRawIntensity(10);
|
sample.setRawIntensity(10);
|
||||||
@ -192,7 +174,6 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Fix Step counters
|
//Fix Step counters
|
||||||
//Todays sample steps will come from the Day Slots messages
|
//Todays sample steps will come from the Day Slots messages
|
||||||
//Historical steps will be provided by Day Summaries messages
|
//Historical steps will be provided by Day Summaries messages
|
||||||
@ -207,19 +188,19 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
int stepsTodayCount = 0;
|
int stepsTodayCount = 0;
|
||||||
HPlusHealthActivitySample lastSample = null;
|
HPlusHealthActivitySample lastSample = null;
|
||||||
|
|
||||||
for (HPlusHealthActivitySample sample: samples) {
|
for (HPlusHealthActivitySample sample : samples) {
|
||||||
if (sample.getTimestamp() >= today.getTimeInMillis() / 1000) {
|
if (sample.getTimestamp() >= today.getTimeInMillis() / 1000) {
|
||||||
|
|
||||||
/**Strategy is:
|
/* Strategy is:
|
||||||
* Calculate max steps from realtime messages
|
* Calculate max steps from realtime messages
|
||||||
* Calculate sum of steps from day 10 minute slot summaries
|
* Calculate sum of steps from day 10 minute slot summaries
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(sample.getRawKind() == HPlusDataRecord.TYPE_REALTIME) {
|
if (sample.getRawKind() == HPlusDataRecord.TYPE_REALTIME) {
|
||||||
stepsTodayMax = Math.max(stepsTodayMax, sample.getSteps());
|
stepsTodayMax = Math.max(stepsTodayMax, sample.getSteps());
|
||||||
}else if(sample.getRawKind() == HPlusDataRecord.TYPE_DAY_SLOT) {
|
} else if (sample.getRawKind() == HPlusDataRecord.TYPE_DAY_SLOT) {
|
||||||
stepsTodayCount += sample.getSteps();
|
stepsTodayCount += sample.getSteps();
|
||||||
}
|
}
|
||||||
|
|
||||||
sample.setSteps(ActivitySample.NOT_MEASURED);
|
sample.setSteps(ActivitySample.NOT_MEASURED);
|
||||||
lastSample = sample;
|
lastSample = sample;
|
||||||
@ -230,7 +211,7 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lastSample != null)
|
if (lastSample != null)
|
||||||
lastSample.setSteps(Math.max(stepsTodayCount, stepsTodayMax));
|
lastSample.setSteps(Math.max(stepsTodayCount, stepsTodayMax));
|
||||||
|
|
||||||
detachFromSession();
|
detachFromSession();
|
||||||
@ -238,13 +219,13 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<HPlusHealthActivitySample> insertVirtualItem(List<HPlusHealthActivitySample> samples, int timestamp, long deviceId, long userId) {
|
private void insertVirtualItem(List<HPlusHealthActivitySample> samples, int timestamp, long deviceId, long userId) {
|
||||||
HPlusHealthActivitySample sample = new HPlusHealthActivitySample(
|
HPlusHealthActivitySample sample = new HPlusHealthActivitySample(
|
||||||
timestamp, // ts
|
timestamp, // ts
|
||||||
deviceId,
|
deviceId,
|
||||||
userId, // User id
|
userId, // User id
|
||||||
null, // Raw Data
|
null, // Raw Data
|
||||||
ActivityKind.TYPE_UNKNOWN,
|
ActivityKind.UNKNOWN.getCode(),
|
||||||
1, // Intensity
|
1, // Intensity
|
||||||
ActivitySample.NOT_MEASURED, // Steps
|
ActivitySample.NOT_MEASURED, // Steps
|
||||||
ActivitySample.NOT_MEASURED, // HR
|
ActivitySample.NOT_MEASURED, // HR
|
||||||
@ -254,8 +235,6 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
|
|||||||
|
|
||||||
sample.setProvider(this);
|
sample.setProvider(this);
|
||||||
samples.add(sample);
|
samples.add(sample);
|
||||||
|
|
||||||
return samples;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
|
|||||||
|
|
||||||
short version = buffer.getShort(); // version
|
short version = buffer.getShort(); // version
|
||||||
LOG.debug("Got sport summary version " + version + " total bytes=" + buffer.capacity());
|
LOG.debug("Got sport summary version " + version + " total bytes=" + buffer.capacity());
|
||||||
int activityKind = ActivityKind.TYPE_UNKNOWN;
|
ActivityKind activityKind = ActivityKind.UNKNOWN;
|
||||||
int rawKind = BLETypeConversions.toUnsigned(buffer.getShort());
|
int rawKind = BLETypeConversions.toUnsigned(buffer.getShort());
|
||||||
try {
|
try {
|
||||||
HuamiSportsActivityType activityType = HuamiSportsActivityType.fromCode(rawKind);
|
HuamiSportsActivityType activityType = HuamiSportsActivityType.fromCode(rawKind);
|
||||||
@ -70,7 +70,7 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
|
|||||||
LOG.error("Error mapping activity kind: " + ex.getMessage(), ex);
|
LOG.error("Error mapping activity kind: " + ex.getMessage(), ex);
|
||||||
summaryData.add("Raw Activity Kind", rawKind, UNIT_NONE);
|
summaryData.add("Raw Activity Kind", rawKind, UNIT_NONE);
|
||||||
}
|
}
|
||||||
summary.setActivityKind(activityKind);
|
summary.setActivityKind(activityKind.getCode());
|
||||||
|
|
||||||
// FIXME: should honor timezone we were in at that time etc
|
// FIXME: should honor timezone we were in at that time etc
|
||||||
long timestamp_start = BLETypeConversions.toUnsigned(buffer.getInt()) * 1000;
|
long timestamp_start = BLETypeConversions.toUnsigned(buffer.getInt()) * 1000;
|
||||||
@ -192,7 +192,7 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
|
|||||||
averageStride = buffer.getShort();
|
averageStride = buffer.getShort();
|
||||||
maxHR = buffer.getShort();
|
maxHR = buffer.getShort();
|
||||||
|
|
||||||
if (activityKind == ActivityKind.TYPE_CYCLING || activityKind == ActivityKind.TYPE_RUNNING || activityKind == ActivityKind.TYPE_HIKING || activityKind == ActivityKind.TYPE_CLIMBING) {
|
if (activityKind == ActivityKind.CYCLING || activityKind == ActivityKind.RUNNING || activityKind == ActivityKind.HIKING || activityKind == ActivityKind.CLIMBING) {
|
||||||
// this had nonsense data with treadmill on bip s, need to test it with running
|
// this had nonsense data with treadmill on bip s, need to test it with running
|
||||||
// for cycling it seems to work... hmm...
|
// for cycling it seems to work... hmm...
|
||||||
// 28 bytes
|
// 28 bytes
|
||||||
@ -203,7 +203,7 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
|
|||||||
descentSeconds = buffer.getInt() / 1000; //ms?
|
descentSeconds = buffer.getInt() / 1000; //ms?
|
||||||
flatDistance = buffer.getFloat();
|
flatDistance = buffer.getFloat();
|
||||||
flatSeconds = buffer.getInt() / 1000; // ms?
|
flatSeconds = buffer.getInt() / 1000; // ms?
|
||||||
} else if (activityKind == ActivityKind.TYPE_SWIMMING || activityKind == ActivityKind.TYPE_SWIMMING_OPENWATER) {
|
} else if (activityKind == ActivityKind.SWIMMING || activityKind == ActivityKind.SWIMMING_OPENWATER) {
|
||||||
// offset 0x8c
|
// offset 0x8c
|
||||||
/*
|
/*
|
||||||
data on the bip s display (example)
|
data on the bip s display (example)
|
||||||
@ -252,7 +252,7 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
|
|||||||
totalStride = buffer.getFloat();
|
totalStride = buffer.getFloat();
|
||||||
|
|
||||||
buffer.getInt(); // unknown
|
buffer.getInt(); // unknown
|
||||||
if (activityKind == ActivityKind.TYPE_SWIMMING) {
|
if (activityKind == ActivityKind.SWIMMING) {
|
||||||
// 28 bytes
|
// 28 bytes
|
||||||
averageStrokeDistance = buffer.getFloat();
|
averageStrokeDistance = buffer.getFloat();
|
||||||
averageStrokesPerSecond = buffer.getFloat();
|
averageStrokesPerSecond = buffer.getFloat();
|
||||||
@ -339,11 +339,11 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
|
|||||||
summaryData.add(CADENCE_MIN, minCadence, UNIT_SPM);
|
summaryData.add(CADENCE_MIN, minCadence, UNIT_SPM);
|
||||||
summaryData.add(CADENCE_AVG, averageCadence, UNIT_SPM);
|
summaryData.add(CADENCE_AVG, averageCadence, UNIT_SPM);
|
||||||
|
|
||||||
if (!(activityKind == ActivityKind.TYPE_ELLIPTICAL_TRAINER ||
|
if (!(activityKind == ActivityKind.ELLIPTICAL_TRAINER ||
|
||||||
activityKind == ActivityKind.TYPE_JUMP_ROPING ||
|
activityKind == ActivityKind.JUMP_ROPING ||
|
||||||
activityKind == ActivityKind.TYPE_EXERCISE ||
|
activityKind == ActivityKind.EXERCISE ||
|
||||||
activityKind == ActivityKind.TYPE_YOGA ||
|
activityKind == ActivityKind.YOGA ||
|
||||||
activityKind == ActivityKind.TYPE_INDOOR_CYCLING)) {
|
activityKind == ActivityKind.INDOOR_CYCLING)) {
|
||||||
summaryData.add(PACE_MIN, minPace, UNIT_SECONDS_PER_M);
|
summaryData.add(PACE_MIN, minPace, UNIT_SECONDS_PER_M);
|
||||||
summaryData.add(PACE_MAX, maxPace, UNIT_SECONDS_PER_M);
|
summaryData.add(PACE_MAX, maxPace, UNIT_SECONDS_PER_M);
|
||||||
// summaryData.add("averagePace", averagePace, UNIT_SECONDS_PER_M);
|
// summaryData.add("averagePace", averagePace, UNIT_SECONDS_PER_M);
|
||||||
@ -359,7 +359,7 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
|
|||||||
summaryData.add(STRIDE_MIN, minStride, UNIT_CM);
|
summaryData.add(STRIDE_MIN, minStride, UNIT_CM);
|
||||||
// summaryData.add("averageStride2", averageStride2, UNIT_CM);
|
// summaryData.add("averageStride2", averageStride2, UNIT_CM);
|
||||||
|
|
||||||
if (activityKind == ActivityKind.TYPE_SWIMMING || activityKind == ActivityKind.TYPE_SWIMMING_OPENWATER) {
|
if (activityKind == ActivityKind.SWIMMING || activityKind == ActivityKind.SWIMMING_OPENWATER) {
|
||||||
summaryData.add(STROKE_DISTANCE_AVG, averageStrokeDistance, UNIT_METERS);
|
summaryData.add(STROKE_DISTANCE_AVG, averageStrokeDistance, UNIT_METERS);
|
||||||
summaryData.add(STROKE_AVG_PER_SECOND, averageStrokesPerSecond, UNIT_STROKES_PER_SECOND);
|
summaryData.add(STROKE_AVG_PER_SECOND, averageStrokesPerSecond, UNIT_STROKES_PER_SECOND);
|
||||||
summaryData.add(LAP_PACE_AVERAGE, averageLapPace, "second");
|
summaryData.add(LAP_PACE_AVERAGE, averageLapPace, "second");
|
||||||
|
@ -142,39 +142,39 @@ public class HuamiConst {
|
|||||||
public static final String PREF_HUAMI_VIBRATION_TRY_TODO_LIST = PREF_HUAMI_VIBRATION_TRY_PREFIX + "todo_list";
|
public static final String PREF_HUAMI_VIBRATION_TRY_TODO_LIST = PREF_HUAMI_VIBRATION_TRY_PREFIX + "todo_list";
|
||||||
public static final String PREF_HUAMI_VIBRATION_TRY_SCHEDULE = PREF_HUAMI_VIBRATION_TRY_PREFIX + "schedule";
|
public static final String PREF_HUAMI_VIBRATION_TRY_SCHEDULE = PREF_HUAMI_VIBRATION_TRY_PREFIX + "schedule";
|
||||||
|
|
||||||
public static int toActivityKind(int rawType) {
|
public static ActivityKind toActivityKind(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case TYPE_DEEP_SLEEP:
|
case TYPE_DEEP_SLEEP:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
case TYPE_LIGHT_SLEEP:
|
case TYPE_LIGHT_SLEEP:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
case TYPE_ACTIVITY:
|
case TYPE_ACTIVITY:
|
||||||
case TYPE_RUNNING:
|
case TYPE_RUNNING:
|
||||||
case TYPE_WAKE_UP:
|
case TYPE_WAKE_UP:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case TYPE_NONWEAR:
|
case TYPE_NONWEAR:
|
||||||
return ActivityKind.TYPE_NOT_WORN;
|
return ActivityKind.NOT_WORN;
|
||||||
case TYPE_CHARGING:
|
case TYPE_CHARGING:
|
||||||
return ActivityKind.TYPE_NOT_WORN; //I believe it's a safe assumption
|
return ActivityKind.NOT_WORN; //I believe it's a safe assumption
|
||||||
case TYPE_RIDE_BIKE:
|
case TYPE_RIDE_BIKE:
|
||||||
return ActivityKind.TYPE_CYCLING;
|
return ActivityKind.CYCLING;
|
||||||
default:
|
default:
|
||||||
case TYPE_UNSET: // fall through
|
case TYPE_UNSET: // fall through
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int toRawActivityType(int activityKind) {
|
public static int toRawActivityType(ActivityKind activityKind) {
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_ACTIVITY:
|
case ACTIVITY:
|
||||||
return TYPE_ACTIVITY;
|
return TYPE_ACTIVITY;
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
return TYPE_DEEP_SLEEP;
|
return TYPE_DEEP_SLEEP;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
return TYPE_LIGHT_SLEEP;
|
return TYPE_LIGHT_SLEEP;
|
||||||
case ActivityKind.TYPE_NOT_WORN:
|
case NOT_WORN:
|
||||||
return TYPE_NONWEAR;
|
return TYPE_NONWEAR;
|
||||||
case ActivityKind.TYPE_UNKNOWN: // fall through
|
case UNKNOWN: // fall through
|
||||||
default:
|
default:
|
||||||
return TYPE_UNSET;
|
return TYPE_UNSET;
|
||||||
}
|
}
|
||||||
|
@ -75,8 +75,8 @@ public class HuamiExtendedSampleProvider extends AbstractSampleProvider<HuamiExt
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<HuamiExtendedActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to, final int activityType) {
|
protected List<HuamiExtendedActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to) {
|
||||||
final List<HuamiExtendedActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to, activityType);
|
final List<HuamiExtendedActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to);
|
||||||
postProcess(samples);
|
postProcess(samples);
|
||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
@ -108,34 +108,34 @@ public class HuamiExtendedSampleProvider extends AbstractSampleProvider<HuamiExt
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(final int rawType) {
|
public ActivityKind normalizeType(final int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case TYPE_OUTDOOR_RUNNING:
|
case TYPE_OUTDOOR_RUNNING:
|
||||||
return ActivityKind.TYPE_RUNNING;
|
return ActivityKind.RUNNING;
|
||||||
case TYPE_NOT_WORN:
|
case TYPE_NOT_WORN:
|
||||||
case TYPE_CHARGING:
|
case TYPE_CHARGING:
|
||||||
return ActivityKind.TYPE_NOT_WORN;
|
return ActivityKind.NOT_WORN;
|
||||||
case TYPE_SLEEP:
|
case TYPE_SLEEP:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
case TYPE_CUSTOM_DEEP_SLEEP:
|
case TYPE_CUSTOM_DEEP_SLEEP:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
case TYPE_CUSTOM_REM_SLEEP:
|
case TYPE_CUSTOM_REM_SLEEP:
|
||||||
return ActivityKind.TYPE_REM_SLEEP;
|
return ActivityKind.REM_SLEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(final int activityKind) {
|
public int toRawActivityKind(final ActivityKind activityKind) {
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_RUNNING:
|
case RUNNING:
|
||||||
return TYPE_OUTDOOR_RUNNING;
|
return TYPE_OUTDOOR_RUNNING;
|
||||||
case ActivityKind.TYPE_NOT_WORN:
|
case NOT_WORN:
|
||||||
return TYPE_NOT_WORN;
|
return TYPE_NOT_WORN;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
case ActivityKind.TYPE_REM_SLEEP:
|
case REM_SLEEP:
|
||||||
return TYPE_SLEEP;
|
return TYPE_SLEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,14 +63,14 @@ public class ZeppOsActivitySummaryParser extends HuamiActivitySummaryParser {
|
|||||||
final ZeppOsActivityType activityType = ZeppOsActivityType
|
final ZeppOsActivityType activityType = ZeppOsActivityType
|
||||||
.fromCode((byte) summaryProto.getType().getType());
|
.fromCode((byte) summaryProto.getType().getType());
|
||||||
|
|
||||||
final int activityKind;
|
final ActivityKind activityKind;
|
||||||
if (activityType != null) {
|
if (activityType != null) {
|
||||||
activityKind = activityType.toActivityKind();
|
activityKind = activityType.toActivityKind();
|
||||||
} else {
|
} else {
|
||||||
LOG.warn("Unknown workout activity type code {}", String.format("0x%X", summaryProto.getType().getType()));
|
LOG.warn("Unknown workout activity type code {}", String.format("0x%X", summaryProto.getType().getType()));
|
||||||
activityKind = ActivityKind.TYPE_UNKNOWN;
|
activityKind = ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
summary.setActivityKind(activityKind);
|
summary.setActivityKind(activityKind.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (summaryProto.hasTime()) {
|
if (summaryProto.hasTime()) {
|
||||||
|
@ -72,23 +72,23 @@ public class HuaweiSampleProvider extends AbstractSampleProvider<HuaweiActivityS
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case RawTypes.DEEP_SLEEP:
|
case RawTypes.DEEP_SLEEP:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
case RawTypes.LIGHT_SLEEP:
|
case RawTypes.LIGHT_SLEEP:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
default:
|
default:
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
return RawTypes.DEEP_SLEEP;
|
return RawTypes.DEEP_SLEEP;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
return RawTypes.LIGHT_SLEEP;
|
return RawTypes.LIGHT_SLEEP;
|
||||||
default:
|
default:
|
||||||
return RawTypes.NOT_MEASURED;
|
return RawTypes.NOT_MEASURED;
|
||||||
@ -294,8 +294,6 @@ public class HuaweiSampleProvider extends AbstractSampleProvider<HuaweiActivityS
|
|||||||
public long deviceId = 0;
|
public long deviceId = 0;
|
||||||
public long userId = 0;
|
public long userId = 0;
|
||||||
|
|
||||||
int[] activityTypes = {};
|
|
||||||
|
|
||||||
public int sleepModifier = 0;
|
public int sleepModifier = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +312,7 @@ public class HuaweiSampleProvider extends AbstractSampleProvider<HuaweiActivityS
|
|||||||
* Note that the data in the database isn't changed, as the samples are detached.
|
* Note that the data in the database isn't changed, as the samples are detached.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected List<HuaweiActivitySample> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) {
|
protected List<HuaweiActivitySample> getGBActivitySamples(int timestamp_from, int timestamp_to) {
|
||||||
// Note that the result of this function has to be sorted by timestamp!
|
// Note that the result of this function has to be sorted by timestamp!
|
||||||
|
|
||||||
List<HuaweiActivitySample> rawSamples = getRawOrderedActivitySamples(timestamp_from, timestamp_to);
|
List<HuaweiActivitySample> rawSamples = getRawOrderedActivitySamples(timestamp_from, timestamp_to);
|
||||||
@ -337,7 +335,6 @@ public class HuaweiSampleProvider extends AbstractSampleProvider<HuaweiActivityS
|
|||||||
state.deviceId = nextRawSample.getDeviceId();
|
state.deviceId = nextRawSample.getDeviceId();
|
||||||
state.userId = nextRawSample.getUserId();
|
state.userId = nextRawSample.getUserId();
|
||||||
}
|
}
|
||||||
state.activityTypes = ActivityKind.mapToDBActivityTypes(activityType, this);
|
|
||||||
|
|
||||||
while (nextRawSample != null || nextWorkoutSample != null) {
|
while (nextRawSample != null || nextWorkoutSample != null) {
|
||||||
if (nextRawSample == null) {
|
if (nextRawSample == null) {
|
||||||
|
@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.ID115ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.ID115ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.ID115ActivitySampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.ID115ActivitySampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class ID115SampleProvider extends AbstractSampleProvider<ID115ActivitySample> {
|
public class ID115SampleProvider extends AbstractSampleProvider<ID115ActivitySample> {
|
||||||
public ID115SampleProvider(GBDevice device, DaoSession session) {
|
public ID115SampleProvider(GBDevice device, DaoSession session) {
|
||||||
@ -55,13 +56,13 @@ public class ID115SampleProvider extends AbstractSampleProvider<ID115ActivitySam
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,6 +26,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.JYouActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.JYouActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.JYouActivitySampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.JYouActivitySampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class JYouSampleProvider extends AbstractSampleProvider<JYouActivitySample> {
|
public class JYouSampleProvider extends AbstractSampleProvider<JYouActivitySample> {
|
||||||
|
|
||||||
@ -42,13 +43,13 @@ public class JYouSampleProvider extends AbstractSampleProvider<JYouActivitySampl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -60,28 +60,28 @@ public class LefunSampleProvider extends AbstractSampleProvider<LefunActivitySam
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case LefunConstants.DB_ACTIVITY_KIND_ACTIVITY:
|
case LefunConstants.DB_ACTIVITY_KIND_ACTIVITY:
|
||||||
case LefunConstants.DB_ACTIVITY_KIND_HEART_RATE:
|
case LefunConstants.DB_ACTIVITY_KIND_HEART_RATE:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case LefunConstants.DB_ACTIVITY_KIND_LIGHT_SLEEP:
|
case LefunConstants.DB_ACTIVITY_KIND_LIGHT_SLEEP:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
case LefunConstants.DB_ACTIVITY_KIND_DEEP_SLEEP:
|
case LefunConstants.DB_ACTIVITY_KIND_DEEP_SLEEP:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
default:
|
default:
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_ACTIVITY:
|
case ACTIVITY:
|
||||||
return LefunConstants.DB_ACTIVITY_KIND_ACTIVITY;
|
return LefunConstants.DB_ACTIVITY_KIND_ACTIVITY;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
return LefunConstants.DB_ACTIVITY_KIND_LIGHT_SLEEP;
|
return LefunConstants.DB_ACTIVITY_KIND_LIGHT_SLEEP;
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
return LefunConstants.DB_ACTIVITY_KIND_DEEP_SLEEP;
|
return LefunConstants.DB_ACTIVITY_KIND_DEEP_SLEEP;
|
||||||
default:
|
default:
|
||||||
return LefunConstants.DB_ACTIVITY_KIND_UNKNOWN;
|
return LefunConstants.DB_ACTIVITY_KIND_UNKNOWN;
|
||||||
|
@ -52,14 +52,14 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
LOG.info(" toRawActivityKind: " + activityKind);
|
LOG.debug("toRawActivityKind: {}", activityKind);
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -104,8 +104,8 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
return WatchXPlusActivitySampleDao.Properties.DeviceId;
|
return WatchXPlusActivitySampleDao.Properties.DeviceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate ActivityKind.TYPE_NOT_MEASURED if there are no data for more than 15 min. and less than 60 min.
|
// generate ActivityKind.NOT_MEASURED if there are no data for more than 15 min. and less than 60 min.
|
||||||
// generate ActivityKind.TYPE_NOT_WORN if there are no data for more than 60 min.
|
// generate ActivityKind.NOT_WORN if there are no data for more than 60 min.
|
||||||
@NonNull
|
@NonNull
|
||||||
private List<WatchXPlusActivitySample> checkActivityData(List<WatchXPlusActivitySample> samples, int notMeasuredTS, int notWornTS) {
|
private List<WatchXPlusActivitySample> checkActivityData(List<WatchXPlusActivitySample> samples, int notMeasuredTS, int notWornTS) {
|
||||||
int oldTS = 0;
|
int oldTS = 0;
|
||||||
@ -116,13 +116,13 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
newTS = samples.get(i).getTimestamp();
|
newTS = samples.get(i).getTimestamp();
|
||||||
if ((newTS - oldTS) < notMeasuredTS) { //check data timestamp diff is more than 15 min
|
if ((newTS - oldTS) < notMeasuredTS) { //check data timestamp diff is more than 15 min
|
||||||
oldTS = samples.get(i).getTimestamp();
|
oldTS = samples.get(i).getTimestamp();
|
||||||
} else if (((newTS - oldTS) > notMeasuredTS) && ((newTS - oldTS) < notWornTS)) { //set data to ActivityKind.TYPE_NOT_MEASURED) if timestamp diff is more than 15 min
|
} else if (((newTS - oldTS) > notMeasuredTS) && ((newTS - oldTS) < notWornTS)) { //set data to ActivityKind.NOT_MEASURED) if timestamp diff is more than 15 min
|
||||||
samples.get(i-1).setRawKind(ActivityKind.TYPE_NOT_MEASURED);
|
samples.get(i-1).setRawKind(ActivityKind.NOT_MEASURED.getCode());
|
||||||
samples.get(i).setRawKind(ActivityKind.TYPE_NOT_MEASURED);
|
samples.get(i).setRawKind(ActivityKind.NOT_MEASURED.getCode());
|
||||||
oldTS = samples.get(i).getTimestamp();
|
oldTS = samples.get(i).getTimestamp();
|
||||||
} else if ((newTS - oldTS) > notWornTS) { //set data to ActivityKind.TYPE_NOT_WORN if timestamp diff is more than 60 min
|
} else if ((newTS - oldTS) > notWornTS) { //set data to ActivityKind.NOT_WORN if timestamp diff is more than 60 min
|
||||||
samples.get(i-1).setRawKind(ActivityKind.TYPE_NOT_WORN);
|
samples.get(i-1).setRawKind(ActivityKind.NOT_WORN.getCode());
|
||||||
samples.get(i).setRawKind(ActivityKind.TYPE_NOT_WORN);
|
samples.get(i).setRawKind(ActivityKind.NOT_WORN.getCode());
|
||||||
oldTS = samples.get(i).getTimestamp();
|
oldTS = samples.get(i).getTimestamp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,9 +137,9 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
public List<WatchXPlusActivitySample> getAllActivitySamples(int timestamp_from, int timestamp_to) {
|
public List<WatchXPlusActivitySample> getAllActivitySamples(int timestamp_from, int timestamp_to) {
|
||||||
boolean showRawData = GBApplication.getDeviceSpecificSharedPrefs(mDevice.getAddress()).getBoolean(WatchXPlusConstants.PREF_SHOW_RAW_GRAPH, false);
|
boolean showRawData = GBApplication.getDeviceSpecificSharedPrefs(mDevice.getAddress()).getBoolean(WatchXPlusConstants.PREF_SHOW_RAW_GRAPH, false);
|
||||||
if (showRawData) {
|
if (showRawData) {
|
||||||
return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ALL);
|
return getGBActivitySamples(timestamp_from, timestamp_to);
|
||||||
}
|
}
|
||||||
List<WatchXPlusActivitySample> samples = getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ALL);
|
List<WatchXPlusActivitySample> samples = getGBActivitySamples(timestamp_from, timestamp_to);
|
||||||
int numEntries = samples.size();
|
int numEntries = samples.size();
|
||||||
if (numEntries < 3) {
|
if (numEntries < 3) {
|
||||||
return samples;
|
return samples;
|
||||||
@ -151,14 +151,14 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
int seekAhead = 10;
|
int seekAhead = 10;
|
||||||
boolean secondBlock = false;
|
boolean secondBlock = false;
|
||||||
|
|
||||||
// find sleep start and sleep stop index based on ActivityKind.TYPE_DEEP_SLEEP BLOCK 1
|
// find sleep start and sleep stop index based on ActivityKind.DEEP_SLEEP BLOCK 1
|
||||||
int sleepStartIndex_1 = 0;
|
int sleepStartIndex_1 = 0;
|
||||||
int sleepStopIndex_1 = numEntries;
|
int sleepStopIndex_1 = numEntries;
|
||||||
int countNextSleepStart_1 = 0;
|
int countNextSleepStart_1 = 0;
|
||||||
int countNextSleepStop_1 = 0;
|
int countNextSleepStop_1 = 0;
|
||||||
|
|
||||||
for (int i = 0; i < numEntries; i++) {
|
for (int i = 0; i < numEntries; i++) {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
if (samples.get(i).getRawKind() == ActivityKind.DEEP_SLEEP.getCode()) {
|
||||||
// normalize RawIntensity
|
// normalize RawIntensity
|
||||||
samples.get(i).setRawIntensity(1000);
|
samples.get(i).setRawIntensity(1000);
|
||||||
// find sleep start index
|
// find sleep start index
|
||||||
@ -186,7 +186,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// find sleep start and sleep stop index based on ActivityKind.TYPE_DEEP_SLEEP BLOCK 2
|
// find sleep start and sleep stop index based on ActivityKind.DEEP_SLEEP BLOCK 2
|
||||||
int sleepStartIndex_2 = 0;
|
int sleepStartIndex_2 = 0;
|
||||||
int sleepStopIndex_2 = numEntries;
|
int sleepStopIndex_2 = numEntries;
|
||||||
int countNextSleepStart_2 = 0;
|
int countNextSleepStart_2 = 0;
|
||||||
@ -194,7 +194,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
int next_block = numEntries;
|
int next_block = numEntries;
|
||||||
|
|
||||||
for (int i = sleepStopIndex_1 + 1; i < numEntries; i++) {
|
for (int i = sleepStopIndex_1 + 1; i < numEntries; i++) {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
if (samples.get(i).getRawKind() == ActivityKind.DEEP_SLEEP.getCode()) {
|
||||||
// find sleep start index
|
// find sleep start index
|
||||||
if (sleepStartIndex_2 == 0) {
|
if (sleepStartIndex_2 == 0) {
|
||||||
sleepStartIndex_2 = i;
|
sleepStartIndex_2 = i;
|
||||||
@ -239,7 +239,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
newSleepStartIndex_1 = 0;
|
newSleepStartIndex_1 = 0;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < newSleepStartIndex_1; i++) {
|
for (int i = 0; i < newSleepStartIndex_1; i++) {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
if (samples.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) {
|
||||||
if (samples.get(i).getRawIntensity() <= 300) {
|
if (samples.get(i).getRawIntensity() <= 300) {
|
||||||
samples.get(i).setRawIntensity(200);
|
samples.get(i).setRawIntensity(200);
|
||||||
} else if ((samples.get(i).getRawIntensity() <= 1000) && (samples.get(i).getRawIntensity() > 100)) {
|
} else if ((samples.get(i).getRawIntensity() <= 1000) && (samples.get(i).getRawIntensity() > 100)) {
|
||||||
@ -250,9 +250,9 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
samples.get(i).setRawKind(1);
|
samples.get(i).setRawKind(1);
|
||||||
resultList.add(samples.get(i));
|
resultList.add(samples.get(i));
|
||||||
} else {
|
} else {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_ACTIVITY) {
|
if (samples.get(i).getRawKind() == ActivityKind.ACTIVITY.getCode()) {
|
||||||
if (i < (newSleepStartIndex_1 - 3)) {
|
if (i < (newSleepStartIndex_1 - 3)) {
|
||||||
if ((samples.get(i + 1).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) || (samples.get(i + 2).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) || (samples.get(i + 3).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP)) {
|
if ((samples.get(i + 1).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) || (samples.get(i + 2).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) || (samples.get(i + 3).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode())) {
|
||||||
samples.get(i).setRawKind(1);
|
samples.get(i).setRawKind(1);
|
||||||
//samples.get(i).setRawIntensity(700);
|
//samples.get(i).setRawIntensity(700);
|
||||||
} else {
|
} else {
|
||||||
@ -280,7 +280,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
for (int i = newSleepStartIndex_1; i < newSleepStopIndex_1; i++) {
|
for (int i = newSleepStartIndex_1; i < newSleepStopIndex_1; i++) {
|
||||||
ActivitySample sample = samples.get(i);
|
ActivitySample sample = samples.get(i);
|
||||||
if (i < sleepStartIndex_1) {
|
if (i < sleepStartIndex_1) {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
if (samples.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) {
|
||||||
replaceActivity_1 = true;
|
replaceActivity_1 = true;
|
||||||
samples.get(i).setRawIntensity(600);
|
samples.get(i).setRawIntensity(600);
|
||||||
resultList.add(samples.get(i));
|
resultList.add(samples.get(i));
|
||||||
@ -295,8 +295,8 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((samples.get(i).getRawKind() == ActivityKind.TYPE_DEEP_SLEEP) || (samples.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP)) {
|
if ((samples.get(i).getRawKind() == ActivityKind.DEEP_SLEEP.getCode()) || (samples.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode())) {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
if (samples.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
if (samples.get(i - 1).getHeartRate() > 0) {
|
if (samples.get(i - 1).getHeartRate() > 0) {
|
||||||
samples.get(i).setHeartRate(samples.get(i - 1).getHeartRate());
|
samples.get(i).setHeartRate(samples.get(i - 1).getHeartRate());
|
||||||
@ -314,7 +314,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((samples.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) && (i > sleepStopIndex_1)) {
|
if ((samples.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) && (i > sleepStopIndex_1)) {
|
||||||
samples.get(i).setRawIntensity(600);
|
samples.get(i).setRawIntensity(600);
|
||||||
resultList.add(samples.get(i));
|
resultList.add(samples.get(i));
|
||||||
}
|
}
|
||||||
@ -324,7 +324,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
// add remaining activity
|
// add remaining activity
|
||||||
if (newSleepStopIndex_1 < next_block) {
|
if (newSleepStopIndex_1 < next_block) {
|
||||||
for (int i = newSleepStopIndex_1; i < (next_block-1); i++) {
|
for (int i = newSleepStopIndex_1; i < (next_block-1); i++) {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
if (samples.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) {
|
||||||
if (samples.get(i).getRawIntensity() <= 300) {
|
if (samples.get(i).getRawIntensity() <= 300) {
|
||||||
samples.get(i).setRawIntensity(200);
|
samples.get(i).setRawIntensity(200);
|
||||||
} else if ((samples.get(i).getRawIntensity() <= 1000) && (samples.get(i).getRawIntensity() > 100)) {
|
} else if ((samples.get(i).getRawIntensity() <= 1000) && (samples.get(i).getRawIntensity() > 100)) {
|
||||||
@ -335,9 +335,9 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
samples.get(i).setRawKind(1);
|
samples.get(i).setRawKind(1);
|
||||||
resultList.add(samples.get(i));
|
resultList.add(samples.get(i));
|
||||||
} else {
|
} else {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_ACTIVITY) {
|
if (samples.get(i).getRawKind() == ActivityKind.ACTIVITY.getCode()) {
|
||||||
if (i < (next_block - 3)) {
|
if (i < (next_block - 3)) {
|
||||||
if ((samples.get(i + 1).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) || (samples.get(i + 2).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) || (samples.get(i + 3).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP)) {
|
if ((samples.get(i + 1).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) || (samples.get(i + 2).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) || (samples.get(i + 3).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode())) {
|
||||||
samples.get(i).setRawKind(1);
|
samples.get(i).setRawKind(1);
|
||||||
//samples.get(i).setRawIntensity(700);
|
//samples.get(i).setRawIntensity(700);
|
||||||
} else {
|
} else {
|
||||||
@ -371,7 +371,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
for (int i = newSleepStartIndex_2; i < newSleepStopIndex_2; i++) {
|
for (int i = newSleepStartIndex_2; i < newSleepStopIndex_2; i++) {
|
||||||
ActivitySample sample = samples.get(i);
|
ActivitySample sample = samples.get(i);
|
||||||
if (i < sleepStartIndex_2) {
|
if (i < sleepStartIndex_2) {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
if (samples.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) {
|
||||||
replaceActivity_2 = true;
|
replaceActivity_2 = true;
|
||||||
samples.get(i).setRawIntensity(600);
|
samples.get(i).setRawIntensity(600);
|
||||||
resultList.add(samples.get(i));
|
resultList.add(samples.get(i));
|
||||||
@ -388,8 +388,8 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((samples.get(i).getRawKind() == ActivityKind.TYPE_DEEP_SLEEP) || (samples.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP)) {
|
if ((samples.get(i).getRawKind() == ActivityKind.DEEP_SLEEP.getCode()) || (samples.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode())) {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
if (samples.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
if (samples.get(i - 1).getHeartRate() > 0) {
|
if (samples.get(i - 1).getHeartRate() > 0) {
|
||||||
samples.get(i).setHeartRate(samples.get(i - 1).getHeartRate());
|
samples.get(i).setHeartRate(samples.get(i - 1).getHeartRate());
|
||||||
@ -406,7 +406,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
resultList.add(samples.get(i));
|
resultList.add(samples.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((samples.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) && (i > sleepStopIndex_2)) {
|
if ((samples.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) && (i > sleepStopIndex_2)) {
|
||||||
samples.get(i).setRawIntensity(600);
|
samples.get(i).setRawIntensity(600);
|
||||||
resultList.add(samples.get(i));
|
resultList.add(samples.get(i));
|
||||||
}
|
}
|
||||||
@ -415,7 +415,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
// add remaining activity
|
// add remaining activity
|
||||||
if (newSleepStopIndex_2 < numEntries) {
|
if (newSleepStopIndex_2 < numEntries) {
|
||||||
for (int i = newSleepStopIndex_2; i < (numEntries - 1); i++) {
|
for (int i = newSleepStopIndex_2; i < (numEntries - 1); i++) {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
if (samples.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) {
|
||||||
if (samples.get(i).getRawIntensity() <= 300) {
|
if (samples.get(i).getRawIntensity() <= 300) {
|
||||||
samples.get(i).setRawIntensity(200);
|
samples.get(i).setRawIntensity(200);
|
||||||
} else if ((samples.get(i).getRawIntensity() <= 1000) && (samples.get(i).getRawIntensity() > 100)) {
|
} else if ((samples.get(i).getRawIntensity() <= 1000) && (samples.get(i).getRawIntensity() > 100)) {
|
||||||
@ -427,9 +427,9 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
samples.get(i).setRawKind(1);
|
samples.get(i).setRawKind(1);
|
||||||
resultList.add(samples.get(i));
|
resultList.add(samples.get(i));
|
||||||
} else {
|
} else {
|
||||||
if (samples.get(i).getRawKind() == ActivityKind.TYPE_ACTIVITY) {
|
if (samples.get(i).getRawKind() == ActivityKind.ACTIVITY.getCode()) {
|
||||||
if (i < (numEntries - 3)) {
|
if (i < (numEntries - 3)) {
|
||||||
if ((samples.get(i + 1).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) || (samples.get(i + 2).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP) || (samples.get(i + 3).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP)) {
|
if ((samples.get(i + 1).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) || (samples.get(i + 2).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode()) || (samples.get(i + 3).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode())) {
|
||||||
samples.get(i).setRawKind(1);
|
samples.get(i).setRawKind(1);
|
||||||
//samples.get(i).setRawIntensity(700);
|
//samples.get(i).setRawIntensity(700);
|
||||||
} else {
|
} else {
|
||||||
@ -445,9 +445,9 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add one ActivityKind.TYPE_NOT_MEASURED at end of data
|
// add one ActivityKind.NOT_MEASURED at end of data
|
||||||
samples.get(numEntries-1).setRawIntensity(0);
|
samples.get(numEntries-1).setRawIntensity(0);
|
||||||
samples.get(numEntries-1).setRawKind(ActivityKind.TYPE_NOT_MEASURED);
|
samples.get(numEntries-1).setRawKind(ActivityKind.NOT_MEASURED.getCode());
|
||||||
samples.get(numEntries-1).setHeartRate(0);
|
samples.get(numEntries-1).setHeartRate(0);
|
||||||
resultList.add(samples.get(numEntries-1));
|
resultList.add(samples.get(numEntries-1));
|
||||||
|
|
||||||
@ -456,7 +456,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
int maxHeartRate = 10;
|
int maxHeartRate = 10;
|
||||||
numEntries = resultList.size();
|
numEntries = resultList.size();
|
||||||
for (int i = 0; i < numEntries-1; i++) {
|
for (int i = 0; i < numEntries-1; i++) {
|
||||||
if (resultList.get(i).getRawKind() == ActivityKind.TYPE_ACTIVITY) {
|
if (resultList.get(i).getRawKind() == ActivityKind.ACTIVITY.getCode()) {
|
||||||
if (resultList.get(i).getSteps() > 0) {
|
if (resultList.get(i).getSteps() > 0) {
|
||||||
totalSteps = totalSteps + resultList.get(i).getSteps();
|
totalSteps = totalSteps + resultList.get(i).getSteps();
|
||||||
}
|
}
|
||||||
@ -470,7 +470,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
int newIntensity, correctedSteps;
|
int newIntensity, correctedSteps;
|
||||||
int totalIntensity = 0;
|
int totalIntensity = 0;
|
||||||
for (int i = 0; i < numEntries-1; i++) {
|
for (int i = 0; i < numEntries-1; i++) {
|
||||||
if ((resultList.get(i).getRawKind() == ActivityKind.TYPE_ACTIVITY) || (resultList.get(i).getRawKind() == ActivityKind.TYPE_LIGHT_SLEEP)) {
|
if ((resultList.get(i).getRawKind() == ActivityKind.ACTIVITY.getCode()) || (resultList.get(i).getRawKind() == ActivityKind.LIGHT_SLEEP.getCode())) {
|
||||||
if (resultList.get(i).getRawIntensity() <= 600) { // set interpolated intensity based on heart rate for every TYPE_ACTIVITY which are converted from TYPE_LIGHT_SLEEP
|
if (resultList.get(i).getRawIntensity() <= 600) { // set interpolated intensity based on heart rate for every TYPE_ACTIVITY which are converted from TYPE_LIGHT_SLEEP
|
||||||
if (resultList.get(i).getHeartRate() < 10) {
|
if (resultList.get(i).getHeartRate() < 10) {
|
||||||
newIntensity = resultList.get(i).getRawIntensity() + ((maxHeartRate - resultList.get(i+1).getHeartRate()) * 2);
|
newIntensity = resultList.get(i).getRawIntensity() + ((maxHeartRate - resultList.get(i+1).getHeartRate()) * 2);
|
||||||
@ -507,7 +507,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
if (totalSteps > 0) {
|
if (totalSteps > 0) {
|
||||||
stepsPerActivity = totalIntensity / totalSteps;
|
stepsPerActivity = totalIntensity / totalSteps;
|
||||||
for (int i = 0; i < numEntries - 1; i++) {
|
for (int i = 0; i < numEntries - 1; i++) {
|
||||||
if (resultList.get(i).getRawKind() == ActivityKind.TYPE_ACTIVITY) {
|
if (resultList.get(i).getRawKind() == ActivityKind.ACTIVITY.getCode()) {
|
||||||
if (stepsPerActivity > 0.0f) {
|
if (stepsPerActivity > 0.0f) {
|
||||||
correctedSteps = (int) (resultList.get(i).getRawIntensity() / stepsPerActivity);
|
correctedSteps = (int) (resultList.get(i).getRawIntensity() / stepsPerActivity);
|
||||||
resultList.get(i).setSteps(correctedSteps);
|
resultList.get(i).setSteps(correctedSteps);
|
||||||
@ -525,7 +525,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
|
|||||||
}
|
}
|
||||||
newTotalSteps = 0;
|
newTotalSteps = 0;
|
||||||
for (int i = 0; i < numEntries - 1; i++) {
|
for (int i = 0; i < numEntries - 1; i++) {
|
||||||
if (resultList.get(i).getRawKind() == ActivityKind.TYPE_ACTIVITY) {
|
if (resultList.get(i).getRawKind() == ActivityKind.ACTIVITY.getCode()) {
|
||||||
correctedSteps = resultList.get(i).getSteps() + increaseStepsWith;
|
correctedSteps = resultList.get(i).getSteps() + increaseStepsWith;
|
||||||
newTotalSteps = newTotalSteps + correctedSteps;
|
newTotalSteps = newTotalSteps + correctedSteps;
|
||||||
if (newTotalSteps <= totalSteps) {
|
if (newTotalSteps <= totalSteps) {
|
||||||
|
@ -26,27 +26,21 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.MakibesHR3ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.MakibesHR3ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.MakibesHR3ActivitySampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.MakibesHR3ActivitySampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class MakibesHR3SampleProvider extends AbstractSampleProvider<MakibesHR3ActivitySample> {
|
public class MakibesHR3SampleProvider extends AbstractSampleProvider<MakibesHR3ActivitySample> {
|
||||||
|
|
||||||
private GBDevice mDevice;
|
|
||||||
private DaoSession mSession;
|
|
||||||
|
|
||||||
public MakibesHR3SampleProvider(GBDevice device, DaoSession session) {
|
public MakibesHR3SampleProvider(GBDevice device, DaoSession session) {
|
||||||
super(device, session);
|
super(device, session);
|
||||||
|
|
||||||
mSession = session;
|
|
||||||
mDevice = device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
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.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.TYPE_IGNORE;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.TYPE_IGNORE;
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.TYPE_NO_CHANGE;
|
import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst.TYPE_NO_CHANGE;
|
||||||
@ -37,15 +38,14 @@ public class MiBand2SampleProvider extends AbstractMiBandSampleProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<MiBandActivitySample> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) {
|
protected List<MiBandActivitySample> getGBActivitySamples(int timestamp_from, int timestamp_to) {
|
||||||
List<MiBandActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to, activityType);
|
List<MiBandActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to);
|
||||||
postprocess(samples);
|
postprocess(samples);
|
||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Temporary" runtime post processing of activity kinds.
|
* "Temporary" runtime post processing of activity kinds.
|
||||||
* @param samples
|
|
||||||
*/
|
*/
|
||||||
private void postprocess(List<MiBandActivitySample> samples) {
|
private void postprocess(List<MiBandActivitySample> samples) {
|
||||||
if (samples.isEmpty()) {
|
if (samples.isEmpty()) {
|
||||||
@ -83,19 +83,19 @@ public class MiBand2SampleProvider extends AbstractMiBandSampleProvider {
|
|||||||
qb.orderDesc(MiBandActivitySampleDao.Properties.Timestamp);
|
qb.orderDesc(MiBandActivitySampleDao.Properties.Timestamp);
|
||||||
qb.limit(1);
|
qb.limit(1);
|
||||||
List<MiBandActivitySample> result = qb.build().list();
|
List<MiBandActivitySample> result = qb.build().list();
|
||||||
if (result.size() > 0) {
|
if (!result.isEmpty()) {
|
||||||
return result.get(0).getRawKind() & 0xf;
|
return result.get(0).getRawKind() & 0xf;
|
||||||
}
|
}
|
||||||
return TYPE_UNSET;
|
return TYPE_UNSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return HuamiConst.toActivityKind(rawType);
|
return HuamiConst.toActivityKind(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return HuamiConst.toRawActivityType(activityKind);
|
return HuamiConst.toRawActivityType(activityKind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,36 +42,36 @@ public class MiBandSampleProvider extends AbstractMiBandSampleProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case TYPE_DEEP_SLEEP:
|
case TYPE_DEEP_SLEEP:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
case TYPE_LIGHT_SLEEP:
|
case TYPE_LIGHT_SLEEP:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
case TYPE_ACTIVITY:
|
case TYPE_ACTIVITY:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case TYPE_NONWEAR:
|
case TYPE_NONWEAR:
|
||||||
return ActivityKind.TYPE_NOT_WORN;
|
return ActivityKind.NOT_WORN;
|
||||||
case TYPE_CHARGING:
|
case TYPE_CHARGING:
|
||||||
return ActivityKind.TYPE_NOT_WORN; //I believe it's a safe assumption
|
return ActivityKind.NOT_WORN; //I believe it's a safe assumption
|
||||||
default:
|
default:
|
||||||
// case TYPE_UNKNOWN: // fall through
|
// case TYPE_UNKNOWN: // fall through
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_ACTIVITY:
|
case ACTIVITY:
|
||||||
return TYPE_ACTIVITY;
|
return TYPE_ACTIVITY;
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
return TYPE_DEEP_SLEEP;
|
return TYPE_DEEP_SLEEP;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
return TYPE_LIGHT_SLEEP;
|
return TYPE_LIGHT_SLEEP;
|
||||||
case ActivityKind.TYPE_NOT_WORN:
|
case NOT_WORN:
|
||||||
return TYPE_NONWEAR;
|
return TYPE_NONWEAR;
|
||||||
case ActivityKind.TYPE_UNKNOWN: // fall through
|
case UNKNOWN: // fall through
|
||||||
default:
|
default:
|
||||||
return TYPE_UNKNOWN;
|
return TYPE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.No1F1ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.No1F1ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.No1F1ActivitySampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.No1F1ActivitySampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class No1F1SampleProvider extends AbstractSampleProvider<No1F1ActivitySample> {
|
public class No1F1SampleProvider extends AbstractSampleProvider<No1F1ActivitySample> {
|
||||||
|
|
||||||
@ -39,13 +40,13 @@ public class No1F1SampleProvider extends AbstractSampleProvider<No1F1ActivitySam
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,7 +55,7 @@ public class PebbleHealthSampleProvider extends AbstractSampleProvider<PebbleHea
|
|||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public List<PebbleHealthActivitySample> getAllActivitySamples(int timestamp_from, int timestamp_to) {
|
public List<PebbleHealthActivitySample> getAllActivitySamples(int timestamp_from, int timestamp_to) {
|
||||||
List<PebbleHealthActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ALL);
|
List<PebbleHealthActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to);
|
||||||
|
|
||||||
Device dbDevice = DBHelper.findDevice(getDevice(), getSession());
|
Device dbDevice = DBHelper.findDevice(getDevice(), getSession());
|
||||||
if (dbDevice == null) {
|
if (dbDevice == null) {
|
||||||
@ -112,32 +112,31 @@ public class PebbleHealthSampleProvider extends AbstractSampleProvider<PebbleHea
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case TYPE_DEEP_NAP:
|
case TYPE_DEEP_NAP:
|
||||||
case TYPE_DEEP_SLEEP:
|
case TYPE_DEEP_SLEEP:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
case TYPE_LIGHT_NAP:
|
case TYPE_LIGHT_NAP:
|
||||||
case TYPE_LIGHT_SLEEP:
|
case TYPE_LIGHT_SLEEP:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
case TYPE_ACTIVITY:
|
case TYPE_ACTIVITY:
|
||||||
case TYPE_WALK:
|
case TYPE_WALK:
|
||||||
case TYPE_RUN:
|
case TYPE_RUN:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
default:
|
default:
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_ACTIVITY:
|
case DEEP_SLEEP:
|
||||||
return TYPE_ACTIVITY;
|
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
|
||||||
return TYPE_DEEP_SLEEP;
|
return TYPE_DEEP_SLEEP;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
return TYPE_LIGHT_SLEEP;
|
return TYPE_LIGHT_SLEEP;
|
||||||
|
case ACTIVITY:
|
||||||
default:
|
default:
|
||||||
return TYPE_ACTIVITY;
|
return TYPE_ACTIVITY;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class PebbleMisfitSampleProvider extends AbstractSampleProvider<PebbleMisfitSample> {
|
public class PebbleMisfitSampleProvider extends AbstractSampleProvider<PebbleMisfitSample> {
|
||||||
|
|
||||||
@ -35,13 +36,13 @@ public class PebbleMisfitSampleProvider extends AbstractSampleProvider<PebbleMis
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class PebbleMorpheuzSampleProvider extends AbstractSampleProvider<PebbleMorpheuzSample> {
|
public class PebbleMorpheuzSampleProvider extends AbstractSampleProvider<PebbleMorpheuzSample> {
|
||||||
|
|
||||||
@ -68,12 +69,12 @@ public class PebbleMorpheuzSampleProvider extends AbstractSampleProvider<PebbleM
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,8 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class PineTimeActivitySampleProvider extends AbstractSampleProvider<PineTimeActivitySample> {
|
public class PineTimeActivitySampleProvider extends AbstractSampleProvider<PineTimeActivitySample> {
|
||||||
private GBDevice mDevice;
|
|
||||||
private DaoSession mSession;
|
|
||||||
|
|
||||||
public PineTimeActivitySampleProvider(GBDevice device, DaoSession session) {
|
public PineTimeActivitySampleProvider(GBDevice device, DaoSession session) {
|
||||||
super(device, session);
|
super(device, session);
|
||||||
|
|
||||||
mSession = session;
|
|
||||||
mDevice = device;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -66,13 +60,13 @@ public class PineTimeActivitySampleProvider extends AbstractSampleProvider<PineT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -91,8 +85,8 @@ public class PineTimeActivitySampleProvider extends AbstractSampleProvider<PineT
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Optional<PineTimeActivitySample> getSampleForTimestamp(int timestamp) {
|
public Optional<PineTimeActivitySample> getSampleForTimestamp(int timestamp) {
|
||||||
List<PineTimeActivitySample> foundSamples = this.getGBActivitySamples(timestamp, timestamp, ActivityKind.TYPE_ALL);
|
List<PineTimeActivitySample> foundSamples = this.getGBActivitySamples(timestamp, timestamp);
|
||||||
if (foundSamples.size() == 0) {
|
if (foundSamples.isEmpty()) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
return Optional.of(foundSamples.get(0));
|
return Optional.of(foundSamples.get(0));
|
||||||
|
@ -19,8 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import de.greenrobot.dao.AbstractDao;
|
import de.greenrobot.dao.AbstractDao;
|
||||||
import de.greenrobot.dao.Property;
|
import de.greenrobot.dao.Property;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
||||||
@ -28,6 +26,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityEntry;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityEntry;
|
||||||
|
|
||||||
public class HybridHRActivitySampleProvider extends AbstractSampleProvider<HybridHRActivitySample> {
|
public class HybridHRActivitySampleProvider extends AbstractSampleProvider<HybridHRActivitySample> {
|
||||||
@ -59,13 +58,13 @@ public class HybridHRActivitySampleProvider extends AbstractSampleProvider<Hybri
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
if(rawType == -1) return 0;
|
if (rawType == -1) return ActivityKind.UNKNOWN;
|
||||||
return ActivityEntry.WEARING_STATE.fromValue((byte) rawType).getActivityKind();
|
return ActivityEntry.WEARING_STATE.fromValue((byte) rawType).getActivityKind();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,16 +77,4 @@ public class HybridHRActivitySampleProvider extends AbstractSampleProvider<Hybri
|
|||||||
public HybridHRActivitySample createActivitySample() {
|
public HybridHRActivitySample createActivitySample() {
|
||||||
return new HybridHRActivitySample();
|
return new HybridHRActivitySample();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public List<HybridHRActivitySample> getActivitySamples(int timestamp_from, int timestamp_to) {
|
|
||||||
return super.getActivitySamples(timestamp_from, timestamp_to);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public List<HybridHRActivitySample> getAllActivitySamples(int timestamp_from, int timestamp_to) {
|
|
||||||
return super.getAllActivitySamples(timestamp_from, timestamp_to);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -43,12 +43,12 @@ public final class QHybridConstants {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Map<Integer, Integer> WORKOUT_TYPES_TO_ACTIVITY_KIND = new HashMap<Integer, Integer>() {
|
public static Map<Integer, ActivityKind> WORKOUT_TYPES_TO_ACTIVITY_KIND = new HashMap<Integer, ActivityKind>() {
|
||||||
{
|
{
|
||||||
put(1, ActivityKind.TYPE_RUNNING);
|
put(1, ActivityKind.RUNNING);
|
||||||
put(2, ActivityKind.TYPE_CYCLING);
|
put(2, ActivityKind.CYCLING);
|
||||||
put(8, ActivityKind.TYPE_WALKING);
|
put(8, ActivityKind.WALKING);
|
||||||
put(12, ActivityKind.TYPE_HIKING);
|
put(12, ActivityKind.HIKING);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -58,53 +58,53 @@ public class SonyWena3ActivitySampleProvider extends AbstractSampleProvider<Wena
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
if(rawType < 0 || rawType >= BehaviorSample.Type.LUT.length) return ActivityKind.TYPE_UNKNOWN;
|
if(rawType < 0 || rawType >= BehaviorSample.Type.LUT.length) return ActivityKind.UNKNOWN;
|
||||||
|
|
||||||
BehaviorSample.Type internalType = BehaviorSample.Type.LUT[rawType];
|
BehaviorSample.Type internalType = BehaviorSample.Type.LUT[rawType];
|
||||||
switch(internalType) {
|
switch(internalType) {
|
||||||
case NOT_WEARING:
|
case NOT_WEARING:
|
||||||
return ActivityKind.TYPE_NOT_WORN;
|
return ActivityKind.NOT_WORN;
|
||||||
|
|
||||||
case WALK:
|
case WALK:
|
||||||
return ActivityKind.TYPE_WALKING;
|
return ActivityKind.WALKING;
|
||||||
case RUN:
|
case RUN:
|
||||||
return ActivityKind.TYPE_RUNNING;
|
return ActivityKind.RUNNING;
|
||||||
case EXERCISE:
|
case EXERCISE:
|
||||||
return ActivityKind.TYPE_EXERCISE;
|
return ActivityKind.EXERCISE;
|
||||||
|
|
||||||
case SLEEP_LIGHT:
|
case SLEEP_LIGHT:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
case SLEEP_REM:
|
case SLEEP_REM:
|
||||||
return ActivityKind.TYPE_REM_SLEEP;
|
return ActivityKind.REM_SLEEP;
|
||||||
case SLEEP_DEEP:
|
case SLEEP_DEEP:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
|
|
||||||
case STATIC:
|
case STATIC:
|
||||||
case SLEEP_AWAKE:
|
case SLEEP_AWAKE:
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
default:
|
default:
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
switch(activityKind) {
|
switch(activityKind) {
|
||||||
case ActivityKind.TYPE_NOT_MEASURED:
|
case NOT_MEASURED:
|
||||||
case ActivityKind.TYPE_NOT_WORN:
|
case NOT_WORN:
|
||||||
return BehaviorSample.Type.NOT_WEARING.ordinal();
|
return BehaviorSample.Type.NOT_WEARING.ordinal();
|
||||||
case ActivityKind.TYPE_WALKING:
|
case WALKING:
|
||||||
return BehaviorSample.Type.WALK.ordinal();
|
return BehaviorSample.Type.WALK.ordinal();
|
||||||
case ActivityKind.TYPE_RUNNING:
|
case RUNNING:
|
||||||
return BehaviorSample.Type.RUN.ordinal();
|
return BehaviorSample.Type.RUN.ordinal();
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
return BehaviorSample.Type.SLEEP_LIGHT.ordinal();
|
return BehaviorSample.Type.SLEEP_LIGHT.ordinal();
|
||||||
case ActivityKind.TYPE_REM_SLEEP:
|
case REM_SLEEP:
|
||||||
return BehaviorSample.Type.SLEEP_REM.ordinal();
|
return BehaviorSample.Type.SLEEP_REM.ordinal();
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
return BehaviorSample.Type.SLEEP_DEEP.ordinal();
|
return BehaviorSample.Type.SLEEP_DEEP.ordinal();
|
||||||
case ActivityKind.TYPE_EXERCISE:
|
case EXERCISE:
|
||||||
return BehaviorSample.Type.EXERCISE.ordinal();
|
return BehaviorSample.Type.EXERCISE.ordinal();
|
||||||
default:
|
default:
|
||||||
return BehaviorSample.Type.UNKNOWN.ordinal();
|
return BehaviorSample.Type.UNKNOWN.ordinal();
|
||||||
|
@ -58,30 +58,30 @@ public class SonySWR12SampleProvider extends AbstractSampleProvider<SonySWR12Sam
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case SonySWR12Constants.TYPE_ACTIVITY:
|
case SonySWR12Constants.TYPE_ACTIVITY:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case SonySWR12Constants.TYPE_LIGHT:
|
case SonySWR12Constants.TYPE_LIGHT:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
case SonySWR12Constants.TYPE_DEEP:
|
case SonySWR12Constants.TYPE_DEEP:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
case SonySWR12Constants.TYPE_NOT_WORN:
|
case SonySWR12Constants.TYPE_NOT_WORN:
|
||||||
return ActivityKind.TYPE_NOT_WORN;
|
return ActivityKind.NOT_WORN;
|
||||||
}
|
}
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_ACTIVITY:
|
case ACTIVITY:
|
||||||
return SonySWR12Constants.TYPE_ACTIVITY;
|
return SonySWR12Constants.TYPE_ACTIVITY;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
return SonySWR12Constants.TYPE_LIGHT;
|
return SonySWR12Constants.TYPE_LIGHT;
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
return SonySWR12Constants.TYPE_DEEP;
|
return SonySWR12Constants.TYPE_DEEP;
|
||||||
case ActivityKind.TYPE_NOT_WORN:
|
case NOT_WORN:
|
||||||
return SonySWR12Constants.TYPE_NOT_WORN;
|
return SonySWR12Constants.TYPE_NOT_WORN;
|
||||||
}
|
}
|
||||||
return SonySWR12Constants.TYPE_ACTIVITY;
|
return SonySWR12Constants.TYPE_ACTIVITY;
|
||||||
|
@ -69,13 +69,13 @@ public class TestSampleProvider extends AbstractSampleProvider<TestSampleProvide
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(final int rawType) {
|
public ActivityKind normalizeType(final int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(final int activityKind) {
|
public int toRawActivityKind(final ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -89,15 +89,15 @@ public class TestSampleProvider extends AbstractSampleProvider<TestSampleProvide
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<TestActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to, final int activityType) {
|
protected List<TestActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to) {
|
||||||
final List<TestActivitySample> samples = new ArrayList<>();
|
final List<TestActivitySample> samples = new ArrayList<>();
|
||||||
|
|
||||||
int[] sleepStages = new int[] {
|
int[] sleepStages = new int[] {
|
||||||
ActivityKind.TYPE_LIGHT_SLEEP,
|
ActivityKind.LIGHT_SLEEP.getCode(),
|
||||||
ActivityKind.TYPE_DEEP_SLEEP,
|
ActivityKind.DEEP_SLEEP.getCode(),
|
||||||
};
|
};
|
||||||
if (getDevice().getDeviceCoordinator().supportsRemSleep()) {
|
if (getDevice().getDeviceCoordinator().supportsRemSleep()) {
|
||||||
sleepStages = ArrayUtils.add(sleepStages, ActivityKind.TYPE_REM_SLEEP);
|
sleepStages = ArrayUtils.add(sleepStages, ActivityKind.REM_SLEEP.getCode());
|
||||||
}
|
}
|
||||||
int sleepStageCurrent = 0;
|
int sleepStageCurrent = 0;
|
||||||
int sleepStageDirection = 1;
|
int sleepStageDirection = 1;
|
||||||
@ -141,7 +141,7 @@ public class TestSampleProvider extends AbstractSampleProvider<TestSampleProvide
|
|||||||
if (TestDeviceRand.randBool(ts, 0.85f)) {
|
if (TestDeviceRand.randBool(ts, 0.85f)) {
|
||||||
samples.add(new TestActivitySample(
|
samples.add(new TestActivitySample(
|
||||||
(int) (ts / 1000),
|
(int) (ts / 1000),
|
||||||
isSleep ? sleepStages[sleepStageCurrent] : ActivityKind.TYPE_UNKNOWN,
|
isSleep ? sleepStages[sleepStageCurrent] : ActivityKind.UNKNOWN.getCode(),
|
||||||
isActive ? steps : 0,
|
isActive ? steps : 0,
|
||||||
intensity,
|
intensity,
|
||||||
hr
|
hr
|
||||||
@ -187,7 +187,7 @@ public class TestSampleProvider extends AbstractSampleProvider<TestSampleProvide
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SampleProvider getProvider() {
|
public SampleProvider<?> getProvider() {
|
||||||
return TestSampleProvider.this;
|
return TestSampleProvider.this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,8 +222,8 @@ public class TestSampleProvider extends AbstractSampleProvider<TestSampleProvide
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getKind() {
|
public ActivityKind getKind() {
|
||||||
return kind;
|
return ActivityKind.fromCode(kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,6 +26,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.TLW64ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.TLW64ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.TLW64ActivitySampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.TLW64ActivitySampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class TLW64SampleProvider extends AbstractSampleProvider<TLW64ActivitySample> {
|
public class TLW64SampleProvider extends AbstractSampleProvider<TLW64ActivitySample> {
|
||||||
|
|
||||||
@ -63,13 +64,13 @@ public class TLW64SampleProvider extends AbstractSampleProvider<TLW64ActivitySam
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,9 +39,9 @@ public class VivomoveHrSampleProvider extends AbstractSampleProvider<VivomoveHrA
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
if (rawType == RAW_NOT_WORN) {
|
if (rawType == RAW_NOT_WORN) {
|
||||||
return ActivityKind.TYPE_NOT_WORN;
|
return ActivityKind.NOT_WORN;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (rawType & RAW_TYPE_KIND_MASK) {
|
switch (rawType & RAW_TYPE_KIND_MASK) {
|
||||||
@ -51,105 +51,95 @@ public class VivomoveHrSampleProvider extends AbstractSampleProvider<VivomoveHrA
|
|||||||
return normalizeSleepType(rawType & ~RAW_TYPE_KIND_MASK);
|
return normalizeSleepType(rawType & ~RAW_TYPE_KIND_MASK);
|
||||||
default:
|
default:
|
||||||
// ???
|
// ???
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int normalizeActivityType(int rawType) {
|
private static ActivityKind normalizeActivityType(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case 0:
|
case 0:
|
||||||
// generic
|
// generic
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case 1:
|
case 1:
|
||||||
// running
|
// running
|
||||||
return ActivityKind.TYPE_RUNNING;
|
return ActivityKind.RUNNING;
|
||||||
case 2:
|
case 2:
|
||||||
// cycling
|
// cycling
|
||||||
return ActivityKind.TYPE_CYCLING;
|
return ActivityKind.CYCLING;
|
||||||
case 3:
|
case 3:
|
||||||
// transition
|
// transition
|
||||||
return ActivityKind.TYPE_ACTIVITY | ActivityKind.TYPE_RUNNING | ActivityKind.TYPE_WALKING | ActivityKind.TYPE_EXERCISE | ActivityKind.TYPE_SWIMMING;
|
return ActivityKind.VIVOMOVE_HR_TRANSITION;
|
||||||
case 4:
|
case 4:
|
||||||
// fitness_equipment
|
// fitness_equipment
|
||||||
return ActivityKind.TYPE_EXERCISE;
|
return ActivityKind.EXERCISE;
|
||||||
case 5:
|
case 5:
|
||||||
// swimming
|
// swimming
|
||||||
return ActivityKind.TYPE_SWIMMING;
|
return ActivityKind.SWIMMING;
|
||||||
case 6:
|
case 6:
|
||||||
// walking
|
// walking
|
||||||
return ActivityKind.TYPE_WALKING;
|
return ActivityKind.WALKING;
|
||||||
case 8:
|
case 8:
|
||||||
// sedentary
|
// sedentary
|
||||||
// TODO?
|
// TODO?
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int normalizeSleepType(int rawType) {
|
private static ActivityKind normalizeSleepType(int rawType) {
|
||||||
switch (rawType) {
|
switch (rawType) {
|
||||||
case 0:
|
case 0:
|
||||||
// deep_sleep
|
// deep_sleep
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
case 1:
|
case 1:
|
||||||
// light_sleep
|
// light_sleep
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
case 2:
|
case 2:
|
||||||
// awake
|
// awake
|
||||||
case 3:
|
case 3:
|
||||||
// more_awake
|
// more_awake
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
default:
|
default:
|
||||||
// ?
|
// ?
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_NOT_WORN:
|
case NOT_WORN:
|
||||||
return RAW_NOT_WORN;
|
return RAW_NOT_WORN;
|
||||||
|
|
||||||
case ActivityKind.TYPE_ACTIVITY:
|
case ACTIVITY:
|
||||||
// generic
|
// generic
|
||||||
//noinspection PointlessBitwiseExpression
|
//noinspection PointlessBitwiseExpression
|
||||||
return RAW_TYPE_KIND_ACTIVITY | 0;
|
return RAW_TYPE_KIND_ACTIVITY | 0;
|
||||||
case ActivityKind.TYPE_RUNNING:
|
case RUNNING:
|
||||||
// running
|
// running
|
||||||
return RAW_TYPE_KIND_ACTIVITY | 1;
|
return RAW_TYPE_KIND_ACTIVITY | 1;
|
||||||
case ActivityKind.TYPE_CYCLING:
|
case CYCLING:
|
||||||
// cycling
|
// cycling
|
||||||
return RAW_TYPE_KIND_ACTIVITY | 2;
|
return RAW_TYPE_KIND_ACTIVITY | 2;
|
||||||
case ActivityKind.TYPE_ACTIVITY | ActivityKind.TYPE_RUNNING | ActivityKind.TYPE_WALKING | ActivityKind.TYPE_EXERCISE | ActivityKind.TYPE_SWIMMING:
|
case VIVOMOVE_HR_TRANSITION:
|
||||||
return RAW_TYPE_KIND_ACTIVITY | 3;
|
return RAW_TYPE_KIND_ACTIVITY | 3;
|
||||||
case ActivityKind.TYPE_EXERCISE:
|
case EXERCISE:
|
||||||
// fitness_equipment
|
// fitness_equipment
|
||||||
return RAW_TYPE_KIND_ACTIVITY | 4;
|
return RAW_TYPE_KIND_ACTIVITY | 4;
|
||||||
case ActivityKind.TYPE_SWIMMING:
|
case SWIMMING:
|
||||||
// swimming
|
// swimming
|
||||||
return RAW_TYPE_KIND_ACTIVITY | 5;
|
return RAW_TYPE_KIND_ACTIVITY | 5;
|
||||||
case ActivityKind.TYPE_WALKING:
|
case WALKING:
|
||||||
// walking
|
// walking
|
||||||
return RAW_TYPE_KIND_ACTIVITY | 6;
|
return RAW_TYPE_KIND_ACTIVITY | 6;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
return RAW_TYPE_KIND_SLEEP | 1;
|
return RAW_TYPE_KIND_SLEEP | 1;
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
//noinspection PointlessBitwiseExpression
|
//noinspection PointlessBitwiseExpression
|
||||||
return RAW_TYPE_KIND_SLEEP | 0;
|
return RAW_TYPE_KIND_SLEEP | 0;
|
||||||
default:
|
default:
|
||||||
if ((activityKind & ActivityKind.TYPE_SWIMMING) != 0) return RAW_TYPE_KIND_ACTIVITY | 5;
|
|
||||||
if ((activityKind & ActivityKind.TYPE_CYCLING) != 0) return RAW_TYPE_KIND_ACTIVITY | 2;
|
|
||||||
if ((activityKind & ActivityKind.TYPE_RUNNING) != 0) return RAW_TYPE_KIND_ACTIVITY | 1;
|
|
||||||
if ((activityKind & ActivityKind.TYPE_EXERCISE) != 0) return RAW_TYPE_KIND_ACTIVITY | 4;
|
|
||||||
if ((activityKind & ActivityKind.TYPE_WALKING) != 0) return RAW_TYPE_KIND_ACTIVITY | 6;
|
|
||||||
if ((activityKind & ActivityKind.TYPE_SLEEP) != 0) return RAW_TYPE_KIND_SLEEP | 1;
|
|
||||||
if ((activityKind & ActivityKind.TYPE_ACTIVITY) != 0) {
|
|
||||||
//noinspection PointlessBitwiseExpression
|
|
||||||
return RAW_TYPE_KIND_ACTIVITY | 0;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,30 +19,16 @@ package nodomain.freeyourgadget.gadgetbridge.devices.withingssteelhr;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import de.greenrobot.dao.AbstractDao;
|
import de.greenrobot.dao.AbstractDao;
|
||||||
import de.greenrobot.dao.Property;
|
import de.greenrobot.dao.Property;
|
||||||
import de.greenrobot.dao.query.Query;
|
|
||||||
import de.greenrobot.dao.query.QueryBuilder;
|
|
||||||
import de.greenrobot.dao.query.WhereCondition;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractSampleProvider;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.WithingsSteelHRActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.WithingsSteelHRActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.WithingsSteelHRActivitySampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.WithingsSteelHRActivitySampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.withingssteelhr.communication.conversation.ActivitySampleHandler;
|
|
||||||
|
|
||||||
public class WithingsSteelHRSampleProvider extends AbstractSampleProvider<WithingsSteelHRActivitySample> {
|
public class WithingsSteelHRSampleProvider extends AbstractSampleProvider<WithingsSteelHRActivitySample> {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(WithingsSteelHRSampleProvider.class);
|
|
||||||
|
|
||||||
public WithingsSteelHRSampleProvider(GBDevice device, DaoSession session) {
|
public WithingsSteelHRSampleProvider(GBDevice device, DaoSession session) {
|
||||||
super(device, session);
|
super(device, session);
|
||||||
}
|
}
|
||||||
@ -70,28 +56,29 @@ public class WithingsSteelHRSampleProvider extends AbstractSampleProvider<Within
|
|||||||
return WithingsSteelHRActivitySampleDao.Properties.DeviceId;
|
return WithingsSteelHRActivitySampleDao.Properties.DeviceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
@Override
|
||||||
public List<WithingsSteelHRActivitySample> getActivitySamples(int timestamp_from, int timestamp_to) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return super.getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ALL);
|
switch (rawType) {
|
||||||
|
case 1:
|
||||||
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
|
case 2:
|
||||||
|
return ActivityKind.DEEP_SLEEP;
|
||||||
|
default:
|
||||||
|
return ActivityKind.fromCode(rawType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return rawType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int toRawActivityKind(int activityKind) {
|
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_UNKNOWN:
|
case UNKNOWN:
|
||||||
return 0;
|
return 0;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
return 1;
|
return 1;
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
return 2;
|
return 2;
|
||||||
default:
|
default:
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,15 +67,15 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(final int rawType) {
|
public ActivityKind normalizeType(final int rawType) {
|
||||||
// TODO
|
// TODO
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(final int activityKind) {
|
public int toRawActivityKind(final ActivityKind activityKind) {
|
||||||
// TODO
|
// TODO
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -89,8 +89,8 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<XiaomiActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to, final int activityType) {
|
protected List<XiaomiActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to) {
|
||||||
final List<XiaomiActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to, activityType);
|
final List<XiaomiActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to);
|
||||||
|
|
||||||
overlaySleep(samples, timestamp_from, timestamp_to);
|
overlaySleep(samples, timestamp_from, timestamp_to);
|
||||||
|
|
||||||
@ -100,16 +100,16 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
|
|||||||
/**
|
/**
|
||||||
* See {@link nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.activity.impl.SleepDetailsParser}
|
* See {@link nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.activity.impl.SleepDetailsParser}
|
||||||
*/
|
*/
|
||||||
private static int getActivityKindForSample(final XiaomiSleepStageSample sample) {
|
private static ActivityKind getActivityKindForSample(final XiaomiSleepStageSample sample) {
|
||||||
switch (sample.getStage()) {
|
switch (sample.getStage()) {
|
||||||
case 2:
|
case 2:
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
case 3:
|
case 3:
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
case 4:
|
case 4:
|
||||||
return ActivityKind.TYPE_REM_SLEEP;
|
return ActivityKind.REM_SLEEP;
|
||||||
default: // default to awake
|
default: // default to awake
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
|
|||||||
* found.
|
* found.
|
||||||
*/
|
*/
|
||||||
public void overlaySleep(final List<XiaomiActivitySample> samples, final int timestamp_from, final int timestamp_to) {
|
public void overlaySleep(final List<XiaomiActivitySample> samples, final int timestamp_from, final int timestamp_to) {
|
||||||
final RangeMap<Long, Integer> stagesMap = new RangeMap<>();
|
final RangeMap<Long, ActivityKind> stagesMap = new RangeMap<>();
|
||||||
|
|
||||||
final XiaomiSleepStageSampleProvider sleepStagesSampleProvider = new XiaomiSleepStageSampleProvider(getDevice(), getSession());
|
final XiaomiSleepStageSampleProvider sleepStagesSampleProvider = new XiaomiSleepStageSampleProvider(getDevice(), getSession());
|
||||||
|
|
||||||
@ -157,8 +157,8 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
|
|||||||
final XiaomiSleepTimeSample lastSleepTimesBeforeRange = sleepTimeSampleProvider.getLastSampleBefore(timestamp_from * 1000L);
|
final XiaomiSleepTimeSample lastSleepTimesBeforeRange = sleepTimeSampleProvider.getLastSampleBefore(timestamp_from * 1000L);
|
||||||
|
|
||||||
if (lastSleepTimesBeforeRange != null) {
|
if (lastSleepTimesBeforeRange != null) {
|
||||||
stagesMap.put(lastSleepTimesBeforeRange.getWakeupTime(), ActivityKind.TYPE_UNKNOWN);
|
stagesMap.put(lastSleepTimesBeforeRange.getWakeupTime(), ActivityKind.UNKNOWN);
|
||||||
stagesMap.put(lastSleepTimesBeforeRange.getTimestamp(), ActivityKind.TYPE_LIGHT_SLEEP);
|
stagesMap.put(lastSleepTimesBeforeRange.getTimestamp(), ActivityKind.LIGHT_SLEEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all wake up and sleep samples in the current time range
|
// Find all wake up and sleep samples in the current time range
|
||||||
@ -172,11 +172,11 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
|
|||||||
for (final XiaomiSleepTimeSample stageSample : sleepTimesInRange) {
|
for (final XiaomiSleepTimeSample stageSample : sleepTimesInRange) {
|
||||||
if (sleepStagesInRange.isEmpty()) {
|
if (sleepStagesInRange.isEmpty()) {
|
||||||
// Only overlay them as light sleep if we don't have actual sleep stages
|
// Only overlay them as light sleep if we don't have actual sleep stages
|
||||||
stagesMap.put(stageSample.getTimestamp(), ActivityKind.TYPE_LIGHT_SLEEP);
|
stagesMap.put(stageSample.getTimestamp(), ActivityKind.LIGHT_SLEEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to set the wakeup times, because some bands don't report them in the stage samples (see #3502)
|
// We need to set the wakeup times, because some bands don't report them in the stage samples (see #3502)
|
||||||
stagesMap.put(stageSample.getWakeupTime(), ActivityKind.TYPE_UNKNOWN);
|
stagesMap.put(stageSample.getWakeupTime(), ActivityKind.UNKNOWN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,18 +185,18 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
|
|||||||
|
|
||||||
for (final XiaomiActivitySample sample : samples) {
|
for (final XiaomiActivitySample sample : samples) {
|
||||||
final long ts = sample.getTimestamp() * 1000L;
|
final long ts = sample.getTimestamp() * 1000L;
|
||||||
final Integer sleepType = stagesMap.get(ts);
|
final ActivityKind sleepType = stagesMap.get(ts);
|
||||||
if (sleepType != null && !sleepType.equals(ActivityKind.TYPE_UNKNOWN)) {
|
if (sleepType != null && !sleepType.equals(ActivityKind.UNKNOWN)) {
|
||||||
sample.setRawKind(sleepType);
|
sample.setRawKind(sleepType.getCode());
|
||||||
|
|
||||||
switch (sleepType) {
|
switch (sleepType) {
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
case DEEP_SLEEP:
|
||||||
sample.setRawIntensity(20);
|
sample.setRawIntensity(20);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
case LIGHT_SLEEP:
|
||||||
sample.setRawIntensity(30);
|
sample.setRawIntensity(30);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_REM_SLEEP:
|
case REM_SLEEP:
|
||||||
sample.setRawIntensity(40);
|
sample.setRawIntensity(40);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -36,12 +36,12 @@ public class XWatchSampleProvider extends AbstractSampleProvider<XWatchActivityS
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return TYPE_ACTIVITY;
|
return TYPE_ACTIVITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.entities.ZeTimeActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.ZeTimeActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.ZeTimeActivitySampleDao;
|
import nodomain.freeyourgadget.gadgetbridge.entities.ZeTimeActivitySampleDao;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class ZeTimeSampleProvider extends AbstractSampleProvider<ZeTimeActivitySample> {
|
public class ZeTimeSampleProvider extends AbstractSampleProvider<ZeTimeActivitySample> {
|
||||||
|
|
||||||
@ -40,13 +41,13 @@ public class ZeTimeSampleProvider extends AbstractSampleProvider<ZeTimeActivityS
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int normalizeType(int rawType) {
|
public ActivityKind normalizeType(int rawType) {
|
||||||
return rawType;
|
return ActivityKind.fromCode(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int toRawActivityKind(int activityKind) {
|
public int toRawActivityKind(ActivityKind activityKind) {
|
||||||
return activityKind;
|
return activityKind.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,14 +17,15 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.entities;
|
package nodomain.freeyourgadget.gadgetbridge.entities;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||||
|
|
||||||
public abstract class AbstractActivitySample implements ActivitySample {
|
public abstract class AbstractActivitySample implements ActivitySample {
|
||||||
private SampleProvider mProvider;
|
private SampleProvider<?> mProvider;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SampleProvider getProvider() {
|
public SampleProvider<?> getProvider() {
|
||||||
return mProvider;
|
return mProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +34,7 @@ public abstract class AbstractActivitySample implements ActivitySample {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getKind() {
|
public ActivityKind getKind() {
|
||||||
return getProvider().normalizeType(getRawKind());
|
return getProvider().normalizeType(getRawKind());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ public abstract class AbstractActivitySample implements ActivitySample {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
int kind = getProvider() != null ? getKind() : ActivitySample.NOT_MEASURED;
|
ActivityKind kind = getProvider() != null ? getKind() : ActivityKind.NOT_MEASURED;
|
||||||
float intensity = getProvider() != null ? getIntensity() : ActivitySample.NOT_MEASURED;
|
float intensity = getProvider() != null ? getIntensity() : ActivitySample.NOT_MEASURED;
|
||||||
return getClass().getSimpleName() + "{" +
|
return getClass().getSimpleName() + "{" +
|
||||||
"timestamp=" + DateTimeUtils.formatDateTime(DateTimeUtils.parseTimeStamp(getTimestamp())) +
|
"timestamp=" + DateTimeUtils.formatDateTime(DateTimeUtils.parseTimeStamp(getTimestamp())) +
|
||||||
|
@ -21,7 +21,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|||||||
public abstract class AbstractPebbleHealthActivitySample extends AbstractActivitySample {
|
public abstract class AbstractPebbleHealthActivitySample extends AbstractActivitySample {
|
||||||
abstract public byte[] getRawPebbleHealthData();
|
abstract public byte[] getRawPebbleHealthData();
|
||||||
|
|
||||||
private transient int rawActivityKind = ActivityKind.TYPE_UNKNOWN;
|
private transient int rawActivityKind = ActivityKind.UNKNOWN.getCode();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRawKind() {
|
public int getRawKind() {
|
||||||
|
@ -23,7 +23,7 @@ public abstract class AbstractPebbleMisfitActivitySample extends AbstractActivit
|
|||||||
|
|
||||||
private transient int intensity = 0;
|
private transient int intensity = 0;
|
||||||
private transient int steps = 0;
|
private transient int steps = 0;
|
||||||
private transient int activityKind = ActivityKind.TYPE_UNKNOWN;
|
private transient ActivityKind activityKind = ActivityKind.UNKNOWN;
|
||||||
|
|
||||||
private void calculate() {
|
private void calculate() {
|
||||||
int sample = getRawPebbleMisfitSample();
|
int sample = getRawPebbleMisfitSample();
|
||||||
@ -33,10 +33,10 @@ public abstract class AbstractPebbleMisfitActivitySample extends AbstractActivit
|
|||||||
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.DEEP_SLEEP;
|
||||||
} else {
|
} else {
|
||||||
// FIXME: this leads to too much false positives, ignore for now
|
// FIXME: this leads to too much false positives, ignore for now
|
||||||
//activityKind = ActivityKind.TYPE_LIGHT_SLEEP;
|
//activityKind = ActivityKind.LIGHT_SLEEP;
|
||||||
//intensity *= 2; // better visual distinction
|
//intensity *= 2; // better visual distinction
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -46,7 +46,7 @@ public abstract class AbstractPebbleMisfitActivitySample extends AbstractActivit
|
|||||||
steps = (sample & 0x000e);
|
steps = (sample & 0x000e);
|
||||||
}
|
}
|
||||||
intensity = steps;
|
intensity = steps;
|
||||||
activityKind = ActivityKind.TYPE_ACTIVITY;
|
activityKind = ActivityKind.ACTIVITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ public abstract class AbstractPebbleMisfitActivitySample extends AbstractActivit
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getKind() {
|
public ActivityKind getKind() {
|
||||||
calculate();
|
calculate();
|
||||||
return activityKind;
|
return activityKind;
|
||||||
}
|
}
|
||||||
|
@ -21,13 +21,13 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|||||||
public abstract class AbstractPebbleMorpheuzActivitySample extends AbstractActivitySample {
|
public abstract class AbstractPebbleMorpheuzActivitySample extends AbstractActivitySample {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getKind() {
|
public ActivityKind getKind() {
|
||||||
int rawIntensity = getRawIntensity();
|
int rawIntensity = getRawIntensity();
|
||||||
if (rawIntensity <= 120) {
|
if (rawIntensity <= 120) {
|
||||||
return ActivityKind.TYPE_DEEP_SLEEP;
|
return ActivityKind.DEEP_SLEEP;
|
||||||
} else if (rawIntensity <= 1000) {
|
} else if (rawIntensity <= 1000) {
|
||||||
return ActivityKind.TYPE_LIGHT_SLEEP;
|
return ActivityKind.LIGHT_SLEEP;
|
||||||
}
|
}
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,22 +112,22 @@ public class OpenTracksController extends Activity {
|
|||||||
sendIntent(context, "de.dennisguse.opentracks.publicapi.StartRecording", null, null);
|
sendIntent(context, "de.dennisguse.opentracks.publicapi.StartRecording", null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void startRecording(Context context, int activityKind) {
|
public static void startRecording(Context context, ActivityKind activityKind) {
|
||||||
final String category = ActivityKind.asString(activityKind, context);
|
final String category = activityKind.getLabel(context);
|
||||||
final String icon;
|
final String icon;
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_CYCLING:
|
case CYCLING:
|
||||||
icon = "BIKE";
|
icon = "BIKE";
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_HIKING:
|
case HIKING:
|
||||||
case ActivityKind.TYPE_WALKING:
|
case WALKING:
|
||||||
icon = "WALK";
|
icon = "WALK";
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_RUNNING:
|
case RUNNING:
|
||||||
icon = "RUN";
|
icon = "RUN";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG.warn("Unmapped activity kind icon for {}", String.format("0x%X", activityKind));
|
LOG.warn("Unmapped activity kind icon for {}", activityKind);
|
||||||
icon = null;
|
icon = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,21 +16,17 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.model;
|
package nodomain.freeyourgadget.gadgetbridge.model;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
|
||||||
|
|
||||||
public class ActivityAmount {
|
public class ActivityAmount {
|
||||||
private final int activityKind;
|
private final ActivityKind activityKind;
|
||||||
private short percent;
|
private short percent;
|
||||||
private long totalSeconds;
|
private long totalSeconds;
|
||||||
private long totalSteps;
|
private long totalSteps;
|
||||||
private Date startDate = null;
|
private Date startDate = null;
|
||||||
private Date endDate = null;
|
private Date endDate = null;
|
||||||
|
|
||||||
public ActivityAmount(int activityKind) {
|
public ActivityAmount(ActivityKind activityKind) {
|
||||||
this.activityKind = activityKind;
|
this.activityKind = activityKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +46,7 @@ public class ActivityAmount {
|
|||||||
return totalSteps;
|
return totalSteps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getActivityKind() {
|
public ActivityKind getActivityKind() {
|
||||||
return activityKind;
|
return activityKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,16 +58,6 @@ public class ActivityAmount {
|
|||||||
this.percent = percent;
|
this.percent = percent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName(Context context) {
|
|
||||||
switch (activityKind) {
|
|
||||||
case ActivityKind.TYPE_DEEP_SLEEP:
|
|
||||||
return context.getString(R.string.abstract_chart_fragment_kind_deep_sleep);
|
|
||||||
case ActivityKind.TYPE_LIGHT_SLEEP:
|
|
||||||
return context.getString(R.string.abstract_chart_fragment_kind_light_sleep);
|
|
||||||
}
|
|
||||||
return context.getString(R.string.abstract_chart_fragment_kind_activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getStartDate() {
|
public Date getStartDate() {
|
||||||
return startDate;
|
return startDate;
|
||||||
}
|
}
|
||||||
|
@ -20,238 +20,97 @@ package nodomain.freeyourgadget.gadgetbridge.model;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
|
import androidx.annotation.StringRes;
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
|
||||||
|
|
||||||
public class ActivityKind {
|
public enum ActivityKind {
|
||||||
public static final int TYPE_NOT_MEASURED = -1;
|
NOT_MEASURED(-1, R.string.activity_type_not_measured, R.drawable.ic_activity_not_measured),
|
||||||
public static final int TYPE_UNKNOWN = 0x00000000;
|
UNKNOWN(0x00000000, R.string.activity_type_unknown),
|
||||||
public static final int TYPE_ACTIVITY = 0x00000001;
|
ACTIVITY(0x00000001, R.string.activity_type_activity),
|
||||||
public static final int TYPE_LIGHT_SLEEP = 0x00000002;
|
LIGHT_SLEEP(0x00000002, R.string.activity_type_light_sleep, R.drawable.ic_activity_sleep),
|
||||||
public static final int TYPE_DEEP_SLEEP = 0x00000004;
|
DEEP_SLEEP(0x00000004, R.string.activity_type_deep_sleep, R.drawable.ic_activity_sleep),
|
||||||
public static final int TYPE_NOT_WORN = 0x00000008;
|
NOT_WORN(0x00000008, R.string.activity_type_not_worn),
|
||||||
public static final int TYPE_RUNNING = 0x00000010;
|
RUNNING(0x00000010, R.string.activity_type_running, R.drawable.ic_activity_running),
|
||||||
public static final int TYPE_WALKING = 0x00000020;
|
WALKING(0x00000020, R.string.activity_type_walking, R.drawable.ic_activity_walking),
|
||||||
public static final int TYPE_SWIMMING = 0x00000040;
|
SWIMMING(0x00000040, R.string.activity_type_swimming, R.drawable.ic_activity_swimming),
|
||||||
public static final int TYPE_CYCLING = 0x00000080;
|
CYCLING(0x00000080, R.string.activity_type_biking, R.drawable.ic_activity_biking),
|
||||||
public static final int TYPE_TREADMILL = 0x00000100;
|
TREADMILL(0x00000100, R.string.activity_type_treadmill, R.drawable.ic_activity_threadmill),
|
||||||
public static final int TYPE_EXERCISE = 0x00000200;
|
EXERCISE(0x00000200, R.string.activity_type_exercise, R.drawable.ic_activity_exercise),
|
||||||
public static final int TYPE_SWIMMING_OPENWATER = 0x00000400;
|
SWIMMING_OPENWATER(0x00000400, R.string.activity_type_swimming_openwater, R.drawable.ic_activity_swimming),
|
||||||
public static final int TYPE_INDOOR_CYCLING = 0x00000800;
|
INDOOR_CYCLING(0x00000800, R.string.activity_type_indoor_cycling, R.drawable.ic_activity_bike_trainer),
|
||||||
public static final int TYPE_ELLIPTICAL_TRAINER = 0x00001000;
|
ELLIPTICAL_TRAINER(0x00001000, R.string.activity_type_elliptical_trainer, R.drawable.ic_activity_eliptical),
|
||||||
public static final int TYPE_JUMP_ROPING = 0x00002000;
|
JUMP_ROPING(0x00002000, R.string.activity_type_jump_roping, R.drawable.ic_activity_rope_jump),
|
||||||
public static final int TYPE_YOGA = 0x00004000;
|
YOGA(0x00004000, R.string.activity_type_yoga, R.drawable.ic_activity_yoga),
|
||||||
public static final int TYPE_SOCCER = 0x00008000;
|
SOCCER(0x00008000, R.string.activity_type_soccer, R.drawable.ic_activity_soccer),
|
||||||
public static final int TYPE_ROWING_MACHINE = 0x00010000;
|
ROWING_MACHINE(0x00010000, R.string.activity_type_rowing_machine, R.drawable.ic_activity_rowing),
|
||||||
public static final int TYPE_CRICKET = 0x00020000;
|
CRICKET(0x00020000, R.string.activity_type_cricket, R.drawable.ic_activity_cricket),
|
||||||
public static final int TYPE_BASKETBALL = 0x00040000;
|
BASKETBALL(0x00040000, R.string.activity_type_basketball, R.drawable.ic_activity_basketball),
|
||||||
public static final int TYPE_PINGPONG = 0x00080000;
|
PINGPONG(0x00080000, R.string.activity_type_pingpong, R.drawable.ic_activity_pingpong),
|
||||||
public static final int TYPE_BADMINTON = 0x00100000;
|
BADMINTON(0x00100000, R.string.activity_type_badminton, R.drawable.ic_activity_badmington),
|
||||||
public static final int TYPE_STRENGTH_TRAINING = 0x00200000;
|
STRENGTH_TRAINING(0x00200000, R.string.activity_type_strength_training),
|
||||||
public static final int TYPE_HIKING = 0x00400000;
|
HIKING(0x00400000, R.string.activity_type_hiking, R.drawable.ic_activity_hiking),
|
||||||
public static final int TYPE_CLIMBING = 0x00800000;
|
CLIMBING(0x00800000, R.string.activity_type_climbing, R.drawable.ic_activity_climbing),
|
||||||
public static final int TYPE_REM_SLEEP = 0x01000000;
|
REM_SLEEP(0x01000000, R.string.abstract_chart_fragment_kind_rem_sleep, R.drawable.ic_activity_sleep),
|
||||||
public static final int TYPE_AWAKE_SLEEP = 0x02000000;
|
SLEEP_ANY(0x00000002 | 0x00000004 | 0x01000000 | 0x02000000, R.string.menuitem_sleep, R.drawable.ic_activity_sleep),
|
||||||
|
AWAKE_SLEEP(0x02000000, R.string.abstract_chart_fragment_kind_awake_sleep, R.drawable.ic_activity_sleep),
|
||||||
|
|
||||||
private static final int TYPES_COUNT = 26;
|
// FIXME: Deprecate these - they're just kept around while we do not support reading from the old db
|
||||||
|
VIVOMOVE_HR_TRANSITION(0x00000001 | 0x00000010 | 0x00000020 | 0x00000200 | 0x00000040, R.string.transition),
|
||||||
|
;
|
||||||
|
|
||||||
public static final int TYPE_SLEEP = TYPE_LIGHT_SLEEP | TYPE_DEEP_SLEEP | TYPE_REM_SLEEP | TYPE_AWAKE_SLEEP;
|
private final int code;
|
||||||
public static final int TYPE_ALL = TYPE_ACTIVITY | TYPE_SLEEP | TYPE_NOT_WORN;
|
private final int label;
|
||||||
|
private final int icon;
|
||||||
|
|
||||||
public static int[] mapToDBActivityTypes(int types, SampleProvider provider) {
|
ActivityKind(final int code) {
|
||||||
int[] result = new int[TYPES_COUNT];
|
this(code, R.string.activity_type_unknown);
|
||||||
int i = 0;
|
|
||||||
if ((types & ActivityKind.TYPE_ACTIVITY) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_ACTIVITY);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_DEEP_SLEEP) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_DEEP_SLEEP);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_LIGHT_SLEEP) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_LIGHT_SLEEP);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_NOT_WORN) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_NOT_WORN);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_RUNNING) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_RUNNING);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_WALKING) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_WALKING);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_HIKING) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_HIKING);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_CLIMBING) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_CLIMBING);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_SWIMMING) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_SWIMMING);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_CYCLING) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_CYCLING);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_TREADMILL) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_TREADMILL);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_EXERCISE) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_EXERCISE);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_SWIMMING_OPENWATER) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_SWIMMING_OPENWATER);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_INDOOR_CYCLING) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_INDOOR_CYCLING);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_ELLIPTICAL_TRAINER) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_ELLIPTICAL_TRAINER);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_JUMP_ROPING) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_JUMP_ROPING);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_YOGA) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_YOGA);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_ROWING_MACHINE) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_ROWING_MACHINE);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_CRICKET) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_CRICKET);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_BASKETBALL) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_BASKETBALL);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_PINGPONG) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_PINGPONG);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_BADMINTON) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_BADMINTON);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_STRENGTH_TRAINING) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_STRENGTH_TRAINING);
|
|
||||||
}
|
|
||||||
if ((types & ActivityKind.TYPE_REM_SLEEP) != 0) {
|
|
||||||
result[i++] = provider.toRawActivityKind(TYPE_REM_SLEEP);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Arrays.copyOf(result, i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String asString(int kind, Context context) {
|
ActivityKind(final int code, @StringRes final int label) {
|
||||||
switch (kind) {
|
this(code, label, R.drawable.ic_activity_unknown_small);
|
||||||
case TYPE_NOT_MEASURED:
|
}
|
||||||
return context.getString(R.string.activity_type_not_measured);
|
|
||||||
case TYPE_ACTIVITY:
|
ActivityKind(final int code, @StringRes final int label, @DrawableRes final int icon) {
|
||||||
return context.getString(R.string.activity_type_activity);
|
this.code = code;
|
||||||
case TYPE_LIGHT_SLEEP:
|
this.label = label;
|
||||||
return context.getString(R.string.activity_type_light_sleep);
|
this.icon = icon;
|
||||||
case TYPE_DEEP_SLEEP:
|
}
|
||||||
return context.getString(R.string.activity_type_deep_sleep);
|
|
||||||
case TYPE_NOT_WORN:
|
public int getCode() {
|
||||||
return context.getString(R.string.activity_type_not_worn);
|
return code;
|
||||||
case TYPE_RUNNING:
|
}
|
||||||
return context.getString(R.string.activity_type_running);
|
|
||||||
case TYPE_WALKING:
|
@StringRes
|
||||||
return context.getString(R.string.activity_type_walking);
|
public int getLabel() {
|
||||||
case TYPE_HIKING:
|
return label;
|
||||||
return context.getString(R.string.activity_type_hiking);
|
}
|
||||||
case TYPE_CLIMBING:
|
|
||||||
return context.getString(R.string.activity_type_climbing);
|
public String getLabel(final Context context) {
|
||||||
case TYPE_SWIMMING:
|
return context.getString(label);
|
||||||
return context.getString(R.string.activity_type_swimming);
|
|
||||||
case TYPE_CYCLING:
|
|
||||||
return context.getString(R.string.activity_type_biking);
|
|
||||||
case TYPE_TREADMILL:
|
|
||||||
return context.getString(R.string.activity_type_treadmill);
|
|
||||||
case TYPE_EXERCISE:
|
|
||||||
return context.getString(R.string.activity_type_exercise);
|
|
||||||
case TYPE_SWIMMING_OPENWATER:
|
|
||||||
return context.getString(R.string.activity_type_swimming_openwater);
|
|
||||||
case TYPE_INDOOR_CYCLING:
|
|
||||||
return context.getString(R.string.activity_type_indoor_cycling);
|
|
||||||
case TYPE_ELLIPTICAL_TRAINER:
|
|
||||||
return context.getString(R.string.activity_type_elliptical_trainer);
|
|
||||||
case TYPE_JUMP_ROPING:
|
|
||||||
return context.getString(R.string.activity_type_jump_roping);
|
|
||||||
case TYPE_YOGA:
|
|
||||||
return context.getString(R.string.activity_type_yoga);
|
|
||||||
case TYPE_SOCCER:
|
|
||||||
return context.getString(R.string.activity_type_soccer);
|
|
||||||
case TYPE_ROWING_MACHINE:
|
|
||||||
return context.getString(R.string.activity_type_rowing_machine);
|
|
||||||
case TYPE_CRICKET:
|
|
||||||
return context.getString(R.string.activity_type_cricket);
|
|
||||||
case TYPE_BASKETBALL:
|
|
||||||
return context.getString(R.string.activity_type_basketball);
|
|
||||||
case TYPE_PINGPONG:
|
|
||||||
return context.getString(R.string.activity_type_pingpong);
|
|
||||||
case TYPE_BADMINTON:
|
|
||||||
return context.getString(R.string.activity_type_badminton);
|
|
||||||
case TYPE_STRENGTH_TRAINING:
|
|
||||||
return context.getString(R.string.activity_type_strength_training);
|
|
||||||
case TYPE_UNKNOWN:
|
|
||||||
default:
|
|
||||||
return context.getString(R.string.activity_type_unknown);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
public static int getIconId(int kind) {
|
public int getIcon() {
|
||||||
switch (kind) {
|
return icon;
|
||||||
case TYPE_NOT_MEASURED:
|
}
|
||||||
return R.drawable.ic_activity_not_measured;
|
|
||||||
case TYPE_LIGHT_SLEEP:
|
|
||||||
case TYPE_DEEP_SLEEP:
|
|
||||||
case TYPE_REM_SLEEP:
|
|
||||||
return R.drawable.ic_activity_sleep;
|
|
||||||
case TYPE_RUNNING:
|
|
||||||
return R.drawable.ic_activity_running;
|
|
||||||
case TYPE_WALKING:
|
|
||||||
return R.drawable.ic_activity_walking;
|
|
||||||
case TYPE_HIKING:
|
|
||||||
return R.drawable.ic_activity_hiking;
|
|
||||||
case TYPE_CLIMBING:
|
|
||||||
return R.drawable.ic_activity_climbing;
|
|
||||||
case TYPE_CYCLING:
|
|
||||||
return R.drawable.ic_activity_biking;
|
|
||||||
case TYPE_TREADMILL:
|
|
||||||
return R.drawable.ic_activity_threadmill;
|
|
||||||
case TYPE_EXERCISE:
|
|
||||||
return R.drawable.ic_activity_exercise;
|
|
||||||
case TYPE_SWIMMING:
|
|
||||||
case TYPE_SWIMMING_OPENWATER:
|
|
||||||
return R.drawable.ic_activity_swimming;
|
|
||||||
case TYPE_INDOOR_CYCLING:
|
|
||||||
return R.drawable.ic_activity_bike_trainer;
|
|
||||||
case TYPE_ELLIPTICAL_TRAINER:
|
|
||||||
return R.drawable.ic_activity_eliptical;
|
|
||||||
case TYPE_JUMP_ROPING:
|
|
||||||
return R.drawable.ic_activity_rope_jump;
|
|
||||||
case TYPE_YOGA:
|
|
||||||
return R.drawable.ic_activity_yoga;
|
|
||||||
case TYPE_SOCCER:
|
|
||||||
return R.drawable.ic_activity_soccer;
|
|
||||||
case TYPE_ROWING_MACHINE:
|
|
||||||
return R.drawable.ic_activity_rowing;
|
|
||||||
case TYPE_CRICKET:
|
|
||||||
return R.drawable.ic_activity_cricket;
|
|
||||||
case TYPE_BASKETBALL:
|
|
||||||
return R.drawable.ic_activity_basketball;
|
|
||||||
case TYPE_PINGPONG:
|
|
||||||
return R.drawable.ic_activity_pingpong;
|
|
||||||
case TYPE_BADMINTON:
|
|
||||||
return R.drawable.ic_activity_badmington;
|
|
||||||
case TYPE_STRENGTH_TRAINING:
|
|
||||||
return R.drawable.ic_activity_unknown_small; //FIXME: find icon
|
|
||||||
|
|
||||||
case TYPE_NOT_WORN: // fall through
|
public static ActivityKind fromCode(final int code) {
|
||||||
case TYPE_ACTIVITY: // fall through
|
for (final ActivityKind kind : ActivityKind.values()) {
|
||||||
case TYPE_UNKNOWN: // fall through
|
if (kind.code == code) {
|
||||||
default:
|
return kind;
|
||||||
return R.drawable.ic_activity_unknown_small;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//throw new IllegalArgumentException("Unknown ActivityKind code " + code);
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSleep(final ActivityKind activityKind) {
|
||||||
|
return activityKind == ActivityKind.SLEEP_ANY
|
||||||
|
|| activityKind == ActivityKind.LIGHT_SLEEP
|
||||||
|
|| activityKind == ActivityKind.DEEP_SLEEP
|
||||||
|
|| activityKind == ActivityKind.REM_SLEEP
|
||||||
|
|| activityKind == ActivityKind.AWAKE_SLEEP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ public interface ActivitySample extends TimeStamped {
|
|||||||
*
|
*
|
||||||
* @return who created the sample data
|
* @return who created the sample data
|
||||||
*/
|
*/
|
||||||
SampleProvider getProvider();
|
SampleProvider<?> getProvider();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the raw activity kind value as recorded by the SampleProvider
|
* Returns the raw activity kind value as recorded by the SampleProvider
|
||||||
@ -55,7 +55,7 @@ public interface ActivitySample extends TimeStamped {
|
|||||||
*
|
*
|
||||||
* @see ActivityKind
|
* @see ActivityKind
|
||||||
*/
|
*/
|
||||||
int getKind();
|
ActivityKind getKind();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the raw intensity value as recorded by the SampleProvider
|
* Returns the raw intensity value as recorded by the SampleProvider
|
||||||
|
@ -34,7 +34,7 @@ public class ActivitySession implements Serializable {
|
|||||||
private final int heartRateAverage;
|
private final int heartRateAverage;
|
||||||
private final float intensity;
|
private final float intensity;
|
||||||
private final float distance;
|
private final float distance;
|
||||||
private final int activityKind;
|
private final ActivityKind activityKind;
|
||||||
// following is related to step session, we hold it here for the listview
|
// following is related to step session, we hold it here for the listview
|
||||||
// it is identified by SESSION_SUMMARY
|
// it is identified by SESSION_SUMMARY
|
||||||
private int sessionCount = 0;
|
private int sessionCount = 0;
|
||||||
@ -45,7 +45,7 @@ public class ActivitySession implements Serializable {
|
|||||||
|
|
||||||
public ActivitySession(Date startTime,
|
public ActivitySession(Date startTime,
|
||||||
Date endTime,
|
Date endTime,
|
||||||
int steps, int heartRateAverage, float intensity, float distance, int activityKind) {
|
int steps, int heartRateAverage, float intensity, float distance, ActivityKind activityKind) {
|
||||||
this.startTime = startTime;
|
this.startTime = startTime;
|
||||||
this.endTime = endTime;
|
this.endTime = endTime;
|
||||||
this.activeSteps = steps;
|
this.activeSteps = steps;
|
||||||
@ -62,7 +62,7 @@ public class ActivitySession implements Serializable {
|
|||||||
this.heartRateAverage = 0;
|
this.heartRateAverage = 0;
|
||||||
this.intensity = 0;
|
this.intensity = 0;
|
||||||
this.distance = 0;
|
this.distance = 0;
|
||||||
this.activityKind = 0;
|
this.activityKind = ActivityKind.UNKNOWN;
|
||||||
};
|
};
|
||||||
|
|
||||||
public Date getStartTime() {
|
public Date getStartTime() {
|
||||||
@ -81,7 +81,7 @@ public class ActivitySession implements Serializable {
|
|||||||
return heartRateAverage;
|
return heartRateAverage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getActivityKind() {
|
public ActivityKind getActivityKind() {
|
||||||
return activityKind;
|
return activityKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,11 +93,11 @@ public class DailyTotals {
|
|||||||
long totalSecondsLightSleep = 0;
|
long totalSecondsLightSleep = 0;
|
||||||
long totalSecondsRemSleep = 0;
|
long totalSecondsRemSleep = 0;
|
||||||
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
for (ActivityAmount amount : activityAmounts.getAmounts()) {
|
||||||
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP) {
|
if (amount.getActivityKind() == ActivityKind.DEEP_SLEEP) {
|
||||||
totalSecondsDeepSleep += amount.getTotalSeconds();
|
totalSecondsDeepSleep += amount.getTotalSeconds();
|
||||||
} else if (amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
|
} else if (amount.getActivityKind() == ActivityKind.LIGHT_SLEEP) {
|
||||||
totalSecondsLightSleep += amount.getTotalSeconds();
|
totalSecondsLightSleep += amount.getTotalSeconds();
|
||||||
} else if (amount.getActivityKind() == ActivityKind.TYPE_REM_SLEEP) {
|
} else if (amount.getActivityKind() == ActivityKind.REM_SLEEP) {
|
||||||
totalSecondsRemSleep += amount.getTotalSeconds();
|
totalSecondsRemSleep += amount.getTotalSeconds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,17 +390,17 @@ class BangleJSActivityTrack {
|
|||||||
summary.setName(log);
|
summary.setName(log);
|
||||||
summary.setStartTime(startTime);
|
summary.setStartTime(startTime);
|
||||||
summary.setEndTime(endTime);
|
summary.setEndTime(endTime);
|
||||||
int activityKind;
|
ActivityKind activityKind;
|
||||||
if (analyticsObject.has("Speed")) {
|
if (analyticsObject.has("Speed")) {
|
||||||
if ((float) 3 > averageOfJSONArray(analyticsObject.getJSONArray("Speed"))) {
|
if ((float) 3 > averageOfJSONArray(analyticsObject.getJSONArray("Speed"))) {
|
||||||
activityKind = ActivityKind.TYPE_WALKING;
|
activityKind = ActivityKind.WALKING;
|
||||||
} else {
|
} else {
|
||||||
activityKind = ActivityKind.TYPE_RUNNING;
|
activityKind = ActivityKind.RUNNING;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
activityKind = ActivityKind.TYPE_ACTIVITY;
|
activityKind = ActivityKind.ACTIVITY;
|
||||||
}
|
}
|
||||||
summary.setActivityKind(activityKind); // TODO: Make this depend on info from watch (currently this info isn't supplied in Bangle.js recorder logs).
|
summary.setActivityKind(activityKind.getCode()); // TODO: Make this depend on info from watch (currently this info isn't supplied in Bangle.js recorder logs).
|
||||||
summary.setRawDetailsPath(String.valueOf(inputFile));
|
summary.setRawDetailsPath(String.valueOf(inputFile));
|
||||||
|
|
||||||
|
|
||||||
@ -577,23 +577,23 @@ class BangleJSActivityTrack {
|
|||||||
|
|
||||||
ActivityTrackExporter exporter = createExporter();
|
ActivityTrackExporter exporter = createExporter();
|
||||||
String trackType = "track";
|
String trackType = "track";
|
||||||
switch (summary.getActivityKind()) {
|
switch (ActivityKind.fromCode(summary.getActivityKind())) {
|
||||||
case ActivityKind.TYPE_CYCLING:
|
case CYCLING:
|
||||||
trackType = context.getString(R.string.activity_type_biking);
|
trackType = context.getString(R.string.activity_type_biking);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_RUNNING:
|
case RUNNING:
|
||||||
trackType = context.getString(R.string.activity_type_running);
|
trackType = context.getString(R.string.activity_type_running);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_WALKING:
|
case WALKING:
|
||||||
trackType = context.getString(R.string.activity_type_walking);
|
trackType = context.getString(R.string.activity_type_walking);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_HIKING:
|
case HIKING:
|
||||||
trackType = context.getString(R.string.activity_type_hiking);
|
trackType = context.getString(R.string.activity_type_hiking);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_CLIMBING:
|
case CLIMBING:
|
||||||
trackType = context.getString(R.string.activity_type_climbing);
|
trackType = context.getString(R.string.activity_type_climbing);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_SWIMMING:
|
case SWIMMING:
|
||||||
trackType = context.getString(R.string.activity_type_swimming);
|
trackType = context.getString(R.string.activity_type_swimming);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -225,9 +225,9 @@ public class FetchStepCountDataOperation extends AbstractBTLEOperation<CasioGBX
|
|||||||
stepCountData.get(packetIndex/2).setSteps(count);
|
stepCountData.get(packetIndex/2).setSteps(count);
|
||||||
stepCountData.get(packetIndex/2).setTimestamp(ts);
|
stepCountData.get(packetIndex/2).setTimestamp(ts);
|
||||||
if(count > 0) {
|
if(count > 0) {
|
||||||
stepCountData.get(packetIndex / 2).setRawKind(ActivityKind.TYPE_ACTIVITY);
|
stepCountData.get(packetIndex / 2).setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
} else {
|
} else {
|
||||||
stepCountData.get(packetIndex / 2).setRawKind(ActivityKind.TYPE_NOT_MEASURED);
|
stepCountData.get(packetIndex / 2).setRawKind(ActivityKind.NOT_MEASURED.getCode());
|
||||||
}
|
}
|
||||||
if(ts > ts_from && ts < ts_to) {
|
if(ts > ts_from && ts < ts_to) {
|
||||||
stepsToday += count;
|
stepsToday += count;
|
||||||
@ -269,9 +269,9 @@ public class FetchStepCountDataOperation extends AbstractBTLEOperation<CasioGBX
|
|||||||
sample.setCalories(cals);
|
sample.setCalories(cals);
|
||||||
sample.setTimestamp(ts);
|
sample.setTimestamp(ts);
|
||||||
if (steps > 0)
|
if (steps > 0)
|
||||||
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
|
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
else
|
else
|
||||||
sample.setRawKind(ActivityKind.TYPE_NOT_MEASURED);
|
sample.setRawKind(ActivityKind.NOT_MEASURED.getCode());
|
||||||
stepCountData.add(0, sample);
|
stepCountData.add(0, sample);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ public class CmfActivitySync {
|
|||||||
|
|
||||||
BaseActivitySummary summary = new BaseActivitySummary();
|
BaseActivitySummary summary = new BaseActivitySummary();
|
||||||
summary.setRawSummaryData(summaryBytes);
|
summary.setRawSummaryData(summaryBytes);
|
||||||
summary.setActivityKind(ActivityKind.TYPE_UNKNOWN);
|
summary.setActivityKind(ActivityKind.UNKNOWN.getCode());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
summary = summaryParser.parseBinaryData(summary);
|
summary = summaryParser.parseBinaryData(summary);
|
||||||
|
@ -24,28 +24,28 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|||||||
|
|
||||||
public enum CmfActivityType {
|
public enum CmfActivityType {
|
||||||
// Core (non-removable in official app)
|
// Core (non-removable in official app)
|
||||||
INDOOR_RUNNING(0x03, R.string.activity_type_indoor_running, ActivityKind.TYPE_RUNNING),
|
INDOOR_RUNNING(0x03, R.string.activity_type_indoor_running, ActivityKind.RUNNING),
|
||||||
OUTDOOR_RUNNING(0x02, R.string.activity_type_outdoor_running, ActivityKind.TYPE_RUNNING),
|
OUTDOOR_RUNNING(0x02, R.string.activity_type_outdoor_running, ActivityKind.RUNNING),
|
||||||
// Fitness
|
// Fitness
|
||||||
OUTDOOR_WALKING(0x01, R.string.activity_type_outdoor_walking, ActivityKind.TYPE_WALKING),
|
OUTDOOR_WALKING(0x01, R.string.activity_type_outdoor_walking, ActivityKind.WALKING),
|
||||||
INDOOR_WALKING(0x19, R.string.activity_type_indoor_walking, ActivityKind.TYPE_WALKING),
|
INDOOR_WALKING(0x19, R.string.activity_type_indoor_walking, ActivityKind.WALKING),
|
||||||
OUTDOOR_CYCLING(0x05, R.string.activity_type_outdoor_cycling, ActivityKind.TYPE_CYCLING),
|
OUTDOOR_CYCLING(0x05, R.string.activity_type_outdoor_cycling, ActivityKind.CYCLING),
|
||||||
INDOOR_CYCLING(0x72, R.string.activity_type_indoor_cycling, ActivityKind.TYPE_INDOOR_CYCLING),
|
INDOOR_CYCLING(0x72, R.string.activity_type_indoor_cycling, ActivityKind.INDOOR_CYCLING),
|
||||||
MOUNTAIN_HIKE(0x04, R.string.activity_type_mountain_hike, ActivityKind.TYPE_HIKING),
|
MOUNTAIN_HIKE(0x04, R.string.activity_type_mountain_hike, ActivityKind.HIKING),
|
||||||
HIKING(0x1A, R.string.activity_type_hiking, ActivityKind.TYPE_HIKING),
|
HIKING(0x1A, R.string.activity_type_hiking, ActivityKind.HIKING),
|
||||||
CROSS_TRAINER(0x18, R.string.activity_type_cross_trainer),
|
CROSS_TRAINER(0x18, R.string.activity_type_cross_trainer),
|
||||||
FREE_TRAINING(0x10, R.string.activity_type_free_training, ActivityKind.TYPE_STRENGTH_TRAINING),
|
FREE_TRAINING(0x10, R.string.activity_type_free_training, ActivityKind.STRENGTH_TRAINING),
|
||||||
STRENGTH_TRAINING(0x13, R.string.activity_type_strength_training, ActivityKind.TYPE_STRENGTH_TRAINING),
|
STRENGTH_TRAINING(0x13, R.string.activity_type_strength_training, ActivityKind.STRENGTH_TRAINING),
|
||||||
YOGA(0x0F, R.string.activity_type_yoga, ActivityKind.TYPE_YOGA),
|
YOGA(0x0F, R.string.activity_type_yoga, ActivityKind.YOGA),
|
||||||
BOXING(0x21, R.string.activity_type_boxing),
|
BOXING(0x21, R.string.activity_type_boxing),
|
||||||
ROWER(0x0E, R.string.activity_type_rower, ActivityKind.TYPE_ROWING_MACHINE),
|
ROWER(0x0E, R.string.activity_type_rower, ActivityKind.ROWING_MACHINE),
|
||||||
DYNAMIC_CYCLE(0x0D, R.string.activity_type_dynamic_cycle),
|
DYNAMIC_CYCLE(0x0D, R.string.activity_type_dynamic_cycle),
|
||||||
STAIR_STEPPER(0x73, R.string.activity_type_stair_stepper),
|
STAIR_STEPPER(0x73, R.string.activity_type_stair_stepper),
|
||||||
TREADMILL(0x26, R.string.activity_type_treadmill, ActivityKind.TYPE_TREADMILL),
|
TREADMILL(0x26, R.string.activity_type_treadmill, ActivityKind.TREADMILL),
|
||||||
KICKBOXING(0x35, R.string.activity_type_kickboxing),
|
KICKBOXING(0x35, R.string.activity_type_kickboxing),
|
||||||
HIIT(0x5C, R.string.activity_type_hiit),
|
HIIT(0x5C, R.string.activity_type_hiit),
|
||||||
FITNESS_EXERCISES(0x4E, R.string.activity_type_fitness_exercises),
|
FITNESS_EXERCISES(0x4E, R.string.activity_type_fitness_exercises),
|
||||||
JUMP_ROPING(0x06, R.string.activity_type_jump_roping, ActivityKind.TYPE_JUMP_ROPING), // moved to leisure sports in watch 2
|
JUMP_ROPING(0x06, R.string.activity_type_jump_roping, ActivityKind.JUMP_ROPING), // moved to leisure sports in watch 2
|
||||||
PILATES(0x2C, R.string.activity_type_pilates),
|
PILATES(0x2C, R.string.activity_type_pilates),
|
||||||
CROSSFIT(0x74, R.string.activity_type_crossfit),
|
CROSSFIT(0x74, R.string.activity_type_crossfit),
|
||||||
FUNCTIONAL_TRAINING(0x2E, R.string.activity_type_functional_training),
|
FUNCTIONAL_TRAINING(0x2E, R.string.activity_type_functional_training),
|
||||||
@ -106,7 +106,7 @@ public enum CmfActivityType {
|
|||||||
KARTING(0xA0, R.string.activity_type_karting),
|
KARTING(0xA0, R.string.activity_type_karting),
|
||||||
// Ball sports
|
// Ball sports
|
||||||
BADMINTON(0x09, R.string.activity_type_badminton),
|
BADMINTON(0x09, R.string.activity_type_badminton),
|
||||||
TABLE_TENNIS(0x0A, R.string.activity_type_table_tennis, ActivityKind.TYPE_PINGPONG),
|
TABLE_TENNIS(0x0A, R.string.activity_type_table_tennis, ActivityKind.PINGPONG),
|
||||||
TENNIS(0x0C, R.string.activity_type_tennis),
|
TENNIS(0x0C, R.string.activity_type_tennis),
|
||||||
BILLIARDS(0x7C, R.string.activity_type_billiards),
|
BILLIARDS(0x7C, R.string.activity_type_billiards),
|
||||||
BOWLING(0x3B, R.string.activity_type_bowling),
|
BOWLING(0x3B, R.string.activity_type_bowling),
|
||||||
@ -120,8 +120,8 @@ public enum CmfActivityType {
|
|||||||
HOCKEY(0x1E, R.string.activity_type_hockey),
|
HOCKEY(0x1E, R.string.activity_type_hockey),
|
||||||
SQUASH(0x3C, R.string.activity_type_squash),
|
SQUASH(0x3C, R.string.activity_type_squash),
|
||||||
DODGEBALL(0x81, R.string.activity_type_dodgeball),
|
DODGEBALL(0x81, R.string.activity_type_dodgeball),
|
||||||
SOCCER(0x07, R.string.activity_type_soccer, ActivityKind.TYPE_SOCCER),
|
SOCCER(0x07, R.string.activity_type_soccer, ActivityKind.SOCCER),
|
||||||
BASKETBALL(0x08, R.string.activity_type_basketball, ActivityKind.TYPE_BASKETBALL),
|
BASKETBALL(0x08, R.string.activity_type_basketball, ActivityKind.BASKETBALL),
|
||||||
AUSTRALIAN_FOOTBALL(0x37, R.string.activity_type_australian_football),
|
AUSTRALIAN_FOOTBALL(0x37, R.string.activity_type_australian_football),
|
||||||
GOLF(0x45, R.string.activity_type_golf),
|
GOLF(0x45, R.string.activity_type_golf),
|
||||||
PICKLEBALL(0x5B, R.string.activity_type_pickleball),
|
PICKLEBALL(0x5B, R.string.activity_type_pickleball),
|
||||||
@ -157,13 +157,13 @@ public enum CmfActivityType {
|
|||||||
private final byte code;
|
private final byte code;
|
||||||
@StringRes
|
@StringRes
|
||||||
private final int nameRes;
|
private final int nameRes;
|
||||||
private final int activityKind;
|
private final ActivityKind activityKind;
|
||||||
|
|
||||||
CmfActivityType(final int code, final int nameRes) {
|
CmfActivityType(final int code, final int nameRes) {
|
||||||
this(code, nameRes, ActivityKind.TYPE_UNKNOWN);
|
this(code, nameRes, ActivityKind.UNKNOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
CmfActivityType(final int code, final int nameRes, final int activityKind) {
|
CmfActivityType(final int code, final int nameRes, final ActivityKind activityKind) {
|
||||||
this.code = (byte) code;
|
this.code = (byte) code;
|
||||||
this.nameRes = nameRes;
|
this.nameRes = nameRes;
|
||||||
this.activityKind = activityKind;
|
this.activityKind = activityKind;
|
||||||
@ -173,7 +173,7 @@ public enum CmfActivityType {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getActivityKind() {
|
public ActivityKind getActivityKind() {
|
||||||
return activityKind;
|
return activityKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.cycling_sensor.support;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.cycling_sensor.support;
|
||||||
|
|
||||||
import static nodomain.freeyourgadget.gadgetbridge.model.ActivityKind.TYPE_CYCLING;
|
import static nodomain.freeyourgadget.gadgetbridge.model.ActivityKind.CYCLING;
|
||||||
|
|
||||||
import android.bluetooth.BluetoothGatt;
|
import android.bluetooth.BluetoothGatt;
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
|
@ -1355,7 +1355,7 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
sample.setSpo2Percent(spo2);
|
sample.setSpo2Percent(spo2);
|
||||||
|
|
||||||
sample.setTimestamp((int) (date.getTimeInMillis() / 1000));
|
sample.setTimestamp((int) (date.getTimeInMillis() / 1000));
|
||||||
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
|
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
|
|
||||||
addGBActivitySample(sample);
|
addGBActivitySample(sample);
|
||||||
broadcastSample(sample);
|
broadcastSample(sample);
|
||||||
@ -1394,7 +1394,7 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
sample.setSteps(newSteps);
|
sample.setSteps(newSteps);
|
||||||
sample.setDistanceMeters(distance);
|
sample.setDistanceMeters(distance);
|
||||||
sample.setCaloriesBurnt(calories);
|
sample.setCaloriesBurnt(calories);
|
||||||
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
|
sample.setRawKind(ActivityKind.ACTIVITY);
|
||||||
sample.setRawIntensity(1);
|
sample.setRawIntensity(1);
|
||||||
addGBActivitySample(sample);
|
addGBActivitySample(sample);
|
||||||
broadcastSample(sample);
|
broadcastSample(sample);
|
||||||
|
@ -285,18 +285,18 @@ public class FitImporter {
|
|||||||
LOG.debug("Persisting workout for {}", fileId);
|
LOG.debug("Persisting workout for {}", fileId);
|
||||||
|
|
||||||
final BaseActivitySummary summary = new BaseActivitySummary();
|
final BaseActivitySummary summary = new BaseActivitySummary();
|
||||||
summary.setActivityKind(ActivityKind.TYPE_UNKNOWN);
|
summary.setActivityKind(ActivityKind.UNKNOWN.getCode());
|
||||||
|
|
||||||
final ActivitySummaryData summaryData = new ActivitySummaryData();
|
final ActivitySummaryData summaryData = new ActivitySummaryData();
|
||||||
|
|
||||||
final int activityKind;
|
final ActivityKind activityKind;
|
||||||
if (sport != null) {
|
if (sport != null) {
|
||||||
summary.setName(sport.getName());
|
summary.setName(sport.getName());
|
||||||
activityKind = getActivityKind(sport.getSport(), sport.getSubSport());
|
activityKind = getActivityKind(sport.getSport(), sport.getSubSport());
|
||||||
} else {
|
} else {
|
||||||
activityKind = getActivityKind(session.getSport(), session.getSubSport());
|
activityKind = getActivityKind(session.getSport(), session.getSubSport());
|
||||||
}
|
}
|
||||||
summary.setActivityKind(activityKind);
|
summary.setActivityKind(activityKind.getCode());
|
||||||
if (session.getStartTime() == null) {
|
if (session.getStartTime() == null) {
|
||||||
LOG.error("No session start time for {}", fileId);
|
LOG.error("No session start time for {}", fileId);
|
||||||
return;
|
return;
|
||||||
@ -355,11 +355,11 @@ public class FitImporter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getActivityKind(final Integer sport, final Integer subsport) {
|
private ActivityKind getActivityKind(final Integer sport, final Integer subsport) {
|
||||||
final Optional<GarminSport> garminSport = GarminSport.fromCodes(sport, subsport);
|
final Optional<GarminSport> garminSport = GarminSport.fromCodes(sport, subsport);
|
||||||
if (garminSport.isEmpty()) {
|
if (garminSport.isEmpty()) {
|
||||||
LOG.warn("Unknown garmin sport {}/{}", sport, subsport);
|
LOG.warn("Unknown garmin sport {}/{}", sport, subsport);
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (garminSport.get()) {
|
switch (garminSport.get()) {
|
||||||
@ -367,48 +367,48 @@ public class FitImporter {
|
|||||||
case PUSH_RUN_SPEED:
|
case PUSH_RUN_SPEED:
|
||||||
case INDOOR_PUSH_RUN_SPEED:
|
case INDOOR_PUSH_RUN_SPEED:
|
||||||
case INDOOR_TRACK:
|
case INDOOR_TRACK:
|
||||||
return ActivityKind.TYPE_RUNNING;
|
return ActivityKind.RUNNING;
|
||||||
case TREADMILL:
|
case TREADMILL:
|
||||||
return ActivityKind.TYPE_TREADMILL;
|
return ActivityKind.TREADMILL;
|
||||||
case E_BIKE:
|
case E_BIKE:
|
||||||
case BIKE:
|
case BIKE:
|
||||||
case BIKE_COMMUTE:
|
case BIKE_COMMUTE:
|
||||||
return ActivityKind.TYPE_CYCLING;
|
return ActivityKind.CYCLING;
|
||||||
case BIKE_INDOOR:
|
case BIKE_INDOOR:
|
||||||
return ActivityKind.TYPE_INDOOR_CYCLING;
|
return ActivityKind.INDOOR_CYCLING;
|
||||||
case ELLIPTICAL:
|
case ELLIPTICAL:
|
||||||
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
|
return ActivityKind.ELLIPTICAL_TRAINER;
|
||||||
case STAIR_STEPPER:
|
case STAIR_STEPPER:
|
||||||
case PILATES:
|
case PILATES:
|
||||||
case CARDIO:
|
case CARDIO:
|
||||||
return ActivityKind.TYPE_EXERCISE;
|
return ActivityKind.EXERCISE;
|
||||||
case POOL_SWIM:
|
case POOL_SWIM:
|
||||||
return ActivityKind.TYPE_SWIMMING;
|
return ActivityKind.SWIMMING;
|
||||||
case OPEN_WATER:
|
case OPEN_WATER:
|
||||||
return ActivityKind.TYPE_SWIMMING_OPENWATER;
|
return ActivityKind.SWIMMING_OPENWATER;
|
||||||
case SOCCER:
|
case SOCCER:
|
||||||
return ActivityKind.TYPE_SOCCER;
|
return ActivityKind.SOCCER;
|
||||||
case STRENGTH:
|
case STRENGTH:
|
||||||
return ActivityKind.TYPE_STRENGTH_TRAINING;
|
return ActivityKind.STRENGTH_TRAINING;
|
||||||
case YOGA:
|
case YOGA:
|
||||||
return ActivityKind.TYPE_YOGA;
|
return ActivityKind.YOGA;
|
||||||
case WALK:
|
case WALK:
|
||||||
case WALK_INDOOR:
|
case WALK_INDOOR:
|
||||||
case PUSH_WALK_SPEED:
|
case PUSH_WALK_SPEED:
|
||||||
case INDOOR_PUSH_WALK_SPEED:
|
case INDOOR_PUSH_WALK_SPEED:
|
||||||
return ActivityKind.TYPE_WALKING;
|
return ActivityKind.WALKING;
|
||||||
case HIKE:
|
case HIKE:
|
||||||
return ActivityKind.TYPE_HIKING;
|
return ActivityKind.HIKING;
|
||||||
case CLIMB_INDOOR:
|
case CLIMB_INDOOR:
|
||||||
case BOULDERING:
|
case BOULDERING:
|
||||||
return ActivityKind.TYPE_CLIMBING;
|
return ActivityKind.CLIMBING;
|
||||||
case BASKETBALL:
|
case BASKETBALL:
|
||||||
return ActivityKind.TYPE_BASKETBALL;
|
return ActivityKind.BASKETBALL;
|
||||||
case JUMP_ROPE:
|
case JUMP_ROPE:
|
||||||
return ActivityKind.TYPE_JUMP_ROPING;
|
return ActivityKind.JUMP_ROPING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reset() {
|
private void reset() {
|
||||||
@ -440,7 +440,7 @@ public class FitImporter {
|
|||||||
final Map<Integer, Long> stepsPerActivity = new HashMap<>();
|
final Map<Integer, Long> stepsPerActivity = new HashMap<>();
|
||||||
|
|
||||||
final int THRESHOLD_NOT_WORN = 10 * 60; // 10 min gap between samples = not-worn
|
final int THRESHOLD_NOT_WORN = 10 * 60; // 10 min gap between samples = not-worn
|
||||||
int prevActivityKind = ActivityKind.TYPE_UNKNOWN;
|
int prevActivityKind = ActivityKind.UNKNOWN.getCode();
|
||||||
int prevTs = -1;
|
int prevTs = -1;
|
||||||
|
|
||||||
for (final int ts : activitySamplesPerTimestamp.keySet()) {
|
for (final int ts : activitySamplesPerTimestamp.keySet()) {
|
||||||
@ -449,7 +449,7 @@ public class FitImporter {
|
|||||||
for (int i = prevTs; i < ts; i += 60) {
|
for (int i = prevTs; i < ts; i += 60) {
|
||||||
final GarminActivitySample sample = new GarminActivitySample();
|
final GarminActivitySample sample = new GarminActivitySample();
|
||||||
sample.setTimestamp(i);
|
sample.setTimestamp(i);
|
||||||
sample.setRawKind(ts - prevTs > THRESHOLD_NOT_WORN ? ActivityKind.TYPE_NOT_WORN : prevActivityKind);
|
sample.setRawKind(ts - prevTs > THRESHOLD_NOT_WORN ? ActivityKind.NOT_WORN.getCode() : prevActivityKind);
|
||||||
sample.setRawIntensity(ActivitySample.NOT_MEASURED);
|
sample.setRawIntensity(ActivitySample.NOT_MEASURED);
|
||||||
sample.setSteps(ActivitySample.NOT_MEASURED);
|
sample.setSteps(ActivitySample.NOT_MEASURED);
|
||||||
activitySamples.add(sample);
|
activitySamples.add(sample);
|
||||||
@ -460,7 +460,7 @@ public class FitImporter {
|
|||||||
|
|
||||||
final GarminActivitySample sample = new GarminActivitySample();
|
final GarminActivitySample sample = new GarminActivitySample();
|
||||||
sample.setTimestamp(ts);
|
sample.setTimestamp(ts);
|
||||||
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
|
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
sample.setRawIntensity(ActivitySample.NOT_MEASURED);
|
sample.setRawIntensity(ActivitySample.NOT_MEASURED);
|
||||||
sample.setSteps(ActivitySample.NOT_MEASURED);
|
sample.setSteps(ActivitySample.NOT_MEASURED);
|
||||||
sample.setHeartRate(ActivitySample.NOT_MEASURED);
|
sample.setHeartRate(ActivitySample.NOT_MEASURED);
|
||||||
|
@ -18,11 +18,9 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
* @author João Paulo Barraca <jpbarraca@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
public class HPlusDataRecord {
|
public class HPlusDataRecord {
|
||||||
public final static int TYPE_UNKNOWN = 0;
|
public final static int TYPE_UNKNOWN = 0;
|
||||||
public final static int TYPE_SLEEP = 100;
|
public final static int TYPE_SLEEP = 100;
|
||||||
@ -31,7 +29,7 @@ public class HPlusDataRecord {
|
|||||||
public final static int TYPE_REALTIME = 103;
|
public final static int TYPE_REALTIME = 103;
|
||||||
|
|
||||||
public int type = TYPE_UNKNOWN;
|
public int type = TYPE_UNKNOWN;
|
||||||
public int activityKind = ActivityKind.TYPE_UNKNOWN;
|
public int activityKindRaw = ActivityKind.UNKNOWN.getCode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Time of this record in seconds
|
* Time of this record in seconds
|
||||||
@ -53,11 +51,10 @@ public class HPlusDataRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getRawData() {
|
public byte[] getRawData() {
|
||||||
|
|
||||||
return rawData;
|
return rawData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RecordInterval {
|
public static class RecordInterval {
|
||||||
/**
|
/**
|
||||||
* Start time of this interval in seconds
|
* Start time of this interval in seconds
|
||||||
*/
|
*/
|
||||||
@ -71,9 +68,9 @@ public class HPlusDataRecord {
|
|||||||
/**
|
/**
|
||||||
* Type of activity {@link ActivityKind}
|
* Type of activity {@link ActivityKind}
|
||||||
*/
|
*/
|
||||||
public int activityKind;
|
public ActivityKind activityKind;
|
||||||
|
|
||||||
RecordInterval(int timestampFrom, int timestampTo, int activityKind) {
|
RecordInterval(int timestampFrom, int timestampTo, ActivityKind activityKind) {
|
||||||
this.timestampFrom = timestampFrom;
|
this.timestampFrom = timestampFrom;
|
||||||
this.timestampTo = timestampTo;
|
this.timestampTo = timestampTo;
|
||||||
this.activityKind = activityKind;
|
this.activityKind = activityKind;
|
||||||
|
@ -21,6 +21,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@ -87,16 +89,16 @@ class HPlusDataRecordRealtime extends HPlusDataRecord {
|
|||||||
battery = ActivitySample.NOT_MEASURED;
|
battery = ActivitySample.NOT_MEASURED;
|
||||||
heartRate = ActivitySample.NOT_MEASURED;
|
heartRate = ActivitySample.NOT_MEASURED;
|
||||||
intensity = 0;
|
intensity = 0;
|
||||||
activityKind = ActivityKind.TYPE_NOT_WORN;
|
activityKindRaw = ActivityKind.NOT_WORN.getCode();
|
||||||
} else {
|
} else {
|
||||||
heartRate = data[11] & 0xFF; // BPM
|
heartRate = data[11] & 0xFF; // BPM
|
||||||
if (heartRate == 255) {
|
if (heartRate == 255) {
|
||||||
intensity = 0;
|
intensity = 0;
|
||||||
activityKind = ActivityKind.TYPE_NOT_MEASURED;
|
activityKindRaw = ActivityKind.NOT_MEASURED.getCode();
|
||||||
heartRate = ActivitySample.NOT_MEASURED;
|
heartRate = ActivitySample.NOT_MEASURED;
|
||||||
} else {
|
} else {
|
||||||
intensity = (int) ((100 * heartRate) / (208 - 0.7 * age));
|
intensity = (int) ((100 * heartRate) / (208 - 0.7 * age));
|
||||||
activityKind = HPlusDataRecord.TYPE_REALTIME;
|
activityKindRaw = HPlusDataRecord.TYPE_REALTIME;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,7 +120,7 @@ class HPlusDataRecordRealtime extends HPlusDataRecord {
|
|||||||
double speed = deltaDistance / deltaTime;
|
double speed = deltaDistance / deltaTime;
|
||||||
|
|
||||||
if(speed >= 1.6) // ~6 KM/h
|
if(speed >= 1.6) // ~6 KM/h
|
||||||
activityKind = ActivityKind.TYPE_ACTIVITY;
|
activityKindRaw = ActivityKind.ACTIVITY.getCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean same(HPlusDataRecordRealtime other){
|
public boolean same(HPlusDataRecordRealtime other){
|
||||||
@ -128,8 +130,8 @@ class HPlusDataRecordRealtime extends HPlusDataRecord {
|
|||||||
return steps == other.steps && distance == other.distance && calories == other.calories && heartRate == other.heartRate && battery == other.battery;
|
return steps == other.steps && distance == other.distance && calories == other.calories && heartRate == other.heartRate && battery == other.battery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return String.format(Locale.US, "Distance: %d Steps: %d Calories: %d HeartRate: %d Battery: %d ActiveTime: %d Intensity: %d", distance, steps, calories, heartRate, battery, activeTime, intensity);
|
return String.format(Locale.US, "Distance: %d Steps: %d Calories: %d HeartRate: %d Battery: %d ActiveTime: %d Intensity: %d", distance, steps, calories, heartRate, battery, activeTime, intensity);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -128,8 +128,8 @@ public class HPlusDataRecordSleep extends HPlusDataRecord {
|
|||||||
List<RecordInterval> intervals = new ArrayList<>();
|
List<RecordInterval> intervals = new ArrayList<>();
|
||||||
|
|
||||||
int ts = bedTimeStart + lightSleepMinutes * 60;
|
int ts = bedTimeStart + lightSleepMinutes * 60;
|
||||||
intervals.add(new RecordInterval(bedTimeStart, ts, ActivityKind.TYPE_LIGHT_SLEEP));
|
intervals.add(new RecordInterval(bedTimeStart, ts, ActivityKind.LIGHT_SLEEP));
|
||||||
intervals.add(new RecordInterval(ts, bedTimeEnd, ActivityKind.TYPE_DEEP_SLEEP));
|
intervals.add(new RecordInterval(ts, bedTimeEnd, ActivityKind.DEEP_SLEEP));
|
||||||
return intervals;
|
return intervals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +321,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
|
|
||||||
//If it is the last of the samples or of the interruption period
|
//If it is the last of the samples or of the interruption period
|
||||||
if (timestamp - lastSlotTimestamp > 10 * 60) {
|
if (timestamp - lastSlotTimestamp > 10 * 60) {
|
||||||
overlayList.add(new HPlusHealthActivityOverlay(firstSlotTimestamp, lastSlotTimestamp, ActivityKind.TYPE_NOT_WORN, deviceId, userId, null));
|
overlayList.add(new HPlusHealthActivityOverlay(firstSlotTimestamp, lastSlotTimestamp, ActivityKind.NOT_WORN.getCode(), deviceId, userId, null));
|
||||||
firstSlotTimestamp = timestamp;
|
firstSlotTimestamp = timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +330,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (firstSlotTimestamp != lastSlotTimestamp)
|
if (firstSlotTimestamp != lastSlotTimestamp)
|
||||||
overlayList.add(new HPlusHealthActivityOverlay(firstSlotTimestamp, lastSlotTimestamp, ActivityKind.TYPE_NOT_WORN, deviceId, userId, null));
|
overlayList.add(new HPlusHealthActivityOverlay(firstSlotTimestamp, lastSlotTimestamp, ActivityKind.NOT_WORN.getCode(), deviceId, userId, null));
|
||||||
|
|
||||||
overlayDao.insertOrReplaceInTx(overlayList);
|
overlayDao.insertOrReplaceInTx(overlayList);
|
||||||
}
|
}
|
||||||
@ -379,7 +379,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
List<HPlusDataRecord.RecordInterval> intervals = record.getIntervals();
|
List<HPlusDataRecord.RecordInterval> intervals = record.getIntervals();
|
||||||
|
|
||||||
for (HPlusDataRecord.RecordInterval interval : intervals) {
|
for (HPlusDataRecord.RecordInterval interval : intervals) {
|
||||||
overlayList.add(new HPlusHealthActivityOverlay(interval.timestampFrom, interval.timestampTo, interval.activityKind, deviceId, userId, null));
|
overlayList.add(new HPlusHealthActivityOverlay(interval.timestampFrom, interval.timestampTo, interval.activityKind.getCode(), deviceId, userId, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
overlayDao.insertOrReplaceInTx(overlayList);
|
overlayDao.insertOrReplaceInTx(overlayList);
|
||||||
@ -387,7 +387,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
//Store the data
|
//Store the data
|
||||||
HPlusHealthActivitySample sample = createSample(dbHandler, record.timestamp);
|
HPlusHealthActivitySample sample = createSample(dbHandler, record.timestamp);
|
||||||
sample.setRawHPlusHealthData(record.getRawData());
|
sample.setRawHPlusHealthData(record.getRawData());
|
||||||
sample.setRawKind(record.activityKind);
|
sample.setRawKind(record.activityKindRaw);
|
||||||
|
|
||||||
sample.setProvider(provider);
|
sample.setProvider(provider);
|
||||||
|
|
||||||
@ -631,7 +631,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
|
|||||||
timestamp, // ts
|
timestamp, // ts
|
||||||
deviceId, userId, // User id
|
deviceId, userId, // User id
|
||||||
null, // Raw Data
|
null, // Raw Data
|
||||||
ActivityKind.TYPE_UNKNOWN,
|
ActivityKind.UNKNOWN.getCode(),
|
||||||
0, // Intensity
|
0, // Intensity
|
||||||
ActivitySample.NOT_MEASURED, // Steps
|
ActivitySample.NOT_MEASURED, // Steps
|
||||||
ActivitySample.NOT_MEASURED, // HR
|
ActivitySample.NOT_MEASURED, // HR
|
||||||
|
@ -47,48 +47,48 @@ public enum HuamiSportsActivityType {
|
|||||||
this.code = code;
|
this.code = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int toActivityKind() {
|
public ActivityKind toActivityKind() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case OutdoorRunning:
|
case OutdoorRunning:
|
||||||
return ActivityKind.TYPE_RUNNING;
|
return ActivityKind.RUNNING;
|
||||||
case OutdoorHiking:
|
case OutdoorHiking:
|
||||||
return ActivityKind.TYPE_HIKING;
|
return ActivityKind.HIKING;
|
||||||
case Climbing:
|
case Climbing:
|
||||||
return ActivityKind.TYPE_CLIMBING;
|
return ActivityKind.CLIMBING;
|
||||||
case Treadmill:
|
case Treadmill:
|
||||||
return ActivityKind.TYPE_TREADMILL;
|
return ActivityKind.TREADMILL;
|
||||||
case Cycling:
|
case Cycling:
|
||||||
return ActivityKind.TYPE_CYCLING;
|
return ActivityKind.CYCLING;
|
||||||
case Walking:
|
case Walking:
|
||||||
return ActivityKind.TYPE_WALKING;
|
return ActivityKind.WALKING;
|
||||||
case Exercise:
|
case Exercise:
|
||||||
return ActivityKind.TYPE_EXERCISE;
|
return ActivityKind.EXERCISE;
|
||||||
case Swimming:
|
case Swimming:
|
||||||
return ActivityKind.TYPE_SWIMMING;
|
return ActivityKind.SWIMMING;
|
||||||
case OpenWaterSwimming:
|
case OpenWaterSwimming:
|
||||||
return ActivityKind.TYPE_SWIMMING_OPENWATER;
|
return ActivityKind.SWIMMING_OPENWATER;
|
||||||
case IndoorCycling:
|
case IndoorCycling:
|
||||||
return ActivityKind.TYPE_INDOOR_CYCLING;
|
return ActivityKind.INDOOR_CYCLING;
|
||||||
case EllipticalTrainer:
|
case EllipticalTrainer:
|
||||||
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
|
return ActivityKind.ELLIPTICAL_TRAINER;
|
||||||
case Soccer:
|
case Soccer:
|
||||||
return ActivityKind.TYPE_SOCCER;
|
return ActivityKind.SOCCER;
|
||||||
case JumpRope:
|
case JumpRope:
|
||||||
return ActivityKind.TYPE_JUMP_ROPING;
|
return ActivityKind.JUMP_ROPING;
|
||||||
case RowingMachine:
|
case RowingMachine:
|
||||||
return ActivityKind.TYPE_ROWING_MACHINE;
|
return ActivityKind.ROWING_MACHINE;
|
||||||
case Yoga:
|
case Yoga:
|
||||||
return ActivityKind.TYPE_YOGA;
|
return ActivityKind.YOGA;
|
||||||
case Cricket:
|
case Cricket:
|
||||||
return ActivityKind.TYPE_CRICKET;
|
return ActivityKind.CRICKET;
|
||||||
case Basketball:
|
case Basketball:
|
||||||
return ActivityKind.TYPE_BASKETBALL;
|
return ActivityKind.BASKETBALL;
|
||||||
case PingPong:
|
case PingPong:
|
||||||
return ActivityKind.TYPE_PINGPONG;
|
return ActivityKind.PINGPONG;
|
||||||
case Badminton:
|
case Badminton:
|
||||||
return ActivityKind.TYPE_BADMINTON;
|
return ActivityKind.BADMINTON;
|
||||||
case StrengthTraining:
|
case StrengthTraining:
|
||||||
return ActivityKind.TYPE_STRENGTH_TRAINING;
|
return ActivityKind.STRENGTH_TRAINING;
|
||||||
}
|
}
|
||||||
throw new RuntimeException("Not mapped activity kind for: " + this);
|
throw new RuntimeException("Not mapped activity kind for: " + this);
|
||||||
}
|
}
|
||||||
@ -102,47 +102,47 @@ public enum HuamiSportsActivityType {
|
|||||||
throw new RuntimeException("No matching HuamiSportsActivityType for code: " + huamiCode);
|
throw new RuntimeException("No matching HuamiSportsActivityType for code: " + huamiCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HuamiSportsActivityType fromActivityKind(int activityKind) {
|
public static HuamiSportsActivityType fromActivityKind(ActivityKind activityKind) {
|
||||||
switch (activityKind) {
|
switch (activityKind) {
|
||||||
case ActivityKind.TYPE_RUNNING:
|
case RUNNING:
|
||||||
return OutdoorRunning;
|
return OutdoorRunning;
|
||||||
case ActivityKind.TYPE_HIKING:
|
case HIKING:
|
||||||
return OutdoorHiking;
|
return OutdoorHiking;
|
||||||
case ActivityKind.TYPE_CLIMBING:
|
case CLIMBING:
|
||||||
return Climbing;
|
return Climbing;
|
||||||
case ActivityKind.TYPE_TREADMILL:
|
case TREADMILL:
|
||||||
return Treadmill;
|
return Treadmill;
|
||||||
case ActivityKind.TYPE_CYCLING:
|
case CYCLING:
|
||||||
return Cycling;
|
return Cycling;
|
||||||
case ActivityKind.TYPE_WALKING:
|
case WALKING:
|
||||||
return Walking;
|
return Walking;
|
||||||
case ActivityKind.TYPE_EXERCISE:
|
case EXERCISE:
|
||||||
return Exercise;
|
return Exercise;
|
||||||
case ActivityKind.TYPE_SWIMMING:
|
case SWIMMING:
|
||||||
return Swimming;
|
return Swimming;
|
||||||
case ActivityKind.TYPE_SWIMMING_OPENWATER:
|
case SWIMMING_OPENWATER:
|
||||||
return OpenWaterSwimming;
|
return OpenWaterSwimming;
|
||||||
case ActivityKind.TYPE_INDOOR_CYCLING:
|
case INDOOR_CYCLING:
|
||||||
return IndoorCycling;
|
return IndoorCycling;
|
||||||
case ActivityKind.TYPE_ELLIPTICAL_TRAINER:
|
case ELLIPTICAL_TRAINER:
|
||||||
return EllipticalTrainer;
|
return EllipticalTrainer;
|
||||||
case ActivityKind.TYPE_SOCCER:
|
case SOCCER:
|
||||||
return Soccer;
|
return Soccer;
|
||||||
case ActivityKind.TYPE_JUMP_ROPING:
|
case JUMP_ROPING:
|
||||||
return JumpRope;
|
return JumpRope;
|
||||||
case ActivityKind.TYPE_ROWING_MACHINE:
|
case ROWING_MACHINE:
|
||||||
return RowingMachine;
|
return RowingMachine;
|
||||||
case ActivityKind.TYPE_YOGA:
|
case YOGA:
|
||||||
return Yoga;
|
return Yoga;
|
||||||
case ActivityKind.TYPE_CRICKET:
|
case CRICKET:
|
||||||
return Cricket;
|
return Cricket;
|
||||||
case ActivityKind.TYPE_BASKETBALL:
|
case BASKETBALL:
|
||||||
return Basketball;
|
return Basketball;
|
||||||
case ActivityKind.TYPE_PINGPONG:
|
case PINGPONG:
|
||||||
return PingPong;
|
return PingPong;
|
||||||
case ActivityKind.TYPE_BADMINTON:
|
case BADMINTON:
|
||||||
return Badminton;
|
return Badminton;
|
||||||
case ActivityKind.TYPE_STRENGTH_TRAINING:
|
case STRENGTH_TRAINING:
|
||||||
return StrengthTraining;
|
return StrengthTraining;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1945,11 +1945,11 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
|||||||
break;
|
break;
|
||||||
case HuamiDeviceEvent.WORKOUT_STARTING:
|
case HuamiDeviceEvent.WORKOUT_STARTING:
|
||||||
final HuamiWorkoutTrackActivityType activityType = HuamiWorkoutTrackActivityType.fromCode(value[3]);
|
final HuamiWorkoutTrackActivityType activityType = HuamiWorkoutTrackActivityType.fromCode(value[3]);
|
||||||
final int activityKind;
|
final ActivityKind activityKind;
|
||||||
|
|
||||||
if (activityType == null) {
|
if (activityType == null) {
|
||||||
LOG.warn("Unknown workout activity type {}", String.format("0x%02x", value[3]));
|
LOG.warn("Unknown workout activity type {}", String.format("0x%02x", value[3]));
|
||||||
activityKind = ActivityKind.TYPE_UNKNOWN;
|
activityKind = ActivityKind.UNKNOWN;
|
||||||
} else {
|
} else {
|
||||||
activityKind = activityType.toActivityKind();
|
activityKind = activityType.toActivityKind();
|
||||||
}
|
}
|
||||||
@ -1975,14 +1975,14 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
|||||||
/**
|
/**
|
||||||
* Track the {@link nodomain.freeyourgadget.gadgetbridge.model.ActivityKind} that was opened, for the same reasons as {@code workoutNeedsGps}.
|
* Track the {@link nodomain.freeyourgadget.gadgetbridge.model.ActivityKind} that was opened, for the same reasons as {@code workoutNeedsGps}.
|
||||||
*/
|
*/
|
||||||
private int workoutActivityKind = ActivityKind.TYPE_UNKNOWN;
|
private ActivityKind workoutActivityKind = ActivityKind.UNKNOWN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Track the last time we actually sent a gps location. We need to signal that GPS as re-acquired if the last update was too long ago.
|
* Track the last time we actually sent a gps location. We need to signal that GPS as re-acquired if the last update was too long ago.
|
||||||
*/
|
*/
|
||||||
private long lastPhoneGpsSent = 0;
|
private long lastPhoneGpsSent = 0;
|
||||||
|
|
||||||
protected void onWorkoutOpen(final boolean needsGps, final int activityKind) {
|
protected void onWorkoutOpen(final boolean needsGps, final ActivityKind activityKind) {
|
||||||
this.workoutNeedsGps = needsGps;
|
this.workoutNeedsGps = needsGps;
|
||||||
this.workoutActivityKind = activityKind;
|
this.workoutActivityKind = activityKind;
|
||||||
|
|
||||||
|
@ -46,31 +46,31 @@ public enum HuamiWorkoutTrackActivityType {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int toActivityKind() {
|
public ActivityKind toActivityKind() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case Elliptical:
|
case Elliptical:
|
||||||
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
|
return ActivityKind.ELLIPTICAL_TRAINER;
|
||||||
case IndoorCycling:
|
case IndoorCycling:
|
||||||
return ActivityKind.TYPE_INDOOR_CYCLING;
|
return ActivityKind.INDOOR_CYCLING;
|
||||||
case JumpRope:
|
case JumpRope:
|
||||||
return ActivityKind.TYPE_JUMP_ROPING;
|
return ActivityKind.JUMP_ROPING;
|
||||||
case OutdoorCycling:
|
case OutdoorCycling:
|
||||||
return ActivityKind.TYPE_CYCLING;
|
return ActivityKind.CYCLING;
|
||||||
case OutdoorRunning:
|
case OutdoorRunning:
|
||||||
return ActivityKind.TYPE_RUNNING;
|
return ActivityKind.RUNNING;
|
||||||
case PoolSwimming:
|
case PoolSwimming:
|
||||||
return ActivityKind.TYPE_SWIMMING;
|
return ActivityKind.SWIMMING;
|
||||||
case RowingMachine:
|
case RowingMachine:
|
||||||
return ActivityKind.TYPE_ROWING_MACHINE;
|
return ActivityKind.ROWING_MACHINE;
|
||||||
case Treadmill:
|
case Treadmill:
|
||||||
return ActivityKind.TYPE_TREADMILL;
|
return ActivityKind.TREADMILL;
|
||||||
case Walking:
|
case Walking:
|
||||||
return ActivityKind.TYPE_WALKING;
|
return ActivityKind.WALKING;
|
||||||
case Yoga:
|
case Yoga:
|
||||||
return ActivityKind.TYPE_YOGA;
|
return ActivityKind.YOGA;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HuamiWorkoutTrackActivityType fromCode(final byte code) {
|
public static HuamiWorkoutTrackActivityType fromCode(final byte code) {
|
||||||
|
@ -99,23 +99,23 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
|
|||||||
final ActivityTrack track = detailsParser.parse(buffer.toByteArray());
|
final ActivityTrack track = detailsParser.parse(buffer.toByteArray());
|
||||||
final ActivityTrackExporter exporter = createExporter();
|
final ActivityTrackExporter exporter = createExporter();
|
||||||
final String trackType;
|
final String trackType;
|
||||||
switch (summary.getActivityKind()) {
|
switch (ActivityKind.fromCode(summary.getActivityKind())) {
|
||||||
case ActivityKind.TYPE_CYCLING:
|
case CYCLING:
|
||||||
trackType = getContext().getString(R.string.activity_type_biking);
|
trackType = getContext().getString(R.string.activity_type_biking);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_RUNNING:
|
case RUNNING:
|
||||||
trackType = getContext().getString(R.string.activity_type_running);
|
trackType = getContext().getString(R.string.activity_type_running);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_WALKING:
|
case WALKING:
|
||||||
trackType = getContext().getString(R.string.activity_type_walking);
|
trackType = getContext().getString(R.string.activity_type_walking);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_HIKING:
|
case HIKING:
|
||||||
trackType = getContext().getString(R.string.activity_type_hiking);
|
trackType = getContext().getString(R.string.activity_type_hiking);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_CLIMBING:
|
case CLIMBING:
|
||||||
trackType = getContext().getString(R.string.activity_type_climbing);
|
trackType = getContext().getString(R.string.activity_type_climbing);
|
||||||
break;
|
break;
|
||||||
case ActivityKind.TYPE_SWIMMING:
|
case SWIMMING:
|
||||||
trackType = getContext().getString(R.string.activity_type_swimming);
|
trackType = getContext().getString(R.string.activity_type_swimming);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -207,6 +207,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final File targetFolder = new File(FileUtils.getExternalFilesDir(), "rawDetails");
|
final File targetFolder = new File(FileUtils.getExternalFilesDir(), "rawDetails");
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
targetFolder.mkdirs();
|
targetFolder.mkdirs();
|
||||||
final File targetFile = new File(targetFolder, fileName);
|
final File targetFile = new File(targetFolder, fileName);
|
||||||
outputStream = new FileOutputStream(targetFile);
|
outputStream = new FileOutputStream(targetFile);
|
||||||
|
@ -159,55 +159,55 @@ public enum ZeppOsActivityType {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int toActivityKind() {
|
public ActivityKind toActivityKind() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case Badminton:
|
case Badminton:
|
||||||
return ActivityKind.TYPE_BADMINTON;
|
return ActivityKind.BADMINTON;
|
||||||
case Basketball:
|
case Basketball:
|
||||||
return ActivityKind.TYPE_BASKETBALL;
|
return ActivityKind.BASKETBALL;
|
||||||
case Cricket:
|
case Cricket:
|
||||||
return ActivityKind.TYPE_CRICKET;
|
return ActivityKind.CRICKET;
|
||||||
case Elliptical:
|
case Elliptical:
|
||||||
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
|
return ActivityKind.ELLIPTICAL_TRAINER;
|
||||||
case Freestyle:
|
case Freestyle:
|
||||||
case IndoorFitness:
|
case IndoorFitness:
|
||||||
return ActivityKind.TYPE_EXERCISE;
|
return ActivityKind.EXERCISE;
|
||||||
case IndoorCycling:
|
case IndoorCycling:
|
||||||
return ActivityKind.TYPE_INDOOR_CYCLING;
|
return ActivityKind.INDOOR_CYCLING;
|
||||||
case JumpRope:
|
case JumpRope:
|
||||||
return ActivityKind.TYPE_JUMP_ROPING;
|
return ActivityKind.JUMP_ROPING;
|
||||||
case OutdoorCycling:
|
case OutdoorCycling:
|
||||||
return ActivityKind.TYPE_CYCLING;
|
return ActivityKind.CYCLING;
|
||||||
case OutdoorHiking:
|
case OutdoorHiking:
|
||||||
return ActivityKind.TYPE_HIKING;
|
return ActivityKind.HIKING;
|
||||||
case OutdoorRunning:
|
case OutdoorRunning:
|
||||||
return ActivityKind.TYPE_RUNNING;
|
return ActivityKind.RUNNING;
|
||||||
case OutdoorSwimming:
|
case OutdoorSwimming:
|
||||||
return ActivityKind.TYPE_SWIMMING_OPENWATER;
|
return ActivityKind.SWIMMING_OPENWATER;
|
||||||
case PoolSwimming:
|
case PoolSwimming:
|
||||||
return ActivityKind.TYPE_SWIMMING;
|
return ActivityKind.SWIMMING;
|
||||||
case RockClimbing:
|
case RockClimbing:
|
||||||
return ActivityKind.TYPE_CLIMBING;
|
return ActivityKind.CLIMBING;
|
||||||
case Rowing:
|
case Rowing:
|
||||||
return ActivityKind.TYPE_ROWING_MACHINE;
|
return ActivityKind.ROWING_MACHINE;
|
||||||
case Soccer:
|
case Soccer:
|
||||||
return ActivityKind.TYPE_SOCCER;
|
return ActivityKind.SOCCER;
|
||||||
case TableTennis:
|
case TableTennis:
|
||||||
return ActivityKind.TYPE_PINGPONG;
|
return ActivityKind.PINGPONG;
|
||||||
case Treadmill:
|
case Treadmill:
|
||||||
return ActivityKind.TYPE_TREADMILL;
|
return ActivityKind.TREADMILL;
|
||||||
case Walking:
|
case Walking:
|
||||||
case RaceWalking:
|
case RaceWalking:
|
||||||
return ActivityKind.TYPE_WALKING;
|
return ActivityKind.WALKING;
|
||||||
case Strength:
|
case Strength:
|
||||||
return ActivityKind.TYPE_STRENGTH_TRAINING;
|
return ActivityKind.STRENGTH_TRAINING;
|
||||||
case Yoga:
|
case Yoga:
|
||||||
return ActivityKind.TYPE_YOGA;
|
return ActivityKind.YOGA;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.warn("Unmapped workout type {}", this);
|
LOG.warn("Unmapped workout type {}", this);
|
||||||
|
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ZeppOsActivityType fromCode(final byte code) {
|
public static ZeppOsActivityType fromCode(final byte code) {
|
||||||
|
@ -1409,11 +1409,11 @@ public class ZeppOsSupport extends HuamiSupport implements ZeppOsFileTransferSer
|
|||||||
case WORKOUT_CMD_APP_OPEN:
|
case WORKOUT_CMD_APP_OPEN:
|
||||||
final ZeppOsActivityType activityType = ZeppOsActivityType.fromCode(payload[3]);
|
final ZeppOsActivityType activityType = ZeppOsActivityType.fromCode(payload[3]);
|
||||||
final boolean workoutNeedsGps = (payload[2] == 1);
|
final boolean workoutNeedsGps = (payload[2] == 1);
|
||||||
final int activityKind;
|
final ActivityKind activityKind;
|
||||||
|
|
||||||
if (activityType == null) {
|
if (activityType == null) {
|
||||||
LOG.warn("Unknown workout activity type {}", String.format("0x%x", payload[3]));
|
LOG.warn("Unknown workout activity type {}", String.format("0x%x", payload[3]));
|
||||||
activityKind = ActivityKind.TYPE_UNKNOWN;
|
activityKind = ActivityKind.UNKNOWN;
|
||||||
} else {
|
} else {
|
||||||
activityKind = activityType.toActivityKind();
|
activityKind = activityType.toActivityKind();
|
||||||
}
|
}
|
||||||
|
@ -122,46 +122,46 @@ public class HuaweiWorkoutGbParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int huaweiTypeToGbType(byte huaweiType) {
|
public static ActivityKind huaweiTypeToGbType(byte huaweiType) {
|
||||||
int type = huaweiType & 0xFF;
|
int type = huaweiType & 0xFF;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 1:
|
case 1:
|
||||||
return ActivityKind.TYPE_RUNNING;
|
return ActivityKind.RUNNING;
|
||||||
case 2:
|
case 2:
|
||||||
case 13:
|
case 13:
|
||||||
return ActivityKind.TYPE_WALKING;
|
return ActivityKind.WALKING;
|
||||||
case 6:
|
case 6:
|
||||||
return ActivityKind.TYPE_SWIMMING;
|
return ActivityKind.SWIMMING;
|
||||||
case 3:
|
case 3:
|
||||||
return ActivityKind.TYPE_CYCLING;
|
return ActivityKind.CYCLING;
|
||||||
case 7:
|
case 7:
|
||||||
return ActivityKind.TYPE_INDOOR_CYCLING;
|
return ActivityKind.INDOOR_CYCLING;
|
||||||
case 129:
|
case 129:
|
||||||
return ActivityKind.TYPE_BADMINTON;
|
return ActivityKind.BADMINTON;
|
||||||
case 130:
|
case 130:
|
||||||
return ActivityKind.TYPE_EXERCISE; // TODO: Tennis
|
return ActivityKind.EXERCISE; // TODO: Tennis
|
||||||
case 131:
|
case 131:
|
||||||
return ActivityKind.TYPE_SOCCER;
|
return ActivityKind.SOCCER;
|
||||||
case 132:
|
case 132:
|
||||||
return ActivityKind.TYPE_BASKETBALL;
|
return ActivityKind.BASKETBALL;
|
||||||
case 133:
|
case 133:
|
||||||
return ActivityKind.TYPE_EXERCISE; // TODO: Volleyball
|
return ActivityKind.EXERCISE; // TODO: Volleyball
|
||||||
case 134:
|
case 134:
|
||||||
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
|
return ActivityKind.ELLIPTICAL_TRAINER;
|
||||||
case 135:
|
case 135:
|
||||||
return ActivityKind.TYPE_ROWING_MACHINE;
|
return ActivityKind.ROWING_MACHINE;
|
||||||
case 163:
|
case 163:
|
||||||
return ActivityKind.TYPE_EXERCISE; // TODO: Roller skating
|
return ActivityKind.EXERCISE; // TODO: Roller skating
|
||||||
case 173:
|
case 173:
|
||||||
return ActivityKind.TYPE_EXERCISE; // TODO: Laser tag
|
return ActivityKind.EXERCISE; // TODO: Laser tag
|
||||||
case 177:
|
case 177:
|
||||||
return ActivityKind.TYPE_EXERCISE; // TODO: stair climbing
|
return ActivityKind.EXERCISE; // TODO: stair climbing
|
||||||
case 196:
|
case 196:
|
||||||
return ActivityKind.TYPE_EXERCISE; // TODO: fishing
|
return ActivityKind.EXERCISE; // TODO: fishing
|
||||||
case 216:
|
case 216:
|
||||||
return ActivityKind.TYPE_EXERCISE; // TODO: motor racing
|
return ActivityKind.EXERCISE; // TODO: motor racing
|
||||||
default:
|
default:
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ public class HuaweiWorkoutGbParser {
|
|||||||
if (!duplicates.isEmpty())
|
if (!duplicates.isEmpty())
|
||||||
previous = duplicates.get(0);
|
previous = duplicates.get(0);
|
||||||
|
|
||||||
int type = huaweiTypeToGbType(summary.getType());
|
ActivityKind type = huaweiTypeToGbType(summary.getType());
|
||||||
|
|
||||||
JSONObject jsonObject = new JSONObject();
|
JSONObject jsonObject = new JSONObject();
|
||||||
|
|
||||||
@ -274,7 +274,7 @@ public class HuaweiWorkoutGbParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean unknownData = false;
|
boolean unknownData = false;
|
||||||
if (dataSamples.size() != 0) {
|
if (!dataSamples.isEmpty()) {
|
||||||
int speed = 0;
|
int speed = 0;
|
||||||
int speedCount = 0;
|
int speedCount = 0;
|
||||||
boolean stepRatePresent = false;
|
boolean stepRatePresent = false;
|
||||||
@ -712,7 +712,7 @@ public class HuaweiWorkoutGbParser {
|
|||||||
"Workout " + summary.getWorkoutNumber(),
|
"Workout " + summary.getWorkoutNumber(),
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
type,
|
type.getCode(),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
@ -729,7 +729,7 @@ public class HuaweiWorkoutGbParser {
|
|||||||
previous.getName(),
|
previous.getName(),
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
type,
|
type.getCode(),
|
||||||
previous.getBaseLongitude(),
|
previous.getBaseLongitude(),
|
||||||
previous.getBaseLatitude(),
|
previous.getBaseLatitude(),
|
||||||
previous.getBaseAltitude(),
|
previous.getBaseAltitude(),
|
||||||
|
@ -60,7 +60,7 @@ public class FetchActivityOperation extends AbstractID115Operation {
|
|||||||
outputStream.write(0x01);
|
outputStream.write(0x01);
|
||||||
outputStream.write(0x00);
|
outputStream.write(0x00);
|
||||||
outputStream.write(0x00);
|
outputStream.write(0x00);
|
||||||
byte cmd[] = outputStream.toByteArray();
|
byte[] cmd = outputStream.toByteArray();
|
||||||
|
|
||||||
expectedCmd = ID115Constants.CMD_KEY_FETCH_ACTIVITY_TODAY;
|
expectedCmd = ID115Constants.CMD_KEY_FETCH_ACTIVITY_TODAY;
|
||||||
expectedSeq = 1;
|
expectedSeq = 1;
|
||||||
@ -74,7 +74,7 @@ public class FetchActivityOperation extends AbstractID115Operation {
|
|||||||
@Override
|
@Override
|
||||||
void handleResponse(byte[] data) {
|
void handleResponse(byte[] data) {
|
||||||
if (!isOperationRunning()) {
|
if (!isOperationRunning()) {
|
||||||
LOG.error("ignoring notification because operation is not running. Data length: " + data.length);
|
LOG.error("ignoring notification because operation is not running. Data length: {}", data.length);
|
||||||
getSupport().logMessageContent(data);
|
getSupport().logMessageContent(data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@ public class FetchActivityOperation extends AbstractID115Operation {
|
|||||||
}
|
}
|
||||||
expectedSeq += 1;
|
expectedSeq += 1;
|
||||||
|
|
||||||
byte payload[] = new byte[data.length - 4];
|
byte[] payload = new byte[data.length - 4];
|
||||||
System.arraycopy(data, 4, payload, 0, payload.length);
|
System.arraycopy(data, 4, payload, 0, payload.length);
|
||||||
packets.add(payload);
|
packets.add(payload);
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ public class FetchActivityOperation extends AbstractID115Operation {
|
|||||||
ID115ActivitySample sample = parseSample(sampleData);
|
ID115ActivitySample sample = parseSample(sampleData);
|
||||||
if (sample != null) {
|
if (sample != null) {
|
||||||
sample.setTimestamp(ts);
|
sample.setTimestamp(ts);
|
||||||
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
|
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
samples.add(sample);
|
samples.add(sample);
|
||||||
}
|
}
|
||||||
ts += dt;
|
ts += dt;
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
/* Copyright (C) 2018-2024 Pavel Elagin
|
|
||||||
|
|
||||||
This file is part of Gadgetbridge.
|
|
||||||
|
|
||||||
Gadgetbridge is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU Affero General Public License as published
|
|
||||||
by the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Gadgetbridge is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU Affero General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.jyou;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @author Pavel Elagin <elagin.pasha@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|
||||||
|
|
||||||
public class JYouDataRecord {
|
|
||||||
public final static int TYPE_UNKNOWN = 0;
|
|
||||||
public final static int TYPE_SLEEP = 100;
|
|
||||||
public final static int TYPE_DAY_SUMMARY = 101;
|
|
||||||
public final static int TYPE_DAY_SLOT = 102;
|
|
||||||
public final static int TYPE_REALTIME = 103;
|
|
||||||
|
|
||||||
public int type = TYPE_UNKNOWN;
|
|
||||||
public int activityKind = ActivityKind.TYPE_UNKNOWN;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Time of this record in seconds
|
|
||||||
*/
|
|
||||||
public int timestamp;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Raw data as sent from the device
|
|
||||||
*/
|
|
||||||
public byte[] rawData;
|
|
||||||
|
|
||||||
protected JYouDataRecord(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected JYouDataRecord(byte[] data, int type){
|
|
||||||
this.rawData = data;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getRawData() {
|
|
||||||
|
|
||||||
return rawData;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RecordInterval {
|
|
||||||
/**
|
|
||||||
* Start time of this interval in seconds
|
|
||||||
*/
|
|
||||||
public int timestampFrom;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* End time of this interval in seconds
|
|
||||||
*/
|
|
||||||
public int timestampTo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type of activity {@link ActivityKind}
|
|
||||||
*/
|
|
||||||
public int activityKind;
|
|
||||||
|
|
||||||
RecordInterval(int timestampFrom, int timestampTo, int activityKind) {
|
|
||||||
this.timestampFrom = timestampFrom;
|
|
||||||
this.timestampTo = timestampTo;
|
|
||||||
this.activityKind = activityKind;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1633,7 +1633,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
sample.setTimestamp(tsWithOffset);
|
sample.setTimestamp(tsWithOffset);
|
||||||
sample.setProvider(provider);
|
sample.setProvider(provider);
|
||||||
sample.setRawIntensity(val);
|
sample.setRawIntensity(val);
|
||||||
sample.setRawKind(val == 0 ? ActivityKind.TYPE_DEEP_SLEEP : ActivityKind.TYPE_LIGHT_SLEEP);
|
sample.setRawKind((val == 0 ? ActivityKind.DEEP_SLEEP : ActivityKind.LIGHT_SLEEP).getCode());
|
||||||
samples.add(sample);
|
samples.add(sample);
|
||||||
overlayList.add(new WatchXPlusHealthActivityOverlay(sample.getTimestamp(), sample.getTimestamp()+300, sample.getRawKind(), sample.getDeviceId(), sample.getUserId(), sample.getRawWatchXPlusHealthData()));
|
overlayList.add(new WatchXPlusHealthActivityOverlay(sample.getTimestamp(), sample.getTimestamp()+300, sample.getRawKind(), sample.getDeviceId(), sample.getUserId(), sample.getRawWatchXPlusHealthData()));
|
||||||
}
|
}
|
||||||
@ -1655,7 +1655,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
sample.setTimestamp(tsWithOffset);
|
sample.setTimestamp(tsWithOffset);
|
||||||
sample.setHeartRate(val);
|
sample.setHeartRate(val);
|
||||||
sample.setProvider(provider);
|
sample.setProvider(provider);
|
||||||
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
|
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
samples.add(sample);
|
samples.add(sample);
|
||||||
}
|
}
|
||||||
provider.addGBActivitySamples(samples.toArray(new WatchXPlusActivitySample[0]));
|
provider.addGBActivitySamples(samples.toArray(new WatchXPlusActivitySample[0]));
|
||||||
@ -1777,7 +1777,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
WatchXPlusActivitySample sample = createSample(dbHandler, timestamp);
|
WatchXPlusActivitySample sample = createSample(dbHandler, timestamp);
|
||||||
sample.setTimestamp(timestamp);
|
sample.setTimestamp(timestamp);
|
||||||
// sample.setRawKind(record.type);
|
// sample.setRawKind(record.type);
|
||||||
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
|
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
sample.setSteps(newSteps);
|
sample.setSteps(newSteps);
|
||||||
// sample.setDistance(record.distance);
|
// sample.setDistance(record.distance);
|
||||||
// sample.setCalories(record.calories);
|
// sample.setCalories(record.calories);
|
||||||
@ -1846,7 +1846,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
timestamp, // ts
|
timestamp, // ts
|
||||||
deviceId, userId, // User id
|
deviceId, userId, // User id
|
||||||
null, // Raw Data
|
null, // Raw Data
|
||||||
ActivityKind.TYPE_UNKNOWN, // rawKind
|
ActivityKind.UNKNOWN.getCode(), // rawKind
|
||||||
ActivitySample.NOT_MEASURED, // rawIntensity
|
ActivitySample.NOT_MEASURED, // rawIntensity
|
||||||
ActivitySample.NOT_MEASURED, // Steps
|
ActivitySample.NOT_MEASURED, // Steps
|
||||||
ActivitySample.NOT_MEASURED, // HR
|
ActivitySample.NOT_MEASURED, // HR
|
||||||
|
@ -580,12 +580,12 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
|
|||||||
if (heartRate > 0) {
|
if (heartRate > 0) {
|
||||||
sample.setHeartRate(heartRate);
|
sample.setHeartRate(heartRate);
|
||||||
sample.setTimestamp((int) (System.currentTimeMillis() / 1000));
|
sample.setTimestamp((int) (System.currentTimeMillis() / 1000));
|
||||||
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
|
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
} else {
|
} else {
|
||||||
if (heartRate == MakibesHR3Constants.ARG_HEARTRATE_NO_TARGET) {
|
if (heartRate == MakibesHR3Constants.ARG_HEARTRATE_NO_TARGET) {
|
||||||
sample.setRawKind(ActivityKind.TYPE_NOT_WORN);
|
sample.setRawKind(ActivityKind.NOT_WORN.getCode());
|
||||||
} else if (heartRate == MakibesHR3Constants.ARG_HEARTRATE_NO_READING) {
|
} else if (heartRate == MakibesHR3Constants.ARG_HEARTRATE_NO_READING) {
|
||||||
sample.setRawKind(ActivityKind.TYPE_NOT_MEASURED);
|
sample.setRawKind(ActivityKind.NOT_MEASURED.getCode());
|
||||||
} else {
|
} else {
|
||||||
LOG.warn("invalid heart rate reading: " + heartRate);
|
LOG.warn("invalid heart rate reading: " + heartRate);
|
||||||
return;
|
return;
|
||||||
@ -608,7 +608,7 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
|
|||||||
sample.setHeartRate(heartRate);
|
sample.setHeartRate(heartRate);
|
||||||
sample.setTimestamp(timeStamp);
|
sample.setTimestamp(timeStamp);
|
||||||
|
|
||||||
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
|
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
|
|
||||||
this.addGBActivitySample(sample);
|
this.addGBActivitySample(sample);
|
||||||
}
|
}
|
||||||
@ -622,12 +622,12 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
|
|||||||
int newSteps = (steps - dayStepCount);
|
int newSteps = (steps - dayStepCount);
|
||||||
|
|
||||||
if (newSteps > 0) {
|
if (newSteps > 0) {
|
||||||
LOG.debug("adding " + newSteps + " steps");
|
LOG.debug("adding {} steps", newSteps);
|
||||||
|
|
||||||
sample.setSteps(steps - dayStepCount);
|
sample.setSteps(steps - dayStepCount);
|
||||||
sample.setTimestamp(timeStamp);
|
sample.setTimestamp(timeStamp);
|
||||||
|
|
||||||
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
|
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
|
|
||||||
this.addGBActivitySample(sample);
|
this.addGBActivitySample(sample);
|
||||||
}
|
}
|
||||||
@ -637,7 +637,7 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
|
|||||||
* The time is the start of the measurement. Each measurement lasts 1h.
|
* The time is the start of the measurement. Each measurement lasts 1h.
|
||||||
*/
|
*/
|
||||||
private void onReceiveStepsSample(int year, int month, int day, int hour, int minute, int steps) {
|
private void onReceiveStepsSample(int year, int month, int day, int hour, int minute, int steps) {
|
||||||
LOG.debug("received steps sample " + year + "-" + month + "-" + day + " " + hour + ":" + minute + " " + steps);
|
LOG.debug("received steps sample {}-{}-{} {}:{} {}", year, month, day, hour, minute, steps);
|
||||||
|
|
||||||
Calendar calendar = new GregorianCalendar(year, month - 1, day, hour + 1, minute);
|
Calendar calendar = new GregorianCalendar(year, month - 1, day, hour + 1, minute);
|
||||||
|
|
||||||
|
@ -484,7 +484,7 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
private void handleActivityData(byte[] data) {
|
private void handleActivityData(byte[] data) {
|
||||||
if (data[1] == (byte) 0xfd) {
|
if (data[1] == (byte) 0xfd) {
|
||||||
LOG.info("CRC received: " + (data[2] & 0xff) + ", calculated: " + (crc & 0xff));
|
LOG.info("CRC received: {}, calculated: {}", data[2] & 0xff, crc & 0xff);
|
||||||
if (data[2] != crc) {
|
if (data[2] != crc) {
|
||||||
GB.toast(getContext(), "Incorrect CRC. Try fetching data again.", Toast.LENGTH_LONG, GB.ERROR);
|
GB.toast(getContext(), "Incorrect CRC. Try fetching data again.", Toast.LENGTH_LONG, GB.ERROR);
|
||||||
GB.updateTransferNotification(null,"Data transfer failed", false, 0, getContext());
|
GB.updateTransferNotification(null,"Data transfer failed", false, 0, getContext());
|
||||||
@ -492,7 +492,7 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
|
|||||||
getDevice().unsetBusyTask();
|
getDevice().unsetBusyTask();
|
||||||
getDevice().sendDeviceUpdateIntent(getContext());
|
getDevice().sendDeviceUpdateIntent(getContext());
|
||||||
}
|
}
|
||||||
} else if (samples.size() > 0) {
|
} else if (!samples.isEmpty()) {
|
||||||
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
||||||
Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId();
|
Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId();
|
||||||
Long deviceId = DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId();
|
Long deviceId = DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId();
|
||||||
@ -501,13 +501,13 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
|
|||||||
samples.get(i).setDeviceId(deviceId);
|
samples.get(i).setDeviceId(deviceId);
|
||||||
samples.get(i).setUserId(userId);
|
samples.get(i).setUserId(userId);
|
||||||
if (data[0] == No1F1Constants.CMD_FETCH_STEPS) {
|
if (data[0] == No1F1Constants.CMD_FETCH_STEPS) {
|
||||||
samples.get(i).setRawKind(ActivityKind.TYPE_ACTIVITY);
|
samples.get(i).setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
samples.get(i).setRawIntensity(samples.get(i).getSteps());
|
samples.get(i).setRawIntensity(samples.get(i).getSteps());
|
||||||
} else if (data[0] == No1F1Constants.CMD_FETCH_SLEEP) {
|
} else if (data[0] == No1F1Constants.CMD_FETCH_SLEEP) {
|
||||||
if (samples.get(i).getRawIntensity() < 7)
|
if (samples.get(i).getRawIntensity() < 7)
|
||||||
samples.get(i).setRawKind(ActivityKind.TYPE_DEEP_SLEEP);
|
samples.get(i).setRawKind(ActivityKind.DEEP_SLEEP.getCode());
|
||||||
else
|
else
|
||||||
samples.get(i).setRawKind(ActivityKind.TYPE_LIGHT_SLEEP);
|
samples.get(i).setRawKind(ActivityKind.LIGHT_SLEEP.getCode());
|
||||||
}
|
}
|
||||||
provider.addGBActivitySample(samples.get(i));
|
provider.addGBActivitySample(samples.get(i));
|
||||||
}
|
}
|
||||||
@ -542,15 +542,18 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
|
|||||||
if (data[0] == No1F1Constants.CMD_FETCH_STEPS) {
|
if (data[0] == No1F1Constants.CMD_FETCH_STEPS) {
|
||||||
timestamp.set(Calendar.MINUTE, 0);
|
timestamp.set(Calendar.MINUTE, 0);
|
||||||
sample.setSteps(data[6] * 256 + (data[7] & 0xff));
|
sample.setSteps(data[6] * 256 + (data[7] & 0xff));
|
||||||
|
//noinspection lossy-conversions
|
||||||
crc ^= (data[6] ^ data[7]);
|
crc ^= (data[6] ^ data[7]);
|
||||||
} else if (data[0] == No1F1Constants.CMD_FETCH_SLEEP) {
|
} else if (data[0] == No1F1Constants.CMD_FETCH_SLEEP) {
|
||||||
timestamp.set(Calendar.MINUTE, data[6] & 0xff);
|
timestamp.set(Calendar.MINUTE, data[6] & 0xff);
|
||||||
sample.setRawIntensity(data[7] * 256 + (data[8] & 0xff));
|
sample.setRawIntensity(data[7] * 256 + (data[8] & 0xff));
|
||||||
|
//noinspection lossy-conversions
|
||||||
crc ^= (data[7] ^ data[8]);
|
crc ^= (data[7] ^ data[8]);
|
||||||
startProgress = 33;
|
startProgress = 33;
|
||||||
} else if (data[0] == No1F1Constants.CMD_FETCH_HEARTRATE) {
|
} else if (data[0] == No1F1Constants.CMD_FETCH_HEARTRATE) {
|
||||||
timestamp.set(Calendar.MINUTE, data[6] & 0xff);
|
timestamp.set(Calendar.MINUTE, data[6] & 0xff);
|
||||||
sample.setHeartRate(data[7] & 0xff);
|
sample.setHeartRate(data[7] & 0xff);
|
||||||
|
//noinspection lossy-conversions
|
||||||
crc ^= (data[6] ^ data[7]);
|
crc ^= (data[6] ^ data[7]);
|
||||||
startProgress = 66;
|
startProgress = 66;
|
||||||
}
|
}
|
||||||
|
@ -1126,7 +1126,7 @@ public class PineTimeJFSupport extends AbstractBTLEDeviceSupport implements DfuL
|
|||||||
sample.setTimestamp(timeStamp);
|
sample.setTimestamp(timeStamp);
|
||||||
|
|
||||||
// since it's a local timestamp, it should NOT be treated as Activity because it will spoil activity charts
|
// since it's a local timestamp, it should NOT be treated as Activity because it will spoil activity charts
|
||||||
sample.setRawKind(ActivityKind.TYPE_UNKNOWN);
|
sample.setRawKind(ActivityKind.UNKNOWN.getCode());
|
||||||
|
|
||||||
this.addGBActivitySample(sample);
|
this.addGBActivitySample(sample);
|
||||||
|
|
||||||
@ -1152,7 +1152,7 @@ public class PineTimeJFSupport extends AbstractBTLEDeviceSupport implements DfuL
|
|||||||
sample.setHeartRate(heartrate);
|
sample.setHeartRate(heartrate);
|
||||||
sample.setTimestamp(timeStamp);
|
sample.setTimestamp(timeStamp);
|
||||||
// since it's a local timestamp, it should NOT be treated as Activity because it will spoil activity charts
|
// since it's a local timestamp, it should NOT be treated as Activity because it will spoil activity charts
|
||||||
sample.setRawKind(ActivityKind.TYPE_UNKNOWN);
|
sample.setRawKind(ActivityKind.UNKNOWN.getCode());
|
||||||
|
|
||||||
this.addGBActivitySample(sample);
|
this.addGBActivitySample(sample);
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
@ -35,7 +34,7 @@ public class ActivityEntry {
|
|||||||
public WEARING_STATE wearingState;
|
public WEARING_STATE wearingState;
|
||||||
|
|
||||||
public HybridHRActivitySample toDAOActivitySample(long userId, long deviceId) {
|
public HybridHRActivitySample toDAOActivitySample(long userId, long deviceId) {
|
||||||
HybridHRActivitySample sample = new HybridHRActivitySample(
|
return new HybridHRActivitySample(
|
||||||
timestamp,
|
timestamp,
|
||||||
deviceId,
|
deviceId,
|
||||||
userId,
|
userId,
|
||||||
@ -48,24 +47,22 @@ public class ActivityEntry {
|
|||||||
wearingState.value,
|
wearingState.value,
|
||||||
heartRate
|
heartRate
|
||||||
);
|
);
|
||||||
|
|
||||||
return sample;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum WEARING_STATE{
|
public enum WEARING_STATE{
|
||||||
WEARING((byte) 0, ActivityKind.TYPE_NOT_MEASURED),
|
WEARING((byte) 0, ActivityKind.NOT_MEASURED),
|
||||||
NOT_WEARING((byte) 1, ActivityKind.TYPE_NOT_WORN),
|
NOT_WEARING((byte) 1, ActivityKind.NOT_WORN),
|
||||||
UNKNOWN((byte) 2, ActivityKind.TYPE_UNKNOWN);
|
UNKNOWN((byte) 2, ActivityKind.UNKNOWN);
|
||||||
|
|
||||||
byte value;
|
final byte value;
|
||||||
int activityKind;
|
final ActivityKind activityKind;
|
||||||
|
|
||||||
WEARING_STATE(byte value, int activityKind){
|
WEARING_STATE(byte value, ActivityKind activityKind){
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.activityKind = activityKind;
|
this.activityKind = activityKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getActivityKind() {
|
public ActivityKind getActivityKind() {
|
||||||
return activityKind;
|
return activityKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,19 +43,15 @@ public class WorkoutRequestHandler {
|
|||||||
JSONObject workoutResponse = new JSONObject();
|
JSONObject workoutResponse = new JSONObject();
|
||||||
if (workoutRequest.optString("state").equals("started") && workoutRequest.optString("gps").equals("on")) {
|
if (workoutRequest.optString("state").equals("started") && workoutRequest.optString("gps").equals("on")) {
|
||||||
int activityType = workoutRequest.optInt("activity", -1);
|
int activityType = workoutRequest.optInt("activity", -1);
|
||||||
final int activityKind;
|
final ActivityKind activityKind = QHybridConstants.WORKOUT_TYPES_TO_ACTIVITY_KIND.getOrDefault(activityType, ActivityKind.UNKNOWN);
|
||||||
if (QHybridConstants.WORKOUT_TYPES_TO_ACTIVITY_KIND.containsKey(activityType)) {
|
LOG.info("Workout started, activity type is {}/{}", activityType, activityKind);
|
||||||
activityKind = QHybridConstants.WORKOUT_TYPES_TO_ACTIVITY_KIND.get(activityType);
|
|
||||||
} else {
|
|
||||||
activityKind = ActivityKind.TYPE_UNKNOWN;
|
|
||||||
}
|
|
||||||
LOG.info("Workout started, activity type is " + activityType + "/" + activityKind);
|
|
||||||
addStateResponse(workoutResponse, "success", "");
|
addStateResponse(workoutResponse, "success", "");
|
||||||
|
//noinspection DataFlowIssue fp, never null
|
||||||
OpenTracksController.startRecording(context, activityKind);
|
OpenTracksController.startRecording(context, activityKind);
|
||||||
} else if (workoutRequest.optString("type").equals("req_distance")) {
|
} else if (workoutRequest.optString("type").equals("req_distance")) {
|
||||||
long timeSecs = Math.round(GBApplication.app().getOpenTracksObserver().getTimeMillisChange() / 1000f);
|
long timeSecs = Math.round(GBApplication.app().getOpenTracksObserver().getTimeMillisChange() / 1000f);
|
||||||
float distanceCM = GBApplication.app().getOpenTracksObserver().getDistanceMeterChange() * 100;
|
float distanceCM = GBApplication.app().getOpenTracksObserver().getDistanceMeterChange() * 100;
|
||||||
LOG.info("Workout distance requested, returning " + distanceCM + " cm, " + timeSecs + " sec");
|
LOG.info("Workout distance requested, returning {} cm, {} sec", distanceCM, timeSecs);
|
||||||
workoutResponse.put("workoutApp._.config.gps", new JSONObject()
|
workoutResponse.put("workoutApp._.config.gps", new JSONObject()
|
||||||
.put("distance", distanceCM)
|
.put("distance", distanceCM)
|
||||||
.put("duration", timeSecs)
|
.put("duration", timeSecs)
|
||||||
|
@ -19,7 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.tlw64;
|
|||||||
|
|
||||||
import android.bluetooth.BluetoothGatt;
|
import android.bluetooth.BluetoothGatt;
|
||||||
import android.bluetooth.BluetoothGattCharacteristic;
|
import android.bluetooth.BluetoothGattCharacteristic;
|
||||||
import android.net.Uri;
|
|
||||||
import android.text.format.DateFormat;
|
import android.text.format.DateFormat;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@ -49,13 +48,8 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceBusyAction;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceBusyAction;
|
||||||
@ -514,7 +508,7 @@ public class TLW64Support extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
private void handleActivityData(byte[] data) {
|
private void handleActivityData(byte[] data) {
|
||||||
if (data[1] == (byte) 0xfd) {
|
if (data[1] == (byte) 0xfd) {
|
||||||
LOG.info("CRC received: " + (data[2] & 0xff) + ", calculated: " + (crc & 0xff));
|
LOG.info("CRC received: {}, calculated: {}", data[2] & 0xff, crc & 0xff);
|
||||||
if (data[2] != crc) {
|
if (data[2] != crc) {
|
||||||
GB.toast(getContext(), "Incorrect CRC. Try fetching data again.", Toast.LENGTH_LONG, GB.ERROR);
|
GB.toast(getContext(), "Incorrect CRC. Try fetching data again.", Toast.LENGTH_LONG, GB.ERROR);
|
||||||
GB.updateTransferNotification(null, "Data transfer failed", false, 0, getContext());
|
GB.updateTransferNotification(null, "Data transfer failed", false, 0, getContext());
|
||||||
@ -522,7 +516,7 @@ public class TLW64Support extends AbstractBTLEDeviceSupport {
|
|||||||
getDevice().unsetBusyTask();
|
getDevice().unsetBusyTask();
|
||||||
getDevice().sendDeviceUpdateIntent(getContext());
|
getDevice().sendDeviceUpdateIntent(getContext());
|
||||||
}
|
}
|
||||||
} else if (samples.size() > 0) {
|
} else if (!samples.isEmpty()) {
|
||||||
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
try (DBHandler dbHandler = GBApplication.acquireDB()) {
|
||||||
Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId();
|
Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId();
|
||||||
Long deviceId = DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId();
|
Long deviceId = DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId();
|
||||||
@ -531,13 +525,13 @@ public class TLW64Support extends AbstractBTLEDeviceSupport {
|
|||||||
samples.get(i).setDeviceId(deviceId);
|
samples.get(i).setDeviceId(deviceId);
|
||||||
samples.get(i).setUserId(userId);
|
samples.get(i).setUserId(userId);
|
||||||
if (data[0] == TLW64Constants.CMD_FETCH_STEPS) {
|
if (data[0] == TLW64Constants.CMD_FETCH_STEPS) {
|
||||||
samples.get(i).setRawKind(ActivityKind.TYPE_ACTIVITY);
|
samples.get(i).setRawKind(ActivityKind.ACTIVITY.getCode());
|
||||||
samples.get(i).setRawIntensity(samples.get(i).getSteps());
|
samples.get(i).setRawIntensity(samples.get(i).getSteps());
|
||||||
} else if (data[0] == TLW64Constants.CMD_FETCH_SLEEP) {
|
} else if (data[0] == TLW64Constants.CMD_FETCH_SLEEP) {
|
||||||
if (samples.get(i).getRawIntensity() < 7) {
|
if (samples.get(i).getRawIntensity() < 7) {
|
||||||
samples.get(i).setRawKind(ActivityKind.TYPE_DEEP_SLEEP);
|
samples.get(i).setRawKind(ActivityKind.DEEP_SLEEP.getCode());
|
||||||
} else
|
} else
|
||||||
samples.get(i).setRawKind(ActivityKind.TYPE_LIGHT_SLEEP);
|
samples.get(i).setRawKind(ActivityKind.LIGHT_SLEEP.getCode());
|
||||||
}
|
}
|
||||||
provider.addGBActivitySample(samples.get(i));
|
provider.addGBActivitySample(samples.get(i));
|
||||||
}
|
}
|
||||||
@ -571,10 +565,12 @@ public class TLW64Support extends AbstractBTLEDeviceSupport {
|
|||||||
if (data[0] == TLW64Constants.CMD_FETCH_STEPS) {
|
if (data[0] == TLW64Constants.CMD_FETCH_STEPS) {
|
||||||
timestamp.set(Calendar.MINUTE, 0);
|
timestamp.set(Calendar.MINUTE, 0);
|
||||||
sample.setSteps(data[6] * 256 + (data[7] & 0xff));
|
sample.setSteps(data[6] * 256 + (data[7] & 0xff));
|
||||||
|
//noinspection lossy-conversions
|
||||||
crc ^= (data[6] ^ data[7]);
|
crc ^= (data[6] ^ data[7]);
|
||||||
} else if (data[0] == TLW64Constants.CMD_FETCH_SLEEP) {
|
} else if (data[0] == TLW64Constants.CMD_FETCH_SLEEP) {
|
||||||
timestamp.set(Calendar.MINUTE, data[6] & 0xff);
|
timestamp.set(Calendar.MINUTE, data[6] & 0xff);
|
||||||
sample.setRawIntensity(data[7] * 256 + (data[8] & 0xff));
|
sample.setRawIntensity(data[7] * 256 + (data[8] & 0xff));
|
||||||
|
//noinspection lossy-conversions
|
||||||
crc ^= (data[7] ^ data[8]);
|
crc ^= (data[7] ^ data[8]);
|
||||||
startProgress = 33;
|
startProgress = 33;
|
||||||
}
|
}
|
||||||
|
@ -699,7 +699,7 @@ public class WithingsSteelHRDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
message.addDataStructure(imageMetaData);
|
message.addDataStructure(imageMetaData);
|
||||||
|
|
||||||
ImageData imageData = new ImageData();
|
ImageData imageData = new ImageData();
|
||||||
final int drawableId = ActivityKind.getIconId(withingsActivityType.toActivityKind());
|
final int drawableId = withingsActivityType.toActivityKind().getIcon();
|
||||||
Drawable drawable = getContext().getDrawable(drawableId);
|
Drawable drawable = getContext().getDrawable(drawableId);
|
||||||
imageData.setImageData(IconHelper.getIconBytesFromDrawable(drawable));
|
imageData.setImageData(IconHelper.getIconBytesFromDrawable(drawable));
|
||||||
message.addDataStructure(imageData);
|
message.addDataStructure(imageData);
|
||||||
@ -719,7 +719,7 @@ public class WithingsSteelHRDeviceSupport extends AbstractBTLEDeviceSupport {
|
|||||||
String localeString = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress())
|
String localeString = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress())
|
||||||
.getString(PREF_LANGUAGE, PREF_LANGUAGE_AUTO);
|
.getString(PREF_LANGUAGE, PREF_LANGUAGE_AUTO);
|
||||||
|
|
||||||
if (localeString == null || localeString.equals(PREF_LANGUAGE_AUTO)) {
|
if (localeString.equals(PREF_LANGUAGE_AUTO)) {
|
||||||
localeString = java.util.Locale.getDefault().getLanguage();
|
localeString = java.util.Locale.getDefault().getLanguage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,6 @@
|
|||||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.withingssteelhr.activity;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.withingssteelhr.activity;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.withingssteelhr.WithingsSteelHRSampleProvider;
|
import nodomain.freeyourgadget.gadgetbridge.devices.withingssteelhr.WithingsSteelHRSampleProvider;
|
||||||
@ -30,10 +27,6 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
|||||||
* This leads to breaking the sleep session in the sleep calculation of GB.
|
* This leads to breaking the sleep session in the sleep calculation of GB.
|
||||||
*/
|
*/
|
||||||
public class SleepActivitySampleHelper {
|
public class SleepActivitySampleHelper {
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(SleepActivitySampleHelper.class);
|
|
||||||
private static int mergeCount;
|
|
||||||
|
|
||||||
public static WithingsSteelHRActivitySample mergeIfNecessary(WithingsSteelHRSampleProvider provider, WithingsSteelHRActivitySample sample) {
|
public static WithingsSteelHRActivitySample mergeIfNecessary(WithingsSteelHRSampleProvider provider, WithingsSteelHRActivitySample sample) {
|
||||||
if (!shouldMerge(sample)) {
|
if (!shouldMerge(sample)) {
|
||||||
return sample;
|
return sample;
|
||||||
@ -55,7 +48,7 @@ public class SleepActivitySampleHelper {
|
|||||||
|
|
||||||
for (int i = samples.size()-1; i >= 0; i--) {
|
for (int i = samples.size()-1; i >= 0; i--) {
|
||||||
WithingsSteelHRActivitySample lastSample = samples.get(i);
|
WithingsSteelHRActivitySample lastSample = samples.get(i);
|
||||||
if (isNotHeartRateOnly(lastSample, (int) timestamp)) {
|
if (isNotHeartRateOnly(lastSample)) {
|
||||||
return lastSample;
|
return lastSample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,8 +56,8 @@ public class SleepActivitySampleHelper {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNotHeartRateOnly(WithingsSteelHRActivitySample lastSample, int timestamp) {
|
private static boolean isNotHeartRateOnly(WithingsSteelHRActivitySample lastSample) {
|
||||||
return lastSample.getRawKind() != ActivityKind.TYPE_NOT_MEASURED; // && lastSample.getTimestamp() <= timestamp && (lastSample.getTimestamp() + lastSample.getDuration()) >= timestamp);
|
return lastSample.getRawKind() != ActivityKind.NOT_MEASURED.getCode(); // && lastSample.getTimestamp() <= timestamp && (lastSample.getTimestamp() + lastSample.getDuration()) >= timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean shouldMerge(WithingsSteelHRActivitySample sample) {
|
private static boolean shouldMerge(WithingsSteelHRActivitySample sample) {
|
||||||
|
@ -61,7 +61,7 @@ public enum WithingsActivityType {
|
|||||||
RIDING(26),
|
RIDING(26),
|
||||||
OTHER(36);
|
OTHER(36);
|
||||||
|
|
||||||
private int code;
|
private final int code;
|
||||||
|
|
||||||
WithingsActivityType(int typeCode) {
|
WithingsActivityType(int typeCode) {
|
||||||
this.code = typeCode;
|
this.code = typeCode;
|
||||||
@ -80,80 +80,80 @@ public enum WithingsActivityType {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int toActivityKind() {
|
public ActivityKind toActivityKind() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case WALKING:
|
case WALKING:
|
||||||
return ActivityKind.TYPE_WALKING;
|
return ActivityKind.WALKING;
|
||||||
case RUNNING:
|
case RUNNING:
|
||||||
return ActivityKind.TYPE_RUNNING;
|
return ActivityKind.RUNNING;
|
||||||
case HIKING:
|
case HIKING:
|
||||||
return ActivityKind.TYPE_HIKING;
|
return ActivityKind.HIKING;
|
||||||
case BIKING:
|
case BIKING:
|
||||||
return ActivityKind.TYPE_CYCLING;
|
return ActivityKind.CYCLING;
|
||||||
case SWIMMING:
|
case SWIMMING:
|
||||||
return ActivityKind.TYPE_SWIMMING;
|
return ActivityKind.SWIMMING;
|
||||||
case SURFING:
|
case SURFING:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case KITESURFING:
|
case KITESURFING:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case WINDSURFING:
|
case WINDSURFING:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case TENNIS:
|
case TENNIS:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case PINGPONG:
|
case PINGPONG:
|
||||||
return ActivityKind.TYPE_PINGPONG;
|
return ActivityKind.PINGPONG;
|
||||||
case SQUASH:
|
case SQUASH:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case BADMINTON:
|
case BADMINTON:
|
||||||
return ActivityKind.TYPE_BADMINTON;
|
return ActivityKind.BADMINTON;
|
||||||
case WEIGHTLIFTING:
|
case WEIGHTLIFTING:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case GYMNASTICS:
|
case GYMNASTICS:
|
||||||
return ActivityKind.TYPE_EXERCISE;
|
return ActivityKind.EXERCISE;
|
||||||
case ELLIPTICAL:
|
case ELLIPTICAL:
|
||||||
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
|
return ActivityKind.ELLIPTICAL_TRAINER;
|
||||||
case PILATES:
|
case PILATES:
|
||||||
return ActivityKind.TYPE_YOGA;
|
return ActivityKind.YOGA;
|
||||||
case BASKETBALL:
|
case BASKETBALL:
|
||||||
return ActivityKind.TYPE_BASKETBALL;
|
return ActivityKind.BASKETBALL;
|
||||||
case SOCCER:
|
case SOCCER:
|
||||||
return ActivityKind.TYPE_SOCCER;
|
return ActivityKind.SOCCER;
|
||||||
case FOOTBALL:
|
case FOOTBALL:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case RUGBY:
|
case RUGBY:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case VOLLEYBALL:
|
case VOLLEYBALL:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case GOLFING:
|
case GOLFING:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case YOGA:
|
case YOGA:
|
||||||
return ActivityKind.TYPE_YOGA;
|
return ActivityKind.YOGA;
|
||||||
case DANCING:
|
case DANCING:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case BOXING:
|
case BOXING:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case SKIING:
|
case SKIING:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case SNOWBOARDING:
|
case SNOWBOARDING:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case ROWING:
|
case ROWING:
|
||||||
return ActivityKind.TYPE_ROWING_MACHINE;
|
return ActivityKind.ROWING_MACHINE;
|
||||||
case ZUMBA:
|
case ZUMBA:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case BASEBALL:
|
case BASEBALL:
|
||||||
return ActivityKind.TYPE_CRICKET;
|
return ActivityKind.CRICKET;
|
||||||
case HANDBALL:
|
case HANDBALL:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case HOCKEY:
|
case HOCKEY:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case ICEHOCKEY:
|
case ICEHOCKEY:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
case CLIMBING:
|
case CLIMBING:
|
||||||
return ActivityKind.TYPE_CLIMBING;
|
return ActivityKind.CLIMBING;
|
||||||
case ICESKATING:
|
case ICESKATING:
|
||||||
return ActivityKind.TYPE_ACTIVITY;
|
return ActivityKind.ACTIVITY;
|
||||||
default:
|
default:
|
||||||
return ActivityKind.TYPE_UNKNOWN;
|
return ActivityKind.UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ public class ActivitySampleHandler extends AbstractResponseHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void handleResponse(Message response) {
|
public void handleResponse(Message response) {
|
||||||
List<WithingsStructure> data = response.getDataStructures();
|
List<WithingsStructure> data = response.getDataStructures();
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
handleActivityData(data, response.getType());
|
handleActivityData(data, response.getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ public class ActivitySampleHandler extends AbstractResponseHandler {
|
|||||||
handleWorkoutType(data);
|
handleWorkoutType(data);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logger.info("Received yet unhandled activity data of type '" + data.getType() + "' with data '" + GB.hexdump(data.getRawData()) + "'.");
|
logger.info("Received yet unhandled activity data of type '{}' with data '{}'.", data.getType(), GB.hexdump(data.getRawData()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,71 +123,71 @@ public class ActivitySampleHandler extends AbstractResponseHandler {
|
|||||||
|
|
||||||
activityEntry = new ActivityEntry();
|
activityEntry = new ActivityEntry();
|
||||||
activityEntry.setIsHeartrate(activityType == WithingsMessageType.GET_HEARTRATE_SAMPLES);
|
activityEntry.setIsHeartrate(activityType == WithingsMessageType.GET_HEARTRATE_SAMPLES);
|
||||||
activityEntry.setTimestamp((int)(((ActivitySampleTime)data).getDate().getTime()/1000));
|
activityEntry.setTimestamp((int) (((ActivitySampleTime) data).getDate().getTime() / 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleWorkoutType(WithingsStructure data) {
|
private void handleWorkoutType(WithingsStructure data) {
|
||||||
WithingsActivityType activityType = WithingsActivityType.fromCode(((WorkoutType)data).getActivityType());
|
WithingsActivityType activityType = WithingsActivityType.fromCode(((WorkoutType) data).getActivityType());
|
||||||
activityEntry.setRawKind(activityType.toActivityKind());
|
activityEntry.setRawKind(activityType.toActivityKind().getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleDuration(WithingsStructure data) {
|
private void handleDuration(WithingsStructure data) {
|
||||||
activityEntry.setDuration(((ActivitySampleDuration)data).getDuration());
|
activityEntry.setDuration(((ActivitySampleDuration) data).getDuration());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleHeartrate(WithingsStructure data) {
|
private void handleHeartrate(WithingsStructure data) {
|
||||||
activityEntry.setIsHeartrate(((ActivityHeartrate)data).getHeartrate());
|
activityEntry.setIsHeartrate(((ActivityHeartrate) data).getHeartrate());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleMovement(WithingsStructure data) {
|
private void handleMovement(WithingsStructure data) {
|
||||||
activityEntry.setRawKind(ActivityKind.TYPE_UNKNOWN);
|
activityEntry.setRawKind(ActivityKind.UNKNOWN.getCode());
|
||||||
activityEntry.setSteps(((ActivitySampleMovement)data).getSteps());
|
activityEntry.setSteps(((ActivitySampleMovement) data).getSteps());
|
||||||
activityEntry.setDistance(((ActivitySampleMovement)data).getDistance());
|
activityEntry.setDistance(((ActivitySampleMovement) data).getDistance());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleWalk(WithingsStructure data) {
|
private void handleWalk(WithingsStructure data) {
|
||||||
activityEntry.setRawKind(ActivityKind.TYPE_WALKING);
|
activityEntry.setRawKind(ActivityKind.WALKING.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleRun(WithingsStructure data) {
|
private void handleRun(WithingsStructure data) {
|
||||||
activityEntry.setRawKind(ActivityKind.TYPE_RUNNING);
|
activityEntry.setRawKind(ActivityKind.RUNNING.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSwim(WithingsStructure data) {
|
private void handleSwim(WithingsStructure data) {
|
||||||
activityEntry.setRawKind(ActivityKind.TYPE_SWIMMING);
|
activityEntry.setRawKind(ActivityKind.SWIMMING.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSleep(WithingsStructure data) {
|
private void handleSleep(WithingsStructure data) {
|
||||||
int sleepType;
|
ActivityKind sleepType;
|
||||||
switch (((ActivitySampleSleep)data).getSleepType()) {
|
switch (((ActivitySampleSleep) data).getSleepType()) {
|
||||||
case 0:
|
case 0:
|
||||||
sleepType = ActivityKind.TYPE_LIGHT_SLEEP;
|
sleepType = ActivityKind.LIGHT_SLEEP;
|
||||||
activityEntry.setRawIntensity(10);
|
activityEntry.setRawIntensity(10);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
sleepType = ActivityKind.TYPE_DEEP_SLEEP;
|
sleepType = ActivityKind.DEEP_SLEEP;
|
||||||
activityEntry.setRawIntensity(70);
|
activityEntry.setRawIntensity(70);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
sleepType = ActivityKind.TYPE_REM_SLEEP;
|
sleepType = ActivityKind.REM_SLEEP;
|
||||||
activityEntry.setRawIntensity(80);
|
activityEntry.setRawIntensity(80);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sleepType = ActivityKind.TYPE_LIGHT_SLEEP;
|
sleepType = ActivityKind.LIGHT_SLEEP;
|
||||||
activityEntry.setRawIntensity(50);
|
activityEntry.setRawIntensity(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
activityEntry.setRawKind(sleepType);
|
activityEntry.setRawKind(sleepType.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleCalories1(WithingsStructure data) {
|
private void handleCalories1(WithingsStructure data) {
|
||||||
activityEntry.setRawIntensity(((ActivitySampleCalories)data).getMet());
|
activityEntry.setRawIntensity(((ActivitySampleCalories) data).getMet());
|
||||||
activityEntry.setCalories(((ActivitySampleCalories)data).getCalories());
|
activityEntry.setCalories(((ActivitySampleCalories) data).getCalories());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleCalories2(WithingsStructure data) {
|
private void handleCalories2(WithingsStructure data) {
|
||||||
activityEntry.setRawIntensity(((ActivitySampleCalories2)data).getMet());
|
activityEntry.setRawIntensity(((ActivitySampleCalories2) data).getMet());
|
||||||
activityEntry.setCalories(((ActivitySampleCalories2)data).getCalories());
|
activityEntry.setCalories(((ActivitySampleCalories2) data).getCalories());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ public class LiveWorkoutHandler implements IncomingMessageHandler {
|
|||||||
baseActivitySummary = new BaseActivitySummary();
|
baseActivitySummary = new BaseActivitySummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
baseActivitySummary.setActivityKind(withingsWorkoutType.toActivityKind());
|
baseActivitySummary.setActivityKind(withingsWorkoutType.toActivityKind().getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendGpsState() {
|
private void sendGpsState() {
|
||||||
|
@ -62,7 +62,7 @@ public abstract class XiaomiActivityParser {
|
|||||||
|
|
||||||
// These will be set later, once we parse the summary
|
// These will be set later, once we parse the summary
|
||||||
summary.setEndTime(fileId.getTimestamp());
|
summary.setEndTime(fileId.getTimestamp());
|
||||||
summary.setActivityKind(ActivityKind.TYPE_UNKNOWN);
|
summary.setActivityKind(ActivityKind.UNKNOWN.getCode());
|
||||||
|
|
||||||
return summary;
|
return summary;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ public class WorkoutGpsParser extends XiaomiActivityParser {
|
|||||||
// Set the info on the activity track
|
// Set the info on the activity track
|
||||||
activityTrack.setUser(user);
|
activityTrack.setUser(user);
|
||||||
activityTrack.setDevice(device);
|
activityTrack.setDevice(device);
|
||||||
activityTrack.setName(ActivityKind.asString(summary.getActivityKind(), support.getContext()));
|
activityTrack.setName(ActivityKind.fromCode(summary.getActivityKind()).getLabel(support.getContext()));
|
||||||
|
|
||||||
// Save the raw bytes
|
// Save the raw bytes
|
||||||
final String rawBytesPath = saveRawBytes(fileId, bytes);
|
final String rawBytesPath = saveRawBytes(fileId, bytes);
|
||||||
@ -149,6 +149,7 @@ public class WorkoutGpsParser extends XiaomiActivityParser {
|
|||||||
private String saveRawBytes(final XiaomiActivityFileId fileId, final byte[] bytes) {
|
private String saveRawBytes(final XiaomiActivityFileId fileId, final byte[] bytes) {
|
||||||
try {
|
try {
|
||||||
final File targetFolder = new File(FileUtils.getExternalFilesDir(), "rawDetails");
|
final File targetFolder = new File(FileUtils.getExternalFilesDir(), "rawDetails");
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
targetFolder.mkdirs();
|
targetFolder.mkdirs();
|
||||||
final File targetFile = new File(targetFolder, fileId.getFilename());
|
final File targetFile = new File(targetFolder, fileId.getFilename());
|
||||||
FileOutputStream outputStream = new FileOutputStream(targetFile);
|
FileOutputStream outputStream = new FileOutputStream(targetFile);
|
||||||
|
@ -100,7 +100,7 @@ public class WorkoutSummaryParser extends XiaomiActivityParser implements Activi
|
|||||||
|
|
||||||
summary.setStartTime(fileId.getTimestamp()); // due to a bug this has to be set
|
summary.setStartTime(fileId.getTimestamp()); // due to a bug this has to be set
|
||||||
summary.setEndTime(fileId.getTimestamp()); // due to a bug this has to be set
|
summary.setEndTime(fileId.getTimestamp()); // due to a bug this has to be set
|
||||||
summary.setActivityKind(ActivityKind.TYPE_UNKNOWN);
|
summary.setActivityKind(ActivityKind.UNKNOWN.getCode());
|
||||||
summary.setRawSummaryData(bytes);
|
summary.setRawSummaryData(bytes);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -172,31 +172,31 @@ public class WorkoutSummaryParser extends XiaomiActivityParser implements Activi
|
|||||||
|
|
||||||
switch (fileId.getSubtype()) {
|
switch (fileId.getSubtype()) {
|
||||||
case SPORTS_OUTDOOR_WALKING_V1:
|
case SPORTS_OUTDOOR_WALKING_V1:
|
||||||
summary.setActivityKind(ActivityKind.TYPE_WALKING);
|
summary.setActivityKind(ActivityKind.WALKING.getCode());
|
||||||
parser = getOutdoorWalkingV1Parser(fileId);
|
parser = getOutdoorWalkingV1Parser(fileId);
|
||||||
break;
|
break;
|
||||||
case SPORTS_OUTDOOR_RUNNING:
|
case SPORTS_OUTDOOR_RUNNING:
|
||||||
summary.setActivityKind(ActivityKind.TYPE_RUNNING);
|
summary.setActivityKind(ActivityKind.RUNNING.getCode());
|
||||||
parser = getOutdoorWalkingV1Parser(fileId);
|
parser = getOutdoorWalkingV1Parser(fileId);
|
||||||
break;
|
break;
|
||||||
case SPORTS_INDOOR_CYCLING:
|
case SPORTS_INDOOR_CYCLING:
|
||||||
summary.setActivityKind(ActivityKind.TYPE_INDOOR_CYCLING);
|
summary.setActivityKind(ActivityKind.INDOOR_CYCLING.getCode());
|
||||||
parser = getIndoorCyclingParser(fileId);
|
parser = getIndoorCyclingParser(fileId);
|
||||||
break;
|
break;
|
||||||
case SPORTS_FREESTYLE:
|
case SPORTS_FREESTYLE:
|
||||||
summary.setActivityKind(ActivityKind.TYPE_STRENGTH_TRAINING);
|
summary.setActivityKind(ActivityKind.STRENGTH_TRAINING.getCode());
|
||||||
parser = getFreestyleParser(fileId);
|
parser = getFreestyleParser(fileId);
|
||||||
break;
|
break;
|
||||||
case SPORTS_POOL_SWIMMING:
|
case SPORTS_POOL_SWIMMING:
|
||||||
summary.setActivityKind(ActivityKind.TYPE_SWIMMING);
|
summary.setActivityKind(ActivityKind.SWIMMING.getCode());
|
||||||
parser = getPoolSwimmingParser(fileId);
|
parser = getPoolSwimmingParser(fileId);
|
||||||
break;
|
break;
|
||||||
case SPORTS_HIIT:
|
case SPORTS_HIIT:
|
||||||
summary.setActivityKind(ActivityKind.TYPE_EXERCISE);
|
summary.setActivityKind(ActivityKind.EXERCISE.getCode());
|
||||||
parser = getHiitParser(fileId);
|
parser = getHiitParser(fileId);
|
||||||
break;
|
break;
|
||||||
case SPORTS_ELLIPTICAL:
|
case SPORTS_ELLIPTICAL:
|
||||||
summary.setActivityKind(ActivityKind.TYPE_ELLIPTICAL_TRAINER);
|
summary.setActivityKind(ActivityKind.ELLIPTICAL_TRAINER.getCode());
|
||||||
// TODO
|
// TODO
|
||||||
break;
|
break;
|
||||||
case SPORTS_OUTDOOR_WALKING_V2:
|
case SPORTS_OUTDOOR_WALKING_V2:
|
||||||
|
@ -102,13 +102,13 @@ public class XiaomiSimpleActivityParser {
|
|||||||
// TODO use XiaomiWorkoutType
|
// TODO use XiaomiWorkoutType
|
||||||
switch (value.intValue()) {
|
switch (value.intValue()) {
|
||||||
case 2:
|
case 2:
|
||||||
summary.setActivityKind(ActivityKind.TYPE_WALKING);
|
summary.setActivityKind(ActivityKind.WALKING.getCode());
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
summary.setActivityKind(ActivityKind.TYPE_CYCLING);
|
summary.setActivityKind(ActivityKind.CYCLING.getCode());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
summary.setActivityKind(ActivityKind.TYPE_UNKNOWN);
|
summary.setActivityKind(ActivityKind.UNKNOWN.getCode());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
summaryData.add(dataEntry.getKey(), value.floatValue(), dataEntry.getUnit());
|
summaryData.add(dataEntry.getKey(), value.floatValue(), dataEntry.getUnit());
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user