From 26b889e53611ea86d967d039ff3a9bd6458b4bda Mon Sep 17 00:00:00 2001 From: Sebin Suresh Date: Sat, 15 Mar 2025 13:03:22 -0500 Subject: [PATCH 1/7] feat: add support for weather module --- apps/timecal/timecal.app.js | 72 ++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/apps/timecal/timecal.app.js b/apps/timecal/timecal.app.js index c4baef486..fd8c316d3 100644 --- a/apps/timecal/timecal.app.js +++ b/apps/timecal/timecal.app.js @@ -2,7 +2,7 @@ class TimeCalClock{ DATE_FONT_SIZE(){ return 20; } TIME_FONT_SIZE(){ return 40; } - + /** * @param{Date} date optional the date (e.g. for testing) * @param{Settings} settings optional settings to use e.g. for testing @@ -18,7 +18,7 @@ class TimeCalClock{ const defaults = { shwDate:1, //0:none, 1:locale, 2:month, 3:monthshort.year #week - + wdStrt:0, //identical to getDay() 0->Su, 1->Mo, ... //Issue #1154: weekstart So/Mo, -1 for use today tdyNumClr:3, //0:fg, 1:red=#E00, 2:green=#0E0, 3:blue=#00E @@ -39,7 +39,12 @@ class TimeCalClock{ Bangle.loadWidgets(); Bangle.drawWidgets(); - this.centerX = Bangle.appRect.w/2; + // X coord to center date and time text at + this.dtCenterX = Bangle.appRect.w/2; + this.hasWeather = require('weather') && require('weather').get(); + if(this.hasWeather){ + this.dtCenterX =2*Bangle.appRect.w/3; + } this.nrgb = [g.theme.fg, "#E00", "#0E0", "#00E"]; //fg, r ,g , b this.ABR_DAY=[]; @@ -68,11 +73,46 @@ class TimeCalClock{ * Run forest run **/ draw(){ + // DEBUG + // require("weather").get = () => ({ + // "temp": 298.15, // Temperature in Kelvin + // "code": 800, // Weather condition code + // "txt": "few clouds", // Weather condition text + // }); + // require("weather").get = undefined; + + this.hasWeather = require('weather') && require('weather').get(); + const prevCenterX = this.dtCenterX; + if(this.hasWeather){ + this.dtCenterX = 2 * Bangle.appRect.w / 3; + } else { + this.dtCenterX = Bangle.appRect.w / 2; + } this.drawTime(); + if(prevCenterX !== this.dtCenterX) { + this.drawDateAndCal(); + } if (this.TZOffset===undefined || this.TZOffset!==d.getTimezoneOffset()) this.drawDateAndCal(); + + if(this.hasWeather){ + this.drawWeather(); } + } + + drawWeather() { + const weather = require('weather'); + const curr = weather.get(); + const temp = require("locale").temp(curr.temp-273.15).match(/^(\D*\d*)(.*)$/)[0]; + weather.drawIcon(curr, 24, 20, 20); + + g + .setFontAlign(0, -1) + .setFont('6x8', 2) + .setColor(g.theme.fg) + .drawString(temp, Bangle.appRect.x2/6, 40); + } /** * draw given or current time from date @@ -85,10 +125,13 @@ class TimeCalClock{ d=d?d :new Date(); - g.setFontAlign(0, -1).setFont("Vector", this.TIME_FONT_SIZE()).setColor(g.theme.fg) - .clearRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+this.TIME_FONT_SIZE()-7) - .drawString(("0" + require("locale").time(d, 1)).slice(-5), this.centerX, Y, true); - //.drawRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+this.TIME_FONT_SIZE()-7); //DEV-Option + g.setFontAlign(0, -1) + .setFont("Vector", this.TIME_FONT_SIZE()) + .setColor(g.theme.fg) + .clearRect(Bangle.appRect.x, Y - 13, Bangle.appRect.x2,Y+this.TIME_FONT_SIZE()-7) + .drawString(("0" + require("locale").time(d, 1)).slice(-5), this.dtCenterX, Y, true) + // .drawRect(Bangle.appRect.x, Y - 13, Bangle.appRect.x2,Y+this.TIME_FONT_SIZE()-7) //DEV-Option + ; setTimeout(this.draw.bind(this), 60000-(d.getSeconds()*1000)-d.getMilliseconds()); } @@ -108,7 +151,7 @@ class TimeCalClock{ clearTimeout(this.tOutD); this.tOutD=setTimeout(this.drawDateAndCal.bind(this), 86400000-(d.getHours()*24*60*1000)-(d.getMinutes()*60*1000)-d.getSeconds()-d.getMilliseconds()); } - + /** * draws given date as defiend in settings */ @@ -164,7 +207,12 @@ class TimeCalClock{ } } if (render){ - g.setFont("Vector", FONT_SIZE).setColor(g.theme.fg).setFontAlign(0, -1).clearRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+FONT_SIZE-3).drawString(dateStr,this.centerX,Y); + g + .setFont("Vector", FONT_SIZE) + .setColor(g.theme.fg) + .setFontAlign(0, -1) + .clearRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+FONT_SIZE-3) + .drawString(dateStr, this.dtCenterX - 3, Y+1); } //g.drawRect(Bangle.appRect.x, Y, Bangle.appRect.x2, Y+FONT_SIZE-3); //DEV-Option } @@ -181,7 +229,7 @@ class TimeCalClock{ const CELL_W=Bangle.appRect.w/7; //cell width const CELL_H=(CAL_AREA_H-DAY_NAME_FONT_SIZE)/3; //cell heigth const DAY_NUM_FONT_SIZE=Math.min(CELL_H-1,15); //size down, max 15 - + g.setFont("Vector", DAY_NAME_FONT_SIZE).setColor(g.theme.fg).setFontAlign(-1, -1).clearRect(Bangle.appRect.x, CAL_Y, Bangle.appRect.x2, CAL_Y+CAL_AREA_H); //draw grid & Headline @@ -202,9 +250,9 @@ class TimeCalClock{ const y=nextY+i*CELL_H; g.drawLine(Bangle.appRect.x, y, Bangle.appRect.x2, y); } - + g.setFont("Vector", DAY_NUM_FONT_SIZE); - + //write days const tdyDate=d.getDate(); const days=this.settings().wdStrt>=0 ? 7+((7+d.getDay()-this.settings().wdStrt)%7) : 10;//start day (week before=7 days + days in this week realtive to week start) or fixed 7+3 days From e0e9f3ec2897689b7c3f2c02f30c26ee6d5a737f Mon Sep 17 00:00:00 2001 From: Sebin Suresh Date: Sat, 15 Mar 2025 13:07:58 -0500 Subject: [PATCH 2/7] fix: bump version --- apps/timecal/ChangeLog | 1 + apps/timecal/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/timecal/ChangeLog b/apps/timecal/ChangeLog index a42d32632..26a1d0f02 100644 --- a/apps/timecal/ChangeLog +++ b/apps/timecal/ChangeLog @@ -10,3 +10,4 @@ 0.05: bugfix: default settings 0.06: bugfix: Mrk.Color doesn't reflect the color selected, fixes #1706 0.07: Minor code improvements +0.08: Added weather integration diff --git a/apps/timecal/metadata.json b/apps/timecal/metadata.json index c6b174338..a0a295545 100644 --- a/apps/timecal/metadata.json +++ b/apps/timecal/metadata.json @@ -1,7 +1,7 @@ { "id": "timecal", "name": "TimeCal", "shortName":"TimeCal", - "version": "0.07", + "version": "0.08", "description": "TimeCal shows the date/time along with a 3 week calendar", "icon": "icon.png", "type": "clock", From ddb00b2bb971783990a07dbae151e768421b4e1c Mon Sep 17 00:00:00 2001 From: Sebin Suresh Date: Sat, 15 Mar 2025 13:40:04 -0500 Subject: [PATCH 3/7] fix: fix position after testing on real device --- apps/timecal/timecal.app.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/timecal/timecal.app.js b/apps/timecal/timecal.app.js index fd8c316d3..8b1acbabc 100644 --- a/apps/timecal/timecal.app.js +++ b/apps/timecal/timecal.app.js @@ -105,13 +105,15 @@ class TimeCalClock{ const weather = require('weather'); const curr = weather.get(); const temp = require("locale").temp(curr.temp-273.15).match(/^(\D*\d*)(.*)$/)[0]; - weather.drawIcon(curr, 24, 20, 20); + const iconRadius = 20; + const widgetHeight = 24; + weather.drawIcon(curr, Bangle.appRect.x + widgetHeight, Bangle.appRect.y + widgetHeight - 4, iconRadius); g .setFontAlign(0, -1) .setFont('6x8', 2) .setColor(g.theme.fg) - .drawString(temp, Bangle.appRect.x2/6, 40); + .drawString(temp, Bangle.appRect.x2/6, Bangle.appRect.y + widgetHeight + iconRadius); } /** From 14abb10b398a1d142a24ab0ed8036c1b6c0d7ff1 Mon Sep 17 00:00:00 2001 From: Sebin Suresh Date: Sun, 16 Mar 2025 10:08:29 -0500 Subject: [PATCH 4/7] feat: enable hiding or showing weather via settings --- apps/timecal/README.md | 2 ++ apps/timecal/timecal.app.js | 14 ++++++++++---- apps/timecal/timecal.settings.js | 8 +++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/apps/timecal/README.md b/apps/timecal/README.md index 8c5d619ad..c14e27c8e 100644 --- a/apps/timecal/README.md +++ b/apps/timecal/README.md @@ -5,6 +5,7 @@ Shows the * Date * Time (hh:mm) - respecting 12/24 (uses locale string) * 3 weeks calendar view (last,current and next week) +* Weather icon and temperature - if weather app is set up ### The settings menu Calendar View can be customized @@ -13,6 +14,7 @@ Calendar View can be customized * Start wday: Set day of week start. Values: 0=Sunday, 1=Monday,...,6=Saturday or -1=Relative to today [default 0: Sunday] * Su color: Set Sundays color. Values: none [default], red, green or blue * Border: show or none [default] +* Weather: show or none [default] * Submenu Today settings - choose how today is highlighted * < Back: * Color: none, red [default], green or blue diff --git a/apps/timecal/timecal.app.js b/apps/timecal/timecal.app.js index 8b1acbabc..034888103 100644 --- a/apps/timecal/timecal.app.js +++ b/apps/timecal/timecal.app.js @@ -29,7 +29,8 @@ class TimeCalClock{ suClr:1, //0:fg, 1:red=#E00, 2:green=#0E0, 3:blue=#00E //phColor:"#E00", //public holiday - calBrdr:false + calBrdr:false, + showWeather:false }; for (const k in this._settings) if (!defaults.hasOwnProperty(k)) delete this._settings[k]; //remove invalid settings for (const k in defaults) if(!this._settings.hasOwnProperty(k)) this._settings[k] = defaults[k]; //assign missing defaults @@ -41,7 +42,7 @@ class TimeCalClock{ // X coord to center date and time text at this.dtCenterX = Bangle.appRect.w/2; - this.hasWeather = require('weather') && require('weather').get(); + this.hasWeather = this.settings().showWeather && require('weather') && require('weather').get(); if(this.hasWeather){ this.dtCenterX =2*Bangle.appRect.w/3; } @@ -81,7 +82,7 @@ class TimeCalClock{ // }); // require("weather").get = undefined; - this.hasWeather = require('weather') && require('weather').get(); + this.hasWeather = this.settings().showWeather && require('weather') && require('weather').get(); const prevCenterX = this.dtCenterX; if(this.hasWeather){ this.dtCenterX = 2 * Bangle.appRect.w / 3; @@ -107,8 +108,13 @@ class TimeCalClock{ const temp = require("locale").temp(curr.temp-273.15).match(/^(\D*\d*)(.*)$/)[0]; const iconRadius = 20; const widgetHeight = 24; + g.clearRect( + Bangle.appRect.x, + Bangle.appRect.y, + Bangle.appRect.w/3, + Bangle.appRect.y + widgetHeight + iconRadius + ); weather.drawIcon(curr, Bangle.appRect.x + widgetHeight, Bangle.appRect.y + widgetHeight - 4, iconRadius); - g .setFontAlign(0, -1) .setFont('6x8', 2) diff --git a/apps/timecal/timecal.settings.js b/apps/timecal/timecal.settings.js index d7824815a..56f8a12f3 100644 --- a/apps/timecal/timecal.settings.js +++ b/apps/timecal/timecal.settings.js @@ -17,7 +17,8 @@ suClr:1, //0:fg, 1:red=#E00, 2:green=#0E0, 3:blue=#00E //phColor:"#E00", //public holiday - calBrdr:false + calBrdr:false, + showWeather:false }; let validSttngs = require("Storage").readJSON(FILE, 1) || {}; for (const k in validSttngs) if (!DEFAULTS.hasOwnProperty(k)) delete this.validSttngs[k]; //remove invalid settings @@ -64,6 +65,11 @@ format: v => v ? /*LANG*/"show" : /*LANG*/"none", onchange: v => chngdSttngs.calBrdr = v }, + "Weather": { + value: chngdSttngs.showWeather, + format: v => v ? /*LANG*/"show" : /*LANG*/"none", + onchange: v => chngdSttngs.showWeather = v + }, /*LANG*/"Today settings": () => showTodayMenu(), /*LANG*/"< Cancel": () => cancelExitSettings() }); From 4d0d9e1e0c03efd4543caa05d8a6ceff13445703 Mon Sep 17 00:00:00 2001 From: Sebin Suresh Date: Sun, 16 Mar 2025 11:42:26 -0500 Subject: [PATCH 5/7] fix: fix warnings from pipeline run --- apps/timecal/timecal.app.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/apps/timecal/timecal.app.js b/apps/timecal/timecal.app.js index 034888103..ee6ab2161 100644 --- a/apps/timecal/timecal.app.js +++ b/apps/timecal/timecal.app.js @@ -128,11 +128,9 @@ class TimeCalClock{ * schedules itself to update */ drawTime(){ - d=this.date ? this.date : new Date(); + const d=this.date ? this.date : new Date(); const Y=Bangle.appRect.y+this.DATE_FONT_SIZE()+10; - d=d?d :new Date(); - g.setFontAlign(0, -1) .setFont("Vector", this.TIME_FONT_SIZE()) .setColor(g.theme.fg) @@ -149,7 +147,7 @@ class TimeCalClock{ * @param{Date} d provide date or uses today */ drawDateAndCal(){ - d=this.date ? this.date : new Date(); + const d=this.date ? this.date : new Date(); this.TZOffset=d.getTimezoneOffset(); this.drawDate(); @@ -164,7 +162,7 @@ class TimeCalClock{ * draws given date as defiend in settings */ drawDate(){ - d=this.date ? this.date : new Date(); + const d=this.date ? this.date : new Date(); const FONT_SIZE=20; const Y=Bangle.appRect.y; @@ -229,7 +227,7 @@ class TimeCalClock{ * draws calender week view (-1,0,1) for given date */ drawCal(){ - d=this.date ? this.date : new Date(); + const d=this.date ? this.date : new Date(); const DAY_NAME_FONT_SIZE=10; const CAL_Y=Bangle.appRect.y+this.DATE_FONT_SIZE()+10+this.TIME_FONT_SIZE()+3; @@ -254,7 +252,7 @@ class TimeCalClock{ var nextY=CAL_Y+DAY_NAME_FONT_SIZE; - for(i=0; i<3; i++){ + for(let i=0; i<3; i++){ const y=nextY+i*CELL_H; g.drawLine(Bangle.appRect.x, y, Bangle.appRect.x2, y); } @@ -273,11 +271,11 @@ class TimeCalClock{ g.setColor(this.nrgb[this.settings().tdyMrkClr]); //today marker color or fg color switch(this.settings().tdyMrkr){ //0:none, 1:circle, 2:rectangle, 3:filled case 1: - for(m=1; m<=this.settings().tdyMrkPxl&&m Date: Sun, 16 Mar 2025 17:45:23 -0500 Subject: [PATCH 6/7] fix: remove missed 'd' variable initialization --- apps/timecal/timecal.app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/timecal/timecal.app.js b/apps/timecal/timecal.app.js index ee6ab2161..20b99d510 100644 --- a/apps/timecal/timecal.app.js +++ b/apps/timecal/timecal.app.js @@ -82,6 +82,7 @@ class TimeCalClock{ // }); // require("weather").get = undefined; + const d = this.date ? this.date : new Date(); this.hasWeather = this.settings().showWeather && require('weather') && require('weather').get(); const prevCenterX = this.dtCenterX; if(this.hasWeather){ @@ -325,4 +326,4 @@ var _setTime = setTime; var setTime = function(t) { _setTime(t); timeCalClock.draw(true); -}; \ No newline at end of file +}; From 9ed08a15421cc389ab3b30325e7ff9c1c0c622d7 Mon Sep 17 00:00:00 2001 From: Sebin Suresh Date: Sat, 22 Mar 2025 11:19:26 -0500 Subject: [PATCH 7/7] fix: avoid calling weather.get twice in draw loop --- apps/timecal/timecal.app.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/apps/timecal/timecal.app.js b/apps/timecal/timecal.app.js index 20b99d510..ec5f5822f 100644 --- a/apps/timecal/timecal.app.js +++ b/apps/timecal/timecal.app.js @@ -42,8 +42,11 @@ class TimeCalClock{ // X coord to center date and time text at this.dtCenterX = Bangle.appRect.w/2; - this.hasWeather = this.settings().showWeather && require('weather') && require('weather').get(); - if(this.hasWeather){ + this.weather = undefined; + if(this.settings().showWeather && require('weather')){ + this.weather = require('weather').get(); + } + if(this.weather){ this.dtCenterX =2*Bangle.appRect.w/3; } this.nrgb = [g.theme.fg, "#E00", "#0E0", "#00E"]; //fg, r ,g , b @@ -83,9 +86,11 @@ class TimeCalClock{ // require("weather").get = undefined; const d = this.date ? this.date : new Date(); - this.hasWeather = this.settings().showWeather && require('weather') && require('weather').get(); + if (this.settings().showWeather && require('weather')){ + this.weather = require('weather').get(); + } const prevCenterX = this.dtCenterX; - if(this.hasWeather){ + if(this.weather){ this.dtCenterX = 2 * Bangle.appRect.w / 3; } else { this.dtCenterX = Bangle.appRect.w / 2; @@ -98,14 +103,13 @@ class TimeCalClock{ if (this.TZOffset===undefined || this.TZOffset!==d.getTimezoneOffset()) this.drawDateAndCal(); - if(this.hasWeather){ + if(this.weather){ this.drawWeather(); } } drawWeather() { - const weather = require('weather'); - const curr = weather.get(); + const curr = this.weather; const temp = require("locale").temp(curr.temp-273.15).match(/^(\D*\d*)(.*)$/)[0]; const iconRadius = 20; const widgetHeight = 24; @@ -115,7 +119,7 @@ class TimeCalClock{ Bangle.appRect.w/3, Bangle.appRect.y + widgetHeight + iconRadius ); - weather.drawIcon(curr, Bangle.appRect.x + widgetHeight, Bangle.appRect.y + widgetHeight - 4, iconRadius); + (require('weather')).drawIcon(curr, Bangle.appRect.x + widgetHeight, Bangle.appRect.y + widgetHeight - 4, iconRadius); g .setFontAlign(0, -1) .setFont('6x8', 2)