diff --git a/apps/tempmonitor/ChangeLog b/apps/tempmonitor/ChangeLog index 99fe6a77d..af69e6e0a 100644 --- a/apps/tempmonitor/ChangeLog +++ b/apps/tempmonitor/ChangeLog @@ -1,2 +1,3 @@ 0.01: 1st version: saves values to csv 0.02: added HTML interface +0.03: Added Stop/start recording, change BG color, filesize info diff --git a/apps/tempmonitor/README.md b/apps/tempmonitor/README.md index a956f0e0f..21b570af9 100644 --- a/apps/tempmonitor/README.md +++ b/apps/tempmonitor/README.md @@ -9,6 +9,12 @@ Bangle JS1 ![](photo_banglejs1.jpg) +UI for bangleJS1 +![](bangle.js_UI.png) + +UI for bangleJS2 +![](bangle.js2_UI.png) + Screenshot BJS2 ![](ss_emul_bjs2.png) @@ -33,15 +39,31 @@ Download the CSV file and process in your favourite spreadsheet software ## Features -Colours, all inputs , graph, widgets loaded -Counter for Times Display +- Cross compatibility (JS1,JS2) and widgets compatibility +- BG/FG Colour, Export to file and counter of saved records per session +- File operations: Info, delete (no yet) +## Pending/future Features +- Buttons layout: btn txt(BJS1) , on screen button (BJS2) +- Long press touch to delete file (BJS1,BJS2) +- File operations: Delete -## Controls - -exit: left side +## Controls/UI + - Left area: Back/Exit/launcher + - BTN3 (long press)(BJS1): default Exit/kill app + - BTN1 (BJS2): "Launcher" / open "Messages" + - BTN2 (BJS1): "Launcher" / open "Messages" + - BTN1 (BJS1): Change FG Color + - BTN3 (BJS1): Change BG Color + - Right area: Change FG Color + - Swipe left: Change BG Color + - Swipe right: Increase/Decrease Hour circle/Points + + ## Creator -Daniel Perez \ No newline at end of file +Daniel Perez +For suggestions or feedback +https://github.com/dapgo/my_espruino_smartwatch_things \ No newline at end of file diff --git a/apps/tempmonitor/bangle.js2_UI.png b/apps/tempmonitor/bangle.js2_UI.png new file mode 100644 index 000000000..ecfc31da8 Binary files /dev/null and b/apps/tempmonitor/bangle.js2_UI.png differ diff --git a/apps/tempmonitor/bangle.js_UI.png b/apps/tempmonitor/bangle.js_UI.png new file mode 100644 index 000000000..4b114b72c Binary files /dev/null and b/apps/tempmonitor/bangle.js_UI.png differ diff --git a/apps/tempmonitor/metadata.json b/apps/tempmonitor/metadata.json index dafb70f27..45d4d2c35 100644 --- a/apps/tempmonitor/metadata.json +++ b/apps/tempmonitor/metadata.json @@ -1,7 +1,7 @@ { "id": "tempmonitor", "name": "Temperature monitor", - "version": "0.02", + "version": "0.03", "description": "Displays the current temperature and stores in a CSV file", "icon": "app.png", "tags": "tool", diff --git a/apps/tempmonitor/tempmonitor.app.js b/apps/tempmonitor/tempmonitor.app.js index 62a4fee67..fd541f7cd 100644 --- a/apps/tempmonitor/tempmonitor.app.js +++ b/apps/tempmonitor/tempmonitor.app.js @@ -1,42 +1,69 @@ // Temperature monitor that saves a log of measures // standalone ver for developer, to remove testing lines // delimiter ; (excel) or , (oldscool) +/* REFACTOR and remove commented code related to +SetUI, Layout, and setWatch( function(b) { }, BTN1, { repeat: true, edge:'falling' }) +*/ { -var v_mode_debug=0; //, 0=no, 1 min, 2 prone detail +var v_mode_debug=2; //, 0=no, 1 min, 2 prone detail //var required for drawing with dynamic screen var rect = Bangle.appRect; var history = []; -var readFreq=5000; //ms //PEND add to settings -var saveFreq=60000; //ms 1min +var readFreq=4000; //ms //PEND add to settings +if (v_mode_debug>0) var saveFreq=6000; //ms for testin 6sec +else var saveFreq=60000; //ms 1min var v_saveToFile= new Boolean(true); //true save //false //with upload file º is not displayed properly //with upload RAM º is displayed var v_t_symbol="";//ºC var v_saved_entries=0; -var filename ="temphistory.csv"; +var v_filename ="temphistory.csv"; var lastMeasure = new String(); var v_model=process.env.BOARD; +var v_color_erase=g.getBgColor(); //original BG color overwritten on SetVariables +var v_color=g.getColor();//original FG color +var id_rec_intv; //var for the recording interval +if (readFreq>saveFreq) console.log("Read refresh freq should be higher than saving"); +if (v_mode_debug>0) console.log("original BG/FG color="+v_color_erase+" / "+v_color); + + + +function SetVariables(){ //EMSCRIPTEN,EMSCRIPTEN2 if (v_model=='BANGLEJS'||v_model=='EMSCRIPTEN') { v_font_size1=16; - v_font_size2=60; - //g.setColor("#0ff"); //light color + v_font_size2=50; }else{ - v_font_size1=11; - v_font_size2=40; - //g.setColor("#000"); //black or dark + //Banglejs2 or others + v_font_size1=11; //too small? + v_font_size2=40; } + //overwriting default BG, is better detect? + if (g.theme.dark==1) v_color_erase=0x0000; //dynamic; //bg black + else if (g.theme.dark==0) v_color_erase=0xFFFF; //dynamic; //bg white +} -function onTemperature(v_temp) { - if (v_mode_debug>1) console.log("v_temp in "+v_temp); +//print result +function printTemperature(v_temp) { + if (v_mode_debug>1) console.log("v_temp in "+v_temp+" entries "+v_saved_entries); ClearBox(); //g.setFont("6x8",2).setFontAlign(0,0); g.setFontVector(v_font_size1).setFontAlign(0,0); - var x = (rect.x+rect.x2)/2; + var x = (rect.x+(rect.x2-60))/2;//-60 space for graph and layout buttons var y = (rect.y+rect.y2)/2 + 20; - g.drawString("Records: "+v_saved_entries, x, rect.y+35); - g.drawString("Temperature:", x, rect.y+37+v_font_size1); + + if (v_saveToFile==true) { + // if (v_mode_debug>0) console.log("prev color="+v_color); + printInfo("Recording : "+v_saved_entries, '#CC3333',x,rect.y+30); + //g.setColor('#CC3333'); //red + // g.drawString("Recording : "+v_saved_entries, x, rect.y+35); + //g.setColor(v_color);//restore default color + } + else printInfo("Rec paused : "+v_saved_entries, v_color,x,rect.y+30); + //else g.drawString("Rec paused : "+v_saved_entries, x, rect.y+35); + //space for printing info + g.drawString("Temperature:", x, rect.y+45+(v_font_size1*2)); //dynamic font (g.getWidth() > 200 ? 60 : 40) g.setFontVector(v_font_size2).setFontAlign(0,0); // Avg of temperature readings @@ -48,34 +75,69 @@ function onTemperature(v_temp) { lastMeasure=avrTemp.toString(); if (lastMeasure.length>4) lastMeasure=lastMeasure.substr(0,4); //DRAW temperature in the center - g.drawString(" ", x-20, y); - g.drawString(v_temp+v_t_symbol, x-20, y); + //remove g.drawString(" ", x-20, y); + g.drawString(v_temp+v_t_symbol, x, y); g.flip(); } // from: BJS2 pressure sensor, BJS1 inbuilt thermistor -function drawTemperature() { +function getTemperature() { if(v_model.substr(0,10)!='EMSCRIPTEN'){ if (Bangle.getPressure) { - Bangle.getPressure().then(p =>{if (p) onTemperature(p);}); - } else onTemperature(E.getTemperature()); + Bangle.getPressure().then(p =>{if (p) printTemperature(p);}); + } else printTemperature(E.getTemperature()); } - else onTemperature(11);//fake temp for emulators + else printTemperature(11.25);//fake temperature medition for emulators } -function saveToFile() { +/* Note that it changes BG and also FG to an opposite*/ +function changeBGcolor(){ + //pend to refactor + if (v_mode_debug>1) console.log("before BG/FG "+v_color_erase+" /"+v_color); + v_color_erase=0xFFFF-v_color_erase; + v_color=0xFFFF-v_color; + if (v_mode_debug>1) console.log("after result BG/FG "+v_color_erase+" /"+v_color); + //g.setColor(color_result); + g.setBgColor(v_color_erase);// 0 white, 1 black + g.setColor(v_color); + //move to event? + ClearScreen(); + ClearBox(); + drawGraph(); + getTemperature(); + //setDrawLayout(); //uncomment if layout can work with setUI + //g.clear();//impact on widgets +} + +function saveToFile(){ //input global vars: lastMeasure var a=new Date(); var strlastSaveTime=new String(); strlastSaveTime=a.toISOString(); //strlastSaveTime=strlastSaveTime.concat(a.getFullYear(),a.getMonth()+1,a.getDate(),a.getHours(),a.getMinutes());; - if (v_mode_debug==1) console.log("saving="+strlastSaveTime+";"+a.getHours()+":"+a.getMinutes()+";"+lastMeasure); + if (v_mode_debug>1) console.log("saving="+strlastSaveTime+";"+a.getHours()+":"+a.getMinutes()+";"+lastMeasure); if (v_saveToFile==true){ - //write(strlastSaveTime+";"+ - require("Storage").open(filename,"a").write((a.getMonth()+1)+";"+a.getDate()+";"+a.getHours()+":"+a.getMinutes()+";"+lastMeasure+"\n"); - //(getTime()+","); - v_saved_entries=v_saved_entries+1; + //write(strlastSaveTime+";"+ + //var f = require("Storage").open(v_filename,"r"); + // f=require("Storage").read(v_filename+"\1");//suffix required load completely!! + //note that .read uses Storage Class .open uses StorageFile Class , difference in file chunks + // if (v_mode_debug>0) console.log("f "+f); + var f = require("Storage").open(v_filename,"r"); + if ((v_mode_debug>0) && (v_saved_entries==0)) console.log("file info:"+f); + if (f.len>0) { + if (!f) { + require("Storage").open(v_filename,"w").write("Month;Day;Time;Temp"+"\n"); + if (v_mode_debug>0) console.log("not exist but created "+f); + } + else{ + require("Storage").open(v_filename,"a").write((a.getMonth()+1)+";"+a.getDate()+";"+a.getHours()+":"+a.getMinutes()+";"+lastMeasure+"\n"); + //(getTime()+","); + v_saved_entries=v_saved_entries+1; + if (v_mode_debug>1) console.log("append to already exist "+f.name+" , "+v_saved_entries); + }; + } } -} + else if (v_mode_debug>0) console.log("recording mode stopped"); +}; function drawGraph(){ var img_obj_thermo = { @@ -83,17 +145,19 @@ function drawGraph(){ transparent : 0, buffer : require("heatshrink").decompress(atob("AEFt2AMKm3bsAMJjdt23ABhEB+/7tgaJ///DRUP//7tuADRP923YDRXbDRfymwaJhu/koaK7eyiwaK3cLDRlWDRY1NKBY1Ztu5kjmJg3cyVI7YMHgdu5Mkyu2fxHkyVJjdgDRFJkmRDRPsDQNbDQ5QBGoONKBJrBoxQIQwO2eRcbtu24AMIFIQLJAH4AMA==")) }; - g.drawImage(img_obj_thermo,rect.x2-50,rect.y2/2); + g.drawImage(img_obj_thermo,rect.x2-60,rect.y2/2); g.flip(); } function ClearScreen(){ //avoid widget areas - g.reset(1).clearRect(rect.x, rect.y+24, rect.x2, rect.y2-24); + g.setBgColor(v_color_erase); + g.clearRect(rect.x, rect.y+24, rect.x2, rect.y2-24); g.flip(); } function ClearBox(){ //custom boxarea , left space for static graph at right - g.reset(1).clearRect(rect.x, rect.y+24, rect.x2-50, rect.y2-24); + g.setBgColor(v_color_erase); + g.clearRect(rect.x, rect.y+24, rect.x2-60, rect.y2-24); g.flip(); } function introPage(){ @@ -109,30 +173,139 @@ function introPage(){ g.drawString("Read freq(ms): "+readFreq, x, y ); g.drawString("Save to file: "+v_saveToFile, x, y+ ((v_font_size1*1)+2) ); g.drawString("Save freq(ms):"+saveFreq, x, y+((v_font_size1*2)+2) ); - fr=require("Storage").read(filename+"\1");//suffix required - if (fr) g.drawString("Current filesize:"+fr.length.toString()+"kb", x, y+((v_font_size1*3)+2) ); + fr=require("Storage").read(v_filename+"\1");//suffix required + if (fr) g.drawString("Filesize:"+fr.length.toString()+"kb", x, y+((v_font_size1*3)+2) ); else g.drawString("File not exist", x, y+((v_font_size1*3)+2)); } +function printInfo(pmsg, pcolor,px,py){ + g.setColor(pcolor); + g.setFontVector(v_font_size1).setFontAlign(0,0); + g.drawString(pmsg, px,py+v_font_size1); + g.setColor(v_color);//restore default color +} +function toggleRecMode(duration, exectime){ + //bydefault float, standard epoch requires *1000 + if (v_mode_debug>0) console.log("duration"+duration); + if (duration>2) { //delete file + var x = (rect.x+(rect.x2-60))/2; + printInfo("Deleting file",'#CC3333',x, rect.y+32+v_font_size1); + // g.setColor('#CC3333'); //red + + //too long "Deleting file: "+v_filename, + // for StorageFiles created with require("Storage").open(filename, ...) + //require("Storage").erase(v_filename); + //TODO refactor in a new function + //var mifile = require("Storage").open(v_filename,"w"); + var mifile = require("Storage").open("temphistory.csv","w"); + var v_output=mifile.erase(); + //mifile.StorageFile.erase(); + if (v_mode_debug>0) console.log("output"+v_output); + setTimeout(function() { if (v_mode_debug>0) console.log("pause for 1 sec");},1000); + return; //leave this function + } + if (v_saveToFile) v_saveToFile=false; + else v_saveToFile=true; + if (v_mode_debug>0) console.log("recording? "+v_saveToFile); + setRecordingFreq(); +} + +function setRecordingFreq(){ + if (v_saveToFile==true) { //TODO now start on false btn will no enable + id_rec_intv=setInterval(function() { + saveToFile(); + }, saveFreq); //ms + if (v_mode_debug>0) console.log("interval id / frq"+id_rec_intv+" / "+saveFreq); + } + else if (id_rec_intv){ + clearInterval(id_rec_intv); + if (v_mode_debug>0) console.log("rec interval removed, id "+id_rec_intv); + id_rec_intv=0; // to reset var + } +} + +function UserInput(){ + //theoretically incompatible with Layout + Bangle.setUI({ + mode : "custom", + //adds a back icon on top widget area + back : function() {load();}, + //touch : function(n,e) {}, // optional - handler for 'touch' events + // righ/Left 1/-1 , updown + swipe : function(dir_rl,dir_ud) { + if(dir_rl == 1) { + if (v_mode_debug>0) console.log("swipe right: "); + getFileInfo(v_filename); + } + else if (dir_rl == -1){ + if (v_mode_debug>0) console.log("swipe left: "); + changeBGcolor(); + } + }, + touch : function(tzone,tobj){ + if ((process.env.HWVERSION == 2)&&(v_mode_debug>0)){ + console.log("tobj x,y,type : "+tobj.x+" "+tobj.y+" "+tobj.type); + } + switch(tzone){ + //case 1: //left , back managed by setUI + case 2: // right disable/enable recording + toggleRecMode(0); //toggleRecMode(duration, exectime) + break; + // case 3: console.log("Touch 3 aka 1+2 not for BJS1 emul");//center 1+2 + // break; + } + }, + //inferior to + btn : function(btn) { + if(btn == 1) { + if (v_model=='BANGLEJS'||v_model=='EMSCRIPTEN') toggleRecMode(1); //console.log("btn1 BJS1"); + else mainBtnShortcut(); //console.log("btn1 BJS2"); + } + else if (btn == 2) mainBtnShortcut(); //console.log("btn2 BJS1"); + else if (btn == 3) changeBGcolor(); //console.log("btn3 BJS1"); + } + }); //endof setUI + + +function mainBtnShortcut() { + //if messages app installed shortcut otherwise default access to launcher + if (require("Storage").read("messagegui.app.js")===undefined) + { + if (require("Storage").read("messagelist.app.js")===undefined) Bangle.showLauncher(); // implies btn2(js1) btn(js2)- launcher + else if (v_model=='BANGLEJS'||v_model=='EMSCRIPTEN') load("messagelist.app.js"); + else load("messagelist.app.js"); + } + else if (v_model=='BANGLEJS'||v_model=='EMSCRIPTEN') load("messagegui.app.js"); + else load("messagegui.app.js"); + } + + +// Show file size +function getFileInfo(v_filename) { + var f = require("Storage").open(v_filename,"r"); + //todo refactor and reuse common code + g.setFontVector(v_font_size1).setFontAlign(0,0); + var x = (rect.x+(rect.x2-60))/2; + printInfo("file size:"+f.len,v_color,x, rect.y+32+v_font_size1); + // g.drawString("file size:"+f.len, x, rect.y+37+v_font_size1); + if (v_mode_debug>0) console.log("file "+v_filename+" size: "+f.len); +}// not used + + //MAIN +SetVariables(); Bangle.loadWidgets(); -Bangle.setUI({ - mode : "custom", - back : function() {load();} -}); ClearScreen(); introPage(); +//setDrawLayout(); //uncomment if layout can work with setUI + +UserInput(); //inc SetUI and back icon + setInterval(function() { - drawTemperature(); + getTemperature(); }, readFreq); //ms -if (v_saveToFile==true) { - setInterval(function() { - saveToFile(); - }, saveFreq); //ms -} -setTimeout(ClearScreen, 3500); -setTimeout(drawGraph,4000); -setTimeout(drawTemperature,4500); +setRecordingFreq(); + } \ No newline at end of file diff --git a/apps/tempmonitor/tempmonitor.info b/apps/tempmonitor/tempmonitor.info index 1824c5c86..f31704b57 100644 --- a/apps/tempmonitor/tempmonitor.info +++ b/apps/tempmonitor/tempmonitor.info @@ -1 +1 @@ -{"id":"tempmonitor","name":"tempmonitor","src":"tempmonitor.app.js","icon":"tempmonitor.img","version":"0.01","files":"tempmonitor.info,tempmonitor.app.js,tempmonitor.img"} \ No newline at end of file +{"id":"tempmonitor","name":"tempmonitor","src":"tempmonitor.app.js","icon":"tempmonitor.img","version":"0.03","files":"tempmonitor.info,tempmonitor.app.js,tempmonitor.img"} \ No newline at end of file