1
0
Fork 0
Bangle.js App Loader (and Apps)
 
 
 
 
 
Go to file
MaBecker 913440c596 minor fixes
- add drawWidgets()
2019-11-26 17:51:23 +01:00
apps minor fixes 2019-11-26 17:51:23 +01:00
bin updated firmware info 2019-11-10 17:01:40 +00:00
css Added customised app loading 2019-11-06 17:25:02 +00:00
img Logo, about page, set time + erase all apps option 2019-11-07 09:26:46 +00:00
lib Added customised app loading 2019-11-06 17:25:02 +00:00
testing merge skeleton README into original README, and make example apps so you can just copy the folder 2019-11-26 10:27:31 +00:00
LICENSE add MIT License 2019-11-20 14:30:01 +00:00
README.md minor fixes 2019-11-26 17:51:23 +01:00
appinfo.js 🐛 Fix filepaths after moving to subfolders #46 2019-11-17 23:44:17 +01:00
apps.json Merge branch 'master' of https://github.com/MaBecker/BangleApps into MaBecker-master 2019-11-26 09:37:36 +00:00
comms.js added the disconnect button 2019-11-12 15:41:03 +01:00
favicon.ico asteroids 2019-11-07 09:50:03 +00:00
firmware.js Highlight default clock if none currently selected 2019-11-16 22:36:43 +00:00
index.html add extra filter options 2019-11-13 17:43:59 +00:00
index.js 🐛 Fix filepaths after moving to subfolders #46 2019-11-17 23:44:17 +01:00
utils.js respond to HTTP errors 2019-11-10 12:16:28 +00:00

README.md

Bangle.js App Loader (and Apps)

Try it live at banglejs.com/apps

How does it work?

  • A list of apps is in apps.json
  • Each element references an app in apps/<id> which is uploaded
  • When it starts, BangleAppLoader checks the JSON and compares it with the files it sees in the watch's storage.
  • To upload an app, BangleAppLoader checks the files that are listed in apps.json, loads them, and sends them over Web Bluetooth.

What filenames are used

Filenames in storage are limited to 8 characters. To easily distinguish between file types, we use the following:

  • +stuff is JSON for an app
  • *stuff is an image
  • -stuff is JS code
  • =stuff is JS code for stuff that is run at boot time - eg. handling settings or creating widgets on the clock screen

Developing your own app

  • Head over to the Web IDE and ensure Save on Send in settings set to the default setting of To RAM
  • We'd recommend that you start off using code from 'Example Applications' (below) to get started...
  • Load app.js or widget.js into the IDE and start developing.
  • The Upload button will load your app to Bangle.js temporarily

Adding your app to the menu

  • Come up with a unique 7 character name, we'll assume 7chname
  • Create a folder called apps/<id>, lets assume apps/7chname
  • We'd recommend that you copy files from 'Example Applications' (below) as a base, or...
  • apps/7chname/app.png should be a 48px icon
  • Use http://www.espruino.com/Image+Converter to create apps/7chname/app-icon.js, using a 1 bit, 4 bit or 8 bit Web Palette "Image String"
  • Create an entry in apps/7chname/app.json as follows:
{
  "name":"Short Name",
  "icon":"*7chname",
  "src":"-7chname"
}
  • Create an entry in apps.json as follows:
{ "id": "7chname",
  "name": "My app's human readable name",
  "icon": "app.png",
  "description": "A detailed description of my great app",
  "tags": "",
  "storage": [
    {"name":"+7chname","url":"app.json"},
    {"name":"-7chname","url":"app.js"},
    {"name":"*7chname","url":"app-icon.js","evaluate":true}
  ],
},

Testing

Online

This is the best way to test...

  • Fork the https://github.com/espruino/BangleApps git repository
  • Add your files
  • Go to GitHub Settings and activate GitHub Pages
  • Run your personal Bangle App Loader at https://<your-github-username>.github.io/BangleApps/index.html to load apps onto your device
  • Your apps should be inside it - if there are problems, check your web browser's 'developer console' for errors

Be aware of the delay between commits and updates on github.io - it can take a few minutes (and a 'hard refresh' of your browser) for changes to take effect.

Offline

You can add the following to the Espruino Web IDE:

// replace with your 7chname app name
var appname = "mygreat";

require("Storage").write('*'+appname,
  // place app-icon.js contents here
);

// 
require("Storage").write("+"+appname,{
  "name":"My Great App","type":"",
  "icon":"*"+appname,
  "src":"-"+appname,
});

require("Storage").write("-"+appname,`
// place contents of app.js here
// be aware of double-quoting templated strings
`

When you upload code this way, your app will be uploaded to Bangle.js's menu without you having to use the Bangle App Loader

Example Applications

To make the process easier we've come up with some example applications that you can use as a base when creating your own. Just come up with a unique 7 character name, copy apps/_example_app or apps/_example_widget to apps/7chname, and add apps/_example_X/add_to_apps.json to apps.json.

App Example

The app example is available in apps/_example_app

Apps are listed in the Bangle.js menu, accessible from a clock app via the middle button.

  • add_to_apps.json - insert into apps.json, describes the widget to bootloader and loader
  • app.png - app icon - 48x48px
  • app-icon.js - JS version of the icon (made with http://www.espruino.com/Image+Converter) for use in Bangle.js's menu
  • app.json - short app name for Bangle.js menu and storage filenames
  • app.js - app code

app-icon.js

The icon image and short description is used in the menu entry as selection posibility.

Use the Espruino image converter and upload your app.png file.

Follow this steps to create a readable icon as image string.

  1. upload a png file
  2. set X Use Compression
  3. set X Transparency (optional)
  4. set Diffusion: flat
  5. set Colours: 1 bit, 4 bit or 8 bit Web Palette
  6. set Output as: Image String

Replace this line with the image converter output:

require("heatshrink").decompress(atob("mEwwJC/AH4A/AH4AgA=="));

Keep in mind to use this converter for creating images you like to draw with g.drawImage() with your app.

Widget Example

The widget example is available in apps/_example_widget

  • add_to_apps.json - insert into apps.json, describes the widget to bootloader and loader
  • widget.json - short widget name and storage names
  • widget.js - widget code

apps.json format

{ "id": "appid",              // 7 character app id
  "name": "Readable name",    // readable name
  "icon": "icon.png",         // icon in apps/
  "description": "...",       // long description
  "type":"...",               // optional(if app) - 'app' or 'widget'
  "tags": "",                 // comma separated tag list for searching

  "custom": "custom.html",    // if supplied, apps/custom.html is loaded in an
                              // iframe, and it must post back an 'app' structure
                              // like this one with 'storage','name' and 'id' set up

  "storage": [                // list of files to add to storage
    {"name":"-appid",         // filename to use in storage
     "url":"",                // URL of file to load (currently relative to apps/)
     "content":"..."          // if supplied, this content is loaded directly
     "evaluate":true          // if supplied, data isn't quoted into a String before upload
                              // (eg it's evaluated as JS)
    },
  "sortorder" : 0,            // optional - choose where in the list this goes.
                              // this should only really be used to put system
                              // stuff at the top
  ]
}
  • 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 or empty.
  • storage is used to identify the app files and how to handle them

Coding hints

  • use g.setFont(.., size) to multiply the font size, eg ("6x8",3) : "18x24"

  • use g.drawString(text,x,y,true) to draw with background color to overwrite existing text

  • use g.clearRect() to clear parts of the screen, instead of using g.clear()

  • use g.fillPoly() or g.drawImage() for complex graphic elements

  • using g.clear() can cause screen flicker

  • using g.setLCDBrightness() can save you power during long periods with lcd on

  • chaining graphics methodes, eg g.setColor(0xFD20).setFontAlign(0,0).setfont("6x8",3)

Graphic areas

The screen is parted in a widget and app area for lcd mode direct(default).

areas as rectangle or point
Widget (0,0,239,23)
Apps (0,24,239,239)
BTN1 (230, 55)
BTN2 (230, 140)
BTN3 (230, 210)
BTN4 (0,0,119, 239)
BTN5 (120,0,239,239)
  • Use g.setFontAlign(0, 0, 3) to draw rotated string to BTN1-BTN3 with g.drawString().

  • For BTN4-5 the touch area is named

Available colors

You can use g.setColor(r,g,b) OR g.setColor(16bitnumber) - some common 16 bit colors are below:

color-name color-value
Black 0x0000
Navy 0x000F
DarkGreen 0x03E0
DarkCyan 0x03EF
Maroon 0x7800
Purple 0x780F
Olive 0x7BE0
LightGray 0xC618
DarkGrey 0x7BEF
Blue 0x001F
Green 0x07E0
Cyan 0x07FF
RED 0xF800
Magenta 0xF81F
Yellow 0xFFE0
White 0xFFFF
Orange 0xFD20
GreenYellow 0xAFE5
Pink 0xF81F

API Reference

Reference

Bangle Class

Graphics Class

'Testing' folder

The testing folder contains snippets of code that might be useful for your apps.

  • testing/colors.js - 16 bit colors as name value pairs
  • testing/gpstrack.js - code to store a GPS track in Bagle.js storage and output it back to the console
  • testing/map - code for splitting an image into map tiles and then displaying them

Credits

The majority of icons used for these apps are from Icons8 - we have a commercial license but icons are also free for Open Source projects.