Closed jh3y closed 4 years ago
Hi! Argh, sorry about this. I believe it may have been fixed on GitHub but I hadn't published an updated package espruino
please could you try the latest now and see if it works?
There's some code here that might help you: https://www.espruino.com/Interfacing#node-js-javascript
The odd thing is that what you're doing looks fine. The only thing I can see that's different is that the example code I have there uses noble.stopScanning();
to stop scanning first, and that might affect you.
Also, if you're doing this just to use esp.expr
then you literally just need:
var esp = require("espruino");
esp.expr("aa:bb:cc:dd:ee:ff", "Bangle.buzz()", result => {
console.info(result)
});
The only thing is finding out the bangle's address - which you can get with espruino --list
edit: can confirm - code above works great (at least on Linux)
Hey @gfwilliams 👋
Thanks for coming back to me 👍 I have tried the latest and I get a little further.
espruino --list
doesn't display the watch. But I can still find the watch with noble
and connect to it but I can't use espruino.expr
with the address
from the noble
peripheral.
const esp = require("espruino")
let BANGLE
noble.startScanning()
noble.on("discover", peripheral => {
if (
peripheral.advertisement &&
peripheral.advertisement.localName &&
peripheral.advertisement.localName.includes("Bangle")
) {
// DISCOVERED BANGLE
BANGLE = peripheral
console.info('DISCOVERED PERIPHERAL', BANGLE.address)
noble.stopScanning()
// Try and connect to Bangle
esp.expr(BANGLE.address, "Bangle.buzz()", result => {
console.info(result)
})
}
})
I'll get an output like the following:
Port "e6-42-6b-7b-02-17" not found
Unable to connect!
I believe it's because (on Mac again?) the BLE address is formatted differently with dashes rather than colons. Try var addr = BANGLE.address.toString().replace('-',':');
Very odd about espruino --list
not working though - that's definitely with the new espruino NPM module? Does 'espruino --list --verbose' give any hints what is wrong?
Ahh 👍
I wasn't clear enough there, sorry. espruino --list
is working now. But the watch seems to be sporadically showing up 😅
I've tinkered further and got this where I can connect via the node
module 🙌
const start = () => {
const BANGLES = []
Espruino.Core.Serial.getPorts(ports => {
for (const port of ports) {
if (port.description && port.description.toLowerCase().includes("bangle"))
BANGLES.push(port)
}
console.info("AVAILABLE BANGLES", BANGLES)
if (BANGLES.length === 0) {
console.info("NO BANGLES FOUND, PLEASE TRY AGAIN")
process.exit(0)
}
const BANGLE = BANGLES[0]
// Once we have a bangle we can connect to it
Espruino.Core.Serial.open(BANGLE.path, info => {
console.info("CONNECTED TO BANGLE:", BANGLE, info)
})
})
}
esp.init(start)
What API functions do I need to use in order to package an app and upload it to the Bangle? I have code upload working using Core.CodeWriter.writeToEspruino
👍
I don't really see why using Espruino.Core.Serial.open
is somehow working for you when .expr
didn't - it's basically using exactly the same code in each case.
The sporadic appearance of Bangle.js is really strange though. You could try modifying https://github.com/espruino/EspruinoTools/blob/gh-pages/core/serial_noble.js#L83 to a higher timeout and see if that helps.
In terms of upload, assuming you can get it working you're best off just doing ./espruino -d Bangle yourcode.js
since this should be doing exactly what you are trying to do now (getPorts, find Bangle by name, then Serial.open). But if for some reason you want to reimplement it you're best off looking there to see what happens.
BUT direct app loading on Bangle.js isn't implemented in the tools yet. Basically you can upload to RAM (the default), or to 'boot code' which is where the bootloader is stored, but there's no support (yet) for uploading to a named file in Storage. That'll be coming very soon, but until then you basically just need to do this between getting the code to write and writing it:
code = 'require("Storage").write("appfile",'+JSON.stringify(code)+');\n'
That could be as easy as running:
espruino --board BANGLEJS myfile.js -o temp.js
# add require("Storage") to temp.js
espruino -d Bangle temp.js
The issue with that though is that I want to send the code from within a script, not by using the CLI app.
I've been able to do this and have code working 👍
Espruino.Core.Serial.open(BANGLE.path, info => {
console.info("CONNECTED TO BANGLE:", BANGLE, info)
Espruino.Core.CodeWriter.init()
Espruino.Core.CodeWriter.writeToEspruino("Bangle.beep();", () => {
console.info("BANGLE DID A BEEP")
})
})
It's just a way of packaging this up and using it however the BangleApps
repo is doing it.
As a last resort, I could just wrap the code being sent with the code from the badge workshop 👍
Ahh, ok - well if you want to literally just connect and send commands, https://www.espruino.com/Interfacing#node-js-javascript would be an easy start I guess. The actual communication method for Bangle.js is called 'Nordic UART' and is used in loads of places, including Adafruit's BLE devices - so there are some packages that handle it already: https://www.npmjs.com/search?q=nordic%20uart
There's also esp.sendCode(port, code, callback)
which does what you're doing, but it doesn't maintain a connection, so yeah - if you're trying to keep a connection open I think what you're doing is the best.
One thing you might be interested in is transformForEspruino
- which will potentially do things like minification and will also automatically load any modules referenced by the code: https://github.com/espruino/EspruinoTools/blob/gh-pages/index.js#L143
But again if you're sending single commands, what you're doing is fine.
I'm not 100% sure what you have planned, but there might be something to be said for making BangleApps an NPM package and putting some simple Node.js code in for loading apps via CLI... All it'd require is basically creating a new comms.js that used the code from https://www.espruino.com/Interfacing#node-js-javascript
Hey @gfwilliams 👋
Thanks for the info! I'm looking to create a CLI tool like create-bangle-app
(think create-react-app
but for Bangle.js 😄) so keeping the connection open is perfect for "dev" mode. I have this working now with fs.watchFile
so that when I make a save to a file it uploads file content as string to the bangle with Core.CodeWriter.writeToEspruino(fileContentString)
.
Oooo. I'll certainly take a look at transformForEspruino
👍
So comms.js
is where the "magic" is happening in the BangleApps
repo for uploading an app to the watch?
Nice - sounds like a great idea to help people get started.
There is the -w
option in the CLI to watch a file and upload it on change (it stays connected and also turns the console into a REPL into the watch). Just from the point of view of reducing duplication (since the REPL might be a handy addition for you too), what's actually missing from the CLI tool itself? Just a way of instantiating it using the espruino
package?
If so, it might be that I could split out the CLI parsing from the tool around about here and then just expose a function that you could hand an object to instead of having to poke into the depths of the tool.
But yeah, in BangleApps
the code that works out what to send over the BLE connection (and handles responses) is in https://github.com/espruino/BangleApps/blob/master/comms.js - and then the code that actually sends it via Web Bluetooth is in https://github.com/espruino/EspruinoWebTools/blob/master/puck.js
So what would be needed is a way to swap out the Puck
object with something that handled comms over Noble.
Hey @gfwilliams 👋
Thanks for pointing me at those resources 👍
I've dug in a little further and got something pretty much there 🙌
AppInfo.getFiles
was what I was looking for then using Core.Serial
to write it to the device.
However, I'm a little stuck on one piece. Although I can fire a script and upload an app to the device or override it. I'm having trouble uploading the associated icon with it.
From digging into AppInfo
, am I right in thinking a stringified version of the following is what should be sent over.
json
require('Storage')
.write("+hellow","{
"name": "Hello World!",
"icon": "*hellow",
"src": "-hellow",
"files": "+hellow,-hellow,*hellow"
}");
js
require('Storage')
.write("-hellow","g.clear()\nE.showMessage('HELLO WORLD!')");
img
require('Storage')
.write("*hellow","require(\"heatshrink\").decompress(atob(\"<IMG>"))\n");
As mentioned, I can upload the app and see it on the menu. It just doesn't have an icon with it.
Thanks for all your help!
I believe it's because (on Mac again?) the BLE address is formatted differently with dashes rather than colons. Try
var addr = BANGLE.address.toString().replace('-',':');
Very odd about
espruino --list
not working though - that's definitely with the new espruino NPM module? Does 'espruino --list --verbose' give any hints what is wrong?
Running on Mac OS 10.14.6 and node v8.16.2 and on my desk is a Pixl.js and a Bangle.js
PORTS: c2-92-a6-15-c3-ec (Bangle.js c3ec)
Noble: Disable Web Bluetooth as we have Noble instead
Noble: Starting scan
Noble: Found device:
Noble: Found device: d0-d2-b0-26-82-01 d0-d2-b0-26-82-01
Noble: Found device: d0-d2-b0-26-82-01 d0-d2-b0-26-82-01
Noble: Found device:
Noble: Found device:
Noble: Found UART device: Bangle.js c3ec c2-92-a6-15-c3-ec
Noble: Found device:
Noble: Found device: d0-4f-7e-49-e6-5c d0-4f-7e-49-e6-5c
Noble: Found device: d0-4f-7e-49-e6-5c d0-4f-7e-49-e6-5c
PORTS:
c2-92-a6-15-c3-ec (Bangle.js c3ec)
.....
Just to confirm
Ahh, interesting - thanks! So it's different on Mac. I should probably replace -
with :
in serial_noble then.
For uploads: What should happen is the evaluate
flag is checked in AppInfo.getFiles
: https://github.com/espruino/BangleApps/blob/master/appinfo.js#L39
If that's the case, the data is sent as-is, so unstringified. Basically it's then executed by Bangle.js before the upload, so the uncompressed data is written to Storage.
It may be that your JSON doesn't have the evaluate
field in it - it should look like this: https://github.com/espruino/BangleApps/blob/master/README.md#developing-your-own-app
Hey @gfwilliams 👋
Thanks for that! That's the piece I was missing. I wasn't evaluating it 🤦♂ It works great now. The icon is uploaded with the code and all is well 👍
Thank you so much for your help with this.
I think we can close the issue. It went off on a slight tangent 😄
Thanks again so much for your help.
No worries - glad you got it working!
Hey @gfwilliams 👋
Playing with
Bangle.js
and I'd love to be able to connect to it from the CLI and send some code over from a node script.I tried using
espruino
directly but I ran into this issue - https://github.com/abandonware/noble/issues/20If I install
@abandonware/noble
and use it directly, I can find and connect to the Bangle. But then I'm not sure how I go about uploading expressions or code to it. I tried the following very rough code to get connected;However,
espruino
is unable to connect. I'm not sure which is or how to grab the correct address in order to connect and upload code/files to the device.Any help would be much appreciated 👍
@jh3y