BSB Developer Docs
Loading...
Searching...
No Matches
JavaScript Applications

Introduction

JavaScript applications are a locally-run form of HTTP API applications. To achieve this, the Firmware includes a JavaScript interpreter to run user scripts and a set of standard and custom interfaces to be used by these scripts.

Additionally, the firmware is able to enumerate and list currently installed applications and display them in the APPS menu for easy access.

Quick start

To facilitate application development, dedicated tooling is available. New developers are advised to try it first, then return to this page for more information as needed.

Application structure

Applications directory

The firmware is looking for JavaScript applications in the /ext/user_assets directory on the EMMC storage.

Every subfolder in this directory will be searched for a valid application file structure.

Application file structure

Every JavaScript application must implement the following basic file structure:

/ext/user_assets
└── org.author.example_app
├── appmeta
│ ├── manifest.json
│ ├── settings.json
│ ├── icon_front_8x8.png
│ └── icon_back_11x11.png
│
└── scripts
└── main.js

The firmware will look for these hardcoded file names when looking for applications.

Root directory

Required. The name must be at most 32 characters long and contain only ASCII alphanumeric characters.

The only allowed special characters are: _ (underscore), - (minus) and . (period). The name cannot start with a period.

To improve the name uniqueness, a reverse domain name scheme is recommended, but is not required.

appmeta directory

Required. Contains the application metadata. See the table below for contents summary.

File Purpose Required?
manifest.json Application manifest (see below) YES
settings.json Application settings description NO [1]
icon_front_8x8.png Icon to be shown in front display UI NO [2]
icon_back_11x11.png Icon to be shown in back display UI NO [3]
  • [1] If not present, it is assumed that the application does not have any settings.
  • [2] Must be a 8x8px PNG colour image. If not present, a default icon will be used.
  • [3] Must be a 11x11px PNG greyscale image. If not present, a default icon will be used.

scripts directory

Required. Contains the JavaScript script files.

The main.js file is the application entry point and is required. Any number of additional .js files may be present if required.

Additional directories

The root directory may also contain any number of additional directories. The maximum length of the full path is limited to 256 characters and is subject to the same character restrictions as the root directory name, with the addition of the directory separator / (forward slash).

It is recommended, but not required, to group the resource files necessary for the application to comprehensively named directories, e.g.

  • resources, data – any kind of resource files used by the application
  • images, graphics, gfx – graphic resources (such as icons or background images)
  • animations – self explanatory
  • sounds – self explanatory, etc.

Manifest file

Application manifest file is a JSON file that describes all of the application's properties that are necessary to run it.

Field Purpose Required? Default
format_version File schema version YES [1] -
id Unique application identifier YES [2] -
name Display name (shown in GUI) YES -
version Application version (x.y.z) YES -
api_version Minimum HTTP API version YES [3] -
description Free form description NO ""
author Application author NO ""
heap_size_kib Memory size for dynamic data NO [4] 128
debug Hide if developer mode is off NO false
  • [1] Defined by the firmware version. Currently equal to 1.
  • [2] Must be the same as the root directory name.
  • [3] Firmware only checks that the expected API version is not newer than the available version.
  • [4] Increase if encountering "out of memory" errors. 512 KiB is the current maximum.

See Appendix 1: Manifest File Schema for the complete file format description.

Settings file

Settings file is a JSON file that describes the settings relevant for the application.

An individual setting entry can be of one of the following types:

Type Explanation
boolean Boolean value (true or false)
integer Signed integer number
string Arbitrary text string
enum List of pre-defined options
color Colour in RGB or RGBA format
time Time in HH:MM:SS format
geolocation Geographic coordinates

An arbitrary number of settings is supported, each of which can be any of the supported types. Additionally, settings can be grouped via the group directive, with a maximum of 4 nested levels.

The graphical interface for viewing and editing the settings is handled by the firmware, so the application does not need to implement it by itself. However, not all settings types (namely, color and geolocation) can be edited via BUSY Bar graphical interface due to display and input limitations. Full editing capability is available from the Web UI or programmaticaly via the HTTP API.

While running, the application only has the ability to read its settings via the GET /api/apps/settings HTTP request.

See Appendix 2: Settings File Schema for the complete file format description.

HTTP Requests

Requests to the HTTP API are performed via the built-in fetch function.

It supports the same syntax as its regular counterpart from browsers with several limitations. See MDN for more info on the usage.

Applications must make requests to http://localhost/api/... in order to interact with the on-device web server.

Example snippet that outputs "Hello world!" on the front display:

fetch("http://localhost/api/display/draw", {
method: "POST",
body: JSON.stringify({
application_name: "app.hello.world",
elements: [
{
id: "0",
type: "text",
x: 72 / 2,
y: 16 / 2,
align: "center",
text: "Hello World!",
font: "small"
}
]
})
});

For application isolation purposes, only the following API endpoints are accessible from within the applications:

Endpoint Allowed method(s)
apps/settings GET [1]
display/brightness GET, POST
display/draw POST, DELETE
audio/play POST, DELETE
busy GET, PUT
name GET
audio/volume GET, POST
time GET
wifi/status GET
version GET
access GET
transport GET
status GET
status/device GET
status/firmware GET
status/system GET
status/power GET
  • [1] The request is only allowed if the app_id request parameter matches the running application ID.

The fetch function can also be used to access remote HTTP(S) resources in the same manner, provided there is a working Wi-Fi connection.

Input handling

Applications that need to react to user input must use the built-in listen function:

const unbind = listen("input", inputHandler);
function inputHandler(event) {
switch(event.key) {
// Various handlers
}
}
// Other logic
// Input not needed anymore
unbind();

The received event object will have the following properties:

Property Explanation
key Name of the control that produced the event
action Type of the event that occurred
delta For the encoder wheel only: number of clicks

The key property may take one of the following values:

Value Hardware control type
encoder Encoder wheel
ok Encoder button
start Start/Stop (big button)
back Back button

The action property may take one of the following values:

Value Explanation
press Button was pressed [1]
release Button was released [1]
short Button was pressed shortly [1]
long Button was held for a longer time [1]
repeat Button is being held continuously [1]
clockwise Rotated clockwise [2]
counterclockwise Rotated counterclockwise [2]
  • [1] Only for buttons
  • [2] Only for encoder wheel

Additionally, if the key is equal to encoder, then an additional delta property will be present, which represents the number of clicks that occurred (currently, only 1). The sign denotes rotation direction (negative is counterclockwise).

It is recommended that applications react to the short action as a normal button press and to long action as the long button press. Raw press and release actions may be useful in games or other applications that need to track explicit press and release events.

See Appendix 3: Input Event Schema for the complete event format description.

Back button behaviour

A long press of the Back button is handled outside of the application and is used to force-quit from an application.