From 2081463a4f4d4f3377d786d91864825efeac72ea Mon Sep 17 00:00:00 2001 From: Arjan Schrijver Date: Sun, 18 Jun 2023 22:11:07 +0200 Subject: [PATCH] Fossil/Skagen Hybrids: Add UV index and chance of rain widgets Note: this needs support from weather apps, for example: https://github.com/TylerWilliamson/QuickWeather/pull/69 --- .../assets/fossil_hr/widgetChanceOfRain.bin | Bin 1258 -> 1254 bytes app/src/main/assets/fossil_hr/widgetUV.bin | Bin 0 -> 1252 bytes .../assets/fossil_hr/widgetUV_preview.png | Bin 0 -> 4774 bytes .../devices/qhybrid/FossilAppWriter.java | 2 +- .../qhybrid/HybridHRWatchfaceFactory.java | 4 +- .../qhybrid/HybridHRWatchfaceWidget.java | 3 +- .../devices/qhybrid/QHybridConstants.java | 2 +- .../fossil_hr/FossilHRWatchAdapter.java | 56 ++++++++++++++++++ app/src/main/res/values/strings.xml | 1 + external/build_fossil_hr_watchface.sh | 1 + external/fossil-hr-watchface | 2 +- 11 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 app/src/main/assets/fossil_hr/widgetUV.bin create mode 100644 app/src/main/assets/fossil_hr/widgetUV_preview.png diff --git a/app/src/main/assets/fossil_hr/widgetChanceOfRain.bin b/app/src/main/assets/fossil_hr/widgetChanceOfRain.bin index 27e039b8be6afdc5b6362de02d97c94a3a79c336..f0197d3977dac4eae65bdfff2eac522e55c30863 100644 GIT binary patch delta 143 zcmaFG`HWN2D<~*Zf&l_HFflMN0+}Gb&_qdphY3K&1)vBAP$C0}MLd`oMPxKs6&NL0 zB$!1+JQz4U7&s-^CD;rlxb!5r4JCLy1bID#_&kL9JwyatH*OGP(NJYjD$h(wPc3oI iNX$!4^-l{*%*@k^*GtaNOUq2x%gjs5SF)6 imz?UK7L=Ho7aZ)W7q6F`pO==Iu9umYmak-0T?+s@02*rm diff --git a/app/src/main/assets/fossil_hr/widgetUV.bin b/app/src/main/assets/fossil_hr/widgetUV.bin new file mode 100644 index 0000000000000000000000000000000000000000..c07b957b071940befb4b645c241dd6a883a18a00 GIT binary patch literal 1252 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 K!YV`JbN&nQ4FEC# literal 0 HcmV?d00001 diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/FossilAppWriter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/FossilAppWriter.java index 086b9c211..5368ac84d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/FossilAppWriter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/FossilAppWriter.java @@ -47,7 +47,7 @@ public class FossilAppWriter { this.mContext = context; if (this.mContext == null) throw new AssertionError("context cannot be null"); this.version = version; - if (!this.version.matches("^[0-9]\\.[0-9]$")) throw new AssertionError("Version must be in x.x format"); + if (!this.version.matches("^[0-9]\\.[0-9]+$")) throw new AssertionError("Version must be in x.x format"); this.code = code; if (this.code.size() == 0) throw new AssertionError("At least one code file InputStream must be supplied"); this.icons = icons; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceFactory.java index cb55791b1..5ec20102a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/HybridHRWatchfaceFactory.java @@ -103,11 +103,12 @@ public class HybridHRWatchfaceFactory { case "widgetCalories": case "widgetActiveMins": case "widgetChanceOfRain": + case "widgetUV": widget.put("type", "comp"); widget.put("name", widgetDesc.getWidgetType()); widget.put("goal_ring", false); widget.put("color", widgetDesc.getColor() == HybridHRWatchfaceWidget.COLOR_WHITE ? "white" : "black"); - if (widgetDesc.getBackground() != "") { + if (!widgetDesc.getBackground().equals("")) { widget.put("bg", widgetDesc.getBackground() + widgetDesc.getColor() + ".rle"); } break; @@ -184,6 +185,7 @@ public class HybridHRWatchfaceFactory { if (includeWidget("widgetCalories") > 0) code.put("widgetCalories", context.getAssets().open("fossil_hr/widgetCalories.bin")); if (includeWidget("widgetActiveMins") > 0) code.put("widgetActiveMins", context.getAssets().open("fossil_hr/widgetActiveMins.bin")); if (includeWidget("widgetChanceOfRain") > 0) code.put("widgetChanceOfRain", context.getAssets().open("fossil_hr/widgetChanceOfRain.bin")); + if (includeWidget("widgetUV") > 0) code.put("widgetUV", context.getAssets().open("fossil_hr/widgetUV.bin")); for (int i=0; i KNOWN_WAPP_VERSIONS = new HashMap() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java index ea0654a5e..db2b32d35 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/adapter/fossil_hr/FossilHRWatchAdapter.java @@ -1502,6 +1502,46 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { } } + public void onSendChanceOfRain(WeatherSpec weatherSpec) { + long ts = System.currentTimeMillis(); + ts /= 1000; + try { + JSONObject rainObject = new JSONObject() + .put("res", new JSONObject() + .put("set", new JSONObject() + .put("widgetChanceOfRain._.config.info", new JSONObject() + .put("alive", ts + 60 * 15) + .put("rain", weatherSpec.precipProbability) + ) + ) + ); + + queueWrite(new JsonPutRequest(rainObject, this)); + } catch (JSONException e) { + LOG.error("JSON exception: ", e); + } + } + + public void onSendUVIndex(WeatherSpec weatherSpec) { + long ts = System.currentTimeMillis(); + ts /= 1000; + try { + JSONObject rainObject = new JSONObject() + .put("res", new JSONObject() + .put("set", new JSONObject() + .put("widgetUV._.config.info", new JSONObject() + .put("alive", ts + 60 * 15) + .put("uv", Math.round(weatherSpec.uvIndex)) + ) + ) + ); + + queueWrite(new JsonPutRequest(rainObject, this)); + } catch (JSONException e) { + LOG.error("JSON exception: ", e); + } + } + @Override public void factoryReset() { queueWrite(new FactoryResetRequest()); @@ -1810,6 +1850,22 @@ public class FossilHRWatchAdapter extends FossilWatchAdapter { } else { LOG.info("no weather data available - ignoring request"); } + } else if (request.has("widgetChanceOfRain._.config.info")) { + LOG.info("Got widgetChanceOfRain request"); + WeatherSpec weatherSpec = Weather.getInstance().getWeatherSpec(); + if (weatherSpec != null) { + onSendChanceOfRain(weatherSpec); + } else { + LOG.info("no weather data available - ignoring request"); + } + } else if (request.has("widgetUV._.config.info")) { + LOG.info("Got widgetUV request"); + WeatherSpec weatherSpec = Weather.getInstance().getWeatherSpec(); + if (weatherSpec != null) { + onSendUVIndex(weatherSpec); + } else { + LOG.info("no weather data available - ignoring request"); + } } else if (request.has("commuteApp._.config.commute_info")) { String action = request.getJSONObject("commuteApp._.config.commute_info") .getString("dest"); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f66525a8a..0058ff584 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1779,6 +1779,7 @@ 2nd time zone Active minutes Chance of rain + UV index Power saving Disable display updates while off wrist Disable hands movement while off wrist diff --git a/external/build_fossil_hr_watchface.sh b/external/build_fossil_hr_watchface.sh index 209469192..28a8acf3d 100755 --- a/external/build_fossil_hr_watchface.sh +++ b/external/build_fossil_hr_watchface.sh @@ -16,6 +16,7 @@ $jerry generate -f '' widget_calories.js -o widgetCalories.bin $jerry generate -f '' widget_2nd_tz.js -o widget2ndTZ.bin $jerry generate -f '' widget_activemins.js -o widgetActiveMins.bin $jerry generate -f '' widget_chanceofrain.js -o widgetChanceOfRain.bin +$jerry generate -f '' widget_uv.js -o widgetUV.bin $jerry generate -f '' widget_custom.js -o widgetCustom.bin popd mv fossil-hr-watchface/*.bin ../app/src/main/assets/fossil_hr/ diff --git a/external/fossil-hr-watchface b/external/fossil-hr-watchface index 1a58411e8..b66f0629e 160000 --- a/external/fossil-hr-watchface +++ b/external/fossil-hr-watchface @@ -1 +1 @@ -Subproject commit 1a58411e8fe32d1a1a80982fdc5775b4529cf8d1 +Subproject commit b66f0629e78e87df8cb7c793f972e3bee57cd44d