diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/StressChartFragment.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/StressChartFragment.java index 12a76d21df..64ad312132 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/StressChartFragment.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/StressChartFragment.java @@ -57,6 +57,7 @@ import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -93,6 +94,9 @@ public class StressChartFragment extends AbstractChartFragment) samples, tsStart, tsEnd); - return new StressChartsDataBuilder(samples, device.getDeviceCoordinator().getStressRanges()).build(); + showStressLevelInPercents = device.getDeviceCoordinator().showStressLevelInPercents(); + + return new StressChartsDataBuilder(samples, device.getDeviceCoordinator().getStressRanges(), device.getDeviceCoordinator().getStressChartParameters()).build(); } protected LineDataSet createDataSet(final StressType stressType, final List values) { @@ -134,6 +140,19 @@ public class StressChartFragment extends AbstractChartFragment 0) { + tv.setText(DateTimeUtils.formatDurationHoursMinutes(value, TimeUnit.SECONDS)); + } else { + tv.setText(R.string.stats_empty_value); + } + } + } + @Override protected void updateChartsnUIThread(final StressChartsData stressData) { final PieData pieData = stressData.getPieData(); @@ -143,30 +162,10 @@ public class StressChartFragment extends AbstractChartFragment stressZoneTimes = stressData.getStressZoneTimes(); - Integer relaxedTime = stressZoneTimes.get(StressType.RELAXED); - if (0 < relaxedTime) { - stressChartRelaxedTime.setText(DateTimeUtils.formatDurationHoursMinutes(relaxedTime, TimeUnit.SECONDS)); - } else { - stressChartRelaxedTime.setText(R.string.stats_empty_value); - } - Integer mildTime = stressZoneTimes.get(StressType.MILD); - if (mildTime > 0) { - stressChartMildTime.setText(DateTimeUtils.formatDurationHoursMinutes(mildTime, TimeUnit.SECONDS)); - } else { - stressChartMildTime.setText(R.string.stats_empty_value); - } - Integer moderateTime = stressZoneTimes.get(StressType.MODERATE); - if (moderateTime > 0) { - stressChartModerateTime.setText(DateTimeUtils.formatDurationHoursMinutes(moderateTime, TimeUnit.SECONDS)); - } else { - stressChartModerateTime.setText(R.string.stats_empty_value); - } - Integer highTime = stressZoneTimes.get(StressType.HIGH); - if (highTime > 0) { - stressChartHighTime.setText(DateTimeUtils.formatDurationHoursMinutes(highTime, TimeUnit.SECONDS)); - } else { - stressChartHighTime.setText(R.string.stats_empty_value); - } + setZoneValue(stressChartRelaxedTime, stressZoneTimes.get(StressType.RELAXED), stressData.getTotalStressTime()); + setZoneValue(stressChartMildTime, stressZoneTimes.get(StressType.MILD), stressData.getTotalStressTime()); + setZoneValue(stressChartModerateTime, stressZoneTimes.get(StressType.MODERATE), stressData.getTotalStressTime()); + setZoneValue(stressChartHighTime, stressZoneTimes.get(StressType.HIGH), stressData.getTotalStressTime()); if (stressData.getAverage() > 0) { int noc = String.valueOf(stressData.getAverage()).length(); @@ -209,9 +208,7 @@ public class StressChartFragment extends AbstractChartFragment= Build.VERSION_CODES.M) { - rootView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> { - getChartsHost().enableSwipeRefresh(scrollY == 0); - }); + rootView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> getChartsHost().enableSwipeRefresh(scrollY == 0)); } mStressChart = rootView.findViewById(R.id.stress_line_chart); @@ -240,7 +237,7 @@ public class StressChartFragment extends AbstractChartFragment samples; private final int[] stressRanges; + private final int sampleRate; + private final int interval; + private final int delta; + private final TimestampTranslation tsTranslation = new TimestampTranslation(); private final Map> lineEntriesPerLevel = new HashMap<>(); @@ -371,9 +372,12 @@ public class StressChartFragment extends AbstractChartFragment samples, final int[] stressRanges) { + public StressChartsDataBuilder(final List samples, final int[] stressRanges, final int[] dataParameters) { this.samples = samples; this.stressRanges = stressRanges; + this.sampleRate = dataParameters[0]; + this.interval = dataParameters[1]; + this.delta = dataParameters[2]; } private void reset() { @@ -413,25 +417,50 @@ public class StressChartFragment extends AbstractChartFragment 0 && sample.getStress() > 0) { + int endTime = interval - delta; + set(ts, stressType, sample.getStress()); + set(endTime - 1, stressType, sample.getStress()); + set(endTime, StressType.UNKNOWN, UNKNOWN_VAL); + } else { + set(ts, stressType, sample.getStress()); + } return; } - if (ts - previousTs > 60 * 10) { - // More than 15 minutes since last sample - // Set to unknown right after the last sample we got until the current time - int lastEndTs = Math.min(previousTs + 60 * 5, ts - 1); - set(lastEndTs, StressType.UNKNOWN, UNKNOWN_VAL); - set(ts - 1, StressType.UNKNOWN, UNKNOWN_VAL); + if(interval > 0) { + // For interval devices bars chard should be used. + // Emulate bars by drawing unknown type on the start and end of interval with delta for spaces. + if(sample.getStress() > 0) { + int startTime = (((ts / interval)) * interval) + delta; + int endTime = (((ts / interval) + 1) * interval) - delta; + + set(startTime, StressType.UNKNOWN, UNKNOWN_VAL); + set(startTime + 1, stressType, sample.getStress()); + set(endTime - 1, stressType, sample.getStress()); + set(endTime, StressType.UNKNOWN, UNKNOWN_VAL); + } else { + set(ts, stressType, sample.getStress()); + } + + + } else { + if (ts - previousTs > sampleRate * 10) { + // More than 15 minutes since last sample + // Set to unknown right after the last sample we got until the current time + int lastEndTs = Math.min(previousTs + sampleRate * 5, ts - 1); + set(lastEndTs, StressType.UNKNOWN, UNKNOWN_VAL); + set(ts - 1, StressType.UNKNOWN, UNKNOWN_VAL); + } + + set(ts, stressType, sample.getStress()); } if (!stressType.equals(previousStressType)) { currentTypeStartTs = ts; } - set(ts, stressType, sample.getStress()); - - accumulator.put(stressType, accumulator.get(stressType) + 60); + accumulator.computeIfPresent(stressType, (k, v) -> v + sampleRate); if (stressType != StressType.UNKNOWN) { averageSum += sample.getStress(); @@ -460,13 +489,16 @@ public class StressChartFragment extends AbstractChartFragment pieColors = new ArrayList<>(); final Map stressZoneTimes = new HashMap<>(); + long totalStressTime = 0; for (final StressType stressType : StressType.values()) { final List stressEntries = lineEntriesPerLevel.get(stressType); lineDataSets.add(createDataSet(stressType, stressEntries)); final Integer stressTime = accumulator.get(stressType); stressZoneTimes.put(stressType, stressTime); + if (stressType != StressType.UNKNOWN && stressTime != null && stressTime != 0) { + totalStressTime += stressTime; pieEntries.add(new PieEntry(stressTime, stressType.getLabel(requireContext()))); pieColors.add(stressType.getColor(requireContext())); } @@ -496,7 +528,7 @@ public class StressChartFragment extends AbstractChartFragment chartsData = new DefaultChartsData<>(lineData, xValueFormatter); - return new StressChartsData(pieData, chartsData, Math.round((float) averageSum / averageNumSamples), stressZoneTimes); + return new StressChartsData(pieData, chartsData, Math.round((float) averageSum / averageNumSamples), stressZoneTimes, totalStressTime); } } @@ -504,13 +536,15 @@ public class StressChartFragment extends AbstractChartFragment chartsData; private final int average; - private Map stressZoneTimes; + private final Map stressZoneTimes; + private final long totalStressTime; - public StressChartsData(final PieData pieData, final DefaultChartsData chartsData, final int average, Map stressZoneTimes) { + public StressChartsData(final PieData pieData, final DefaultChartsData chartsData, final int average, Map stressZoneTimes, long totalStressTime) { this.pieData = pieData; this.chartsData = chartsData; this.average = average; this.stressZoneTimes = stressZoneTimes; + this.totalStressTime = totalStressTime; } public Map getStressZoneTimes() { @@ -528,6 +562,10 @@ public class StressChartFragment extends AbstractChartFragment getTemperatureSampleProvider(GBDevice device, DaoSession session) { return null; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java index 04e02246a0..8d32dc4582 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java @@ -375,6 +375,15 @@ public interface DeviceCoordinator { */ int[] getStressRanges(); + /** + * Returns true if stress level percentages are displayed instead of actual time. + */ + boolean showStressLevelInPercents(); + + /** + * Returns the stress data parameters (sampleRate, interval, delta) used for chart drawing + */ + int[] getStressChartParameters(); /** * Returns the sample provider for temperature data, for the device being supported. */ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiBRCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiBRCoordinator.java index af546e8fef..e3327100c6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiBRCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiBRCoordinator.java @@ -259,6 +259,16 @@ public abstract class HuaweiBRCoordinator extends AbstractBLClassicDeviceCoordin return huaweiCoordinator.getStressRanges(); } + @Override + public boolean showStressLevelInPercents() { + return true; + } + + @Override + public int[] getStressChartParameters() { + return huaweiCoordinator.getStressChartParameters(); + } + public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) { return huaweiCoordinator.getDeviceSpecificSettings(device); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java index 149827886a..be44936a42 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiCoordinator.java @@ -1072,4 +1072,9 @@ public class HuaweiCoordinator { return new int[]{1, 30, 60, 80}; } + public int[] getStressChartParameters() { + // For Huawei devices stress data is provided every 30 minutes. So draw it as bars with delta + return new int[]{1800, 1800, 400}; + } + } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiLECoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiLECoordinator.java index bc62cd984d..8e5fa7f64d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiLECoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiLECoordinator.java @@ -268,6 +268,16 @@ public abstract class HuaweiLECoordinator extends AbstractBLEDeviceCoordinator i return huaweiCoordinator.getStressRanges(); } + @Override + public boolean showStressLevelInPercents() { + return true; + } + + @Override + public int[] getStressChartParameters() { + return huaweiCoordinator.getStressChartParameters(); + } + public DeviceSpecificSettings getDeviceSpecificSettings(final GBDevice device) { return huaweiCoordinator.getDeviceSpecificSettings(device); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiStressSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiStressSampleProvider.java index 6641e8eb1d..aedd21fffd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiStressSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiStressSampleProvider.java @@ -58,23 +58,4 @@ public class HuaweiStressSampleProvider extends AbstractTimeSampleProvider getAllSamples(long timestampFrom, long timestampTo) { - final long delta = 300000; - final long interval = 1800000; - List samples = super.getAllSamples(timestampFrom, timestampTo); - List newSamples = new ArrayList<>(); - for (HuaweiStressSample sample : samples) { - long startTime = (((sample.getStartTime() / interval)) * interval) + delta; - long endTime = (((sample.getTimestamp() / interval) + 1) * interval) - delta; - for (long i = startTime; i < endTime; i += delta) { - if (i > timestampFrom && i < timestampTo) { - newSamples.add(new HuaweiStressSample(i, sample.getDeviceId(), sample.getUserId(), sample.getStress(), sample.getLevel(), sample.getStartTime())); - } - } - } - return newSamples; - } - }