mirror of https://github.com/espruino/BangleApps
Create app.js
parent
ff40b61747
commit
230625ae78
|
@ -0,0 +1,395 @@
|
||||||
|
// Temperature Graph
|
||||||
|
// BangleJS Script
|
||||||
|
|
||||||
|
Bangle.setBarometerPower(true,"tempgraph");
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
var wids=WIDGETS;
|
||||||
|
var widsOn=true;
|
||||||
|
var rm=null;
|
||||||
|
var gt=null;
|
||||||
|
var dg=null;
|
||||||
|
var Layout=require("Layout");
|
||||||
|
var C=true;
|
||||||
|
var temp,tempMode,readErrCnt,watchButton2;
|
||||||
|
|
||||||
|
var graph=require("Storage").readJSON("tempgraph.json",true);
|
||||||
|
if(graph==undefined) {
|
||||||
|
graph=[];
|
||||||
|
}
|
||||||
|
|
||||||
|
var timesData=[
|
||||||
|
// dur=duration, u=time units, d=divisions on graph, s=seconds per unit.
|
||||||
|
{dur:10,u:"Mins",d:5,s:60},
|
||||||
|
{dur:20,u:"Mins",d:4,s:60},
|
||||||
|
{dur:30,u:"Mins",d:3,s:60},
|
||||||
|
{dur:40,u:"Mins",d:4,s:60},
|
||||||
|
{dur:1,u:"Hr",d:4,s:3600},
|
||||||
|
{dur:2,u:"Hrs",d:4,s:3600},
|
||||||
|
{dur:3,u:"Hrs",d:3,s:3600},
|
||||||
|
{dur:4,u:"Hrs",d:4,s:3600},
|
||||||
|
{dur:6,u:"Hrs",d:6,s:3600},
|
||||||
|
{dur:8,u:"Hrs",d:4,s:3600},
|
||||||
|
{dur:12,u:"Hrs",d:6,s:3600},
|
||||||
|
{dur:16,u:"Hrs",d:4,s:3600},
|
||||||
|
{dur:20,u:"Hrs",d:5,s:3600},
|
||||||
|
{dur:1,u:"Day",d:4,s:3600},
|
||||||
|
{dur:2,u:"Days",d:4,s:86400},
|
||||||
|
{dur:3,u:"Days",d:3,s:86400},
|
||||||
|
{dur:4,u:"Days",d:4,s:86400},
|
||||||
|
{dur:5,u:"Days",d:5,s:86400},
|
||||||
|
{dur:6,u:"Days",d:6,s:86400},
|
||||||
|
{dur:7,u:"Days",d:7,s:86400}
|
||||||
|
];
|
||||||
|
var times=[];
|
||||||
|
for(n=0;n<timesData.length;n++){
|
||||||
|
times.push(timesData[n].dur+" "+timesData[n].u);
|
||||||
|
}
|
||||||
|
var durInd=0;
|
||||||
|
var duration=times[durInd];
|
||||||
|
|
||||||
|
function drawWids(){
|
||||||
|
g.clear();
|
||||||
|
if(widsOn){
|
||||||
|
WIDGETS=wids;
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
} else {
|
||||||
|
WIDGETS={};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openMenu(){
|
||||||
|
drawWids();
|
||||||
|
E.showMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
function redoMenu(){
|
||||||
|
clearInterval(rm);
|
||||||
|
E.showMenu();
|
||||||
|
openMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshMenu(){
|
||||||
|
rm = setInterval(redoMenu,100);
|
||||||
|
}
|
||||||
|
function getF(c){
|
||||||
|
// Get Fahrenheit temperature from Celsius.
|
||||||
|
return c*1.8+32;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getT(){
|
||||||
|
Bangle.getPressure().then(p=>{
|
||||||
|
temp=p.temperature;
|
||||||
|
if(tempMode=="drawGraph"&&graph.length>0&&Math.abs(graph[graph.length-1].temp-temp)>10&&readErrCnt<2){
|
||||||
|
// A large change in temperature may be a reading error. ie. A 0C or less reading after
|
||||||
|
// a 20C reading. So if this happens, the reading is repeated up to 2 times to hopefully
|
||||||
|
// skip such errors.
|
||||||
|
readErrCnt++;
|
||||||
|
print("readErrCnt "+readErrCnt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearInterval(gt);
|
||||||
|
readErrCnt=0;
|
||||||
|
switch (tempMode){
|
||||||
|
case "showTemp":
|
||||||
|
showT();
|
||||||
|
break;
|
||||||
|
case "drawGraph":
|
||||||
|
var date=new Date();
|
||||||
|
var dateStr=require("locale").date(date).trim();
|
||||||
|
var hrs=date.getHours();
|
||||||
|
var mins=date.getMinutes();
|
||||||
|
var secs=date.getSeconds();
|
||||||
|
graph.push({
|
||||||
|
temp:temp,
|
||||||
|
date:dateStr,
|
||||||
|
hrs:hrs,
|
||||||
|
mins:mins,
|
||||||
|
secs:secs
|
||||||
|
});
|
||||||
|
if(graph.length==1){
|
||||||
|
graph[0].dur=durInd;
|
||||||
|
}
|
||||||
|
require("Storage").writeJSON("tempgraph.json", graph);
|
||||||
|
if(graph.length==150){
|
||||||
|
clearInterval(dg);
|
||||||
|
}
|
||||||
|
drawG();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTemp(){
|
||||||
|
readErrCnt=0;
|
||||||
|
gt = setInterval(getT,800);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setButton(){
|
||||||
|
var watchButton=setWatch(function(){
|
||||||
|
clearInterval(gt);
|
||||||
|
clearInterval(dg);
|
||||||
|
clearWatch(watchButton);
|
||||||
|
Bangle.removeListener("touch",screenTouch);
|
||||||
|
openMenu();
|
||||||
|
},BTN);
|
||||||
|
Bangle.on('touch',screenTouch);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setButton2(){
|
||||||
|
watchButton2=setWatch(function(){
|
||||||
|
clearWatch(watchButton2);
|
||||||
|
openMenu();
|
||||||
|
},BTN);
|
||||||
|
}
|
||||||
|
|
||||||
|
function zPad(n){
|
||||||
|
return n.toString().padStart(2,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function screenTouch(n,ev){
|
||||||
|
if(ev.y>23&&ev.y<152){
|
||||||
|
C=C==false;
|
||||||
|
drawG(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawG(){
|
||||||
|
function cf(t){
|
||||||
|
if(C){
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return getF(t);
|
||||||
|
}
|
||||||
|
drawWids();
|
||||||
|
var top=1;
|
||||||
|
var bar=21;
|
||||||
|
var barBot=175-22;
|
||||||
|
if(widsOn){
|
||||||
|
top=25;
|
||||||
|
bar=bar+24;
|
||||||
|
barBot=barBot-24;
|
||||||
|
}
|
||||||
|
var low=graph[0].temp;
|
||||||
|
var hi=low;
|
||||||
|
for(n=0;n<graph.length;n++){
|
||||||
|
var t=graph[n].temp;
|
||||||
|
if(low>t){
|
||||||
|
low=t;
|
||||||
|
}
|
||||||
|
if(hi<t){
|
||||||
|
hi=t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var tempHi=Math.ceil((cf(hi)+2)/10)*10;
|
||||||
|
var tempLow=Math.floor((cf(low)-2)/10)*10;
|
||||||
|
var div=2;
|
||||||
|
if(tempHi-tempLow>10){
|
||||||
|
div=5;
|
||||||
|
}
|
||||||
|
if(C){
|
||||||
|
g.setColor(1,0,0);
|
||||||
|
}else{
|
||||||
|
g.setColor(0,0,1);
|
||||||
|
}
|
||||||
|
var step=(barBot-bar)/((tempHi-tempLow)/div);
|
||||||
|
for(n=0;n<graph.length;n++){
|
||||||
|
var pos=tempLow-cf(graph[n].temp);
|
||||||
|
g.drawLine(n+3,pos*(step/div)+barBot,n+3,barBot+3);
|
||||||
|
}
|
||||||
|
g.fillRect(161,barBot+5,174,barBot+20);
|
||||||
|
g.setColor(1,1,1);
|
||||||
|
g.setFont("6x8:2");
|
||||||
|
if(C){
|
||||||
|
g.drawString("C",163,barBot+5);
|
||||||
|
}else{
|
||||||
|
g.drawString("F",163,barBot+5);
|
||||||
|
}
|
||||||
|
g.setColor(0,0,0);
|
||||||
|
g.setFont6x15();
|
||||||
|
g.drawString("Temperature Graph - "+times[graph[0].dur],1,top);
|
||||||
|
g.drawRect(2,bar-4,153,barBot+4);
|
||||||
|
g.setFont("6x8:1");
|
||||||
|
var num=tempHi;
|
||||||
|
for(n=bar;n<=barBot;n=n+step){
|
||||||
|
g.drawLine(3,n,152,n);
|
||||||
|
g.drawString(num.toString().padStart(3," "),155,n-4);
|
||||||
|
num=num-div;
|
||||||
|
}
|
||||||
|
step=151/timesData[graph[0].dur].d;
|
||||||
|
for(n=step+2;n<152;n=n+step){
|
||||||
|
g.drawLine(n,bar-4,n,barBot+4);
|
||||||
|
}
|
||||||
|
grSt=graph[0];
|
||||||
|
g.drawString("Start: "+grSt.date+" "+grSt.hrs+":"+zPad(grSt.mins),1,barBot+6);
|
||||||
|
var lastT=graph[graph.length-1].temp;
|
||||||
|
g.drawString("Last Reading:",1,barBot+14);
|
||||||
|
g.setColor(1,0,0);
|
||||||
|
g.drawString(lastT.toFixed(1)+"C",85,barBot+14);
|
||||||
|
g.setColor(0,0,1);
|
||||||
|
g.drawString(getF(lastT).toFixed(1)+"F",121,barBot+14);
|
||||||
|
process.memory(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawGraph(){
|
||||||
|
setButton();
|
||||||
|
tempMode="drawGraph";
|
||||||
|
durInd=times.indexOf(duration);
|
||||||
|
graph=[];
|
||||||
|
getTemp();
|
||||||
|
dg=setInterval(getTemp,1000*timesData[durInd].dur*timesData[durInd].s/150);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showGraph(){
|
||||||
|
setButton();
|
||||||
|
drawG();
|
||||||
|
}
|
||||||
|
|
||||||
|
function noBluetooth(){
|
||||||
|
if(NRF.getSecurityStatus().connected){
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
message("Error! Your\nBangle Watch\ncurrently has\nno Bluetooth\nconnection.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveGraph(){
|
||||||
|
if(noBluetooth()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
drawG();
|
||||||
|
g.flip();
|
||||||
|
g.dump();
|
||||||
|
message("Graph has\nbeen sent\nto Web IDE\nfor saving.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveData(){
|
||||||
|
if(noBluetooth()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
drawG();
|
||||||
|
g.flip();
|
||||||
|
print("Temperature Graph - "+times[graph[0].dur]+"\n");
|
||||||
|
print("\"Date\",\"Time\",\"Celsius\",\"Fahrenheit\"");
|
||||||
|
for(n=0;n<graph.length;n++){
|
||||||
|
var gr=graph[n];
|
||||||
|
print("\""+gr.date+"\",\""+gr.hrs+":"+zPad(gr.mins)+":"+zPad(gr.secs)+"\","+gr.temp+","+getF(gr.temp));
|
||||||
|
}
|
||||||
|
message("Data has\nbeen sent\nto Web IDE\nfor saving.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
function message(mes){
|
||||||
|
setButton2();
|
||||||
|
var messageLO=new Layout({
|
||||||
|
type:"v",c:[
|
||||||
|
{type:"txt",font:"6x8:2",width:171,label:mes,id:"label"},
|
||||||
|
{type:"btn",font:"6x8:2",pad:3,label:"OK",cb:l=>exit()},
|
||||||
|
],lazy:true
|
||||||
|
});
|
||||||
|
drawWids();
|
||||||
|
messageLO.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
function showT(){
|
||||||
|
tempLO.lab1.label=tempLO.lab3.label;
|
||||||
|
tempLO.lab2.label=tempLO.lab4.label;
|
||||||
|
tempLO.lab3.label=tempLO.lab5.label;
|
||||||
|
tempLO.lab4.label=tempLO.lab6.label;
|
||||||
|
tempLO.lab5.label=temp.toFixed(2)+"C";
|
||||||
|
tempLO.lab6.label=getF(temp).toFixed(2)+"F";
|
||||||
|
tempLO.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
function exit(){
|
||||||
|
clearWatch(watchButton2);
|
||||||
|
openMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
function showTemp(){
|
||||||
|
tempMode="showTemp";
|
||||||
|
setButton2();
|
||||||
|
tempLO=new Layout({
|
||||||
|
type:"v",c:[
|
||||||
|
{type:"h",c:[
|
||||||
|
{type:"txt",pad:5,col:"#f77",font:"6x8:2",label:" ",id:"lab1"},
|
||||||
|
{type:"txt",pad:5,col:"#77f",font:"6x8:2",label:" ",id:"lab2"}
|
||||||
|
]},
|
||||||
|
{type:"h",c:[
|
||||||
|
{type:"txt",pad:5,col:"#f77",font:"6x8:2",label:" ",id:"lab3"},
|
||||||
|
{type:"txt",pad:5,col:"#77f",font:"6x8:2",label:" ",id:"lab4"}
|
||||||
|
]},
|
||||||
|
{type:"h",c:[
|
||||||
|
{type:"txt",pad:5,col:"#f00",font:"6x8:2",label:" ",id:"lab5"},
|
||||||
|
{type:"txt",pad:5,col:"#00f",font:"6x8:2",label:" ",id:"lab6"}
|
||||||
|
]},
|
||||||
|
{type:"h",c:[
|
||||||
|
{type:"btn",pad:2,font:"6x8:2",label:"Temp",cb:l=>getTemp()},
|
||||||
|
{type:"btn",pad:2,font:"6x8:2",label:"Exit",cb:l=>exit()}
|
||||||
|
]}
|
||||||
|
]
|
||||||
|
},{lazy:true});
|
||||||
|
tempLO.render();
|
||||||
|
getTemp();
|
||||||
|
}
|
||||||
|
|
||||||
|
var menu={
|
||||||
|
"":{
|
||||||
|
"title":" Temp. Graph"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Widgets":{
|
||||||
|
value:widsOn,
|
||||||
|
format:vis=>vis?"Hide":"Show",
|
||||||
|
onchange:vis=>{
|
||||||
|
widsOn=vis;
|
||||||
|
refreshMenu();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"Duration":{
|
||||||
|
value:times.indexOf(duration),
|
||||||
|
min:0,max:times.length-1,step:1,wrap:true,
|
||||||
|
format:tim=>times[tim],
|
||||||
|
onchange:(dur)=>{
|
||||||
|
duration=times[dur];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"Draw Graph":function(){
|
||||||
|
E.showMenu();
|
||||||
|
drawGraph();
|
||||||
|
},
|
||||||
|
|
||||||
|
"Show Graph" : function(){
|
||||||
|
E.showMenu();
|
||||||
|
if(graph.length>0){
|
||||||
|
showGraph();
|
||||||
|
}else{
|
||||||
|
message("No graph to\nshow as no\ngraph has been\ndrawn yet.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"Save Graph" : function(){
|
||||||
|
E.showMenu();
|
||||||
|
if(graph.length>0){
|
||||||
|
saveGraph();
|
||||||
|
}else{
|
||||||
|
message("No graph to\nsave as no\ngraph has been\ndrawn yet.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"Save Data" : function(){
|
||||||
|
E.showMenu();
|
||||||
|
if(graph.length>0){
|
||||||
|
saveData();
|
||||||
|
}else{
|
||||||
|
message("No data to\nsave as no\ngraph has been\ndrawn yet.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"Show Temp":function(){
|
||||||
|
E.showMenu();
|
||||||
|
showTemp();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
openMenu();
|
Loading…
Reference in New Issue