1
0
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:
José Rebelo 2024-08-12 19:41:50 +01:00
parent 8c7cc98d36
commit 34378a4a11
107 changed files with 1016 additions and 1465 deletions

View File

@ -46,9 +46,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
@ -75,8 +72,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB;
public class ActivitySummariesActivity extends AbstractListActivity<BaseActivitySummary> {
static final int ACTIVITY_FILTER = 1;
static final int ACTIVITY_DETAIL = 11;
private static final Logger LOG = LoggerFactory.getLogger(ActivitySummariesActivity.class);
HashMap<String, Integer> activityKindMap = new HashMap<>(0);
HashMap<String, ActivityKind> activityKindMap = new HashMap<>(0);
int activityFilter = 0;
long dateFromFilter = 0;
long dateToFilter = 0;
@ -326,15 +322,14 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
}
private LinkedHashMap fillKindMap() {
LinkedHashMap<String, Integer> newMap = new LinkedHashMap<>(0); //reset
private LinkedHashMap<String, ActivityKind> fillKindMap() {
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()) {
String activityName = ActivityKind.asString(item.getActivityKind(), this);
String activityName = ActivityKind.fromCode(item.getActivityKind()).getLabel(this);
if (!newMap.containsKey(activityName) && item.getActivityKind() != 0) {
newMap.put(activityName, item.getActivityKind());
newMap.put(activityName, ActivityKind.fromCode(item.getActivityKind()));
}
}
return newMap;
@ -395,7 +390,7 @@ public class ActivitySummariesActivity extends AbstractListActivity<BaseActivity
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);
intent.setType("application/gpx+xml");
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);

View File

@ -75,7 +75,7 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
long dateFromFilter = 0;
long dateToFilter = 0;
String nameContainsFilter;
HashMap<String, Integer> activityKindMap = new HashMap<>(1);
HashMap<String, ActivityKind> activityKindMap = new HashMap<>(1);
List<Long> itemsFilter;
long deviceFilter;
long initial_deviceFilter;
@ -87,7 +87,7 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
super.onCreate(savedInstanceState);
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");
activityFilter = bundle.getInt("activityFilter", 0);
dateFromFilter = bundle.getLong("dateFromFilter", 0);
@ -120,13 +120,13 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
final Spinner filterKindSpinner = findViewById(R.id.select_kind);
ArrayList<SpinnerWithIconItem> kindArray = new ArrayList<>();
for (Map.Entry<String, Integer> item : activityKindMap.entrySet()) {
if (item.getValue() == 0) 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())));
for (Map.Entry<String, ActivityKind> item : activityKindMap.entrySet()) {
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(), (long) item.getValue().getCode(), item.getValue().getIcon()));
}
//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);
SpinnerWithIconAdapter adapter = new SpinnerWithIconAdapter(this,
@ -407,12 +407,14 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
return newMap;
}
public SpinnerWithIconItem getKindByValue(Integer value) {
for (Map.Entry<String, Integer> entry : activityKindMap.entrySet()) {
if (Objects.equals(value, entry.getValue())) {
return new SpinnerWithIconItem(entry.getKey(),
new Long(entry.getValue()),
ActivityKind.getIconId(entry.getValue()));
public SpinnerWithIconItem getKindByValue(int value) {
for (Map.Entry<String, ActivityKind> entry : activityKindMap.entrySet()) {
if (value == entry.getValue().getCode()) {
return new SpinnerWithIconItem(
entry.getKey(),
(long) entry.getValue().getCode(),
entry.getValue().getIcon()
);
}
}
return null;
@ -434,7 +436,7 @@ public class ActivitySummariesFilter extends AbstractGBActivity {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
SpinnerWithIconItem selectedItem = (SpinnerWithIconItem) parent.getItemAtPosition(pos);
String activity = selectedItem.getText();
activityFilter = activityKindMap.get(activity);
activityFilter = activityKindMap.get(activity).getCode();
update_filter_fields();
}

View File

@ -345,7 +345,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
private void makeSummaryHeader(BaseActivitySummary 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();
Date starttime = item.getStartTime();
Date endtime = item.getEndTime();
@ -354,7 +354,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
String durationhms = DateTimeUtils.formatDurationHoursMinutes((endtime.getTime() - starttime.getTime()), TimeUnit.MILLISECONDS);
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);
activity_kind.setText(activitykindname);
@ -594,7 +594,7 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
int height = layout.getChildAt(0).getWidth();
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 {
File targetFile = new File(FileUtils.getExternalFilesDir(), fileName);
FileOutputStream fOut = new FileOutputStream(targetFile);

View File

@ -261,7 +261,7 @@ public class ControlCenterv2 extends AppCompatActivity
// Signal DeviceCommunicationService to fetch activity for all connected devices
Intent intent = new Intent(getApplicationContext(), DeviceCommunicationService.class);
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);
// Hide 'refreshing' animation immediately if no health devices are connected
List<GBDevice> devices1 = GBApplication.app().getDeviceManager().getDevices();

View File

@ -63,6 +63,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardSleepW
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardStepsWidget;
import nodomain.freeyourgadget.gadgetbridge.activities.dashboard.DashboardTodayWidget;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.util.DashboardUtils;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
@ -422,11 +423,11 @@ public class DashboardFragment extends Fragment {
}
public static class GeneralizedActivity implements Serializable {
public int activityKind;
public ActivityKind activityKind;
public long timeFrom;
public long timeTo;
public GeneralizedActivity(int activityKind, long timeFrom, long timeTo) {
public GeneralizedActivity(ActivityKind activityKind, long timeFrom, long timeTo) {
this.activityKind = activityKind;
this.timeFrom = timeFrom;
this.timeTo = timeTo;

View File

@ -45,12 +45,13 @@ import nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
public abstract class AbstractActivityChartFragment<D extends ChartsData> extends AbstractChartFragment<D> {
private static final Logger LOG = LoggerFactory.getLogger(AbstractActivityChartFragment.class);
public static final float Y_VALUE_DEEP_SLEEP = 0.01f;
public boolean supportsHeartrate(GBDevice device) {
DeviceCoordinator coordinator = device.getDeviceCoordinator();
return coordinator != null && coordinator.supportsHeartRateMeasurement(device);
@ -62,11 +63,11 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
}
protected static final class ActivityConfig {
public final int type;
public final ActivityKind type;
public final String label;
public final Integer color;
public ActivityConfig(int kind, String label, Integer color) {
public ActivityConfig(ActivityKind kind, String label, Integer color) {
this.type = kind;
this.label = label;
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_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);
akLightSleep = new ActivityConfig(ActivityKind.TYPE_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);
akRemSleep = new ActivityConfig(ActivityKind.TYPE_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);
akActivity = new ActivityConfig(ActivityKind.ACTIVITY, getString(R.string.abstract_chart_fragment_kind_activity), AK_ACTIVITY_COLOR);
akLightSleep = new ActivityConfig(ActivityKind.LIGHT_SLEEP, getString(R.string.abstract_chart_fragment_kind_light_sleep), AK_LIGHT_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.REM_SLEEP, getString(R.string.abstract_chart_fragment_kind_rem_sleep), AK_REM_SLEEP_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) {
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
return akDeepSleep.color;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
return akLightSleep.color;
case ActivityKind.TYPE_REM_SLEEP:
case REM_SLEEP:
return akRemSleep.color;
case ActivityKind.TYPE_ACTIVITY:
case ACTIVITY:
return akActivity.color;
}
return akActivity.color;
@ -166,12 +167,6 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
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) {
// Calendar cal = GregorianCalendar.getInstance();
// cal.clear();
@ -187,7 +182,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
boolean annotate = true;
boolean use_steps_as_movement;
int last_type = ActivityKind.TYPE_UNKNOWN;
ActivityKind last_type = ActivityKind.UNKNOWN;
int numEntries = samples.size();
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++) {
ActivitySample sample = samples.get(i);
int type = sample.getKind();
ActivityKind type = sample.getKind();
int ts = tsTranslation.shorten(sample.getTimestamp());
// System.out.println(ts);
@ -223,7 +218,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
float value = movement;
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)
deepSleepEntries.add(createLineEntry(0, ts - 1));
@ -232,9 +227,9 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
notWornEntries.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;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
if (last_type != type) {
lightSleepEntries.add(createLineEntry(0, ts - 1));
@ -245,7 +240,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
}
lightSleepEntries.add(createLineEntry(value, ts));
break;
case ActivityKind.TYPE_REM_SLEEP:
case REM_SLEEP:
if (last_type != type) {
remSleepEntries.add(createLineEntry(0, ts - 1));
@ -256,7 +251,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
}
remSleepEntries.add(createLineEntry(value, ts));
break;
case ActivityKind.TYPE_NOT_WORN:
case NOT_WORN:
if (last_type != type) {
notWornEntries.add(createLineEntry(0, ts - 1));
@ -265,7 +260,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
remSleepEntries.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;
default:
// short steps = sample.getSteps();
@ -284,7 +279,7 @@ public abstract class AbstractActivityChartFragment<D extends ChartsData> extend
}
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) {
heartrateEntries.add(createLineEntry(0, lastHrSampleIndex + 1));
heartrateEntries.add(createLineEntry(0, ts - 1));

View File

@ -37,30 +37,30 @@ public class ActivityAnalysis {
private int maxSpeed = 0;
public ActivityAmounts calculateActivityAmounts(List<? extends ActivitySample> samples) {
ActivityAmount deepSleep = new ActivityAmount(ActivityKind.TYPE_DEEP_SLEEP);
ActivityAmount lightSleep = new ActivityAmount(ActivityKind.TYPE_LIGHT_SLEEP);
ActivityAmount remSleep = new ActivityAmount(ActivityKind.TYPE_REM_SLEEP);
ActivityAmount notWorn = new ActivityAmount(ActivityKind.TYPE_NOT_WORN);
ActivityAmount activity = new ActivityAmount(ActivityKind.TYPE_ACTIVITY);
ActivityAmount deepSleep = new ActivityAmount(ActivityKind.DEEP_SLEEP);
ActivityAmount lightSleep = new ActivityAmount(ActivityKind.LIGHT_SLEEP);
ActivityAmount remSleep = new ActivityAmount(ActivityKind.REM_SLEEP);
ActivityAmount notWorn = new ActivityAmount(ActivityKind.NOT_WORN);
ActivityAmount activity = new ActivityAmount(ActivityKind.ACTIVITY);
ActivityAmount previousAmount = null;
ActivitySample previousSample = null;
for (ActivitySample sample : samples) {
ActivityAmount amount;
switch (sample.getKind()) {
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
amount = deepSleep;
break;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
amount = lightSleep;
break;
case ActivityKind.TYPE_REM_SLEEP:
case REM_SLEEP:
amount = remSleep;
break;
case ActivityKind.TYPE_NOT_WORN:
case NOT_WORN:
amount = notWorn;
break;
case ActivityKind.TYPE_ACTIVITY:
case ACTIVITY:
default:
amount = activity;
break;
@ -82,7 +82,7 @@ public class ActivityAnalysis {
}
// add time
if (steps > 0 && sample.getKind() == ActivityKind.TYPE_ACTIVITY) {
if (steps > 0 && sample.getKind() == ActivityKind.ACTIVITY) {
if (steps > maxSpeed) {
maxSpeed = steps;
}

View File

@ -254,7 +254,7 @@ public class ActivityListingAdapter extends AbstractActivityListingAdapter<Activ
@Override
protected String getActivityName(ActivitySession item) {
return ActivityKind.asString(item.getActivityKind(), getContext());
return item.getActivityKind().getLabel(getContext());
}
@Override
@ -354,6 +354,6 @@ public class ActivityListingAdapter extends AbstractActivityListingAdapter<Activ
@Override
protected int getIcon(ActivitySession item) {
return ActivityKind.getIconId(item.getActivityKind());
return item.getActivityKind().getIcon();
}
}

View File

@ -59,11 +59,11 @@ public class SleepAnalysis {
if (previousSample != null) {
long durationSinceLastSample = sample.getTimestamp() - previousSample.getTimestamp();
if (sample.getKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
if (sample.getKind() == ActivityKind.LIGHT_SLEEP) {
lightSleepDuration += durationSinceLastSample;
} else if (sample.getKind() == ActivityKind.TYPE_DEEP_SLEEP) {
} else if (sample.getKind() == ActivityKind.DEEP_SLEEP) {
deepSleepDuration += durationSinceLastSample;
} else if (sample.getKind() == ActivityKind.TYPE_REM_SLEEP) {
} else if (sample.getKind() == ActivityKind.REM_SLEEP) {
remSleepDuration += durationSinceLastSample;
} else {
durationSinceLastSleep += durationSinceLastSample;
@ -88,9 +88,9 @@ public class SleepAnalysis {
}
private boolean isSleep(ActivitySample sample) {
return sample.getKind() == ActivityKind.TYPE_DEEP_SLEEP ||
sample.getKind() == ActivityKind.TYPE_LIGHT_SLEEP ||
sample.getKind() == ActivityKind.TYPE_REM_SLEEP;
return sample.getKind() == ActivityKind.DEEP_SLEEP ||
sample.getKind() == ActivityKind.LIGHT_SLEEP ||
sample.getKind() == ActivityKind.REM_SLEEP;
}
private Date getDateFromSample(ActivitySample sample) {

View File

@ -144,12 +144,12 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
if (!sleepSessions.isEmpty()) {
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)));
colors.add(getColorFor(ActivityKind.TYPE_LIGHT_SLEEP));
colors.add(getColorFor(ActivityKind.TYPE_DEEP_SLEEP));
colors.add(getColorFor(ActivityKind.LIGHT_SLEEP));
colors.add(getColorFor(ActivityKind.DEEP_SLEEP));
if (supportsRemSleep(mGBDevice)) {
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 {
@ -266,7 +266,7 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
List<Integer> heartRateValues = new ArrayList<>();
HeartRateUtils heartRateUtilsInstance = HeartRateUtils.getInstance();
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();
if (heartRateUtilsInstance.isValidHeartRateValue(heartRate)) {
heartRateValues.add(heartRate);
@ -309,7 +309,7 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
List<Float> allIntensities = new ArrayList<>();
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();
allIntensities.add(intensity);
}
@ -477,7 +477,6 @@ public class SleepChartFragment extends AbstractActivityChartFragment<SleepChart
@Override
protected List<? extends ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
// temporary fix for totally wrong sleep amounts
// return super.getSleepSamples(db, device, tsFrom, tsTo);
return super.getAllSamples(db, device, tsFrom, tsTo);
}

View File

@ -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;
}
}

View File

@ -79,7 +79,7 @@ public class SpeedZonesFragment extends AbstractActivityChartFragment<ChartsData
BarDataSet set = new BarDataSet(entries, "");
set.setValueTextColor(CHART_TEXT_COLOR);
set.setColors(getColorFor(ActivityKind.TYPE_ACTIVITY));
set.setColors(getColorFor(ActivityKind.ACTIVITY));
//set.setDrawValues(false);
//data.setBarWidth(0.1f);
data.addDataSet(set);

View File

@ -52,7 +52,7 @@ public class StepAnalysis {
int activeSteps = 0; //steps that we count
int stepsBetweenActivePeriods = 0; //steps during time when we maybe take a rest but then restart
int durationSinceLastActiveStep = 0;
int activityKind;
ActivityKind activityKind;
List<Integer> heartRateSum = new ArrayList<>();
List<Integer> heartRateBetweenActivePeriodsSum = new ArrayList<>();
@ -67,7 +67,7 @@ public class StepAnalysis {
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
if (sessionStart == null) {
@ -178,7 +178,7 @@ public class StepAnalysis {
endTime = new Date(durationSum);
ActivitySession stepSessionSummary = new ActivitySession(startTime, endTime,
stepsSum, heartRateAverage, intensitySum, distanceSum, 0);
stepsSum, heartRateAverage, intensitySum, distanceSum, ActivityKind.UNKNOWN);
stepSessionSummary.setSessionCount(sessionCount);
stepSessionSummary.setSessionType(ActivitySession.SESSION_SUMMARY);
@ -207,19 +207,19 @@ public class StepAnalysis {
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);
int spm = (int) (activeSteps / (session_length / 60));
if (spm > MIN_STEPS_PER_MINUTE_FOR_RUN) {
return ActivityKind.TYPE_RUNNING;
return ActivityKind.RUNNING;
}
if (activeSteps > 200) {
return ActivityKind.TYPE_WALKING;
return ActivityKind.WALKING;
}
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) {

View File

@ -197,9 +197,9 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
long balance = 0;
for (ActivityAmount amount : activityAmounts.getAmounts()) {
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP ||
amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP ||
amount.getActivityKind() == ActivityKind.TYPE_REM_SLEEP) {
if (amount.getActivityKind() == ActivityKind.DEEP_SLEEP ||
amount.getActivityKind() == ActivityKind.LIGHT_SLEEP ||
amount.getActivityKind() == ActivityKind.REM_SLEEP) {
balance += amount.getTotalSeconds();
}
}
@ -224,11 +224,11 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
long totalSecondsLightSleep = 0;
long totalSecondsRemSleep = 0;
for (ActivityAmount amount : activityAmounts.getAmounts()) {
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP) {
if (amount.getActivityKind() == ActivityKind.DEEP_SLEEP) {
totalSecondsDeepSleep += amount.getTotalSeconds();
} else if (amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
} else if (amount.getActivityKind() == ActivityKind.LIGHT_SLEEP) {
totalSecondsLightSleep += amount.getTotalSeconds();
} else if (amount.getActivityKind() == ActivityKind.TYPE_REM_SLEEP) {
} else if (amount.getActivityKind() == ActivityKind.REM_SLEEP) {
totalSecondsRemSleep += amount.getTotalSeconds();
}
}

View File

@ -246,27 +246,27 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
}
float start_angle = startAngle + (activity.timeFrom - dashboardData.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.setColor(color_worn);
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.setColor(color_not_worn);
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.setColor(color_light_sleep);
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.setColor(color_rem_sleep);
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.setColor(color_deep_sleep);
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.setColor(color_exercise);
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 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++) {
// If the current timestamp isn't saved yet, do so immediately
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
// keep the most 'important' one
switch (activityTimestamps.get(i)) {
case ActivityKind.TYPE_EXERCISE:
case EXERCISE:
break;
case ActivityKind.TYPE_ACTIVITY:
if (activityKind == ActivityKind.TYPE_EXERCISE)
case ACTIVITY:
if (activityKind == ActivityKind.EXERCISE)
activityTimestamps.put(i, activityKind);
break;
case ActivityKind.TYPE_DEEP_SLEEP:
if (activityKind == ActivityKind.TYPE_EXERCISE ||
activityKind == ActivityKind.TYPE_ACTIVITY)
case DEEP_SLEEP:
if (activityKind == ActivityKind.EXERCISE ||
activityKind == ActivityKind.ACTIVITY)
activityTimestamps.put(i, activityKind);
break;
case ActivityKind.TYPE_LIGHT_SLEEP:
if (activityKind == ActivityKind.TYPE_EXERCISE ||
activityKind == ActivityKind.TYPE_ACTIVITY ||
activityKind == ActivityKind.TYPE_DEEP_SLEEP)
case LIGHT_SLEEP:
if (activityKind == ActivityKind.EXERCISE ||
activityKind == ActivityKind.ACTIVITY ||
activityKind == ActivityKind.DEEP_SLEEP)
activityTimestamps.put(i, activityKind);
break;
case ActivityKind.TYPE_REM_SLEEP:
if (activityKind == ActivityKind.TYPE_EXERCISE ||
activityKind == ActivityKind.TYPE_ACTIVITY ||
activityKind == ActivityKind.TYPE_DEEP_SLEEP ||
activityKind == ActivityKind.TYPE_LIGHT_SLEEP)
case REM_SLEEP:
if (activityKind == ActivityKind.EXERCISE ||
activityKind == ActivityKind.ACTIVITY ||
activityKind == ActivityKind.DEEP_SLEEP ||
activityKind == ActivityKind.LIGHT_SLEEP)
activityTimestamps.put(i, activityKind);
break;
case ActivityKind.TYPE_SLEEP:
if (activityKind == ActivityKind.TYPE_EXERCISE ||
activityKind == ActivityKind.TYPE_ACTIVITY ||
activityKind == ActivityKind.TYPE_DEEP_SLEEP ||
activityKind == ActivityKind.TYPE_LIGHT_SLEEP ||
activityKind == ActivityKind.TYPE_REM_SLEEP)
case SLEEP_ANY:
if (activityKind == ActivityKind.EXERCISE ||
activityKind == ActivityKind.ACTIVITY ||
activityKind == ActivityKind.DEEP_SLEEP ||
activityKind == ActivityKind.LIGHT_SLEEP ||
activityKind == ActivityKind.REM_SLEEP)
activityTimestamps.put(i, activityKind);
break;
default:
@ -395,7 +395,7 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
if (lastTimestamp == 0) lastTimestamp = sample.getTimestamp();
if ((sample.getHeartRate() < 10 || sample.getTimestamp() > lastTimestamp + dashboardData.hrIntervalSecs) && 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) {
firstTimestamp = 0;
lastTimestamp = 0;
@ -409,16 +409,16 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
}
if (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() {
DashboardFragment.DashboardData.GeneralizedActivity previous = null;
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();
int activityKind = activity.getValue();
ActivityKind activityKind = activity.getValue();
if (previous == null || previous.activityKind != activityKind || (!mode_24h && timestamp == midDaySecond) || previous.timeTo < timestamp - 60) {
previous = new DashboardFragment.DashboardData.GeneralizedActivity(activityKind, timestamp, timestamp);
dashboardData.generalizedActivities.add(previous);
@ -457,18 +457,18 @@ public class DashboardTodayWidget extends AbstractDashboardWidget {
// Integrate various data from multiple devices
for (ActivitySample sample : allActivitySamples) {
// 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;
// Add to day results
addActivity(sample.getTimestamp(), sample.getTimestamp() + 60, sample.getKind());
}
if (activitySummaries != null) {
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) {
addActivity(session.getStartTime().getTime() / 1000, session.getEndTime().getTime() / 1000, ActivityKind.TYPE_ACTIVITY);
addActivity(session.getStartTime().getTime() / 1000, session.getEndTime().getTime() / 1000, ActivityKind.ACTIVITY);
}
createGeneralizedActivities();
return null;

View File

@ -235,13 +235,15 @@ public class ActivitySummariesAdapter extends AbstractActivityListingAdapter<Bas
activitiesCountView.setText(String.valueOf(activitiesCount));
String activityName = context.getString(R.string.activity_summaries_all_activities);
if (gettActivityKindFilter() != 0) {
activityName = ActivityKind.asString(gettActivityKindFilter(), context);
activityIconView.setImageResource(ActivityKind.getIconId(gettActivityKindFilter()));
activityIconBigView.setImageResource(ActivityKind.getIconId(gettActivityKindFilter()));
ActivityKind activityKind = ActivityKind.fromCode(gettActivityKindFilter());
activityName = activityKind.getLabel(context);
activityIconView.setImageResource(activityKind.getIcon());
activityIconBigView.setImageResource(activityKind.getIcon());
} else {
if (activitySame) {
activityIconView.setImageResource(ActivityKind.getIconId(activityIcon));
activityIconBigView.setImageResource(ActivityKind.getIconId(activityIcon));
ActivityKind activityKind = ActivityKind.fromCode(activityIcon);
activityIconView.setImageResource(activityKind.getIcon());
activityIconBigView.setImageResource(activityKind.getIcon());
}
}
@ -308,7 +310,7 @@ public class ActivitySummariesAdapter extends AbstractActivityListingAdapter<Bas
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);
}
@ -393,7 +395,7 @@ public class ActivitySummariesAdapter extends AbstractActivityListingAdapter<Bas
@Override
protected int getIcon(BaseActivitySummary item) {
return ActivityKind.getIconId(item.getActivityKind());
return ActivityKind.fromCode(item.getActivityKind()).getIcon();
}
public void setBackgroundColor(int backgroundColor) {

View File

@ -30,6 +30,7 @@ import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.Property;
@ -71,34 +72,16 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
@NonNull
@Override
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
@Override
public List<T> getActivitySamples(int timestamp_from, int timestamp_to) {
if (getRawKindSampleProperty() != null) {
return getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ACTIVITY);
return getGBActivitySamples(timestamp_from, timestamp_to);
} else {
return getActivitySamplesByActivityFilter(timestamp_from, timestamp_to, ActivityKind.TYPE_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);
return getActivitySamplesByActivityFilter(timestamp_from, timestamp_to, Collections.singleton(ActivityKind.ACTIVITY));
}
}
@ -152,11 +135,7 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
return sample;
}
protected List<T> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) {
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();
}
protected List<T> getGBActivitySamples(int timestamp_from, int timestamp_to) {
QueryBuilder<T> qb = getSampleDao().queryBuilder();
Property timestampProperty = getTimestampSampleProperty();
Device dbDevice = DBHelper.findDevice(getDevice(), getSession());
@ -166,7 +145,7 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
}
Property deviceProperty = getDeviceIdentifierSampleProperty();
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();
for (T sample : samples) {
sample.setProvider(this);
@ -185,51 +164,12 @@ public abstract class AbstractSampleProvider<T extends AbstractActivitySample> i
getSampleDao().detachAll();
}
private WhereCondition[] getClauseForActivityType(QueryBuilder<T> qb, int activityTypes) {
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) {
private List<T> getActivitySamplesByActivityFilter(int timestamp_from, int timestamp_to, Set<ActivityKind> activityFilter) {
List<T> samples = getAllActivitySamples(timestamp_from, timestamp_to);
List<T> filteredSamples = new ArrayList<>();
for (T sample : samples) {
if ((sample.getKind() & activityFilter) != 0) {
if (activityFilter.contains(sample.getKind())) {
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) {
final T dummySample = createActivitySample();
dummySample.setTimestamp(ts);
dummySample.setRawKind(ActivityKind.TYPE_UNKNOWN);
dummySample.setRawKind(ActivityKind.UNKNOWN.getCode());
dummySample.setRawIntensity(ActivitySample.NOT_MEASURED);
dummySample.setSteps(ActivitySample.NOT_MEASURED);
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) {
final T dummySample = createActivitySample();
dummySample.setTimestamp(ts);
dummySample.setRawKind(ActivityKind.TYPE_UNKNOWN);
dummySample.setRawKind(ActivityKind.UNKNOWN.getCode());
dummySample.setRawIntensity(ActivitySample.NOT_MEASURED);
dummySample.setSteps(ActivitySample.NOT_MEASURED);
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) {
final T dummySample = createActivitySample();
dummySample.setTimestamp(ts);
dummySample.setRawKind(ActivityKind.TYPE_UNKNOWN);
dummySample.setRawKind(ActivityKind.UNKNOWN.getCode());
dummySample.setRawIntensity(ActivitySample.NOT_MEASURED);
dummySample.setSteps(ActivitySample.NOT_MEASURED);
dummySample.setProvider(this);

View File

@ -22,6 +22,7 @@ import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.
@ -38,9 +39,9 @@ public interface SampleProvider<T extends AbstractActivitySample> {
int PROVIDER_PEBBLE_MISFIT = 3;
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);
@ -63,16 +64,6 @@ public interface SampleProvider<T extends AbstractActivitySample> {
@NonNull
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
* timestamp will be overwritten.

View File

@ -45,12 +45,12 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
private static final class UnknownSampleProvider implements SampleProvider {
@Override
public int normalizeType(int rawType) {
return ActivityKind.TYPE_UNKNOWN;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.UNKNOWN;
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
return 0;
}
@ -69,11 +69,6 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator {
return null;
}
@Override
public List getSleepSamples(int timestamp_from, int timestamp_to) {
return null;
}
@Override
public void addGBActivitySample(AbstractActivitySample activitySample) {
}

View File

@ -66,17 +66,17 @@ public class BangleJSSampleProvider extends AbstractSampleProvider<BangleJSActiv
}
@Override
public int normalizeType(int rawType) {
public ActivityKind normalizeType(int rawType) {
switch (rawType) {
case TYPE_ACTIVITY:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
default: // fall through
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
return TYPE_ACTIVITY;
}
@ -97,8 +97,7 @@ public class BangleJSSampleProvider extends AbstractSampleProvider<BangleJSActiv
public void upsertSample(final BangleJSActivitySample sample) {
final List<BangleJSActivitySample> nearSamples = getGBActivitySamples(
sample.getTimestamp() - 60 * 2,
sample.getTimestamp() + 60 * 2,
normalizeType(sample.getRawKind())
sample.getTimestamp() + 60 * 2
);
if (nearSamples.isEmpty()) {

View File

@ -19,11 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.casio.gbx100;
import androidx.annotation.NonNull;
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.Property;
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.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class CasioGBX100SampleProvider extends AbstractSampleProvider<CasioGBX100ActivitySample> {
private static final Logger LOG = LoggerFactory.getLogger(CasioGBX100SampleProvider.class);
public CasioGBX100SampleProvider(GBDevice device, DaoSession session) {
super(device, session);
}
@Override
public int normalizeType(int rawType) {
return rawType;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
return activityKind;
public int toRawActivityKind(ActivityKind activityKind) {
return activityKind.getCode();
}
@Override
@ -83,17 +77,4 @@ public class CasioGBX100SampleProvider extends AbstractSampleProvider<CasioGBX10
protected Property getDeviceIdentifierSampleProperty() {
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);
}
}

View File

@ -72,13 +72,13 @@ public class CmfActivitySampleProvider extends AbstractSampleProvider<CmfActivit
}
@Override
public int normalizeType(final int rawType) {
return rawType;
public ActivityKind normalizeType(final int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(final int activityKind) {
return activityKind;
public int toRawActivityKind(final ActivityKind activityKind) {
return activityKind.getCode();
}
@Override
@ -92,17 +92,16 @@ public class CmfActivitySampleProvider extends AbstractSampleProvider<CmfActivit
}
@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(
"Getting cmf activity samples for {} between {} and {}",
String.format("0x%08x", activityType),
"Getting cmf activity samples between {} and {}",
timestamp_from,
timestamp_to
);
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()) {
convertCumulativeSteps(samples, CmfActivitySampleDao.Properties.Steps);
@ -165,17 +164,17 @@ public class CmfActivitySampleProvider extends AbstractSampleProvider<CmfActivit
sampleByTs.put(i, sample);
}
final int sleepRawKind = sleepStageToActivityKind(sleepStageSample.getStage());
sample.setRawKind(sleepRawKind);
final ActivityKind sleepRawKind = sleepStageToActivityKind(sleepStageSample.getStage());
sample.setRawKind(sleepRawKind.getCode());
switch (sleepRawKind) {
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
sample.setRawIntensity(20);
break;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
sample.setRawIntensity(30);
break;
case ActivityKind.TYPE_REM_SLEEP:
case REM_SLEEP:
sample.setRawIntensity(40);
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) {
case 1:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case 2:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
case 3:
return ActivityKind.TYPE_REM_SLEEP;
return ActivityKind.REM_SLEEP;
default:
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
}

View File

@ -57,9 +57,9 @@ public class CmfWorkoutSummaryParser implements ActivitySummaryParser {
final CmfActivityType cmfActivityType = CmfActivityType.fromCode(workoutType);
if (cmfActivityType != null) {
summary.setActivityKind(cmfActivityType.getActivityKind());
summary.setActivityKind(cmfActivityType.getActivityKind().getCode());
} else {
summary.setActivityKind(ActivityKind.TYPE_UNKNOWN);
summary.setActivityKind(ActivityKind.UNKNOWN.getCode());
}
summaryData.add(ACTIVE_SECONDS, duration, UNIT_SECONDS);

View File

@ -43,28 +43,27 @@ public class FitProSampleProvider extends AbstractSampleProvider<FitProActivityS
// as per FitProDeviceSupport.rawActivityKindToUniqueKind
@Override
public int normalizeType(int rawType) {
public ActivityKind normalizeType(int rawType) {
switch (rawType) {
case 1:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case 11:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case 12:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
default:
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_ACTIVITY:
return 1;
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
return 11;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
return 12;
case ACTIVITY:
default:
return 1;
}

View File

@ -68,13 +68,13 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
}
@Override
public int normalizeType(final int rawType) {
return rawType;
public ActivityKind normalizeType(final int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(final int activityKind) {
return activityKind;
public int toRawActivityKind(final ActivityKind activityKind) {
return activityKind.getCode();
}
@Override
@ -88,10 +88,9 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
}
@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(
"Getting garmin activity samples for {} between {} and {}",
String.format("0x%08x", activityType),
"Getting garmin activity samples between {} and {}",
timestamp_from,
timestamp_to
);
@ -99,7 +98,7 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
final long nanoStart = System.nanoTime();
final List<GarminActivitySample> samples = fillGaps(
super.getGBActivitySamples(timestamp_from, timestamp_to, activityType),
super.getGBActivitySamples(timestamp_from, timestamp_to),
timestamp_from,
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) {
// 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 List<GarminEventSample> sleepEventSamples = eventSampleProvider.getSleepEvents(
@ -134,7 +133,7 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
switch (event.getEventType()) {
case 0: // start
// 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
default:
}
@ -170,18 +169,18 @@ public class GarminActivitySampleProvider extends AbstractSampleProvider<GarminA
if (!stagesMap.isEmpty()) {
for (final GarminActivitySample sample : samples) {
final long ts = sample.getTimestamp() * 1000L;
final Integer sleepType = stagesMap.get(ts);
if (sleepType != null && !sleepType.equals(ActivityKind.TYPE_UNKNOWN)) {
sample.setRawKind(sleepType);
final ActivityKind sleepType = stagesMap.get(ts);
if (sleepType != null && !sleepType.equals(ActivityKind.UNKNOWN)) {
sample.setRawKind(sleepType.getCode());
switch (sleepType) {
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
sample.setRawIntensity(20);
break;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
sample.setRawIntensity(30);
break;
case ActivityKind.TYPE_REM_SLEEP:
case REM_SLEEP:
sample.setRawIntensity(40);
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());
if (sleepStage == null) {
LOG.error("Unknown sleep stage for {}", stageSample.getStage());
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
switch (sleepStage) {
case LIGHT:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
case DEEP:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case REM:
return ActivityKind.TYPE_REM_SLEEP;
return ActivityKind.REM_SLEEP;
}
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}

View File

@ -28,6 +28,7 @@ import java.util.GregorianCalendar;
import java.util.List;
import androidx.annotation.NonNull;
import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.Property;
import de.greenrobot.dao.query.QueryBuilder;
@ -45,36 +46,28 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.service.devices.hplus.HPlusDataRecord;
public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealthActivitySample> {
private GBDevice mDevice;
private DaoSession mSession;
public HPlusHealthSampleProvider(GBDevice device, DaoSession session) {
super(device, session);
mSession = session;
mDevice = device;
}
public int normalizeType(int rawType) {
public ActivityKind normalizeType(int rawType) {
switch (rawType) {
case HPlusDataRecord.TYPE_DAY_SLOT:
case HPlusDataRecord.TYPE_DAY_SUMMARY:
case HPlusDataRecord.TYPE_REALTIME:
case HPlusDataRecord.TYPE_SLEEP:
case HPlusDataRecord.TYPE_UNKNOWN:
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
default:
return rawType;
return ActivityKind.fromCode(rawType);
}
}
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_DEEP_SLEEP:
return ActivityKind.TYPE_DEEP_SLEEP;
case ActivityKind.TYPE_LIGHT_SLEEP:
return ActivityKind.TYPE_LIGHT_SLEEP;
case DEEP_SLEEP:
case LIGHT_SLEEP:
return activityKind.getCode();
default:
return HPlusDataRecord.TYPE_DAY_SLOT;
}
@ -113,20 +106,10 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
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
@Override
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());
if (dbDevice == null) {
@ -143,7 +126,6 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
List<HPlusHealthActivityOverlay> overlayRecords = qb.build().list();
//Apply Overlays
for (HPlusHealthActivityOverlay overlay : overlayRecords) {
@ -167,11 +149,11 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
long nonSleepTimeEnd = 0;
for (HPlusHealthActivitySample sample : samples) {
if (sample.getRawKind() == ActivityKind.TYPE_NOT_WORN)
if (sample.getRawKind() == ActivityKind.NOT_WORN.getCode())
continue;
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) {
nonSleepTimeEnd = sample.getTimestamp() + 10 * 60; // 10 minutes
continue;
@ -179,10 +161,10 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
continue;
}
if (overlay.getRawKind() == ActivityKind.TYPE_NOT_WORN)
if (overlay.getRawKind() == ActivityKind.NOT_WORN.getCode())
sample.setHeartRate(0);
if (sample.getRawKind() != ActivityKind.TYPE_NOT_WORN)
if (sample.getRawKind() != ActivityKind.NOT_WORN.getCode())
sample.setRawKind(overlay.getRawKind());
sample.setRawIntensity(10);
@ -192,7 +174,6 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
}
//Fix Step counters
//Todays sample steps will come from the Day Slots messages
//Historical steps will be provided by Day Summaries messages
@ -210,7 +191,7 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
for (HPlusHealthActivitySample sample : samples) {
if (sample.getTimestamp() >= today.getTimeInMillis() / 1000) {
/**Strategy is:
/* Strategy is:
* Calculate max steps from realtime messages
* Calculate sum of steps from day 10 minute slot summaries
*/
@ -238,13 +219,13 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
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(
timestamp, // ts
deviceId,
userId, // User id
null, // Raw Data
ActivityKind.TYPE_UNKNOWN,
ActivityKind.UNKNOWN.getCode(),
1, // Intensity
ActivitySample.NOT_MEASURED, // Steps
ActivitySample.NOT_MEASURED, // HR
@ -254,8 +235,6 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider<HPlusHealt
sample.setProvider(this);
samples.add(sample);
return samples;
}
}

View File

@ -61,7 +61,7 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
short version = buffer.getShort(); // version
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());
try {
HuamiSportsActivityType activityType = HuamiSportsActivityType.fromCode(rawKind);
@ -70,7 +70,7 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
LOG.error("Error mapping activity kind: " + ex.getMessage(), ex);
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
long timestamp_start = BLETypeConversions.toUnsigned(buffer.getInt()) * 1000;
@ -192,7 +192,7 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
averageStride = 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
// for cycling it seems to work... hmm...
// 28 bytes
@ -203,7 +203,7 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
descentSeconds = buffer.getInt() / 1000; //ms?
flatDistance = buffer.getFloat();
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
/*
data on the bip s display (example)
@ -252,7 +252,7 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
totalStride = buffer.getFloat();
buffer.getInt(); // unknown
if (activityKind == ActivityKind.TYPE_SWIMMING) {
if (activityKind == ActivityKind.SWIMMING) {
// 28 bytes
averageStrokeDistance = buffer.getFloat();
averageStrokesPerSecond = buffer.getFloat();
@ -339,11 +339,11 @@ public class HuamiActivitySummaryParser implements ActivitySummaryParser {
summaryData.add(CADENCE_MIN, minCadence, UNIT_SPM);
summaryData.add(CADENCE_AVG, averageCadence, UNIT_SPM);
if (!(activityKind == ActivityKind.TYPE_ELLIPTICAL_TRAINER ||
activityKind == ActivityKind.TYPE_JUMP_ROPING ||
activityKind == ActivityKind.TYPE_EXERCISE ||
activityKind == ActivityKind.TYPE_YOGA ||
activityKind == ActivityKind.TYPE_INDOOR_CYCLING)) {
if (!(activityKind == ActivityKind.ELLIPTICAL_TRAINER ||
activityKind == ActivityKind.JUMP_ROPING ||
activityKind == ActivityKind.EXERCISE ||
activityKind == ActivityKind.YOGA ||
activityKind == ActivityKind.INDOOR_CYCLING)) {
summaryData.add(PACE_MIN, minPace, UNIT_SECONDS_PER_M);
summaryData.add(PACE_MAX, maxPace, 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("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_AVG_PER_SECOND, averageStrokesPerSecond, UNIT_STROKES_PER_SECOND);
summaryData.add(LAP_PACE_AVERAGE, averageLapPace, "second");

View File

@ -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_SCHEDULE = PREF_HUAMI_VIBRATION_TRY_PREFIX + "schedule";
public static int toActivityKind(int rawType) {
public static ActivityKind toActivityKind(int rawType) {
switch (rawType) {
case TYPE_DEEP_SLEEP:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case TYPE_LIGHT_SLEEP:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
case TYPE_ACTIVITY:
case TYPE_RUNNING:
case TYPE_WAKE_UP:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case TYPE_NONWEAR:
return ActivityKind.TYPE_NOT_WORN;
return ActivityKind.NOT_WORN;
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:
return ActivityKind.TYPE_CYCLING;
return ActivityKind.CYCLING;
default:
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) {
case ActivityKind.TYPE_ACTIVITY:
case ACTIVITY:
return TYPE_ACTIVITY;
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
return TYPE_DEEP_SLEEP;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
return TYPE_LIGHT_SLEEP;
case ActivityKind.TYPE_NOT_WORN:
case NOT_WORN:
return TYPE_NONWEAR;
case ActivityKind.TYPE_UNKNOWN: // fall through
case UNKNOWN: // fall through
default:
return TYPE_UNSET;
}

View File

@ -75,8 +75,8 @@ public class HuamiExtendedSampleProvider extends AbstractSampleProvider<HuamiExt
}
@Override
protected List<HuamiExtendedActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to, final int activityType) {
final List<HuamiExtendedActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to, activityType);
protected List<HuamiExtendedActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to) {
final List<HuamiExtendedActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to);
postProcess(samples);
return samples;
}
@ -108,34 +108,34 @@ public class HuamiExtendedSampleProvider extends AbstractSampleProvider<HuamiExt
}
@Override
public int normalizeType(final int rawType) {
public ActivityKind normalizeType(final int rawType) {
switch (rawType) {
case TYPE_OUTDOOR_RUNNING:
return ActivityKind.TYPE_RUNNING;
return ActivityKind.RUNNING;
case TYPE_NOT_WORN:
case TYPE_CHARGING:
return ActivityKind.TYPE_NOT_WORN;
return ActivityKind.NOT_WORN;
case TYPE_SLEEP:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
case TYPE_CUSTOM_DEEP_SLEEP:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case TYPE_CUSTOM_REM_SLEEP:
return ActivityKind.TYPE_REM_SLEEP;
return ActivityKind.REM_SLEEP;
}
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
@Override
public int toRawActivityKind(final int activityKind) {
public int toRawActivityKind(final ActivityKind activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_RUNNING:
case RUNNING:
return TYPE_OUTDOOR_RUNNING;
case ActivityKind.TYPE_NOT_WORN:
case NOT_WORN:
return TYPE_NOT_WORN;
case ActivityKind.TYPE_LIGHT_SLEEP:
case ActivityKind.TYPE_DEEP_SLEEP:
case ActivityKind.TYPE_REM_SLEEP:
case LIGHT_SLEEP:
case DEEP_SLEEP:
case REM_SLEEP:
return TYPE_SLEEP;
}

View File

@ -63,14 +63,14 @@ public class ZeppOsActivitySummaryParser extends HuamiActivitySummaryParser {
final ZeppOsActivityType activityType = ZeppOsActivityType
.fromCode((byte) summaryProto.getType().getType());
final int activityKind;
final ActivityKind activityKind;
if (activityType != null) {
activityKind = activityType.toActivityKind();
} else {
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()) {

View File

@ -72,23 +72,23 @@ public class HuaweiSampleProvider extends AbstractSampleProvider<HuaweiActivityS
}
@Override
public int normalizeType(int rawType) {
public ActivityKind normalizeType(int rawType) {
switch (rawType) {
case RawTypes.DEEP_SLEEP:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case RawTypes.LIGHT_SLEEP:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
default:
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
return RawTypes.DEEP_SLEEP;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
return RawTypes.LIGHT_SLEEP;
default:
return RawTypes.NOT_MEASURED;
@ -294,8 +294,6 @@ public class HuaweiSampleProvider extends AbstractSampleProvider<HuaweiActivityS
public long deviceId = 0;
public long userId = 0;
int[] activityTypes = {};
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.
*/
@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!
List<HuaweiActivitySample> rawSamples = getRawOrderedActivitySamples(timestamp_from, timestamp_to);
@ -337,7 +335,6 @@ public class HuaweiSampleProvider extends AbstractSampleProvider<HuaweiActivityS
state.deviceId = nextRawSample.getDeviceId();
state.userId = nextRawSample.getUserId();
}
state.activityTypes = ActivityKind.mapToDBActivityTypes(activityType, this);
while (nextRawSample != null || nextWorkoutSample != null) {
if (nextRawSample == null) {

View File

@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.ID115ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.ID115ActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class ID115SampleProvider extends AbstractSampleProvider<ID115ActivitySample> {
public ID115SampleProvider(GBDevice device, DaoSession session) {
@ -55,13 +56,13 @@ public class ID115SampleProvider extends AbstractSampleProvider<ID115ActivitySam
}
@Override
public int normalizeType(int rawType) {
return rawType;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
return activityKind;
public int toRawActivityKind(ActivityKind activityKind) {
return activityKind.getCode();
}
@Override

View File

@ -26,6 +26,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.JYouActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.JYouActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class JYouSampleProvider extends AbstractSampleProvider<JYouActivitySample> {
@ -42,13 +43,13 @@ public class JYouSampleProvider extends AbstractSampleProvider<JYouActivitySampl
}
@Override
public int normalizeType(int rawType) {
return rawType;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
return activityKind;
public int toRawActivityKind(ActivityKind activityKind) {
return activityKind.getCode();
}
@Override

View File

@ -60,28 +60,28 @@ public class LefunSampleProvider extends AbstractSampleProvider<LefunActivitySam
}
@Override
public int normalizeType(int rawType) {
public ActivityKind normalizeType(int rawType) {
switch (rawType) {
case LefunConstants.DB_ACTIVITY_KIND_ACTIVITY:
case LefunConstants.DB_ACTIVITY_KIND_HEART_RATE:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case LefunConstants.DB_ACTIVITY_KIND_LIGHT_SLEEP:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
case LefunConstants.DB_ACTIVITY_KIND_DEEP_SLEEP:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
default:
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_ACTIVITY:
case ACTIVITY:
return LefunConstants.DB_ACTIVITY_KIND_ACTIVITY;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
return LefunConstants.DB_ACTIVITY_KIND_LIGHT_SLEEP;
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
return LefunConstants.DB_ACTIVITY_KIND_DEEP_SLEEP;
default:
return LefunConstants.DB_ACTIVITY_KIND_UNKNOWN;

View File

@ -52,14 +52,14 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
}
@Override
public int normalizeType(int rawType) {
return rawType;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
LOG.info(" toRawActivityKind: " + activityKind);
return activityKind;
public int toRawActivityKind(ActivityKind activityKind) {
LOG.debug("toRawActivityKind: {}", activityKind);
return activityKind.getCode();
}
@Override
@ -104,8 +104,8 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
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.TYPE_NOT_WORN if there are no data for more than 60 min.
// generate ActivityKind.NOT_MEASURED if there are no data for more than 15 min. and less than 60 min.
// generate ActivityKind.NOT_WORN if there are no data for more than 60 min.
@NonNull
private List<WatchXPlusActivitySample> checkActivityData(List<WatchXPlusActivitySample> samples, int notMeasuredTS, int notWornTS) {
int oldTS = 0;
@ -116,13 +116,13 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
newTS = samples.get(i).getTimestamp();
if ((newTS - oldTS) < notMeasuredTS) { //check data timestamp diff is more than 15 min
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
samples.get(i-1).setRawKind(ActivityKind.TYPE_NOT_MEASURED);
samples.get(i).setRawKind(ActivityKind.TYPE_NOT_MEASURED);
} 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.NOT_MEASURED.getCode());
samples.get(i).setRawKind(ActivityKind.NOT_MEASURED.getCode());
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
samples.get(i-1).setRawKind(ActivityKind.TYPE_NOT_WORN);
samples.get(i).setRawKind(ActivityKind.TYPE_NOT_WORN);
} 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.NOT_WORN.getCode());
samples.get(i).setRawKind(ActivityKind.NOT_WORN.getCode());
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) {
boolean showRawData = GBApplication.getDeviceSpecificSharedPrefs(mDevice.getAddress()).getBoolean(WatchXPlusConstants.PREF_SHOW_RAW_GRAPH, false);
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();
if (numEntries < 3) {
return samples;
@ -151,14 +151,14 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
int seekAhead = 10;
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 sleepStopIndex_1 = numEntries;
int countNextSleepStart_1 = 0;
int countNextSleepStop_1 = 0;
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
samples.get(i).setRawIntensity(1000);
// 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 sleepStopIndex_2 = numEntries;
int countNextSleepStart_2 = 0;
@ -194,7 +194,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
int next_block = numEntries;
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
if (sleepStartIndex_2 == 0) {
sleepStartIndex_2 = i;
@ -239,7 +239,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
newSleepStartIndex_1 = 0;
}
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) {
samples.get(i).setRawIntensity(200);
} 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);
resultList.add(samples.get(i));
} else {
if (samples.get(i).getRawKind() == ActivityKind.TYPE_ACTIVITY) {
if (samples.get(i).getRawKind() == ActivityKind.ACTIVITY.getCode()) {
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).setRawIntensity(700);
} else {
@ -280,7 +280,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
for (int i = newSleepStartIndex_1; i < newSleepStopIndex_1; i++) {
ActivitySample sample = samples.get(i);
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;
samples.get(i).setRawIntensity(600);
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.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.LIGHT_SLEEP.getCode()) {
if (i > 0) {
if (samples.get(i - 1).getHeartRate() > 0) {
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);
resultList.add(samples.get(i));
}
@ -324,7 +324,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
// add remaining activity
if (newSleepStopIndex_1 < next_block) {
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) {
samples.get(i).setRawIntensity(200);
} 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);
resultList.add(samples.get(i));
} else {
if (samples.get(i).getRawKind() == ActivityKind.TYPE_ACTIVITY) {
if (samples.get(i).getRawKind() == ActivityKind.ACTIVITY.getCode()) {
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).setRawIntensity(700);
} else {
@ -371,7 +371,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
for (int i = newSleepStartIndex_2; i < newSleepStopIndex_2; i++) {
ActivitySample sample = samples.get(i);
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;
samples.get(i).setRawIntensity(600);
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.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.LIGHT_SLEEP.getCode()) {
if (i > 0) {
if (samples.get(i - 1).getHeartRate() > 0) {
samples.get(i).setHeartRate(samples.get(i - 1).getHeartRate());
@ -406,7 +406,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
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);
resultList.add(samples.get(i));
}
@ -415,7 +415,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
// add remaining activity
if (newSleepStopIndex_2 < numEntries) {
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) {
samples.get(i).setRawIntensity(200);
} 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);
resultList.add(samples.get(i));
} else {
if (samples.get(i).getRawKind() == ActivityKind.TYPE_ACTIVITY) {
if (samples.get(i).getRawKind() == ActivityKind.ACTIVITY.getCode()) {
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).setRawIntensity(700);
} 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).setRawKind(ActivityKind.TYPE_NOT_MEASURED);
samples.get(numEntries-1).setRawKind(ActivityKind.NOT_MEASURED.getCode());
samples.get(numEntries-1).setHeartRate(0);
resultList.add(samples.get(numEntries-1));
@ -456,7 +456,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
int maxHeartRate = 10;
numEntries = resultList.size();
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) {
totalSteps = totalSteps + resultList.get(i).getSteps();
}
@ -470,7 +470,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
int newIntensity, correctedSteps;
int totalIntensity = 0;
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).getHeartRate() < 10) {
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) {
stepsPerActivity = totalIntensity / totalSteps;
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) {
correctedSteps = (int) (resultList.get(i).getRawIntensity() / stepsPerActivity);
resultList.get(i).setSteps(correctedSteps);
@ -525,7 +525,7 @@ public class WatchXPlusSampleProvider extends AbstractSampleProvider<WatchXPlusA
}
newTotalSteps = 0;
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;
newTotalSteps = newTotalSteps + correctedSteps;
if (newTotalSteps <= totalSteps) {

View File

@ -26,27 +26,21 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.MakibesHR3ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.MakibesHR3ActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class MakibesHR3SampleProvider extends AbstractSampleProvider<MakibesHR3ActivitySample> {
private GBDevice mDevice;
private DaoSession mSession;
public MakibesHR3SampleProvider(GBDevice device, DaoSession session) {
super(device, session);
mSession = session;
mDevice = device;
}
@Override
public int normalizeType(int rawType) {
return rawType;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
return activityKind;
public int toRawActivityKind(ActivityKind activityKind) {
return activityKind.getCode();
}
@Override

View File

@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.MiBandActivitySampleDao;
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_NO_CHANGE;
@ -37,15 +38,14 @@ public class MiBand2SampleProvider extends AbstractMiBandSampleProvider {
}
@Override
protected List<MiBandActivitySample> getGBActivitySamples(int timestamp_from, int timestamp_to, int activityType) {
List<MiBandActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to, activityType);
protected List<MiBandActivitySample> getGBActivitySamples(int timestamp_from, int timestamp_to) {
List<MiBandActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to);
postprocess(samples);
return samples;
}
/**
* "Temporary" runtime post processing of activity kinds.
* @param samples
*/
private void postprocess(List<MiBandActivitySample> samples) {
if (samples.isEmpty()) {
@ -83,19 +83,19 @@ public class MiBand2SampleProvider extends AbstractMiBandSampleProvider {
qb.orderDesc(MiBandActivitySampleDao.Properties.Timestamp);
qb.limit(1);
List<MiBandActivitySample> result = qb.build().list();
if (result.size() > 0) {
if (!result.isEmpty()) {
return result.get(0).getRawKind() & 0xf;
}
return TYPE_UNSET;
}
@Override
public int normalizeType(int rawType) {
public ActivityKind normalizeType(int rawType) {
return HuamiConst.toActivityKind(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
return HuamiConst.toRawActivityType(activityKind);
}
}

View File

@ -42,36 +42,36 @@ public class MiBandSampleProvider extends AbstractMiBandSampleProvider {
}
@Override
public int normalizeType(int rawType) {
public ActivityKind normalizeType(int rawType) {
switch (rawType) {
case TYPE_DEEP_SLEEP:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case TYPE_LIGHT_SLEEP:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
case TYPE_ACTIVITY:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case TYPE_NONWEAR:
return ActivityKind.TYPE_NOT_WORN;
return ActivityKind.NOT_WORN;
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:
// case TYPE_UNKNOWN: // fall through
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_ACTIVITY:
case ACTIVITY:
return TYPE_ACTIVITY;
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
return TYPE_DEEP_SLEEP;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
return TYPE_LIGHT_SLEEP;
case ActivityKind.TYPE_NOT_WORN:
case NOT_WORN:
return TYPE_NONWEAR;
case ActivityKind.TYPE_UNKNOWN: // fall through
case UNKNOWN: // fall through
default:
return TYPE_UNKNOWN;
}

View File

@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.No1F1ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.No1F1ActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class No1F1SampleProvider extends AbstractSampleProvider<No1F1ActivitySample> {
@ -39,13 +40,13 @@ public class No1F1SampleProvider extends AbstractSampleProvider<No1F1ActivitySam
}
@Override
public int normalizeType(int rawType) {
return rawType;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
return activityKind;
public int toRawActivityKind(ActivityKind activityKind) {
return activityKind.getCode();
}
@Override

View File

@ -55,7 +55,7 @@ public class PebbleHealthSampleProvider extends AbstractSampleProvider<PebbleHea
@NonNull
@Override
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());
if (dbDevice == null) {
@ -112,32 +112,31 @@ public class PebbleHealthSampleProvider extends AbstractSampleProvider<PebbleHea
}
@Override
public int normalizeType(int rawType) {
public ActivityKind normalizeType(int rawType) {
switch (rawType) {
case TYPE_DEEP_NAP:
case TYPE_DEEP_SLEEP:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case TYPE_LIGHT_NAP:
case TYPE_LIGHT_SLEEP:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
case TYPE_ACTIVITY:
case TYPE_WALK:
case TYPE_RUN:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
default:
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_ACTIVITY:
return TYPE_ACTIVITY;
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
return TYPE_DEEP_SLEEP;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
return TYPE_LIGHT_SLEEP;
case ACTIVITY:
default:
return TYPE_ACTIVITY;
}

View File

@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSample;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMisfitSampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class PebbleMisfitSampleProvider extends AbstractSampleProvider<PebbleMisfitSample> {
@ -35,13 +36,13 @@ public class PebbleMisfitSampleProvider extends AbstractSampleProvider<PebbleMis
}
@Override
public int normalizeType(int rawType) {
return rawType;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
return activityKind;
public int toRawActivityKind(ActivityKind activityKind) {
return activityKind.getCode();
}
@Override

View File

@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSample;
import nodomain.freeyourgadget.gadgetbridge.entities.PebbleMorpheuzSampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class PebbleMorpheuzSampleProvider extends AbstractSampleProvider<PebbleMorpheuzSample> {
@ -68,12 +69,12 @@ public class PebbleMorpheuzSampleProvider extends AbstractSampleProvider<PebbleM
}
@Override
public int normalizeType(int rawType) {
return rawType;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
return activityKind;
public int toRawActivityKind(ActivityKind activityKind) {
return activityKind.getCode();
}
}

View File

@ -32,14 +32,8 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class PineTimeActivitySampleProvider extends AbstractSampleProvider<PineTimeActivitySample> {
private GBDevice mDevice;
private DaoSession mSession;
public PineTimeActivitySampleProvider(GBDevice device, DaoSession session) {
super(device, session);
mSession = session;
mDevice = device;
}
@Override
@ -66,13 +60,13 @@ public class PineTimeActivitySampleProvider extends AbstractSampleProvider<PineT
}
@Override
public int normalizeType(int rawType) {
return rawType;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
return activityKind;
public int toRawActivityKind(ActivityKind activityKind) {
return activityKind.getCode();
}
@Override
@ -91,8 +85,8 @@ public class PineTimeActivitySampleProvider extends AbstractSampleProvider<PineT
}
public Optional<PineTimeActivitySample> getSampleForTimestamp(int timestamp) {
List<PineTimeActivitySample> foundSamples = this.getGBActivitySamples(timestamp, timestamp, ActivityKind.TYPE_ALL);
if (foundSamples.size() == 0) {
List<PineTimeActivitySample> foundSamples = this.getGBActivitySamples(timestamp, timestamp);
if (foundSamples.isEmpty()) {
return Optional.empty();
}
return Optional.of(foundSamples.get(0));

View File

@ -19,8 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.List;
import de.greenrobot.dao.AbstractDao;
import de.greenrobot.dao.Property;
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.HybridHRActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser.ActivityEntry;
public class HybridHRActivitySampleProvider extends AbstractSampleProvider<HybridHRActivitySample> {
@ -59,13 +58,13 @@ public class HybridHRActivitySampleProvider extends AbstractSampleProvider<Hybri
}
@Override
public int normalizeType(int rawType) {
if(rawType == -1) return 0;
public ActivityKind normalizeType(int rawType) {
if (rawType == -1) return ActivityKind.UNKNOWN;
return ActivityEntry.WEARING_STATE.fromValue((byte) rawType).getActivityKind();
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
return 0;
}
@ -78,16 +77,4 @@ public class HybridHRActivitySampleProvider extends AbstractSampleProvider<Hybri
public HybridHRActivitySample createActivitySample() {
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);
}
}

View File

@ -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(2, ActivityKind.TYPE_CYCLING);
put(8, ActivityKind.TYPE_WALKING);
put(12, ActivityKind.TYPE_HIKING);
put(1, ActivityKind.RUNNING);
put(2, ActivityKind.CYCLING);
put(8, ActivityKind.WALKING);
put(12, ActivityKind.HIKING);
}
};
}

View File

@ -58,53 +58,53 @@ public class SonyWena3ActivitySampleProvider extends AbstractSampleProvider<Wena
}
@Override
public int normalizeType(int rawType) {
if(rawType < 0 || rawType >= BehaviorSample.Type.LUT.length) return ActivityKind.TYPE_UNKNOWN;
public ActivityKind normalizeType(int rawType) {
if(rawType < 0 || rawType >= BehaviorSample.Type.LUT.length) return ActivityKind.UNKNOWN;
BehaviorSample.Type internalType = BehaviorSample.Type.LUT[rawType];
switch(internalType) {
case NOT_WEARING:
return ActivityKind.TYPE_NOT_WORN;
return ActivityKind.NOT_WORN;
case WALK:
return ActivityKind.TYPE_WALKING;
return ActivityKind.WALKING;
case RUN:
return ActivityKind.TYPE_RUNNING;
return ActivityKind.RUNNING;
case EXERCISE:
return ActivityKind.TYPE_EXERCISE;
return ActivityKind.EXERCISE;
case SLEEP_LIGHT:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
case SLEEP_REM:
return ActivityKind.TYPE_REM_SLEEP;
return ActivityKind.REM_SLEEP;
case SLEEP_DEEP:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case STATIC:
case SLEEP_AWAKE:
case UNKNOWN:
default:
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
switch(activityKind) {
case ActivityKind.TYPE_NOT_MEASURED:
case ActivityKind.TYPE_NOT_WORN:
case NOT_MEASURED:
case NOT_WORN:
return BehaviorSample.Type.NOT_WEARING.ordinal();
case ActivityKind.TYPE_WALKING:
case WALKING:
return BehaviorSample.Type.WALK.ordinal();
case ActivityKind.TYPE_RUNNING:
case RUNNING:
return BehaviorSample.Type.RUN.ordinal();
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
return BehaviorSample.Type.SLEEP_LIGHT.ordinal();
case ActivityKind.TYPE_REM_SLEEP:
case REM_SLEEP:
return BehaviorSample.Type.SLEEP_REM.ordinal();
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
return BehaviorSample.Type.SLEEP_DEEP.ordinal();
case ActivityKind.TYPE_EXERCISE:
case EXERCISE:
return BehaviorSample.Type.EXERCISE.ordinal();
default:
return BehaviorSample.Type.UNKNOWN.ordinal();

View File

@ -58,30 +58,30 @@ public class SonySWR12SampleProvider extends AbstractSampleProvider<SonySWR12Sam
}
@Override
public int normalizeType(int rawType) {
public ActivityKind normalizeType(int rawType) {
switch (rawType) {
case SonySWR12Constants.TYPE_ACTIVITY:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case SonySWR12Constants.TYPE_LIGHT:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
case SonySWR12Constants.TYPE_DEEP:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case SonySWR12Constants.TYPE_NOT_WORN:
return ActivityKind.TYPE_NOT_WORN;
return ActivityKind.NOT_WORN;
}
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_ACTIVITY:
case ACTIVITY:
return SonySWR12Constants.TYPE_ACTIVITY;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
return SonySWR12Constants.TYPE_LIGHT;
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
return SonySWR12Constants.TYPE_DEEP;
case ActivityKind.TYPE_NOT_WORN:
case NOT_WORN:
return SonySWR12Constants.TYPE_NOT_WORN;
}
return SonySWR12Constants.TYPE_ACTIVITY;

View File

@ -69,13 +69,13 @@ public class TestSampleProvider extends AbstractSampleProvider<TestSampleProvide
}
@Override
public int normalizeType(final int rawType) {
return rawType;
public ActivityKind normalizeType(final int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(final int activityKind) {
return activityKind;
public int toRawActivityKind(final ActivityKind activityKind) {
return activityKind.getCode();
}
@Override
@ -89,15 +89,15 @@ public class TestSampleProvider extends AbstractSampleProvider<TestSampleProvide
}
@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<>();
int[] sleepStages = new int[] {
ActivityKind.TYPE_LIGHT_SLEEP,
ActivityKind.TYPE_DEEP_SLEEP,
ActivityKind.LIGHT_SLEEP.getCode(),
ActivityKind.DEEP_SLEEP.getCode(),
};
if (getDevice().getDeviceCoordinator().supportsRemSleep()) {
sleepStages = ArrayUtils.add(sleepStages, ActivityKind.TYPE_REM_SLEEP);
sleepStages = ArrayUtils.add(sleepStages, ActivityKind.REM_SLEEP.getCode());
}
int sleepStageCurrent = 0;
int sleepStageDirection = 1;
@ -141,7 +141,7 @@ public class TestSampleProvider extends AbstractSampleProvider<TestSampleProvide
if (TestDeviceRand.randBool(ts, 0.85f)) {
samples.add(new TestActivitySample(
(int) (ts / 1000),
isSleep ? sleepStages[sleepStageCurrent] : ActivityKind.TYPE_UNKNOWN,
isSleep ? sleepStages[sleepStageCurrent] : ActivityKind.UNKNOWN.getCode(),
isActive ? steps : 0,
intensity,
hr
@ -187,7 +187,7 @@ public class TestSampleProvider extends AbstractSampleProvider<TestSampleProvide
}
@Override
public SampleProvider getProvider() {
public SampleProvider<?> getProvider() {
return TestSampleProvider.this;
}
@ -222,8 +222,8 @@ public class TestSampleProvider extends AbstractSampleProvider<TestSampleProvide
}
@Override
public int getKind() {
return kind;
public ActivityKind getKind() {
return ActivityKind.fromCode(kind);
}
@Override

View File

@ -26,6 +26,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.TLW64ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.TLW64ActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class TLW64SampleProvider extends AbstractSampleProvider<TLW64ActivitySample> {
@ -63,13 +64,13 @@ public class TLW64SampleProvider extends AbstractSampleProvider<TLW64ActivitySam
}
@Override
public int normalizeType(int rawType) {
return rawType;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
return activityKind;
public int toRawActivityKind(ActivityKind activityKind) {
return activityKind.getCode();
}
@Override

View File

@ -39,9 +39,9 @@ public class VivomoveHrSampleProvider extends AbstractSampleProvider<VivomoveHrA
}
@Override
public int normalizeType(int rawType) {
public ActivityKind normalizeType(int rawType) {
if (rawType == RAW_NOT_WORN) {
return ActivityKind.TYPE_NOT_WORN;
return ActivityKind.NOT_WORN;
}
switch (rawType & RAW_TYPE_KIND_MASK) {
@ -51,105 +51,95 @@ public class VivomoveHrSampleProvider extends AbstractSampleProvider<VivomoveHrA
return normalizeSleepType(rawType & ~RAW_TYPE_KIND_MASK);
default:
// ???
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
private static int normalizeActivityType(int rawType) {
private static ActivityKind normalizeActivityType(int rawType) {
switch (rawType) {
case 0:
// generic
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case 1:
// running
return ActivityKind.TYPE_RUNNING;
return ActivityKind.RUNNING;
case 2:
// cycling
return ActivityKind.TYPE_CYCLING;
return ActivityKind.CYCLING;
case 3:
// transition
return ActivityKind.TYPE_ACTIVITY | ActivityKind.TYPE_RUNNING | ActivityKind.TYPE_WALKING | ActivityKind.TYPE_EXERCISE | ActivityKind.TYPE_SWIMMING;
return ActivityKind.VIVOMOVE_HR_TRANSITION;
case 4:
// fitness_equipment
return ActivityKind.TYPE_EXERCISE;
return ActivityKind.EXERCISE;
case 5:
// swimming
return ActivityKind.TYPE_SWIMMING;
return ActivityKind.SWIMMING;
case 6:
// walking
return ActivityKind.TYPE_WALKING;
return ActivityKind.WALKING;
case 8:
// sedentary
// TODO?
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
default:
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
private static int normalizeSleepType(int rawType) {
private static ActivityKind normalizeSleepType(int rawType) {
switch (rawType) {
case 0:
// deep_sleep
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case 1:
// light_sleep
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
case 2:
// awake
case 3:
// more_awake
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
default:
// ?
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_NOT_WORN:
case NOT_WORN:
return RAW_NOT_WORN;
case ActivityKind.TYPE_ACTIVITY:
case ACTIVITY:
// generic
//noinspection PointlessBitwiseExpression
return RAW_TYPE_KIND_ACTIVITY | 0;
case ActivityKind.TYPE_RUNNING:
case RUNNING:
// running
return RAW_TYPE_KIND_ACTIVITY | 1;
case ActivityKind.TYPE_CYCLING:
case CYCLING:
// cycling
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;
case ActivityKind.TYPE_EXERCISE:
case EXERCISE:
// fitness_equipment
return RAW_TYPE_KIND_ACTIVITY | 4;
case ActivityKind.TYPE_SWIMMING:
case SWIMMING:
// swimming
return RAW_TYPE_KIND_ACTIVITY | 5;
case ActivityKind.TYPE_WALKING:
case WALKING:
// walking
return RAW_TYPE_KIND_ACTIVITY | 6;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
return RAW_TYPE_KIND_SLEEP | 1;
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
//noinspection PointlessBitwiseExpression
return RAW_TYPE_KIND_SLEEP | 0;
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;
}
}

View File

@ -19,30 +19,16 @@ package nodomain.freeyourgadget.gadgetbridge.devices.withingssteelhr;
import androidx.annotation.NonNull;
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.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.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
import nodomain.freeyourgadget.gadgetbridge.entities.WithingsSteelHRActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.WithingsSteelHRActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.service.devices.withingssteelhr.communication.conversation.ActivitySampleHandler;
public class WithingsSteelHRSampleProvider extends AbstractSampleProvider<WithingsSteelHRActivitySample> {
private static final Logger logger = LoggerFactory.getLogger(WithingsSteelHRSampleProvider.class);
public WithingsSteelHRSampleProvider(GBDevice device, DaoSession session) {
super(device, session);
}
@ -70,28 +56,29 @@ public class WithingsSteelHRSampleProvider extends AbstractSampleProvider<Within
return WithingsSteelHRActivitySampleDao.Properties.DeviceId;
}
@NonNull
@Override
public List<WithingsSteelHRActivitySample> getActivitySamples(int timestamp_from, int timestamp_to) {
return super.getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ALL);
public ActivityKind normalizeType(int rawType) {
switch (rawType) {
case 1:
return ActivityKind.LIGHT_SLEEP;
case 2:
return ActivityKind.DEEP_SLEEP;
default:
return ActivityKind.fromCode(rawType);
}
}
@Override
public int normalizeType(int rawType) {
return rawType;
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_UNKNOWN:
case UNKNOWN:
return 0;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
return 1;
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
return 2;
default:
return activityKind;
return activityKind.getCode();
}
}

View File

@ -67,15 +67,15 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
}
@Override
public int normalizeType(final int rawType) {
public ActivityKind normalizeType(final int rawType) {
// TODO
return rawType;
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(final int activityKind) {
public int toRawActivityKind(final ActivityKind activityKind) {
// TODO
return activityKind;
return activityKind.getCode();
}
@Override
@ -89,8 +89,8 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
}
@Override
protected List<XiaomiActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to, final int activityType) {
final List<XiaomiActivitySample> samples = super.getGBActivitySamples(timestamp_from, timestamp_to, activityType);
protected List<XiaomiActivitySample> getGBActivitySamples(final int timestamp_from, final int timestamp_to) {
final List<XiaomiActivitySample> samples = super.getGBActivitySamples(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}
*/
private static int getActivityKindForSample(final XiaomiSleepStageSample sample) {
private static ActivityKind getActivityKindForSample(final XiaomiSleepStageSample sample) {
switch (sample.getStage()) {
case 2:
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
case 3:
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
case 4:
return ActivityKind.TYPE_REM_SLEEP;
return ActivityKind.REM_SLEEP;
default: // default to awake
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
@ -122,7 +122,7 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
* found.
*/
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());
@ -157,8 +157,8 @@ public class XiaomiSampleProvider extends AbstractSampleProvider<XiaomiActivityS
final XiaomiSleepTimeSample lastSleepTimesBeforeRange = sleepTimeSampleProvider.getLastSampleBefore(timestamp_from * 1000L);
if (lastSleepTimesBeforeRange != null) {
stagesMap.put(lastSleepTimesBeforeRange.getWakeupTime(), ActivityKind.TYPE_UNKNOWN);
stagesMap.put(lastSleepTimesBeforeRange.getTimestamp(), ActivityKind.TYPE_LIGHT_SLEEP);
stagesMap.put(lastSleepTimesBeforeRange.getWakeupTime(), ActivityKind.UNKNOWN);
stagesMap.put(lastSleepTimesBeforeRange.getTimestamp(), ActivityKind.LIGHT_SLEEP);
}
// 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) {
if (sleepStagesInRange.isEmpty()) {
// 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)
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) {
final long ts = sample.getTimestamp() * 1000L;
final Integer sleepType = stagesMap.get(ts);
if (sleepType != null && !sleepType.equals(ActivityKind.TYPE_UNKNOWN)) {
sample.setRawKind(sleepType);
final ActivityKind sleepType = stagesMap.get(ts);
if (sleepType != null && !sleepType.equals(ActivityKind.UNKNOWN)) {
sample.setRawKind(sleepType.getCode());
switch (sleepType) {
case ActivityKind.TYPE_DEEP_SLEEP:
case DEEP_SLEEP:
sample.setRawIntensity(20);
break;
case ActivityKind.TYPE_LIGHT_SLEEP:
case LIGHT_SLEEP:
sample.setRawIntensity(30);
break;
case ActivityKind.TYPE_REM_SLEEP:
case REM_SLEEP:
sample.setRawIntensity(40);
break;
}

View File

@ -36,12 +36,12 @@ public class XWatchSampleProvider extends AbstractSampleProvider<XWatchActivityS
}
@Override
public int normalizeType(int rawType) {
return ActivityKind.TYPE_ACTIVITY;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.ACTIVITY;
}
@Override
public int toRawActivityKind(int activityKind) {
public int toRawActivityKind(ActivityKind activityKind) {
return TYPE_ACTIVITY;
}

View File

@ -25,6 +25,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
import nodomain.freeyourgadget.gadgetbridge.entities.ZeTimeActivitySample;
import nodomain.freeyourgadget.gadgetbridge.entities.ZeTimeActivitySampleDao;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class ZeTimeSampleProvider extends AbstractSampleProvider<ZeTimeActivitySample> {
@ -40,13 +41,13 @@ public class ZeTimeSampleProvider extends AbstractSampleProvider<ZeTimeActivityS
}
@Override
public int normalizeType(int rawType) {
return rawType;
public ActivityKind normalizeType(int rawType) {
return ActivityKind.fromCode(rawType);
}
@Override
public int toRawActivityKind(int activityKind) {
return activityKind;
public int toRawActivityKind(ActivityKind activityKind) {
return activityKind.getCode();
}
@Override

View File

@ -17,14 +17,15 @@
package nodomain.freeyourgadget.gadgetbridge.entities;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
public abstract class AbstractActivitySample implements ActivitySample {
private SampleProvider mProvider;
private SampleProvider<?> mProvider;
@Override
public SampleProvider getProvider() {
public SampleProvider<?> getProvider() {
return mProvider;
}
@ -33,7 +34,7 @@ public abstract class AbstractActivitySample implements ActivitySample {
}
@Override
public int getKind() {
public ActivityKind getKind() {
return getProvider().normalizeType(getRawKind());
}
@ -90,7 +91,7 @@ public abstract class AbstractActivitySample implements ActivitySample {
@Override
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;
return getClass().getSimpleName() + "{" +
"timestamp=" + DateTimeUtils.formatDateTime(DateTimeUtils.parseTimeStamp(getTimestamp())) +

View File

@ -21,7 +21,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public abstract class AbstractPebbleHealthActivitySample extends AbstractActivitySample {
abstract public byte[] getRawPebbleHealthData();
private transient int rawActivityKind = ActivityKind.TYPE_UNKNOWN;
private transient int rawActivityKind = ActivityKind.UNKNOWN.getCode();
@Override
public int getRawKind() {

View File

@ -23,7 +23,7 @@ public abstract class AbstractPebbleMisfitActivitySample extends AbstractActivit
private transient int intensity = 0;
private transient int steps = 0;
private transient int activityKind = ActivityKind.TYPE_UNKNOWN;
private transient ActivityKind activityKind = ActivityKind.UNKNOWN;
private void calculate() {
int sample = getRawPebbleMisfitSample();
@ -33,10 +33,10 @@ public abstract class AbstractPebbleMisfitActivitySample extends AbstractActivit
intensity = (sample & 0x7c00) >>> 10;
// 9-18 decimal after shift
if (intensity <= 13) {
activityKind = ActivityKind.TYPE_DEEP_SLEEP;
activityKind = ActivityKind.DEEP_SLEEP;
} else {
// 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
}
} else {
@ -46,7 +46,7 @@ public abstract class AbstractPebbleMisfitActivitySample extends AbstractActivit
steps = (sample & 0x000e);
}
intensity = steps;
activityKind = ActivityKind.TYPE_ACTIVITY;
activityKind = ActivityKind.ACTIVITY;
}
}
@ -57,7 +57,7 @@ public abstract class AbstractPebbleMisfitActivitySample extends AbstractActivit
}
@Override
public int getKind() {
public ActivityKind getKind() {
calculate();
return activityKind;
}

View File

@ -21,13 +21,13 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public abstract class AbstractPebbleMorpheuzActivitySample extends AbstractActivitySample {
@Override
public int getKind() {
public ActivityKind getKind() {
int rawIntensity = getRawIntensity();
if (rawIntensity <= 120) {
return ActivityKind.TYPE_DEEP_SLEEP;
return ActivityKind.DEEP_SLEEP;
} else if (rawIntensity <= 1000) {
return ActivityKind.TYPE_LIGHT_SLEEP;
return ActivityKind.LIGHT_SLEEP;
}
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
}
}

View File

@ -112,22 +112,22 @@ public class OpenTracksController extends Activity {
sendIntent(context, "de.dennisguse.opentracks.publicapi.StartRecording", null, null);
}
public static void startRecording(Context context, int activityKind) {
final String category = ActivityKind.asString(activityKind, context);
public static void startRecording(Context context, ActivityKind activityKind) {
final String category = activityKind.getLabel(context);
final String icon;
switch (activityKind) {
case ActivityKind.TYPE_CYCLING:
case CYCLING:
icon = "BIKE";
break;
case ActivityKind.TYPE_HIKING:
case ActivityKind.TYPE_WALKING:
case HIKING:
case WALKING:
icon = "WALK";
break;
case ActivityKind.TYPE_RUNNING:
case RUNNING:
icon = "RUN";
break;
default:
LOG.warn("Unmapped activity kind icon for {}", String.format("0x%X", activityKind));
LOG.warn("Unmapped activity kind icon for {}", activityKind);
icon = null;
}

View File

@ -16,21 +16,17 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.model;
import android.content.Context;
import java.util.Date;
import nodomain.freeyourgadget.gadgetbridge.R;
public class ActivityAmount {
private final int activityKind;
private final ActivityKind activityKind;
private short percent;
private long totalSeconds;
private long totalSteps;
private Date startDate = null;
private Date endDate = null;
public ActivityAmount(int activityKind) {
public ActivityAmount(ActivityKind activityKind) {
this.activityKind = activityKind;
}
@ -50,7 +46,7 @@ public class ActivityAmount {
return totalSteps;
}
public int getActivityKind() {
public ActivityKind getActivityKind() {
return activityKind;
}
@ -62,16 +58,6 @@ public class ActivityAmount {
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() {
return startDate;
}

View File

@ -20,238 +20,97 @@ package nodomain.freeyourgadget.gadgetbridge.model;
import android.content.Context;
import androidx.annotation.DrawableRes;
import java.util.Arrays;
import androidx.annotation.StringRes;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
public class ActivityKind {
public static final int TYPE_NOT_MEASURED = -1;
public static final int TYPE_UNKNOWN = 0x00000000;
public static final int TYPE_ACTIVITY = 0x00000001;
public static final int TYPE_LIGHT_SLEEP = 0x00000002;
public static final int TYPE_DEEP_SLEEP = 0x00000004;
public static final int TYPE_NOT_WORN = 0x00000008;
public static final int TYPE_RUNNING = 0x00000010;
public static final int TYPE_WALKING = 0x00000020;
public static final int TYPE_SWIMMING = 0x00000040;
public static final int TYPE_CYCLING = 0x00000080;
public static final int TYPE_TREADMILL = 0x00000100;
public static final int TYPE_EXERCISE = 0x00000200;
public static final int TYPE_SWIMMING_OPENWATER = 0x00000400;
public static final int TYPE_INDOOR_CYCLING = 0x00000800;
public static final int TYPE_ELLIPTICAL_TRAINER = 0x00001000;
public static final int TYPE_JUMP_ROPING = 0x00002000;
public static final int TYPE_YOGA = 0x00004000;
public static final int TYPE_SOCCER = 0x00008000;
public static final int TYPE_ROWING_MACHINE = 0x00010000;
public static final int TYPE_CRICKET = 0x00020000;
public static final int TYPE_BASKETBALL = 0x00040000;
public static final int TYPE_PINGPONG = 0x00080000;
public static final int TYPE_BADMINTON = 0x00100000;
public static final int TYPE_STRENGTH_TRAINING = 0x00200000;
public static final int TYPE_HIKING = 0x00400000;
public static final int TYPE_CLIMBING = 0x00800000;
public static final int TYPE_REM_SLEEP = 0x01000000;
public static final int TYPE_AWAKE_SLEEP = 0x02000000;
public enum ActivityKind {
NOT_MEASURED(-1, R.string.activity_type_not_measured, R.drawable.ic_activity_not_measured),
UNKNOWN(0x00000000, R.string.activity_type_unknown),
ACTIVITY(0x00000001, R.string.activity_type_activity),
LIGHT_SLEEP(0x00000002, R.string.activity_type_light_sleep, R.drawable.ic_activity_sleep),
DEEP_SLEEP(0x00000004, R.string.activity_type_deep_sleep, R.drawable.ic_activity_sleep),
NOT_WORN(0x00000008, R.string.activity_type_not_worn),
RUNNING(0x00000010, R.string.activity_type_running, R.drawable.ic_activity_running),
WALKING(0x00000020, R.string.activity_type_walking, R.drawable.ic_activity_walking),
SWIMMING(0x00000040, R.string.activity_type_swimming, R.drawable.ic_activity_swimming),
CYCLING(0x00000080, R.string.activity_type_biking, R.drawable.ic_activity_biking),
TREADMILL(0x00000100, R.string.activity_type_treadmill, R.drawable.ic_activity_threadmill),
EXERCISE(0x00000200, R.string.activity_type_exercise, R.drawable.ic_activity_exercise),
SWIMMING_OPENWATER(0x00000400, R.string.activity_type_swimming_openwater, R.drawable.ic_activity_swimming),
INDOOR_CYCLING(0x00000800, R.string.activity_type_indoor_cycling, R.drawable.ic_activity_bike_trainer),
ELLIPTICAL_TRAINER(0x00001000, R.string.activity_type_elliptical_trainer, R.drawable.ic_activity_eliptical),
JUMP_ROPING(0x00002000, R.string.activity_type_jump_roping, R.drawable.ic_activity_rope_jump),
YOGA(0x00004000, R.string.activity_type_yoga, R.drawable.ic_activity_yoga),
SOCCER(0x00008000, R.string.activity_type_soccer, R.drawable.ic_activity_soccer),
ROWING_MACHINE(0x00010000, R.string.activity_type_rowing_machine, R.drawable.ic_activity_rowing),
CRICKET(0x00020000, R.string.activity_type_cricket, R.drawable.ic_activity_cricket),
BASKETBALL(0x00040000, R.string.activity_type_basketball, R.drawable.ic_activity_basketball),
PINGPONG(0x00080000, R.string.activity_type_pingpong, R.drawable.ic_activity_pingpong),
BADMINTON(0x00100000, R.string.activity_type_badminton, R.drawable.ic_activity_badmington),
STRENGTH_TRAINING(0x00200000, R.string.activity_type_strength_training),
HIKING(0x00400000, R.string.activity_type_hiking, R.drawable.ic_activity_hiking),
CLIMBING(0x00800000, R.string.activity_type_climbing, R.drawable.ic_activity_climbing),
REM_SLEEP(0x01000000, R.string.abstract_chart_fragment_kind_rem_sleep, R.drawable.ic_activity_sleep),
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;
public static final int TYPE_ALL = TYPE_ACTIVITY | TYPE_SLEEP | TYPE_NOT_WORN;
private final int code;
private final int label;
private final int icon;
public static int[] mapToDBActivityTypes(int types, SampleProvider provider) {
int[] result = new int[TYPES_COUNT];
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);
ActivityKind(final int code) {
this(code, R.string.activity_type_unknown);
}
return Arrays.copyOf(result, i);
ActivityKind(final int code, @StringRes final int label) {
this(code, label, R.drawable.ic_activity_unknown_small);
}
public static String asString(int kind, Context context) {
switch (kind) {
case TYPE_NOT_MEASURED:
return context.getString(R.string.activity_type_not_measured);
case TYPE_ACTIVITY:
return context.getString(R.string.activity_type_activity);
case TYPE_LIGHT_SLEEP:
return context.getString(R.string.activity_type_light_sleep);
case TYPE_DEEP_SLEEP:
return context.getString(R.string.activity_type_deep_sleep);
case TYPE_NOT_WORN:
return context.getString(R.string.activity_type_not_worn);
case TYPE_RUNNING:
return context.getString(R.string.activity_type_running);
case TYPE_WALKING:
return context.getString(R.string.activity_type_walking);
case TYPE_HIKING:
return context.getString(R.string.activity_type_hiking);
case TYPE_CLIMBING:
return context.getString(R.string.activity_type_climbing);
case TYPE_SWIMMING:
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);
ActivityKind(final int code, @StringRes final int label, @DrawableRes final int icon) {
this.code = code;
this.label = label;
this.icon = icon;
}
public int getCode() {
return code;
}
@StringRes
public int getLabel() {
return label;
}
public String getLabel(final Context context) {
return context.getString(label);
}
@DrawableRes
public static int getIconId(int kind) {
switch (kind) {
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
public int getIcon() {
return icon;
}
case TYPE_NOT_WORN: // fall through
case TYPE_ACTIVITY: // fall through
case TYPE_UNKNOWN: // fall through
default:
return R.drawable.ic_activity_unknown_small;
public static ActivityKind fromCode(final int code) {
for (final ActivityKind kind : ActivityKind.values()) {
if (kind.code == code) {
return kind;
}
}
//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;
}
}

View File

@ -43,7 +43,7 @@ public interface ActivitySample extends TimeStamped {
*
* @return who created the sample data
*/
SampleProvider getProvider();
SampleProvider<?> getProvider();
/**
* Returns the raw activity kind value as recorded by the SampleProvider
@ -55,7 +55,7 @@ public interface ActivitySample extends TimeStamped {
*
* @see ActivityKind
*/
int getKind();
ActivityKind getKind();
/**
* Returns the raw intensity value as recorded by the SampleProvider

View File

@ -34,7 +34,7 @@ public class ActivitySession implements Serializable {
private final int heartRateAverage;
private final float intensity;
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
// it is identified by SESSION_SUMMARY
private int sessionCount = 0;
@ -45,7 +45,7 @@ public class ActivitySession implements Serializable {
public ActivitySession(Date startTime,
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.endTime = endTime;
this.activeSteps = steps;
@ -62,7 +62,7 @@ public class ActivitySession implements Serializable {
this.heartRateAverage = 0;
this.intensity = 0;
this.distance = 0;
this.activityKind = 0;
this.activityKind = ActivityKind.UNKNOWN;
};
public Date getStartTime() {
@ -81,7 +81,7 @@ public class ActivitySession implements Serializable {
return heartRateAverage;
}
public int getActivityKind() {
public ActivityKind getActivityKind() {
return activityKind;
}

View File

@ -93,11 +93,11 @@ public class DailyTotals {
long totalSecondsLightSleep = 0;
long totalSecondsRemSleep = 0;
for (ActivityAmount amount : activityAmounts.getAmounts()) {
if (amount.getActivityKind() == ActivityKind.TYPE_DEEP_SLEEP) {
if (amount.getActivityKind() == ActivityKind.DEEP_SLEEP) {
totalSecondsDeepSleep += amount.getTotalSeconds();
} else if (amount.getActivityKind() == ActivityKind.TYPE_LIGHT_SLEEP) {
} else if (amount.getActivityKind() == ActivityKind.LIGHT_SLEEP) {
totalSecondsLightSleep += amount.getTotalSeconds();
} else if (amount.getActivityKind() == ActivityKind.TYPE_REM_SLEEP) {
} else if (amount.getActivityKind() == ActivityKind.REM_SLEEP) {
totalSecondsRemSleep += amount.getTotalSeconds();
}
}

View File

@ -390,17 +390,17 @@ class BangleJSActivityTrack {
summary.setName(log);
summary.setStartTime(startTime);
summary.setEndTime(endTime);
int activityKind;
ActivityKind activityKind;
if (analyticsObject.has("Speed")) {
if ((float) 3 > averageOfJSONArray(analyticsObject.getJSONArray("Speed"))) {
activityKind = ActivityKind.TYPE_WALKING;
activityKind = ActivityKind.WALKING;
} else {
activityKind = ActivityKind.TYPE_RUNNING;
activityKind = ActivityKind.RUNNING;
}
} 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));
@ -577,23 +577,23 @@ class BangleJSActivityTrack {
ActivityTrackExporter exporter = createExporter();
String trackType = "track";
switch (summary.getActivityKind()) {
case ActivityKind.TYPE_CYCLING:
switch (ActivityKind.fromCode(summary.getActivityKind())) {
case CYCLING:
trackType = context.getString(R.string.activity_type_biking);
break;
case ActivityKind.TYPE_RUNNING:
case RUNNING:
trackType = context.getString(R.string.activity_type_running);
break;
case ActivityKind.TYPE_WALKING:
case WALKING:
trackType = context.getString(R.string.activity_type_walking);
break;
case ActivityKind.TYPE_HIKING:
case HIKING:
trackType = context.getString(R.string.activity_type_hiking);
break;
case ActivityKind.TYPE_CLIMBING:
case CLIMBING:
trackType = context.getString(R.string.activity_type_climbing);
break;
case ActivityKind.TYPE_SWIMMING:
case SWIMMING:
trackType = context.getString(R.string.activity_type_swimming);
break;
}

View File

@ -225,9 +225,9 @@ public class FetchStepCountDataOperation extends AbstractBTLEOperation<CasioGBX
stepCountData.get(packetIndex/2).setSteps(count);
stepCountData.get(packetIndex/2).setTimestamp(ts);
if(count > 0) {
stepCountData.get(packetIndex / 2).setRawKind(ActivityKind.TYPE_ACTIVITY);
stepCountData.get(packetIndex / 2).setRawKind(ActivityKind.ACTIVITY.getCode());
} 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) {
stepsToday += count;
@ -269,9 +269,9 @@ public class FetchStepCountDataOperation extends AbstractBTLEOperation<CasioGBX
sample.setCalories(cals);
sample.setTimestamp(ts);
if (steps > 0)
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
else
sample.setRawKind(ActivityKind.TYPE_NOT_MEASURED);
sample.setRawKind(ActivityKind.NOT_MEASURED.getCode());
stepCountData.add(0, sample);
}

View File

@ -405,7 +405,7 @@ public class CmfActivitySync {
BaseActivitySummary summary = new BaseActivitySummary();
summary.setRawSummaryData(summaryBytes);
summary.setActivityKind(ActivityKind.TYPE_UNKNOWN);
summary.setActivityKind(ActivityKind.UNKNOWN.getCode());
try {
summary = summaryParser.parseBinaryData(summary);

View File

@ -24,28 +24,28 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public enum CmfActivityType {
// Core (non-removable in official app)
INDOOR_RUNNING(0x03, R.string.activity_type_indoor_running, ActivityKind.TYPE_RUNNING),
OUTDOOR_RUNNING(0x02, R.string.activity_type_outdoor_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.RUNNING),
// Fitness
OUTDOOR_WALKING(0x01, R.string.activity_type_outdoor_walking, ActivityKind.TYPE_WALKING),
INDOOR_WALKING(0x19, R.string.activity_type_indoor_walking, ActivityKind.TYPE_WALKING),
OUTDOOR_CYCLING(0x05, R.string.activity_type_outdoor_cycling, ActivityKind.TYPE_CYCLING),
INDOOR_CYCLING(0x72, R.string.activity_type_indoor_cycling, ActivityKind.TYPE_INDOOR_CYCLING),
MOUNTAIN_HIKE(0x04, R.string.activity_type_mountain_hike, ActivityKind.TYPE_HIKING),
HIKING(0x1A, R.string.activity_type_hiking, ActivityKind.TYPE_HIKING),
OUTDOOR_WALKING(0x01, R.string.activity_type_outdoor_walking, ActivityKind.WALKING),
INDOOR_WALKING(0x19, R.string.activity_type_indoor_walking, ActivityKind.WALKING),
OUTDOOR_CYCLING(0x05, R.string.activity_type_outdoor_cycling, ActivityKind.CYCLING),
INDOOR_CYCLING(0x72, R.string.activity_type_indoor_cycling, ActivityKind.INDOOR_CYCLING),
MOUNTAIN_HIKE(0x04, R.string.activity_type_mountain_hike, ActivityKind.HIKING),
HIKING(0x1A, R.string.activity_type_hiking, ActivityKind.HIKING),
CROSS_TRAINER(0x18, R.string.activity_type_cross_trainer),
FREE_TRAINING(0x10, R.string.activity_type_free_training, ActivityKind.TYPE_STRENGTH_TRAINING),
STRENGTH_TRAINING(0x13, R.string.activity_type_strength_training, ActivityKind.TYPE_STRENGTH_TRAINING),
YOGA(0x0F, R.string.activity_type_yoga, ActivityKind.TYPE_YOGA),
FREE_TRAINING(0x10, R.string.activity_type_free_training, ActivityKind.STRENGTH_TRAINING),
STRENGTH_TRAINING(0x13, R.string.activity_type_strength_training, ActivityKind.STRENGTH_TRAINING),
YOGA(0x0F, R.string.activity_type_yoga, ActivityKind.YOGA),
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),
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),
HIIT(0x5C, R.string.activity_type_hiit),
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),
CROSSFIT(0x74, R.string.activity_type_crossfit),
FUNCTIONAL_TRAINING(0x2E, R.string.activity_type_functional_training),
@ -106,7 +106,7 @@ public enum CmfActivityType {
KARTING(0xA0, R.string.activity_type_karting),
// Ball sports
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),
BILLIARDS(0x7C, R.string.activity_type_billiards),
BOWLING(0x3B, R.string.activity_type_bowling),
@ -120,8 +120,8 @@ public enum CmfActivityType {
HOCKEY(0x1E, R.string.activity_type_hockey),
SQUASH(0x3C, R.string.activity_type_squash),
DODGEBALL(0x81, R.string.activity_type_dodgeball),
SOCCER(0x07, R.string.activity_type_soccer, ActivityKind.TYPE_SOCCER),
BASKETBALL(0x08, R.string.activity_type_basketball, ActivityKind.TYPE_BASKETBALL),
SOCCER(0x07, R.string.activity_type_soccer, ActivityKind.SOCCER),
BASKETBALL(0x08, R.string.activity_type_basketball, ActivityKind.BASKETBALL),
AUSTRALIAN_FOOTBALL(0x37, R.string.activity_type_australian_football),
GOLF(0x45, R.string.activity_type_golf),
PICKLEBALL(0x5B, R.string.activity_type_pickleball),
@ -157,13 +157,13 @@ public enum CmfActivityType {
private final byte code;
@StringRes
private final int nameRes;
private final int activityKind;
private final ActivityKind activityKind;
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.nameRes = nameRes;
this.activityKind = activityKind;
@ -173,7 +173,7 @@ public enum CmfActivityType {
return code;
}
public int getActivityKind() {
public ActivityKind getActivityKind() {
return activityKind;
}

View File

@ -1,6 +1,6 @@
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.BluetoothGattCharacteristic;

View File

@ -1355,7 +1355,7 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport {
sample.setSpo2Percent(spo2);
sample.setTimestamp((int) (date.getTimeInMillis() / 1000));
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
addGBActivitySample(sample);
broadcastSample(sample);
@ -1394,7 +1394,7 @@ public class FitProDeviceSupport extends AbstractBTLEDeviceSupport {
sample.setSteps(newSteps);
sample.setDistanceMeters(distance);
sample.setCaloriesBurnt(calories);
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
sample.setRawKind(ActivityKind.ACTIVITY);
sample.setRawIntensity(1);
addGBActivitySample(sample);
broadcastSample(sample);

View File

@ -285,18 +285,18 @@ public class FitImporter {
LOG.debug("Persisting workout for {}", fileId);
final BaseActivitySummary summary = new BaseActivitySummary();
summary.setActivityKind(ActivityKind.TYPE_UNKNOWN);
summary.setActivityKind(ActivityKind.UNKNOWN.getCode());
final ActivitySummaryData summaryData = new ActivitySummaryData();
final int activityKind;
final ActivityKind activityKind;
if (sport != null) {
summary.setName(sport.getName());
activityKind = getActivityKind(sport.getSport(), sport.getSubSport());
} else {
activityKind = getActivityKind(session.getSport(), session.getSubSport());
}
summary.setActivityKind(activityKind);
summary.setActivityKind(activityKind.getCode());
if (session.getStartTime() == null) {
LOG.error("No session start time for {}", fileId);
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);
if (garminSport.isEmpty()) {
LOG.warn("Unknown garmin sport {}/{}", sport, subsport);
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
switch (garminSport.get()) {
@ -367,48 +367,48 @@ public class FitImporter {
case PUSH_RUN_SPEED:
case INDOOR_PUSH_RUN_SPEED:
case INDOOR_TRACK:
return ActivityKind.TYPE_RUNNING;
return ActivityKind.RUNNING;
case TREADMILL:
return ActivityKind.TYPE_TREADMILL;
return ActivityKind.TREADMILL;
case E_BIKE:
case BIKE:
case BIKE_COMMUTE:
return ActivityKind.TYPE_CYCLING;
return ActivityKind.CYCLING;
case BIKE_INDOOR:
return ActivityKind.TYPE_INDOOR_CYCLING;
return ActivityKind.INDOOR_CYCLING;
case ELLIPTICAL:
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
return ActivityKind.ELLIPTICAL_TRAINER;
case STAIR_STEPPER:
case PILATES:
case CARDIO:
return ActivityKind.TYPE_EXERCISE;
return ActivityKind.EXERCISE;
case POOL_SWIM:
return ActivityKind.TYPE_SWIMMING;
return ActivityKind.SWIMMING;
case OPEN_WATER:
return ActivityKind.TYPE_SWIMMING_OPENWATER;
return ActivityKind.SWIMMING_OPENWATER;
case SOCCER:
return ActivityKind.TYPE_SOCCER;
return ActivityKind.SOCCER;
case STRENGTH:
return ActivityKind.TYPE_STRENGTH_TRAINING;
return ActivityKind.STRENGTH_TRAINING;
case YOGA:
return ActivityKind.TYPE_YOGA;
return ActivityKind.YOGA;
case WALK:
case WALK_INDOOR:
case PUSH_WALK_SPEED:
case INDOOR_PUSH_WALK_SPEED:
return ActivityKind.TYPE_WALKING;
return ActivityKind.WALKING;
case HIKE:
return ActivityKind.TYPE_HIKING;
return ActivityKind.HIKING;
case CLIMB_INDOOR:
case BOULDERING:
return ActivityKind.TYPE_CLIMBING;
return ActivityKind.CLIMBING;
case BASKETBALL:
return ActivityKind.TYPE_BASKETBALL;
return ActivityKind.BASKETBALL;
case JUMP_ROPE:
return ActivityKind.TYPE_JUMP_ROPING;
return ActivityKind.JUMP_ROPING;
}
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
private void reset() {
@ -440,7 +440,7 @@ public class FitImporter {
final Map<Integer, Long> stepsPerActivity = new HashMap<>();
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;
for (final int ts : activitySamplesPerTimestamp.keySet()) {
@ -449,7 +449,7 @@ public class FitImporter {
for (int i = prevTs; i < ts; i += 60) {
final GarminActivitySample sample = new GarminActivitySample();
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.setSteps(ActivitySample.NOT_MEASURED);
activitySamples.add(sample);
@ -460,7 +460,7 @@ public class FitImporter {
final GarminActivitySample sample = new GarminActivitySample();
sample.setTimestamp(ts);
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
sample.setRawIntensity(ActivitySample.NOT_MEASURED);
sample.setSteps(ActivitySample.NOT_MEASURED);
sample.setHeartRate(ActivitySample.NOT_MEASURED);

View File

@ -18,11 +18,9 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
/*
/**
* @author João Paulo Barraca &lt;jpbarraca@gmail.com&gt;
*/
public class HPlusDataRecord {
public final static int TYPE_UNKNOWN = 0;
public final static int TYPE_SLEEP = 100;
@ -31,7 +29,7 @@ public class HPlusDataRecord {
public final static int TYPE_REALTIME = 103;
public int type = TYPE_UNKNOWN;
public int activityKind = ActivityKind.TYPE_UNKNOWN;
public int activityKindRaw = ActivityKind.UNKNOWN.getCode();
/**
* Time of this record in seconds
@ -53,11 +51,10 @@ public class HPlusDataRecord {
}
public byte[] getRawData() {
return rawData;
}
public class RecordInterval {
public static class RecordInterval {
/**
* Start time of this interval in seconds
*/
@ -71,9 +68,9 @@ public class HPlusDataRecord {
/**
* 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.timestampTo = timestampTo;
this.activityKind = activityKind;

View File

@ -21,6 +21,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus;
*/
import androidx.annotation.NonNull;
import java.util.GregorianCalendar;
import java.util.Locale;
@ -87,16 +89,16 @@ class HPlusDataRecordRealtime extends HPlusDataRecord {
battery = ActivitySample.NOT_MEASURED;
heartRate = ActivitySample.NOT_MEASURED;
intensity = 0;
activityKind = ActivityKind.TYPE_NOT_WORN;
activityKindRaw = ActivityKind.NOT_WORN.getCode();
} else {
heartRate = data[11] & 0xFF; // BPM
if (heartRate == 255) {
intensity = 0;
activityKind = ActivityKind.TYPE_NOT_MEASURED;
activityKindRaw = ActivityKind.NOT_MEASURED.getCode();
heartRate = ActivitySample.NOT_MEASURED;
} else {
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;
if(speed >= 1.6) // ~6 KM/h
activityKind = ActivityKind.TYPE_ACTIVITY;
activityKindRaw = ActivityKind.ACTIVITY.getCode();
}
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;
}
@NonNull
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);
}
}

View File

@ -128,8 +128,8 @@ public class HPlusDataRecordSleep extends HPlusDataRecord {
List<RecordInterval> intervals = new ArrayList<>();
int ts = bedTimeStart + lightSleepMinutes * 60;
intervals.add(new RecordInterval(bedTimeStart, ts, ActivityKind.TYPE_LIGHT_SLEEP));
intervals.add(new RecordInterval(ts, bedTimeEnd, ActivityKind.TYPE_DEEP_SLEEP));
intervals.add(new RecordInterval(bedTimeStart, ts, ActivityKind.LIGHT_SLEEP));
intervals.add(new RecordInterval(ts, bedTimeEnd, ActivityKind.DEEP_SLEEP));
return intervals;
}

View File

@ -321,7 +321,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
//If it is the last of the samples or of the interruption period
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;
}
@ -330,7 +330,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
}
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);
}
@ -379,7 +379,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
List<HPlusDataRecord.RecordInterval> intervals = record.getIntervals();
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);
@ -387,7 +387,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
//Store the data
HPlusHealthActivitySample sample = createSample(dbHandler, record.timestamp);
sample.setRawHPlusHealthData(record.getRawData());
sample.setRawKind(record.activityKind);
sample.setRawKind(record.activityKindRaw);
sample.setProvider(provider);
@ -631,7 +631,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
timestamp, // ts
deviceId, userId, // User id
null, // Raw Data
ActivityKind.TYPE_UNKNOWN,
ActivityKind.UNKNOWN.getCode(),
0, // Intensity
ActivitySample.NOT_MEASURED, // Steps
ActivitySample.NOT_MEASURED, // HR

View File

@ -47,48 +47,48 @@ public enum HuamiSportsActivityType {
this.code = code;
}
public int toActivityKind() {
public ActivityKind toActivityKind() {
switch (this) {
case OutdoorRunning:
return ActivityKind.TYPE_RUNNING;
return ActivityKind.RUNNING;
case OutdoorHiking:
return ActivityKind.TYPE_HIKING;
return ActivityKind.HIKING;
case Climbing:
return ActivityKind.TYPE_CLIMBING;
return ActivityKind.CLIMBING;
case Treadmill:
return ActivityKind.TYPE_TREADMILL;
return ActivityKind.TREADMILL;
case Cycling:
return ActivityKind.TYPE_CYCLING;
return ActivityKind.CYCLING;
case Walking:
return ActivityKind.TYPE_WALKING;
return ActivityKind.WALKING;
case Exercise:
return ActivityKind.TYPE_EXERCISE;
return ActivityKind.EXERCISE;
case Swimming:
return ActivityKind.TYPE_SWIMMING;
return ActivityKind.SWIMMING;
case OpenWaterSwimming:
return ActivityKind.TYPE_SWIMMING_OPENWATER;
return ActivityKind.SWIMMING_OPENWATER;
case IndoorCycling:
return ActivityKind.TYPE_INDOOR_CYCLING;
return ActivityKind.INDOOR_CYCLING;
case EllipticalTrainer:
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
return ActivityKind.ELLIPTICAL_TRAINER;
case Soccer:
return ActivityKind.TYPE_SOCCER;
return ActivityKind.SOCCER;
case JumpRope:
return ActivityKind.TYPE_JUMP_ROPING;
return ActivityKind.JUMP_ROPING;
case RowingMachine:
return ActivityKind.TYPE_ROWING_MACHINE;
return ActivityKind.ROWING_MACHINE;
case Yoga:
return ActivityKind.TYPE_YOGA;
return ActivityKind.YOGA;
case Cricket:
return ActivityKind.TYPE_CRICKET;
return ActivityKind.CRICKET;
case Basketball:
return ActivityKind.TYPE_BASKETBALL;
return ActivityKind.BASKETBALL;
case PingPong:
return ActivityKind.TYPE_PINGPONG;
return ActivityKind.PINGPONG;
case Badminton:
return ActivityKind.TYPE_BADMINTON;
return ActivityKind.BADMINTON;
case StrengthTraining:
return ActivityKind.TYPE_STRENGTH_TRAINING;
return ActivityKind.STRENGTH_TRAINING;
}
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);
}
public static HuamiSportsActivityType fromActivityKind(int activityKind) {
public static HuamiSportsActivityType fromActivityKind(ActivityKind activityKind) {
switch (activityKind) {
case ActivityKind.TYPE_RUNNING:
case RUNNING:
return OutdoorRunning;
case ActivityKind.TYPE_HIKING:
case HIKING:
return OutdoorHiking;
case ActivityKind.TYPE_CLIMBING:
case CLIMBING:
return Climbing;
case ActivityKind.TYPE_TREADMILL:
case TREADMILL:
return Treadmill;
case ActivityKind.TYPE_CYCLING:
case CYCLING:
return Cycling;
case ActivityKind.TYPE_WALKING:
case WALKING:
return Walking;
case ActivityKind.TYPE_EXERCISE:
case EXERCISE:
return Exercise;
case ActivityKind.TYPE_SWIMMING:
case SWIMMING:
return Swimming;
case ActivityKind.TYPE_SWIMMING_OPENWATER:
case SWIMMING_OPENWATER:
return OpenWaterSwimming;
case ActivityKind.TYPE_INDOOR_CYCLING:
case INDOOR_CYCLING:
return IndoorCycling;
case ActivityKind.TYPE_ELLIPTICAL_TRAINER:
case ELLIPTICAL_TRAINER:
return EllipticalTrainer;
case ActivityKind.TYPE_SOCCER:
case SOCCER:
return Soccer;
case ActivityKind.TYPE_JUMP_ROPING:
case JUMP_ROPING:
return JumpRope;
case ActivityKind.TYPE_ROWING_MACHINE:
case ROWING_MACHINE:
return RowingMachine;
case ActivityKind.TYPE_YOGA:
case YOGA:
return Yoga;
case ActivityKind.TYPE_CRICKET:
case CRICKET:
return Cricket;
case ActivityKind.TYPE_BASKETBALL:
case BASKETBALL:
return Basketball;
case ActivityKind.TYPE_PINGPONG:
case PINGPONG:
return PingPong;
case ActivityKind.TYPE_BADMINTON:
case BADMINTON:
return Badminton;
case ActivityKind.TYPE_STRENGTH_TRAINING:
case STRENGTH_TRAINING:
return StrengthTraining;
}

View File

@ -1945,11 +1945,11 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
break;
case HuamiDeviceEvent.WORKOUT_STARTING:
final HuamiWorkoutTrackActivityType activityType = HuamiWorkoutTrackActivityType.fromCode(value[3]);
final int activityKind;
final ActivityKind activityKind;
if (activityType == null) {
LOG.warn("Unknown workout activity type {}", String.format("0x%02x", value[3]));
activityKind = ActivityKind.TYPE_UNKNOWN;
activityKind = ActivityKind.UNKNOWN;
} else {
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}.
*/
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.
*/
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.workoutActivityKind = activityKind;

View File

@ -46,31 +46,31 @@ public enum HuamiWorkoutTrackActivityType {
return code;
}
public int toActivityKind() {
public ActivityKind toActivityKind() {
switch (this) {
case Elliptical:
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
return ActivityKind.ELLIPTICAL_TRAINER;
case IndoorCycling:
return ActivityKind.TYPE_INDOOR_CYCLING;
return ActivityKind.INDOOR_CYCLING;
case JumpRope:
return ActivityKind.TYPE_JUMP_ROPING;
return ActivityKind.JUMP_ROPING;
case OutdoorCycling:
return ActivityKind.TYPE_CYCLING;
return ActivityKind.CYCLING;
case OutdoorRunning:
return ActivityKind.TYPE_RUNNING;
return ActivityKind.RUNNING;
case PoolSwimming:
return ActivityKind.TYPE_SWIMMING;
return ActivityKind.SWIMMING;
case RowingMachine:
return ActivityKind.TYPE_ROWING_MACHINE;
return ActivityKind.ROWING_MACHINE;
case Treadmill:
return ActivityKind.TYPE_TREADMILL;
return ActivityKind.TREADMILL;
case Walking:
return ActivityKind.TYPE_WALKING;
return ActivityKind.WALKING;
case Yoga:
return ActivityKind.TYPE_YOGA;
return ActivityKind.YOGA;
}
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
public static HuamiWorkoutTrackActivityType fromCode(final byte code) {

View File

@ -99,23 +99,23 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
final ActivityTrack track = detailsParser.parse(buffer.toByteArray());
final ActivityTrackExporter exporter = createExporter();
final String trackType;
switch (summary.getActivityKind()) {
case ActivityKind.TYPE_CYCLING:
switch (ActivityKind.fromCode(summary.getActivityKind())) {
case CYCLING:
trackType = getContext().getString(R.string.activity_type_biking);
break;
case ActivityKind.TYPE_RUNNING:
case RUNNING:
trackType = getContext().getString(R.string.activity_type_running);
break;
case ActivityKind.TYPE_WALKING:
case WALKING:
trackType = getContext().getString(R.string.activity_type_walking);
break;
case ActivityKind.TYPE_HIKING:
case HIKING:
trackType = getContext().getString(R.string.activity_type_hiking);
break;
case ActivityKind.TYPE_CLIMBING:
case CLIMBING:
trackType = getContext().getString(R.string.activity_type_climbing);
break;
case ActivityKind.TYPE_SWIMMING:
case SWIMMING:
trackType = getContext().getString(R.string.activity_type_swimming);
break;
default:
@ -207,6 +207,7 @@ public class FetchSportsDetailsOperation extends AbstractFetchOperation {
try {
final File targetFolder = new File(FileUtils.getExternalFilesDir(), "rawDetails");
//noinspection ResultOfMethodCallIgnored
targetFolder.mkdirs();
final File targetFile = new File(targetFolder, fileName);
outputStream = new FileOutputStream(targetFile);

View File

@ -159,55 +159,55 @@ public enum ZeppOsActivityType {
return code;
}
public int toActivityKind() {
public ActivityKind toActivityKind() {
switch (this) {
case Badminton:
return ActivityKind.TYPE_BADMINTON;
return ActivityKind.BADMINTON;
case Basketball:
return ActivityKind.TYPE_BASKETBALL;
return ActivityKind.BASKETBALL;
case Cricket:
return ActivityKind.TYPE_CRICKET;
return ActivityKind.CRICKET;
case Elliptical:
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
return ActivityKind.ELLIPTICAL_TRAINER;
case Freestyle:
case IndoorFitness:
return ActivityKind.TYPE_EXERCISE;
return ActivityKind.EXERCISE;
case IndoorCycling:
return ActivityKind.TYPE_INDOOR_CYCLING;
return ActivityKind.INDOOR_CYCLING;
case JumpRope:
return ActivityKind.TYPE_JUMP_ROPING;
return ActivityKind.JUMP_ROPING;
case OutdoorCycling:
return ActivityKind.TYPE_CYCLING;
return ActivityKind.CYCLING;
case OutdoorHiking:
return ActivityKind.TYPE_HIKING;
return ActivityKind.HIKING;
case OutdoorRunning:
return ActivityKind.TYPE_RUNNING;
return ActivityKind.RUNNING;
case OutdoorSwimming:
return ActivityKind.TYPE_SWIMMING_OPENWATER;
return ActivityKind.SWIMMING_OPENWATER;
case PoolSwimming:
return ActivityKind.TYPE_SWIMMING;
return ActivityKind.SWIMMING;
case RockClimbing:
return ActivityKind.TYPE_CLIMBING;
return ActivityKind.CLIMBING;
case Rowing:
return ActivityKind.TYPE_ROWING_MACHINE;
return ActivityKind.ROWING_MACHINE;
case Soccer:
return ActivityKind.TYPE_SOCCER;
return ActivityKind.SOCCER;
case TableTennis:
return ActivityKind.TYPE_PINGPONG;
return ActivityKind.PINGPONG;
case Treadmill:
return ActivityKind.TYPE_TREADMILL;
return ActivityKind.TREADMILL;
case Walking:
case RaceWalking:
return ActivityKind.TYPE_WALKING;
return ActivityKind.WALKING;
case Strength:
return ActivityKind.TYPE_STRENGTH_TRAINING;
return ActivityKind.STRENGTH_TRAINING;
case Yoga:
return ActivityKind.TYPE_YOGA;
return ActivityKind.YOGA;
}
LOG.warn("Unmapped workout type {}", this);
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
public static ZeppOsActivityType fromCode(final byte code) {

View File

@ -1409,11 +1409,11 @@ public class ZeppOsSupport extends HuamiSupport implements ZeppOsFileTransferSer
case WORKOUT_CMD_APP_OPEN:
final ZeppOsActivityType activityType = ZeppOsActivityType.fromCode(payload[3]);
final boolean workoutNeedsGps = (payload[2] == 1);
final int activityKind;
final ActivityKind activityKind;
if (activityType == null) {
LOG.warn("Unknown workout activity type {}", String.format("0x%x", payload[3]));
activityKind = ActivityKind.TYPE_UNKNOWN;
activityKind = ActivityKind.UNKNOWN;
} else {
activityKind = activityType.toActivityKind();
}

View File

@ -122,46 +122,46 @@ public class HuaweiWorkoutGbParser {
}
}
public static int huaweiTypeToGbType(byte huaweiType) {
public static ActivityKind huaweiTypeToGbType(byte huaweiType) {
int type = huaweiType & 0xFF;
switch (type) {
case 1:
return ActivityKind.TYPE_RUNNING;
return ActivityKind.RUNNING;
case 2:
case 13:
return ActivityKind.TYPE_WALKING;
return ActivityKind.WALKING;
case 6:
return ActivityKind.TYPE_SWIMMING;
return ActivityKind.SWIMMING;
case 3:
return ActivityKind.TYPE_CYCLING;
return ActivityKind.CYCLING;
case 7:
return ActivityKind.TYPE_INDOOR_CYCLING;
return ActivityKind.INDOOR_CYCLING;
case 129:
return ActivityKind.TYPE_BADMINTON;
return ActivityKind.BADMINTON;
case 130:
return ActivityKind.TYPE_EXERCISE; // TODO: Tennis
return ActivityKind.EXERCISE; // TODO: Tennis
case 131:
return ActivityKind.TYPE_SOCCER;
return ActivityKind.SOCCER;
case 132:
return ActivityKind.TYPE_BASKETBALL;
return ActivityKind.BASKETBALL;
case 133:
return ActivityKind.TYPE_EXERCISE; // TODO: Volleyball
return ActivityKind.EXERCISE; // TODO: Volleyball
case 134:
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
return ActivityKind.ELLIPTICAL_TRAINER;
case 135:
return ActivityKind.TYPE_ROWING_MACHINE;
return ActivityKind.ROWING_MACHINE;
case 163:
return ActivityKind.TYPE_EXERCISE; // TODO: Roller skating
return ActivityKind.EXERCISE; // TODO: Roller skating
case 173:
return ActivityKind.TYPE_EXERCISE; // TODO: Laser tag
return ActivityKind.EXERCISE; // TODO: Laser tag
case 177:
return ActivityKind.TYPE_EXERCISE; // TODO: stair climbing
return ActivityKind.EXERCISE; // TODO: stair climbing
case 196:
return ActivityKind.TYPE_EXERCISE; // TODO: fishing
return ActivityKind.EXERCISE; // TODO: fishing
case 216:
return ActivityKind.TYPE_EXERCISE; // TODO: motor racing
return ActivityKind.EXERCISE; // TODO: motor racing
default:
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}
@ -204,7 +204,7 @@ public class HuaweiWorkoutGbParser {
if (!duplicates.isEmpty())
previous = duplicates.get(0);
int type = huaweiTypeToGbType(summary.getType());
ActivityKind type = huaweiTypeToGbType(summary.getType());
JSONObject jsonObject = new JSONObject();
@ -274,7 +274,7 @@ public class HuaweiWorkoutGbParser {
}
boolean unknownData = false;
if (dataSamples.size() != 0) {
if (!dataSamples.isEmpty()) {
int speed = 0;
int speedCount = 0;
boolean stepRatePresent = false;
@ -712,7 +712,7 @@ public class HuaweiWorkoutGbParser {
"Workout " + summary.getWorkoutNumber(),
start,
end,
type,
type.getCode(),
null,
null,
null,
@ -729,7 +729,7 @@ public class HuaweiWorkoutGbParser {
previous.getName(),
start,
end,
type,
type.getCode(),
previous.getBaseLongitude(),
previous.getBaseLatitude(),
previous.getBaseAltitude(),

View File

@ -60,7 +60,7 @@ public class FetchActivityOperation extends AbstractID115Operation {
outputStream.write(0x01);
outputStream.write(0x00);
outputStream.write(0x00);
byte cmd[] = outputStream.toByteArray();
byte[] cmd = outputStream.toByteArray();
expectedCmd = ID115Constants.CMD_KEY_FETCH_ACTIVITY_TODAY;
expectedSeq = 1;
@ -74,7 +74,7 @@ public class FetchActivityOperation extends AbstractID115Operation {
@Override
void handleResponse(byte[] data) {
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);
return;
}
@ -97,7 +97,7 @@ public class FetchActivityOperation extends AbstractID115Operation {
}
expectedSeq += 1;
byte payload[] = new byte[data.length - 4];
byte[] payload = new byte[data.length - 4];
System.arraycopy(data, 4, payload, 0, payload.length);
packets.add(payload);
}
@ -129,7 +129,7 @@ public class FetchActivityOperation extends AbstractID115Operation {
ID115ActivitySample sample = parseSample(sampleData);
if (sample != null) {
sample.setTimestamp(ts);
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
samples.add(sample);
}
ts += dt;

View File

@ -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 &lt;elagin.pasha@gmail.com&gt;
*/
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;
}
}
}

View File

@ -1633,7 +1633,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
sample.setTimestamp(tsWithOffset);
sample.setProvider(provider);
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);
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.setHeartRate(val);
sample.setProvider(provider);
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
samples.add(sample);
}
provider.addGBActivitySamples(samples.toArray(new WatchXPlusActivitySample[0]));
@ -1777,7 +1777,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
WatchXPlusActivitySample sample = createSample(dbHandler, timestamp);
sample.setTimestamp(timestamp);
// sample.setRawKind(record.type);
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
sample.setSteps(newSteps);
// sample.setDistance(record.distance);
// sample.setCalories(record.calories);
@ -1846,7 +1846,7 @@ public class WatchXPlusDeviceSupport extends AbstractBTLEDeviceSupport {
timestamp, // ts
deviceId, userId, // User id
null, // Raw Data
ActivityKind.TYPE_UNKNOWN, // rawKind
ActivityKind.UNKNOWN.getCode(), // rawKind
ActivitySample.NOT_MEASURED, // rawIntensity
ActivitySample.NOT_MEASURED, // Steps
ActivitySample.NOT_MEASURED, // HR

View File

@ -580,12 +580,12 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
if (heartRate > 0) {
sample.setHeartRate(heartRate);
sample.setTimestamp((int) (System.currentTimeMillis() / 1000));
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
} else {
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) {
sample.setRawKind(ActivityKind.TYPE_NOT_MEASURED);
sample.setRawKind(ActivityKind.NOT_MEASURED.getCode());
} else {
LOG.warn("invalid heart rate reading: " + heartRate);
return;
@ -608,7 +608,7 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
sample.setHeartRate(heartRate);
sample.setTimestamp(timeStamp);
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
this.addGBActivitySample(sample);
}
@ -622,12 +622,12 @@ public class MakibesHR3DeviceSupport extends AbstractBTLEDeviceSupport implement
int newSteps = (steps - dayStepCount);
if (newSteps > 0) {
LOG.debug("adding " + newSteps + " steps");
LOG.debug("adding {} steps", newSteps);
sample.setSteps(steps - dayStepCount);
sample.setTimestamp(timeStamp);
sample.setRawKind(ActivityKind.TYPE_ACTIVITY);
sample.setRawKind(ActivityKind.ACTIVITY.getCode());
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.
*/
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);

View File

@ -484,7 +484,7 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
private void handleActivityData(byte[] data) {
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) {
GB.toast(getContext(), "Incorrect CRC. Try fetching data again.", Toast.LENGTH_LONG, GB.ERROR);
GB.updateTransferNotification(null,"Data transfer failed", false, 0, getContext());
@ -492,7 +492,7 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
getDevice().unsetBusyTask();
getDevice().sendDeviceUpdateIntent(getContext());
}
} else if (samples.size() > 0) {
} else if (!samples.isEmpty()) {
try (DBHandler dbHandler = GBApplication.acquireDB()) {
Long userId = DBHelper.getUser(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).setUserId(userId);
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());
} else if (data[0] == No1F1Constants.CMD_FETCH_SLEEP) {
if (samples.get(i).getRawIntensity() < 7)
samples.get(i).setRawKind(ActivityKind.TYPE_DEEP_SLEEP);
samples.get(i).setRawKind(ActivityKind.DEEP_SLEEP.getCode());
else
samples.get(i).setRawKind(ActivityKind.TYPE_LIGHT_SLEEP);
samples.get(i).setRawKind(ActivityKind.LIGHT_SLEEP.getCode());
}
provider.addGBActivitySample(samples.get(i));
}
@ -542,15 +542,18 @@ public class No1F1Support extends AbstractBTLEDeviceSupport {
if (data[0] == No1F1Constants.CMD_FETCH_STEPS) {
timestamp.set(Calendar.MINUTE, 0);
sample.setSteps(data[6] * 256 + (data[7] & 0xff));
//noinspection lossy-conversions
crc ^= (data[6] ^ data[7]);
} else if (data[0] == No1F1Constants.CMD_FETCH_SLEEP) {
timestamp.set(Calendar.MINUTE, data[6] & 0xff);
sample.setRawIntensity(data[7] * 256 + (data[8] & 0xff));
//noinspection lossy-conversions
crc ^= (data[7] ^ data[8]);
startProgress = 33;
} else if (data[0] == No1F1Constants.CMD_FETCH_HEARTRATE) {
timestamp.set(Calendar.MINUTE, data[6] & 0xff);
sample.setHeartRate(data[7] & 0xff);
//noinspection lossy-conversions
crc ^= (data[6] ^ data[7]);
startProgress = 66;
}

View File

@ -1126,7 +1126,7 @@ public class PineTimeJFSupport extends AbstractBTLEDeviceSupport implements DfuL
sample.setTimestamp(timeStamp);
// 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);
@ -1152,7 +1152,7 @@ public class PineTimeJFSupport extends AbstractBTLEDeviceSupport implements DfuL
sample.setHeartRate(heartrate);
sample.setTimestamp(timeStamp);
// 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);

View File

@ -16,7 +16,6 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
@ -35,7 +34,7 @@ public class ActivityEntry {
public WEARING_STATE wearingState;
public HybridHRActivitySample toDAOActivitySample(long userId, long deviceId) {
HybridHRActivitySample sample = new HybridHRActivitySample(
return new HybridHRActivitySample(
timestamp,
deviceId,
userId,
@ -48,24 +47,22 @@ public class ActivityEntry {
wearingState.value,
heartRate
);
return sample;
}
public enum WEARING_STATE{
WEARING((byte) 0, ActivityKind.TYPE_NOT_MEASURED),
NOT_WEARING((byte) 1, ActivityKind.TYPE_NOT_WORN),
UNKNOWN((byte) 2, ActivityKind.TYPE_UNKNOWN);
WEARING((byte) 0, ActivityKind.NOT_MEASURED),
NOT_WEARING((byte) 1, ActivityKind.NOT_WORN),
UNKNOWN((byte) 2, ActivityKind.UNKNOWN);
byte value;
int activityKind;
final byte value;
final ActivityKind activityKind;
WEARING_STATE(byte value, int activityKind){
WEARING_STATE(byte value, ActivityKind activityKind){
this.value = value;
this.activityKind = activityKind;
}
public int getActivityKind() {
public ActivityKind getActivityKind() {
return activityKind;
}

View File

@ -43,19 +43,15 @@ public class WorkoutRequestHandler {
JSONObject workoutResponse = new JSONObject();
if (workoutRequest.optString("state").equals("started") && workoutRequest.optString("gps").equals("on")) {
int activityType = workoutRequest.optInt("activity", -1);
final int activityKind;
if (QHybridConstants.WORKOUT_TYPES_TO_ACTIVITY_KIND.containsKey(activityType)) {
activityKind = QHybridConstants.WORKOUT_TYPES_TO_ACTIVITY_KIND.get(activityType);
} else {
activityKind = ActivityKind.TYPE_UNKNOWN;
}
LOG.info("Workout started, activity type is " + activityType + "/" + activityKind);
final ActivityKind activityKind = QHybridConstants.WORKOUT_TYPES_TO_ACTIVITY_KIND.getOrDefault(activityType, ActivityKind.UNKNOWN);
LOG.info("Workout started, activity type is {}/{}", activityType, activityKind);
addStateResponse(workoutResponse, "success", "");
//noinspection DataFlowIssue fp, never null
OpenTracksController.startRecording(context, activityKind);
} else if (workoutRequest.optString("type").equals("req_distance")) {
long timeSecs = Math.round(GBApplication.app().getOpenTracksObserver().getTimeMillisChange() / 1000f);
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()
.put("distance", distanceCM)
.put("duration", timeSecs)

View File

@ -19,7 +19,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.tlw64;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.net.Uri;
import android.text.format.DateFormat;
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.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
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.WeatherSpec;
import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceBusyAction;
@ -514,7 +508,7 @@ public class TLW64Support extends AbstractBTLEDeviceSupport {
private void handleActivityData(byte[] data) {
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) {
GB.toast(getContext(), "Incorrect CRC. Try fetching data again.", Toast.LENGTH_LONG, GB.ERROR);
GB.updateTransferNotification(null, "Data transfer failed", false, 0, getContext());
@ -522,7 +516,7 @@ public class TLW64Support extends AbstractBTLEDeviceSupport {
getDevice().unsetBusyTask();
getDevice().sendDeviceUpdateIntent(getContext());
}
} else if (samples.size() > 0) {
} else if (!samples.isEmpty()) {
try (DBHandler dbHandler = GBApplication.acquireDB()) {
Long userId = DBHelper.getUser(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).setUserId(userId);
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());
} else if (data[0] == TLW64Constants.CMD_FETCH_SLEEP) {
if (samples.get(i).getRawIntensity() < 7) {
samples.get(i).setRawKind(ActivityKind.TYPE_DEEP_SLEEP);
samples.get(i).setRawKind(ActivityKind.DEEP_SLEEP.getCode());
} else
samples.get(i).setRawKind(ActivityKind.TYPE_LIGHT_SLEEP);
samples.get(i).setRawKind(ActivityKind.LIGHT_SLEEP.getCode());
}
provider.addGBActivitySample(samples.get(i));
}
@ -571,10 +565,12 @@ public class TLW64Support extends AbstractBTLEDeviceSupport {
if (data[0] == TLW64Constants.CMD_FETCH_STEPS) {
timestamp.set(Calendar.MINUTE, 0);
sample.setSteps(data[6] * 256 + (data[7] & 0xff));
//noinspection lossy-conversions
crc ^= (data[6] ^ data[7]);
} else if (data[0] == TLW64Constants.CMD_FETCH_SLEEP) {
timestamp.set(Calendar.MINUTE, data[6] & 0xff);
sample.setRawIntensity(data[7] * 256 + (data[8] & 0xff));
//noinspection lossy-conversions
crc ^= (data[7] ^ data[8]);
startProgress = 33;
}

View File

@ -699,7 +699,7 @@ public class WithingsSteelHRDeviceSupport extends AbstractBTLEDeviceSupport {
message.addDataStructure(imageMetaData);
ImageData imageData = new ImageData();
final int drawableId = ActivityKind.getIconId(withingsActivityType.toActivityKind());
final int drawableId = withingsActivityType.toActivityKind().getIcon();
Drawable drawable = getContext().getDrawable(drawableId);
imageData.setImageData(IconHelper.getIconBytesFromDrawable(drawable));
message.addDataStructure(imageData);
@ -719,7 +719,7 @@ public class WithingsSteelHRDeviceSupport extends AbstractBTLEDeviceSupport {
String localeString = GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress())
.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();
}

View File

@ -16,9 +16,6 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.withingssteelhr.activity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
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.
*/
public class SleepActivitySampleHelper {
private static Logger logger = LoggerFactory.getLogger(SleepActivitySampleHelper.class);
private static int mergeCount;
public static WithingsSteelHRActivitySample mergeIfNecessary(WithingsSteelHRSampleProvider provider, WithingsSteelHRActivitySample sample) {
if (!shouldMerge(sample)) {
return sample;
@ -55,7 +48,7 @@ public class SleepActivitySampleHelper {
for (int i = samples.size()-1; i >= 0; i--) {
WithingsSteelHRActivitySample lastSample = samples.get(i);
if (isNotHeartRateOnly(lastSample, (int) timestamp)) {
if (isNotHeartRateOnly(lastSample)) {
return lastSample;
}
}
@ -63,8 +56,8 @@ public class SleepActivitySampleHelper {
return null;
}
private static boolean isNotHeartRateOnly(WithingsSteelHRActivitySample lastSample, int timestamp) {
return lastSample.getRawKind() != ActivityKind.TYPE_NOT_MEASURED; // && lastSample.getTimestamp() <= timestamp && (lastSample.getTimestamp() + lastSample.getDuration()) >= timestamp);
private static boolean isNotHeartRateOnly(WithingsSteelHRActivitySample lastSample) {
return lastSample.getRawKind() != ActivityKind.NOT_MEASURED.getCode(); // && lastSample.getTimestamp() <= timestamp && (lastSample.getTimestamp() + lastSample.getDuration()) >= timestamp);
}
private static boolean shouldMerge(WithingsSteelHRActivitySample sample) {

View File

@ -61,7 +61,7 @@ public enum WithingsActivityType {
RIDING(26),
OTHER(36);
private int code;
private final int code;
WithingsActivityType(int typeCode) {
this.code = typeCode;
@ -80,80 +80,80 @@ public enum WithingsActivityType {
return code;
}
public int toActivityKind() {
public ActivityKind toActivityKind() {
switch (this) {
case WALKING:
return ActivityKind.TYPE_WALKING;
return ActivityKind.WALKING;
case RUNNING:
return ActivityKind.TYPE_RUNNING;
return ActivityKind.RUNNING;
case HIKING:
return ActivityKind.TYPE_HIKING;
return ActivityKind.HIKING;
case BIKING:
return ActivityKind.TYPE_CYCLING;
return ActivityKind.CYCLING;
case SWIMMING:
return ActivityKind.TYPE_SWIMMING;
return ActivityKind.SWIMMING;
case SURFING:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case KITESURFING:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case WINDSURFING:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case TENNIS:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case PINGPONG:
return ActivityKind.TYPE_PINGPONG;
return ActivityKind.PINGPONG;
case SQUASH:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case BADMINTON:
return ActivityKind.TYPE_BADMINTON;
return ActivityKind.BADMINTON;
case WEIGHTLIFTING:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case GYMNASTICS:
return ActivityKind.TYPE_EXERCISE;
return ActivityKind.EXERCISE;
case ELLIPTICAL:
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
return ActivityKind.ELLIPTICAL_TRAINER;
case PILATES:
return ActivityKind.TYPE_YOGA;
return ActivityKind.YOGA;
case BASKETBALL:
return ActivityKind.TYPE_BASKETBALL;
return ActivityKind.BASKETBALL;
case SOCCER:
return ActivityKind.TYPE_SOCCER;
return ActivityKind.SOCCER;
case FOOTBALL:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case RUGBY:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case VOLLEYBALL:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case GOLFING:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case YOGA:
return ActivityKind.TYPE_YOGA;
return ActivityKind.YOGA;
case DANCING:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case BOXING:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case SKIING:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case SNOWBOARDING:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case ROWING:
return ActivityKind.TYPE_ROWING_MACHINE;
return ActivityKind.ROWING_MACHINE;
case ZUMBA:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case BASEBALL:
return ActivityKind.TYPE_CRICKET;
return ActivityKind.CRICKET;
case HANDBALL:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case HOCKEY:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case ICEHOCKEY:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
case CLIMBING:
return ActivityKind.TYPE_CLIMBING;
return ActivityKind.CLIMBING;
case ICESKATING:
return ActivityKind.TYPE_ACTIVITY;
return ActivityKind.ACTIVITY;
default:
return ActivityKind.TYPE_UNKNOWN;
return ActivityKind.UNKNOWN;
}
}

View File

@ -106,7 +106,7 @@ public class ActivitySampleHandler extends AbstractResponseHandler {
handleWorkoutType(data);
break;
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()));
}
}
@ -128,7 +128,7 @@ public class ActivitySampleHandler extends AbstractResponseHandler {
private void handleWorkoutType(WithingsStructure data) {
WithingsActivityType activityType = WithingsActivityType.fromCode(((WorkoutType) data).getActivityType());
activityEntry.setRawKind(activityType.toActivityKind());
activityEntry.setRawKind(activityType.toActivityKind().getCode());
}
private void handleDuration(WithingsStructure data) {
@ -140,44 +140,44 @@ public class ActivitySampleHandler extends AbstractResponseHandler {
}
private void handleMovement(WithingsStructure data) {
activityEntry.setRawKind(ActivityKind.TYPE_UNKNOWN);
activityEntry.setRawKind(ActivityKind.UNKNOWN.getCode());
activityEntry.setSteps(((ActivitySampleMovement) data).getSteps());
activityEntry.setDistance(((ActivitySampleMovement) data).getDistance());
}
private void handleWalk(WithingsStructure data) {
activityEntry.setRawKind(ActivityKind.TYPE_WALKING);
activityEntry.setRawKind(ActivityKind.WALKING.getCode());
}
private void handleRun(WithingsStructure data) {
activityEntry.setRawKind(ActivityKind.TYPE_RUNNING);
activityEntry.setRawKind(ActivityKind.RUNNING.getCode());
}
private void handleSwim(WithingsStructure data) {
activityEntry.setRawKind(ActivityKind.TYPE_SWIMMING);
activityEntry.setRawKind(ActivityKind.SWIMMING.getCode());
}
private void handleSleep(WithingsStructure data) {
int sleepType;
ActivityKind sleepType;
switch (((ActivitySampleSleep) data).getSleepType()) {
case 0:
sleepType = ActivityKind.TYPE_LIGHT_SLEEP;
sleepType = ActivityKind.LIGHT_SLEEP;
activityEntry.setRawIntensity(10);
break;
case 2:
sleepType = ActivityKind.TYPE_DEEP_SLEEP;
sleepType = ActivityKind.DEEP_SLEEP;
activityEntry.setRawIntensity(70);
break;
case 3:
sleepType = ActivityKind.TYPE_REM_SLEEP;
sleepType = ActivityKind.REM_SLEEP;
activityEntry.setRawIntensity(80);
break;
default:
sleepType = ActivityKind.TYPE_LIGHT_SLEEP;
sleepType = ActivityKind.LIGHT_SLEEP;
activityEntry.setRawIntensity(50);
}
activityEntry.setRawKind(sleepType);
activityEntry.setRawKind(sleepType.getCode());
}
private void handleCalories1(WithingsStructure data) {

View File

@ -119,7 +119,7 @@ public class LiveWorkoutHandler implements IncomingMessageHandler {
baseActivitySummary = new BaseActivitySummary();
}
baseActivitySummary.setActivityKind(withingsWorkoutType.toActivityKind());
baseActivitySummary.setActivityKind(withingsWorkoutType.toActivityKind().getCode());
}
private void sendGpsState() {

View File

@ -62,7 +62,7 @@ public abstract class XiaomiActivityParser {
// These will be set later, once we parse the summary
summary.setEndTime(fileId.getTimestamp());
summary.setActivityKind(ActivityKind.TYPE_UNKNOWN);
summary.setActivityKind(ActivityKind.UNKNOWN.getCode());
return summary;
}

View File

@ -111,7 +111,7 @@ public class WorkoutGpsParser extends XiaomiActivityParser {
// Set the info on the activity track
activityTrack.setUser(user);
activityTrack.setDevice(device);
activityTrack.setName(ActivityKind.asString(summary.getActivityKind(), support.getContext()));
activityTrack.setName(ActivityKind.fromCode(summary.getActivityKind()).getLabel(support.getContext()));
// Save the raw 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) {
try {
final File targetFolder = new File(FileUtils.getExternalFilesDir(), "rawDetails");
//noinspection ResultOfMethodCallIgnored
targetFolder.mkdirs();
final File targetFile = new File(targetFolder, fileId.getFilename());
FileOutputStream outputStream = new FileOutputStream(targetFile);

View File

@ -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.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);
try {
@ -172,31 +172,31 @@ public class WorkoutSummaryParser extends XiaomiActivityParser implements Activi
switch (fileId.getSubtype()) {
case SPORTS_OUTDOOR_WALKING_V1:
summary.setActivityKind(ActivityKind.TYPE_WALKING);
summary.setActivityKind(ActivityKind.WALKING.getCode());
parser = getOutdoorWalkingV1Parser(fileId);
break;
case SPORTS_OUTDOOR_RUNNING:
summary.setActivityKind(ActivityKind.TYPE_RUNNING);
summary.setActivityKind(ActivityKind.RUNNING.getCode());
parser = getOutdoorWalkingV1Parser(fileId);
break;
case SPORTS_INDOOR_CYCLING:
summary.setActivityKind(ActivityKind.TYPE_INDOOR_CYCLING);
summary.setActivityKind(ActivityKind.INDOOR_CYCLING.getCode());
parser = getIndoorCyclingParser(fileId);
break;
case SPORTS_FREESTYLE:
summary.setActivityKind(ActivityKind.TYPE_STRENGTH_TRAINING);
summary.setActivityKind(ActivityKind.STRENGTH_TRAINING.getCode());
parser = getFreestyleParser(fileId);
break;
case SPORTS_POOL_SWIMMING:
summary.setActivityKind(ActivityKind.TYPE_SWIMMING);
summary.setActivityKind(ActivityKind.SWIMMING.getCode());
parser = getPoolSwimmingParser(fileId);
break;
case SPORTS_HIIT:
summary.setActivityKind(ActivityKind.TYPE_EXERCISE);
summary.setActivityKind(ActivityKind.EXERCISE.getCode());
parser = getHiitParser(fileId);
break;
case SPORTS_ELLIPTICAL:
summary.setActivityKind(ActivityKind.TYPE_ELLIPTICAL_TRAINER);
summary.setActivityKind(ActivityKind.ELLIPTICAL_TRAINER.getCode());
// TODO
break;
case SPORTS_OUTDOOR_WALKING_V2:

View File

@ -102,13 +102,13 @@ public class XiaomiSimpleActivityParser {
// TODO use XiaomiWorkoutType
switch (value.intValue()) {
case 2:
summary.setActivityKind(ActivityKind.TYPE_WALKING);
summary.setActivityKind(ActivityKind.WALKING.getCode());
break;
case 6:
summary.setActivityKind(ActivityKind.TYPE_CYCLING);
summary.setActivityKind(ActivityKind.CYCLING.getCode());
break;
default:
summary.setActivityKind(ActivityKind.TYPE_UNKNOWN);
summary.setActivityKind(ActivityKind.UNKNOWN.getCode());
}
} else {
summaryData.add(dataEntry.getKey(), value.floatValue(), dataEntry.getUnit());

Some files were not shown because too many files have changed in this diff Show More