From 95c1cf770daeba6ba9a33b12003609f1d9361844 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 14 Jun 2026 12:30:53 +0200 Subject: [PATCH] Pebble: Support TrekV3Reworked watchface natively (for @izzy) --- .../AppMessageHandlerTrekV3Reworked.java | 96 +++++++++++++++++++ .../devices/pebble/PebbleProtocol.java | 2 + 2 files changed, 98 insertions(+) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTrekV3Reworked.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTrekV3Reworked.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTrekV3Reworked.java new file mode 100644 index 0000000000..241a22c72b --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/AppMessageHandlerTrekV3Reworked.java @@ -0,0 +1,96 @@ +/* Copyright (C)2026 Andreas Shimokawa + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.pebble; + +import android.util.Pair; +import android.widget.Toast; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes; +import nodomain.freeyourgadget.gadgetbridge.model.WeatherSpec; +import nodomain.freeyourgadget.gadgetbridge.model.weather.Weather; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +class AppMessageHandlerTrekV3Reworked extends AppMessageHandler { + private static final int ID_IMAGE_ERROR = 14; + private int MESSAGE_KEY_WEATHER_TEMPERATURE; + private int MESSAGE_KEY_WEATHER_ICON; + private int MESSAGE_KEY_WEATHER_TEMP_RANGE; + + AppMessageHandlerTrekV3Reworked(UUID uuid, PebbleProtocol pebbleProtocol) { + super(uuid, pebbleProtocol); + + try { + JSONObject appKeys = getAppKeys(); + MESSAGE_KEY_WEATHER_TEMPERATURE = appKeys.getInt("temperature"); + MESSAGE_KEY_WEATHER_ICON = appKeys.getInt("icon"); + MESSAGE_KEY_WEATHER_TEMP_RANGE = appKeys.getInt("temp_range"); + } catch (JSONException e) { + GB.toast("There was an error accessing the TrekV3Reworked watchface configuration.", Toast.LENGTH_LONG, GB.ERROR, e); + } catch (IOException ignore) { + } + } + + private int getIconForConditionCode(int code) { + // from javascript + if (code >= 200 && code <= 232) return 0; + if (code >= 300 && code <= 531) return 11; + if (code >= 600 && code <= 622) return 13; + if (code >= 700 && code <= 781) return 20; + if (code >= 801 && code <= 804) return 26; + if (code == 800) return 36; + return ID_IMAGE_ERROR; + } + + private byte[] encodeTrekV3ReworkedWeather(WeatherSpec weatherSpec) { + + if (weatherSpec == null) { + return null; + } + + + ArrayList> pairs = new ArrayList<>(); + pairs.add(new Pair<>(MESSAGE_KEY_WEATHER_ICON, getIconForConditionCode(weatherSpec.getCurrentConditionCode()))); + pairs.add(new Pair<>(MESSAGE_KEY_WEATHER_TEMPERATURE, (weatherSpec.getCurrentTemp() - 273) + "°")); + pairs.add(new Pair<>(MESSAGE_KEY_WEATHER_TEMP_RANGE, (weatherSpec.getTodayMinTemp() - 273) + "° " + (weatherSpec.getTodayMaxTemp() - 273) + "°")); + + return mPebbleProtocol.encodeApplicationMessagePush(PebbleProtocol.ENDPOINT_APPLICATIONMESSAGE, mUUID, pairs, null); + } + + @Override + public GBDeviceEvent[] onAppStart() { + WeatherSpec weatherSpec = Weather.getWeatherSpec(); + if (weatherSpec == null) { + return new GBDeviceEvent[]{null}; + } + GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes(); + sendBytes.encodedBytes = encodeTrekV3ReworkedWeather(weatherSpec); + return new GBDeviceEvent[]{sendBytes}; + } + + @Override + public byte[] encodeUpdateWeather(WeatherSpec weatherSpec) { + return encodeTrekV3ReworkedWeather(weatherSpec); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index d1d3f8b44a..6fea0ea279 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -417,6 +417,7 @@ public class PebbleProtocol extends GBDeviceProtocol { private static final UUID UUID_MARIOTIME = UUID.fromString("43caa750-2896-4f46-94dc-1adbd4bc1ff3"); private static final UUID UUID_HELTHIFY = UUID.fromString("7ee97b2c-95e8-4720-b94e-70fccd905d98"); private static final UUID UUID_TREKVOLLE = UUID.fromString("2da02267-7a19-4e49-9ed1-439d25db14e4"); + private static final UUID UUID_TREKV3_REWORKED = UUID.fromString("fb9b2ec0-586b-4d3a-8a4d-89c24e80d971"); private static final UUID UUID_SQUARE = UUID.fromString("cb332373-4ee5-4c5c-8912-4f62af2d756c"); private static final UUID UUID_ZALEWSZCZAK_CROWEX = UUID.fromString("a88b3151-2426-43c6-b1d0-9b288b3ec47e"); private static final UUID UUID_ZALEWSZCZAK_FANCY = UUID.fromString("014e17bf-5878-4781-8be1-8ef998cee1ba"); @@ -449,6 +450,7 @@ public class PebbleProtocol extends GBDeviceProtocol { mAppMessageHandlers.put(UUID_MARIOTIME, new AppMessageHandlerMarioTime(UUID_MARIOTIME, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_HELTHIFY, new AppMessageHandlerHealthify(UUID_HELTHIFY, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_TREKVOLLE, new AppMessageHandlerTrekVolle(UUID_TREKVOLLE, PebbleProtocol.this)); + mAppMessageHandlers.put(UUID_TREKV3_REWORKED, new AppMessageHandlerTrekV3Reworked(UUID_TREKV3_REWORKED, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_SQUARE, new AppMessageHandlerSquare(UUID_SQUARE, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_ZALEWSZCZAK_CROWEX, new AppMessageHandlerZalewszczak(UUID_ZALEWSZCZAK_CROWEX, PebbleProtocol.this)); mAppMessageHandlers.put(UUID_ZALEWSZCZAK_FANCY, new AppMessageHandlerZalewszczak(UUID_ZALEWSZCZAK_FANCY, PebbleProtocol.this));