From 1369047259d789e4a7e63210f7df3b1d3e206d6e Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Tue, 19 Jul 2022 12:19:40 +0100 Subject: [PATCH] Add Espruino terminal - to allow communications with Espruino devices via terminal --- README.md | 2 +- apps/espruinoctrl/metadata.json | 2 +- apps/espruinoterm/ChangeLog | 1 + apps/espruinoterm/README.md | 22 +++++++ apps/espruinoterm/app-icon.js | 1 + apps/espruinoterm/app.js | 101 ++++++++++++++++++++++++++++++ apps/espruinoterm/app.json | 5 ++ apps/espruinoterm/app.png | Bin 0 -> 523 bytes apps/espruinoterm/interface.html | 104 +++++++++++++++++++++++++++++++ apps/espruinoterm/metadata.json | 20 ++++++ apps/espruinoterm/screenshot.png | Bin 0 -> 2223 bytes apps/kbtouch/metadata.json | 5 +- 12 files changed, 259 insertions(+), 4 deletions(-) create mode 100644 apps/espruinoterm/ChangeLog create mode 100644 apps/espruinoterm/README.md create mode 100644 apps/espruinoterm/app-icon.js create mode 100644 apps/espruinoterm/app.js create mode 100644 apps/espruinoterm/app.json create mode 100644 apps/espruinoterm/app.png create mode 100644 apps/espruinoterm/interface.html create mode 100644 apps/espruinoterm/metadata.json create mode 100644 apps/espruinoterm/screenshot.png diff --git a/README.md b/README.md index ea485da86..d2f7022e9 100644 --- a/README.md +++ b/README.md @@ -324,7 +324,7 @@ and which gives information about the app for the Launcher. ``` * name, icon and description present the app in the app loader. -* tags is used for grouping apps in the library, separate multiple entries by comma. Known tags are `tool`, `system`, `clock`, `game`, `sound`, `gps`, `widget`, `launcher` or empty. +* tags is used for grouping apps in the library, separate multiple entries by comma. Known tags are `tool`, `system`, `clock`, `game`, `sound`, `gps`, `widget`, `launcher`, `bluetooth` or empty. * storage is used to identify the app files and how to handle them * data is used to clean up files when the app is uninstalled diff --git a/apps/espruinoctrl/metadata.json b/apps/espruinoctrl/metadata.json index 253307fa0..5107bc6ae 100644 --- a/apps/espruinoctrl/metadata.json +++ b/apps/espruinoctrl/metadata.json @@ -5,7 +5,7 @@ "version": "0.01", "description": "Send commands to other Espruino devices via the Bluetooth UART interface. Customisable commands!", "icon": "app.png", - "tags": "", + "tags": "tool,bluetooth", "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "custom": "custom.html", diff --git a/apps/espruinoterm/ChangeLog b/apps/espruinoterm/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/espruinoterm/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/espruinoterm/README.md b/apps/espruinoterm/README.md new file mode 100644 index 000000000..df26d59a0 --- /dev/null +++ b/apps/espruinoterm/README.md @@ -0,0 +1,22 @@ +# Espruino Terminal + +Send commands to other Espruino devices via the Bluetooth UART interface and +see the result on a terminal. + +## Customising + +Once installed and you're connected to the Bangle you can click the button next to the app in the app loader +to change the commands (they will be read from the device). + +When done, click `Save to Bangle.js` and your changes will be saved to the same device. + +## Usage + +* Load the app and after a few seconds you'll see a menu with Espruino devices +in the vicinity. +* Tap on the device you want to connect to +* A terminal will pop up showing `Connecting...` and then `Connected` +* Now tap on the right (or press the button) to bring up a menu with options for commands, or the option to disconnect. + +You can also choose `Custom` in which case a keyboard (using the currently installed text input method) will +be displayed and you can enter the command you would like to send. diff --git a/apps/espruinoterm/app-icon.js b/apps/espruinoterm/app-icon.js new file mode 100644 index 000000000..f566aedf7 --- /dev/null +++ b/apps/espruinoterm/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwcCpMkyQC/AVW//4AK/oR/COD8LCP4R/CK8DCKNsCKFt2BHPhu2CJ8BCKAjQI4OQNaIUB23bsCPMCJzp/CP4Rf/4AKCKwC/AVIA==")) diff --git a/apps/espruinoterm/app.js b/apps/espruinoterm/app.js new file mode 100644 index 000000000..348190db4 --- /dev/null +++ b/apps/espruinoterm/app.js @@ -0,0 +1,101 @@ +var uart; // require("ble_uart") +var device; // BluetoothDevice +var customCommand = ""; +// Set up terminal +Bangle.loadWidgets(); +var R = Bangle.appRect; +var termg = Graphics.createArrayBuffer(R.w, R.h, 1, {msb:true}); +var termVisible = false; +termg.setFont("6x8"); +term = require("VT100").connect(termg, { + charWidth : 6, + charHeight : 8 +}); +term.print = str => { + for (var i of str) term.char(i); + if (termVisible) g.reset().drawImage(termg,R.x,R.y).setFont("6x8").setFontAlign(0,-1,1).drawString("MORE",R.w-1,(R.y+R.y2)/2); +}; + +function showConnectMenu() { + termVisible = false; + var m = { "" : {title:"Devices"} }; + E.showMessage("Scanning..."); + NRF.findDevices(devices => { + devices.forEach(dev=>{ + m[dev.name||dev.id.substr(0,17)] = ()=>{ + connectTo(dev); + }; + }); + m["< Back"] = () => showConnectMenu(); + E.showMenu(m); + },{filters:[ + { namePrefix: 'Puck.js' }, + { namePrefix: 'Pixl.js' }, + { namePrefix: 'MDBT42Q' }, + { namePrefix: 'Bangle.js' }, + { namePrefix: 'Espruino' }, + { services: [ "6e400001-b5a3-f393-e0a9-e50e24dcca9e" ] } + ],active:true,timeout:4000}); +} + +function showOptionsMenu() { + if (!uart) showConnectMenu(); + termVisible = false; + var menu = {"":{title:/*LANG*/"Options"}, + "< Back" : () => showTerminal(), + }; + var json = require("Storage").readJSON("espruinoterm.json",1); + if (Array.isArray(json)) { + json.forEach(j => { menu[j.title] = () => sendCommand(j.cmd); }); + } else { + Object.assign(menu,{ + "Version" : () => sendCommand("process.env.VERSION"), + "Battery" : () => sendCommand("E.getBattery()"), + "Flash LED" : () => sendCommand("LED.set();setTimeout(()=>LED.reset(),1000);") + }); + } + menu[/*LANG*/"Custom"] = () => { require("textinput").input({text:customCommand}).then(result => { + customCommand = result; + sendCommand(customCommand); + })}; + menu[/*LANG*/"Disconnect"] = () => { showTerminal(); term.print("\r\nDisconnecting...\r\n"); uart.disconnect(); } + + E.showMenu(menu); +} + +function showTerminal() { + E.showMenu(); + Bangle.setUI({ + mode : "custom", + btn : n=> { showOptionsMenu(); }, + touch : (n,e) => { if (n==2) showOptionsMenu(); } + }); + termVisible = true; + term.print(""); // redraw terminal +} + +function sendCommand(cmd) { + showTerminal(); + uart.write(cmd+"\n"); +} + +function connectTo(dev) { + device = dev; + showTerminal(); + term.print(`\r\nConnect to ${dev.name||dev.id.substr(0,17)}...\r\n`); + device.on('gattserverdisconnected', function(reason) { + term.print(`\r\nDISCONNECTED (${reason})\r\n`); + uart = undefined; + device = undefined; + setTimeout(showConnectMenu, 1000); + }); + require("ble_uart").connect(device).then(function(u) { + uart = u; + term.print("Connected...\r\n"); + uart.on('data', function(d) { term.print(d); }); + }); +} + +// now start +Bangle.drawWidgets(); +showConnectMenu(); diff --git a/apps/espruinoterm/app.json b/apps/espruinoterm/app.json new file mode 100644 index 000000000..72a12e635 --- /dev/null +++ b/apps/espruinoterm/app.json @@ -0,0 +1,5 @@ +[ + {"title":"Version", "cmd":"process.env.VERSION"}, + {"title":"Battery", "cmd":"E.getBattery()"}, + {"title":"Flash LED", "cmd":"LED.set();setTimeout(()=>LED.reset(),1000);"} +] diff --git a/apps/espruinoterm/app.png b/apps/espruinoterm/app.png new file mode 100644 index 0000000000000000000000000000000000000000..e9a8c375895d49180b68b170ca01cfd1860595de GIT binary patch literal 523 zcmV+m0`&cfP)|+wTBP*eLoGzeMHGqnhnz(51*j-U54Pf=P)vWbS)_t-WX;Q=%!*KZW{+q?7a2lYl1 zGjWzn=J|itvU!~V0QE)-yXWw|(R5wQ=3Br_#EIxS=DE1*S~jms>0WmFY-?3Pe6_g09n<%k#VXl*3{H3?r;;fd~~iIe(MmOUr0K8!#E;VDT31XO*zB z1tNBd9S7spYhr~PL~6SL^pY3C$Q77a0ZpTmzec3p!+7yBlwd|gfiXx%Qx^C}aiGMZ)mHUIVTU7+Wjx_ouu3_=B>Z{Bij zbq)P%P2@2`gbJKkxa~O?d9y){_ou`tPz7XD1!PkNWK%zP6-80T+aGf$aGZ;X%((yn N002ovPDHLkV1l1*_P785 literal 0 HcmV?d00001 diff --git a/apps/espruinoterm/interface.html b/apps/espruinoterm/interface.html new file mode 100644 index 000000000..660b3a86c --- /dev/null +++ b/apps/espruinoterm/interface.html @@ -0,0 +1,104 @@ + + + + + + + + +

Enter the menu items you'd like to see appear in the app below. When finished, click `Save to Bangle.js` to save the JavaScript back.

+
+ + + + + + + + + + +
TitleCommand
+
+

+ + + + + + diff --git a/apps/espruinoterm/metadata.json b/apps/espruinoterm/metadata.json new file mode 100644 index 000000000..25e6183e1 --- /dev/null +++ b/apps/espruinoterm/metadata.json @@ -0,0 +1,20 @@ +{ + "id": "espruinoterm", + "name": "Espruino Terminal", + "shortName": "Espruino Term", + "version": "0.01", + "description": "Send commands to other Espruino devices via the Bluetooth UART interface, and see the result on a VT100 terminal. Customisable commands!", + "icon": "app.png", + "screenshots": [{"url":"screenshot.png"}], + "tags": "tool,bluetooth", + "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", + "interface": "interface.html", + "dependencies": {"textinput":"type"}, + "storage": [ + {"name":"espruinoterm.app.js","url":"app.js"}, + {"name":"espruinoterm.img","url":"app-icon.js","evaluate":true} + ],"data": [ + {"name":"espruinoterm.json","url":"app.json"} + ] +} diff --git a/apps/espruinoterm/screenshot.png b/apps/espruinoterm/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..cce881a378eff5c194a0871b6b94460c9feffb4c GIT binary patch literal 2223 zcmeHJc~BDi7XE=kNow7c5+m2l?WOiiEw5;qNrh=*E=YN8Lvtgy0^A^PCZ%RKg|u9* zqIOFnQ-o5BrjjzsToN-}Leq#yd=_q*&-d4xdGr2x|GzVH&NuVTnKSd9GxN=19`wiR zA&e0K0KI*Ceelb8_g}dZzFc{Nv4~}WB;&E(;LdBb0)UmL_WA5OM2S$9eJHIq)7?`y zx%8&-x0YBo9?CqIH1&n|&emHvW3)AFVrpSIo_HCq2_Auns$Op~(Tq;bmL9d0Le+9J ziBnttvp)VqZ7y;NKAk}4KKAAAeQiR9kA^bM57fHkLMTY_`s-qY5o;mWuN86_caD0U z1lOdLe%=^gk%q*04rFe1-BjBM`JvkkpZZlx+JRVNwSTqpF)WNu1FT5(!9rWn@|f8| z30k(BfzN@BT)c;M&RpH|X*7s|KBidiyxXN>sL(KcZnayYmot}v)k3M3&#gDSE+^^#0{1bAYjd{G<#R-`v%-x`AT=2Z=j7Pv7E^@$mh?Y0!We;i7fY7u5lu)p*blSs7Yhb~2@M^s{Hd7y=6u%0kVbv&wY z->w>N^t_`J`RsvP_DAcY;CavY>$>wDp zz0&8Bo7IM&n&Fx7Xl@`bbs(IS_wDMr`5*7*3nJ#<*=$wJq{C{rRF^rzEbZ)0+lt!y z>eAS@ZMxGAQM7!l*Amj`jKRb&J80FU?^G*MXo0GW^4)d(fUNvWShzAgb~K!L`$1%} z0)JKWu+D;4%317{|5f}+6D@Q<-8K<5^z^N(-u_*b+iOm>SfYe)JI~0+=x^l`G8A_? zgVtUH?cNa7;+1T_qZAV!8Aj+{6;}QNclTq@w;N_eub~19^AI2;U&|0Rgvafj{Furm7!pI%zRaK(2H&4;Mkz^&vbIyM)0FCq4Ao%Q%1| z7G3GnCN&dEP}_Op@zV(gA2uhr;wF&+$vTOSJFam{p`d=;Xe!et(sOm5zfEQ3PJv^p zogd3c8dRxdyGyTLK)t%NQyPkUKS>oUk4SgqQMCl4_v!4BnxNh6}bLW6HIr6d4ZkS=3gO_ zp{D%cWU&i%(^qLXS?h=fehzxl%Fhci&;cm8+nnX|TOi%ViSl3N{-6Ah`~NQsQLku- X*+mIcB9oRs5U_8Lzt0`-$aDV$whsFx literal 0 HcmV?d00001 diff --git a/apps/kbtouch/metadata.json b/apps/kbtouch/metadata.json index f6d6d5228..89d121d63 100644 --- a/apps/kbtouch/metadata.json +++ b/apps/kbtouch/metadata.json @@ -6,10 +6,11 @@ "type":"textinput", "tags": "keyboard", "supports" : ["BANGLEJS2"], - "screenshots": [{"url":"screenshot.png"}], + "screenshots": [{"url":"screenshot.png"}], "readme": "README.md", "storage": [ {"name":"textinput","url":"lib.js"}, {"name":"kbtouch.settings.js","url":"settings.js"} - ] + ], + "sortorder":-1 }