Huawei: Changed the sleep prefs and enabled sleep breathing awareness configuration

Sleep breathing awareness can be enabled for some devices.
Information is currently not retrieved from the watch.
This commit is contained in:
Me7c7
2025-08-16 14:54:36 +03:00
parent 878018f412
commit f76d64b20d
9 changed files with 120 additions and 21 deletions
@@ -97,6 +97,7 @@ public final class HuaweiConstants {
public static final String PREF_HUAWEI_ADDRESS = "huawei_address"; public static final String PREF_HUAWEI_ADDRESS = "huawei_address";
public static final String PREF_HUAWEI_WORKMODE = "workmode"; public static final String PREF_HUAWEI_WORKMODE = "workmode";
public static final String PREF_HUAWEI_TRUSLEEP = "trusleep"; public static final String PREF_HUAWEI_TRUSLEEP = "trusleep";
public static final String PREF_HUAWEI_SLEEP_BREATH = "huawei_sleep_breath";
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";
@@ -871,6 +871,12 @@ public class HuaweiCoordinator {
return false; return false;
} }
public boolean supportsSleepBreath() {
if (supportsExpandCapability())
return supportsExpandCapability(178); // 107
return false;
}
public boolean supportsPromptPushMessage () { public boolean supportsPromptPushMessage () {
// do not ask for capabilities under specific condition // do not ask for capabilities under specific condition
// if (deviceType == 10 && deviceVersion == 73617766697368 && deviceSoftVersion == 372E312E31) -> leo device // if (deviceType == 10 && deviceVersion == 73617766697368 && deviceSoftVersion == 372E312E31) -> leo device
@@ -48,6 +48,7 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstant
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_HEART_RATE_HIGH_ALERT; import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_HEART_RATE_HIGH_ALERT;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_HEART_RATE_LOW_ALERT; import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_HEART_RATE_LOW_ALERT;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_HEART_RATE_REALTIME_MODE; import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_HEART_RATE_REALTIME_MODE;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_SLEEP_BREATH;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_SPO_LOW_ALERT; import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_SPO_LOW_ALERT;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_STRESS_CALIBRATE; import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_STRESS_CALIBRATE;
import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_STRESS_SWITCH; import static nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiConstants.PREF_HUAWEI_STRESS_SWITCH;
@@ -116,6 +117,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_SLEEP_BREATH);
handler.addPreferenceHandlerFor(PREF_HUAWEI_DEBUG_REQUEST); handler.addPreferenceHandlerFor(PREF_HUAWEI_DEBUG_REQUEST);
handler.addPreferenceHandlerFor(PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT); handler.addPreferenceHandlerFor(PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT);
handler.addPreferenceHandlerFor(PREF_HUAWEI_HEART_RATE_REALTIME_MODE); handler.addPreferenceHandlerFor(PREF_HUAWEI_HEART_RATE_REALTIME_MODE);
@@ -147,6 +149,12 @@ public class HuaweiSettingsCustomizer implements DeviceSpecificSettingsCustomize
forceSpO2.setVisible(!supportsSpO2); forceSpO2.setVisible(!supportsSpO2);
} }
final SwitchPreferenceCompat sleepBreath = handler.findPreference(PREF_HUAWEI_SLEEP_BREATH);
if(sleepBreath != null && !coordinator.supportsSleepBreath()) {
sleepBreath.setVisible(false);
}
final SwitchPreferenceCompat reparseWorkout = handler.findPreference("huawei_reparse_workout_data"); final SwitchPreferenceCompat reparseWorkout = handler.findPreference("huawei_reparse_workout_data");
if (reparseWorkout != null) { if (reparseWorkout != null) {
reparseWorkout.setVisible(false); reparseWorkout.setVisible(false);
@@ -0,0 +1,26 @@
package nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiTLV;
public class Breath {
public static final byte id = 0x2d;
public static class SleepBreath {
public static final byte id = 0x01;
public static class Request extends HuaweiPacket {
public Request(ParamsProvider paramsProvider, byte type) {
super(paramsProvider);
this.serviceId = Breath.id;
this.commandId = id;
this.tlv = new HuaweiTLV().put(0x1, type);
this.isEncrypted = true;
this.complete = true;
}
}
}
}
@@ -167,6 +167,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Send
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendSetContactsRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendSetContactsRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotifyHeartRateCapabilityRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotifyHeartRateCapabilityRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotifyRestHeartRateCapabilityRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotifyRestHeartRateCapabilityRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendSleepBreathRequest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetAutomaticHeartrateRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SetAutomaticHeartrateRequest;
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;
@@ -882,6 +883,7 @@ public class HuaweiSupportProvider {
initRequestQueue.add(new SetDateFormatRequest(this)); initRequestQueue.add(new SetDateFormatRequest(this));
initRequestQueue.add(new SetActivityReminderRequest(this)); initRequestQueue.add(new SetActivityReminderRequest(this));
initRequestQueue.add(new SetTruSleepRequest(this)); initRequestQueue.add(new SetTruSleepRequest(this));
initRequestQueue.add(new SendSleepBreathRequest(this));
initRequestQueue.add(new GetContactsCount(this)); initRequestQueue.add(new GetContactsCount(this));
initRequestQueue.add(new SendOTASetAutoUpdate(this)); initRequestQueue.add(new SendOTASetAutoUpdate(this));
initRequestQueue.add(new GetOTAChangeLog(this)); initRequestQueue.add(new GetOTAChangeLog(this));
@@ -1113,6 +1115,10 @@ public class HuaweiSupportProvider {
setTrusleep(); setTrusleep();
break; break;
} }
case HuaweiConstants.PREF_HUAWEI_SLEEP_BREATH: {
setSleepBreath();
break;
}
case HuaweiConstants.PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT: { case HuaweiConstants.PREF_HUAWEI_CONTINUOUS_SKIN_TEMPERATURE_MEASUREMENT: {
setContinuousSkinTemperatureMeasurement(); setContinuousSkinTemperatureMeasurement();
break; break;
@@ -2305,6 +2311,16 @@ public class HuaweiSupportProvider {
} }
} }
public void setSleepBreath() {
try {
SendSleepBreathRequest setSleepBreathReq = new SendSleepBreathRequest(this);
setSleepBreathReq.doPerform();
} catch (IOException e) {
GB.toast(context, "Failed to configure sleep breathing awareness", Toast.LENGTH_SHORT, GB.ERROR, e);
LOG.error("Failed to configure sleep breathing awareness", e);
}
}
public void setTemperatureUnit() { public void setTemperatureUnit() {
try { try {
SetTemperatureUnitSetting setTemperatureUnitSetting = new SetTemperatureUnitSetting(this); SetTemperatureUnitSetting setTemperatureUnitSetting = new SetTemperatureUnitSetting(this);
@@ -16,9 +16,6 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. */ along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List; import java.util.List;
import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket; import nodomain.freeyourgadget.gadgetbridge.devices.huawei.HuaweiPacket;
@@ -26,8 +23,6 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huawei.packets.HrRriTest;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class SendHROpenCloseRequest extends Request { public class SendHROpenCloseRequest extends Request {
private static final Logger LOG = LoggerFactory.getLogger(SendHROpenCloseRequest.class);
private final byte type; private final byte type;
public SendHROpenCloseRequest(HuaweiSupportProvider support, byte type) { public SendHROpenCloseRequest(HuaweiSupportProvider support, byte type) {
@@ -0,0 +1,36 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests;
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.Breath;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.HuaweiSupportProvider;
public class SendSleepBreathRequest extends Request {
public SendSleepBreathRequest(HuaweiSupportProvider support) {
super(support);
this.serviceId = Breath.id;
this.commandId = Breath.SleepBreath.id;
}
@Override
protected boolean requestSupported() {
return supportProvider.getHuaweiCoordinator().supportsSleepBreath();
}
@Override
protected List<byte[]> createRequest() throws Request.RequestCreationException {
boolean sleepBreathSwitch = GBApplication
.getDeviceSpecificSharedPrefs(this.getDevice().getAddress())
.getBoolean(HuaweiConstants.PREF_HUAWEI_SLEEP_BREATH, false);
byte type = (byte) (sleepBreathSwitch?2:0);
try {
return new Breath.SleepBreath.Request(paramsProvider, type).serialize();
} catch (HuaweiPacket.CryptoException e) {
throw new Request.RequestCreationException(e);
}
}
}
+4 -3
View File
@@ -3340,10 +3340,11 @@
<string name="prefs_workmode">Work Mode</string> <string name="prefs_workmode">Work Mode</string>
<string name="huawei_alarm_smart_description">Do not uncheck smart wakeup checkbox.</string> <string name="huawei_alarm_smart_description">Do not uncheck smart wakeup checkbox.</string>
<string name="huawei_alarm_event_description">Do not check smart wakeup checkbox.</string> <string name="huawei_alarm_event_description">Do not check smart wakeup checkbox.</string>
<string name="huawei_trusleep_title">HUAWEI TruSleep &#8482;</string> <string name="huawei_trusleep_title">HUAWEI TruSleep&#8482;</string>
<string name="huawei_trusleep_summary">Monitor your sleep quality and breathing pattern in real time.\nAnalyze your sleep patterns and accurately diagnose 6 types of sleeping problems.</string> <string name="huawei_trusleep_summary">Monitor your sleep quality in real time.</string>
<string name="huawei_trusleep_summary_light">Improved sleep monitoring</string> <string name="huawei_trusleep_summary_light">Improved sleep monitoring</string>
<string name="huawei_trusleep_warning">Warning: enabling this will make all sleep show up as light sleep in Gadgetbridge! Click here if you accept this.</string> <string name="huawei_trusleep_warning">Warning: TruSleep&#8482; is not fully implemented. Enabling it on some devices will cause all sleep data to show up as light sleep in Gadgetbridge!</string>
<string name="huawei_sleep_breath_summary">Assess your breathing in a quiet environment. May affect battery life.\nWarning: Not synced to the Gadgetbridge yet.</string>
<string name="prefs_activity_recognition">Activity recognition settings</string> <string name="prefs_activity_recognition">Activity recognition settings</string>
<string name="pref_activity_recognize_running">recognize running</string> <string name="pref_activity_recognize_running">recognize running</string>
<string name="pref_activity_recognize_biking">recognize biking</string> <string name="pref_activity_recognize_biking">recognize biking</string>
@@ -4,23 +4,33 @@
android:icon="@drawable/ic_activity_sleep" android:icon="@drawable/ic_activity_sleep"
android:key="screen_trusleep" android:key="screen_trusleep"
android:persistent="false" android:persistent="false"
android:title="@string/huawei_trusleep_title" android:summary="@string/huawei_trusleep_summary_light"
android:summary="@string/huawei_trusleep_summary_light"> android:title="@string/huawei_trusleep_title">
<PreferenceScreen <PreferenceScreen
android:icon="@drawable/ic_activity_sleep" android:icon="@drawable/ic_warning"
android:key="screen_trusleep_warning" android:key="screen_trusleep_warning"
android:title="@string/huawei_trusleep_title" android:persistent="false"
android:summary="@string/huawei_trusleep_warning"> android:selectable="false"
android:summary="@string/huawei_trusleep_warning"
android:title="@string/huawei_trusleep_title" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:icon="@drawable/ic_activity_sleep" android:defaultValue="false"
android:defaultValue="false" android:icon="@drawable/ic_activity_sleep"
android:key="trusleep" android:key="trusleep"
android:layout="@layout/preference_checkbox" android:layout="@layout/preference_checkbox"
android:title="@string/huawei_trusleep_title" android:summary="@string/huawei_trusleep_summary"
android:summary="@string/huawei_trusleep_summary"/> android:title="@string/huawei_trusleep_title" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:dependency="trusleep"
android:icon="@drawable/ic_activity_sleep"
android:key="huawei_sleep_breath"
android:layout="@layout/preference_checkbox"
android:summary="@string/huawei_sleep_breath_summary"
android:title="@string/pref_sleep_breathing_quality_monitoring" />
</PreferenceScreen>
</PreferenceScreen> </PreferenceScreen>
</androidx.preference.PreferenceScreen> </androidx.preference.PreferenceScreen>