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_HFflMNGB7ZJ_(BsU{T(JSFfd$TWMJT6VqnN%Vqg&QU}6-J z(O^|zlwgry77_7a;P7DJlwg-&GnC-cli)U#;PDXT^$_Co5a#y~5pdnOL5xL1l|iXI oGbKH>#5p4|FFDmeEhsTFPcL3CIX^EgGhHt;FD+lms=Af|05BgLkN^Mx delta 147 zcmaFH`HEB0D<~*Zf&l_{FflMNGB7ZJ_`(w<{XJ$dFfiO;WMB|rVqhp>Vqg&QU}6-J z(O^|zlwgry77_7a;P7DJlwg-&GcuIm(v#pel;H6YN8oY6Z7>kM$ ngHm!vVqS8pe_BvtW?pcxt6scba(-S~X1ZQxURu7ARdp=@Ish7L 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 zcmYk4&1>UE7{(usWl8>y93`u4lG;wYSfRw=h1jKp-gaYpT-b%4w1YI3r`RJ`8t0>> zkei{GF6=+ho3H6F7oG^02%d3B*n)T6UW8`eS@G>5Q6s%V3 zz5=YOz_JEJb>O}MtTq7C22Pu~=V}w^IysMGSGZOra7IP_bIr8=a*bixHii{V_o{B`<|T|wznF2Y+d$OGXYJ|> z4Sy4O+OTj4{pebM=%a*%2-%nm7NP_Zhs+mr#sFBDQNhP7l?EiAu_Ud4PWc)0vmFcs zu^9762N&a*U~yK=&z0txKc<0<6Ew0@pQnDXND?L_Hu4I)nDgW^(=sukBAl`WO+-xk z37b(axQP6e1*wiOq2~?~HcnVN@y{8R6PEbOwTx88^Bky(#f5*KaLN2>9957?n#c#% zE%4Nr6ZKM^V5m;)q7Y-*mqfvyEr)KVZ`L?H$A_XH_=mpAAI@4kN6k4CmT`# literal 0 HcmV?d00001 diff --git a/app/src/main/assets/fossil_hr/widgetUV_preview.png b/app/src/main/assets/fossil_hr/widgetUV_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..38b25d85587dfc31499e7ac1d362ba784d0f709f GIT binary patch literal 4774 zcmeHKdsGu=79Xe*Kmltlx-4i6U{OpmnS?y13D1C}7)TKXwH}#dCNRQGhGc+&Rt3Zr zX{!ioTaOfc;1du*5uc!_xC%aCZMW11#o8WJ6n3qwkCr_X5b$(Q_wYymvfUyoE+U80RV8)gsYa>NsFuYOd)A*98NXcE>D1ZPa^P%6iM%<# z`h!m*m1OJq^)rrF*1fuTyrZf?+-QXTqTFY>PVgwFLEmj|y;D-uH|fh$A;H1z$K*-( z-I8t>)q|VcVz(ZTw2X6@t9O{J_Sv^17dnvFdZ0)@GxTMOOMlh9FD{i892^(6VSG$! zP}-}G)jcPd`UWU|n6oJ@M^d1Mp?E6QoNO%zH3+d}jKE0RA`}TkZ)`bFqty*Xuo5KT1Z9n4 z2Ph^;(f#Wb?sJXt46TeWJqPx)2LNEc7GT(8E_OH_=};K zQ4FGdDI$jW5)mllBO(LDS0IQ?uaJnu21q}GN<&&`gfw6*6+=)097kaZg!xIOkeDw9 zA&f5(p&(yjfTVm3@rtCu~aCI!UzUQjhIZ#N92f}FOf+Q zzTVGh;A1k#2pScbpI9WbQlSPo%w#4ITE)W&BmomrWP;Ve3JwS9G%6k>0Ebs}$p~#U znF$qdK2D}G!-g1~z!uO5tENaQmw_?}l*<)jF$Btoofctc3vMD=P7x>&ORN^QEo?Cu zNh9nzRq;gDb%vne5Hp6*CUcC*l&s>hDRJ4zA+r{v5fq^jH9})59t1*S7?i>yc?_t4 zK{*V{eL)BYNBEmi+?etIyxHO5DhFB~j$3GxIm5a%Fi{Jzl!3Q_*JRu}N?fjWC}6}e zP=Wl)WHKZoWCDh&c!THfbqM}HjsgUsM!j5N&UAYURu5k7)q5py8W4i!CVm>J4|6VZRV8KH6 z&Ujt1lASfJcBCc)4kIoZ_U^IFK>i001~p;fpN* zAn;@#8>TEE4FCWRtZezu#;vA0jj>)!+bwmOYED28e8Zm&;z2XSxez1FtEduPs+ zvb+$VyzDvc+Vi1P&gVNjM}N4^b>8^*QhHpdsZ;mY<^}A}TT{BPw8lQClsnm%rVd{> zRt0&R)+w_kE#6;sZhCoY>%D*7@{aOX-o0YE77B@naqz8=cCJwFSQ(pKlK-+MWwq(k zzKIR)RrWug=vBRl-rieLSDcvA9Hhz6xCGl@S?uztYEYrHn!uiO1gA(>tivfp`bF8E&8=es={YG>X5&(hXq zoZ1(icZFRaEmOF9br(IA^>_$c^4dHeTr7E45VbD*T(5wrP3m*Tr3ZHW%a{*E>wf zaxdUi+OE!8-VlH8`HZZ|J+}LR=W}mO_prSziM6?UOx_oK`|zP^I_fxwv454fYlRKt z>`q$l7~>UoY3=Dh8?E@xH5R&<)zr{ex1!gta>c~=cihbO;4XHUriobIR=uY`wzYis zy~5gv%Nn;$Ps3ZoG*eaO@Lw|;Q#RkWxK*rKGT{;M_-Q(SYB^tnB=CeyeO@ zzf@O1E3RI-bK;vtcG5Qep89d0!DU;r37bmbi9QhPm_T{H6IIvJJcRa_9M1(eRK7R9 R5wYL@n$SpfWpI4Xe*y6g05Sjo 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