1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-28 21:06:50 +01:00

Merge branch 'master' into feature-weather

This commit is contained in:
Andreas Shimokawa 2016-12-26 23:03:11 +01:00
commit 16d9279728
6 changed files with 94 additions and 88 deletions

View File

@ -72,8 +72,6 @@ public class LiveActivityFragment extends AbstractChartFragment {
private TimestampTranslation tsTranslation;
private class Steps {
private int initialSteps;
private int steps;
private int lastTimestamp;
private int currentStepsPerMinute;
@ -90,39 +88,29 @@ public class LiveActivityFragment extends AbstractChartFragment {
}
public int getTotalSteps() {
return steps - initialSteps;
return steps;
}
public int getMaxStepsPerMinute() {
return maxStepsPerMinute;
}
public void updateCurrentSteps(int newSteps, int timestamp) {
public void updateCurrentSteps(int stepsDelta, int timestamp) {
try {
if (steps == 0) {
steps = newSteps;
steps += stepsDelta;
lastTimestamp = timestamp;
if (newSteps > 0) {
initialSteps = newSteps;
}
return;
}
if (newSteps >= steps) {
int stepsDelta = newSteps - steps;
int timeDelta = timestamp - lastTimestamp;
currentStepsPerMinute = calculateStepsPerMinute(stepsDelta, timeDelta);
if (currentStepsPerMinute > maxStepsPerMinute) {
maxStepsPerMinute = currentStepsPerMinute;
maxStepsResetCounter = 0;
}
steps = newSteps;
lastTimestamp = timestamp;
} else {
// TODO: handle new day?
int timeDelta = timestamp - lastTimestamp;
currentStepsPerMinute = calculateStepsPerMinute(stepsDelta, timeDelta);
if (currentStepsPerMinute > maxStepsPerMinute) {
maxStepsPerMinute = currentStepsPerMinute;
maxStepsResetCounter = 0;
}
steps += stepsDelta;
lastTimestamp = timestamp;
} catch (Exception ex) {
GB.toast(LiveActivityFragment.this.getContext(), ex.getMessage(), Toast.LENGTH_SHORT, GB.ERROR, ex);
}
@ -136,7 +124,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
throw new IllegalArgumentException("delta in seconds is <= 0 -- time change?");
}
int oneMinute = 60 * 1000;
int oneMinute = 60;
float factor = oneMinute / seconds;
int result = (int) (stepsDelta * factor);
if (result > MAX_STEPS_PER_MINUTE) {
@ -152,24 +140,27 @@ public class LiveActivityFragment extends AbstractChartFragment {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action) {
case DeviceService.ACTION_REALTIME_STEPS: {
int steps = intent.getIntExtra(DeviceService.EXTRA_REALTIME_STEPS, 0);
int timestamp = translateTimestampFrom(intent);
addEntries(steps, timestamp);
break;
}
case DeviceService.ACTION_HEARTRATE_MEASUREMENT: {
int heartRate = intent.getIntExtra(DeviceService.EXTRA_HEART_RATE_VALUE, 0);
int timestamp = translateTimestampFrom(intent);
if (isValidHeartRateValue(heartRate)) {
setCurrentHeartRate(heartRate, timestamp);
}
case DeviceService.ACTION_REALTIME_SAMPLES: {
ActivitySample sample = (ActivitySample) intent.getSerializableExtra(DeviceService.EXTRA_REALTIME_SAMPLE);
addSample(sample);
break;
}
}
}
};
private void addSample(ActivitySample sample) {
int heartRate = sample.getHeartRate();
int timestamp = tsTranslation.shorten(sample.getTimestamp());
if (isValidHeartRateValue(heartRate)) {
setCurrentHeartRate(heartRate, timestamp);
}
int steps = sample.getSteps();
if (steps != ActivitySample.NOT_MEASURED) {
addEntries(steps, timestamp);
}
}
private int translateTimestampFrom(Intent intent) {
return translateTimestamp(intent.getLongExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis()));
}
@ -251,8 +242,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
IntentFilter filterLocal = new IntentFilter();
filterLocal.addAction(DeviceService.ACTION_REALTIME_STEPS);
filterLocal.addAction(DeviceService.ACTION_HEARTRATE_MEASUREMENT);
filterLocal.addAction(DeviceService.ACTION_REALTIME_SAMPLES);
heartRateValues = new ArrayList<>();
tsTranslation = new TimestampTranslation();
@ -377,6 +367,9 @@ public class LiveActivityFragment extends AbstractChartFragment {
// chart.getXAxis().setPosition(XAxis.XAxisPosition.TOP);
chart.getXAxis().setDrawLabels(false);
chart.getXAxis().setEnabled(false);
chart.getXAxis().setTextColor(CHART_TEXT_COLOR);
chart.getAxisLeft().setTextColor(CHART_TEXT_COLOR);
chart.setBackgroundColor(BACKGROUND_COLOR);
chart.getDescription().setTextColor(DESCRIPTION_COLOR);
chart.getDescription().setText(title);

View File

@ -38,11 +38,6 @@ public interface DeviceService extends EventHandler {
String ACTION_SET_ALARMS = PREFIX + ".action.set_alarms";
String ACTION_ENABLE_REALTIME_STEPS = PREFIX + ".action.enable_realtime_steps";
String ACTION_REALTIME_SAMPLES = PREFIX + ".action.realtime_samples";
/**
* Use EXTRA_REALTIME_SAMPLE instead
*/
@Deprecated
String ACTION_REALTIME_STEPS = PREFIX + ".action.realtime_steps";
String ACTION_ENABLE_REALTIME_HEARTRATE_MEASUREMENT = PREFIX + ".action.realtime_hr_measurement";
String ACTION_ENABLE_HEARTRATE_SLEEP_SUPPORT = PREFIX + ".action.enable_heartrate_sleep_support";
String ACTION_HEARTRATE_MEASUREMENT = PREFIX + ".action.hr_measurement";

View File

@ -950,30 +950,25 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport {
MiBandSampleProvider provider = new MiBandSampleProvider(gbDevice, session);
MiBandActivitySample sample = createActivitySample(device, user, ts, provider);
sample.setHeartRate(getHeartrateBpm());
sample.setSteps(getSteps());
sample.setRawIntensity(ActivitySample.NOT_MEASURED);
sample.setRawKind(MiBandSampleProvider.TYPE_ACTIVITY); // to make it visible in the charts TODO: add a MANUAL kind for that?
// TODO: remove this once fully ported to REALTIME_SAMPLES
if (sample.getSteps() != ActivitySample.NOT_MEASURED) {
Intent intent = new Intent(DeviceService.ACTION_REALTIME_STEPS)
.putExtra(DeviceService.EXTRA_REALTIME_STEPS, sample.getSteps())
.putExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis());
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
}
if (sample.getHeartRate() != ActivitySample.NOT_MEASURED) {
Intent intent = new Intent(DeviceService.ACTION_HEARTRATE_MEASUREMENT)
.putExtra(DeviceService.EXTRA_HEART_RATE_VALUE, sample.getHeartRate())
.putExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis());
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
}
// Intent intent = new Intent(DeviceService.ACTION_REALTIME_SAMPLES)
// .putExtra(DeviceService.EXTRA_REALTIME_SAMPLE, sample);
// LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
LOG.debug("Storing realtime sample: " + sample);
provider.addGBActivitySample(sample);
// set the steps only afterwards, since realtime steps are also recorded
// in the regular samples and we must not count them twice
// Note: we know that the DAO sample is never committed again, so we simply
// change the value here in memory.
sample.setSteps(getSteps());
if (LOG.isDebugEnabled()) {
LOG.debug("realtime sample: " + sample);
}
Intent intent = new Intent(DeviceService.ACTION_REALTIME_SAMPLES)
.putExtra(DeviceService.EXTRA_REALTIME_SAMPLE, sample);
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
} catch (Exception e) {
LOG.warn("Unable to acquire db for saving realtime samples", e);
}

View File

@ -22,6 +22,7 @@ public abstract class RealtimeSamplesSupport {
protected int steps;
protected int heartrateBpm;
private int lastSteps;
// subclasses may add more
private Timer realtimeStorageTimer;
@ -56,12 +57,27 @@ public abstract class RealtimeSamplesSupport {
return realtimeStorageTimer != null;
}
public void setSteps(int stepsPerMinute) {
public synchronized void setSteps(int stepsPerMinute) {
this.steps = stepsPerMinute;
}
public int getSteps() {
return steps;
/**
* Returns the number of steps recorded since the last measurements. If no
* steps are available yet, ActivitySample.NOT_MEASURED is returned.
* @return
*/
public synchronized int getSteps() {
if (steps == ActivitySample.NOT_MEASURED) {
return ActivitySample.NOT_MEASURED;
}
if (lastSteps == 0) {
return ActivitySample.NOT_MEASURED; // wait until we have a delta between two samples
}
int delta = steps - lastSteps;
if (delta < 0) {
return 0;
}
return delta;
}
public void setHeartrateBpm(int hrBpm) {
@ -77,7 +93,10 @@ public abstract class RealtimeSamplesSupport {
resetCurrentValues();
}
protected void resetCurrentValues() {
protected synchronized void resetCurrentValues() {
if (steps >= lastSteps) {
lastSteps = steps;
}
steps = ActivitySample.NOT_MEASURED;
heartrateBpm = ActivitySample.NOT_MEASURED;
}

View File

@ -55,6 +55,7 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
private final boolean hasExtendedActivityData;
private static class ActivityStruct {
private int lastNotifiedProgress;
private final byte[] activityDataHolder;
private final int activityDataHolderSize;
//index of the buffer above
@ -129,6 +130,7 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
public void bufferFlushed(int minutes) {
activityDataTimestampProgress.add(Calendar.MINUTE, minutes);
activityDataHolderProgress = 0;
lastNotifiedProgress = 0;
}
}
@ -199,9 +201,16 @@ public class FetchActivityOperation extends AbstractMiBand1Operation {
} else {
bufferActivityData(value);
}
LOG.debug("activity data: length: " + value.length + ", remaining bytes: " + activityStruct.activityDataRemainingBytes);
if (LOG.isDebugEnabled()) {
LOG.debug("activity data: length: " + value.length + ", remaining bytes: " + activityStruct.activityDataRemainingBytes);
}
GB.updateTransferNotification(getContext().getString(R.string.busy_task_fetch_activity_data), true, (int) (((float) (activityStruct.activityDataUntilNextHeader - activityStruct.activityDataRemainingBytes)) / activityStruct.activityDataUntilNextHeader * 100), getContext());
int progress = (int) (((float) (activityStruct.activityDataUntilNextHeader - activityStruct.activityDataRemainingBytes)) / activityStruct.activityDataUntilNextHeader * 100);
// avoid too many notifications overloading the system
if (progress - activityStruct.lastNotifiedProgress >= 8) {
activityStruct.lastNotifiedProgress = progress;
GB.updateTransferNotification(getContext().getString(R.string.busy_task_fetch_activity_data), true, progress, getContext());
}
if (activityStruct.isBlockFinished()) {
sendAckDataTransfer(activityStruct.activityDataTimestampToAck, activityStruct.activityDataUntilNextHeader);

View File

@ -70,7 +70,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.Dev
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.heartrate.HeartRateProfile;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.CheckAuthenticationNeededAction;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.DeviceInfo;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.MiBandSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.RealtimeSamplesSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband2.operations.FetchActivityOperation;
@ -983,26 +982,22 @@ public class MiBand2Support extends AbstractBTLEDeviceSupport {
sample.setRawIntensity(ActivitySample.NOT_MEASURED);
sample.setRawKind(MiBand2SampleProvider.TYPE_ACTIVITY); // to make it visible in the charts TODO: add a MANUAL kind for that?
// TODO: remove this once fully ported to REALTIME_SAMPLES
if (sample.getSteps() != ActivitySample.NOT_MEASURED) {
Intent intent = new Intent(DeviceService.ACTION_REALTIME_STEPS)
.putExtra(DeviceService.EXTRA_REALTIME_STEPS, sample.getSteps())
.putExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis());
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
}
if (sample.getHeartRate() != ActivitySample.NOT_MEASURED) {
Intent intent = new Intent(DeviceService.ACTION_HEARTRATE_MEASUREMENT)
.putExtra(DeviceService.EXTRA_HEART_RATE_VALUE, sample.getHeartRate())
.putExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis());
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
}
// Intent intent = new Intent(DeviceService.ACTION_REALTIME_SAMPLES)
// .putExtra(DeviceService.EXTRA_REALTIME_SAMPLE, sample);
// LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
LOG.debug("Storing realtime sample: " + sample);
provider.addGBActivitySample(sample);
// set the steps only afterwards, since realtime steps are also recorded
// in the regular samples and we must not count them twice
// Note: we know that the DAO sample is never committed again, so we simply
// change the value here in memory.
sample.setSteps(getSteps());
if (LOG.isDebugEnabled()) {
LOG.debug("realtime sample: " + sample);
}
Intent intent = new Intent(DeviceService.ACTION_REALTIME_SAMPLES)
.putExtra(DeviceService.EXTRA_REALTIME_SAMPLE, sample);
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
} catch (Exception e) {
LOG.warn("Unable to acquire db for saving realtime samples", e);
}