mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Zepp OS: Add temperature support
This commit is contained in:
+2
-2
@@ -113,7 +113,7 @@ public class ActivityChartsActivity extends AbstractChartsActivity {
|
||||
if (!coordinator.supportsRealtimeData()) {
|
||||
tabList.remove("livestats");
|
||||
}
|
||||
if (!coordinator.supportsTemperatureMeasurement()) {
|
||||
if (!coordinator.supportsTemperatureMeasurement(device)) {
|
||||
tabList.remove("temperature");
|
||||
}
|
||||
if (!coordinator.supportsCyclingData()) {
|
||||
@@ -190,7 +190,7 @@ public class ActivityChartsActivity extends AbstractChartsActivity {
|
||||
case "spo2":
|
||||
return new Spo2ChartFragment();
|
||||
case "temperature":
|
||||
return coordinator.supportsContinuousTemperature()? new TemperatureDailyFragment(): new TemperatureChartFragment();
|
||||
return coordinator.supportsContinuousTemperature(getDevice())? new TemperatureDailyFragment(): new TemperatureChartFragment();
|
||||
case "cycling":
|
||||
return new CyclingChartFragment();
|
||||
case "weight":
|
||||
|
||||
+2
-2
@@ -550,12 +550,12 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemperatureMeasurement() {
|
||||
public boolean supportsTemperatureMeasurement(final GBDevice device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsContinuousTemperature() {
|
||||
public boolean supportsContinuousTemperature(final GBDevice device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -257,13 +257,13 @@ public interface DeviceCoordinator {
|
||||
* Returns true if measurement and fetching of body temperature is supported by the device
|
||||
* (with this coordinator).
|
||||
*/
|
||||
boolean supportsTemperatureMeasurement();
|
||||
boolean supportsTemperatureMeasurement(GBDevice device);
|
||||
|
||||
/**
|
||||
* Returns true if continuous temperature measurement used in device
|
||||
* (with this coordinator).
|
||||
*/
|
||||
boolean supportsContinuousTemperature();
|
||||
boolean supportsContinuousTemperature(GBDevice device);
|
||||
|
||||
/**
|
||||
* Returns true if SpO2 measurement and fetching is supported by the device
|
||||
|
||||
+1
-1
@@ -235,7 +235,7 @@ public abstract class AbstractColmiR0xCoordinator extends AbstractBLEDeviceCoord
|
||||
final DeviceSpecificSettings deviceSpecificSettings = new DeviceSpecificSettings();
|
||||
final List<Integer> health = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH);
|
||||
health.add(R.xml.devicesettings_colmi_r0x);
|
||||
if (supportsContinuousTemperature()) {
|
||||
if (supportsContinuousTemperature(device)) {
|
||||
health.add(R.xml.devicesettings_temperature_automatic_enable);
|
||||
}
|
||||
return deviceSpecificSettings;
|
||||
|
||||
+2
-2
@@ -43,12 +43,12 @@ public class ColmiR09Coordinator extends AbstractColmiR0xCoordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemperatureMeasurement() {
|
||||
public boolean supportsTemperatureMeasurement(final GBDevice device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsContinuousTemperature() {
|
||||
public boolean supportsContinuousTemperature(final GBDevice device) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ public class FemometerVinca2DeviceCoordinator extends AbstractDeviceCoordinator
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemperatureMeasurement() {
|
||||
public boolean supportsTemperatureMeasurement(final GBDevice device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+8
@@ -46,6 +46,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSpec
|
||||
import nodomain.freeyourgadget.gadgetbridge.capabilities.password.PasswordCapabilityImpl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.AbstractBLEDeviceCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.GenericHrvValueSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.GenericTemperatureSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.TimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.DateTimeDisplay;
|
||||
@@ -60,6 +61,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummaryDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GenericHrvValueSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GenericTemperatureSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuamiExtendedActivitySampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuamiHeartRateManualSampleDao;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.HuamiHeartRateMaxSampleDao;
|
||||
@@ -112,6 +114,7 @@ public abstract class HuamiCoordinator extends AbstractBLEDeviceCoordinator {
|
||||
put(session.getHuamiPaiSampleDao(), HuamiPaiSampleDao.Properties.DeviceId);
|
||||
put(session.getHuamiSleepRespiratoryRateSampleDao(), HuamiSleepRespiratoryRateSampleDao.Properties.DeviceId);
|
||||
put(session.getGenericHrvValueSampleDao(), GenericHrvValueSampleDao.Properties.DeviceId);
|
||||
put(session.getGenericTemperatureSampleDao(), GenericTemperatureSampleDao.Properties.DeviceId);
|
||||
put(session.getHuamiSleepSessionSampleDao(), HuamiSleepSessionSampleDao.Properties.DeviceId);
|
||||
put(session.getBaseActivitySummaryDao(), BaseActivitySummaryDao.Properties.DeviceId);
|
||||
}};
|
||||
@@ -213,6 +216,11 @@ public abstract class HuamiCoordinator extends AbstractBLEDeviceCoordinator {
|
||||
return new GenericHrvValueSampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericTemperatureSampleProvider getTemperatureSampleProvider(GBDevice device, DaoSession session) {
|
||||
return new GenericTemperatureSampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends SleepScoreSample> getSleepScoreProvider(final GBDevice device, final DaoSession session) {
|
||||
return new HuamiSleepSessionSampleProvider(device, session);
|
||||
|
||||
+7
-2
@@ -523,8 +523,13 @@ public abstract class ZeppOsCoordinator extends HuamiCoordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemperatureMeasurement() {
|
||||
return false; // TODO: supportsDisplayItem(device, "temperature");
|
||||
public boolean supportsTemperatureMeasurement(final GBDevice device) {
|
||||
return supportsDisplayItem(device, "thermometer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsContinuousTemperature(final GBDevice device) {
|
||||
return supportsDisplayItem(device, "thermometer");
|
||||
}
|
||||
|
||||
public boolean supportsAgpsUpdates() {
|
||||
|
||||
+2
-2
@@ -205,12 +205,12 @@ public abstract class HuaweiBRCoordinator extends AbstractBLClassicDeviceCoordin
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemperatureMeasurement() {
|
||||
public boolean supportsTemperatureMeasurement(final GBDevice device) {
|
||||
return huaweiCoordinator.supportsTemperature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsContinuousTemperature() {
|
||||
public boolean supportsContinuousTemperature(final GBDevice device) {
|
||||
return huaweiCoordinator.supportsTemperature();
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -41,7 +41,6 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryParser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.Spo2Sample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.TemperatureSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.DeviceSupport;
|
||||
@@ -214,12 +213,12 @@ public abstract class HuaweiLECoordinator extends AbstractBLEDeviceCoordinator i
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemperatureMeasurement() {
|
||||
public boolean supportsTemperatureMeasurement(final GBDevice device) {
|
||||
return huaweiCoordinator.supportsTemperature();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsContinuousTemperature() {
|
||||
public boolean supportsContinuousTemperature(final GBDevice device) {
|
||||
return huaweiCoordinator.supportsTemperature();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -84,12 +84,12 @@ public abstract class AbstractMijiaLywsdCoordinator extends AbstractBLEDeviceCoo
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemperatureMeasurement() {
|
||||
public boolean supportsTemperatureMeasurement(final GBDevice device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsContinuousTemperature() {
|
||||
public boolean supportsContinuousTemperature(final GBDevice device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -145,7 +145,7 @@ public class TestDeviceCoordinator extends AbstractDeviceCoordinator {
|
||||
|
||||
@Override
|
||||
public TimeSampleProvider<? extends TemperatureSample> getTemperatureSampleProvider(final GBDevice device, final DaoSession session) {
|
||||
return supportsTemperatureMeasurement() ? new TestTemperatureSampleProvider() : super.getTemperatureSampleProvider(device, session);
|
||||
return supportsTemperatureMeasurement(device) ? new TestTemperatureSampleProvider() : super.getTemperatureSampleProvider(device, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -325,7 +325,7 @@ public class TestDeviceCoordinator extends AbstractDeviceCoordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemperatureMeasurement() {
|
||||
public boolean supportsTemperatureMeasurement(final GBDevice device) {
|
||||
return supports(getTestDevice(), TestFeature.TEMPERATURE_MEASUREMENT);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -172,7 +172,7 @@ public class UltrahumanDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsContinuousTemperature() {
|
||||
public boolean supportsContinuousTemperature(final GBDevice device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ public class UltrahumanDeviceCoordinator extends AbstractBLEDeviceCoordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemperatureMeasurement() {
|
||||
public boolean supportsTemperatureMeasurement(final GBDevice device) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -20,6 +20,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
|
||||
public class XiaomiWatchS1ProCoordinator extends XiaomiCoordinator {
|
||||
|
||||
@@ -60,7 +61,7 @@ public class XiaomiWatchS1ProCoordinator extends XiaomiCoordinator {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsTemperatureMeasurement() {
|
||||
public boolean supportsTemperatureMeasurement(final GBDevice device) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -314,7 +314,7 @@ public class ColmiR0xDeviceSupport extends AbstractBTLEDeviceSupport {
|
||||
daysAgo++;
|
||||
fetchHistoryHRV();
|
||||
} else {
|
||||
if (getDevice().getDeviceCoordinator().supportsTemperatureMeasurement()) {
|
||||
if (getDevice().getDeviceCoordinator().supportsTemperatureMeasurement(gbDevice)) {
|
||||
fetchTemperature();
|
||||
} else {
|
||||
fetchRecordedDataFinished();
|
||||
|
||||
+1
-1
@@ -1728,7 +1728,7 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
||||
this.fetchOperationQueue.add(new FetchSleepRespiratoryRateOperation(this));
|
||||
}
|
||||
|
||||
if ((dataTypes & RecordedDataTypes.TYPE_TEMPERATURE) != 0 && coordinator.supportsTemperatureMeasurement()) {
|
||||
if ((dataTypes & RecordedDataTypes.TYPE_TEMPERATURE) != 0 && coordinator.supportsTemperatureMeasurement(gbDevice)) {
|
||||
this.fetchOperationQueue.add(new FetchTemperatureOperation(this));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ public abstract class AbstractRepeatingFetchOperation extends AbstractFetchOpera
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fetchCount > 5) {
|
||||
if (fetchCount > 10) {
|
||||
LOG.warn("Already have {} fetch rounds for {}, not doing another one", fetchCount, getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
+51
-8
@@ -16,15 +16,27 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.fetch;
|
||||
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.GenericTemperatureSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||
import nodomain.freeyourgadget.gadgetbridge.entities.GenericTemperatureSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
|
||||
/**
|
||||
@@ -51,17 +63,48 @@ public class FetchTemperatureOperation extends AbstractRepeatingFetchOperation {
|
||||
|
||||
final ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
while (buffer.position() < bytes.length) {
|
||||
final int temp1 = buffer.getShort();
|
||||
final int temp2 = buffer.getShort();
|
||||
final int temp3 = buffer.getShort();
|
||||
final int temp4 = buffer.getShort();
|
||||
final List<GenericTemperatureSample> samples = new ArrayList<>();
|
||||
|
||||
// TODO persist / parse rest
|
||||
LOG.warn("temp1: {}, temp2={}, temp3: {}, temp4={}", temp1, temp2, temp3, temp4);
|
||||
while (buffer.position() < bytes.length) {
|
||||
final int unk1 = buffer.getShort(); // 32767
|
||||
final int temperature = buffer.getShort();
|
||||
final int unk3 = buffer.getShort(); // 23130
|
||||
final int unk4 = buffer.getShort(); // 23130
|
||||
|
||||
LOG.trace(
|
||||
"Temperature at {}: {}",
|
||||
DateTimeUtils.formatIso8601(timestamp.getTime()),
|
||||
temperature
|
||||
);
|
||||
|
||||
final GenericTemperatureSample sample = new GenericTemperatureSample();
|
||||
sample.setTimestamp(timestamp.getTimeInMillis());
|
||||
sample.setTemperature(temperature / 100f);
|
||||
sample.setTemperatureType(0);
|
||||
samples.add(sample);
|
||||
|
||||
timestamp.add(Calendar.MINUTE, 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
timestamp.add(Calendar.MINUTE, -1);
|
||||
|
||||
return persistSamples(samples);
|
||||
}
|
||||
|
||||
protected boolean persistSamples(final List<GenericTemperatureSample> samples) {
|
||||
try (DBHandler handler = GBApplication.acquireDB()) {
|
||||
final DaoSession session = handler.getDaoSession();
|
||||
|
||||
final HuamiCoordinator coordinator = (HuamiCoordinator) getDevice().getDeviceCoordinator();
|
||||
final GenericTemperatureSampleProvider sampleProvider = coordinator.getTemperatureSampleProvider(getDevice(), session);
|
||||
|
||||
sampleProvider.persistForDevice(getContext(), getDevice(), samples);
|
||||
} catch (final Exception e) {
|
||||
GB.toast(getContext(), "Error saving temperature samples", Toast.LENGTH_LONG, GB.ERROR, e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user