diff --git a/apps/bthometemp/ChangeLog b/apps/bthometemp/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/bthometemp/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/bthometemp/README.md b/apps/bthometemp/README.md new file mode 100644 index 000000000..1a8212ea4 --- /dev/null +++ b/apps/bthometemp/README.md @@ -0,0 +1,9 @@ +# BTHome Temperature and Pressure + +This app displays temperature and pressure and advertises them over bluetooth using BTHome.io standard (along with battery level) + +This can be used to integrate with [Home Assistant](https://www.home-assistant.io/), so you can use your Bangle as a wireless temperature/pressure sensor. + +More info on the standard at https://bthome.io + +And the data format used is https://bthome.io/format/ diff --git a/apps/bthometemp/app-icon.js b/apps/bthometemp/app-icon.js new file mode 100644 index 000000000..e2dff3eb9 --- /dev/null +++ b/apps/bthometemp/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4kA///1N6BIPf//1gMIwdE8sG2me+9Y/8C/2snXsoUNpdnzdt/xj/AH4AYgMRAAUQCyoYSCQNXs1muoFBFyHm1X//+qtwwPiMX1+YmczxP6uIwNFwN6yeDnGDmc504wNFwOpnGYC4OJweaGBsR9WTmYtBmc4GAOuC5ZGBt4SBAAQEBwf2JBcBiupnIuCmedxGTzVRC5cX1AuDnPZF4OKuIXLi3zIoedMgMzn9hC5uICQON5IDBxAXSznYC6RdDPQYXNO4JcB7pdCO56nBnGZ7p6DU5zXBXgSqDa5sAiPqIgOZd4c510RCxQXBi+pRQIXBxODzVxC5hIBvR1DnE505GMGAevzAvC/QuNGAfm1X//+qtwuOGAURq9ms11AoIWOGAQAEFw1EDBwWFggBCkUgAQMigUAAIIAJoABDCgIXQFwYXBCYYBDHAMCEAIkCFgcEAIIKCCoQFCkAhBAQIlCkAsBOoIXCBoIvEAwQTCAYI2BIwgXIF4YXDQwIVCC4YIBMIwfCAQRfGYBSPNC6TBFACgwBACouWAH4AiA=")) diff --git a/apps/bthometemp/app.js b/apps/bthometemp/app.js new file mode 100644 index 000000000..7b55777d1 --- /dev/null +++ b/apps/bthometemp/app.js @@ -0,0 +1,58 @@ +// history of temperature/pressure readings +var history = []; + +// When we get temperature... +function onTemperature(p) { + // Average the last 5 temperature readings + while (history.length>4) history.shift(); + history.push(p); + var avrTemp = history.reduce((i,h)=>h.temperature+i,0) / history.length; + var avrPressure = history.reduce((i,h)=>h.pressure+i,0) / history.length; + var t = require('locale').temp(avrTemp).replace("'","°"); + // Draw + var rect = Bangle.appRect; + g.reset(1).clearRect(rect.x, rect.y, rect.x2, rect.y2); + var x = (rect.x+rect.x2)/2; + var y = (rect.y+rect.y2)/2 + 10; + g.setFont("6x15").setFontAlign(0,0).drawString("Temperature:", x, y - 65); + g.setFontVector(50).setFontAlign(0,0).drawString(t, x, y-25); + g.setFont("6x15").setFontAlign(0,0).drawString("Pressure:", x, y+15 ); + g.setFont("12x20").setFontAlign(0,0).drawString(Math.round(avrPressure)+" hPa", x, y+40); + // Set Bluetooth Advertising + // https://bthome.io/format/ + var temp100 = Math.round(avrTemp*100); + var pressure100 = Math.round(avrPressure*100); + + Bangle.bleAdvert[0xFCD2] = [ 0x40, /* BTHome Device Information + bit 0: "Encryption flag" + bit 1-4: "Reserved for future use" + bit 5-7: "BTHome Version" */ + + 0x01, // Battery, 8 bit + E.getBattery(), + + 0x02, // Temperature, 16 bit + temp100&255,temp100>>8, + + 0x04, // Pressure, 16 bit + pressure100&255,(pressure100>>8)&255,pressure100>>16 + ]; + NRF.setAdvertising(Bangle.bleAdvert); +} + +// Gets the temperature in the most accurate way with pressure sensor +function drawTemperature() { + Bangle.getPressure().then(p =>{if (p) onTemperature(p);}); +} + +if (!Bangle.bleAdvert) Bangle.bleAdvert = {}; +setInterval(function() { + drawTemperature(); +}, 10000); // update every 10s +Bangle.loadWidgets(); +Bangle.setUI({ + mode : "custom", + back : function() {load();} +}); +E.showMessage("Reading temperature..."); +drawTemperature(); diff --git a/apps/bthometemp/app.png b/apps/bthometemp/app.png new file mode 100644 index 000000000..6c8eb3f14 Binary files /dev/null and b/apps/bthometemp/app.png differ diff --git a/apps/bthometemp/metadata.json b/apps/bthometemp/metadata.json new file mode 100644 index 000000000..4bfd08c31 --- /dev/null +++ b/apps/bthometemp/metadata.json @@ -0,0 +1,14 @@ +{ "id": "bthometemp", + "name": "BTHome Temperature and Pressure", + "shortName":"BTHome T", + "version":"0.01", + "description": "Displays temperature and pressure, and advertises them over bluetooth using BTHome.io standard", + "icon": "app.png", + "tags": "bthome,bluetooth,temperature", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"bthometemp.app.js","url":"app.js"}, + {"name":"bthometemp.img","url":"app-icon.js","evaluate":true} + ] +} diff --git a/apps/hworldclock/ChangeLog b/apps/hworldclock/ChangeLog index df3965698..87c7cf288 100644 --- a/apps/hworldclock/ChangeLog +++ b/apps/hworldclock/ChangeLog @@ -15,3 +15,4 @@ 0.29: Use 'modules/suncalc.js' to avoid it being copied 8 times for different apps 0.30: BJS2: swipe seems to be working now 0.31: Tweaking the swipe option; Added mylocation as a dependency. + Remove calls to Bangle.loadWidgets as they are not needed and create warnings \ No newline at end of file diff --git a/apps/hworldclock/app.js b/apps/hworldclock/app.js index 6b10fb4f0..2eba0fb71 100644 --- a/apps/hworldclock/app.js +++ b/apps/hworldclock/app.js @@ -321,7 +321,6 @@ let draw = function() { //g.clear().setRotation(defaultRotation); //currentRotation = defaultRotation; //draw(); - //Bangle.loadWidgets(); //Bangle.drawWidgets(); } else { if (currentRotation == rotationTarget) { @@ -333,7 +332,6 @@ let draw = function() { } draw(); - Bangle.loadWidgets(); Bangle.drawWidgets(); } } else { @@ -459,4 +457,4 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); // ); -} \ No newline at end of file +} diff --git a/core b/core index 2a89ea64f..376824068 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 2a89ea64f7874b9264572f68836fe8ecd0a6b191 +Subproject commit 376824068d90986c245b46970fd80ccdca44e431 diff --git a/modules/clock_info.js b/modules/clock_info.js index 50968311e..6f37e5d3d 100644 --- a/modules/clock_info.js +++ b/modules/clock_info.js @@ -61,12 +61,15 @@ if (stepGoal == undefined) { exports.load = function() { // info used for drawing... - var hrm = "--"; + var hrm = 0; var alt = "--"; // callbacks (needed for easy removal of listeners) function batteryUpdateHandler() { bangleItems[0].emit("redraw"); } function stepUpdateHandler() { bangleItems[1].emit("redraw"); } - function hrmUpdateHandler() { bangleItems[2].emit("redraw"); } + function hrmUpdateHandler(e) { + if (e && e.confidence>60) hrm = Math.round(e.bpm); + bangleItems[2].emit("redraw"); + } function altUpdateHandler() { Bangle.getPressure().then(data=>{ if (!data) return; @@ -99,12 +102,12 @@ exports.load = function() { }, { name : "HRM", hasRange : true, - get : () => { let v = Math.round(Bangle.getHealthStatus("last").bpm); return { - text : v + " bpm", v : v, min : 40, max : 200, + get : () => { return { + text : (hrm||"--") + " bpm", v : hrm, min : 40, max : 200, img : atob("GBiBAAAAAAAAAAAAAAAAAAAAAADAAADAAAHAAAHjAAHjgAPngH9n/n82/gA+AAA8AAA8AAAcAAAYAAAYAAAAAAAAAAAAAAAAAAAAAA==") }}, - show : function() { Bangle.setHRMPower(1,"clkinfo"); Bangle.on("HRM", hrmUpdateHandler); hrm = Math.round(Bangle.getHealthStatus("last").bpm); hrmUpdateHandler(); }, - hide : function() { Bangle.setHRMPower(0,"clkinfo"); Bangle.removeListener("HRM", hrmUpdateHandler); hrm = "--"; }, + show : function() { Bangle.setHRMPower(1,"clkinfo"); Bangle.on("HRM", hrmUpdateHandler); hrm = Math.round(Bangle.getHealthStatus().bpm||Bangle.getHealthStatus("last").bpm); hrmUpdateHandler(); }, + hide : function() { Bangle.setHRMPower(0,"clkinfo"); Bangle.removeListener("HRM", hrmUpdateHandler); hrm = 0; }, } ], }];