Temperature charts: Add unit, respect metric/imperial

This commit is contained in:
José Rebelo
2025-12-26 21:26:10 +00:00
parent ad1e0c5589
commit e6c4d53e5d
5 changed files with 52 additions and 19 deletions
@@ -44,6 +44,7 @@ import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.TimeSampleProvider;
@@ -60,6 +61,7 @@ public class TemperatureChartFragment extends AbstractChartFragment<TemperatureC
protected final int TOTAL_DAYS = getRangeDays();
private final boolean isMetric = GBApplication.getPrefs().getString(SettingsActivity.PREF_MEASUREMENT_SYSTEM, "metric").equals("metric");
@Override
protected void init() {
@@ -84,7 +86,6 @@ public class TemperatureChartFragment extends AbstractChartFragment<TemperatureC
return new TemperatureChartsDataBuilder(samples).build();
}
@Override
protected void updateChartsnUIThread(final TemperatureChartsData temperatureData) {
mTemperatureChart.setData(null); // workaround for https://github.com/PhilJay/MPAndroidChart/issues/2317
@@ -92,8 +93,8 @@ public class TemperatureChartFragment extends AbstractChartFragment<TemperatureC
mTemperatureChart.getXAxis().setAvoidFirstLastClipping(true);
// Using approximately the range of survivable body-temperatures (in celsius), rounded to multiples of 5
mTemperatureChart.getAxisLeft().setAxisMinimum(30f);
mTemperatureChart.getAxisLeft().setAxisMaximum(45f);
mTemperatureChart.getAxisLeft().setAxisMinimum((float) (isMetric ? 30f : celsiusToFahrenheit(30d)));
mTemperatureChart.getAxisLeft().setAxisMaximum((float) (isMetric ? 45f : celsiusToFahrenheit(45f)));
mTemperatureChart.setData(temperatureData.getData());
}
@@ -178,12 +179,15 @@ public class TemperatureChartFragment extends AbstractChartFragment<TemperatureC
public TemperatureChartsData build() {
TimestampTranslation tsTranslation = new TimestampTranslation();
List<Entry> entries = new ArrayList<Entry>();
List<Entry> entries = new ArrayList<>();
long firstTs = 0;
for (TemperatureSample sample : samples) {
int timestamp_in_seconds = (int) (sample.getTimestamp() / 1000L);
entries.add(new Entry(tsTranslation.shorten(timestamp_in_seconds), sample.getTemperature()));
entries.add(new Entry(
tsTranslation.shorten(timestamp_in_seconds),
(float) (isMetric ? sample.getTemperature() : celsiusToFahrenheit(sample.getTemperature()))
));
if (firstTs == 0) {
firstTs = sample.getTimestamp();
}
@@ -242,4 +246,7 @@ public class TemperatureChartFragment extends AbstractChartFragment<TemperatureC
}
}
public static double celsiusToFahrenheit(final double celsius) {
return ((celsius * (9d/5d)) + 32d);
}
}
@@ -45,6 +45,7 @@ import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils;
import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.TimeSampleProvider;
@@ -68,6 +69,7 @@ public class TemperatureDailyFragment extends AbstractChartFragment<TemperatureD
private TextView tempMaximum;
private LineChart tempLineChart;
private final boolean isMetric = GBApplication.getPrefs().getString(SettingsActivity.PREF_MEASUREMENT_SYSTEM, "metric").equals("metric");
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@@ -190,11 +192,12 @@ public class TemperatureDailyFragment extends AbstractChartFragment<TemperatureD
for (int i =0; i < samples.size(); i++) {
TemperatureSample sample = samples.get(i);
int timestamp_in_seconds = (int) (sample.getTimestamp() / 1000L);
lineEntries.add(new Entry(tsTranslation.shorten(timestamp_in_seconds), sample.getTemperature()));
accumulator.add(sample.getTemperature());
final float temperature = isMetric ? sample.getTemperature() : celsiusToFahrenheit(sample.getTemperature());
lineEntries.add(new Entry(tsTranslation.shorten(timestamp_in_seconds), temperature));
accumulator.add(temperature);
}
LineDataSet dataSet = new LineDataSet(lineEntries, "Heart Rate");
LineDataSet dataSet = new LineDataSet(lineEntries, "Temperature");
dataSet.setLineWidth(1.5f);
dataSet.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER);
dataSet.setCubicIntensity(0.1f);
@@ -208,18 +211,20 @@ public class TemperatureDailyFragment extends AbstractChartFragment<TemperatureD
final double minimum = accumulator.getCount() > 0 ? accumulator.getMin() : -1;
final double maximum = accumulator.getCount() > 0 ? accumulator.getMax() : -1;
tempAverage.setText(average > 0 ? String.format(Locale.ROOT, "%.1f", average) : "-");
tempMinimum.setText(minimum > 0 ? String.format(Locale.ROOT, "%.1f", minimum) : "-");
tempMaximum.setText(maximum > 0 ? String.format(Locale.ROOT, "%.1f", maximum) : "-");
final String unit = getString(isMetric ? R.string.unit_celsius : R.string.unit_fahrenheit);
tempAverage.setText(average > 0 ? String.format(Locale.ROOT, "%.1f %s", average, unit) : "-");
tempMinimum.setText(minimum > 0 ? String.format(Locale.ROOT, "%.1f %s", minimum, unit) : "-");
tempMaximum.setText(maximum > 0 ? String.format(Locale.ROOT, "%.1f %s", maximum, unit) : "-");
final int axisGap = (isMetric ? 3 : 6);
if (minimum > 0) {
long axisMin = Math.max(Math.round(minimum) - 3, 0);
long axisMin = Math.max(Math.round(minimum) - axisGap, 0);
tempLineChart.getAxisLeft().setAxisMinimum(axisMin);
tempLineChart.getAxisRight().setAxisMinimum(axisMin);
}
if (maximum > 0) {
tempLineChart.getAxisLeft().setAxisMaximum(Math.round(maximum) + 3);
tempLineChart.getAxisRight().setAxisMaximum(Math.round(maximum) + 3);
tempLineChart.getAxisLeft().setAxisMaximum(Math.round(maximum) + axisGap);
tempLineChart.getAxisRight().setAxisMaximum(Math.round(maximum) + axisGap);
}
tempLineChart.getXAxis().setValueFormatter(new SampleXLabelFormatter(tsTranslation, "HH:mm"));
@@ -237,6 +242,10 @@ public class TemperatureDailyFragment extends AbstractChartFragment<TemperatureD
}
public static float celsiusToFahrenheit(final float celsius) {
return ((celsius * (9f/5f)) + 32f);
}
protected static class TemperatureChartData extends ChartsData {
public List<? extends TemperatureSample> samples;
@@ -134,7 +134,7 @@ public class TestDeviceCoordinator extends AbstractDeviceCoordinator {
@Override
public TimeSampleProvider<? extends TemperatureSample> getTemperatureSampleProvider(final GBDevice device, final DaoSession session) {
return supportsTemperatureMeasurement(device) ? new TestTemperatureSampleProvider() : super.getTemperatureSampleProvider(device, session);
return supportsTemperatureMeasurement(device) ? new TestTemperatureSampleProvider(device) : super.getTemperatureSampleProvider(device, session);
}
@Override
@@ -318,6 +318,11 @@ public class TestDeviceCoordinator extends AbstractDeviceCoordinator {
return supports(getTestDevice(), TestFeature.TEMPERATURE_MEASUREMENT);
}
@Override
public boolean supportsContinuousTemperature(@NonNull final GBDevice device) {
return supports(getTestDevice(), TestFeature.CONTINUOUS_TEMPERATURE);
}
@Override
public boolean supportsActivityTracks(@NonNull final GBDevice device) {
return supports(device, TestFeature.ACTIVITY_TRACKS);
@@ -68,6 +68,7 @@ public enum TestFeature {
BODY_ENERGY,
HRV_MEASUREMENT,
TEMPERATURE_MEASUREMENT,
CONTINUOUS_TEMPERATURE,
UNICODE_EMOJIS,
WATCHFACE_MANAGEMENT,
WEATHER,
@@ -23,22 +23,33 @@ import java.util.ArrayList;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.devices.test.TestDeviceRand;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.model.TemperatureSample;
public class TestTemperatureSampleProvider extends AbstractTestSampleProvider<TemperatureSample> {
private final GBDevice device;
public TestTemperatureSampleProvider(final GBDevice device) {
this.device = device;
}
@NonNull
@Override
public List<TemperatureSample> getAllSamples(final long timestampFrom, final long timestampTo) {
final List<TemperatureSample> samples = new ArrayList<>();
int temp = TestDeviceRand.randInt(timestampFrom, 33, 40);
float temp = TestDeviceRand.randInt(timestampFrom, 33, 40);
for (long ts = timestampFrom; ts < timestampTo; ts += 120 * 60 * 1000L) {
final boolean continuous = device.getDeviceCoordinator().supportsContinuousTemperature(device);
final long temperatureTimeStep = continuous ? 15 * 60 * 1000L : 120 * 60 * 1000L;
final float temperatureValueStep = continuous ? 0.2f : 1f;
for (long ts = timestampFrom; ts < timestampTo; ts += temperatureTimeStep) {
if (TestDeviceRand.randBool(ts, 0.3f)) {
samples.add(new TestTemperatureSample(ts, temp));
}
temp += TestDeviceRand.randInt(ts, 33 - temp, 40 - temp);
break;
temp += (TestDeviceRand.randInt(ts, 33 - Math.round(temp), 40 - Math.round(temp)) * temperatureValueStep);
}
return samples;