From 6c4d3f41a59d519bc502f6d1a1792c472586398d Mon Sep 17 00:00:00 2001 From: Niko Komin Date: Tue, 29 Aug 2023 11:32:03 -0700 Subject: [PATCH 1/4] added new app --- apps/nightwatch/ChangeLog | 1 + apps/nightwatch/README.md | 20 +++ apps/nightwatch/metadata.json | 16 +++ apps/nightwatch/nightwatch.app.info | 6 + apps/nightwatch/nightwatch.app.js | 175 +++++++++++++++++++++++++ apps/nightwatch/nightwatch.icon.js | 1 + apps/nightwatch/nightwatch.icon.png | Bin 0 -> 959 bytes apps/nightwatch/nightwatch.info.js | 6 + apps/nightwatch/nightwatch.settings.js | 25 ++++ apps/nightwatch/screenshot.png | Bin 0 -> 3608 bytes apps/nightwatch/screenshot2.png | Bin 0 -> 3795 bytes 11 files changed, 250 insertions(+) create mode 100644 apps/nightwatch/ChangeLog create mode 100644 apps/nightwatch/README.md create mode 100644 apps/nightwatch/metadata.json create mode 100644 apps/nightwatch/nightwatch.app.info create mode 100644 apps/nightwatch/nightwatch.app.js create mode 100644 apps/nightwatch/nightwatch.icon.js create mode 100644 apps/nightwatch/nightwatch.icon.png create mode 100644 apps/nightwatch/nightwatch.info.js create mode 100644 apps/nightwatch/nightwatch.settings.js create mode 100644 apps/nightwatch/screenshot.png create mode 100644 apps/nightwatch/screenshot2.png diff --git a/apps/nightwatch/ChangeLog b/apps/nightwatch/ChangeLog new file mode 100644 index 000000000..dc179ee9d --- /dev/null +++ b/apps/nightwatch/ChangeLog @@ -0,0 +1 @@ +1.0: first working version of App diff --git a/apps/nightwatch/README.md b/apps/nightwatch/README.md new file mode 100644 index 000000000..6d1749c5d --- /dev/null +++ b/apps/nightwatch/README.md @@ -0,0 +1,20 @@ +# The Nightwatch + +Snuggle into your sleeping bag, hang the Bangle on the tent wall +and check the screen before you fall asleep: + +![](screenshot.png) +![](screenshot2.png) + + +Reads temperature and pressure sensor. Shows current, maximal and minimal values +since the start of the app. Also show a graph of the last 20 measures. + +Swipe left/right between values. + +Screen is updated periodically, time step is configurable in settings. + + +# Creator + +[Niko Komin](https://www.laikaundfreunde.de/niko-komin/) diff --git a/apps/nightwatch/metadata.json b/apps/nightwatch/metadata.json new file mode 100644 index 000000000..90e05214e --- /dev/null +++ b/apps/nightwatch/metadata.json @@ -0,0 +1,16 @@ +{ + "id":"nightwatch", + "readme":"README.md", + "name":"The Nightwatch", + "shortName":"Nightwatch", + "supports" : ["BANGLEJS2"], + "icon":"nightwatch.icon.png", + "screenshots" : [ { "url":"screenshot.png","url":"screenshot2.png" } ], + "version":"1.0", + "description":"Logs sensor readings (currently T and p), show min/max and graph.", + "tags": "tools,outdoors", + "storage": [ + {"name":"nightwatch.app.js","url":"nightwatch.app.js"}, + {"name":"nightwatch.img","url":"nightwatch.icon.js","evaluate":true} + ] +} diff --git a/apps/nightwatch/nightwatch.app.info b/apps/nightwatch/nightwatch.app.info new file mode 100644 index 000000000..36345ce26 --- /dev/null +++ b/apps/nightwatch/nightwatch.app.info @@ -0,0 +1,6 @@ +require("Storage").write("nightwatch.info",{ + "id":"nightwatch", + "name":"nightwatch", + "src":"nightwatch.app.js", + "icon":"nightwatch.icon.png" +}); \ No newline at end of file diff --git a/apps/nightwatch/nightwatch.app.js b/apps/nightwatch/nightwatch.app.js new file mode 100644 index 000000000..035307106 --- /dev/null +++ b/apps/nightwatch/nightwatch.app.js @@ -0,0 +1,175 @@ +// PTLOGGER +// MEASURES p AND T PERIODICALLY AND UPDATES MIN & MAX VALS +// DISPLAYS EITHER OF BOTH + + +var settings = Object.assign({ + dt: 5, //time interval in minutes +}, require('Storage').readJSON("nightwatch.json", true) || {}); + +let dt = settings.dt; +delete settings; + +var timerID; + +const highColor = '#35b779';//#6dcd59; +const lowColor = '#eb005c';//#3d4a89;//#482878; +const normColor = '#000000'; +const historyAmnt = 24; + + +const TData = { + ondisplay:true, + unit: '\xB0C', + accuracy: 1, + value : 100, t_value:'0:00', + values : new Array(historyAmnt), + maxval : -100, t_max:'0:00', + minval : 100, t_min:'0:00' +}; + +const PData = { + ondisplay:false, + unit: 'mbar', + accuracy: 0, + value : 0, t_value:'0:00', + values : new Array(historyAmnt), + maxval : 0, t_max:'0:00', + minval : 10000, t_min:'0:00' +}; + +function minMaxString(val,accuracy,unit,time){ + return time+' '+val.toFixed(accuracy)+unit; +// return val.toFixed(accuracy)+unit+'('+time+')'; +} + +function updateScreen() { + // what are we showing right now? + let data; + if (TData.ondisplay){data = TData;} + else {data = PData;} + + // make strings + let valueString = data.value.toFixed(data.accuracy)+data.unit; + let minString = minMaxString(data.minval, data.accuracy, data.unit, data.t_min); + let maxString = minMaxString(data.maxval, data.accuracy, data.unit, data.t_max); + + // LETS PAINT + g.clear(); + g.setFontAlign(0, 0); + + // MINUM AND MAXIMUM VALUES AND TIMES + g.setFont("Vector:18"); + g.setColor(normColor); + g.drawString(maxString, g.getWidth() / 2, 11); + g.drawString(minString, g.getWidth() / 2, g.getHeight() - 11); + + g.setColor(normColor); + + // TIME OF LAST MEASURE AND SIZE OF INTERVAL + g.setFontAlign(-1, 0); + g.drawString(data.t_value, 0, g.getHeight()/2 - 25); + g.setFontAlign(1, 0); + g.drawString('dt='+dt+'min', g.getWidth() , g.getHeight()/2 - 25); + + //////////////////////////////////////////////////////////// + // GRAPH OF MEASUREMENT HISTORY + g.setFont("Vector:16"); + const graphHeight=35; + const graphWidth=g.getWidth()-30; + const graphLocX = 15; + const graphLocY = g.getHeight() - 16 - 18 - graphHeight; + + // DRAW SOME KIND OF AXES + g.setColor(0.4,0.4,0.4); + g.drawRect(graphLocX,graphLocY,graphLocX+graphWidth,graphLocY+graphHeight); + g.drawLine(graphLocX,graphLocY+graphHeight/2,graphLocX+graphWidth,graphLocY+graphHeight/2); + g.drawLine(graphLocX+graphWidth/2,graphLocY,graphLocX+graphWidth/2,graphLocY+graphHeight); + g.drawLine(graphLocX+graphWidth/4,graphLocY,graphLocX+graphWidth/4,graphLocY+graphHeight); + g.drawLine(graphLocX+3*graphWidth/4,graphLocY,graphLocX+3*graphWidth/4,graphLocY+graphHeight); + g.setColor(normColor); + + // DRAW LINE + require("graph").drawLine(g, data.values, { + x:graphLocX, + y:graphLocY, + width:graphWidth, + height:graphHeight + }); + + let graphMax=Math.max.apply(Math,data.values); + let graphMin=Math.min.apply(Math,data.values); + g.setFontAlign(0, 0); + g.setColor(highColor); + g.drawString(graphMax.toFixed(data.accuracy), g.getWidth()/2, g.getHeight() - 16 - 18 - graphHeight); + g.setColor(lowColor); + g.drawString(graphMin.toFixed(data.accuracy), g.getWidth()/2, g.getHeight() - 16 - 18); + g.setColor(normColor); + + let historyLength = (historyAmnt*dt >= 60)?('-'+historyAmnt*dt/60+'h'):('-'+historyAmnt*dt+'"'); + + g.drawString(historyLength,25, g.getHeight() - 16 - 18 - graphHeight/2); + + //////////////////////////////////////////////////////////// + // LAST MEASURE + g.setFontAlign(0, 0); + g.setFont('Vector:36'); + g.drawString(valueString, g.getWidth() / 2, g.getHeight() / 2); + + data.ondisplay = true; +} + +function updateMinMax( data, currentValue ){ + data.values.push(currentValue); + data.values.shift(); + data.value=currentValue; + + let now = new Date(); + data.t_value = now.getHours()+':'+String(now.getMinutes()).padStart(2, '0'); + if (currentValue < data.minval){data.t_min=data.t_value;data.minval = currentValue;} + if (currentValue > data.maxval){data.t_max=data.t_value;data.maxval = currentValue;} +} + +function switchDisplay(){ + if (TData.ondisplay) {TData.ondisplay=false;PData.ondisplay=true;updateScreen();} + else {PData.ondisplay=false;TData.ondisplay=true;updateScreen();} +} + +function settingsPage(){ + Bangle.on('swipe',function (){}); + eval(require("Storage").read("nightwatch.settings.js"))(()=>load()); + Bangle.on('swipe',switchDisplay); + console.log(3); +} + +function handlePressureSensorReading(data) { + updateMinMax(TData,data.temperature); + updateMinMax(PData,data.pressure); +} + +function startup(){ + // testing in emulator + // handlePressureSensorReading({ "temperature": 28.64251302083, "pressure": 1004.66520303803, "altitude": 71.72072902749 }); + // updateScreen(); + + // ON STARTUP: + // fill current reading into data, + // before `updateMinMax` uses it + Bangle.getPressure().then(d=>{TData.value=d.temperature; + TData.values.fill(d.temperature); + PData.value=d.pressure; + PData.values.fill(d.pressure); + handlePressureSensorReading(d); + updateScreen();}); + Bangle.on('swipe',switchDisplay); + + //Bangle.on('tap',settingsPage); + + timerID = setInterval( function() { + Bangle.getPressure().then(d=>{handlePressureSensorReading(d);updateScreen();}); + }, dt * 60000); + +} + +startup(); + diff --git a/apps/nightwatch/nightwatch.icon.js b/apps/nightwatch/nightwatch.icon.js new file mode 100644 index 000000000..19b4623f0 --- /dev/null +++ b/apps/nightwatch/nightwatch.icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4MA///ospETUQAgc//gFDv4FF/wFP/4FF/5PCgIFChF/AoWA/1/+YFBx/+g4EBAAPAFAIEBEgUDBQYAN/E/AgQvDDoXHDocH4wFDgf8v4RCDooAMj/4AoZcBcM8DOAgFFgJSDAqQAhA==")) diff --git a/apps/nightwatch/nightwatch.icon.png b/apps/nightwatch/nightwatch.icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bf3a3282a2f655eba40d0441711ed16c1a809216 GIT binary patch literal 959 zcmV;w13>(VP)Vs(=D#7dY15`A0EmtJSi%|rFP2^IAo;3<%`y2-Hk*Aq zG!sUyF!8R5|M?Pe+la$PZjrFZh~N6J71vcs&xB^di2Y>&4!^*<7p##pOHJN4!)R1B)doOs4)O$NzqyfyNz7`VAe=@cZeeUMZzwUi*mW#r1DS9 zWKx|*+;|)TR!F1X!6H@yJ`j1pi0hAtC;pT)ITR=49*M_IygAf2WyC27+l^cXV6JzO z#|~Z(M64q@FD5^9K_>q3KlfiX;aeY)Q4~EpKy_DF*HdQEeDBd-oJrud3bOk3j|pE% zSPdW@D#1Mq$=8kCD)CG`0v2&Qc^0|VpWV~b^F*i>UN~maLf`V@R{tpCiim%!`)1iE z@_Vl}16KJ^^ehOCU~XsU_)I4AT@gkV>VVl=Pm2kIZb2Tj!zf z&Ci%I(SYR=HjsQJG#WFbx7)JR=u7N{MGG=O-j~l737?mBxw}4hYMSGf;Dg1)ze`%} z*}`CZM9?rr%dhL6_hvRz#I=&(Kl6O=uLX(URaVeASl6A9_-WZ7>h)UiYo0PjTsHAm zQWwP0k%)+ap1KKeuO#tEd0UitzQp4!>fe!JMBH+rp#gMwak`@%Se)*m^hW88KJtCn z2F?py@|wv+Q52ehjwp(z4`%vGku)yX-Tji!hWdpzn#pFfQ~f;1Q^v^m-K`ew@6U+^ zCVNGm^NuC*hh!Fz8x2_LE;x?UXxQ;e9H+DH5Z%X!{KkV8d7&^H@RNjXB+V>(Q{tBe z-{Y+pzb4k5{KCbMT>Nq>^+H2Lv}x036t~xOIz6TTwVCBYDmLfxlF({o{C7c7z##u}Y6&|0giXZnp;a+*uaWygt3vWEKRgbtN-me1 h)GWWa+O!$1+y}#On>2C^{7nD=002ovPDHLkV1lA$%cuYV literal 0 HcmV?d00001 diff --git a/apps/nightwatch/nightwatch.info.js b/apps/nightwatch/nightwatch.info.js new file mode 100644 index 000000000..ccbc8909a --- /dev/null +++ b/apps/nightwatch/nightwatch.info.js @@ -0,0 +1,6 @@ +require("Storage").write("nightwatch.info",{ + "id":"nightwatch", + "name":"The Nightwatch", + "src":"nightwatch.app.js", + "icon":"nightwatch.icon.png" +}); diff --git a/apps/nightwatch/nightwatch.settings.js b/apps/nightwatch/nightwatch.settings.js new file mode 100644 index 000000000..c543b7343 --- /dev/null +++ b/apps/nightwatch/nightwatch.settings.js @@ -0,0 +1,25 @@ +(function(back) { + var FILE = "nightwatch.json"; + // Load settings + var settings = Object.assign({ + dt: 30, + }, require('Storage').readJSON(FILE, true) || {}); + + function writeSettings() { + require('Storage').writeJSON(FILE, settings); + } + + // Show the menu + E.showMenu({ + "" : { "title" : "nightwatch" }, + "< Back" : () => back(), + 'log freq (min)': { + value: 0|settings.dt, // 0| converts undefined to 0 + min: 1, max: 60, + onchange: v => { + settings.dt = v; + writeSettings(); + } + }, + }); +}); diff --git a/apps/nightwatch/screenshot.png b/apps/nightwatch/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..194c91b28c327b6ca06d06515b1dd81197411ed9 GIT binary patch literal 3608 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 literal 0 HcmV?d00001 From 08687fb265b64ca7042c44b4d76e16afa8361a47 Mon Sep 17 00:00:00 2001 From: Niko Komin Date: Tue, 29 Aug 2023 20:22:23 -0700 Subject: [PATCH 2/4] bugfix (enable settings page) --- apps/nightwatch/ChangeLog | 1 + apps/nightwatch/metadata.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/nightwatch/ChangeLog b/apps/nightwatch/ChangeLog index dc179ee9d..829c8c887 100644 --- a/apps/nightwatch/ChangeLog +++ b/apps/nightwatch/ChangeLog @@ -1 +1,2 @@ +1.1: bugfix (enable settings page) 1.0: first working version of App diff --git a/apps/nightwatch/metadata.json b/apps/nightwatch/metadata.json index 90e05214e..fc0150051 100644 --- a/apps/nightwatch/metadata.json +++ b/apps/nightwatch/metadata.json @@ -6,11 +6,12 @@ "supports" : ["BANGLEJS2"], "icon":"nightwatch.icon.png", "screenshots" : [ { "url":"screenshot.png","url":"screenshot2.png" } ], - "version":"1.0", + "version":"1.1", "description":"Logs sensor readings (currently T and p), show min/max and graph.", "tags": "tools,outdoors", "storage": [ {"name":"nightwatch.app.js","url":"nightwatch.app.js"}, + {"name":"nightwatch.settings.js","url":"nightwatch.settings.js"}, {"name":"nightwatch.img","url":"nightwatch.icon.js","evaluate":true} ] } From 72f49eeee71a57b49fa27b8c4eaf7ddd0c1f66e3 Mon Sep 17 00:00:00 2001 From: Niko Komin Date: Tue, 29 Aug 2023 21:00:52 -0700 Subject: [PATCH 3/4] bugfix (enable settings page) --- apps/nightwatch/ChangeLog | 2 +- apps/nightwatch/metadata.json | 3 ++- apps/nightwatch/nightwatch.settings.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/nightwatch/ChangeLog b/apps/nightwatch/ChangeLog index 829c8c887..c854e9e5b 100644 --- a/apps/nightwatch/ChangeLog +++ b/apps/nightwatch/ChangeLog @@ -1,2 +1,2 @@ -1.1: bugfix (enable settings page) 1.0: first working version of App +1.1: bugfix (enable settings page) diff --git a/apps/nightwatch/metadata.json b/apps/nightwatch/metadata.json index fc0150051..4de2a0271 100644 --- a/apps/nightwatch/metadata.json +++ b/apps/nightwatch/metadata.json @@ -13,5 +13,6 @@ {"name":"nightwatch.app.js","url":"nightwatch.app.js"}, {"name":"nightwatch.settings.js","url":"nightwatch.settings.js"}, {"name":"nightwatch.img","url":"nightwatch.icon.js","evaluate":true} - ] + ], + "data": [{"name":"nightwatch.json"}] } diff --git a/apps/nightwatch/nightwatch.settings.js b/apps/nightwatch/nightwatch.settings.js index c543b7343..744ebd8dc 100644 --- a/apps/nightwatch/nightwatch.settings.js +++ b/apps/nightwatch/nightwatch.settings.js @@ -2,7 +2,7 @@ var FILE = "nightwatch.json"; // Load settings var settings = Object.assign({ - dt: 30, + dt: 5, }, require('Storage').readJSON(FILE, true) || {}); function writeSettings() { From c645b3110504d38e9b05ebd7b5ba8384ca486652 Mon Sep 17 00:00:00 2001 From: Niko Komin Date: Wed, 30 Aug 2023 11:06:26 -0700 Subject: [PATCH 4/4] corrected screenshot --- apps/nightwatch/screenshot.png | Bin 3608 -> 3660 bytes apps/nightwatch/screenshot2.png | Bin 3795 -> 3855 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/nightwatch/screenshot.png b/apps/nightwatch/screenshot.png index 194c91b28c327b6ca06d06515b1dd81197411ed9..3f524eac9e1402c8ae66f48f312f8748d41cb628 100644 GIT binary patch literal 3660 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 literal 3608 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 literal 3795 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