From 17b530c989d24fd1832d5864f799ab31530f3be3 Mon Sep 17 00:00:00 2001 From: Me7c7 Date: Fri, 20 Sep 2024 17:19:50 +0300 Subject: [PATCH] Huawei: simple run pace config added --- .../devices/huawei/HuaweiCoordinator.java | 6 ++ .../devices/huawei/HuaweiPacket.java | 2 + .../devices/huawei/packets/FitnessData.java | 44 +++++++++++++++ .../devices/huawei/HuaweiSupportProvider.java | 2 + .../requests/SendRunPaceConfigRequest.java | 55 +++++++++++++++++++ 5 files changed, 109 insertions(+) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendRunPaceConfigRequest.java 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 3fb7b053b..f45c81063 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 @@ -393,11 +393,17 @@ public class HuaweiCoordinator { return supportsSPo2() || getForceOption(gbDevice, PREF_FORCE_ENABLE_SPO2_SUPPORT); } + public boolean supportsRunPaceConfig() { + return supportsCommandForService(0x07, 0x28); + } + public boolean supportsFitnessThresholdValue() { return supportsCommandForService(0x07, 0x29); } public boolean supportsFitnessThresholdValueV2() { return supportsExpandCapability(0x9a) || supportsExpandCapability(0x9c); } + + // 0x1d - SupportTemperature // 0xba - SupportTemperatureClassification // 0x43 - SupportTemperatureStudy diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiPacket.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiPacket.java index 705929ec1..b86a0d259 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiPacket.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/HuaweiPacket.java @@ -503,6 +503,8 @@ public class HuaweiPacket { return new FitnessData.MessageCount.Response(paramsProvider).fromPacket(this); case FitnessData.MessageData.sleepId: return new FitnessData.MessageData.SleepResponse(paramsProvider).fromPacket(this); + case FitnessData.RunPaceConfig.id: + return new FitnessData.RunPaceConfig.Response(paramsProvider).fromPacket(this); default: this.isEncrypted = this.attemptDecrypt(); // Helps with debugging return this; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/FitnessData.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/FitnessData.java index 39a02be04..12a4a63a9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/FitnessData.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/huawei/packets/FitnessData.java @@ -539,6 +539,50 @@ public class FitnessData { } } } + public static class RunPaceConfig { + public static final byte id = 0x28; + + public static class Request extends HuaweiPacket { + public Request(ParamsProvider paramsProvider, + int easyPaceZoneMinValue, + int marathonPaceZoneMinValue, + int lactatePaceZoneMinValue, + int anaerobicPaceZoneMinValue, + int maxOxygenPaceZoneMinValue, + int maxOxygenPaceZoneMaxValue) { + super(paramsProvider); + + this.serviceId = FitnessData.id; + this.commandId = id; + + this.tlv = new HuaweiTLV() + .put(0x01, (short)easyPaceZoneMinValue) + .put(0x02, (short)marathonPaceZoneMinValue) + .put(0x03, (short)lactatePaceZoneMinValue) + .put(0x04, (short)anaerobicPaceZoneMinValue) + .put(0x05, (short)maxOxygenPaceZoneMinValue) + .put(0x06, (short)maxOxygenPaceZoneMaxValue); + this.complete = true; + } + } + + public static class Response extends HuaweiPacket { + + public boolean isOk; + + public Response(ParamsProvider paramsProvider) { + super(paramsProvider); + this.serviceId = FitnessData.id; + this.commandId = id; + } + + @Override + public void parseTlv() throws ParseException { + isOk = this.tlv.getInteger(0x7f) == 0x000186A0; + } + } + + } public static class MediumToStrengthThreshold { public static final byte id = 0x29; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java index de9ca73fb..9ea0ef43b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/HuaweiSupportProvider.java @@ -107,6 +107,7 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.Send import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsAndTimeToDeviceRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendGpsDataRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendFileUploadInfo; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendRunPaceConfigRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendSetContactsRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendWeatherCurrentRequest; import nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests.SendNotifyHeartRateCapabilityRequest; @@ -723,6 +724,7 @@ public class HuaweiSupportProvider { initRequestQueue.add(new SendMenstrualCapabilityRequest(this)); initRequestQueue.add(new SendNotifyHeartRateCapabilityRequest(this)); initRequestQueue.add(new SendNotifyRestHeartRateCapabilityRequest(this)); + initRequestQueue.add(new SendRunPaceConfigRequest(this)); initRequestQueue.add(new SetMediumToStrengthThresholdRequest(this)); initRequestQueue.add(new SendFitnessGoalRequest(this)); initRequestQueue.add(new GetNotificationCapabilitiesRequest(this)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendRunPaceConfigRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendRunPaceConfigRequest.java new file mode 100644 index 000000000..bb1be876f --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huawei/requests/SendRunPaceConfigRequest.java @@ -0,0 +1,55 @@ +package nodomain.freeyourgadget.gadgetbridge.service.devices.huawei.requests; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +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 SendRunPaceConfigRequest extends Request { + private static final Logger LOG = LoggerFactory.getLogger(SendRunPaceConfigRequest.class); + + public SendRunPaceConfigRequest(HuaweiSupportProvider support) { + super(support); + this.serviceId = FitnessData.id; + this.commandId = FitnessData.RunPaceConfig.id; + } + + @Override + protected boolean requestSupported() { + return supportProvider.getHuaweiCoordinator().supportsRunPaceConfig(); + } + + @Override + protected List createRequest() throws Request.RequestCreationException { + try { + //Hardcoded value till interface enable threshold values + return new FitnessData.RunPaceConfig.Request(paramsProvider, + 0x1C2, + 0x1A4, + 0x186, + 0x168, + 0x14A, + 0x12C + ).serialize(); + } catch (HuaweiPacket.CryptoException e) { + throw new Request.RequestCreationException(e); + } + } + + @Override + protected void processResponse() { + if (receivedPacket instanceof FitnessData.RunPaceConfig.Response) { + if (((FitnessData.RunPaceConfig.Response) receivedPacket).isOk) { + LOG.debug("RunPace set"); + } else { + LOG.warn("Error set RunPace"); + } + } else { + LOG.error("Set RunPace response is not of type RunPaceConfig response"); + } + } +}