From 47af3b482a4b7b4233b92c8d007967deb298e1b3 Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Sat, 13 Apr 2024 10:31:38 +0200 Subject: [PATCH 01/16] bthrm - Streamline the code a bit --- apps/bthrm/ChangeLog | 1 + apps/bthrm/lib.js | 73 ++++++++++++++++++++++---------------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/apps/bthrm/ChangeLog b/apps/bthrm/ChangeLog index 85a7ca0b6..aea80e531 100644 --- a/apps/bthrm/ChangeLog +++ b/apps/bthrm/ChangeLog @@ -42,3 +42,4 @@ Add debug option for disabling active scanning 0.17: New GUI based on layout library 0.18: Minor code improvements +0.19: Fix setHRMPower method not returning new state diff --git a/apps/bthrm/lib.js b/apps/bthrm/lib.js index 18af4f3ae..a49329818 100644 --- a/apps/bthrm/lib.js +++ b/apps/bthrm/lib.js @@ -318,12 +318,13 @@ exports.enable = () => { log("Starting notifications", newCharacteristic); var startPromise = newCharacteristic.startNotifications().then(()=>log("Notifications started", newCharacteristic)); - log("Add " + settings.gracePeriodNotification + "ms grace period after starting notifications"); - startPromise = startPromise.then(()=>{ - log("Wait after connect"); - return waitingPromise(settings.gracePeriodNotification); - }); - + if (settings.gracePeriodNotification){ + log("Add " + settings.gracePeriodNotification + "ms grace period after starting notifications"); + startPromise = startPromise.then(()=>{ + log("Wait after connect"); + return waitingPromise(settings.gracePeriodNotification); + }); + } return startPromise; }); } @@ -397,6 +398,10 @@ exports.enable = () => { if (settings.gracePeriodRequest){ log("Add " + settings.gracePeriodRequest + "ms grace period after request"); + promise = promise.then(()=>{ + log("Wait after request"); + return waitingPromise(settings.gracePeriodRequest); + }); } promise = promise.then((d)=>{ @@ -404,33 +409,22 @@ exports.enable = () => { d.on('gattserverdisconnected', onDisconnect); device = d; }); - - promise = promise.then(()=>{ - log("Wait after request"); - return waitingPromise(settings.gracePeriodRequest); - }); } else { promise = Promise.resolve(); log("Reuse device", device); } promise = promise.then(()=>{ - if (gatt){ - log("Reuse GATT", gatt); - } else { - log("GATT is new", gatt); - characteristics = []; - var cachedId = getCache().id; - if (device.id !== cachedId){ - log("Device ID changed from " + cachedId + " to " + device.id + ", clearing cache"); - clearCache(); - } + gatt = device.gatt; + + let cache = getCache(); + if (device.id !== cache.id){ + log("Device ID changed from " + cache.id + " to " + device.id + ", clearing cache"); + clearCache(); var newCache = getCache(); newCache.id = device.id; writeCache(newCache); - gatt = device.gatt; } - return Promise.resolve(gatt); }); @@ -440,11 +434,13 @@ exports.enable = () => { var connectPromise = gatt.connect(connectSettings).then(function() { log("Connected."); }); - log("Add " + settings.gracePeriodConnect + "ms grace period after connecting"); - connectPromise = connectPromise.then(()=>{ - log("Wait after connect"); - return waitingPromise(settings.gracePeriodConnect); - }); + if (settings.gracePeriodConnect){ + log("Add " + settings.gracePeriodConnect + "ms grace period after connecting"); + connectPromise = connectPromise.then(()=>{ + log("Wait after connect"); + return waitingPromise(settings.gracePeriodConnect); + }); + } return connectPromise; } else { return Promise.resolve(); @@ -460,20 +456,20 @@ exports.enable = () => { } else { log("Start bonding"); return gatt.startBonding() - .then(() => log("Security status" + gatt.getSecurityStatus())); + .then(() => log("Security status after bonding" + gatt.getSecurityStatus())); } }); } promise = promise.then(()=>{ - if (!characteristics || characteristics.length === 0){ + if (!characteristics || characteristics.length == 0){ characteristics = characteristicsFromCache(device); } }); promise = promise.then(()=>{ var characteristicsPromise = Promise.resolve(); - if (characteristics.length === 0){ + if (characteristics.length == 0){ characteristicsPromise = characteristicsPromise.then(()=>{ log("Getting services"); return gatt.getPrimaryServices(); @@ -487,11 +483,13 @@ exports.enable = () => { log("Supporting service", service.uuid); result = attachServicePromise(result, service); } - log("Add " + settings.gracePeriodService + "ms grace period after services"); - result = result.then(()=>{ - log("Wait after services"); - return waitingPromise(settings.gracePeriodService); - }); + if (settings.gracePeriodService){ + log("Add " + settings.gracePeriodService + "ms grace period after services"); + result = result.then(()=>{ + log("Wait after services"); + return waitingPromise(settings.gracePeriodService); + }); + } return result; }); } else { @@ -598,9 +596,10 @@ exports.enable = () => { Bangle.setBTHRMPower(0); if (!isOn) stopFallback(); } + return Bangle.isBTHRMOn() || Bangle.isHRMOn(); } if ((settings.enabled && !settings.replace) || !settings.enabled){ - Bangle.origSetHRMPower(isOn, app); + return Bangle.origSetHRMPower(isOn, app); } }; } From 4e696ee36efeabc01b59a8e3c170596ad8308989 Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Wed, 10 Apr 2024 19:02:06 +0200 Subject: [PATCH 02/16] bthrm - Move caching of characteristics out of the lib into the settings app --- apps/bthrm/default.json | 3 +- apps/bthrm/lib.js | 128 +++----------------------- apps/bthrm/settings.js | 197 ++++++++++++++++++++++++++++++++++------ 3 files changed, 186 insertions(+), 142 deletions(-) diff --git a/apps/bthrm/default.json b/apps/bthrm/default.json index 79605b412..e1464a9d4 100644 --- a/apps/bthrm/default.json +++ b/apps/bthrm/default.json @@ -15,8 +15,7 @@ "custom_fallbackTimeout": 10, "gracePeriodNotification": 0, "gracePeriodConnect": 0, - "gracePeriodService": 0, "gracePeriodRequest": 0, "bonding": false, - "active": true + "active": false } diff --git a/apps/bthrm/lib.js b/apps/bthrm/lib.js index a49329818..f6074a0db 100644 --- a/apps/bthrm/lib.js +++ b/apps/bthrm/lib.js @@ -16,55 +16,20 @@ exports.enable = () => { log("Settings: ", settings); - if (settings.enabled){ + if (settings.enabled && settings.cache){ - var clearCache = function() { - return require('Storage').erase("bthrm.cache.json"); - }; - - var getCache = function() { - var cache = require('Storage').readJSON("bthrm.cache.json", true) || {}; - if (settings.btid && settings.btid === cache.id) return cache; - clearCache(); - return {}; - }; + log("Start"); var addNotificationHandler = function(characteristic) { log("Setting notification handler"/*supportedCharacteristics[characteristic.uuid].handler*/); characteristic.on('characteristicvaluechanged', (ev) => supportedCharacteristics[characteristic.uuid].handler(ev.target.value)); }; - var writeCache = function(cache) { - var oldCache = getCache(); - if (oldCache !== cache) { - log("Writing cache"); - require('Storage').writeJSON("bthrm.cache.json", cache); - } else { - log("No changes, don't write cache"); - } - }; - - var characteristicsToCache = function(characteristics) { - log("Cache characteristics"); - var cache = getCache(); - if (!cache.characteristics) cache.characteristics = {}; - for (var c of characteristics){ - //"handle_value":16,"handle_decl":15 - log("Saving handle " + c.handle_value + " for characteristic: ", c); - cache.characteristics[c.uuid] = { - "handle": c.handle_value, - "uuid": c.uuid, - "notify": c.properties.notify, - "read": c.properties.read - }; - } - writeCache(cache); - }; var characteristicsFromCache = function(device) { var service = { device : device }; // fake a BluetoothRemoteGATTService log("Read cached characteristics"); - var cache = getCache(); + var cache = settings.cache; if (!cache.characteristics) return []; var restored = []; for (var c in cache.characteristics){ @@ -84,18 +49,6 @@ exports.enable = () => { return restored; }; - log("Start"); - - var lastReceivedData={ - }; - - var supportedServices = [ - "0x180d", // Heart Rate - "0x180f", // Battery - ]; - - var bpmTimeout; - var supportedCharacteristics = { "0x2a37": { //Heart rate measurement @@ -177,6 +130,7 @@ exports.enable = () => { //Body sensor location handler: function(dv){ if (!lastReceivedData["0x180d"]) lastReceivedData["0x180d"] = {}; + log("Got location", dv); lastReceivedData["0x180d"]["0x2a38"] = parseInt(dv.buffer, 10); } }, @@ -189,6 +143,11 @@ exports.enable = () => { } }; + var lastReceivedData={ + }; + + var bpmTimeout; + var device; var gatt; var characteristics = []; @@ -198,11 +157,6 @@ exports.enable = () => { var maxRetryTime = 60000; var retryTime = initialRetryTime; - var connectSettings = { - minInterval: 7.5, - maxInterval: 1500 - }; - var waitingPromise = function(timeout) { return new Promise(function(resolve){ log("Start waiting for " + timeout); @@ -317,7 +271,7 @@ exports.enable = () => { result = result.then(()=>{ log("Starting notifications", newCharacteristic); var startPromise = newCharacteristic.startNotifications().then(()=>log("Notifications started", newCharacteristic)); - + if (settings.gracePeriodNotification){ log("Add " + settings.gracePeriodNotification + "ms grace period after starting notifications"); startPromise = startPromise.then(()=>{ @@ -395,7 +349,7 @@ exports.enable = () => { onDisconnect(e); return; } - + if (settings.gracePeriodRequest){ log("Add " + settings.gracePeriodRequest + "ms grace period after request"); promise = promise.then(()=>{ @@ -416,22 +370,13 @@ exports.enable = () => { promise = promise.then(()=>{ gatt = device.gatt; - - let cache = getCache(); - if (device.id !== cache.id){ - log("Device ID changed from " + cache.id + " to " + device.id + ", clearing cache"); - clearCache(); - var newCache = getCache(); - newCache.id = device.id; - writeCache(newCache); - } return Promise.resolve(gatt); }); promise = promise.then((gatt)=>{ if (!gatt.connected){ log("Connecting..."); - var connectPromise = gatt.connect(connectSettings).then(function() { + var connectPromise = gatt.connect().then(function() { log("Connected."); }); if (settings.gracePeriodConnect){ @@ -446,56 +391,14 @@ exports.enable = () => { return Promise.resolve(); } }); - - if (settings.bonding){ - promise = promise.then(() => { - log(JSON.stringify(gatt.getSecurityStatus())); - if (gatt.getSecurityStatus()['bonded']) { - log("Already bonded"); - return Promise.resolve(); - } else { - log("Start bonding"); - return gatt.startBonding() - .then(() => log("Security status after bonding" + gatt.getSecurityStatus())); - } - }); - } promise = promise.then(()=>{ if (!characteristics || characteristics.length == 0){ characteristics = characteristicsFromCache(device); } - }); - - promise = promise.then(()=>{ - var characteristicsPromise = Promise.resolve(); - if (characteristics.length == 0){ - characteristicsPromise = characteristicsPromise.then(()=>{ - log("Getting services"); - return gatt.getPrimaryServices(); - }); - - characteristicsPromise = characteristicsPromise.then((services)=>{ - log("Got services", services); - var result = Promise.resolve(); - for (var service of services){ - if (!(supportedServices.includes(service.uuid))) continue; - log("Supporting service", service.uuid); - result = attachServicePromise(result, service); - } - if (settings.gracePeriodService){ - log("Add " + settings.gracePeriodService + "ms grace period after services"); - result = result.then(()=>{ - log("Wait after services"); - return waitingPromise(settings.gracePeriodService); - }); - } - return result; - }); - } else { - for (var characteristic of characteristics){ - characteristicsPromise = attachCharacteristicPromise(characteristicsPromise, characteristic, true); - } + let characteristicsPromise = Promise.resolve(); + for (var characteristic of characteristics){ + characteristicsPromise = attachCharacteristicPromise(characteristicsPromise, characteristic, true); } return characteristicsPromise; @@ -503,7 +406,6 @@ exports.enable = () => { return promise.then(()=>{ log("Connection established, waiting for notifications"); - characteristicsToCache(characteristics); clearRetryTimeout(true); }).catch((e) => { characteristics = []; diff --git a/apps/bthrm/settings.js b/apps/bthrm/settings.js index 459ed29fc..928ce85e7 100644 --- a/apps/bthrm/settings.js +++ b/apps/bthrm/settings.js @@ -1,6 +1,6 @@ (function(back) { function writeSettings(key, value) { - var s = require('Storage').readJSON(FILE, true) || {}; + let s = require('Storage').readJSON(FILE, true) || {}; s[key] = value; require('Storage').writeJSON(FILE, s); readSettings(); @@ -13,10 +13,16 @@ ); } - var FILE="bthrm.json"; - var settings; + let FILE="bthrm.json"; + let settings; readSettings(); + let log = ()=>{}; + if (settings.debuglog) + log = print; + + const bthrm = require("bthrm"); + function applyCustomSettings(){ writeSettings("enabled",true); writeSettings("replace",settings.custom_replace); @@ -26,7 +32,7 @@ } function buildMainMenu(){ - var mainmenu = { + let mainmenu = { '': { 'title': 'Bluetooth HRM' }, '< Back': back, 'Mode': { @@ -63,12 +69,13 @@ }; if (settings.btname || settings.btid){ - var name = "Clear " + (settings.btname || settings.btid); + let name = "Clear " + (settings.btname || settings.btid); mainmenu[name] = function() { E.showPrompt("Clear current device?").then((r)=>{ if (r) { writeSettings("btname",undefined); writeSettings("btid",undefined); + writeSettings("cache", undefined); } E.showMenu(buildMainMenu()); }); @@ -81,7 +88,7 @@ return mainmenu; } - var submenu_debug = { + let submenu_debug = { '' : { title: "Debug"}, '< Back': function() { E.showMenu(buildMainMenu()); }, 'Alert on disconnect': { @@ -111,11 +118,137 @@ 'Grace periods': function() { E.showMenu(submenu_grace); } }; + let supportedServices = [ + "0x180d", // Heart Rate + "0x180f", // Battery + ]; + + let supportedCharacteristics = [ + "0x2a37", // Heart Rate + "0x2a38", // Body sensor location + "0x2a19", // Battery + ]; + + var characteristicsToCache = function(characteristics, deviceId) { + log("Cache characteristics"); + let cache = { + id: deviceId + }; + if (!cache.characteristics) cache.characteristics = {}; + for (var c of characteristics){ + //"handle_value":16,"handle_decl":15 + log("Saving handle " + c.handle_value + " for characteristic: ", c.uuid); + cache.characteristics[c.uuid] = { + "handle": c.handle_value, + "uuid": c.uuid, + "notify": c.properties.notify, + "read": c.properties.read + }; + } + writeSettings("cache", cache); + }; + + let createCharacteristicPromise = function(newCharacteristic) { + log("Create characteristic promise", newCharacteristic.uuid); + return Promise.resolve().then(()=>log("Handled characteristic", newCharacteristic.uuid)); + }; + + let attachCharacteristicPromise = function(promise, characteristic) { + return promise.then(()=>{ + log("Handling characteristic:", characteristic.uuid); + return createCharacteristicPromise(characteristic); + }); + }; + + let characteristics; + + let createCharacteristicsPromise = function(newCharacteristics) { + log("Create characteristics promise ", newCharacteristics.length); + let result = Promise.resolve(); + for (let c of newCharacteristics){ + if (!supportedCharacteristics.includes(c.uuid)) continue; + log("Supporting characteristic", c.uuid); + characteristics.push(c); + + result = attachCharacteristicPromise(result, c); + } + return result.then(()=>log("Handled characteristics")); + }; + + let createServicePromise = function(service) { + log("Create service promise", service.uuid); + let result = Promise.resolve(); + result = result.then(()=>{ + log("Handling service", service.uuid); + return service.getCharacteristics().then((c)=>createCharacteristicsPromise(c)); + }); + return result.then(()=>log("Handled service", service.uuid)); + }; + + let attachServicePromise = function(promise, service) { + return promise.then(()=>createServicePromise(service)); + }; + + function cacheDevice(deviceId){ + let promise; + let filters; + let gatt; + characteristics = []; + filters = [{ id: deviceId }]; + + log("Requesting device with filters", filters); + promise = NRF.requestDevice({ filters: filters, active: settings.active }); + + promise = promise.then((d)=>{ + log("Got device", d); + gatt = d.gatt; + log("Connecting..."); + return gatt.connect().then(function() { + log("Connected."); + }); + }); + + if (settings.bonding){ + promise = promise.then(() => { + log(JSON.stringify(gatt.getSecurityStatus())); + if (gatt.getSecurityStatus().bonded) { + log("Already bonded"); + return Promise.resolve(); + } else { + log("Start bonding"); + return gatt.startBonding() + .then(() => log("Security status after bonding" + gatt.getSecurityStatus())); + } + }); + } + + promise = promise.then(()=>{ + log("Getting services"); + return gatt.getPrimaryServices(); + }); + + promise = promise.then((services)=>{ + log("Got services", services.length); + let result = Promise.resolve(); + for (let service of services){ + if (!(supportedServices.includes(service.uuid))) continue; + log("Supporting service", service.uuid); + result = attachServicePromise(result, service); + } + return result; + }); + + return promise.then(()=>{ + log("Connection established, saving cache"); + characteristicsToCache(characteristics, deviceId); + }); + } + function createMenuFromScan(){ E.showMenu(); E.showMessage("Scanning for 4 seconds"); - var submenu_scan = { + let submenu_scan = { '< Back': function() { E.showMenu(buildMainMenu()); } }; NRF.findDevices(function(devices) { @@ -126,18 +259,38 @@ return; } else { devices.forEach((d) => { - print("Found device", d); - var shown = (d.name || d.id.substr(0, 17)); + log("Found device", d); + let shown = (d.name || d.id.substr(0, 17)); submenu_scan[shown] = function () { E.showPrompt("Set " + shown + "?").then((r) => { if (r) { - writeSettings("btid", d.id); - // Store the name for displaying later. Will connect by ID - if (d.name) { - writeSettings("btname", d.name); - } + E.showMessage("Connecting..."); + let count = 0; + const successHandler = ()=>{ + E.showAlert("Success").then(()=>{ + writeSettings("btid", d.id); + // Store the name for displaying later. Will connect by ID + if (d.name) { + writeSettings("btname", d.name); + } + E.showMenu(buildMainMenu()); + }); + }; + const errorHandler = (e)=>{ + count++; + log("ERROR", e); + if (count <= 10){ + E.showMessage("Error during caching, Retry " + count + "/10", e); + return cacheDevice(d.id).then(successHandler).catch(errorHandler); + } else { + E.showAlert("Error during caching", e).then(()=>{ + E.showMenu(buildMainMenu()); + }); + } + }; + + return cacheDevice(d.id).then(successHandler).catch(errorHandler); } - E.showMenu(buildMainMenu()); }); }; }); @@ -146,7 +299,7 @@ }, { timeout: 4000, active: true, filters: [{services: [ "180d" ]}]}); } - var submenu_custom = { + let submenu_custom = { '' : { title: "Custom mode"}, '< Back': function() { E.showMenu(buildMainMenu()); }, 'Replace HRM': { @@ -183,7 +336,7 @@ }, }; - var submenu_grace = { + let submenu_grace = { '' : { title: "Grace periods"}, '< Back': function() { E.showMenu(submenu_debug); }, 'Request': { @@ -215,16 +368,6 @@ onchange: v => { writeSettings("gracePeriodNotification",v); } - }, - 'Service': { - value: settings.gracePeriodService, - min: 0, - max: 3000, - step: 100, - format: v=>v+"ms", - onchange: v => { - writeSettings("gracePeriodService",v); - } } }; From 81f05e181cdf676b0f03c8d58bb2cc36874caace Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Wed, 10 Apr 2024 20:46:00 +0200 Subject: [PATCH 03/16] bthrm - Update ChangeLog --- apps/bthrm/ChangeLog | 4 +++- apps/bthrm/metadata.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/bthrm/ChangeLog b/apps/bthrm/ChangeLog index aea80e531..9a00f833c 100644 --- a/apps/bthrm/ChangeLog +++ b/apps/bthrm/ChangeLog @@ -42,4 +42,6 @@ Add debug option for disabling active scanning 0.17: New GUI based on layout library 0.18: Minor code improvements -0.19: Fix setHRMPower method not returning new state +0.19: Move caching of characteristics into settings app (needs repairing of the sensor) + Changed default of active scanning to false + Fix setHRMPower method not returning new state diff --git a/apps/bthrm/metadata.json b/apps/bthrm/metadata.json index 343df40a1..56e1beffd 100644 --- a/apps/bthrm/metadata.json +++ b/apps/bthrm/metadata.json @@ -2,7 +2,7 @@ "id": "bthrm", "name": "Bluetooth Heart Rate Monitor", "shortName": "BT HRM", - "version": "0.18", + "version": "0.19", "description": "Overrides Bangle.js's build in heart rate monitor with an external Bluetooth one.", "icon": "app.png", "screenshots": [{"url":"screen.png"}], From a98513d2ff9dc3a39c0099f938f1030bf68c8ef7 Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Wed, 10 Apr 2024 21:13:30 +0200 Subject: [PATCH 04/16] bthrm - Use let instead of var --- apps/bthrm/lib.js | 129 +++++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 64 deletions(-) diff --git a/apps/bthrm/lib.js b/apps/bthrm/lib.js index f6074a0db..7f60d2624 100644 --- a/apps/bthrm/lib.js +++ b/apps/bthrm/lib.js @@ -1,14 +1,14 @@ exports.enable = () => { - var settings = Object.assign( + let settings = Object.assign( require('Storage').readJSON("bthrm.default.json", true) || {}, require('Storage').readJSON("bthrm.json", true) || {} ); - var log = function(text, param){ + let log = function(text, param){ if (global.showStatusInfo) global.showStatusInfo(text); if (settings.debuglog){ - var logline = new Date().toISOString() + " - " + text; + let logline = new Date().toISOString() + " - " + text; if (param) logline += ": " + JSON.stringify(param); print(logline); } @@ -20,21 +20,21 @@ exports.enable = () => { log("Start"); - var addNotificationHandler = function(characteristic) { + let addNotificationHandler = function(characteristic) { log("Setting notification handler"/*supportedCharacteristics[characteristic.uuid].handler*/); characteristic.on('characteristicvaluechanged', (ev) => supportedCharacteristics[characteristic.uuid].handler(ev.target.value)); }; - var characteristicsFromCache = function(device) { - var service = { device : device }; // fake a BluetoothRemoteGATTService + let characteristicsFromCache = function(device) { + let service = { device : device }; // fake a BluetoothRemoteGATTService log("Read cached characteristics"); - var cache = settings.cache; + let cache = settings.cache; if (!cache.characteristics) return []; - var restored = []; - for (var c in cache.characteristics){ - var cached = cache.characteristics[c]; - var r = new BluetoothRemoteGATTCharacteristic(); + let restored = []; + for (let c in cache.characteristics){ + let cached = cache.characteristics[c]; + let r = new BluetoothRemoteGATTCharacteristic(); log("Restoring characteristic ", cached); r.handle_value = cached.handle; r.uuid = cached.uuid; @@ -49,14 +49,14 @@ exports.enable = () => { return restored; }; - var supportedCharacteristics = { + let supportedCharacteristics = { "0x2a37": { //Heart rate measurement active: false, handler: function (dv){ - var flags = dv.getUint8(0); + let flags = dv.getUint8(0); - var bpm = (flags & 1) ? (dv.getUint16(1) / 100 /* ? */ ) : dv.getUint8(1); // 8 or 16 bit + let bpm = (flags & 1) ? (dv.getUint16(1) / 100 /* ? */ ) : dv.getUint8(1); // 8 or 16 bit supportedCharacteristics["0x2a37"].active = bpm > 0; log("BTHRM BPM " + supportedCharacteristics["0x2a37"].active); switchFallback(); @@ -67,42 +67,42 @@ exports.enable = () => { startFallback(); }, 3000); - var sensorContact; + let sensorContact; if (flags & 2){ sensorContact = !!(flags & 4); } - var idx = 2 + (flags&1); + let idx = 2 + (flags&1); - var energyExpended; + let energyExpended; if (flags & 8){ energyExpended = dv.getUint16(idx,1); idx += 2; } - var interval; + let interval; if (flags & 16) { interval = []; - var maxIntervalBytes = (dv.byteLength - idx); + let maxIntervalBytes = (dv.byteLength - idx); log("Found " + (maxIntervalBytes / 2) + " rr data fields"); - for(var i = 0 ; i < maxIntervalBytes / 2; i++){ + for(let i = 0 ; i < maxIntervalBytes / 2; i++){ interval[i] = dv.getUint16(idx,1); // in milliseconds idx += 2; } } - var location; + let location; if (lastReceivedData && lastReceivedData["0x180d"] && lastReceivedData["0x180d"]["0x2a38"]){ location = lastReceivedData["0x180d"]["0x2a38"]; } - var battery; + let battery; if (lastReceivedData && lastReceivedData["0x180f"] && lastReceivedData["0x180f"]["0x2a19"]){ battery = lastReceivedData["0x180f"]["0x2a19"]; } if (settings.replace && bpm > 0){ - var repEvent = { + let repEvent = { bpm: bpm, confidence: (sensorContact || sensorContact === undefined)? 100 : 0, src: "bthrm" @@ -112,7 +112,7 @@ exports.enable = () => { Bangle.emit("HRM_R", repEvent); } - var newEvent = { + let newEvent = { bpm: bpm }; @@ -138,26 +138,27 @@ exports.enable = () => { //Battery handler: function (dv){ if (!lastReceivedData["0x180f"]) lastReceivedData["0x180f"] = {}; + log("Got battery", dv); lastReceivedData["0x180f"]["0x2a19"] = dv.getUint8(0); } } }; - var lastReceivedData={ + let lastReceivedData={ }; - var bpmTimeout; + let bpmTimeout; - var device; - var gatt; - var characteristics = []; - var blockInit = false; - var currentRetryTimeout; - var initialRetryTime = 40; - var maxRetryTime = 60000; - var retryTime = initialRetryTime; + let device; + let gatt; + let characteristics = []; + let blockInit = false; + let currentRetryTimeout; + let initialRetryTime = 40; + let maxRetryTime = 60000; + let retryTime = initialRetryTime; - var waitingPromise = function(timeout) { + let waitingPromise = function(timeout) { return new Promise(function(resolve){ log("Start waiting for " + timeout); setTimeout(()=>{ @@ -194,7 +195,7 @@ exports.enable = () => { }; } - var clearRetryTimeout = function(resetTime) { + let clearRetryTimeout = function(resetTime) { if (currentRetryTimeout){ log("Clearing timeout " + currentRetryTimeout); clearTimeout(currentRetryTimeout); @@ -206,12 +207,12 @@ exports.enable = () => { } }; - var retry = function() { + let retry = function() { log("Retry"); if (!currentRetryTimeout && !powerdownRequested){ - var clampedTime = retryTime < 100 ? 100 : retryTime; + let clampedTime = retryTime < 100 ? 100 : retryTime; log("Set timeout for retry as " + clampedTime); clearRetryTimeout(); @@ -230,13 +231,13 @@ exports.enable = () => { } }; - var buzzing = false; - var onDisconnect = function(reason) { + let buzzing = false; + let onDisconnect = function(reason) { log("Disconnect: " + reason); log("GATT", gatt); log("Characteristics", characteristics); - var retryTimeResetNeeded = true; + let retryTimeResetNeeded = true; retryTimeResetNeeded &= reason != "Connection Timeout"; retryTimeResetNeeded &= reason != "No device found matching filters"; clearRetryTimeout(retryTimeResetNeeded); @@ -252,9 +253,9 @@ exports.enable = () => { } }; - var createCharacteristicPromise = function(newCharacteristic) { + let createCharacteristicPromise = function(newCharacteristic) { log("Create characteristic promise", newCharacteristic); - var result = Promise.resolve(); + let result = Promise.resolve(); // For values that can be read, go ahead and read them, even if we might be notified in the future // Allows for getting initial state of infrequently updating characteristics, like battery if (newCharacteristic.readValue){ @@ -270,7 +271,7 @@ exports.enable = () => { if (newCharacteristic.properties.notify){ result = result.then(()=>{ log("Starting notifications", newCharacteristic); - var startPromise = newCharacteristic.startNotifications().then(()=>log("Notifications started", newCharacteristic)); + let startPromise = newCharacteristic.startNotifications().then(()=>log("Notifications started", newCharacteristic)); if (settings.gracePeriodNotification){ log("Add " + settings.gracePeriodNotification + "ms grace period after starting notifications"); @@ -285,17 +286,17 @@ exports.enable = () => { return result.then(()=>log("Handled characteristic", newCharacteristic)); }; - var attachCharacteristicPromise = function(promise, characteristic) { + let attachCharacteristicPromise = function(promise, characteristic) { return promise.then(()=>{ log("Handling characteristic:", characteristic); return createCharacteristicPromise(characteristic); }); }; - var createCharacteristicsPromise = function(newCharacteristics) { + let createCharacteristicsPromise = function(newCharacteristics) { log("Create characteristics promis ", newCharacteristics); - var result = Promise.resolve(); - for (var c of newCharacteristics){ + let result = Promise.resolve(); + for (let c of newCharacteristics){ if (!supportedCharacteristics[c.uuid]) continue; log("Supporting characteristic", c); characteristics.push(c); @@ -308,9 +309,9 @@ exports.enable = () => { return result.then(()=>log("Handled characteristics")); }; - var createServicePromise = function(service) { + let createServicePromise = function(service) { log("Create service promise", service); - var result = Promise.resolve(); + let result = Promise.resolve(); result = result.then(()=>{ log("Handling service" + service.uuid); return service.getCharacteristics().then((c)=>createCharacteristicsPromise(c)); @@ -318,11 +319,11 @@ exports.enable = () => { return result.then(()=>log("Handled service" + service.uuid)); }; - var attachServicePromise = function(promise, service) { + let attachServicePromise = function(promise, service) { return promise.then(()=>createServicePromise(service)); }; - var initBt = function () { + let initBt = function () { log("initBt with blockInit: " + blockInit); if (blockInit && !powerdownRequested){ retry(); @@ -331,8 +332,8 @@ exports.enable = () => { blockInit = true; - var promise; - var filters; + let promise; + let filters; if (!device){ if (settings.btid){ @@ -376,7 +377,7 @@ exports.enable = () => { promise = promise.then((gatt)=>{ if (!gatt.connected){ log("Connecting..."); - var connectPromise = gatt.connect().then(function() { + let connectPromise = gatt.connect().then(function() { log("Connected."); }); if (settings.gracePeriodConnect){ @@ -397,7 +398,7 @@ exports.enable = () => { characteristics = characteristicsFromCache(device); } let characteristicsPromise = Promise.resolve(); - for (var characteristic of characteristics){ + for (let characteristic of characteristics){ characteristicsPromise = attachCharacteristicPromise(characteristicsPromise, characteristic, true); } @@ -414,7 +415,7 @@ exports.enable = () => { }); }; - var powerdownRequested = false; + let powerdownRequested = false; Bangle.setBTHRMPower = function(isOn, app) { // Do app power handling @@ -506,10 +507,10 @@ exports.enable = () => { }; } - var fallbackActive = false; - var inSwitch = false; + let fallbackActive = false; + let inSwitch = false; - var stopFallback = function(){ + let stopFallback = function(){ if (fallbackActive){ Bangle.origSetHRMPower(0, "bthrm_fallback"); fallbackActive = false; @@ -517,7 +518,7 @@ exports.enable = () => { } }; - var startFallback = function(){ + let startFallback = function(){ if (!fallbackActive && settings.allowFallback) { fallbackActive = true; Bangle.origSetHRMPower(1, "bthrm_fallback"); @@ -525,7 +526,7 @@ exports.enable = () => { } }; - var switchFallback = function() { + let switchFallback = function() { log("Check falling back to HRM"); if (!inSwitch){ inSwitch = true; @@ -541,8 +542,8 @@ exports.enable = () => { if (settings.replace){ log("Replace HRM event"); if (Bangle._PWR && Bangle._PWR.HRM){ - for (var i = 0; i < Bangle._PWR.HRM.length; i++){ - var app = Bangle._PWR.HRM[i]; + for (let i = 0; i < Bangle._PWR.HRM.length; i++){ + let app = Bangle._PWR.HRM[i]; log("Moving app " + app); Bangle.origSetHRMPower(0, app); Bangle.setBTHRMPower(1, app); From 7e0792409c6677bb8441ff39231dadb9967bca54 Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Wed, 10 Apr 2024 21:39:06 +0200 Subject: [PATCH 05/16] bthrm - Modify dialogs --- apps/bthrm/settings.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/bthrm/settings.js b/apps/bthrm/settings.js index 928ce85e7..5609fe215 100644 --- a/apps/bthrm/settings.js +++ b/apps/bthrm/settings.js @@ -262,12 +262,15 @@ log("Found device", d); let shown = (d.name || d.id.substr(0, 17)); submenu_scan[shown] = function () { - E.showPrompt("Set " + shown + "?").then((r) => { + E.showPrompt("Connect to\n" + shown + "?", {title: "Pairing"}).then((r) => { if (r) { - E.showMessage("Connecting..."); + E.showMessage("Connecting...", {img:require("Storage").read("bthrm.img")}); let count = 0; const successHandler = ()=>{ - E.showAlert("Success").then(()=>{ + E.showPrompt("Success!", { + img:require("Storage").read("bthrm.img"), + buttons: { "OK":true } + }).then(()=>{ writeSettings("btid", d.id); // Store the name for displaying later. Will connect by ID if (d.name) { @@ -280,7 +283,7 @@ count++; log("ERROR", e); if (count <= 10){ - E.showMessage("Error during caching, Retry " + count + "/10", e); + E.showMessage("Error during caching\nRetry " + count + "/10", e); return cacheDevice(d.id).then(successHandler).catch(errorHandler); } else { E.showAlert("Error during caching", e).then(()=>{ From 8363f9aa392f939053fae5da61480f0e7ec6de3a Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Wed, 10 Apr 2024 22:21:05 +0200 Subject: [PATCH 06/16] bthrm - Convert old cache to new settings if found --- apps/bthrm/lib.js | 8 ++++++++ apps/bthrm/settings.js | 8 +++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/bthrm/lib.js b/apps/bthrm/lib.js index 7f60d2624..d4cb7412c 100644 --- a/apps/bthrm/lib.js +++ b/apps/bthrm/lib.js @@ -16,6 +16,14 @@ exports.enable = () => { log("Settings: ", settings); + //this is for compatibility with 0.18 and older + let oldCache = require('Storage').readJSON("bthrm.cache.json", true); + if(oldCache){ + settings.cache = oldCache; + require('Storage').writeJSON("bthrm.json", settings); + require('Storage').erase("bthrm.cache.json"); + } + if (settings.enabled && settings.cache){ log("Start"); diff --git a/apps/bthrm/settings.js b/apps/bthrm/settings.js index 5609fe215..4f52683ff 100644 --- a/apps/bthrm/settings.js +++ b/apps/bthrm/settings.js @@ -129,11 +129,9 @@ "0x2a19", // Battery ]; - var characteristicsToCache = function(characteristics, deviceId) { + var characteristicsToCache = function(characteristics) { log("Cache characteristics"); - let cache = { - id: deviceId - }; + let cache = {}; if (!cache.characteristics) cache.characteristics = {}; for (var c of characteristics){ //"handle_value":16,"handle_decl":15 @@ -240,7 +238,7 @@ return promise.then(()=>{ log("Connection established, saving cache"); - characteristicsToCache(characteristics, deviceId); + characteristicsToCache(characteristics); }); } From 04d00b501871b64f04b1ac2e583a0df7d2842a1c Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Wed, 10 Apr 2024 22:32:27 +0200 Subject: [PATCH 07/16] bthrm - Fix the request period promise loosing the device argument --- apps/bthrm/lib.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/bthrm/lib.js b/apps/bthrm/lib.js index d4cb7412c..07f9688dd 100644 --- a/apps/bthrm/lib.js +++ b/apps/bthrm/lib.js @@ -361,9 +361,9 @@ exports.enable = () => { if (settings.gracePeriodRequest){ log("Add " + settings.gracePeriodRequest + "ms grace period after request"); - promise = promise.then(()=>{ + promise = promise.then((d)=>{ log("Wait after request"); - return waitingPromise(settings.gracePeriodRequest); + return waitingPromise(settings.gracePeriodRequest).then(()=>Promise.resolve(d)); }); } From c635c39dbea779ecdb57679f230b9b85fd5c3370 Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Sat, 13 Apr 2024 10:55:49 +0200 Subject: [PATCH 08/16] bthrm - Update README --- apps/bthrm/ChangeLog | 2 +- apps/bthrm/README.md | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/bthrm/ChangeLog b/apps/bthrm/ChangeLog index 9a00f833c..e53c5175a 100644 --- a/apps/bthrm/ChangeLog +++ b/apps/bthrm/ChangeLog @@ -42,6 +42,6 @@ Add debug option for disabling active scanning 0.17: New GUI based on layout library 0.18: Minor code improvements -0.19: Move caching of characteristics into settings app (needs repairing of the sensor) +0.19: Move caching of characteristics into settings app Changed default of active scanning to false Fix setHRMPower method not returning new state diff --git a/apps/bthrm/README.md b/apps/bthrm/README.md index 6234f3b78..570072dbf 100644 --- a/apps/bthrm/README.md +++ b/apps/bthrm/README.md @@ -21,6 +21,10 @@ Once installed you will have to go into this app's settings while your heart rat **To disable this and return to normal HRM, uninstall the app or change the settings** +The characteristics of your selected sensor are cached in the settings. That means if your sensor changes, e.g. by firmware updates or similar, you will need to re-scan in the settings to update the cache of characteristics. This is done to take some complexity (and time) out of the boot process. + +Scanning in the settings will do 10 retries and then give up on adding the sensor. Usually that works fine, if it does not for you just try multiple times. Currently saved sensor information is only replaced on a successful pairing. There are additional options in the Debug entry of the menu that can help with specific sensor oddities. Bonding and active scanning can help with connecting, but can also prevent some sensors from working. The "Grace Periods" just add some additional time at certain steps in the connection process which can help with stability or reconnect speed of some finicky sensors. Defaults should be fine for most. + ### Modes * Off - Internal HRM is used, no attempt on connecting to BT HRM. @@ -57,3 +61,7 @@ This replaces `Bangle.setHRMPower` with its own implementation. ## Creator Gordon Williams + +## Contributer + +[halemmerich](https://github.com/halemmerich) From 4c81e249eeba0c77c3de37235815d0aa96cea3bc Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Sat, 13 Apr 2024 11:28:30 +0200 Subject: [PATCH 09/16] bthrm - Only buzz for disconnect if there was an actual connection before --- apps/bthrm/ChangeLog | 1 + apps/bthrm/lib.js | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/bthrm/ChangeLog b/apps/bthrm/ChangeLog index e53c5175a..0753534e4 100644 --- a/apps/bthrm/ChangeLog +++ b/apps/bthrm/ChangeLog @@ -45,3 +45,4 @@ 0.19: Move caching of characteristics into settings app Changed default of active scanning to false Fix setHRMPower method not returning new state + Only buzz for disconnect after switching on if there already was an actual connection diff --git a/apps/bthrm/lib.js b/apps/bthrm/lib.js index 07f9688dd..4786a361f 100644 --- a/apps/bthrm/lib.js +++ b/apps/bthrm/lib.js @@ -239,6 +239,7 @@ exports.enable = () => { } }; + let initialDisconnects = true; let buzzing = false; let onDisconnect = function(reason) { log("Disconnect: " + reason); @@ -252,7 +253,7 @@ exports.enable = () => { supportedCharacteristics["0x2a37"].active = false; if (!powerdownRequested) startFallback(); blockInit = false; - if (settings.warnDisconnect && !buzzing){ + if (settings.warnDisconnect && !buzzing && !initialDisconnects){ buzzing = true; Bangle.buzz(500,0.3).then(()=>waitingPromise(4500)).then(()=>{buzzing = false;}); } @@ -415,6 +416,7 @@ exports.enable = () => { return promise.then(()=>{ log("Connection established, waiting for notifications"); + initialDisconnects = false; clearRetryTimeout(true); }).catch((e) => { characteristics = []; @@ -435,6 +437,7 @@ exports.enable = () => { isOn = Bangle._PWR.BTHRM.length; // so now we know if we're really on if (isOn) { + initialDisconnects = true; powerdownRequested = false; switchFallback(); if (!Bangle.isBTHRMConnected()) initBt(); From f1628097947b7bff2837cf8238c3b509ff91115d Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Sat, 13 Apr 2024 19:43:04 +0200 Subject: [PATCH 10/16] bthrm - Fix lint issues caused by obsolete code --- apps/bthrm/lib.js | 14 -------------- apps/bthrm/settings.js | 2 -- 2 files changed, 16 deletions(-) diff --git a/apps/bthrm/lib.js b/apps/bthrm/lib.js index 4786a361f..b00e15d93 100644 --- a/apps/bthrm/lib.js +++ b/apps/bthrm/lib.js @@ -318,20 +318,6 @@ exports.enable = () => { return result.then(()=>log("Handled characteristics")); }; - let createServicePromise = function(service) { - log("Create service promise", service); - let result = Promise.resolve(); - result = result.then(()=>{ - log("Handling service" + service.uuid); - return service.getCharacteristics().then((c)=>createCharacteristicsPromise(c)); - }); - return result.then(()=>log("Handled service" + service.uuid)); - }; - - let attachServicePromise = function(promise, service) { - return promise.then(()=>createServicePromise(service)); - }; - let initBt = function () { log("initBt with blockInit: " + blockInit); if (blockInit && !powerdownRequested){ diff --git a/apps/bthrm/settings.js b/apps/bthrm/settings.js index 4f52683ff..68e958db8 100644 --- a/apps/bthrm/settings.js +++ b/apps/bthrm/settings.js @@ -21,8 +21,6 @@ if (settings.debuglog) log = print; - const bthrm = require("bthrm"); - function applyCustomSettings(){ writeSettings("enabled",true); writeSettings("replace",settings.custom_replace); From 08f412f7f5b4c5b845a9b4ac33c1d70765477d3e Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Sat, 13 Apr 2024 21:58:49 +0200 Subject: [PATCH 11/16] bthrm - Fix new lint warnings --- apps/bthrm/lib.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/apps/bthrm/lib.js b/apps/bthrm/lib.js index b00e15d93..b81bd6118 100644 --- a/apps/bthrm/lib.js +++ b/apps/bthrm/lib.js @@ -302,22 +302,6 @@ exports.enable = () => { }); }; - let createCharacteristicsPromise = function(newCharacteristics) { - log("Create characteristics promis ", newCharacteristics); - let result = Promise.resolve(); - for (let c of newCharacteristics){ - if (!supportedCharacteristics[c.uuid]) continue; - log("Supporting characteristic", c); - characteristics.push(c); - if (c.properties.notify){ - addNotificationHandler(c); - } - - result = attachCharacteristicPromise(result, c); - } - return result.then(()=>log("Handled characteristics")); - }; - let initBt = function () { log("initBt with blockInit: " + blockInit); if (blockInit && !powerdownRequested){ From 020924fb037c1a5725092847decdf889883cb6dc Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Sun, 14 Apr 2024 10:39:05 +0200 Subject: [PATCH 12/16] bthrm - Do not use lazy rendering --- apps/bthrm/bthrm.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/bthrm/bthrm.js b/apps/bthrm/bthrm.js index 246b539d4..15c8c95b1 100644 --- a/apps/bthrm/bthrm.js +++ b/apps/bthrm/bthrm.js @@ -57,7 +57,7 @@ var layout = new Layout( { { type:undefined, height:8 } //dummy to protect debug output ] }, { - lazy:true + lazy:false }); var int,agg,bt; @@ -108,6 +108,7 @@ function draw(){ } layout.update(); + layout.clear(); layout.render(); let first = true; for (let c of layout.l.c){ From 6a04e3d394e33f9ee1031c5a54d8a3ff9765963d Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Sun, 14 Apr 2024 10:46:56 +0200 Subject: [PATCH 13/16] bthrm - Draw on event instead of every second --- apps/bthrm/bthrm.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/bthrm/bthrm.js b/apps/bthrm/bthrm.js index 15c8c95b1..47e04ef1a 100644 --- a/apps/bthrm/bthrm.js +++ b/apps/bthrm/bthrm.js @@ -133,16 +133,19 @@ function showStatusInfo(txt) { function onBtHrm(e) { bt = e; bt.time = Date.now(); + draw(); } function onInt(e) { int = e; int.time = Date.now(); + draw(); } function onAgg(e) { agg = e; agg.time = Date.now(); + draw(); } var settings = require('Storage').readJSON("bthrm.json", true) || {}; @@ -163,7 +166,6 @@ Bangle.drawWidgets(); if (Bangle.setBTHRMPower){ g.reset().setFont("6x8",2).setFontAlign(0,0); g.drawString("Please wait...",g.getWidth()/2,g.getHeight()/2); - setInterval(draw, 1000); } else { g.reset().setFont("6x8",2).setFontAlign(0,0); g.drawString("BTHRM disabled",g.getWidth()/2,g.getHeight()/2); From a22beea01a9d92d692b20b0ca0a504460a826c60 Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Sun, 14 Apr 2024 11:43:47 +0200 Subject: [PATCH 14/16] bthrm - Fix BTHRM not being toggled on and of by recorder --- apps/bthrm/ChangeLog | 3 ++- apps/bthrm/recorder.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/bthrm/ChangeLog b/apps/bthrm/ChangeLog index 0753534e4..1480698a2 100644 --- a/apps/bthrm/ChangeLog +++ b/apps/bthrm/ChangeLog @@ -45,4 +45,5 @@ 0.19: Move caching of characteristics into settings app Changed default of active scanning to false Fix setHRMPower method not returning new state - Only buzz for disconnect after switching on if there already was an actual connection + Only buzz for disconnect after switching on if there already was an actual connection + Fix recorder not switching BTHRM on and off diff --git a/apps/bthrm/recorder.js b/apps/bthrm/recorder.js index c3019b465..ec880d553 100644 --- a/apps/bthrm/recorder.js +++ b/apps/bthrm/recorder.js @@ -26,11 +26,11 @@ }, start : () => { Bangle.on('BTHRM', onHRM); - if (Bangle.setBTRHMPower) Bangle.setBTHRMPower(1,"recorder"); + if (Bangle.setBTHRMPower) Bangle.setBTHRMPower(1,"recorder"); }, stop : () => { Bangle.removeListener('BTHRM', onHRM); - if (Bangle.setBTRHMPower) Bangle.setBTHRMPower(0,"recorder"); + if (Bangle.setBTHRMPower) Bangle.setBTHRMPower(0,"recorder"); }, draw : (x,y) => g.setColor((Bangle.isBTHRMActive && Bangle.isBTHRMActive())?"#00f":"#88f").drawImage(atob("DAwBAAAAMMeef+f+f+P8H4DwBgAA"),x,y) }; From bc9d1ec7228054353c5a99d87577cc7b7b460214 Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Sun, 14 Apr 2024 11:49:19 +0200 Subject: [PATCH 15/16] bthrm - Try to make linter happy by adding status method to global object --- apps/bthrm/bthrm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/bthrm/bthrm.js b/apps/bthrm/bthrm.js index 47e04ef1a..acd3b3a60 100644 --- a/apps/bthrm/bthrm.js +++ b/apps/bthrm/bthrm.js @@ -123,7 +123,7 @@ function draw(){ // This can get called for the boot code to show what's happening -function showStatusInfo(txt) { +global.showStatusInfo = function(txt) { var R = Bangle.appRect; g.reset().clearRect(R.x,R.y2-8,R.x2,R.y2).setFont("6x8"); txt = g.wrapString(txt, R.w)[0]; From 40591473853074319e8139a7e046246804a791d3 Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Sun, 14 Apr 2024 13:04:52 +0200 Subject: [PATCH 16/16] bthrm - Fix updating the layout on every draw --- apps/bthrm/bthrm.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/bthrm/bthrm.js b/apps/bthrm/bthrm.js index acd3b3a60..14ef531c8 100644 --- a/apps/bthrm/bthrm.js +++ b/apps/bthrm/bthrm.js @@ -106,8 +106,6 @@ function draw(){ layout.btContact.label = "--"; layout.btEnergy.label = "--"; } - - layout.update(); layout.clear(); layout.render(); let first = true; @@ -128,7 +126,7 @@ global.showStatusInfo = function(txt) { g.reset().clearRect(R.x,R.y2-8,R.x2,R.y2).setFont("6x8"); txt = g.wrapString(txt, R.w)[0]; g.setFontAlign(0,1).drawString(txt, (R.x+R.x2)/2, R.y2); -} +}; function onBtHrm(e) { bt = e;