From 787696ddf2b905a44c5cb9e3619c6e1d0509d94c Mon Sep 17 00:00:00 2001 From: stweedo Date: Fri, 27 Jun 2025 03:50:03 -0500 Subject: [PATCH 1/3] weather 0.28: Fix UV positioning, hide when 0 --- apps/weather/ChangeLog | 3 +- apps/weather/README.md | 8 ++++-- apps/weather/app.js | 59 ++++++++++++++++++++------------------ apps/weather/metadata.json | 2 +- 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/apps/weather/ChangeLog b/apps/weather/ChangeLog index c51459fe04..f7f86fad73 100644 --- a/apps/weather/ChangeLog +++ b/apps/weather/ChangeLog @@ -23,4 +23,5 @@ 0.24: Redraw clock_info on update and provide color field for condition 0.25: Added monochrome parameter to drawIcon in lib 0.26: Expose update function (for use by iOS integration) -0.27: Add UV index display \ No newline at end of file +0.27: Add UV index display +0.28: Fix UV positioning, hide when 0 \ No newline at end of file diff --git a/apps/weather/README.md b/apps/weather/README.md index a90c02b96b..5a34b39cb3 100644 --- a/apps/weather/README.md +++ b/apps/weather/README.md @@ -7,8 +7,11 @@ It also adds a ClockInfo list to Bangle.js. You can view the full report through the app: ![Screenshot](screenshot.png) + ## iOS Setup -Use the iOS shortcut [here](https://www.icloud.com/shortcuts/dbf7159200d945179e0938c15e64f102). The shortcut uses Apple Weather for weather updates, and sends a notification, which is read by Bangle.js. To push weather every hour, or interval, you will need to create a shortcut automation for every time you want to push the weather. + +Use the iOS shortcut [here](https://www.icloud.com/shortcuts/ae5f3d7d6ed3460c98a3396b267aa1c5). The shortcut uses Apple Weather for weather updates, and sends a notification, which is read by Bangle.js. To push weather every hour, or interval, you will need to create a shortcut automation for every time you want to push the weather. + ## Android Setup 1. Install [Gadgetbridge for Android](https://f-droid.org/packages/nodomain.freeyourgadget.gadgetbridge/) on your phone. @@ -51,8 +54,8 @@ When you first load QuickWeather, it will take you through the setup process. Yo **Note:** at one time, the Weather Notification app also worked with Gadgetbridge. However, many users are reporting it's no longer seeing the OpenWeatherMap API key as valid. The app has not received any updates since August of 2020, and may be unmaintained. - ## Clock Infos + Tap on any clockInfo when focused to directly open the weather app. Adds: * Condition ClockInfo with condition icon @@ -60,6 +63,7 @@ Adds: * Wind speed ClockInfo. * Chance of rain ClockInfo. * Temperature ClockInfo without condition icon. + ## Settings * Expiration timespan can be set after which the local weather data is considered as invalid diff --git a/apps/weather/app.js b/apps/weather/app.js index 4875a3877a..557d3cbc35 100644 --- a/apps/weather/app.js +++ b/apps/weather/app.js @@ -9,54 +9,56 @@ Bangle.loadWidgets(); var layout = new Layout({type:"v", bgCol: g.theme.bg, c: [ {filly: 1}, {type: "h", filly: 0, c: [ - {type: "v", width: g.getWidth()/2, c: [ // Vertical container for icon + UV + {type: "v", width: g.getWidth()/2, c: [ // Vertical container for icon {type: "custom", fillx: 1, height: g.getHeight()/2 - 30, valign: -1, txt: "unknown", id: "icon", - render: l => weather.drawIcon(l, l.x+l.w/2, l.y+l.h/2, l.w/2-10)}, - {type: "custom", fillx: 1, height: 20, id: "uvDisplay", + render: l => weather.drawIcon(l, l.x+l.w/2, l.y+l.h/2, l.w/2-5)}, + ]}, + {type: "v", fillx: 1, c: [ + {type: "h", pad: 2, c: [ + {type: "txt", font: "18%", id: "temp", label: "000"}, + {type: "txt", font: "12%", valign: -1, id: "tempUnit", label: "°C"}, + ]}, + {filly: 1}, + {type: "txt", font: "6x8", pad: 2, halign: 1, label: /*LANG*/"Humidity"}, + {type: "txt", font: "9%", pad: 2, halign: 1, id: "hum", label: "000%"}, + {type: "txt", font: "6x8", pad: [2, 2, 2, 2], halign: -1, label: /*LANG*/"Wind"}, + {type: "h", pad: [0, 2, 2, 2], halign: -1, c: [ + {type: "txt", font: "9%", pad: 2, id: "wind", label: "00"}, + {type: "txt", font: "6x8", pad: 2, valign: -1, id: "windUnit", label: "km/h"}, + ]}, + {type: "custom", fillx: 1, height: 15, id: "uvDisplay", render: l => { - if (!current || current.uv === undefined) return; + if (!current || current.uv === undefined || current.uv === 0) return; const uv = Math.min(parseInt(current.uv), 11); // Cap at 11 // UV color thresholds: [max_value, color] based on WHO standards const colors = [[2,"#0F0"], [5,"#FF0"], [7,"#F80"], [10,"#F00"], [11,"#F0F"]]; const color = colors.find(c => uv <= c[0])[1]; + const blockH = 8, blockW = 3; - // Setup and measure label + // Draw UV title and blocks on same line g.setFont("6x8").setFontAlign(-1, 0); - const label = "UV: "; + const label = "UV"; const labelW = g.stringWidth(label); - // Calculate centered position (4px block + 1px spacing) * blocks - last spacing - const totalW = labelW + uv * 5 - (uv > 0 ? 1 : 0); - const x = l.x + (l.w - totalW) / 2; - const y = l.y + l.h; + const x = l.x + 2; + const y = l.y + l.h / 2; - // Draw label + // Draw title g.setColor(g.theme.fg).drawString(label, x, y); - // Draw UV blocks + // Draw UV blocks after title g.setColor(color); for (let i = 0; i < uv; i++) { - g.fillRect(x + labelW + i * 5, y - 3, x + labelW + i * 5 + 3, y + 3); + const blockX = x + labelW + 4 + i * (blockW + 2); + g.fillRect(blockX, y - blockH/2, blockX + blockW, y + blockW/2); } + + // Reset graphics state to prevent interference + g.reset(); } }, ]}, - {type: "v", fillx: 1, c: [ - {type: "h", pad: 2, c: [ - {type: "txt", font: "18%", id: "temp", label: "000"}, - {type: "txt", font: "12%", valign: -1, id: "tempUnit", label: "°C"}, - ]}, - {filly: 1}, - {type: "txt", font: "6x8", pad: 2, halign: 1, label: /*LANG*/"Humidity"}, - {type: "txt", font: "9%", pad: 2, halign: 1, id: "hum", label: "000%"}, - {filly: 1}, - {type: "txt", font: "6x8", pad: 2, halign: -1, label: /*LANG*/"Wind"}, - {type: "h", halign: -1, c: [ - {type: "txt", font: "9%", pad: 2, id: "wind", label: "00"}, - {type: "txt", font: "6x8", pad: 2, valign: -1, id: "windUnit", label: "km/h"}, - ]}, - ]}, ]}, {filly: 1}, {type: "txt", font: "9%", wrap: true, height: g.getHeight()*0.18, fillx: 1, id: "cond", label: /*LANG*/"Weather condition"}, @@ -91,6 +93,7 @@ function draw() { layout.loc.label = current.loc; layout.updateTime.label = `${formatDuration(Date.now() - current.time)} ago`; // How to autotranslate this and similar? layout.update(); + layout.forgetLazyState(); layout.render(); } diff --git a/apps/weather/metadata.json b/apps/weather/metadata.json index ccefac8c03..699cdd6274 100644 --- a/apps/weather/metadata.json +++ b/apps/weather/metadata.json @@ -1,7 +1,7 @@ { "id": "weather", "name": "Weather", - "version": "0.27", + "version": "0.28", "description": "Show Gadgetbridge/iOS weather report", "icon": "icon.png", "screenshots": [{"url":"screenshot.png"}], From e7d64baee0f1bf5d429a077a5622dd04beeaabea Mon Sep 17 00:00:00 2001 From: stweedo <108593831+stweedo@users.noreply.github.com> Date: Fri, 27 Jun 2025 08:27:24 -0500 Subject: [PATCH 2/3] Update README.md with new iOS shortcut link MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds “mostly cloudy” as a filter before “cloud” or “part” to catch that specific phrase and use weather code 803 to drawBrokenClouds which was previously unused. --- apps/weather/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/weather/README.md b/apps/weather/README.md index 5a34b39cb3..7e74d9f9d8 100644 --- a/apps/weather/README.md +++ b/apps/weather/README.md @@ -10,7 +10,7 @@ You can view the full report through the app: ## iOS Setup -Use the iOS shortcut [here](https://www.icloud.com/shortcuts/ae5f3d7d6ed3460c98a3396b267aa1c5). The shortcut uses Apple Weather for weather updates, and sends a notification, which is read by Bangle.js. To push weather every hour, or interval, you will need to create a shortcut automation for every time you want to push the weather. +Use the iOS shortcut [here](https://www.icloud.com/shortcuts/738171beab944a5caacb4396f473811e). The shortcut uses Apple Weather for weather updates, and sends a notification, which is read by Bangle.js. To push weather every hour, or interval, you will need to create a shortcut automation for every time you want to push the weather. ## Android Setup From 381efdb087bccb075cb47de6831f6cc2e1cc84b8 Mon Sep 17 00:00:00 2001 From: stweedo <108593831+stweedo@users.noreply.github.com> Date: Sat, 28 Jun 2025 17:21:03 -0500 Subject: [PATCH 3/3] =?UTF-8?q?Update=20iOS=20shortcut=20to=20include=20fe?= =?UTF-8?q?els=20like=20and=20=E2=80=9Cmostly=20sunny=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/weather/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/weather/README.md b/apps/weather/README.md index 7e74d9f9d8..f4b6615fc0 100644 --- a/apps/weather/README.md +++ b/apps/weather/README.md @@ -10,7 +10,7 @@ You can view the full report through the app: ## iOS Setup -Use the iOS shortcut [here](https://www.icloud.com/shortcuts/738171beab944a5caacb4396f473811e). The shortcut uses Apple Weather for weather updates, and sends a notification, which is read by Bangle.js. To push weather every hour, or interval, you will need to create a shortcut automation for every time you want to push the weather. +Use the iOS shortcut [here](https://www.icloud.com/shortcuts/73be0ce1076446f3bdc45a5707de5c4d). The shortcut uses Apple Weather for weather updates, and sends a notification, which is read by Bangle.js. To push weather every hour, or interval, you will need to create a shortcut automation for every time you want to push the weather. ## Android Setup