mirror of https://github.com/espruino/BangleApps
Add Espruino terminal - to allow communications with Espruino devices via terminal
parent
da31affbea
commit
1369047259
|
@ -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.
|
* 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
|
* 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
|
* data is used to clean up files when the app is uninstalled
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"version": "0.01",
|
"version": "0.01",
|
||||||
"description": "Send commands to other Espruino devices via the Bluetooth UART interface. Customisable commands!",
|
"description": "Send commands to other Espruino devices via the Bluetooth UART interface. Customisable commands!",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"tags": "",
|
"tags": "tool,bluetooth",
|
||||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"custom": "custom.html",
|
"custom": "custom.html",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
0.01: New App!
|
|
@ -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.
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwwcCpMkyQC/AVW//4AK/oR/COD8LCP4R/CK8DCKNsCKFt2BHPhu2CJ8BCKAjQI4OQNaIUB23bsCPMCJzp/CP4Rf/4AKCKwC/AVIA=="))
|
|
@ -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();
|
|
@ -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);"}
|
||||||
|
]
|
Binary file not shown.
After Width: | Height: | Size: 523 B |
|
@ -0,0 +1,104 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="../../css/spectre.min.css">
|
||||||
|
<link rel="stylesheet" href="../../css/spectre-exp.min.css">
|
||||||
|
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
|
||||||
|
<style>
|
||||||
|
.badgeerror[data-badge]::after { background-color: red; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>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.</p>
|
||||||
|
<div style="overflow-x:scroll">
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Command</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="tbody">
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<p><button id="save" class="btn btn-primary">Save to Bangle.js</button></p>
|
||||||
|
|
||||||
|
<script src="../../core/lib/interface.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var options;
|
||||||
|
setDefaults();
|
||||||
|
|
||||||
|
function setDefaults() {
|
||||||
|
options = [
|
||||||
|
{title:"Version", cmd:"process.env.VERSION"},
|
||||||
|
{title:"Battery", cmd:"E.getBattery()"},
|
||||||
|
{title:"Flash LED", cmd:"LED.set();setTimeout(()=>LED.reset(),1000);"}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
var tbody = document.getElementById("tbody");
|
||||||
|
tbody.innerHTML = "";
|
||||||
|
options.forEach((option,idx)=>{
|
||||||
|
var tr = document.createElement("tr");
|
||||||
|
tr.innerHTML = `
|
||||||
|
<td><input type="text" name="title"></td>
|
||||||
|
<td><input type="text" name="command"></td>
|
||||||
|
<td><button class="btn btn-action"><i class="icon icon-delete"></i></button></td>
|
||||||
|
`;
|
||||||
|
var titleInput = tr.children[0].firstChild;
|
||||||
|
titleInput.value = option.title;
|
||||||
|
titleInput.addEventListener("change", function(e) {
|
||||||
|
option.title = titleInput.value;
|
||||||
|
});
|
||||||
|
var cmdInput = tr.children[1].firstChild;
|
||||||
|
cmdInput.value = option.cmd;
|
||||||
|
cmdInput.addEventListener("change", function(e) {
|
||||||
|
option.cmd = cmdInput.value;
|
||||||
|
});
|
||||||
|
tr.children[2].firstChild.addEventListener("click", function() {
|
||||||
|
options.splice(idx,1);
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
tbody.appendChild(tr);
|
||||||
|
});
|
||||||
|
var tr = document.createElement("tr");
|
||||||
|
tr.innerHTML = `
|
||||||
|
<td><button class="btn">Reset to Defaults</button></td>
|
||||||
|
<td></td>
|
||||||
|
<td><button class="btn btn-action"><i class="icon icon-plus"></i></button></td>
|
||||||
|
`;
|
||||||
|
tr.children[0].firstChild.addEventListener("click", function() {
|
||||||
|
setDefaults();
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
tr.children[2].firstChild.addEventListener("click", function() {
|
||||||
|
options.push({"title":"",cmd:""});
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
tbody.appendChild(tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onInit() {
|
||||||
|
Util.showModal("Loading...");
|
||||||
|
Util.readStorage("espruinoterm.json", function(j) {
|
||||||
|
Util.hideModal();
|
||||||
|
try {
|
||||||
|
options = JSON.parse(j);
|
||||||
|
} catch (e) {}
|
||||||
|
if (!Array.isArray(options)) setDefaults();
|
||||||
|
refresh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
refresh();
|
||||||
|
document.getElementById("save").addEventListener("click", function() {
|
||||||
|
Util.showModal("Saving...");
|
||||||
|
Util.writeStorage("espruinoterm.json", JSON.stringify(options), function() {
|
||||||
|
Util.hideModal();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -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"}
|
||||||
|
]
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
|
@ -6,10 +6,11 @@
|
||||||
"type":"textinput",
|
"type":"textinput",
|
||||||
"tags": "keyboard",
|
"tags": "keyboard",
|
||||||
"supports" : ["BANGLEJS2"],
|
"supports" : ["BANGLEJS2"],
|
||||||
"screenshots": [{"url":"screenshot.png"}],
|
"screenshots": [{"url":"screenshot.png"}],
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"textinput","url":"lib.js"},
|
{"name":"textinput","url":"lib.js"},
|
||||||
{"name":"kbtouch.settings.js","url":"settings.js"}
|
{"name":"kbtouch.settings.js","url":"settings.js"}
|
||||||
]
|
],
|
||||||
|
"sortorder":-1
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue