1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-11-30 22:12:55 +01:00

Huawei: Continuous skin temperature measurement switch

This commit is contained in:
Me7c7 2024-09-06 16:39:26 +03:00 committed by José Rebelo
parent 42def1cefb
commit 0745a374a5
11 changed files with 186 additions and 0 deletions

View File

@ -82,6 +82,7 @@ public final class HuaweiConstants {
public static final String PREF_HUAWEI_ACCOUNT = "huawei_account"; public static final String PREF_HUAWEI_ACCOUNT = "huawei_account";
public static final String PREF_HUAWEI_DND_LIFT_WRIST_TYPE = "dnd_lift_wrist_type"; // SharedPref for 0x01 0x1D public static final String PREF_HUAWEI_DND_LIFT_WRIST_TYPE = "dnd_lift_wrist_type"; // SharedPref for 0x01 0x1D
public static final String PREF_HUAWEI_DEBUG_REQUEST = "debug_huawei_request"; public static final String PREF_HUAWEI_DEBUG_REQUEST = "debug_huawei_request";
public static final String PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT = "continuous_skin_temperature_measurement";
public static final String PKG_NAME = "com.huawei.devicegroupmanage"; public static final String PKG_NAME = "com.huawei.devicegroupmanage";
} }

View File

@ -220,6 +220,9 @@ public class HuaweiCoordinator {
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_heartrate_automatic_enable); deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_heartrate_automatic_enable);
if (supportsSPo2()) if (supportsSPo2())
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_spo_automatic_enable); deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_spo_automatic_enable);
if(supportsTemperature()) {
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.HEALTH, R.xml.devicesettings_temperature_automatic_enable);
}
// Notifications // Notifications
final List<Integer> notifications = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.NOTIFICATIONS); final List<Integer> notifications = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.NOTIFICATIONS);
@ -266,6 +269,9 @@ public class HuaweiCoordinator {
// Currently on main setting menu. // Currently on main setting menu.
/*if (supportsLanguageSetting()) /*if (supportsLanguageSetting())
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.DISPLAY, R.xml.devicesettings_language_generic);*/ deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.DISPLAY, R.xml.devicesettings_language_generic);*/
if(supportsTemperature()) {
deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.DISPLAY, R.xml.devicesettings_temperature_scale_cf);
}
// Developer // Developer
final List<Integer> developer = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.DEVELOPER); final List<Integer> developer = deviceSpecificSettings.addRootScreen(DeviceSpecificSettingsScreen.DEVELOPER);
@ -391,6 +397,11 @@ public class HuaweiCoordinator {
return supportsCommandForService(0x07, 0x29); return supportsCommandForService(0x07, 0x29);
} }
// 0x1d - SupportTemperature
// 0xba - SupportTemperatureClassification
// 0x43 - SupportTemperatureStudy
public boolean supportsTemperature() { return supportsExpandCapability(0x1d); }
public boolean supportsEventAlarm() { public boolean supportsEventAlarm() {
return supportsCommandForService(0x08, 0x01); return supportsCommandForService(0x08, 0x01);
} }

View File

@ -38,6 +38,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.XTimePreference;
import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.*; import static nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst.*;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_DEBUG_REQUEST; import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_DEBUG_REQUEST;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_TRUSLEEP; import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_TRUSLEEP;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_WORKMODE; import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_WORKMODE;
@ -104,6 +105,7 @@ public class HuaweiSettingsCustomizer implements DeviceSpecificSettingsCustomize
handler.addPreferenceHandlerFor(PREF_HUAWEI_WORKMODE); handler.addPreferenceHandlerFor(PREF_HUAWEI_WORKMODE);
handler.addPreferenceHandlerFor(PREF_HUAWEI_TRUSLEEP); handler.addPreferenceHandlerFor(PREF_HUAWEI_TRUSLEEP);
handler.addPreferenceHandlerFor(PREF_HUAWEI_DEBUG_REQUEST); handler.addPreferenceHandlerFor(PREF_HUAWEI_DEBUG_REQUEST);
handler.addPreferenceHandlerFor(PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT);
final Preference forceOptions = handler.findPreference(PREF_FORCE_OPTIONS); final Preference forceOptions = handler.findPreference(PREF_FORCE_OPTIONS);
if (forceOptions != null) { if (forceOptions != null) {

View File

@ -577,6 +577,25 @@ public class FitnessData {
} }
} }
public static class SkinTemperatureMeasurement {
public static final byte id = 0x2a;
public static class Request extends HuaweiPacket {
public Request(ParamsProvider paramsProvider, boolean temperatureSwitch) {
super(paramsProvider);
this.serviceId = FitnessData.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x01, (byte)0x01)
.put(0x02, temperatureSwitch);
this.complete = true;
}
}
}
public static class Type { public static class Type {
// TODO: enum? // TODO: enum?

View File

@ -49,4 +49,24 @@ public class LocaleConfig {
public static final byte metric = 0x00; public static final byte metric = 0x00;
public static final byte imperial = 0x01; public static final byte imperial = 0x01;
} }
public static class SetTemperatureUnitSetting extends HuaweiPacket {
public static final byte id = 0x05;
public SetTemperatureUnitSetting(
ParamsProvider paramsProvider,
byte isFahrenheit
) {
super(paramsProvider);
this.serviceId = LocaleConfig.id;
this.commandId = id;
this.tlv = new HuaweiTLV()
.put(0x01, isFahrenheit);
this.complete = true;
}
}
} }

View File

@ -121,6 +121,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetA
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetAutomaticSpoRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetAutomaticSpoRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetDisconnectNotification; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetDisconnectNotification;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetMediumToStrengthThresholdRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetMediumToStrengthThresholdRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetSkinTemperatureMeasurement;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetTemperatureUnitSetting;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.StopFindPhoneRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.StopFindPhoneRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.StopNotificationRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.StopNotificationRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetFitnessTotalsRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.GetFitnessTotalsRequest;
@ -925,6 +927,14 @@ public class HuaweiSupportProvider {
setTrusleep(); setTrusleep();
break; break;
} }
case HuaweiConstants.PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT: {
setContinuousSkinTemperatureMeasurement();
break;
}
case DeviceSettingsPreferenceConst.PREF_TEMPERATURE_SCALE_CF: {
setTemperatureUnit();
break;
}
case DeviceSettingsPreferenceConst.PREF_NOTIFICATION_ENABLE: { case DeviceSettingsPreferenceConst.PREF_NOTIFICATION_ENABLE: {
setNotificationStatus(); setNotificationStatus();
break; break;
@ -1661,6 +1671,28 @@ public class HuaweiSupportProvider {
} }
} }
public void setTemperatureUnit() {
try {
SetTemperatureUnitSetting setTemperatureUnitSetting = new SetTemperatureUnitSetting(this);
setTemperatureUnitSetting.doPerform();
} catch (IOException e) {
// TODO: Use translatable string
GB.toast(context, "Failed to set temperature unit", Toast.LENGTH_SHORT, GB.ERROR, e);
LOG.error("Failed to configure TemperatureUnitSetting", e);
}
}
public void setContinuousSkinTemperatureMeasurement() {
try {
SetSkinTemperatureMeasurement skinTemperatureMeasurement = new SetSkinTemperatureMeasurement(this);
skinTemperatureMeasurement.doPerform();
} catch (IOException e) {
// TODO: Use translatable string
GB.toast(context, "Failed to configure continuous skin temperature measurement", Toast.LENGTH_SHORT, GB.ERROR, e);
LOG.error("Failed to configure SkinTemperatureMeasurement", e);
}
}
public void setDnd() { public void setDnd() {
try { try {
SendDndDeleteRequest sendDndDeleteReq = new SendDndDeleteRequest(this); SendDndDeleteRequest sendDndDeleteReq = new SendDndDeleteRequest(this);

View File

@ -0,0 +1,39 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.FitnessData;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class SetSkinTemperatureMeasurement extends Request {
private static final Logger LOG = LoggerFactory.getLogger(SetSkinTemperatureMeasurement.class);
public SetSkinTemperatureMeasurement(HuaweiSupportProvider support) {
super(support);
this.serviceId = FitnessData.id;
this.commandId = FitnessData.SkinTemperatureMeasurement.id;
}
@Override
protected List<byte[]> createRequest() throws RequestCreationException {
boolean temperatureSwitch = GBApplication
.getDeviceSpecificSharedPrefs(this.getDevice().getAddress())
.getBoolean(HuaweiConstants.PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT, false);
try {
return new FitnessData.SkinTemperatureMeasurement.Request(paramsProvider, temperatureSwitch).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}
}
@Override
protected void processResponse() {
LOG.debug("handle Set SkinTemperatureMeasurement");
}
}

View File

@ -0,0 +1,38 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.LocaleConfig;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class SetTemperatureUnitSetting extends Request {
private static final Logger LOG = LoggerFactory.getLogger(SetLanguageSettingRequest.class);
public SetTemperatureUnitSetting(HuaweiSupportProvider support) {
super(support);
this.serviceId = LocaleConfig.id;
this.commandId = LocaleConfig.SetTemperatureUnitSetting.id;
}
@Override
protected List<byte[]> createRequest() throws RequestCreationException {
String temperatureScale = GBApplication.getDeviceSpecificSharedPrefs(this.getDevice().getAddress()).getString(DeviceSettingsPreferenceConst.PREF_TEMPERATURE_SCALE_CF, "");
byte isFahrenheit = (byte) ((temperatureScale.equals("f")) ? 1 : 0);
try {
return new LocaleConfig.SetTemperatureUnitSetting(paramsProvider, isFahrenheit).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new RequestCreationException(e);
}
}
@Override
protected void processResponse() {
LOG.debug("handle Set Temperature unit");
}
}

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="m11.182,1.149c-1.543,0 -2.786,1.452 -2.786,3.255v8.775a5.82,5.163 0,0 0,-3.034 4.53,5.82 5.163,0 0,0 5.82,5.163 5.82,5.163 0,0 0,5.82 -5.163,5.82 5.163,0 0,0 -3.034,-4.533L13.968,4.404c0,-1.803 -1.242,-3.255 -2.786,-3.255zM8.475,4.763h1.93c0.04,0 0.073,0.032 0.073,0.072v0.873c0,0.04 -0.033,0.072 -0.073,0.072L8.475,5.781c-0.04,0 -0.073,-0.032 -0.073,-0.072L8.402,4.835c0,-0.04 0.033,-0.072 0.073,-0.072zM8.5,7.779h2.593c0.054,0 0.098,0.032 0.098,0.072v0.873c0,0.04 -0.044,0.072 -0.098,0.072L8.5,8.798c-0.054,0 -0.098,-0.032 -0.098,-0.072L8.402,7.852c0,-0.04 0.044,-0.072 0.098,-0.072zM8.475,10.796h1.93c0.04,0 0.073,0.032 0.073,0.072v0.873c0,0.04 -0.033,0.072 -0.073,0.072L8.475,11.814c-0.04,0 -0.073,-0.032 -0.073,-0.072v-0.873c0,-0.04 0.033,-0.072 0.073,-0.072z"
android:strokeWidth="1.5"
android:fillColor="#00000000"
android:strokeColor="#7e7e7e"
android:fillAlpha="0"/>
</vector>

View File

@ -2750,6 +2750,8 @@
<string name="pref_activity_recognition_mode_none">none</string> <string name="pref_activity_recognition_mode_none">none</string>
<string name="pref_activity_recognition_mode_ask">ask</string> <string name="pref_activity_recognition_mode_ask">ask</string>
<string name="pref_activity_recognition_mode_auto">auto</string> <string name="pref_activity_recognition_mode_auto">auto</string>
<string name="pref_continuous_skin_temperature_measurement_title">Continuous skin temperature measurement</string>
<string name="pref_continuous_skin_temperature_measurement_description">Temperature retrieval is not currently supported. This setting only enable continuous measurement on the device</string>
<string name="menuitem_menu">Menu</string> <string name="menuitem_menu">Menu</string>
<string name="fossil_hr_button_config_info">Some buttons cannot be configured because their functions are hard-coded in the watch firmware.\n\nWarning: long-pressing the upper button when a watchface from the official Fossil app is installed will also toggle between showing/hiding widgets.</string> <string name="fossil_hr_button_config_info">Some buttons cannot be configured because their functions are hard-coded in the watch firmware.\n\nWarning: long-pressing the upper button when a watchface from the official Fossil app is installed will also toggle between showing/hiding widgets.</string>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreferenceCompat
android:icon="@drawable/ic_temperature"
android:defaultValue="false"
android:key="continuous_skin_temperature_measurement"
android:layout="@layout/preference_checkbox"
android:summary="@string/pref_continuous_skin_temperature_measurement_description"
android:title="@string/pref_continuous_skin_temperature_measurement_title" />
</androidx.preference.PreferenceScreen>