From 94c7b43ad478b1b870bcf1ca4fa1e0d1542cd78e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Rebelo?= Date: Wed, 26 Apr 2023 09:51:14 +0100 Subject: [PATCH] Zepp OS: Map known watchfaces to human-readable names --- .../devices/huami/Huami2021Support.java | 5 ++ .../UpdateFirmwareOperation2021.java | 18 ++++- .../services/ZeppOsWatchfaceService.java | 68 ++++++++++++++++--- app/src/main/res/values/arrays.xml | 28 ++++++++ app/src/main/res/values/strings.xml | 10 +++ .../devicesettings_huami2021_watchface.xml | 4 +- 6 files changed, 120 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java index f8cd09715..18ad7b2d4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/Huami2021Support.java @@ -1460,6 +1460,11 @@ public abstract class Huami2021Support extends HuamiSupport { return this; } + public void requestWatchfaces(final TransactionBuilder builder) { + watchfaceService.requestWatchfaces(builder); + watchfaceService.requestCurrentWatchface(builder); + } + protected Huami2021Support requestShortcuts(final TransactionBuilder builder) { LOG.info("Requesting shortcuts"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation2021.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation2021.java index 7faf353a5..944a38aad 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation2021.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/operations/UpdateFirmwareOperation2021.java @@ -28,14 +28,14 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService; import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.AbstractHuamiFirmwareInfo; +import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.Huami2021Support; import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiFirmwareType; -import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport; import nodomain.freeyourgadget.gadgetbridge.util.ArrayUtils; public class UpdateFirmwareOperation2021 extends UpdateFirmwareOperation2020 { private static final Logger LOG = LoggerFactory.getLogger(UpdateFirmwareOperation2021.class); - public UpdateFirmwareOperation2021(final Uri uri, final HuamiSupport support) { + public UpdateFirmwareOperation2021(final Uri uri, final Huami2021Support support) { super(uri, support); } @@ -61,6 +61,11 @@ public class UpdateFirmwareOperation2021 extends UpdateFirmwareOperation2020 { */ } + @Override + public Huami2021Support getSupport() { + return (Huami2021Support) super.getSupport(); + } + @Override protected void handleNotificationNotif(byte[] value) { super.handleNotificationNotif(value); @@ -75,6 +80,15 @@ public class UpdateFirmwareOperation2021 extends UpdateFirmwareOperation2020 { } catch (final IOException e) { LOG.error("Failed to request display items after app install", e); } + } else if (getFirmwareInfo().getFirmwareType() == HuamiFirmwareType.WATCHFACE) { + // After a watchface is installed, request the watchfaces from the band (new watchface will be at the end) + try { + TransactionBuilder builder = performInitialized("request watchfaces"); + getSupport().requestWatchfaces(builder); + builder.queue(getQueue()); + } catch (final IOException e) { + LOG.error("Failed to request watchfaces after watchface install", e); + } } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/zeppos/services/ZeppOsWatchfaceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/zeppos/services/ZeppOsWatchfaceService.java index fcab0dff4..6b32ca2d0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/zeppos/services/ZeppOsWatchfaceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/huami/zeppos/services/ZeppOsWatchfaceService.java @@ -48,6 +48,41 @@ public class ZeppOsWatchfaceService extends AbstractZeppOsService { public static final byte CMD_CURRENT_GET = 0x09; public static final byte CMD_CURRENT_RET = 0x0a; + public enum Watchface { + // Codes are from GTR 4, not sure if they match on other watches + RED_FANTASY(0x00002D38), + MULTIPLE_DATA(0x00002D10), + RUSH(0x00002D37), + MINIMALIST(0x00002D0E), + SIMPLICITY_DATA(0x00002D08), + VIBRANT(0x00002D09), + BUSINESS_STYLE(0x00002D0D), + EMERALD_MOONLIGHT(0x00002D0A), + ROTATING_EARTH(0x00002D0F), + SUPERPOSITION(0x00002D0C), + ; + + private final int code; + + Watchface(final int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static Watchface fromCode(final int code) { + for (final Watchface watchface : values()) { + if (watchface.getCode() == code) { + return watchface; + } + } + + return null; + } + } + public ZeppOsWatchfaceService(final Huami2021Support support) { super(support); } @@ -104,8 +139,15 @@ public class ZeppOsWatchfaceService extends AbstractZeppOsService { final List watchfaces = new ArrayList<>(); for (int i = 0; i < numWatchfaces; i++) { - final int watchface = buf.getInt(); - watchfaces.add(String.format(Locale.ROOT, "0x%08X", watchface)); + final int watchfaceCode = buf.getInt(); + final Watchface watchface = Watchface.fromCode(watchfaceCode); + if (watchface != null) { + watchfaces.add(watchface.name().toLowerCase(Locale.ROOT)); + } else { + final String watchfaceHex = String.format(Locale.ROOT, "0x%08X", watchfaceCode); + LOG.warn("Unknown watchface code {}", watchfaceHex); + watchfaces.add(watchfaceHex); + } } final GBDeviceEventUpdatePreferences evt = new GBDeviceEventUpdatePreferences() @@ -113,18 +155,26 @@ public class ZeppOsWatchfaceService extends AbstractZeppOsService { getSupport().evaluateGBDeviceEvent(evt); } - public void setWatchface(final String watchface) { - if (watchface == null) { + public void setWatchface(final String watchfacePrefValue) { + if (watchfacePrefValue == null) { LOG.warn("watchface is null"); return; } - final Matcher matcher = Pattern.compile("^0[xX]([0-9a-fA-F]+)$").matcher(watchface); - if (!matcher.find()) { - LOG.warn("Failed to parse watchface '{}' as hex", watchface); - return; + int watchfaceInt; + + try { + final Watchface watchfaceEnum = Watchface.valueOf(watchfacePrefValue.toUpperCase(Locale.ROOT)); + watchfaceInt = watchfaceEnum.getCode(); + } catch (final IllegalArgumentException e) { + // attempt to parse as hex + final Matcher matcher = Pattern.compile("^0[xX]([0-9a-fA-F]+)$").matcher(watchfacePrefValue); + if (!matcher.find()) { + LOG.warn("Failed to parse watchface '{}' as hex", watchfacePrefValue); + return; + } + watchfaceInt = Integer.parseInt(matcher.group(1), 16); } - final int watchfaceInt = Integer.parseInt(matcher.group(1), 16); final ByteBuffer buf = ByteBuffer.allocate(5).order(ByteOrder.LITTLE_ENDIAN); buf.put(CMD_SET); diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 25fe101f2..fa2400948 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -754,6 +754,34 @@ low + + + @string/zepp_os_watchface_red_fantasy + @string/zepp_os_watchface_multiple_data + @string/zepp_os_watchface_rush + @string/zepp_os_watchface_minimalist + @string/zepp_os_watchface_simplicity_data + @string/zepp_os_watchface_vibrant + @string/zepp_os_watchface_business_style + @string/zepp_os_watchface_emerald_moonlight + @string/zepp_os_watchface_rotating_earth + @string/zepp_os_watchface_superposition + + + + + red_fantasy + multiple_data + rush + minimalist + simplicity_data + vibrant + business_style + emerald_moonlight + rotating_earth + superposition + + @string/menuitem_activity @string/menuitem_alarm diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ef82fa9ec..f1d164216 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1362,6 +1362,16 @@ Eject Water Unknown (%s) [UNSUPPORTED] %s + Red Fantasy + Multiple Data + Rush + Minimalist + Simplicity Data + Vibrant + Business Style + Emerald Moonlight + Rotating Earth + superposition Yesterday\'s Activity Minutes: Hours: diff --git a/app/src/main/res/xml/devicesettings_huami2021_watchface.xml b/app/src/main/res/xml/devicesettings_huami2021_watchface.xml index 7f6d312a5..e3da5fbf7 100644 --- a/app/src/main/res/xml/devicesettings_huami2021_watchface.xml +++ b/app/src/main/res/xml/devicesettings_huami2021_watchface.xml @@ -3,8 +3,8 @@