From 260dff75f71a4d80965fb564b47af0f1fe679ea1 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 28 Apr 2025 21:37:02 +0100 Subject: [PATCH 1/3] typescript: update --- typescript/types/main.d.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/typescript/types/main.d.ts b/typescript/types/main.d.ts index ea9dbb131a..318373d3f7 100644 --- a/typescript/types/main.d.ts +++ b/typescript/types/main.d.ts @@ -11,7 +11,7 @@ type MenuBooleanItem = { value: boolean; format?: (value: boolean) => string; - onchange?: (value: boolean) => void; + onchange?: (value: boolean, evt?: TouchCallbackXY) => void; }; /** @@ -20,7 +20,7 @@ type MenuBooleanItem = { type MenuNumberItem = { value: number; format?: (value: number) => string; - onchange?: (value: number) => void; + onchange?: (value: number, evt?: TouchCallbackXY) => void; step?: number; min?: number; max?: number; @@ -56,10 +56,10 @@ type Menu = { ""?: MenuOptions; [key: string]: | MenuOptions - | (() => void) + | ((e?: TouchCallbackXY) => void) | MenuBooleanItem | MenuNumberItem - | { value: string; onchange?: () => void } + | { value: string; onchange?: (value: unknown, evt?: TouchCallbackXY) => void } | undefined; }; @@ -68,8 +68,6 @@ type Menu = { */ type MenuInstance = { draw: () => void; - move: (n: number) => void; - select: () => void; scroller?: MenuScroller; // BangleJS 2 }; @@ -149,7 +147,8 @@ type TapAxis = -2 | -1 | 0 | 1 | 2; type SwipeCallback = (directionLR: -1 | 0 | 1, directionUD?: -1 | 0 | 1) => void; -type TouchCallback = (button: number, xy?: { x: number, y: number }) => void; +type TouchCallbackXY = { x: number, y: number, type: 0 | 2 }; +type TouchCallback = (button?: number, xy?: TouchCallbackXY) => void; type DragCallback = (event: { x: number; @@ -15146,4 +15145,4 @@ declare module "Storage" { * @url http://www.espruino.com/Reference#l_Storage_open */ function open(name: string, mode: "r" | "w" | "a"): StorageFile; -} \ No newline at end of file +} From 123498424aea7444db0943851286cd4f411bcd64 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 28 Apr 2025 21:36:58 +0100 Subject: [PATCH 2/3] promenu/folderlaunch: update to new touch event arg e.g. from https://github.com/espruino/BangleApps/issues/3804#issuecomment-2834920685 aka: - https://github.com/espruino/BangleApps/pull/3604 - https://github.com/espruino/Espruino/pull/2565 - https://github.com/espruino/BangleApps/pull/3609 - https://github.com/espruino/Espruino/pull/2569 --- apps/folderlaunch/app.ts | 4 ++-- apps/promenu/ChangeLog | 1 + apps/promenu/bootb2.js | 26 +++++++++++++++----------- apps/promenu/bootb2.ts | 27 +++++++++++++++++---------- apps/promenu/metadata.json | 2 +- 5 files changed, 36 insertions(+), 24 deletions(-) diff --git a/apps/folderlaunch/app.ts b/apps/folderlaunch/app.ts index aff8e5c7ed..5140919dbe 100644 --- a/apps/folderlaunch/app.ts +++ b/apps/folderlaunch/app.ts @@ -174,7 +174,7 @@ * @param _button 1 for left half, 2 for right half * @param xy postion on screen */ - let onTouch = function (_button: number, xy: { x: number, y: number } | undefined) { + let onTouch = function (_button, xy) { // Determine which grid cell was tapped let x: number = Math.floor((xy!.x - 12) / ((g.getWidth() - 24) / config.display.rows)); if (x < 0) x = 0; @@ -206,7 +206,7 @@ break; } } - } + } satisfies TouchCallback; let page: number = 0; let nPages: number; // Set when setting folder diff --git a/apps/promenu/ChangeLog b/apps/promenu/ChangeLog index 4a0f538fbc..d944788bfb 100644 --- a/apps/promenu/ChangeLog +++ b/apps/promenu/ChangeLog @@ -14,3 +14,4 @@ 0.10: Trigger `remove` callbacks when ending the menu 0.11: Add options for natural scroll and disabling wrap-around 0.12: Fix bug where settings would behave as if all were set to false +0.13: Update to new touch-event handling diff --git a/apps/promenu/bootb2.js b/apps/promenu/bootb2.js index d11beb48c4..540a0f04c0 100644 --- a/apps/promenu/bootb2.js +++ b/apps/promenu/bootb2.js @@ -133,10 +133,10 @@ E.showMenu = function (items) { g.setColor((idx < menuItems.length) ? g.theme.fg : g.theme.bg).fillPoly([72, 166, 104, 166, 88, 174]); g.flip(); }, - select: function () { + select: function (evt) { var item = items[menuItems[selected]]; if (typeof item === "function") { - item(); + item(evt); } else if (typeof item === "object") { if (typeof item.value === "number") { @@ -146,12 +146,12 @@ E.showMenu = function (items) { if (typeof item.value === "boolean") item.value = !item.value; if (item.onchange) - item.onchange(item.value); + item.onchange(item.value, evt); } l.draw(); } }, - move: function (dir) { + move: function (dir, evt) { var item = selectEdit; if (typeof item === "object" && typeof item.value === "number") { var orig = item.value; @@ -162,7 +162,7 @@ E.showMenu = function (items) { item.value = item.wrap ? item.min : item.max; if (item.value !== orig) { if (item.onchange) - item.onchange(item.value); + item.onchange(item.value, evt); l.draw(selected, selected); } } @@ -198,6 +198,12 @@ E.showMenu = function (items) { }; Bangle.on('swipe', onSwipe); } + var cb = function (dir, evt) { + if (dir) + l.move(prosettings.naturalScroll ? -dir : dir, evt); + else + l.select(evt); + }; Bangle.setUI({ mode: "updown", back: back, @@ -208,11 +214,9 @@ E.showMenu = function (items) { Bangle.removeListener("swipe", onSwipe); (_a = options.remove) === null || _a === void 0 ? void 0 : _a.call(options); }, - }, function (dir) { - if (dir) - l.move(prosettings.naturalScroll ? -dir : dir); - else - l.select(); - }); + touch: (function (_button, xy) { + cb(void 0, xy); + }), + }, cb); return l; }; diff --git a/apps/promenu/bootb2.ts b/apps/promenu/bootb2.ts index e128151e3f..86bc414886 100644 --- a/apps/promenu/bootb2.ts +++ b/apps/promenu/bootb2.ts @@ -175,11 +175,11 @@ E.showMenu = (items?: Menu): MenuInstance => { g.setColor((idx < menuItems.length)?g.theme.fg:g.theme.bg).fillPoly([72, 166, 104, 166, 88, 174]); g.flip(); }, - select: () => { + select: (evt: TouchCallbackXY | undefined) => { const item = items![menuItems[selected]] as ActualMenuItem; if (typeof item === "function") { - item(); + item(evt); } else if (typeof item === "object") { if (typeof item.value === "number") { selectEdit = selectEdit ? undefined : item; @@ -188,12 +188,12 @@ E.showMenu = (items?: Menu): MenuInstance => { item.value = !item.value; if (item.onchange) - item.onchange(item.value as boolean); + item.onchange(item.value as boolean, evt); } l.draw(); } }, - move: (dir: number) => { + move: (dir: number, evt: TouchCallbackXY | undefined) => { const item = selectEdit; if (typeof item === "object" && typeof item.value === "number") { @@ -209,7 +209,7 @@ E.showMenu = (items?: Menu): MenuInstance => { if (item.value !== orig) { if (item.onchange) - item.onchange(item.value); + item.onchange(item.value, evt); l.draw(selected, selected); } @@ -247,6 +247,11 @@ E.showMenu = (items?: Menu): MenuInstance => { Bangle.on('swipe', onSwipe); } + const cb = (dir?: 1 | -1, evt?: TouchCallbackXY) => { + if (dir) l.move(prosettings.naturalScroll ? -dir : dir, evt); + else l.select(evt); + }; + Bangle.setUI({ mode: "updown", back, @@ -255,11 +260,13 @@ E.showMenu = (items?: Menu): MenuInstance => { Bangle.removeListener("swipe", onSwipe); options.remove?.(); }, - } as SetUIArg<"updown">, - dir => { - if (dir) l.move(prosettings.naturalScroll ? -dir : dir); - else l.select(); - }); + touch: ((_button, xy) => { + // since we've specified options.touch, + // we need to pass through all taps since the default + // touchHandler isn't installed in setUI + cb(void 0, xy); + }) satisfies TouchCallback, + } as SetUIArg<"updown">, cb); return l; }; diff --git a/apps/promenu/metadata.json b/apps/promenu/metadata.json index 05583e1fd6..9b0ba21210 100644 --- a/apps/promenu/metadata.json +++ b/apps/promenu/metadata.json @@ -1,7 +1,7 @@ { "id": "promenu", "name": "Pro Menu", - "version": "0.12", + "version": "0.13", "description": "Replace the built in menu function. Supports Bangle.js 1 and Bangle.js 2.", "icon": "icon.png", "type": "bootloader", From 45241325bcdd4d19199973d7d41311e563e3dde4 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 30 Apr 2025 08:44:10 +0100 Subject: [PATCH 3/3] typescript: update from espruino as opposed to manual --- typescript/types/main.d.ts | 7176 ++++++++++++++++-------------------- 1 file changed, 3245 insertions(+), 3931 deletions(-) diff --git a/typescript/types/main.d.ts b/typescript/types/main.d.ts index 318373d3f7..216b30dfb6 100644 --- a/typescript/types/main.d.ts +++ b/typescript/types/main.d.ts @@ -5,6 +5,11 @@ // TYPES +type AES_CCM_EncryptResult = { + data: ArrayBuffer, + tag: ArrayBuffer, +}; + /** * Menu item that holds a boolean value. */ @@ -376,130 +381,6 @@ type PipeOptions = { // CLASSES -/** - * A class to support some simple Queue handling for RTOS queues - * @url http://www.espruino.com/Reference#Queue - */ -declare class Queue { - /** - * Creates a Queue Object - * @constructor - * - * @param {any} queueName - Name of the queue - * @returns {any} A Queue object - * @url http://www.espruino.com/Reference#l_Queue_Queue - */ - static new(queueName: any): any; - - /** - * reads one character from queue, if available - * @url http://www.espruino.com/Reference#l_Queue_read - */ - read(): void; - - /** - * Writes one character to queue - * - * @param {any} char - char to be send - * @url http://www.espruino.com/Reference#l_Queue_writeChar - */ - writeChar(char: any): void; - - /** - * logs list of queues - * @url http://www.espruino.com/Reference#l_Queue_log - */ - log(): void; -} - -/** - * A class to support some simple Task handling for RTOS tasks - * @url http://www.espruino.com/Reference#Task - */ -declare class Task { - /** - * Creates a Task Object - * @constructor - * - * @param {any} taskName - Name of the task - * @returns {any} A Task object - * @url http://www.espruino.com/Reference#l_Task_Task - */ - static new(taskName: any): any; - - /** - * Suspend task, be careful not to suspend Espruino task itself - * @url http://www.espruino.com/Reference#l_Task_suspend - */ - suspend(): void; - - /** - * Resumes a suspended task - * @url http://www.espruino.com/Reference#l_Task_resume - */ - resume(): void; - - /** - * returns name of actual task - * @returns {any} Name of current task - * @url http://www.espruino.com/Reference#l_Task_getCurrent - */ - getCurrent(): any; - - /** - * Sends a binary notify to task - * @url http://www.espruino.com/Reference#l_Task_notify - */ - notify(): void; - - /** - * logs list of tasks - * @url http://www.espruino.com/Reference#l_Task_log - */ - log(): void; -} - -/** - * A class to handle Timer on base of ESP32 Timer - * @url http://www.espruino.com/Reference#Timer - */ -declare class Timer { - /** - * Creates a Timer Object - * @constructor - * - * @param {any} timerName - Timer Name - * @param {number} group - Timer group - * @param {number} index - Timer index - * @param {number} isrIndex - isr (0 = Espruino, 1 = test) - * @returns {any} A Timer Object - * @url http://www.espruino.com/Reference#l_Timer_Timer - */ - static new(timerName: any, group: number, index: number, isrIndex: number): any; - - /** - * Starts a timer - * - * @param {number} duration - duration of timmer in micro secs - * @url http://www.espruino.com/Reference#l_Timer_start - */ - start(duration: number): void; - - /** - * Reschedules a timer, needs to be started at least once - * - * @param {number} duration - duration of timmer in micro secs - * @url http://www.espruino.com/Reference#l_Timer_reschedule - */ - reschedule(duration: number): void; - - /** - * logs list of timers - * @url http://www.espruino.com/Reference#l_Timer_log - */ - log(): void; -} - /** * Class containing utility functions for the * [ESP32](http://www.espruino.com/ESP32) @@ -845,1683 +726,674 @@ declare class Nucleo { } /** - * The NRF class is for controlling functionality of the Nordic nRF51/nRF52 chips. - * Most functionality is related to Bluetooth Low Energy, however there are also - * some functions related to NFC that apply to NRF52-based devices. - * @url http://www.espruino.com/Reference#NRF + * This class provides functionality to recognise gestures drawn on a touchscreen. + * It is only built into Bangle.js 2. + * Usage: + * ``` + * var strokes = { + * stroke1 : Unistroke.new(new Uint8Array([x1, y1, x2, y2, x3, y3, ...])), + * stroke2 : Unistroke.new(new Uint8Array([x1, y1, x2, y2, x3, y3, ...])), + * stroke3 : Unistroke.new(new Uint8Array([x1, y1, x2, y2, x3, y3, ...])) + * }; + * var r = Unistroke.recognise(strokes,new Uint8Array([x1, y1, x2, y2, x3, y3, ...])) + * print(r); // stroke1/stroke2/stroke3 + * ``` + * @url http://www.espruino.com/Reference#Unistroke */ -declare class NRF { +declare class Unistroke { /** - * @returns {any} An object - * @url http://www.espruino.com/Reference#l_NRF_getSecurityStatus + * Create a new Unistroke based on XY coordinates + * + * @param {any} xy - An array of interleaved XY coordinates + * @returns {any} A string of data representing this unistroke + * @url http://www.espruino.com/Reference#l_Unistroke_new */ - static getSecurityStatus(): NRFSecurityStatus; + static new(xy: any): any; /** - * @returns {any} An object - * @url http://www.espruino.com/Reference#l_NRF_getAddress + * Recognise based on an object of named strokes, and a list of XY coordinates + * + * @param {any} strokes - An object of named strokes : `{arrow:..., circle:...}` + * @param {any} xy - An array of interleaved XY coordinates + * @returns {any} The key name of the matched stroke + * @url http://www.espruino.com/Reference#l_Unistroke_recognise */ - static getAddress(): any; + static recognise(strokes: any, xy: any): any; + + +} + +/** + * Class containing utility functions for the Qwiic connectors + * on the [Jolt.js Smart Bluetooth driver](http://www.espruino.com/Jolt.js). + * Each class (available from `Jolt.Q0`/`Jolt.Q1`/`Jolt.Q2`/`Jolt.Q3`) + * has `sda` and `scl` fields with the pins for SDA and SCL on them. + * On Jolt.js, the four Qwiic connectors can be individually powered: + * * Q0/Q1 - GND is switched with a 500mA FET. The `fet` field contains the pin that controls the FET + * * Q2/Q3 - all 4 pins are connected to GPIO. `gnd` and `vcc` fields contain the pins for GND and VCC + * To control the power, use `Qwiic.setPower`, for example: `Jolt.Q0.setPower(true)` + * @url http://www.espruino.com/Reference#Qwiic + */ +declare class Qwiic { + /** + * This turns power for the given Qwiic connector on or off. See `Qwiic` for more information. * - * @param {any} data - The service (and characteristics) to advertise - * @param {any} options - Optional object containing options - * @url http://www.espruino.com/Reference#l_NRF_setServices + * @param {boolean} isOn - Whether the Qwiic connector is to be on or not + * @returns {any} The same Qwiic object (for call chaining) + * @url http://www.espruino.com/Reference#l_Qwiic_setPower */ - static setServices(data: any, options: any): void; + setPower(isOn: ShortBoolean): any; /** - * - * @param {any} data - The data to advertise as an object - see below for more info - * @param {any} [options] - [optional] An object of options - * @url http://www.espruino.com/Reference#l_NRF_setAdvertising + * @returns {any} An I2C object using this Qwiic connector, already set up + * @url http://www.espruino.com/Reference#l_Qwiic_i2c */ - static setAdvertising(data: any, options?: any): void; + i2c: any; +} +/** + * Class containing AES encryption/decryption + * **Note:** This library is currently only included in builds for boards where + * there is space. For other boards there is `crypto.js` which implements SHA1 in + * JS. + * @url http://www.espruino.com/Reference#AES + */ +declare class AES { /** - * Called when a host device connects to Espruino. The first argument contains the - * address. - * @param {string} event - The event to listen to. - * @param {(addr: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `addr` The address of the device that has connected - * @url http://www.espruino.com/Reference#l_NRF_connect + * + * @param {any} passphrase - Message to encrypt + * @param {any} key - Key to encrypt message - must be an `ArrayBuffer` of 128, 192, or 256 BITS + * @param {any} [options] - [optional] An object, may specify `{ iv : new Uint8Array(16), mode : 'CBC|CFB|CTR|OFB|ECB' }` + * @returns {any} Returns an `ArrayBuffer` + * @url http://www.espruino.com/Reference#l_AES_encrypt */ - static on(event: "connect", callback: (addr: any) => void): void; + static encrypt(passphrase: any, key: any, options?: any): ArrayBuffer; /** - * Called when a host device disconnects from Espruino. - * The most common reason is: - * * 19 - `REMOTE_USER_TERMINATED_CONNECTION` - * * 22 - `LOCAL_HOST_TERMINATED_CONNECTION` - * @param {string} event - The event to listen to. - * @param {(reason: number) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `reason` The reason code reported back by the BLE stack - see Nordic's [`ble_hci.h` file](https://github.com/espruino/Espruino/blob/master/targetlibs/nrf5x_12/components/softdevice/s132/headers/ble_hci.h#L71) for more information - * @url http://www.espruino.com/Reference#l_NRF_disconnect + * + * @param {any} passphrase - Message to decrypt + * @param {any} key - Key to encrypt message - must be an `ArrayBuffer` of 128, 192, or 256 BITS + * @param {any} [options] - [optional] An object, may specify `{ iv : new Uint8Array(16), mode : 'CBC|CFB|CTR|OFB|ECB' }` + * @returns {any} Returns an `ArrayBuffer` + * @url http://www.espruino.com/Reference#l_AES_decrypt */ - static on(event: "disconnect", callback: (reason: number) => void): void; + static decrypt(passphrase: any, key: any, options?: any): ArrayBuffer; /** - * Called when the Nordic Bluetooth stack (softdevice) generates an error. In pretty - * much all cases an Exception will also have been thrown. - * @param {string} event - The event to listen to. - * @param {(msg: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `msg` The error string - * @url http://www.espruino.com/Reference#l_NRF_error + * Encrypt a message with a key using AES in CCM authenticated encryption mode. + * This returns an object with the encrypted data and a generated tag for message authentication. + * Usage example: + * ``` + * let message = "Hello World!"; + * let key = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]; + * let nonce = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66]; + * let tagLength = 4; + * let result = AES.ccmEncrypt(message, key, nonce, tagLength); + * ``` + * The `result` object should now have a `data` and `tag` attribute; both are needed for decrypting and verifying the message: + * ``` + * { + * data: [206, 98, 239, 219, 146, 157, 59, 123, 102, 92, 118, 209], + * tag: [230, 153, 191, 142] + * } + * ``` + * + * @param {any} message - Message to encrypt + * @param {any} key - Key to encrypt message - an `ArrayBuffer` of 128 BITS + * @param {any} iv - nonce (initialization vector) - an `ArrayBuffer` of 7 to 13 bytes + * @param {any} tagLen - Length of tag to generate in bytes - must be one of 4, 6, 8, 10, 12, 14 or 16 + * @returns {any} An object + * @url http://www.espruino.com/Reference#l_AES_ccmEncrypt */ - static on(event: "error", callback: (msg: any) => void): void; + static ccmEncrypt(message: any, key: any, iv: any, tagLen: any): AES_CCM_EncryptResult; /** - * (Added in 2v19) Called when a central device connects to Espruino, pairs, and sends a passkey that Espruino should display. - * For this to be used, you'll have to specify that your device has a display using `NRF.setSecurity({mitm:1, display:1});` - * For instance: + * Decrypt and authenticate an AES CCM encrypted message with an associated tag. + * Usage example: * ``` - * NRF.setSecurity({mitm:1, display:1}); - * NRF.on("passkey", key => print("Enter PIN: ",passkey)); + * let message = "Hello World!"; + * let key = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]; + * let nonce = [0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66]; + * let tagLength = 4; + * let result = AES.ccmEncrypt(message, key, nonce, tagLength); + * let decrypted = AES.ccmDecrypt(result.data, key, nonce, result.tag); + * let decryptedMessage = String.fromCharCode.apply(null, decrypted); * ``` - * It is also possible to specify a static passkey with `NRF.setSecurity({passkey:"123456", mitm:1, display:1});` - * in which case no `passkey` event handler is needed (this method works on Espruino 2v02 and later) - * **Note:** A similar event, [`BluetoothDevice.on("passkey", ...)`](http://www.espruino.com/Reference#l_BluetoothDevice_passkey) is available - * for when Espruino is connecting *to* another device (central mode). - * @param {string} event - The event to listen to. - * @param {(passkey: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `passkey` A 6 character numeric String to be displayed - * @url http://www.espruino.com/Reference#l_NRF_passkey + * The `decryptedMessage` variable should now contain "Hello World!". + * + * @param {any} message - Message to decrypt + * @param {any} key - Key to decrypt message - an `ArrayBuffer` of 128 BITS + * @param {any} iv - Nonce (initialization vector) - an `ArrayBuffer` of 7 to 13 bytes + * @param {any} tag - Tag that came with the message - an `ArrayBuffer` + * @returns {any} Decrypted message, or null on error (for example if the tag doesn't match) + * @url http://www.espruino.com/Reference#l_AES_ccmDecrypt */ - static on(event: "passkey", callback: (passkey: any) => void): void; + static ccmDecrypt(message: any, key: any, iv: any, tag: any): any; + +} + +/** + * Class containing utility functions for + * [Pixl.js](http://www.espruino.com/Pixl.js) + * @url http://www.espruino.com/Reference#Pixl + */ +declare class Pixl { /** - * Contains updates on the security of the current Bluetooth link. - * See Nordic's `ble_gap_evt_auth_status_t` structure for more information. - * @param {string} event - The event to listen to. - * @param {(status: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `status` An object containing `{auth_status,bonded,lv4,kdist_own,kdist_peer}` - * @url http://www.espruino.com/Reference#l_NRF_security + * **DEPRECATED** - Please use `E.getBattery()` instead. + * Return an approximate battery percentage remaining based on a normal CR2032 + * battery (2.8 - 2.2v) + * @returns {number} A percentage between 0 and 100 + * @url http://www.espruino.com/Reference#l_Pixl_getBatteryPercentage */ - static on(event: "security", callback: (status: any) => void): void; + static getBatteryPercentage(): number; /** - * Called when Bluetooth advertising starts or stops on Espruino - * @param {string} event - The event to listen to. - * @param {(isAdvertising: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `isAdvertising` Whether we are advertising or not - * @url http://www.espruino.com/Reference#l_NRF_advertising + * Set the LCD's contrast + * + * @param {number} c - Contrast between 0 and 1 + * @url http://www.espruino.com/Reference#l_Pixl_setContrast */ - static on(event: "advertising", callback: (isAdvertising: ShortBoolean) => void): void; + static setContrast(c: number): void; /** - * Called during the bonding process to update on status - * `status` is one of: - * * `"request"` - Bonding has been requested in code via `NRF.startBonding` - * * `"start"` - The bonding procedure has started - * * `"success"` - The bonding procedure has succeeded (`NRF.startBonding`'s promise resolves) - * * `"fail"` - The bonding procedure has failed (`NRF.startBonding`'s promise rejects) - * @param {string} event - The event to listen to. - * @param {(status: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `status` One of `'request'/'start'/'success'/'fail'` - * @url http://www.espruino.com/Reference#l_NRF_bond + * This function can be used to turn Pixl.js's LCD off or on. + * * With the LCD off, Pixl.js draws around 0.1mA + * * With the LCD on, Pixl.js draws around 0.25mA + * + * @param {boolean} isOn - True if the LCD should be on, false if not + * @url http://www.espruino.com/Reference#l_Pixl_setLCDPower */ - static on(event: "bond", callback: (status: any) => void): void; + static setLCDPower(isOn: ShortBoolean): void; /** - * Called with a single byte value when Espruino is set up as a HID device and the - * computer it is connected to sends a HID report back to Espruino. This is usually - * used for handling indications such as the Caps Lock LED. - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_NRF_HID + * Writes a command directly to the ST7567 LCD controller + * + * @param {number} c + * @url http://www.espruino.com/Reference#l_Pixl_lcdw */ - static on(event: "HID", callback: () => void): void; + static lcdw(c: number): void; /** - * Called with discovered services when discovery is finished - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_NRF_servicesDiscover + * Display a menu on Pixl.js's screen, and set up the buttons to navigate through + * it. + * DEPRECATED: Use `E.showMenu` + * + * @param {any} menu - An object containing name->function mappings to to be used in a menu + * @returns {any} A menu object with `draw`, `move` and `select` functions + * @url http://www.espruino.com/Reference#l_Pixl_menu */ - static on(event: "servicesDiscover", callback: () => void): void; + static menu(menu: Menu): MenuInstance; + +} + +/** + * This class helps to convert URLs into Objects of information ready for + * http.request/get + * @url http://www.espruino.com/Reference#url + */ +declare class url { /** - * Called with discovered characteristics when discovery is finished - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_NRF_characteristicsDiscover + * A utility function to split a URL into parts + * This is useful in web servers for instance when handling a request. + * For instance `url.parse("/a?b=c&d=e",true)` returns + * `{"method":"GET","host":"","path":"/a?b=c&d=e","pathname":"/a","search":"?b=c&d=e","port":80,"query":{"b":"c","d":"e"}}` + * + * @param {any} urlStr - A URL to be parsed + * @param {boolean} parseQuery - Whether to parse the query string into an object not (default = false) + * @returns {any} An object containing options for ```http.request``` or ```http.get```. Contains `method`, `host`, `path`, `pathname`, `search`, `port` and `query` + * @url http://www.espruino.com/Reference#l_url_parse */ - static on(event: "characteristicsDiscover", callback: () => void): void; + static parse(urlStr: any, parseQuery: ShortBoolean): any; + + +} + +/** + * The socket server created by `require('net').createServer` + * @url http://www.espruino.com/Reference#Server + */ +declare class Server { + /** - * Called when an NFC field is detected - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_NRF_NFCon + * Start listening for new connections on the given port + * + * @param {number} port - The port to listen on + * @returns {any} The HTTP server instance that 'listen' was called on + * @url http://www.espruino.com/Reference#l_Server_listen */ - static on(event: "NFCon", callback: () => void): void; + listen(port: number): any; /** - * Called when an NFC field is no longer detected - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_NRF_NFCoff + * Stop listening for new connections + * @url http://www.espruino.com/Reference#l_Server_close */ - static on(event: "NFCoff", callback: () => void): void; + close(): void; +} +/** + * An actual socket connection - allowing transmit/receive of TCP data + * @url http://www.espruino.com/Reference#Socket + */ +declare class Socket { /** - * When NFC is started with `NRF.nfcStart`, this is fired when NFC data is - * received. It doesn't get called if NFC is started with `NRF.nfcURL` or - * `NRF.nfcRaw` + * The 'data' event is called when data is received. If a handler is defined with + * `X.on('data', function(data) { ... })` then it will be called, otherwise data + * will be stored in an internal buffer, where it can be retrieved with `X.read()` * @param {string} event - The event to listen to. - * @param {(arr: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `arr` An ArrayBuffer containign the received data - * @url http://www.espruino.com/Reference#l_NRF_NFCrx + * @param {(data: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `data` A string containing one or more characters of received data + * @url http://www.espruino.com/Reference#l_Socket_data */ - static on(event: "NFCrx", callback: (arr: any) => void): void; + static on(event: "data", callback: (data: any) => void): void; /** - * If a device is connected to Espruino, disconnect from it. - * @url http://www.espruino.com/Reference#l_NRF_disconnect + * Called when the connection closes. + * @param {string} event - The event to listen to. + * @param {(had_error: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `had_error` A boolean indicating whether the connection had an error (use an error event handler to get error details). + * @url http://www.espruino.com/Reference#l_Socket_close */ - static disconnect(): void; + static on(event: "close", callback: (had_error: any) => void): void; /** - * Disable Bluetooth advertising and disconnect from any device that connected to - * Puck.js as a peripheral (this won't affect any devices that Puck.js initiated - * connections to). - * This makes Puck.js undiscoverable, so it can't be connected to. - * Use `NRF.wake()` to wake up and make Puck.js connectable again. - * @url http://www.espruino.com/Reference#l_NRF_sleep + * There was an error on this socket and it is closing (or wasn't opened in the + * first place). If a "connected" event was issued on this socket then the error + * event is always followed by a close event. The error codes are: + * * -1: socket closed (this is not really an error and will not cause an error + * callback) + * * -2: out of memory (typically while allocating a buffer to hold data) + * * -3: timeout + * * -4: no route + * * -5: busy + * * -6: not found (DNS resolution) + * * -7: max sockets (... exceeded) + * * -8: unsent data (some data could not be sent) + * * -9: connection reset (or refused) + * * -10: unknown error + * * -11: no connection + * * -12: bad argument + * * -13: SSL handshake failed + * * -14: invalid SSL data + * @param {string} event - The event to listen to. + * @param {(details: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `details` An error object with an error code (a negative integer) and a message. + * @url http://www.espruino.com/Reference#l_Socket_error */ - static sleep(): void; + static on(event: "error", callback: (details: any) => void): void; /** - * Enable Bluetooth advertising (this is enabled by default), which allows other - * devices to discover and connect to Puck.js. - * Use `NRF.sleep()` to disable advertising. - * @url http://www.espruino.com/Reference#l_NRF_wake + * An event that is fired when the buffer is empty and it can accept more data to + * send. + * @param {string} event - The event to listen to. + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_Socket_drain */ - static wake(): void; + static on(event: "drain", callback: () => void): void; /** - * Restart the Bluetooth softdevice (if there is currently a BLE connection, it - * will queue a restart to be done when the connection closes). - * You shouldn't need to call this function in normal usage. However, Nordic's BLE - * softdevice has some settings that cannot be reset. For example there are only a - * certain number of unique UUIDs. Once these are all used the only option is to - * restart the softdevice to clear them all out. - * - * @param {any} [callback] - [optional] A function to be called while the softdevice is uninitialised. Use with caution - accessing console/bluetooth will almost certainly result in a crash. - * @url http://www.espruino.com/Reference#l_NRF_restart + * Return how many bytes are available to read. If there is already a listener for + * data, this will always return 0. + * @returns {number} How many bytes are available + * @url http://www.espruino.com/Reference#l_Socket_available */ - static restart(callback?: any): void; + available(): number; /** - * Delete all data stored for all peers (bonding data used for secure connections). This cannot be done - * while a connection is active, so if there is a connection it will be postponed until everything is disconnected - * (which can be done by calling `NRF.disconnect()` and waiting). - * Booting your device while holding all buttons down together should also have the same effect. + * Return a string containing characters that have been received * - * @param {any} [callback] - [optional] A function to be called while the softdevice is uninitialised. Use with caution - accessing console/bluetooth will almost certainly result in a crash. - * @url http://www.espruino.com/Reference#l_NRF_eraseBonds + * @param {number} chars - The number of characters to read, or undefined/0 for all available + * @returns {any} A string containing the required bytes. + * @url http://www.espruino.com/Reference#l_Socket_read */ - static eraseBonds(callback?: any): void; + read(chars: number): any; /** - * Get this device's default or current Bluetooth MAC address. - * For Puck.js, the last 5 characters of this (e.g. `ee:ff`) are used in the - * device's advertised Bluetooth name. + * Pipe this to a stream (an object with a 'write' method) * - * @param {boolean} current - If true, return the current address rather than the default - * @returns {any} MAC address - a string of the form 'aa:bb:cc:dd:ee:ff' - * @url http://www.espruino.com/Reference#l_NRF_getAddress + * @param {any} destination - The destination file/stream that will receive content from the source. + * @param {any} [options] + * [optional] An object `{ chunkSize : int=32, end : bool=true, complete : function }` + * chunkSize : The amount of data to pipe from source to destination at a time + * complete : a function to call when the pipe activity is complete + * end : call the 'end' function on the destination when the source is finished + * @url http://www.espruino.com/Reference#l_Socket_pipe */ - static getAddress(current: ShortBoolean): any; + pipe(destination: any, options?: PipeOptions): void /** - * Set this device's default Bluetooth MAC address: + * This function writes the `data` argument as a string. Data that is passed in + * (including arrays) will be converted to a string with the normal JavaScript + * `toString` method. + * If you wish to send binary data then you need to convert that data directly to a + * String. This can be done with `String.fromCharCode`, however it's often easier + * and faster to use the Espruino-specific `E.toString`, which will read its + * arguments as an array of bytes and convert that to a String: * ``` - * NRF.setAddress("ff:ee:dd:cc:bb:aa random"); + * socket.write(E.toString([0,1,2,3,4,5])); + * ``` + * If you need to send something other than bytes, you can use 'Typed Arrays', or + * even `DataView`: + * ``` + * var d = new DataView(new ArrayBuffer(8)); // 8 byte array buffer + * d.setFloat32(0, 765.3532564); // write float at bytes 0-3 + * d.setInt8(4, 42); // write int8 at byte 4 + * socket.write(E.toString(d.buffer)) * ``` - * Addresses take the form: - * * `"ff:ee:dd:cc:bb:aa"` or `"ff:ee:dd:cc:bb:aa public"` for a public address - * * `"ff:ee:dd:cc:bb:aa random"` for a random static address (the default for - * Espruino) - * This may throw a `INVALID_BLE_ADDR` error if the upper two bits of the address - * don't match the address type. - * To change the address, Espruino must restart the softdevice. It will only do so - * when it is disconnected from other devices. * - * @param {any} addr - The address to use (as a string) - * @url http://www.espruino.com/Reference#l_NRF_setAddress + * @param {any} data - A string containing data to send + * @returns {boolean} For node.js compatibility, returns the boolean false. When the send buffer is empty, a `drain` event will be sent + * @url http://www.espruino.com/Reference#l_Socket_write */ - static setAddress(addr: any): void; + write(data: any): boolean; /** - * Try to resolve a **bonded** peer's address from a random private resolvable address. If the peer - * is not bonded, there will be no IRK and `undefined` will be returned. - * A bunch of devices, especially smartphones, implement address randomisation and periodically change - * their bluetooth address to prevent being tracked. - * If such a device uses a "random private resolvable address", that address is generated - * with the help of an identity resolving key (IRK) that is exchanged during bonding. - * If we know the IRK of a device, we can check if an address was potentially generated by that device. - * The following will check an address against the IRKs of all bonded devices, - * and return the actual address of a bonded device if the given address was likely generated using that device's IRK: - * ``` - * NRF.on('connect',addr=> { - * // addr could be "aa:bb:cc:dd:ee:ff private-resolvable" - * if (addr.endsWith("private-resolvable")) { - * let resolved = NRF.resolveAddress(addr); - * // resolved is "aa:bb:cc:dd:ee:ff public" - * if (resolved) addr = resolved; - * } - * console.log("Device connected: ", addr); - * }) - * ``` - * You can get the current connection's address using `NRF.getSecurityStatus().connected_addr`, - * so can for instance do `NRF.resolveAddress(NRF.getSecurityStatus().connected_addr)`. + * Close this socket - optional data to append as an argument. + * See `Socket.write` for more information about the data argument * - * @param {any} options - The address that should be resolved. - * @returns {any} The resolved address, or `undefined` if it couldn't be resolved. - * @url http://www.espruino.com/Reference#l_NRF_resolveAddress + * @param {any} data - A string containing data to send + * @url http://www.espruino.com/Reference#l_Socket_end */ - static resolveAddress(options: any): any; + end(data: any): void; +} +/** + * An actual socket connection - allowing transmit/receive of TCP data + * @url http://www.espruino.com/Reference#dgramSocket + */ +declare class dgramSocket { /** - * Get the battery level in volts (the voltage that the NRF chip is running off - * of). - * This is the battery level of the device itself - it has nothing to with any - * device that might be connected. - * @returns {number} Battery level in volts - * @url http://www.espruino.com/Reference#l_NRF_getBattery - */ - static getBattery(): number; - - /** - * Change the data that Espruino advertises. - * Data can be of the form `{ UUID : data_as_byte_array }`. The UUID should be a - * [Bluetooth Service - * ID](https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx). - * For example to return battery level at 95%, do: - * ``` - * NRF.setAdvertising({ - * 0x180F : [95] // Service data 0x180F = 95 - * }); - * ``` - * Or you could report the current temperature: - * ``` - * setInterval(function() { - * NRF.setAdvertising({ - * 0x1809 : [Math.round(E.getTemperature())] - * }); - * }, 30000); - * ``` - * If you specify a value for the object key, Service Data is advertised. However - * if you specify `undefined`, the Service UUID is advertised: - * ``` - * NRF.setAdvertising({ - * 0x180D : undefined // Advertise service UUID 0x180D (HRM) - * }); - * ``` - * Service UUIDs can also be supplied in the second argument of `NRF.setServices`, - * but those go in the scan response packet. - * You can also supply the raw advertising data in an array. For example to - * advertise as an Eddystone beacon: - * ``` - * NRF.setAdvertising([0x03, // Length of Service List - * 0x03, // Param: Service List - * 0xAA, 0xFE, // Eddystone ID - * 0x13, // Length of Service Data - * 0x16, // Service Data - * 0xAA, 0xFE, // Eddystone ID - * 0x10, // Frame type: URL - * 0xF8, // Power - * 0x03, // https:// - * 'g','o','o','.','g','l','/','B','3','J','0','O','c'], - * {interval:100}); - * ``` - * (However for Eddystone we'd advise that you use the [Espruino Eddystone - * library](/Puck.js+Eddystone)) - * **Note:** When specifying data as an array, certain advertising options such as - * `discoverable` and `showName` won't have any effect. - * **Note:** The size of Bluetooth LE advertising packets is limited to 31 bytes. - * If you want to advertise more data, consider using an array for `data` (See - * below), or `NRF.setScanResponse`. - * You can even specify an array of arrays or objects, in which case each - * advertising packet will be used in turn - for instance to make your device - * advertise battery level and its name as well as both Eddystone and iBeacon : - * ``` - * NRF.setAdvertising([ - * {0x180F : [E.getBattery()]}, // normal advertising, with battery % - * require("ble_ibeacon").get(...), // iBeacon - * require("ble_eddystone").get(...), // eddystone - * ], {interval:300}); - * ``` - * `options` is an object, which can contain: - * ``` - * { - * name: "Hello" // The name of the device - * showName: true/false // include full name, or nothing - * discoverable: true/false // general discoverable, or limited - default is limited - * connectable: true/false // whether device is connectable - default is true - * scannable : true/false // whether device can be scanned for scan response packets - default is true - * whenConnected : true/false // keep advertising when connected (nRF52 only) - * // switches to advertising as non-connectable when it is connected - * interval: 600 // Advertising interval in msec, between 20 and 10000 (default is 375ms) - * manufacturer: 0x0590 // IF sending manufacturer data, this is the manufacturer ID - * manufacturerData: [...] // IF sending manufacturer data, this is an array of data - * phy: "1mbps/2mbps/coded" // (NRF52833/NRF52840 only) use the long-range coded phy for transmission (1mbps default) - * } - * ``` - * Setting `connectable` and `scannable` to false gives the lowest power - * consumption as the BLE radio doesn't have to listen after sending advertising. - * **NOTE:** Non-`connectable` advertising can't have an advertising interval less - * than 100ms according to the BLE spec. - * So for instance to set the name of Puck.js without advertising any other data - * you can just use the command: - * ``` - * NRF.setAdvertising({},{name:"Hello"}); - * ``` - * You can also specify 'manufacturer data', which is another form of advertising - * data. We've registered the Manufacturer ID 0x0590 (as Pur3 Ltd) for use with - * *Official Espruino devices* - use it to advertise whatever data you'd like, but - * we'd recommend using JSON. - * For example by not advertising a device name you can send up to 24 bytes of JSON - * on Espruino's manufacturer ID: - * ``` - * var data = {a:1,b:2}; - * NRF.setAdvertising({},{ - * showName:false, - * manufacturer:0x0590, - * manufacturerData:JSON.stringify(data) - * }); - * ``` - * If you're using [EspruinoHub](https://github.com/espruino/EspruinoHub) then it - * will automatically decode this into the following MQTT topics: - * * `/ble/advertise/ma:c_:_a:dd:re:ss/espruino` -> `{"a":10,"b":15}` - * * `/ble/advertise/ma:c_:_a:dd:re:ss/a` -> `1` - * * `/ble/advertise/ma:c_:_a:dd:re:ss/b` -> `2` - * Note that **you only have 24 characters available for JSON**, so try to use the - * shortest field names possible and avoid floating point values that can be very - * long when converted to a String. - * - * @param {any} data - The service data to advertise as an object - see below for more info - * @param {any} [options] - [optional] Object of options - * @url http://www.espruino.com/Reference#l_NRF_setAdvertising - */ - static setAdvertising(data: any, options?: any): void; - - /** - * This is just like `NRF.setAdvertising`, except instead of advertising the data, - * it returns the packet that would be advertised as an array. - * - * @param {any} data - The data to advertise as an object - * @param {any} [options] - [optional] An object of options - * @returns {any} An array containing the advertising data - * @url http://www.espruino.com/Reference#l_NRF_getAdvertisingData - */ - static getAdvertisingData(data: any, options?: any): any; - - /** - * The raw scan response data should be supplied as an array. For example to return - * "Sample" for the device name: - * ``` - * NRF.setScanResponse([0x07, // Length of Data - * 0x09, // Param: Complete Local Name - * 'S', 'a', 'm', 'p', 'l', 'e']); - * ``` - * **Note:** `NRF.setServices(..., {advertise:[ ... ]})` writes advertised services - * into the scan response - so you can't use both `advertise` and `NRF.setServices` - * or one will overwrite the other. - * - * @param {any} data - The data to for the scan response - * @url http://www.espruino.com/Reference#l_NRF_setScanResponse - */ - static setScanResponse(data: any): void; - - /** - * Change the services and characteristics Espruino advertises. - * If you want to **change** the value of a characteristic, you need to use - * `NRF.updateServices()` instead - * To expose some information on Characteristic `ABCD` on service `BCDE` you could - * do: - * ``` - * NRF.setServices({ - * 0xBCDE : { - * 0xABCD : { - * value : "Hello", - * readable : true - * } - * } - * }); - * ``` - * Or to allow the 3 LEDs to be controlled by writing numbers 0 to 7 to a - * characteristic, you can do the following. `evt.data` is an ArrayBuffer. - * ``` - * NRF.setServices({ - * 0xBCDE : { - * 0xABCD : { - * writable : true, - * onWrite : function(evt) { - * digitalWrite([LED3,LED2,LED1], evt.data[0]); - * } - * } - * } - * }); - * ``` - * You can supply many different options: - * ``` - * NRF.setServices({ - * 0xBCDE : { - * 0xABCD : { - * value : "Hello", // optional - * maxLen : 5, // optional (otherwise is length of initial value) - * broadcast : false, // optional, default is false - * readable : true, // optional, default is false - * writable : true, // optional, default is false - * notify : true, // optional, default is false - * indicate : true, // optional, default is false - * description: "My Characteristic", // optional, default is null, - * security: { // optional - see NRF.setSecurity - * read: { // optional - * encrypted: false, // optional, default is false - * mitm: false, // optional, default is false - * lesc: false, // optional, default is false - * signed: false // optional, default is false - * }, - * write: { // optional - * encrypted: true, // optional, default is false - * mitm: false, // optional, default is false - * lesc: false, // optional, default is false - * signed: false // optional, default is false - * } - * }, - * onWrite : function(evt) { // optional - * console.log("Got ", evt.data); // an ArrayBuffer - * }, - * onWriteDesc : function(evt) { // optional - called when the 'cccd' descriptor is written - * // for example this is called when notifications are requested by the client: - * console.log("Notifications enabled = ", evt.data[0]&1); - * } - * } - * // more characteristics allowed - * } - * // more services allowed - * }); - * ``` - * **Note:** UUIDs can be integers between `0` and `0xFFFF`, strings of the form - * `"ABCD"`, or strings of the form `"ABCDABCD-ABCD-ABCD-ABCD-ABCDABCDABCD"` - * `options` can be of the form: - * ``` - * NRF.setServices(undefined, { - * hid : new Uint8Array(...), // optional, default is undefined. Enable BLE HID support - * uart : true, // optional, default is true. Enable BLE UART support - * advertise: [ '180D' ] // optional, list of service UUIDs to advertise - * ancs : true, // optional, Bangle.js-only, enable Apple ANCS support for notifications (see `NRF.ancs*`) - * ams : true // optional, Bangle.js-only, enable Apple AMS support for media control (see `NRF.ams*`) - * cts : true // optional, Bangle.js-only, enable Apple Current Time Service support (see `NRF.ctsGetTime`) - * }); - * ``` - * To enable BLE HID, you must set `hid` to an array which is the BLE report - * descriptor. The easiest way to do this is to use the `ble_hid_controls` or - * `ble_hid_keyboard` modules. - * **Note:** Just creating a service doesn't mean that the service will be - * advertised. It will only be available after a device connects. To advertise, - * specify the UUIDs you wish to advertise in the `advertise` field of the second - * `options` argument. For example this will create and advertise a heart rate - * service: - * ``` - * NRF.setServices({ - * 0x180D: { // heart_rate - * 0x2A37: { // heart_rate_measurement - * notify: true, - * value : [0x06, heartrate], - * } - * } - * }, { advertise: [ '180D' ] }); - * ``` - * You may specify 128 bit UUIDs to advertise, however you may get a `DATA_SIZE` - * exception because there is insufficient space in the Bluetooth LE advertising - * packet for the 128 bit UART UUID as well as the UUID you specified. In this case - * you can add `uart:false` after the `advertise` element to disable the UART, - * however you then be unable to connect to Puck.js's console via Bluetooth. - * If you absolutely require two or more 128 bit UUIDs then you will have to - * specify your own raw advertising data packets with `NRF.setAdvertising` - * **Note:** The services on Espruino can only be modified when there is no device - * connected to it as it requires a restart of the Bluetooth stack. **iOS devices - * will 'cache' the list of services** so apps like NRF Connect may incorrectly - * display the old services even after you have modified them. To fix this, disable - * and re-enable Bluetooth on your iOS device, or use an Android device to run NRF - * Connect. - * **Note:** Not all combinations of security configuration values are valid, the - * valid combinations are: encrypted, encrypted + mitm, lesc, signed, signed + - * mitm. See `NRF.setSecurity` for more information. - * - * @param {any} data - The service (and characteristics) to advertise - * @param {any} [options] - [optional] Object containing options - * @url http://www.espruino.com/Reference#l_NRF_setServices - */ - static setServices(data: { [key: number]: { [key: number]: { value?: string, maxLen?: number, broadcast?: boolean, readable?: boolean, writable?: boolean, notify?: boolean, indicate?: boolean, description?: string, security?: { read?: { encrypted?: boolean, mitm?: boolean, lesc?: boolean, signed?: boolean }, write?: { encrypted?: boolean, mitm?: boolean, lesc?: boolean, signed?: boolean } }, onWrite?: (evt: { data: ArrayBuffer }) => void } } }, options?: any): void; - - /** - * Update values for the services and characteristics Espruino advertises. Only - * services and characteristics previously declared using `NRF.setServices` are - * affected. - * To update the '0xABCD' characteristic in the '0xBCDE' service: - * ``` - * NRF.updateServices({ - * 0xBCDE : { - * 0xABCD : { - * value : "World" - * } - * } - * }); - * ``` - * You can also use 128 bit UUIDs, for example - * `"b7920001-3c1b-4b40-869f-3c0db9be80c6"`. - * To define a service and characteristic and then notify connected clients of a - * change to it when a button is pressed: - * ``` - * NRF.setServices({ - * 0xBCDE : { - * 0xABCD : { - * value : "Hello", - * maxLen : 20, - * notify: true - * } - * } - * }); - * setWatch(function() { - * NRF.updateServices({ - * 0xBCDE : { - * 0xABCD : { - * value : "World!", - * notify: true - * } - * } - * }); - * }, BTN, { repeat:true, edge:"rising", debounce: 50 }); - * ``` - * This only works if the characteristic was created with `notify: true` using - * `NRF.setServices`, otherwise the characteristic will be updated but no - * notification will be sent. - * Also note that `maxLen` was specified. If it wasn't then the maximum length of - * the characteristic would have been 5 - the length of `"Hello"`. - * To indicate (i.e. notify with ACK) connected clients of a change to the '0xABCD' - * characteristic in the '0xBCDE' service: - * ``` - * NRF.updateServices({ - * 0xBCDE : { - * 0xABCD : { - * value : "World", - * indicate: true - * } - * } - * }); - * ``` - * This only works if the characteristic was created with `indicate: true` using - * `NRF.setServices`, otherwise the characteristic will be updated but no - * notification will be sent. - * **Note:** See `NRF.setServices` for more information - * - * @param {any} data - The service (and characteristics) to update - * @url http://www.espruino.com/Reference#l_NRF_updateServices - */ - static updateServices(data: any): void; - - /** - * Start/stop listening for BLE advertising packets within range. Returns a - * `BluetoothDevice` for each advertising packet. **By default this is not an active - * scan, so Scan Response advertising data is not included (see below)** - * ``` - * // Start scanning - * packets=10; - * NRF.setScan(function(d) { - * packets--; - * if (packets<=0) - * NRF.setScan(); // stop scanning - * else - * console.log(d); // print packet info - * }); - * ``` - * Each `BluetoothDevice` will look a bit like: - * ``` - * BluetoothDevice { - * "id": "aa:bb:cc:dd:ee:ff", // address - * "rssi": -89, // signal strength - * "services": [ "128bit-uuid", ... ], // zero or more service UUIDs - * "data": new Uint8Array([ ... ]).buffer, // ArrayBuffer of returned data - * "serviceData" : { "0123" : [ 1 ] }, // if service data is in 'data', it's extracted here - * "manufacturer" : 0x1234, // if manufacturer data is in 'data', the 16 bit manufacturer ID is extracted here - * "manufacturerData" : new Uint8Array([...]).buffer, // if manufacturer data is in 'data', the data is extracted here as an ArrayBuffer - * "name": "DeviceName" // the advertised device name - * } - * ``` - * You can also supply a set of filters (as described in `NRF.requestDevice`) as a - * second argument, which will allow you to filter the devices you get a callback - * for. This helps to cut down on the time spent processing JavaScript code in - * areas with a lot of Bluetooth advertisements. For example to find only devices - * with the manufacturer data `0x0590` (Espruino's ID) you could do: - * ``` - * NRF.setScan(function(d) { - * console.log(d.manufacturerData); - * }, { filters: [{ manufacturerData:{0x0590:{}} }] }); - * ``` - * You can also specify `active:true` in the second argument to perform active - * scanning (this requests scan response packets) from any devices it finds. - * **Note:** Using a filter in `setScan` filters each advertising packet - * individually. As a result, if you filter based on a service UUID and a device - * advertises with multiple packets (or a scan response when `active:true`) only - * the packets matching the filter are returned. To aggregate multiple packets you - * can use `NRF.findDevices`. - * **Note:** BLE advertising packets can arrive quickly - faster than you'll be - * able to print them to the console. It's best only to print a few, or to use a - * function like `NRF.findDevices(..)` which will collate a list of available - * devices. - * **Note:** Using setScan turns the radio's receive mode on constantly. This can - * draw a *lot* of power (12mA or so), so you should use it sparingly or you can - * run your battery down quickly. - * - * @param {any} callback - The callback to call with received advertising packets, or undefined to stop - * @param {any} [options] - [optional] An object `{filters: ...}` (as would be passed to `NRF.requestDevice`) to filter devices by - * @url http://www.espruino.com/Reference#l_NRF_setScan - */ - static setScan(callback: any, options?: any): void; - - /** - * This function can be used to quickly filter through Bluetooth devices. - * For instance if you wish to scan for multiple different types of device at the - * same time then you could use `NRF.findDevices` with all the filters you're - * interested in. When scanning is finished you can then use `NRF.filterDevices` to - * pick out just the devices of interest. - * ``` - * // the two types of device we're interested in - * var filter1 = [{serviceData:{"fe95":{}}}]; - * var filter2 = [{namePrefix:"Pixl.js"}]; - * // the following filter will return both types of device - * var allFilters = filter1.concat(filter2); - * // now scan for both types of device, and filter them out afterwards - * NRF.findDevices(function(devices) { - * var devices1 = NRF.filterDevices(devices, filter1); - * var devices2 = NRF.filterDevices(devices, filter2); - * // ... - * }, {filters : allFilters}); - * ``` - * - * @param {any} devices - An array of `BluetoothDevice` objects, from `NRF.findDevices` or similar - * @param {any} filters - A list of filters (as would be passed to `NRF.requestDevice`) to filter devices by - * @returns {any} An array of `BluetoothDevice` objects that match the given filters - * @url http://www.espruino.com/Reference#l_NRF_filterDevices - */ - static filterDevices(devices: any, filters: any): any; - - /** - * Utility function to return a list of BLE devices detected in range. Behind the - * scenes, this uses `NRF.setScan(...)` and collates the results. - * ``` - * NRF.findDevices(function(devices) { - * console.log(devices); - * }, 1000); - * ``` - * prints something like: - * ``` - * [ - * BluetoothDevice { - * "id" : "e7:e0:57:ad:36:a2 random", - * "rssi": -45, - * "services": [ "4567" ], - * "serviceData" : { "0123" : [ 1 ] }, - * "manufacturer" : 1424, - * "manufacturerData" : new Uint8Array([ ... ]).buffer, - * "data": new ArrayBuffer([ ... ]).buffer, - * "name": "Puck.js 36a2" - * }, - * BluetoothDevice { - * "id": "c0:52:3f:50:42:c9 random", - * "rssi": -65, - * "data": new ArrayBuffer([ ... ]), - * "name": "Puck.js 8f57" - * } - * ] - * ``` - * For more information on the structure returned, see `NRF.setScan`. - * If you want to scan only for specific devices you can replace the timeout with - * an object of the form `{filters: ..., timeout : ..., active: bool}` using the - * filters described in `NRF.requestDevice`. For example to search for devices with - * Espruino's `manufacturerData`: - * ``` - * NRF.findDevices(function(devices) { - * ... - * }, {timeout : 2000, filters : [{ manufacturerData:{0x0590:{}} }] }); - * ``` - * You could then use - * [`BluetoothDevice.gatt.connect(...)`](/Reference#l_BluetoothRemoteGATTServer_connect) - * on the device returned to make a connection. - * You can also use [`NRF.connect(...)`](/Reference#l_NRF_connect) on just the `id` - * string returned, which may be useful if you always want to connect to a specific - * device. - * **Note:** Using findDevices turns the radio's receive mode on for 2000ms (or - * however long you specify). This can draw a *lot* of power (12mA or so), so you - * should use it sparingly or you can run your battery down quickly. - * **Note:** The 'data' field contains the data of *the last packet received*. - * There may have been more packets. To get data for each packet individually use - * `NRF.setScan` instead. - * - * @param {any} callback - The callback to call with received advertising packets (as `BluetoothDevice`), or undefined to stop - * @param {any} [options] - [optional] A time in milliseconds to scan for (defaults to 2000), Or an optional object `{filters: ..., timeout : ..., active: bool}` (as would be passed to `NRF.requestDevice`) to filter devices by - * @url http://www.espruino.com/Reference#l_NRF_findDevices - */ - static findDevices(callback: (devices: BluetoothDevice[]) => void, options?: number | { filters?: NRFFilters[], timeout?: number, active?: boolean }): void; - - /** - * Start/stop listening for RSSI values on the currently active connection (where - * This device is a peripheral and is being connected to by a 'central' device) - * ``` - * // Start scanning - * NRF.setRSSIHandler(function(rssi) { - * console.log(rssi); // prints -85 (or similar) - * }); - * // Stop Scanning - * NRF.setRSSIHandler(); - * ``` - * RSSI is the 'Received Signal Strength Indication' in dBm - * - * @param {any} callback - The callback to call with the RSSI value, or undefined to stop - * @url http://www.espruino.com/Reference#l_NRF_setRSSIHandler - */ - static setRSSIHandler(callback: any): void; - - /** - * Set the BLE radio transmit power. The default TX power is 0 dBm, and - * - * @param {number} power - Transmit power. Accepted values are -40(nRF52 only), -30(nRF51 only), -20, -16, -12, -8, -4, 0, and 4 dBm. On nRF52840 (eg Bangle.js 2) 5/6/7/8 dBm are available too. Others will give an error code. - * @url http://www.espruino.com/Reference#l_NRF_setTxPower - */ - static setTxPower(power: number): void; - - /** - * **THIS IS DEPRECATED** - please use `NRF.setConnectionInterval` for peripheral - * and `NRF.connect(address, options)`/`BluetoothRemoteGATTServer.connect(options)` - * for central connections. - * This sets the connection parameters - these affect the transfer speed and power - * usage when the device is connected. - * * When not low power, the connection interval is between 7.5 and 20ms - * * When low power, the connection interval is between 500 and 1000ms - * When low power connection is enabled, transfers of data over Bluetooth will be - * very slow, however power usage while connected will be drastically decreased. - * This will only take effect after the connection is disconnected and - * re-established. - * - * @param {boolean} lowPower - Whether the connection is low power or not - * @url http://www.espruino.com/Reference#l_NRF_setLowPowerConnection - */ - static setLowPowerConnection(lowPower: ShortBoolean): void; - - /** - * Enables NFC and starts advertising the given URL. For example: - * ``` - * NRF.nfcURL("http://espruino.com"); - * ``` - * - * @param {any} url - The URL string to expose on NFC, or `undefined` to disable NFC - * @url http://www.espruino.com/Reference#l_NRF_nfcURL - */ - static nfcURL(url: any): void; - - /** - * Enables NFC and with an out of band 16 byte pairing key. - * For example the following will enable out of band pairing on BLE such that the - * device will pair when you tap the phone against it: - * ``` - * var bleKey = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00]; - * NRF.on('security',s=>print("security",JSON.stringify(s))); - * NRF.nfcPair(bleKey); - * NRF.setSecurity({oob:bleKey, mitm:true}); - * ``` - * - * @param {any} key - 16 byte out of band key - * @url http://www.espruino.com/Reference#l_NRF_nfcPair - */ - static nfcPair(key: any): void; - - /** - * Enables NFC with a record that will launch the given android app. - * For example: - * ``` - * NRF.nfcAndroidApp("no.nordicsemi.android.nrftoolbox") - * ``` - * - * @param {any} app - The unique identifier of the given Android App - * @url http://www.espruino.com/Reference#l_NRF_nfcAndroidApp - */ - static nfcAndroidApp(app: any): void; - - /** - * Enables NFC and starts advertising with Raw data. For example: - * ``` - * NRF.nfcRaw(new Uint8Array([193, 1, 0, 0, 0, 13, 85, 3, 101, 115, 112, 114, 117, 105, 110, 111, 46, 99, 111, 109])); - * // same as NRF.nfcURL("http://espruino.com"); - * ``` - * - * @param {any} payload - The NFC NDEF message to deliver to the reader - * @url http://www.espruino.com/Reference#l_NRF_nfcRaw - */ - static nfcRaw(payload: any): void; - - /** - * **Advanced NFC Functionality.** If you just want to advertise a URL, use - * `NRF.nfcURL` instead. - * Enables NFC and starts advertising. `NFCrx` events will be fired when data is - * received. - * ``` - * NRF.nfcStart(); - * ``` - * - * @param {any} payload - Optional 7 byte UID - * @returns {any} Internal tag memory (first 10 bytes of tag data) - * @url http://www.espruino.com/Reference#l_NRF_nfcStart - */ - static nfcStart(payload: any): any; - - /** - * **Advanced NFC Functionality.** If you just want to advertise a URL, use - * `NRF.nfcURL` instead. - * Disables NFC. - * ``` - * NRF.nfcStop(); - * ``` - * - * @url http://www.espruino.com/Reference#l_NRF_nfcStop - */ - static nfcStop(): void; - - /** - * **Advanced NFC Functionality.** If you just want to advertise a URL, use - * `NRF.nfcURL` instead. - * Acknowledges the last frame and optionally transmits a response. If payload is - * an array, then a array.length byte nfc frame is sent. If payload is a int, then - * a 4bit ACK/NACK is sent. **Note:** ```nfcSend``` should always be called after - * an ```NFCrx``` event. - * ``` - * NRF.nfcSend(new Uint8Array([0x01, 0x02, ...])); - * // or - * NRF.nfcSend(0x0A); - * // or - * NRF.nfcSend(); - * ``` - * - * @param {any} payload - Optional tx data - * @url http://www.espruino.com/Reference#l_NRF_nfcSend - */ - static nfcSend(payload: any): void; - - /** - * Send a USB HID report. HID must first be enabled with `NRF.setServices({}, {hid: - * hid_report})` - * - * @param {any} data - Input report data as an array - * @param {any} callback - A callback function to be called when the data is sent - * @url http://www.espruino.com/Reference#l_NRF_sendHIDReport - */ - static sendHIDReport(data: number[], callback?: () => void): void - - /** - * Check if Apple Notification Center Service (ANCS) is currently active on the BLE - * connection - * - * @returns {boolean} True if Apple Notification Center Service (ANCS) has been initialised and is active - * @url http://www.espruino.com/Reference#l_NRF_ancsIsActive - */ - static ancsIsActive(): boolean; - - /** - * Send an ANCS action for a specific Notification UID. Corresponds to - * posaction/negaction in the 'ANCS' event that was received - * - * @param {number} uid - The UID of the notification to respond to - * @param {boolean} positive - `true` for positive action, `false` for negative - * @url http://www.espruino.com/Reference#l_NRF_ancsAction - */ - static ancsAction(uid: number, positive: ShortBoolean): void; - - /** - * Get ANCS info for a notification event received via `E.ANCS`, e.g.: - * ``` - * E.on('ANCS', event => { - * NRF.ancsGetNotificationInfo( event.uid ).then(a=>print("Notify",E.toJS(a))); - * }); - * ``` - * Returns: - * ``` - * { - * "uid" : integer, - * "appId": string, - * "title": string, - * "subtitle": string, - * "message": string, - * "messageSize": string, - * "date": string, - * "posAction": string, - * "negAction": string - * } - * ``` - * - * @param {number} uid - The UID of the notification to get information for - * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete - * @url http://www.espruino.com/Reference#l_NRF_ancsGetNotificationInfo - */ - static ancsGetNotificationInfo(uid: number): Promise; - - /** - * Get ANCS info for an app (app id is available via `NRF.ancsGetNotificationInfo`) - * Promise returns: - * ``` - * { - * "uid" : int, - * "appId" : string, - * "title" : string, - * "subtitle" : string, - * "message" : string, - * "messageSize" : string, - * "date" : string, - * "posAction" : string, - * "negAction" : string, - * "name" : string, - * } - * ``` - * - * @param {any} id - The app ID to get information for - * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete - * @url http://www.espruino.com/Reference#l_NRF_ancsGetAppInfo - */ - static ancsGetAppInfo(id: any): Promise; - - /** - * Check if Apple Media Service (AMS) is currently active on the BLE connection - * - * @returns {boolean} True if Apple Media Service (AMS) has been initialised and is active - * @url http://www.espruino.com/Reference#l_NRF_amsIsActive - */ - static amsIsActive(): boolean; - - /** - * Get Apple Media Service (AMS) info for the current media player. "playbackinfo" - * returns a concatenation of three comma-separated values: - * - PlaybackState: a string that represents the integer value of the playback - * state: - * - PlaybackStatePaused = 0 - * - PlaybackStatePlaying = 1 - * - PlaybackStateRewinding = 2 - * - PlaybackStateFastForwarding = 3 - * - PlaybackRate: a string that represents the floating point value of the - * playback rate. - * - ElapsedTime: a string that represents the floating point value of the elapsed - * time of the current track, in seconds - * - * @param {any} id - Either 'name', 'playbackinfo' or 'volume' - * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete - * @url http://www.espruino.com/Reference#l_NRF_amsGetPlayerInfo - */ - static amsGetPlayerInfo(id: any): Promise; - - /** - * Get Apple Media Service (AMS) info for the currently-playing track - * - * @param {any} id - Either 'artist', 'album', 'title' or 'duration' - * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete - * @url http://www.espruino.com/Reference#l_NRF_amsGetTrackInfo - */ - static amsGetTrackInfo(id: any): Promise; - - /** - * Send an AMS command to an Apple Media Service device to control music playback - * Command is one of play, pause, playpause, next, prev, volup, voldown, repeat, - * shuffle, skipforward, skipback, like, dislike, bookmark - * - * @param {any} id - For example, 'play', 'pause', 'volup' or 'voldown' - * @url http://www.espruino.com/Reference#l_NRF_amsCommand - */ - static amsCommand(id: any): void; - - /** - * Check if Apple Current Time Service (CTS) is currently active on the BLE connection - * - * @returns {boolean} True if Apple Current Time Service (CTS) has been initialised and is active - * @url http://www.espruino.com/Reference#l_NRF_ctsIsActive - */ - static ctsIsActive(): boolean; - - /** - * Returns time information from the Current Time Service - * (if requested with `NRF.ctsGetTime` and is activated by calling `NRF.setServices(..., {..., cts:true})`) - * ``` - * { - * date : // Date object with the current date - * day : // if known, 0=sun,1=mon (matches JS `Date`) - * reason : [ // reason for the date change - * "external", // External time change - * "manual", // Manual update - * "timezone", // Timezone changed - * "DST", // Daylight savings - * ] - * timezone // if LTI characteristic exists, this is the timezone - * dst // if LTI characteristic exists, this is the dst adjustment - * } - * ``` - * For instance this can be used as follows to update Espruino's time: - * ``` - * E.on('CTS',e=>{ - * setTime(e.date.getTime()/1000); - * }); - * NRF.ctsGetTime(); // also returns a promise with CTS info - * ``` - * @param {string} event - The event to listen to. - * @param {(info: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `info` An object (see below) - * @url http://www.espruino.com/Reference#l_NRF_CTS - */ - static on(event: "CTS", callback: (info: any) => void): void; - - /** - * Read the time from CTS - creates an `NRF.on('CTS', ...)` event as well - * ``` - * NRF.ctsGetTime(); // also returns a promise - * ``` - * @returns {any} A `Promise` that is resolved (or rejected) when time is received - * @url http://www.espruino.com/Reference#l_NRF_ctsGetTime - */ - static ctsGetTime(): Promise; - - /** - * Search for available devices matching the given filters. Since we have no UI - * here, Espruino will pick the FIRST device it finds, or it'll call `catch`. - * `options` can have the following fields: - * * `filters` - a list of filters that a device must match before it is returned - * (see below) - * * `timeout` - the maximum time to scan for in milliseconds (scanning stops when - * a match is found. e.g. `NRF.requestDevice({ timeout:2000, filters: [ ... ] })` - * * `active` - whether to perform active scanning (requesting 'scan response' - * packets from any devices that are found). e.g. `NRF.requestDevice({ active:true, - * filters: [ ... ] })` - * * `phy` - (NRF52833/NRF52840 only) the type of Bluetooth signals to scan for (can - * be `"1mbps/coded/both/2mbps"`) - * * `1mbps` (default) - standard Bluetooth LE advertising - * * `coded` - long range - * * `both` - standard and long range - * * `2mbps` - high speed 2mbps (not working) - * * `extended` - (NRF52833/NRF52840 only) support receiving extended-length advertising - * packets (default=true if phy isn't `"1mbps"`) - * * `extended` - (NRF52833/NRF52840 only) support receiving extended-length advertising - * packets (default=true if phy isn't `"1mbps"`) - * * `window` - (2v22+) how long we scan for in milliseconds (default 100ms) - * * `interval` - (2v22+) how often we scan in milliseconds (default 100ms) - `window=interval=100`(default) is all the time. When - * scanning on both `1mbps` and `coded`, `interval` needs to be twice `window`. - * **NOTE:** `timeout` and `active` are not part of the Web Bluetooth standard. - * The following filter types are implemented: - * * `services` - list of services as strings (all of which must match). 128 bit - * services must be in the form '01230123-0123-0123-0123-012301230123' - * * `name` - exact device name - * * `namePrefix` - starting characters of device name - * * `id` - exact device address (`id:"e9:53:86:09:89:99 random"`) (this is - * Espruino-specific, and is not part of the Web Bluetooth spec) - * * `serviceData` - an object containing service characteristics which must all - * match (`serviceData:{"1809":{}}`). Matching of actual service data is not - * supported yet. - * * `manufacturerData` - an object containing manufacturer UUIDs which must all - * match (`manufacturerData:{0x0590:{}}`). Matching of actual manufacturer data - * is not supported yet. - * ``` - * NRF.requestDevice({ filters: [{ namePrefix: 'Puck.js' }] }).then(function(device) { ... }); - * // or - * NRF.requestDevice({ filters: [{ services: ['1823'] }] }).then(function(device) { ... }); - * // or - * NRF.requestDevice({ filters: [{ manufacturerData:{0x0590:{}} }] }).then(function(device) { ... }); - * ``` - * As a full example, to send data to another Puck.js to turn an LED on: - * ``` - * var gatt; - * NRF.requestDevice({ filters: [{ namePrefix: 'Puck.js' }] }).then(function(device) { - * return device.gatt.connect(); - * }).then(function(g) { - * gatt = g; - * return gatt.getPrimaryService("6e400001-b5a3-f393-e0a9-e50e24dcca9e"); - * }).then(function(service) { - * return service.getCharacteristic("6e400002-b5a3-f393-e0a9-e50e24dcca9e"); - * }).then(function(characteristic) { - * return characteristic.writeValue("LED1.set()\n"); - * }).then(function() { - * gatt.disconnect(); - * console.log("Done!"); - * }); - * ``` - * Or slightly more concisely, using ES6 arrow functions: - * ``` - * var gatt; - * NRF.requestDevice({ filters: [{ namePrefix: 'Puck.js' }]}).then( - * device => device.gatt.connect()).then( - * g => (gatt=g).getPrimaryService("6e400001-b5a3-f393-e0a9-e50e24dcca9e")).then( - * service => service.getCharacteristic("6e400002-b5a3-f393-e0a9-e50e24dcca9e")).then( - * characteristic => characteristic.writeValue("LED1.reset()\n")).then( - * () => { gatt.disconnect(); console.log("Done!"); } ); - * ``` - * Note that you have to keep track of the `gatt` variable so that you can - * disconnect the Bluetooth connection when you're done. - * **Note:** Using a filter in `NRF.requestDevice` filters each advertising packet - * individually. As soon as a matching advertisement is received, - * `NRF.requestDevice` resolves the promise and stops scanning. This means that if - * you filter based on a service UUID and a device advertises with multiple packets - * (or a scan response when `active:true`) only the packet matching the filter is - * returned - you may not get the device's name is that was in a separate packet. - * To aggregate multiple packets you can use `NRF.findDevices`. - * - * @param {any} options - Options used to filter the device to use - * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete - * @url http://www.espruino.com/Reference#l_NRF_requestDevice - */ - static requestDevice(options?: { filters?: NRFFilters[], timeout?: number, active?: boolean, phy?: string, extended?: boolean }): Promise; - - /** - * Connect to a BLE device by MAC address. Returns a promise, the argument of which - * is the `BluetoothRemoteGATTServer` connection. - * ``` - * NRF.connect("aa:bb:cc:dd:ee").then(function(server) { - * // ... - * }); - * ``` - * This has the same effect as calling `BluetoothDevice.gatt.connect` on a - * `BluetoothDevice` requested using `NRF.requestDevice`. It just allows you to - * specify the address directly (without having to scan). - * You can use it as follows - this would connect to another Puck device and turn - * its LED on: - * ``` - * var gatt; - * NRF.connect("aa:bb:cc:dd:ee random").then(function(g) { - * gatt = g; - * return gatt.getPrimaryService("6e400001-b5a3-f393-e0a9-e50e24dcca9e"); - * }).then(function(service) { - * return service.getCharacteristic("6e400002-b5a3-f393-e0a9-e50e24dcca9e"); - * }).then(function(characteristic) { - * return characteristic.writeValue("LED1.set()\n"); - * }).then(function() { - * gatt.disconnect(); - * console.log("Done!"); - * }); - * ``` - * **Note:** Espruino Bluetooth devices use a type of BLE address known as 'random - * static', which is different to a 'public' address. To connect to an Espruino - * device you'll need to use an address string of the form `"aa:bb:cc:dd:ee - * random"` rather than just `"aa:bb:cc:dd:ee"`. If you scan for devices with - * `NRF.findDevices`/`NRF.setScan` then addresses are already reported in the - * correct format. - * - * @param {any} mac - The MAC address to connect to - * @param {any} options - (Espruino-specific) An object of connection options (see `BluetoothRemoteGATTServer.connect` for full details) - * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete - * @url http://www.espruino.com/Reference#l_NRF_connect - */ - static connect(mac: any, options: any): Promise; - - /** - * If set to true, whenever a device bonds it will be added to the whitelist. - * When set to false, the whitelist is cleared and newly bonded devices will not be - * added to the whitelist. - * **Note:** This is remembered between `reset()`s but isn't remembered after - * power-on (you'll have to add it to `onInit()`. - * - * @param {boolean} whitelisting - Are we using a whitelist? (default false) - * @url http://www.espruino.com/Reference#l_NRF_setWhitelist - */ - static setWhitelist(whitelisting: ShortBoolean): void; - - /** - * When connected, Bluetooth LE devices communicate at a set interval. Lowering the - * interval (e.g. more packets/second) means a lower delay when sending data, higher - * bandwidth, but also more power consumption. - * By default, when connected as a peripheral Espruino automatically adjusts the - * connection interval. When connected it's as fast as possible (7.5ms) but when - * idle for over a minute it drops to 200ms. On continued activity (>1 BLE - * operation) the interval is raised to 7.5ms again. - * The options for `interval` are: - * * `undefined` / `"auto"` : (default) automatically adjust connection interval - * * `100` : set min and max connection interval to the same number (between 7.5ms - * and 4000ms) - * * `{minInterval:20, maxInterval:100}` : set min and max connection interval as a - * range - * This configuration is not remembered during a `save()` - you will have to re-set - * it via `onInit`. - * **Note:** If connecting to another device (as Central), you can use an extra - * argument to `NRF.connect` or `BluetoothRemoteGATTServer.connect` to specify a - * connection interval. - * **Note:** This overwrites any changes imposed by the deprecated - * `NRF.setLowPowerConnection` - * - * @param {any} interval - The connection interval to use (see below) - * @url http://www.espruino.com/Reference#l_NRF_setConnectionInterval - */ - static setConnectionInterval(interval: any): void; - - /** - * Sets the security options used when connecting/pairing. This applies to both - * central *and* peripheral mode. - * ``` - * NRF.setSecurity({ - * display : bool // default false, can this device display a passkey on a screen/etc? - * // - sent via the `BluetoothDevice.passkey` event - * keyboard : bool // default false, can this device enter a passkey - * // - request sent via the `BluetoothDevice.passkeyRequest` event - * pair : bool // default true, allow other devices to pair with this device - * bond : bool // default true, Perform bonding - * // This stores info from pairing in flash and allows reconnecting without having to pair each time - * mitm : bool // default false, Man In The Middle protection - * lesc : bool // default false, LE Secure Connections - * passkey : // default "", or a 6 digit passkey to use (display must be true for this) - * oob : [0..15] // if specified, Out Of Band pairing is enabled and - * // the 16 byte pairing code supplied here is used - * encryptUart : bool // default false (unless oob or passkey specified) - * // This sets the BLE UART service such that it - * // is encrypted and can only be used from a paired connection - * privacy : // default false, true to enable with (ideally sensible) defaults, - * // or an object defining BLE privacy / random address options - see below for more info - * // only available if Espruino was compiled with private address support (like for example on Bangle.js 2) - * }); - * ``` - * **NOTE:** Some combinations of arguments will cause an error. For example - * supplying a passkey without `display:1` is not allowed. If `display:1` is set - * you do not require a physical display, the user just needs to know the passkey - * you supplied. - * For instance, to require pairing and to specify a passkey, use: - * ``` - * NRF.setSecurity({passkey:"123456", mitm:1, display:1}); - * ``` - * Or to require pairing and to display a PIN that the connecting device - * provides, use: - * ``` - * NRF.setSecurity({mitm:1, display:1}); - * NRF.on("passkey", key => print("Enter PIN: ", key)); - * ``` - * However, while most devices will request a passkey for pairing at this point it - * is still possible for a device to connect without requiring one (e.g. using the - * 'NRF Connect' app). - * To force a passkey you need to protect each characteristic you define with - * `NRF.setSecurity`. For instance the following code will *require* that the - * passkey `123456` is entered before the characteristic - * `9d020002-bf5f-1d1a-b52a-fe52091d5b12` can be read. - * ``` - * NRF.setSecurity({passkey:"123456", mitm:1, display:1}); - * NRF.setServices({ - * "9d020001-bf5f-1d1a-b52a-fe52091d5b12" : { - * "9d020002-bf5f-1d1a-b52a-fe52091d5b12" : { - * // readable always - * value : "Not Secret" - * }, - * "9d020003-bf5f-1d1a-b52a-fe52091d5b12" : { - * // readable only once bonded - * value : "Secret", - * readable : true, - * security: { - * read: { - * mitm: true, - * encrypted: true - * } - * } - * }, - * "9d020004-bf5f-1d1a-b52a-fe52091d5b12" : { - * // readable always - * // writable only once bonded - * value : "Readable", - * readable : true, - * writable : true, - * onWrite : function(evt) { - * console.log("Wrote ", evt.data); - * }, - * security: { - * write: { - * mitm: true, - * encrypted: true - * } - * } - * } - * } - * }); - * ``` - * **Note:** If `passkey` or `oob` is specified, the Nordic UART service (if - * enabled) will automatically be set to require encryption, but otherwise it is - * open. - * On Bangle.js 2, the `privacy` parameter can be used to set this device's BLE privacy / random address settings. - * The privacy feature provides a way to avoid being tracked over a period of time. - * This works by replacing the real BLE address with a random private address, - * that automatically changes at a specified interval. - * If a `"random_private_resolvable"` address is used, that address is generated with the help - * of an identity resolving key (IRK), that is exchanged during bonding. - * This allows a bonded device to still identify another device that is using a random private resolvable address. - * Note that, while this can help against being tracked, there are other ways a Bluetooth device can reveal its identity. - * For example, the name or services it advertises may be unique enough. - * ``` - * NRF.setSecurity({ - * privacy: { - * mode : "off"/"device_privacy"/"network_privacy" // The privacy mode that should be used. - * addr_type : "random_private_resolvable"/"random_private_non_resolvable" // The type of address to use. - * addr_cycle_s : int // How often the address should change, in seconds. - * } - * }); - * // enabled with (ideally sensible) defaults of: - * // mode: device_privacy - * // addr_type: random_private_resolvable - * // addr_cycle_s: 0 (use default address change interval) - * NRF.setSecurity({ - * privacy: 1 - * }); - * ``` - * `mode` can be one of: - * * `"off"` - Use the real address. - * * `"device_privacy"` - Use a private address. - * * `"network_privacy"` - Use a private address, - * and reject a peer that uses its real address if we know that peer's IRK. - * If `mode` is `"off"`, all other fields are ignored and become optional. - * `addr_type` can be one of: - * * `"random_private_resolvable"` - Address that can be resolved by a bonded peer that knows our IRK. - * * `"random_private_non_resolvable"` - Address that cannot be resolved. - * `addr_cycle_s` must be an integer. Pass `0` to use the default address change interval. - * The default is usually to change the address every 15 minutes (or 900 seconds). - * - * @param {any} options - An object containing security-related options (see below) - * @url http://www.espruino.com/Reference#l_NRF_setSecurity + * The 'message' event is called when a datagram message is received. If a handler + * is defined with `X.on('message', function(msg) { ... })` then it will be called + * @param {string} event - The event to listen to. + * @param {(msg: any, rinfo: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `msg` A string containing the received message + * * `rinfo` Sender address,port containing information + * @url http://www.espruino.com/Reference#l_dgramSocket_message */ - static setSecurity(options: any): void; + static on(event: "message", callback: (msg: any, rinfo: any) => void): void; /** - * Return an object with information about the security state of the current - * peripheral connection: - * ``` - * { - * connected // The connection is active (not disconnected). - * encrypted // Communication on this link is encrypted. - * mitm_protected // The encrypted communication is also protected against man-in-the-middle attacks. - * bonded // The peer is bonded with us - * advertising // Are we currently advertising? - * connected_addr // If connected=true, the MAC address of the currently connected device - * privacy // Current BLE privacy / random address settings. - * // Only present if Espruino was compiled with private address support (like for example on Bangle.js 2). - * } - * ``` - * If there is no active connection, `{connected:false}` will be returned. - * See `NRF.setSecurity` for information about negotiating a secure connection. - * @returns {any} An object - * @url http://www.espruino.com/Reference#l_NRF_getSecurityStatus + * Called when the connection closes. + * @param {string} event - The event to listen to. + * @param {(had_error: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `had_error` A boolean indicating whether the connection had an error (use an error event handler to get error details). + * @url http://www.espruino.com/Reference#l_dgramSocket_close */ - static getSecurityStatus(): NRFSecurityStatus; + static on(event: "close", callback: (had_error: any) => void): void; /** * - * @param {boolean} forceRepair - True if we should force repairing even if there is already valid pairing info - * @returns {any} A promise - * @url http://www.espruino.com/Reference#l_NRF_startBonding + * @param {any} buffer - A string containing message to send + * @param {any} offset - Offset in the passed string where the message starts [optional] + * @param {any} length - Number of bytes in the message [optional] + * @param {any} args - Destination port number, Destination IP address string + * @url http://www.espruino.com/Reference#l_dgramSocket_send */ - static startBonding(forceRepair: ShortBoolean): any; + send(buffer: any, offset: any, length: any, ...args: any[]): void; + + /** + * + * @param {number} port - The port to bind at + * @param {any} callback - A function(res) that will be called when the socket is bound. You can then call `res.on('message', function(message, info) { ... })` and `res.on('close', function() { ... })` to deal with the response. + * @returns {any} The dgramSocket instance that 'bind' was called on + * @url http://www.espruino.com/Reference#l_dgramSocket_bind + */ + bind(port: number, callback: any): any; + /** + * Close the socket + * @url http://www.espruino.com/Reference#l_dgramSocket_close + */ + close(): void; + /** + * + * @param {any} group - A string containing the group ip to join + * @param {any} ip - A string containing the ip to join with + * @url http://www.espruino.com/Reference#l_dgramSocket_addMembership + */ + addMembership(group: any, ip: any): void; } /** - * This class provides functionality to recognise gestures drawn on a touchscreen. - * It is only built into Bangle.js 2. - * Usage: - * ``` - * var strokes = { - * stroke1 : Unistroke.new(new Uint8Array([x1, y1, x2, y2, x3, y3, ...])), - * stroke2 : Unistroke.new(new Uint8Array([x1, y1, x2, y2, x3, y3, ...])), - * stroke3 : Unistroke.new(new Uint8Array([x1, y1, x2, y2, x3, y3, ...])) - * }; - * var r = Unistroke.recognise(strokes,new Uint8Array([x1, y1, x2, y2, x3, y3, ...])) - * print(r); // stroke1/stroke2/stroke3 - * ``` - * @url http://www.espruino.com/Reference#Unistroke + * The HTTP server created by `require('http').createServer` + * @url http://www.espruino.com/Reference#httpSrv */ -declare class Unistroke { +declare class httpSrv { + + /** - * Create a new Unistroke based on XY coordinates + * Start listening for new HTTP connections on the given port * - * @param {any} xy - An array of interleaved XY coordinates - * @returns {any} A string of data representing this unistroke - * @url http://www.espruino.com/Reference#l_Unistroke_new + * @param {number} port - The port to listen on + * @returns {any} The HTTP server instance that 'listen' was called on + * @url http://www.espruino.com/Reference#l_httpSrv_listen */ - static new(xy: any): any; + listen(port: number): any; /** - * Recognise based on an object of named strokes, and a list of XY coordinates - * - * @param {any} strokes - An object of named strokes : `{arrow:..., circle:...}` - * @param {any} xy - An array of interleaved XY coordinates - * @returns {any} The key name of the matched stroke - * @url http://www.espruino.com/Reference#l_Unistroke_recognise + * Stop listening for new HTTP connections + * @url http://www.espruino.com/Reference#l_httpSrv_close */ - static recognise(strokes: any, xy: any): any; - - + close(): void; } /** - * Class containing AES encryption/decryption - * **Note:** This library is currently only included in builds for boards where - * there is space. For other boards there is `crypto.js` which implements SHA1 in - * JS. - * @url http://www.espruino.com/Reference#AES + * The HTTP server request + * @url http://www.espruino.com/Reference#httpSRq */ -declare class AES { +declare class httpSRq { /** - * - * @param {any} passphrase - Message to encrypt - * @param {any} key - Key to encrypt message - must be an `ArrayBuffer` of 128, 192, or 256 BITS - * @param {any} [options] - [optional] An object, may specify `{ iv : new Uint8Array(16), mode : 'CBC|CFB|CTR|OFB|ECB' }` - * @returns {any} Returns an `ArrayBuffer` - * @url http://www.espruino.com/Reference#l_AES_encrypt + * The 'data' event is called when data is received. If a handler is defined with + * `X.on('data', function(data) { ... })` then it will be called, otherwise data + * will be stored in an internal buffer, where it can be retrieved with `X.read()` + * @param {string} event - The event to listen to. + * @param {(data: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `data` A string containing one or more characters of received data + * @url http://www.espruino.com/Reference#l_httpSRq_data */ - static encrypt(passphrase: any, key: any, options?: any): ArrayBuffer; + static on(event: "data", callback: (data: any) => void): void; /** - * - * @param {any} passphrase - Message to decrypt - * @param {any} key - Key to encrypt message - must be an `ArrayBuffer` of 128, 192, or 256 BITS - * @param {any} [options] - [optional] An object, may specify `{ iv : new Uint8Array(16), mode : 'CBC|CFB|CTR|OFB|ECB' }` - * @returns {any} Returns an `ArrayBuffer` - * @url http://www.espruino.com/Reference#l_AES_decrypt + * Called when the connection closes. + * @param {string} event - The event to listen to. + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_httpSRq_close */ - static decrypt(passphrase: any, key: any, options?: any): ArrayBuffer; - + static on(event: "close", callback: () => void): void; -} + /** + * The headers to sent to the server with this HTTP request. + * @returns {any} An object mapping header name to value + * @url http://www.espruino.com/Reference#l_httpSRq_headers + */ + headers: any; -/** - * Class containing utility functions for - * [Pixl.js](http://www.espruino.com/Pixl.js) - * @url http://www.espruino.com/Reference#Pixl - */ -declare class Pixl { /** - * **DEPRECATED** - Please use `E.getBattery()` instead. - * Return an approximate battery percentage remaining based on a normal CR2032 - * battery (2.8 - 2.2v) - * @returns {number} A percentage between 0 and 100 - * @url http://www.espruino.com/Reference#l_Pixl_getBatteryPercentage + * The HTTP method used with this request. Often `"GET"`. + * @returns {any} A string + * @url http://www.espruino.com/Reference#l_httpSRq_method */ - static getBatteryPercentage(): number; + method: any; /** - * Set the LCD's contrast - * - * @param {number} c - Contrast between 0 and 1 - * @url http://www.espruino.com/Reference#l_Pixl_setContrast + * The URL requested in this HTTP request, for instance: + * * `"/"` - the main page + * * `"/favicon.ico"` - the web page's icon + * @returns {any} A string representing the URL + * @url http://www.espruino.com/Reference#l_httpSRq_url */ - static setContrast(c: number): void; + url: any; /** - * This function can be used to turn Pixl.js's LCD off or on. - * * With the LCD off, Pixl.js draws around 0.1mA - * * With the LCD on, Pixl.js draws around 0.25mA - * - * @param {boolean} isOn - True if the LCD should be on, false if not - * @url http://www.espruino.com/Reference#l_Pixl_setLCDPower + * Return how many bytes are available to read. If there is already a listener for + * data, this will always return 0. + * @returns {number} How many bytes are available + * @url http://www.espruino.com/Reference#l_httpSRq_available */ - static setLCDPower(isOn: ShortBoolean): void; + available(): number; /** - * Writes a command directly to the ST7567 LCD controller + * Return a string containing characters that have been received * - * @param {number} c - * @url http://www.espruino.com/Reference#l_Pixl_lcdw + * @param {number} chars - The number of characters to read, or undefined/0 for all available + * @returns {any} A string containing the required bytes. + * @url http://www.espruino.com/Reference#l_httpSRq_read */ - static lcdw(c: number): void; + read(chars: number): any; /** - * Display a menu on Pixl.js's screen, and set up the buttons to navigate through - * it. - * DEPRECATED: Use `E.showMenu` + * Pipe this to a stream (an object with a 'write' method) * - * @param {any} menu - An object containing name->function mappings to to be used in a menu - * @returns {any} A menu object with `draw`, `move` and `select` functions - * @url http://www.espruino.com/Reference#l_Pixl_menu + * @param {any} destination - The destination file/stream that will receive content from the source. + * @param {any} [options] + * [optional] An object `{ chunkSize : int=32, end : bool=true, complete : function }` + * chunkSize : The amount of data to pipe from source to destination at a time + * complete : a function to call when the pipe activity is complete + * end : call the 'end' function on the destination when the source is finished + * @url http://www.espruino.com/Reference#l_httpSRq_pipe */ - static menu(menu: Menu): MenuInstance; - - + pipe(dest: any, options?: PipeOptions): void } /** - * This class exists in order to interface Espruino with fast-moving trigger - * wheels. Trigger wheels are physical discs with evenly spaced teeth cut into - * them, and often with one or two teeth next to each other missing. A sensor sends - * a signal whenever a tooth passed by, and this allows a device to measure not - * only RPM, but absolute position. - * This class is currently in testing - it is NOT AVAILABLE on normal boards. - * @url http://www.espruino.com/Reference#Trig + * The HTTP server response + * @url http://www.espruino.com/Reference#httpSRs */ -declare class Trig { +declare class httpSRs { /** - * Get the position of the trigger wheel at the given time (from getTime) - * - * @param {number} time - The time at which to find the position - * @returns {number} The position of the trigger wheel in degrees - as a floating point number - * @url http://www.espruino.com/Reference#l_Trig_getPosAtTime + * An event that is fired when the buffer is empty and it can accept more data to + * send. + * @param {string} event - The event to listen to. + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_httpSRs_drain */ - static getPosAtTime(time: number): number; + static on(event: "drain", callback: () => void): void; /** - * Initialise the trigger class - * - * @param {Pin} pin - The pin to use for triggering - * @param {any} options - Additional options as an object. defaults are: ```{teethTotal:60,teethMissing:2,minRPM:30,keyPosition:0}``` - * @url http://www.espruino.com/Reference#l_Trig_setup + * Called when the connection closes. + * @param {string} event - The event to listen to. + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_httpSRs_close */ - static setup(pin: Pin, options: any): void; + static on(event: "close", callback: () => void): void; /** - * Set a trigger for a certain point in the cycle - * - * @param {number} num - The trigger number (0..7) - * @param {number} pos - The position (in degrees) to fire the trigger at - * @param {any} pins - An array of pins to pulse (max 4) - * @param {number} pulseLength - The time (in msec) to pulse for - * @url http://www.espruino.com/Reference#l_Trig_setTrigger + * The headers to send back along with the HTTP response. + * The default contents are: + * ``` + * { + * "Connection": "close" + * } + * ``` + * @returns {any} An object mapping header name to value + * @url http://www.espruino.com/Reference#l_httpSRs_headers */ - static setTrigger(num: number, pos: number, pins: any, pulseLength: number): void; + headers: any; /** - * Disable a trigger + * This function writes the `data` argument as a string. Data that is passed in + * (including arrays) will be converted to a string with the normal JavaScript + * `toString` method. For more information about sending binary data see + * `Socket.write` * - * @param {number} num - The trigger number (0..7) - * @url http://www.espruino.com/Reference#l_Trig_killTrigger + * @param {any} data - A string containing data to send + * @returns {boolean} For node.js compatibility, returns the boolean false. When the send buffer is empty, a `drain` event will be sent + * @url http://www.espruino.com/Reference#l_httpSRs_write */ - static killTrigger(num: number): void; + write(data: any): boolean; /** - * Get the current state of a trigger + * See `Socket.write` for more information about the data argument * - * @param {number} num - The trigger number (0..7) - * @returns {any} A structure containing all information about the trigger - * @url http://www.espruino.com/Reference#l_Trig_getTrigger - */ - static getTrigger(num: number): any; - - /** - * Get the RPM of the trigger wheel - * @returns {number} The current RPM of the trigger wheel - * @url http://www.espruino.com/Reference#l_Trig_getRPM + * @param {any} data - A string containing data to send + * @url http://www.espruino.com/Reference#l_httpSRs_end */ - static getRPM(): number; + end(data: any): void; /** - * Get the current error flags from the trigger wheel - and zero them - * @returns {number} The error flags - * @url http://www.espruino.com/Reference#l_Trig_getErrors + * Send the given status code and headers. If not explicitly called this will be + * done automatically the first time data is written to the response. + * This cannot be called twice, or after data has already been sent in the + * response. + * + * @param {number} statusCode - The HTTP status code + * @param {any} headers - An object containing the headers + * @url http://www.espruino.com/Reference#l_httpSRs_writeHead */ - static getErrors(): number; + writeHead(statusCode: number, headers: any): void; /** - * Get the current error flags from the trigger wheel - and zero them - * @returns {any} An array of error strings - * @url http://www.espruino.com/Reference#l_Trig_getErrorArray + * Set a value to send in the header of this HTTP response. This updates the + * `httpSRs.headers` property. + * Any headers supplied to `writeHead` will overwrite any headers with the same + * name. + * + * @param {any} name - The name of the header as a String + * @param {any} value - The value of the header as a String + * @url http://www.espruino.com/Reference#l_httpSRs_setHeader */ - static getErrorArray(): any; - - -} - -/** - * @url http://www.espruino.com/Reference#Dickens - */ -declare class Dickens { - - - + setHeader(name: any, value: any): void; } /** - * This class helps to convert URLs into Objects of information ready for - * http.request/get - * @url http://www.espruino.com/Reference#url + * The HTTP client request, returned by `http.request()` and `http.get()`. + * @url http://www.espruino.com/Reference#httpCRq */ -declare class url { +declare class httpCRq { /** - * A utility function to split a URL into parts - * This is useful in web servers for instance when handling a request. - * For instance `url.parse("/a?b=c&d=e",true)` returns - * `{"method":"GET","host":"","path":"/a?b=c&d=e","pathname":"/a","search":"?b=c&d=e","port":80,"query":{"b":"c","d":"e"}}` - * - * @param {any} urlStr - A URL to be parsed - * @param {boolean} parseQuery - Whether to parse the query string into an object not (default = false) - * @returns {any} An object containing options for ```http.request``` or ```http.get```. Contains `method`, `host`, `path`, `pathname`, `search`, `port` and `query` - * @url http://www.espruino.com/Reference#l_url_parse + * An event that is fired when the buffer is empty and it can accept more data to + * send. + * @param {string} event - The event to listen to. + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_httpCRq_drain */ - static parse(urlStr: any, parseQuery: ShortBoolean): any; - - -} - -/** - * The socket server created by `require('net').createServer` - * @url http://www.espruino.com/Reference#Server - */ -declare class Server { + static on(event: "drain", callback: () => void): void; + /** + * An event that is fired if there is an error making the request and the response + * callback has not been invoked. In this case the error event concludes the + * request attempt. The error event function receives an error object as parameter + * with a `code` field and a `message` field. + * @param {string} event - The event to listen to. + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_httpCRq_error + */ + static on(event: "error", callback: () => void): void; /** - * Start listening for new connections on the given port + * This function writes the `data` argument as a string. Data that is passed in + * (including arrays) will be converted to a string with the normal JavaScript + * `toString` method. For more information about sending binary data see + * `Socket.write` * - * @param {number} port - The port to listen on - * @returns {any} The HTTP server instance that 'listen' was called on - * @url http://www.espruino.com/Reference#l_Server_listen + * @param {any} data - A string containing data to send + * @returns {boolean} For node.js compatibility, returns the boolean false. When the send buffer is empty, a `drain` event will be sent + * @url http://www.espruino.com/Reference#l_httpCRq_write */ - listen(port: number): any; + write(data: any): boolean; /** - * Stop listening for new connections - * @url http://www.espruino.com/Reference#l_Server_close + * Finish this HTTP request - optional data to append as an argument + * See `Socket.write` for more information about the data argument + * + * @param {any} data - A string containing data to send + * @url http://www.espruino.com/Reference#l_httpCRq_end */ - close(): void; + end(data: any): void; } /** - * An actual socket connection - allowing transmit/receive of TCP data - * @url http://www.espruino.com/Reference#Socket + * The HTTP client response, passed to the callback of `http.request()` an + * `http.get()`. + * @url http://www.espruino.com/Reference#httpCRs */ -declare class Socket { +declare class httpCRs { /** * The 'data' event is called when data is received. If a handler is defined with * `X.on('data', function(data) { ... })` then it will be called, otherwise data @@ -2529,59 +1401,63 @@ declare class Socket { * @param {string} event - The event to listen to. * @param {(data: any) => void} callback - A function that is executed when the event occurs. Its arguments are: * * `data` A string containing one or more characters of received data - * @url http://www.espruino.com/Reference#l_Socket_data + * @url http://www.espruino.com/Reference#l_httpCRs_data */ static on(event: "data", callback: (data: any) => void): void; /** - * Called when the connection closes. + * Called when the connection closes with one `hadError` boolean parameter, which + * indicates whether an error occurred. * @param {string} event - The event to listen to. - * @param {(had_error: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `had_error` A boolean indicating whether the connection had an error (use an error event handler to get error details). - * @url http://www.espruino.com/Reference#l_Socket_close + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_httpCRs_close */ - static on(event: "close", callback: (had_error: any) => void): void; + static on(event: "close", callback: () => void): void; /** - * There was an error on this socket and it is closing (or wasn't opened in the - * first place). If a "connected" event was issued on this socket then the error - * event is always followed by a close event. The error codes are: - * * -1: socket closed (this is not really an error and will not cause an error - * callback) - * * -2: out of memory (typically while allocating a buffer to hold data) - * * -3: timeout - * * -4: no route - * * -5: busy - * * -6: not found (DNS resolution) - * * -7: max sockets (... exceeded) - * * -8: unsent data (some data could not be sent) - * * -9: connection reset (or refused) - * * -10: unknown error - * * -11: no connection - * * -12: bad argument - * * -13: SSL handshake failed - * * -14: invalid SSL data + * An event that is fired if there is an error receiving the response. The error + * event function receives an error object as parameter with a `code` field and a + * `message` field. After the error event the close even will also be triggered to + * conclude the HTTP request/response. * @param {string} event - The event to listen to. - * @param {(details: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `details` An error object with an error code (a negative integer) and a message. - * @url http://www.espruino.com/Reference#l_Socket_error + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_httpCRs_error */ - static on(event: "error", callback: (details: any) => void): void; + static on(event: "error", callback: () => void): void; /** - * An event that is fired when the buffer is empty and it can accept more data to - * send. - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_Socket_drain + * The headers received along with the HTTP response + * @returns {any} An object mapping header name to value + * @url http://www.espruino.com/Reference#l_httpCRs_headers + */ + headers: any; + + /** + * The HTTP response's status code - usually `"200"` if all went well + * @returns {any} The status code as a String + * @url http://www.espruino.com/Reference#l_httpCRs_statusCode + */ + statusCode: any; + + /** + * The HTTP response's status message - Usually `"OK"` if all went well + * @returns {any} An String Status Message + * @url http://www.espruino.com/Reference#l_httpCRs_statusMessage + */ + statusMessage: any; + + /** + * The HTTP version reported back by the server - usually `"1.1"` + * @returns {any} Th + * @url http://www.espruino.com/Reference#l_httpCRs_httpVersion */ - static on(event: "drain", callback: () => void): void; + httpVersion: any; /** - * Return how many bytes are available to read. If there is already a listener for - * data, this will always return 0. + * Return how many bytes are available to read. If there is a 'data' event handler, + * this will always return 0. * @returns {number} How many bytes are available - * @url http://www.espruino.com/Reference#l_Socket_available + * @url http://www.espruino.com/Reference#l_httpCRs_available */ available(): number; @@ -2590,7 +1466,7 @@ declare class Socket { * * @param {number} chars - The number of characters to read, or undefined/0 for all available * @returns {any} A string containing the required bytes. - * @url http://www.espruino.com/Reference#l_Socket_read + * @url http://www.espruino.com/Reference#l_httpCRs_read */ read(chars: number): any; @@ -2603,194 +1479,274 @@ declare class Socket { * chunkSize : The amount of data to pipe from source to destination at a time * complete : a function to call when the pipe activity is complete * end : call the 'end' function on the destination when the source is finished - * @url http://www.espruino.com/Reference#l_Socket_pipe + * @url http://www.espruino.com/Reference#l_httpCRs_pipe */ pipe(destination: any, options?: PipeOptions): void +} + +/** + * An instantiation of an Ethernet network adaptor + * @url http://www.espruino.com/Reference#Ethernet + */ +declare class Ethernet { + /** - * This function writes the `data` argument as a string. Data that is passed in - * (including arrays) will be converted to a string with the normal JavaScript - * `toString` method. - * If you wish to send binary data then you need to convert that data directly to a - * String. This can be done with `String.fromCharCode`, however it's often easier - * and faster to use the Espruino-specific `E.toString`, which will read its - * arguments as an array of bytes and convert that to a String: - * ``` - * socket.write(E.toString([0,1,2,3,4,5])); - * ``` - * If you need to send something other than bytes, you can use 'Typed Arrays', or - * even `DataView`: - * ``` - * var d = new DataView(new ArrayBuffer(8)); // 8 byte array buffer - * d.setFloat32(0, 765.3532564); // write float at bytes 0-3 - * d.setInt8(4, 42); // write int8 at byte 4 - * socket.write(E.toString(d.buffer)) - * ``` + * Get the current IP address, subnet, gateway and mac address. * - * @param {any} data - A string containing data to send - * @returns {boolean} For node.js compatibility, returns the boolean false. When the send buffer is empty, a `drain` event will be sent - * @url http://www.espruino.com/Reference#l_Socket_write + * @param {any} [options] - [optional] An `callback(err, ipinfo)` function to be called back with the IP information. + * @returns {any} + * @url http://www.espruino.com/Reference#l_Ethernet_getIP */ - write(data: any): boolean; + getIP(options?: any): any; /** - * Close this socket - optional data to append as an argument. - * See `Socket.write` for more information about the data argument + * Set the current IP address or get an IP from DHCP (if no options object is + * specified) + * If 'mac' is specified as an option, it must be a string of the form + * `"00:01:02:03:04:05"` The default mac is 00:08:DC:01:02:03. * - * @param {any} data - A string containing data to send - * @url http://www.espruino.com/Reference#l_Socket_end + * @param {any} options - Object containing IP address options `{ ip : '1.2.3.4', subnet : '...', gateway: '...', dns:'...', mac:':::::' }`, or do not supply an object in order to force DHCP. + * @param {any} [callback] - [optional] An `callback(err)` function to invoke when ip is set. `err==null` on success, or a string on failure. + * @returns {boolean} True on success + * @url http://www.espruino.com/Reference#l_Ethernet_setIP */ - end(data: any): void; -} + setIP(options: any, callback?: any): boolean; -/** - * An actual socket connection - allowing transmit/receive of TCP data - * @url http://www.espruino.com/Reference#dgramSocket - */ -declare class dgramSocket { /** - * The 'message' event is called when a datagram message is received. If a handler - * is defined with `X.on('message', function(msg) { ... })` then it will be called - * @param {string} event - The event to listen to. - * @param {(msg: any, rinfo: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `msg` A string containing the received message - * * `rinfo` Sender address,port containing information - * @url http://www.espruino.com/Reference#l_dgramSocket_message + * Set hostname used during the DHCP request. Minimum 8 and maximum 12 characters, + * best set before calling `eth.setIP()`. Default is WIZnet010203, 010203 is the + * default nic as part of the mac. + * + * @param {any} hostname - hostname as string + * @param {any} [callback] - [optional] An `callback(err)` function to be called back with null or error text. + * @returns {boolean} True on success + * @url http://www.espruino.com/Reference#l_Ethernet_setHostname */ - static on(event: "message", callback: (msg: any, rinfo: any) => void): void; + setHostname(hostname: any, callback?: any): boolean; /** - * Called when the connection closes. - * @param {string} event - The event to listen to. - * @param {(had_error: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `had_error` A boolean indicating whether the connection had an error (use an error event handler to get error details). - * @url http://www.espruino.com/Reference#l_dgramSocket_close + * Returns the hostname + * + * @param {any} [callback] - [optional] An `callback(err,hostname)` function to be called back with the status information. + * @returns {any} + * @url http://www.espruino.com/Reference#l_Ethernet_getHostname */ - static on(event: "close", callback: (had_error: any) => void): void; + getHostname(callback?: any): any; /** + * Get the current status of the ethernet device * - * @param {any} buffer - A string containing message to send - * @param {any} offset - Offset in the passed string where the message starts [optional] - * @param {any} length - Number of bytes in the message [optional] - * @param {any} args - Destination port number, Destination IP address string - * @url http://www.espruino.com/Reference#l_dgramSocket_send + * @param {any} [options] - [optional] An `callback(err, status)` function to be called back with the status information. + * @returns {any} + * @url http://www.espruino.com/Reference#l_Ethernet_getStatus */ - send(buffer: any, offset: any, length: any, ...args: any[]): void; + getStatus(options?: any): any; +} + +/** + * An instantiation of a WiFi network adaptor + * @url http://www.espruino.com/Reference#WLAN + */ +declare class WLAN { + /** + * Connect to a wireless network * - * @param {number} port - The port to bind at - * @param {any} callback - A function(res) that will be called when the socket is bound. You can then call `res.on('message', function(message, info) { ... })` and `res.on('close', function() { ... })` to deal with the response. - * @returns {any} The dgramSocket instance that 'bind' was called on - * @url http://www.espruino.com/Reference#l_dgramSocket_bind + * @param {any} ap - Access point name + * @param {any} key - WPA2 key (or undefined for unsecured connection) + * @param {any} callback - Function to call back with connection status. It has one argument which is one of 'connect'/'disconnect'/'dhcp' + * @returns {boolean} True if connection succeeded, false if it didn't. + * @url http://www.espruino.com/Reference#l_WLAN_connect */ - bind(port: number, callback: any): any; + connect(ap: any, key: any, callback: any): boolean; /** - * Close the socket - * @url http://www.espruino.com/Reference#l_dgramSocket_close + * Completely uninitialise and power down the CC3000. After this you'll have to use + * ```require("CC3000").connect()``` again. + * @url http://www.espruino.com/Reference#l_WLAN_disconnect */ - close(): void; + disconnect(): void; + + /** + * Completely uninitialise and power down the CC3000, then reconnect to the old + * access point. + * @url http://www.espruino.com/Reference#l_WLAN_reconnect + */ + reconnect(): void; + + /** + * Get the current IP address + * @returns {any} + * @url http://www.espruino.com/Reference#l_WLAN_getIP + */ + getIP(): any; /** + * Set the current IP address for get an IP from DHCP (if no options object is + * specified). + * **Note:** Changes are written to non-volatile memory, but will only take effect + * after calling `wlan.reconnect()` * - * @param {any} group - A string containing the group ip to join - * @param {any} ip - A string containing the ip to join with - * @url http://www.espruino.com/Reference#l_dgramSocket_addMembership + * @param {any} options - Object containing IP address options `{ ip : '1,2,3,4', subnet, gateway, dns }`, or do not supply an object in otder to force DHCP. + * @returns {boolean} True on success + * @url http://www.espruino.com/Reference#l_WLAN_setIP */ - addMembership(group: any, ip: any): void; + setIP(options: any): boolean; } /** - * The HTTP server created by `require('http').createServer` - * @url http://www.espruino.com/Reference#httpSrv + * Class containing [micro:bit's](https://www.espruino.com/MicroBit) utility + * functions. + * @url http://www.espruino.com/Reference#Microbit */ -declare class httpSrv { +declare class Microbit { + /** + * The micro:bit's speaker pin + * @returns {Pin} + * @url http://www.espruino.com/Reference#l_Microbit_SPEAKER + */ + static SPEAKER: Pin; + /** + * The micro:bit's microphone pin + * `MIC_ENABLE` should be set to 1 before using this + * @returns {Pin} + * @url http://www.espruino.com/Reference#l_Microbit_MIC + */ + static MIC: Pin; /** - * Start listening for new HTTP connections on the given port + * The micro:bit's microphone enable pin + * @returns {Pin} + * @url http://www.espruino.com/Reference#l_Microbit_MIC_ENABLE + */ + static MIC_ENABLE: Pin; + + /** + * Called when the Micro:bit is moved in a deliberate fashion, and includes data on + * the detected gesture. + * @param {string} event - The event to listen to. + * @param {(gesture: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `gesture` An Int8Array containing the accelerations (X,Y,Z) from the last gesture detected by the accelerometer + * @url http://www.espruino.com/Reference#l_Microbit_gesture + */ + static on(event: "gesture", callback: (gesture: any) => void): void; + + /** + * @returns {any} An Object `{x,y,z}` of magnetometer readings as integers + * @url http://www.espruino.com/Reference#l_Microbit_mag + */ + static mag(): any; + + /** + * @returns {any} An Object `{x,y,z}` of acceleration readings in G + * @url http://www.espruino.com/Reference#l_Microbit_accel + */ + static accel(): any; + + /** + * **Note:** This function is only available on the [BBC micro:bit](/MicroBit) + * board + * Write the given value to the accelerometer * - * @param {number} port - The port to listen on - * @returns {any} The HTTP server instance that 'listen' was called on - * @url http://www.espruino.com/Reference#l_httpSrv_listen + * @param {number} addr - Accelerometer address + * @param {number} data - Data to write + * @url http://www.espruino.com/Reference#l_Microbit_accelWr */ - listen(port: number): any; + static accelWr(addr: number, data: number): void; /** - * Stop listening for new HTTP connections - * @url http://www.espruino.com/Reference#l_httpSrv_close + * Turn on the accelerometer, and create `Microbit.accel` and `Microbit.gesture` + * events. + * **Note:** The accelerometer is currently always enabled - this code just + * responds to interrupts and reads + * @url http://www.espruino.com/Reference#l_Microbit_accelOn */ - close(): void; -} + static accelOn(): void; -/** - * The HTTP server request - * @url http://www.espruino.com/Reference#httpSRq - */ -declare class httpSRq { /** - * The 'data' event is called when data is received. If a handler is defined with - * `X.on('data', function(data) { ... })` then it will be called, otherwise data - * will be stored in an internal buffer, where it can be retrieved with `X.read()` - * @param {string} event - The event to listen to. - * @param {(data: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `data` A string containing one or more characters of received data - * @url http://www.espruino.com/Reference#l_httpSRq_data + * Turn off events from the accelerometer (started with `Microbit.accelOn`) + * @url http://www.espruino.com/Reference#l_Microbit_accelOff + */ + static accelOff(): void; + + /** + * Play a waveform on the Micro:bit's speaker + * + * @param {any} waveform - An array of data to play (unsigned 8 bit) + * @param {any} samplesPerSecond - The number of samples per second for playback default is 4000 + * @param {any} callback - A function to call when playback is finished + * @url http://www.espruino.com/Reference#l_Microbit_play */ - static on(event: "data", callback: (data: any) => void): void; + static play(waveform: any, samplesPerSecond: any, callback: any): void; /** - * Called when the connection closes. - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_httpSRq_close + * Records sound from the micro:bit's onboard microphone and returns the result + * + * @param {any} samplesPerSecond - The number of samples per second for recording - 4000 is recommended + * @param {any} callback - A function to call with the result of recording (unsigned 8 bit ArrayBuffer) + * @param {any} [samples] - [optional] How many samples to record (6000 default) + * @url http://www.espruino.com/Reference#l_Microbit_record */ - static on(event: "close", callback: () => void): void; + static record(samplesPerSecond: any, callback: any, samples?: any): void; + + +} + +interface FileConstructor { + +} +interface File { /** - * The headers to sent to the server with this HTTP request. - * @returns {any} An object mapping header name to value - * @url http://www.espruino.com/Reference#l_httpSRq_headers + * Close an open file. + * @url http://www.espruino.com/Reference#l_File_close */ - headers: any; + close(): void; /** - * The HTTP method used with this request. Often `"GET"`. - * @returns {any} A string - * @url http://www.espruino.com/Reference#l_httpSRq_method + * Write data to a file. + * **Note:** By default this function flushes all changes to the SD card, which + * makes it slow (but also safe!). You can use `E.setFlags({unsyncFiles:1})` to + * disable this behaviour and really speed up writes - but then you must be sure to + * close all files you are writing before power is lost or you will cause damage to + * your SD card's filesystem. + * + * @param {any} buffer - A string containing the bytes to write + * @returns {number} the number of bytes written + * @url http://www.espruino.com/Reference#l_File_write */ - method: any; + write(buffer: any): number; /** - * The URL requested in this HTTP request, for instance: - * * `"/"` - the main page - * * `"/favicon.ico"` - the web page's icon - * @returns {any} A string representing the URL - * @url http://www.espruino.com/Reference#l_httpSRq_url + * Read data in a file in byte size chunks + * + * @param {number} length - is an integer specifying the number of bytes to read. + * @returns {any} A string containing the characters that were read + * @url http://www.espruino.com/Reference#l_File_read */ - url: any; + read(length: number): any; /** - * Return how many bytes are available to read. If there is already a listener for - * data, this will always return 0. - * @returns {number} How many bytes are available - * @url http://www.espruino.com/Reference#l_httpSRq_available + * Skip the specified number of bytes forward in the file + * + * @param {number} nBytes - is a positive integer specifying the number of bytes to skip forwards. + * @url http://www.espruino.com/Reference#l_File_skip */ - available(): number; + skip(nBytes: number): void; /** - * Return a string containing characters that have been received + * Seek to a certain position in the file * - * @param {number} chars - The number of characters to read, or undefined/0 for all available - * @returns {any} A string containing the required bytes. - * @url http://www.espruino.com/Reference#l_httpSRq_read + * @param {number} nBytes - is an integer specifying the number of bytes to skip forwards. + * @url http://www.espruino.com/Reference#l_File_seek */ - read(chars: number): any; + seek(nBytes: number): void; /** - * Pipe this to a stream (an object with a 'write' method) + * Pipe this file to a stream (an object with a 'write' method) * * @param {any} destination - The destination file/stream that will receive content from the source. * @param {any} [options] @@ -2798,2385 +1754,3002 @@ declare class httpSRq { * chunkSize : The amount of data to pipe from source to destination at a time * complete : a function to call when the pipe activity is complete * end : call the 'end' function on the destination when the source is finished - * @url http://www.espruino.com/Reference#l_httpSRq_pipe + * @url http://www.espruino.com/Reference#l_File_pipe */ - pipe(dest: any, options?: PipeOptions): void + pipe(destination: any, options?: PipeOptions): void } /** - * The HTTP server response - * @url http://www.espruino.com/Reference#httpSRs + * This is the File object - it allows you to stream data to and from files (As + * opposed to the `require('fs').readFile(..)` style functions that read an entire + * file). + * To create a File object, you must type ```var fd = + * E.openFile('filepath','mode')``` - see [E.openFile](#l_E_openFile) for more + * information. + * **Note:** If you want to remove an SD card after you have started using it, you + * *must* call `E.unmountSD()` or you may cause damage to the card. + * @url http://www.espruino.com/Reference#File */ -declare class httpSRs { +declare const File: FileConstructor + +/** + * Class containing [Puck.js's](http://www.puck-js.com) utility functions. + * @url http://www.espruino.com/Reference#Puck + */ +declare class Puck { /** - * An event that is fired when the buffer is empty and it can accept more data to - * send. - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_httpSRs_drain + * Turn on the magnetometer, take a single reading, and then turn it off again. + * If the magnetometer is already on (with `Puck.magOn()`) then the last reading + * is returned. + * An object of the form `{x,y,z}` is returned containing magnetometer readings. + * Due to residual magnetism in the Puck and magnetometer itself, with no magnetic + * field the Puck will not return `{x:0,y:0,z:0}`. + * Instead, it's up to you to figure out what the 'zero value' is for your Puck in + * your location and to then subtract that from the value returned. If you're not + * trying to measure the Earth's magnetic field then it's a good idea to just take + * a reading at startup and use that. + * With the aerial at the top of the board, the `y` reading is vertical, `x` is + * horizontal, and `z` is through the board. + * Readings are in increments of 0.1 micro Tesla (uT). The Earth's magnetic field + * varies from around 25-60 uT, so the reading will vary by 250 to 600 depending on + * location. + * @returns {any} An Object `{x,y,z}` of magnetometer readings as integers + * @url http://www.espruino.com/Reference#l_Puck_mag */ - static on(event: "drain", callback: () => void): void; + static mag(): any; /** - * Called when the connection closes. - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_httpSRs_close + * Turn on the magnetometer, take a single temperature reading from the MAG3110 + * chip, and then turn it off again. + * (If the magnetometer is already on, this just returns the last reading obtained) + * `E.getTemperature()` uses the microcontroller's temperature sensor, but this + * uses the magnetometer's. + * The reading obtained is an integer (so no decimal places), but the sensitivity + * is factory trimmed. to 1°C, however the temperature offset isn't - so + * absolute readings may still need calibrating. + * @returns {number} Temperature in degrees C + * @url http://www.espruino.com/Reference#l_Puck_magTemp */ - static on(event: "close", callback: () => void): void; + static magTemp(): number; /** - * The headers to send back along with the HTTP response. - * The default contents are: + * Called after `Puck.magOn()` every time magnetometer data is sampled. There is + * one argument which is an object of the form `{x,y,z}` containing magnetometer + * readings as integers (for more information see `Puck.mag()`). + * Check out [the Puck.js page on the + * magnetometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more + * information. * ``` - * { - * "Connection": "close" - * } + * Puck.magOn(10); // 10 Hz + * Puck.on('mag', function(e) { + * print(e); + * }); + * // { "x": -874, "y": -332, "z": -1938 } * ``` - * @returns {any} An object mapping header name to value - * @url http://www.espruino.com/Reference#l_httpSRs_headers - */ - headers: any; - - /** - * This function writes the `data` argument as a string. Data that is passed in - * (including arrays) will be converted to a string with the normal JavaScript - * `toString` method. For more information about sending binary data see - * `Socket.write` - * - * @param {any} data - A string containing data to send - * @returns {boolean} For node.js compatibility, returns the boolean false. When the send buffer is empty, a `drain` event will be sent - * @url http://www.espruino.com/Reference#l_httpSRs_write - */ - write(data: any): boolean; - - /** - * See `Socket.write` for more information about the data argument - * - * @param {any} data - A string containing data to send - * @url http://www.espruino.com/Reference#l_httpSRs_end + * @param {string} event - The event to listen to. + * @param {(xyz: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `xyz` an object of the form `{x,y,z}` + * @url http://www.espruino.com/Reference#l_Puck_mag */ - end(data: any): void; + static on(event: "mag", callback: (xyz: any) => void): void; /** - * Send the given status code and headers. If not explicitly called this will be - * done automatically the first time data is written to the response. - * This cannot be called twice, or after data has already been sent in the - * response. - * - * @param {number} statusCode - The HTTP status code - * @param {any} headers - An object containing the headers - * @url http://www.espruino.com/Reference#l_httpSRs_writeHead + * Only on Puck.js v2.0 + * Called after `Puck.accelOn()` every time accelerometer data is sampled. There is + * one argument which is an object of the form `{acc:{x,y,z}, gyro:{x,y,z}}` + * containing the data. + * ``` + * Puck.accelOn(12.5); // default 12.5Hz + * Puck.on('accel', function(e) { + * print(e); + * }); + * //{ + * // "acc": { "x": -525, "y": -112, "z": 8160 }, + * // "gyro": { "x": 154, "y": -152, "z": -34 } + * //} + * ``` + * The data is as it comes off the accelerometer and is not scaled to 1g. For more + * information see `Puck.accel()` or [the Puck.js page on the + * magnetometer](http://www.espruino.com/Puck.js#on-board-peripherals). + * @param {string} event - The event to listen to. + * @param {(e: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `e` an object of the form `{acc:{x,y,z}, gyro:{x,y,z}}` + * @url http://www.espruino.com/Reference#l_Puck_accel */ - writeHead(statusCode: number, headers: any): void; + static on(event: "accel", callback: (e: any) => void): void; /** - * Set a value to send in the header of this HTTP response. This updates the - * `httpSRs.headers` property. - * Any headers supplied to `writeHead` will overwrite any headers with the same - * name. - * - * @param {any} name - The name of the header as a String - * @param {any} value - The value of the header as a String - * @url http://www.espruino.com/Reference#l_httpSRs_setHeader + * Turn the magnetometer on and start periodic sampling. Samples will then cause a + * 'mag' event on 'Puck': + * ``` + * Puck.magOn(); + * Puck.on('mag', function(xyz) { + * console.log(xyz); + * // {x:..., y:..., z:...} + * }); + * // Turn events off with Puck.magOff(); + * ``` + * This call will be ignored if the sampling is already on. + * If given an argument, the sample rate is set (if not, it's at 0.63 Hz). The + * sample rate must be one of the following (resulting in the given power + * consumption): + * * 80 Hz - 900uA + * * 40 Hz - 550uA + * * 20 Hz - 275uA + * * 10 Hz - 137uA + * * 5 Hz - 69uA + * * 2.5 Hz - 34uA + * * 1.25 Hz - 17uA + * * 0.63 Hz - 8uA + * * 0.31 Hz - 8uA + * * 0.16 Hz - 8uA + * * 0.08 Hz - 8uA + * When the battery level drops too low while sampling is turned on, the + * magnetometer may stop sampling without warning, even while other Puck functions + * continue uninterrupted. + * Check out [the Puck.js page on the + * magnetometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more + * information. + * + * @param {number} samplerate - The sample rate in Hz, or undefined + * @url http://www.espruino.com/Reference#l_Puck_magOn */ - setHeader(name: any, value: any): void; -} + static magOn(samplerate: number): void; -/** - * The HTTP client request, returned by `http.request()` and `http.get()`. - * @url http://www.espruino.com/Reference#httpCRq - */ -declare class httpCRq { /** - * An event that is fired when the buffer is empty and it can accept more data to - * send. - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_httpCRq_drain + * Turn the magnetometer off + * @url http://www.espruino.com/Reference#l_Puck_magOff */ - static on(event: "drain", callback: () => void): void; + static magOff(): void; /** - * An event that is fired if there is an error making the request and the response - * callback has not been invoked. In this case the error event concludes the - * request attempt. The error event function receives an error object as parameter - * with a `code` field and a `message` field. - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_httpCRq_error + * Writes a register on the LIS3MDL / MAX3110 Magnetometer. Can be used for + * configuring advanced functions. + * Check out [the Puck.js page on the + * magnetometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more + * information and links to modules that use this function. + * + * @param {number} reg + * @param {number} data + * @url http://www.espruino.com/Reference#l_Puck_magWr */ - static on(event: "error", callback: () => void): void; + static magWr(reg: number, data: number): void; /** - * This function writes the `data` argument as a string. Data that is passed in - * (including arrays) will be converted to a string with the normal JavaScript - * `toString` method. For more information about sending binary data see - * `Socket.write` + * Reads a register from the LIS3MDL / MAX3110 Magnetometer. Can be used for + * configuring advanced functions. + * Check out [the Puck.js page on the + * magnetometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more + * information and links to modules that use this function. * - * @param {any} data - A string containing data to send - * @returns {boolean} For node.js compatibility, returns the boolean false. When the send buffer is empty, a `drain` event will be sent - * @url http://www.espruino.com/Reference#l_httpCRq_write + * @param {number} reg + * @returns {number} + * @url http://www.espruino.com/Reference#l_Puck_magRd */ - write(data: any): boolean; + static magRd(reg: number): number; /** - * Finish this HTTP request - optional data to append as an argument - * See `Socket.write` for more information about the data argument - * - * @param {any} data - A string containing data to send - * @url http://www.espruino.com/Reference#l_httpCRq_end + * On Puck.js v2.0 this will use the on-board PCT2075TP temperature sensor, but on + * Puck.js the less accurate on-chip Temperature sensor is used. + * @returns {number} Temperature in degrees C + * @url http://www.espruino.com/Reference#l_Puck_getTemperature */ - end(data: any): void; -} + static getTemperature(): number; -/** - * The HTTP client response, passed to the callback of `http.request()` an - * `http.get()`. - * @url http://www.espruino.com/Reference#httpCRs - */ -declare class httpCRs { /** - * The 'data' event is called when data is received. If a handler is defined with - * `X.on('data', function(data) { ... })` then it will be called, otherwise data - * will be stored in an internal buffer, where it can be retrieved with `X.read()` - * @param {string} event - The event to listen to. - * @param {(data: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `data` A string containing one or more characters of received data - * @url http://www.espruino.com/Reference#l_httpCRs_data + * Accepted values are: + * * 1.6 Hz (no Gyro) - 40uA (2v05 and later firmware) + * * 12.5 Hz (with Gyro)- 350uA + * * 26 Hz (with Gyro) - 450 uA + * * 52 Hz (with Gyro) - 600 uA + * * 104 Hz (with Gyro) - 900 uA + * * 208 Hz (with Gyro) - 1500 uA + * * 416 Hz (with Gyro) (not recommended) + * * 833 Hz (with Gyro) (not recommended) + * * 1660 Hz (with Gyro) (not recommended) + * Once `Puck.accelOn()` is called, the `Puck.accel` event will be called each time + * data is received. `Puck.accelOff()` can be called to turn the accelerometer off. + * For instance to light the red LED whenever Puck.js is face up: + * ``` + * Puck.on('accel', function(a) { + * digitalWrite(LED1, a.acc.z > 0); + * }); + * Puck.accelOn(); + * ``` + * Check out [the Puck.js page on the + * accelerometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more + * information. + * **Note:** Puck.js cannot currently read every sample from the + * accelerometer at sample rates above 208Hz. + * + * @param {number} samplerate - The sample rate in Hz, or `undefined` (default is 12.5 Hz) + * @url http://www.espruino.com/Reference#l_Puck_accelOn */ - static on(event: "data", callback: (data: any) => void): void; + static accelOn(samplerate: number): void; /** - * Called when the connection closes with one `hadError` boolean parameter, which - * indicates whether an error occurred. - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_httpCRs_close + * Turn the accelerometer off after it has been turned on by `Puck.accelOn()`. + * Check out [the Puck.js page on the + * accelerometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more + * information. + * @url http://www.espruino.com/Reference#l_Puck_accelOff */ - static on(event: "close", callback: () => void): void; + static accelOff(): void; /** - * An event that is fired if there is an error receiving the response. The error - * event function receives an error object as parameter with a `code` field and a - * `message` field. After the error event the close even will also be triggered to - * conclude the HTTP request/response. - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_httpCRs_error + * Turn on the accelerometer, take a single reading, and then turn it off again. + * The values reported are the raw values from the chip. In normal configuration: + * * accelerometer: full-scale (32768) is 4g, so you need to divide by 8192 to get + * correctly scaled values + * * gyro: full-scale (32768) is 245 dps, so you need to divide by 134 to get + * correctly scaled values + * If taking more than one reading, we'd suggest you use `Puck.accelOn()` and the + * `Puck.accel` event. + * @returns {any} An Object `{acc:{x,y,z}, gyro:{x,y,z}}` of accelerometer/gyro readings + * @url http://www.espruino.com/Reference#l_Puck_accel */ - static on(event: "error", callback: () => void): void; + static accel(): any; /** - * The headers received along with the HTTP response - * @returns {any} An object mapping header name to value - * @url http://www.espruino.com/Reference#l_httpCRs_headers + * Writes a register on the LSM6DS3TR-C Accelerometer. Can be used for configuring + * advanced functions. + * Check out [the Puck.js page on the + * accelerometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more + * information and links to modules that use this function. + * + * @param {number} reg + * @param {number} data + * @url http://www.espruino.com/Reference#l_Puck_accelWr */ - headers: any; + static accelWr(reg: number, data: number): void; /** - * The HTTP response's status code - usually `"200"` if all went well - * @returns {any} The status code as a String - * @url http://www.espruino.com/Reference#l_httpCRs_statusCode + * Reads a register from the LSM6DS3TR-C Accelerometer. Can be used for configuring + * advanced functions. + * Check out [the Puck.js page on the + * accelerometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more + * information and links to modules that use this function. + * + * @param {number} reg + * @returns {number} + * @url http://www.espruino.com/Reference#l_Puck_accelRd */ - statusCode: any; + static accelRd(reg: number): number; /** - * The HTTP response's status message - Usually `"OK"` if all went well - * @returns {any} An String Status Message - * @url http://www.espruino.com/Reference#l_httpCRs_statusMessage + * Transmit the given set of IR pulses - data should be an array of pulse times in + * milliseconds (as `[on, off, on, off, on, etc]`). + * For example `Puck.IR(pulseTimes)` - see http://www.espruino.com/Puck.js+Infrared + * for a full example. + * You can also attach an external LED to Puck.js, in which case you can just + * execute `Puck.IR(pulseTimes, led_cathode, led_anode)` + * It is also possible to just supply a single pin for IR transmission with + * `Puck.IR(pulseTimes, led_anode)` (on 2v05 and above). + * + * @param {any} data - An array of pulse lengths, in milliseconds + * @param {Pin} [cathode] - [optional] pin to use for IR LED cathode - if not defined, the built-in IR LED is used + * @param {Pin} [anode] - [optional] pin to use for IR LED anode - if not defined, the built-in IR LED is used + * @url http://www.espruino.com/Reference#l_Puck_IR */ - statusMessage: any; + static IR(data: any, cathode?: Pin, anode?: Pin): void; /** - * The HTTP version reported back by the server - usually `"1.1"` - * @returns {any} Th - * @url http://www.espruino.com/Reference#l_httpCRs_httpVersion + * Capacitive sense - the higher the capacitance, the higher the number returned. + * If called without arguments, a value depending on the capacitance of what is + * attached to pin D11 will be returned. If you attach a length of wire to D11, + * you'll be able to see a higher value returned when your hand is near the wire + * than when it is away. + * You can also supply pins to use yourself, however if you do this then the TX pin + * must be connected to RX pin and sense plate via a roughly 1MOhm resistor. + * When not supplying pins, Puck.js uses an internal resistor between D12(tx) and + * D11(rx). + * + * @param {Pin} tx + * @param {Pin} rx + * @returns {number} Capacitive sense counter + * @url http://www.espruino.com/Reference#l_Puck_capSense */ - httpVersion: any; + static capSense(tx: Pin, rx: Pin): number; /** - * Return how many bytes are available to read. If there is a 'data' event handler, - * this will always return 0. - * @returns {number} How many bytes are available - * @url http://www.espruino.com/Reference#l_httpCRs_available + * Return a light value based on the light the red LED is seeing. + * **Note:** If called more than 5 times per second, the received light value may + * not be accurate. + * @returns {number} A light value from 0 to 1 + * @url http://www.espruino.com/Reference#l_Puck_light */ - available(): number; + static light(): number; /** - * Return a string containing characters that have been received - * - * @param {number} chars - The number of characters to read, or undefined/0 for all available - * @returns {any} A string containing the required bytes. - * @url http://www.espruino.com/Reference#l_httpCRs_read + * **DEPRECATED** - Please use `E.getBattery()` instead. + * Return an approximate battery percentage remaining based on a normal CR2032 + * battery (2.8 - 2.2v). + * @returns {number} A percentage between 0 and 100 + * @url http://www.espruino.com/Reference#l_Puck_getBatteryPercentage */ - read(chars: number): any; + static getBatteryPercentage(): number; /** - * Pipe this to a stream (an object with a 'write' method) - * - * @param {any} destination - The destination file/stream that will receive content from the source. - * @param {any} [options] - * [optional] An object `{ chunkSize : int=32, end : bool=true, complete : function }` - * chunkSize : The amount of data to pipe from source to destination at a time - * complete : a function to call when the pipe activity is complete - * end : call the 'end' function on the destination when the source is finished - * @url http://www.espruino.com/Reference#l_httpCRs_pipe + * Run a self-test, and return true for a pass. This checks for shorts between + * pins, so your Puck shouldn't have anything connected to it. + * **Note:** This self-test auto starts if you hold the button on your Puck down + * while inserting the battery, leave it pressed for 3 seconds (while the green LED + * is lit) and release it soon after all LEDs turn on. 5 red blinks is a fail, 5 + * green is a pass. + * If the self test fails, it'll set the Puck.js Bluetooth advertising name to + * `Puck.js !ERR` where ERR is a 3 letter error code. + * @returns {boolean} True if the self-test passed + * @url http://www.espruino.com/Reference#l_Puck_selfTest */ - pipe(destination: any, options?: PipeOptions): void -} + static selfTest(): boolean; -/** - * An instantiation of an Ethernet network adaptor - * @url http://www.espruino.com/Reference#Ethernet - */ -declare class Ethernet { +} + +/** + * Class containing utility functions for the [Jolt.js Smart Bluetooth driver](http://www.espruino.com/Jolt.js) + * @url http://www.espruino.com/Reference#Jolt + */ +declare class Jolt { + /** + * `Q0` and `Q1` Qwiic connectors can have their power controlled by a 500mA FET (`Jolt.Q0.fet`) which switches GND. + * The `sda` and `scl` pins on this port are also analog inputs - use `analogRead(Jolt.Q0.sda)`/etc + * To turn this connector on run `Jolt.Q0.setPower(1)` + * @returns {any} An object containing the pins for the Q0 connector on Jolt.js `{sda,scl,fet}` + * @url http://www.espruino.com/Reference#l_Jolt_Q0 + */ + static Q0: Qwiic; /** - * Get the current IP address, subnet, gateway and mac address. - * - * @param {any} [options] - [optional] An `callback(err, ipinfo)` function to be called back with the IP information. - * @returns {any} - * @url http://www.espruino.com/Reference#l_Ethernet_getIP + * `Q0` and `Q1` Qwiic connectors can have their power controlled by a 500mA FET (`Jolt.Q1.fet`) which switches GND. + * The `sda` and `scl` pins on this port are also analog inputs - use `analogRead(Jolt.Q1.sda)`/etc + * To turn this connector on run `Jolt.Q1.setPower(1)` + * @returns {any} An object containing the pins for the Q1 connector on Jolt.js `{sda,scl,fet}` + * @url http://www.espruino.com/Reference#l_Jolt_Q1 */ - getIP(options?: any): any; + static Q1: Qwiic; /** - * Set the current IP address or get an IP from DHCP (if no options object is - * specified) - * If 'mac' is specified as an option, it must be a string of the form - * `"00:01:02:03:04:05"` The default mac is 00:08:DC:01:02:03. - * - * @param {any} options - Object containing IP address options `{ ip : '1.2.3.4', subnet : '...', gateway: '...', dns:'...', mac:':::::' }`, or do not supply an object in order to force DHCP. - * @param {any} [callback] - [optional] An `callback(err)` function to invoke when ip is set. `err==null` on success, or a string on failure. - * @returns {boolean} True on success - * @url http://www.espruino.com/Reference#l_Ethernet_setIP + * `Q2` and `Q3` have all 4 pins connected to Jolt.js's GPIO (including those usually used for power). + * As such only around 8mA of power can be supplied to any connected device. + * To use this as a normal Qwiic connector, run `Jolt.Q2.setPower(1)` + * @returns {any} An object containing the pins for the Q2 connector on Jolt.js `{sda,scl,gnd,vcc}` + * @url http://www.espruino.com/Reference#l_Jolt_Q2 */ - setIP(options: any, callback?: any): boolean; + static Q2: Qwiic; /** - * Set hostname used during the DHCP request. Minimum 8 and maximum 12 characters, - * best set before calling `eth.setIP()`. Default is WIZnet010203, 010203 is the - * default nic as part of the mac. - * - * @param {any} hostname - hostname as string - * @param {any} [callback] - [optional] An `callback(err)` function to be called back with null or error text. - * @returns {boolean} True on success - * @url http://www.espruino.com/Reference#l_Ethernet_setHostname + * `Q2` and `Q3` have all 4 pins connected to Jolt.js's GPIO (including those usually used for power). + * As such only around 8mA of power can be supplied to any connected device. + * To use this as a normal Qwiic connector, run `Jolt.Q3.setPower(1)` + * @returns {any} An object containing the pins for the Q3 connector on Jolt.js `{sda,scl,gnd,vcc}` + * @url http://www.espruino.com/Reference#l_Jolt_Q3 */ - setHostname(hostname: any, callback?: any): boolean; + static Q3: Qwiic; /** - * Returns the hostname + * Sets the mode of the motor drivers. Jolt.js has two motor drivers, + * one (`0`) for outputs H0..H3, and one (`1`) for outputs H4..H7. They + * can be controlled independently. + * Mode can be: + * * `undefined` / `false` / `"off"` - the motor driver is off, all motor driver pins are open circuit (the motor driver still has a ~2.5k pulldown to GND) + * * `"auto"` - (default) - if any pin in the set of 4 pins (H0..H3, H4..H7) is set as an output, the driver is turned on. Eg `H0.set()` will + * turn the driver on with a high output, `H0.reset()` will pull the output to GND and `H0.read()` (or `H0.mode("input")` to set the state explicitly) is needed to + * turn the motor driver off. + * * `true` / `"output"` - **[recommended]** driver is set to "Independent bridge" mode. All 4 outputs in the bank are enabled + * * `"motor"` - driver is set to "4 pin interface" mode where pins are paired up (H0+H1, H2+H3, etc). If both + * in a pair are 0 the output is open circuit (motor coast), if both are 1 both otputs are 0 (motor brake), and + * if both are different, those values are on the output: + * `output`/`auto` mode: + * | H0 | H1 | Out 0 | Out 1 | + * |----|----|-------|-------| + * | 0 | 0 | Low | Low | + * | 0 | 1 | Low | High | + * | 1 | 0 | High | Low | + * | 1 | 1 | High | High | + * `motor` mode + * | H0 | H1 | Out 0 | Out 1 | + * |----|----|-------|-------| + * | 0 | 0 | Open | Open | + * | 0 | 1 | Low | High | + * | 1 | 0 | High | Low | + * | 1 | 1 | Low | Low | * - * @param {any} [callback] - [optional] An `callback(err,hostname)` function to be called back with the status information. - * @returns {any} - * @url http://www.espruino.com/Reference#l_Ethernet_getHostname + * @param {number} driver - The number of the motor driver (0 or 1) + * @param {any} mode - The mode of the motor driver (see below) + * @url http://www.espruino.com/Reference#l_Jolt_setDriverMode */ - getHostname(callback?: any): any; + static setDriverMode(driver: number, mode: any): void; /** - * Get the current status of the ethernet device - * - * @param {any} [options] - [optional] An `callback(err, status)` function to be called back with the status information. - * @returns {any} - * @url http://www.espruino.com/Reference#l_Ethernet_getStatus + * Run a self-test, and return true for a pass. This checks for shorts between + * pins, so your Jolt shouldn't have anything connected to it. + * **Note:** This self-test auto starts if you hold the button on your Jolt down + * while inserting the battery, leave it pressed for 3 seconds (while the green LED + * is lit) and release it soon after all LEDs turn on. 5 red blinks is a fail, 5 + * green is a pass. + * If the self test fails, it'll set the Jolt.js Bluetooth advertising name to + * `Jolt.js !ERR` where ERR is a 3 letter error code. + * @returns {boolean} True if the self-test passed + * @url http://www.espruino.com/Reference#l_Jolt_selfTest */ - getStatus(options?: any): any; + static selfTest(): boolean; + + } /** - * An instantiation of a WiFi network adaptor - * @url http://www.espruino.com/Reference#WLAN + * Class containing utility functions for the [Bangle.js Smart + * Watch](http://www.espruino.com/Bangle.js) + * @url http://www.espruino.com/Reference#Bangle */ -declare class WLAN { - - +declare class Bangle { /** - * Connect to a wireless network - * - * @param {any} ap - Access point name - * @param {any} key - WPA2 key (or undefined for unsecured connection) - * @param {any} callback - Function to call back with connection status. It has one argument which is one of 'connect'/'disconnect'/'dhcp' - * @returns {boolean} True if connection succeeded, false if it didn't. - * @url http://www.espruino.com/Reference#l_WLAN_connect + * Accelerometer data available with `{x,y,z,diff,mag}` object as a parameter. + * * `x` is X axis (left-right) in `g` + * * `y` is Y axis (up-down) in `g` + * * `z` is Z axis (in-out) in `g` + * * `diff` is difference between this and the last reading in `g` + * * `mag` is the magnitude of the acceleration in `g` + * You can also retrieve the most recent reading with `Bangle.getAccel()`. + * @param {string} event - The event to listen to. + * @param {(xyz: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `xyz` + * @url http://www.espruino.com/Reference#l_Bangle_accel */ - connect(ap: any, key: any, callback: any): boolean; + static on(event: "accel", callback: (xyz: AccelData) => void): void; /** - * Completely uninitialise and power down the CC3000. After this you'll have to use - * ```require("CC3000").connect()``` again. - * @url http://www.espruino.com/Reference#l_WLAN_disconnect + * Called whenever a step is detected by Bangle.js's pedometer. + * @param {string} event - The event to listen to. + * @param {(up: number) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `up` The number of steps since Bangle.js was last reset + * @url http://www.espruino.com/Reference#l_Bangle_step */ - disconnect(): void; + static on(event: "step", callback: (up: number) => void): void; /** - * Completely uninitialise and power down the CC3000, then reconnect to the old - * access point. - * @url http://www.espruino.com/Reference#l_WLAN_reconnect + * See `Bangle.getHealthStatus()` for more information. This is used for health + * tracking to allow Bangle.js to record historical exercise data. + * @param {string} event - The event to listen to. + * @param {(info: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `info` An object containing the last 10 minutes health data + * @url http://www.espruino.com/Reference#l_Bangle_health */ - reconnect(): void; + static on(event: "health", callback: (info: HealthStatus) => void): void; /** - * Get the current IP address - * @returns {any} - * @url http://www.espruino.com/Reference#l_WLAN_getIP + * Has the watch been moved so that it is face-up, or not face up? + * @param {string} event - The event to listen to. + * @param {(up: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `up` `true` if face-up + * @url http://www.espruino.com/Reference#l_Bangle_faceUp */ - getIP(): any; + static on(event: "faceUp", callback: (up: ShortBoolean) => void): void; /** - * Set the current IP address for get an IP from DHCP (if no options object is - * specified). - * **Note:** Changes are written to non-volatile memory, but will only take effect - * after calling `wlan.reconnect()` - * - * @param {any} options - Object containing IP address options `{ ip : '1,2,3,4', subnet, gateway, dns }`, or do not supply an object in otder to force DHCP. - * @returns {boolean} True on success - * @url http://www.espruino.com/Reference#l_WLAN_setIP + * This event happens when the watch has been twisted around it's axis - for + * instance as if it was rotated so someone could look at the time. + * To tweak when this happens, see the `twist*` options in `Bangle.setOptions()` + * @param {string} event - The event to listen to. + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_Bangle_twist */ - setIP(options: any): boolean; -} + static on(event: "twist", callback: () => void): void; -/** - * Class containing [micro:bit's](https://www.espruino.com/MicroBit) utility - * functions. - * @url http://www.espruino.com/Reference#Microbit - */ -declare class Microbit { /** - * The micro:bit's speaker pin - * @returns {Pin} - * @url http://www.espruino.com/Reference#l_Microbit_SPEAKER + * Is the battery charging or not? + * @param {string} event - The event to listen to. + * @param {(charging: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `charging` `true` if charging + * @url http://www.espruino.com/Reference#l_Bangle_charging */ - static SPEAKER: Pin; + static on(event: "charging", callback: (charging: ShortBoolean) => void): void; /** - * The micro:bit's microphone pin - * `MIC_ENABLE` should be set to 1 before using this - * @returns {Pin} - * @url http://www.espruino.com/Reference#l_Microbit_MIC + * Magnetometer/Compass data available with `{x,y,z,dx,dy,dz,heading}` object as a + * parameter + * * `x/y/z` raw x,y,z magnetometer readings + * * `dx/dy/dz` readings based on calibration since magnetometer turned on + * * `heading` in degrees based on calibrated readings (will be NaN if magnetometer + * hasn't been rotated around 360 degrees). + * **Note:** In 2v15 firmware and earlier the heading is inverted (360-heading). There's + * a fix in the bootloader which will apply a fix for those headings, but old apps may + * still expect an inverted value. + * To get this event you must turn the compass on with `Bangle.setCompassPower(1)`. + * You can also retrieve the most recent reading with `Bangle.getCompass()`. + * @param {string} event - The event to listen to. + * @param {(xyz: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `xyz` + * @url http://www.espruino.com/Reference#l_Bangle_mag */ - static MIC: Pin; + static on(event: "mag", callback: (xyz: CompassData) => void): void; /** - * The micro:bit's microphone enable pin - * @returns {Pin} - * @url http://www.espruino.com/Reference#l_Microbit_MIC_ENABLE + * Raw NMEA GPS / u-blox data messages received as a string + * To get this event you must turn the GPS on with `Bangle.setGPSPower(1)`. + * @param {string} event - The event to listen to. + * @param {(nmea: any, dataLoss: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `nmea` A string containing the raw NMEA data from the GPS + * * `dataLoss` This is set to true if some lines of GPS data have previously been lost (eg because system was too busy to queue up a GPS-raw event) + * @url http://www.espruino.com/Reference#l_Bangle_GPS-raw */ - static MIC_ENABLE: Pin; + static on(event: "GPS-raw", callback: (nmea: string, dataLoss: boolean) => void): void; /** - * Called when the Micro:bit is moved in a deliberate fashion, and includes data on - * the detected gesture. + * GPS data, as an object. Contains: + * ``` + * { "lat": number, // Latitude in degrees + * "lon": number, // Longitude in degrees + * "alt": number, // altitude in M + * "speed": number, // Speed in kph + * "course": number, // Course in degrees + * "time": Date, // Current Time (or undefined if not known) + * "satellites": 7, // Number of satellites + * "fix": 1 // NMEA Fix state - 0 is no fix + * "hdop": number, // Horizontal Dilution of Precision + * } + * ``` + * If a value such as `lat` is not known because there is no fix, it'll be `NaN`. + * `hdop` is a value from the GPS receiver that gives a rough idea of accuracy of + * lat/lon based on the geometry of the satellites in range. Multiply by 5 to get a + * value in meters. This is just a ballpark estimation and should not be considered + * remotely accurate. + * To get this event you must turn the GPS on with `Bangle.setGPSPower(1)`. * @param {string} event - The event to listen to. - * @param {(gesture: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `gesture` An Int8Array containing the accelerations (X,Y,Z) from the last gesture detected by the accelerometer - * @url http://www.espruino.com/Reference#l_Microbit_gesture - */ - static on(event: "gesture", callback: (gesture: any) => void): void; - - /** - * @returns {any} An Object `{x,y,z}` of magnetometer readings as integers - * @url http://www.espruino.com/Reference#l_Microbit_mag + * @param {(fix: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `fix` An object with fix info (see below) + * @url http://www.espruino.com/Reference#l_Bangle_GPS */ - static mag(): any; + static on(event: "GPS", callback: (fix: GPSFix) => void): void; /** - * @returns {any} An Object `{x,y,z}` of acceleration readings in G - * @url http://www.espruino.com/Reference#l_Microbit_accel + * Heat rate data, as an object. Contains: + * ``` + * { "bpm": number, // Beats per minute + * "confidence": number, // 0-100 percentage confidence in the heart rate + * "raw": Uint8Array, // raw samples from heart rate monitor + * } + * ``` + * To get this event you must turn the heart rate monitor on with + * `Bangle.setHRMPower(1)`. + * @param {string} event - The event to listen to. + * @param {(hrm: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `hrm` An object with heart rate info (see below) + * @url http://www.espruino.com/Reference#l_Bangle_HRM */ - static accel(): any; + static on(event: "HRM", callback: (hrm: { bpm: number, confidence: number, raw: Uint8Array }) => void): void; /** - * **Note:** This function is only available on the [BBC micro:bit](/MicroBit) - * board - * Write the given value to the accelerometer - * - * @param {number} addr - Accelerometer address - * @param {number} data - Data to write - * @url http://www.espruino.com/Reference#l_Microbit_accelWr + * Called when heart rate sensor data is available - see `Bangle.setHRMPower(1)`. + * `hrm` is of the form: + * ``` + * { "raw": -1, // raw value from sensor + * "filt": -1, // bandpass-filtered raw value from sensor + * "bpm": 88.9, // last BPM value measured + * "confidence": 0 // confidence in the BPM value + * } + * ``` + * @param {string} event - The event to listen to. + * @param {(hrm: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `hrm` A object containing instant readings from the heart rate sensor + * @url http://www.espruino.com/Reference#l_Bangle_HRM-raw */ - static accelWr(addr: number, data: number): void; + static on(event: "HRM-raw", callback: (hrm: { raw: number, filt: number, bpm: number, confidence: number }) => void): void; /** - * Turn on the accelerometer, and create `Microbit.accel` and `Microbit.gesture` - * events. - * **Note:** The accelerometer is currently always enabled - this code just - * responds to interrupts and reads - * @url http://www.espruino.com/Reference#l_Microbit_accelOn + * Called when an environment sample heart rate sensor data is available (this is the amount of light received by the HRM sensor from the environment when its LED is off). On the newest VC31B based watches this is only 4 bit (0..15). + * To get it you need to turn the HRM on with `Bangle.setHRMPower(1)` and also set `Bangle.setOptions({hrmPushEnv:true})`. + * It is also possible to poke registers with `Bangle.hrmWr` to increase the poll rate if needed. See https://banglejs.com/apps/?id=flashcount for an example of this. + * @param {string} event - The event to listen to. + * @param {(env: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `env` An integer containing current environment reading (light level) + * @url http://www.espruino.com/Reference#l_Bangle_HRM-env */ - static accelOn(): void; + static on(event: "HRM-env", callback: (env: any) => void): void; /** - * Turn off events from the accelerometer (started with `Microbit.accelOn`) - * @url http://www.espruino.com/Reference#l_Microbit_accelOff + * When `Bangle.setBarometerPower(true)` is called, this event is fired containing + * barometer readings. + * Same format as `Bangle.getPressure()` + * @param {string} event - The event to listen to. + * @param {(e: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `e` An object containing `{temperature,pressure,altitude}` + * @url http://www.espruino.com/Reference#l_Bangle_pressure */ - static accelOff(): void; + static on(event: "pressure", callback: (e: PressureData) => void): void; /** - * Play a waveform on the Micro:bit's speaker - * - * @param {any} waveform - An array of data to play (unsigned 8 bit) - * @param {any} samplesPerSecond - The number of samples per second for playback default is 4000 - * @param {any} callback - A function to call when playback is finished - * @url http://www.espruino.com/Reference#l_Microbit_play + * Has the screen been turned on or off? Can be used to stop tasks that are no + * longer useful if nothing is displayed. Also see `Bangle.isLCDOn()` + * @param {string} event - The event to listen to. + * @param {(on: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `on` `true` if screen is on + * @url http://www.espruino.com/Reference#l_Bangle_lcdPower */ - static play(waveform: any, samplesPerSecond: any, callback: any): void; + static on(event: "lcdPower", callback: (on: ShortBoolean) => void): void; /** - * Records sound from the micro:bit's onboard microphone and returns the result - * - * @param {any} samplesPerSecond - The number of samples per second for recording - 4000 is recommended - * @param {any} callback - A function to call with the result of recording (unsigned 8 bit ArrayBuffer) - * @param {any} [samples] - [optional] How many samples to record (6000 default) - * @url http://www.espruino.com/Reference#l_Microbit_record + * Has the backlight been turned on or off? Can be used to stop tasks that are no + * longer useful if want to see in sun screen only. Also see `Bangle.isBacklightOn()` + * @param {string} event - The event to listen to. + * @param {(on: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `on` `true` if backlight is on + * @url http://www.espruino.com/Reference#l_Bangle_backlight */ - static record(samplesPerSecond: any, callback: any, samples?: any): void; - - -} - -interface FileConstructor { - -} + static on(event: "backlight", callback: (on: ShortBoolean) => void): void; -interface File { /** - * Close an open file. - * @url http://www.espruino.com/Reference#l_File_close + * Has the screen been locked? Also see `Bangle.isLocked()` + * @param {string} event - The event to listen to. + * @param {(on: ShortBoolean, reason: string) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `on` `true` if screen is locked, `false` if it is unlocked and touchscreen/buttons will work + * * `reason` (2v20 onwards) If known, the reason for locking/unlocking - 'button','js','tap','doubleTap','faceUp','twist','timeout' + * @url http://www.espruino.com/Reference#l_Bangle_lock */ - close(): void; + static on(event: "lock", callback: (on: ShortBoolean, reason: string) => void): void; /** - * Write data to a file. - * **Note:** By default this function flushes all changes to the SD card, which - * makes it slow (but also safe!). You can use `E.setFlags({unsyncFiles:1})` to - * disable this behaviour and really speed up writes - but then you must be sure to - * close all files you are writing before power is lost or you will cause damage to - * your SD card's filesystem. - * - * @param {any} buffer - A string containing the bytes to write - * @returns {number} the number of bytes written - * @url http://www.espruino.com/Reference#l_File_write + * If the watch is tapped, this event contains information on the way it was + * tapped. + * `dir` reports the side of the watch that was tapped (not the direction it was + * tapped in). + * ``` + * { + * dir : "left/right/top/bottom/front/back", + * double : true/false // was this a double-tap? + * x : -2 .. 2, // the axis of the tap + * y : -2 .. 2, // the axis of the tap + * z : -2 .. 2 // the axis of the tap + * ``` + * @param {string} event - The event to listen to. + * @param {(data: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `data` `{dir, double, x, y, z}` + * @url http://www.espruino.com/Reference#l_Bangle_tap */ - write(buffer: any): number; + static on(event: "tap", callback: (data: { dir: "left" | "right" | "top" | "bottom" | "front" | "back", double: boolean, x: TapAxis, y: TapAxis, z: TapAxis }) => void): void; /** - * Read data in a file in byte size chunks - * - * @param {number} length - is an integer specifying the number of bytes to read. - * @returns {any} A string containing the characters that were read - * @url http://www.espruino.com/Reference#l_File_read + * Emitted when a 'gesture' (fast movement) is detected + * @param {string} event - The event to listen to. + * @param {(xyz: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `xyz` An Int8Array of XYZXYZXYZ data + * @url http://www.espruino.com/Reference#l_Bangle_gesture */ - read(length: number): any; + static on(event: "gesture", callback: (xyz: Int8Array) => void): void; /** - * Skip the specified number of bytes forward in the file - * - * @param {number} nBytes - is a positive integer specifying the number of bytes to skip forwards. - * @url http://www.espruino.com/Reference#l_File_skip + * Emitted when a 'gesture' (fast movement) is detected, and a Tensorflow model is + * in storage in the `".tfmodel"` file. + * If a `".tfnames"` file is specified as a comma-separated list of names, it will + * be used to decode `gesture` from a number into a string. + * @param {string} event - The event to listen to. + * @param {(gesture: any, weights: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `gesture` The name of the gesture (if '.tfnames' exists, or the index. 'undefined' if not matching + * * `weights` An array of floating point values output by the model + * @url http://www.espruino.com/Reference#l_Bangle_aiGesture */ - skip(nBytes: number): void; + static on(event: "aiGesture", callback: (gesture: string | undefined, weights: number[]) => void): void; /** - * Seek to a certain position in the file - * - * @param {number} nBytes - is an integer specifying the number of bytes to skip forwards. - * @url http://www.espruino.com/Reference#l_File_seek + * Emitted when a swipe on the touchscreen is detected (a movement from + * left->right, right->left, down->up or up->down) + * Bangle.js 1 is only capable of detecting left/right swipes as it only contains a + * 2 zone touchscreen. + * @param {string} event - The event to listen to. + * @param {(directionLR: number, directionUD: number) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `directionLR` `-1` for left, `1` for right, `0` for up/down + * * `directionUD` `-1` for up, `1` for down, `0` for left/right (Bangle.js 2 only) + * @url http://www.espruino.com/Reference#l_Bangle_swipe */ - seek(nBytes: number): void; + static on(event: "swipe", callback: SwipeCallback): void; /** - * Pipe this file to a stream (an object with a 'write' method) - * - * @param {any} destination - The destination file/stream that will receive content from the source. - * @param {any} [options] - * [optional] An object `{ chunkSize : int=32, end : bool=true, complete : function }` - * chunkSize : The amount of data to pipe from source to destination at a time - * complete : a function to call when the pipe activity is complete - * end : call the 'end' function on the destination when the source is finished - * @url http://www.espruino.com/Reference#l_File_pipe + * Emitted when the touchscreen is pressed + * @param {string} event - The event to listen to. + * @param {(button: number, xy: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `button` `1` for left, `2` for right + * * `xy` Object of form `{x,y,type}` containing touch coordinates (if the device supports full touch). Clipped to 0..175 (LCD pixel coordinates) on firmware 2v13 and later.`type` is only available on Bangle.js 2 and is an integer, either 0 for swift touches or 2 for longer ones. + * @url http://www.espruino.com/Reference#l_Bangle_touch */ - pipe(destination: any, options?: PipeOptions): void -} - -/** - * This is the File object - it allows you to stream data to and from files (As - * opposed to the `require('fs').readFile(..)` style functions that read an entire - * file). - * To create a File object, you must type ```var fd = - * E.openFile('filepath','mode')``` - see [E.openFile](#l_E_openFile) for more - * information. - * **Note:** If you want to remove an SD card after you have started using it, you - * *must* call `E.unmountSD()` or you may cause damage to the card. - * @url http://www.espruino.com/Reference#File - */ -declare const File: FileConstructor + static on(event: "touch", callback: TouchCallback): void; -/** - * Class containing [Puck.js's](http://www.puck-js.com) utility functions. - * @url http://www.espruino.com/Reference#Puck - */ -declare class Puck { /** - * Turn on the magnetometer, take a single reading, and then turn it off again. - * An object of the form `{x,y,z}` is returned containing magnetometer readings. - * Due to residual magnetism in the Puck and magnetometer itself, with no magnetic - * field the Puck will not return `{x:0,y:0,z:0}`. - * Instead, it's up to you to figure out what the 'zero value' is for your Puck in - * your location and to then subtract that from the value returned. If you're not - * trying to measure the Earth's magnetic field then it's a good idea to just take - * a reading at startup and use that. - * With the aerial at the top of the board, the `y` reading is vertical, `x` is - * horizontal, and `z` is through the board. - * Readings are in increments of 0.1 micro Tesla (uT). The Earth's magnetic field - * varies from around 25-60 uT, so the reading will vary by 250 to 600 depending on - * location. - * @returns {any} An Object `{x,y,z}` of magnetometer readings as integers - * @url http://www.espruino.com/Reference#l_Puck_mag + * Emitted when the touchscreen is dragged or released + * The touchscreen extends past the edge of the screen and while `x` and `y` + * coordinates are arranged such that they align with the LCD's pixels, if your + * finger goes towards the edge of the screen, `x` and `y` could end up larger than + * 175 (the screen's maximum pixel coordinates) or smaller than 0. Coordinates from + * the `touch` event are clipped. + * @param {string} event - The event to listen to. + * @param {(event: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `event` Object of form `{x,y,dx,dy,b}` containing touch coordinates, difference in touch coordinates, and an integer `b` containing number of touch points (currently 1 or 0) + * @url http://www.espruino.com/Reference#l_Bangle_drag */ - static mag(): any; + static on(event: "drag", callback: DragCallback): void; /** - * Turn on the magnetometer, take a single temperature reading from the MAG3110 - * chip, and then turn it off again. - * (If the magnetometer is already on, this just returns the last reading obtained) - * `E.getTemperature()` uses the microcontroller's temperature sensor, but this - * uses the magnetometer's. - * The reading obtained is an integer (so no decimal places), but the sensitivity - * is factory trimmed. to 1°C, however the temperature offset isn't - so - * absolute readings may still need calibrating. - * @returns {number} Temperature in degrees C - * @url http://www.espruino.com/Reference#l_Puck_magTemp + * Emitted when the touchscreen is dragged for a large enough distance to count as + * a gesture. + * If Bangle.strokes is defined and populated with data from `Unistroke.new`, the + * `event` argument will also contain a `stroke` field containing the most closely + * matching stroke name. + * For example: + * ``` + * Bangle.strokes = { + * up : Unistroke.new(new Uint8Array([57, 151, ... 158, 137])), + * alpha : Unistroke.new(new Uint8Array([161, 55, ... 159, 161])), + * }; + * Bangle.on('stroke',o=>{ + * print(o.stroke); + * g.clear(1).drawPoly(o.xy); + * }); + * // Might print something like + * { + * "xy": new Uint8Array([149, 50, ... 107, 136]), + * "stroke": "alpha" + * } + * ``` + * @param {string} event - The event to listen to. + * @param {(event: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `event` Object of form `{xy:Uint8Array([x1,y1,x2,y2...])}` containing touch coordinates + * @url http://www.espruino.com/Reference#l_Bangle_stroke */ - static magTemp(): number; + static on(event: "stroke", callback: (event: { xy: Uint8Array, stroke?: string }) => void): void; /** - * Called after `Puck.magOn()` every time magnetometer data is sampled. There is - * one argument which is an object of the form `{x,y,z}` containing magnetometer - * readings as integers (for more information see `Puck.mag()`). - * Check out [the Puck.js page on the - * magnetometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more - * information. - * ```JS - * Puck.magOn(10); // 10 Hz - * Puck.on('mag', function(e) { - * print(e); - * }); - * // { "x": -874, "y": -332, "z": -1938 } - * ``` + * Emitted at midnight (at the point the `day` health info is reset to 0). + * Can be used for housekeeping tasks that don't want to be run during the day. * @param {string} event - The event to listen to. - * @param {(xyz: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `xyz` an object of the form `{x,y,z}` - * @url http://www.espruino.com/Reference#l_Puck_mag + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_Bangle_midnight */ - static on(event: "mag", callback: (xyz: any) => void): void; + static on(event: "midnight", callback: () => void): void; /** - * Only on Puck.js v2.0 - * Called after `Puck.accelOn()` every time accelerometer data is sampled. There is - * one argument which is an object of the form `{acc:{x,y,z}, gyro:{x,y,z}}` - * containing the data. - * ```JS - * Puck.accelOn(12.5); // default 12.5Hz - * Puck.on('accel', function(e) { - * print(e); - * }); - * //{ - * // "acc": { "x": -525, "y": -112, "z": 8160 }, - * // "gyro": { "x": 154, "y": -152, "z": -34 } - * //} + * This function can be used to turn Bangle.js's LCD backlight off or on. + * This function resets the Bangle's 'activity timer' (like pressing a button or + * the screen would) so after a time period of inactivity set by + * `Bangle.setOptions({backlightTimeout: X});` the backlight will turn off. + * If you want to keep the backlight on permanently (until apps are changed) you can + * do: * ``` - * The data is as it comes off the accelerometer and is not scaled to 1g. For more - * information see `Puck.accel()` or [the Puck.js page on the - * magnetometer](http://www.espruino.com/Puck.js#on-board-peripherals). - * @param {string} event - The event to listen to. - * @param {(e: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `e` an object of the form `{acc:{x,y,z}, gyro:{x,y,z}}` - * @url http://www.espruino.com/Reference#l_Puck_accel + * Bangle.setOptions({backlightTimeout: 0}) // turn off the timeout + * Bangle.setBacklight(1); // keep screen on + * ``` + * Of course, the backlight depends on `Bangle.setLCDPower` too, so any lcdPowerTimeout/setLCDTimeout will + * also turn the backlight off. The use case is when you require the backlight timeout + * to be shorter than the power timeout. + * + * @param {boolean} isOn - True if the LCD backlight should be on, false if not + * @url http://www.espruino.com/Reference#l_Bangle_setBacklight */ - static on(event: "accel", callback: (e: any) => void): void; + static setBacklight(isOn: ShortBoolean): void; /** - * Turn the magnetometer on and start periodic sampling. Samples will then cause a - * 'mag' event on 'Puck': + * This function can be used to turn Bangle.js's LCD off or on. + * This function resets the Bangle's 'activity timer' (like pressing a button or + * the screen would) so after a time period of inactivity set by + * `Bangle.setLCDTimeout` the screen will turn off. + * If you want to keep the screen on permanently (until apps are changed) you can + * do: * ``` - * Puck.magOn(); - * Puck.on('mag', function(xyz) { - * console.log(xyz); - * // {x:..., y:..., z:...} - * }); - * // Turn events off with Puck.magOff(); + * Bangle.setLCDTimeout(0); // turn off the timeout + * Bangle.setLCDPower(1); // keep screen on * ``` - * This call will be ignored if the sampling is already on. - * If given an argument, the sample rate is set (if not, it's at 0.63 Hz). The - * sample rate must be one of the following (resulting in the given power - * consumption): - * * 80 Hz - 900uA - * * 40 Hz - 550uA - * * 20 Hz - 275uA - * * 10 Hz - 137uA - * * 5 Hz - 69uA - * * 2.5 Hz - 34uA - * * 1.25 Hz - 17uA - * * 0.63 Hz - 8uA - * * 0.31 Hz - 8uA - * * 0.16 Hz - 8uA - * * 0.08 Hz - 8uA - * When the battery level drops too low while sampling is turned on, the - * magnetometer may stop sampling without warning, even while other Puck functions - * continue uninterrupted. - * Check out [the Puck.js page on the - * magnetometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more - * information. + * **When on full, the LCD draws roughly 40mA.** You can adjust When brightness + * using `Bangle.setLCDBrightness`. * - * @param {number} samplerate - The sample rate in Hz, or undefined - * @url http://www.espruino.com/Reference#l_Puck_magOn + * @param {boolean} isOn - True if the LCD should be on, false if not + * @url http://www.espruino.com/Reference#l_Bangle_setLCDPower */ - static magOn(samplerate: number): void; + static setLCDPower(isOn: ShortBoolean): void; /** - * Turn the magnetometer off - * @url http://www.espruino.com/Reference#l_Puck_magOff + * This function can be used to adjust the brightness of Bangle.js's display, and + * hence prolong its battery life. + * Due to hardware design constraints on Bangle.js 1, software PWM has to be used which means that + * the display may flicker slightly when Bluetooth is active and the display is not + * at full power. + * **Power consumption** + * * 0 = 7mA + * * 0.1 = 12mA + * * 0.2 = 18mA + * * 0.5 = 28mA + * * 0.9 = 40mA (switching overhead) + * * 1 = 40mA + * In 2v21 and earlier, this function would erroneously turn the LCD backlight on. 2v22 and later + * fix this, and if you want the backlight on your should use `Bangle.setLCDPowerBacklight()` + * + * @param {number} brightness - The brightness of Bangle.js's display - from 0(off) to 1(on full) + * @url http://www.espruino.com/Reference#l_Bangle_setLCDBrightness */ - static magOff(): void; + static setLCDBrightness(brightness: number): void; /** - * Writes a register on the LIS3MDL / MAX3110 Magnetometer. Can be used for - * configuring advanced functions. - * Check out [the Puck.js page on the - * magnetometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more - * information and links to modules that use this function. + * This function can be used to change the way graphics is handled on Bangle.js. + * Available options for `Bangle.setLCDMode` are: + * * `Bangle.setLCDMode()` or `Bangle.setLCDMode("direct")` (the default) - The + * drawable area is 240x240 16 bit. Unbuffered, so draw calls take effect + * immediately. Terminal and vertical scrolling work (horizontal scrolling + * doesn't). + * * `Bangle.setLCDMode("doublebuffered")` - The drawable area is 240x160 16 bit, + * terminal and scrolling will not work. `g.flip()` must be called for draw + * operations to take effect. + * * `Bangle.setLCDMode("120x120")` - The drawable area is 120x120 8 bit, + * `g.getPixel`, terminal, and full scrolling work. Uses an offscreen buffer + * stored on Bangle.js, `g.flip()` must be called for draw operations to take + * effect. + * * `Bangle.setLCDMode("80x80")` - The drawable area is 80x80 8 bit, `g.getPixel`, + * terminal, and full scrolling work. Uses an offscreen buffer stored on + * Bangle.js, `g.flip()` must be called for draw operations to take effect. + * You can also call `Bangle.setLCDMode()` to return to normal, unbuffered + * `"direct"` mode. * - * @param {number} reg - * @param {number} data - * @url http://www.espruino.com/Reference#l_Puck_magWr + * @param {any} mode - The LCD mode (See below) + * @url http://www.espruino.com/Reference#l_Bangle_setLCDMode */ - static magWr(reg: number, data: number): void; + static setLCDMode(mode?: LCDMode): void; /** - * Reads a register from the LIS3MDL / MAX3110 Magnetometer. Can be used for - * configuring advanced functions. - * Check out [the Puck.js page on the - * magnetometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more - * information and links to modules that use this function. + * The current LCD mode. + * See `Bangle.setLCDMode` for examples. + * @returns {any} The LCD mode as a String + * @url http://www.espruino.com/Reference#l_Bangle_getLCDMode + */ + static getLCDMode(): LCDMode; + + /** + * This can be used to move the displayed memory area up or down temporarily. It's + * used for displaying notifications while keeping the main display contents + * intact. * - * @param {number} reg - * @returns {number} - * @url http://www.espruino.com/Reference#l_Puck_magRd + * @param {number} y - The amount of pixels to shift the LCD up or down + * @url http://www.espruino.com/Reference#l_Bangle_setLCDOffset */ - static magRd(reg: number): number; + static setLCDOffset(y: number): void; + + /** + * Overlay an image or graphics instance on top of the contents of the graphics buffer. + * This only works on Bangle.js 2 because Bangle.js 1 doesn't have an offscreen buffer accessible from the CPU. + * ``` + * // display an alarm clock icon on the screen + * var img = require("heatshrink").decompress(atob(`lss4UBvvv///ovBlMyqoADv/VAwlV//1qtfAQX/BINXDoPVq/9DAP + * /AYIKDrWq0oREAYPW1QAB1IWCBQXaBQWq04WCAQP6BQeqA4P1AQPq1WggEK1WrBAIkBBQJsCBYO///fBQOoPAcqCwP3BQnwgECCwP9 + * GwIKCngWC14sB7QKCh4CBCwN/64KDgfACwWn6vWGwYsBCwOputWJgYsCgGqytVBQYsCLYOlqtqwAsFEINVrR4BFgghBBQosDEINWIQ + * YsDEIQ3DFgYhCG4msSYeVFgnrFhMvOAgsEkE/FhEggYWCFgIhDkEACwQKBEIYKBCwSGFBQJxCQwYhBBQTKDqohCBQhCCEIJlDXwrKE + * BQoWHBQdaCwuqJoI4CCwgKECwJ9CJgIKDq+qBYUq1WtBQf+BYIAC3/VBQX/tQKDz/9BQY5BAAVV/4WCBQJcBKwVf+oHBv4wCAAYhB`)); + * Bangle.setLCDOverlay(img,66,66, {id: "myOverlay", remove: () => print("Removed")}); + * ``` + * Or use a `Graphics` instance: + * ``` + * var ovr = Graphics.createArrayBuffer(100,100,2,{msb:true}); + * ovr.transparent = 0; // (optional) set a transparent color + * ovr.palette = new Uint16Array([0,0,g.toColor("#F00"),g.toColor("#FFF")]); // (optional) set a color palette + * ovr.setColor(1).fillRect({x:0,y:0,w:99,h:99,r:8}); + * ovr.setColor(3).fillRect({x:2,y:2,w:95,h:95,r:7}); + * ovr.setColor(2).setFont("Vector:30").setFontAlign(0,0).drawString("Hi",50,50); + * Bangle.setLCDOverlay(ovr,38,38, {id: "myOverlay", remove: () => print("Removed")}); + * ``` + * To remove an overlay, simply call: + * ``` + * Bangle.setLCDOverlay(undefined, {id: "myOverlay"}); + * ``` + * Before 2v22 the `options` object isn't parsed, and as a result + * the remove callback won't be called, and `Bangle.setLCDOverlay(undefined)` will + * remove *any* active overlay. + * The `remove` callback is called when the current overlay is removed or replaced with + * another, but *not* if setLCDOverlay is called again with an image and the same ID. + * + * @param {any} img - An image, or undefined to clear + * @param {any} x - The X offset the graphics instance should be overlaid on the screen with + * @param {number} y - The Y offset the graphics instance should be overlaid on the screen with + * @param {any} options - [Optional] object `{remove:fn, id:"str"}` + * @url http://www.espruino.com/Reference#l_Bangle_setLCDOverlay + */ + static setLCDOverlay(img: any, x: number, y: number): void; + static setLCDOverlay(): void; + static setLCDOverlay(img: any, x: number, y: number, options: { id : string, remove: () => void }): void; + static setLCDOverlay(img: any, options: { id : string }): void; /** - * On Puck.js v2.0 this will use the on-board PCT2075TP temperature sensor, but on - * Puck.js the less accurate on-chip Temperature sensor is used. - * @returns {number} Temperature in degrees C - * @url http://www.espruino.com/Reference#l_Puck_getTemperature + * This function can be used to turn Bangle.js's LCD power saving on or off. + * With power saving off, the display will remain in the state you set it with + * `Bangle.setLCDPower`. + * With power saving on, the display will turn on if a button is pressed, the watch + * is turned face up, or the screen is updated (see `Bangle.setOptions` for + * configuration). It'll turn off automatically after the given timeout. + * **Note:** This function also sets the Backlight and Lock timeout (the time at + * which the touchscreen/buttons start being ignored). To set both separately, use + * `Bangle.setOptions` + * + * @param {number} isOn - The timeout of the display in seconds, or `0`/`undefined` to turn power saving off. Default is 10 seconds. + * @url http://www.espruino.com/Reference#l_Bangle_setLCDTimeout */ - static getTemperature(): number; + static setLCDTimeout(isOn: number): void; /** - * Accepted values are: - * * 1.6 Hz (no Gyro) - 40uA (2v05 and later firmware) - * * 12.5 Hz (with Gyro)- 350uA - * * 26 Hz (with Gyro) - 450 uA - * * 52 Hz (with Gyro) - 600 uA - * * 104 Hz (with Gyro) - 900 uA - * * 208 Hz (with Gyro) - 1500 uA - * * 416 Hz (with Gyro) (not recommended) - * * 833 Hz (with Gyro) (not recommended) - * * 1660 Hz (with Gyro) (not recommended) - * Once `Puck.accelOn()` is called, the `Puck.accel` event will be called each time - * data is received. `Puck.accelOff()` can be called to turn the accelerometer off. - * For instance to light the red LED whenever Puck.js is face up: - * ``` - * Puck.on('accel', function(a) { - * digitalWrite(LED1, a.acc.z > 0); - * }); - * Puck.accelOn(); - * ``` - * Check out [the Puck.js page on the - * accelerometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more - * information. - * **Note:** Puck.js cannot currently read every sample from the - * accelerometer at sample rates above 208Hz. + * Set how often the watch should poll its sensors (accel/hr/mag) for new data and kick the + * Watchdog timer. It isn't recommended that you make this interval much larger + * than 1000ms, but values up to 4000ms are allowed. + * Calling this will set `Bangle.setOptions({powerSave: false})` - disabling the + * dynamic adjustment of poll interval to save battery power when Bangle.js is + * stationary. * - * @param {number} samplerate - The sample rate in Hz, or `undefined` (default is 12.5 Hz) - * @url http://www.espruino.com/Reference#l_Puck_accelOn + * @param {number} interval - Polling interval in milliseconds (Default is 80ms - 12.5Hz to match accelerometer) + * @url http://www.espruino.com/Reference#l_Bangle_setPollInterval */ - static accelOn(samplerate: number): void; + static setPollInterval(interval: number): void; /** - * Turn the accelerometer off after it has been turned on by `Puck.accelOn()`. - * Check out [the Puck.js page on the - * accelerometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more - * information. - * @url http://www.espruino.com/Reference#l_Puck_accelOff + * Set internal options used for gestures, etc... + * * `wakeOnBTN1` should the LCD turn on when BTN1 is pressed? default = `true` + * * `wakeOnBTN2` (Bangle.js 1) should the LCD turn on when BTN2 is pressed? + * default = `true` + * * `wakeOnBTN3` (Bangle.js 1) should the LCD turn on when BTN3 is pressed? + * default = `true` + * * `wakeOnFaceUp` should the LCD turn on when the watch is turned face up? + * default = `false` + * * `wakeOnTouch` should the LCD turn on when the touchscreen is pressed? On Bangle.js 1 this + * is a physical press on the touchscreen, on Bangle.js 2 we have to use the accelerometer as + * the touchscreen cannot be left powered without running the battery down. default = `false` + * * `wakeOnDoubleTap` (2v20 onwards) should the LCD turn on when the watch is double-tapped on the screen? + * This uses the accelerometer, not the touchscreen itself. default = `false` + * * `wakeOnTwist` should the LCD turn on when the watch is twisted? default = + * `true` + * * `twistThreshold` How much acceleration to register a twist of the watch strap? + * Can be negative for opposite direction. default = `800` + * * `twistMaxY` Maximum acceleration in Y to trigger a twist (low Y means watch is + * facing the right way up). default = `-800` + * * `twistTimeout` How little time (in ms) must a twist take from low->high + * acceleration? default = `1000` + * * `gestureStartThresh` how big a difference before we consider a gesture + * started? default = `sqr(800)` + * * `gestureEndThresh` how small a difference before we consider a gesture ended? + * default = `sqr(2000)` + * * `gestureInactiveCount` how many samples do we keep after a gesture has ended? + * default = `4` + * * `gestureMinLength` how many samples must a gesture have before we notify about + * it? default = `10` + * * `powerSave` after a minute of not being moved, Bangle.js will change the + * accelerometer poll interval down to 800ms (10x accelerometer samples). On + * movement it'll be raised to the default 80ms. If `Bangle.setPollInterval` is + * used this is disabled, and for it to work the poll interval must be either + * 80ms or 800ms. default = `true`. Setting `powerSave:false` will disable this + * automatic power saving, but will **not** change the poll interval from its + * current value. If you desire a specific interval (e.g. the default 80ms) you + * must set it manually with `Bangle.setPollInterval(80)` after setting + * `powerSave:false`. + * * `lowResistanceFix` (Bangle.js 2, 2v22+) In the very rare case that your watch button + * gets damaged such that it has a low resistance and always stays on, putting the watch + * into a boot loop, setting this flag may improve matters (by forcing the input low + * before reading and disabling the hardware watch on BTN1). + * * `lockTimeout` how many milliseconds before the screen locks + * * `lcdPowerTimeout` how many milliseconds before the screen turns off + * * `backlightTimeout` how many milliseconds before the screen's backlight turns + * off + * * `btnLoadTimeout` how many milliseconds does the home button have to be pressed + * for before the clock is reloaded? 1500ms default, or 0 means never. + * * `manualWatchdog` if set, this disables automatic kicking of the watchdog timer + * from the interrupt (when the button isn't held). You will then have to manually + * call `E.kickWatchdog()` from your code or the watch will reset after ~5 seconds. + * * `hrmPollInterval` set the requested poll interval (in milliseconds) for the + * heart rate monitor. On Bangle.js 2 only 10,20,40,80,160,200 ms are supported, + * and polling rate may not be exact. The algorithm's filtering is tuned for + * 20-40ms poll intervals, so higher/lower intervals may effect the reliability + * of the BPM reading. You must call this *before* `Bangle.setHRMPower` - calling + * when the HRM is already on will not affect the poll rate. + * * `hrmSportMode` - on the newest Bangle.js 2 builds with with the proprietary + * heart rate algorithm, this is the sport mode passed to the algorithm. See `libs/misc/vc31_binary/algo.h` + * for more info. -1 = auto, 0 = normal (default), 1 = running, 2 = ... + * * `hrmGreenAdjust` - (Bangle.js 2, 2v19+) if false (default is true) the green LED intensity won't be adjusted to get the HRM sensor 'exposure' correct. This is reset when the HRM is initialised with `Bangle.setHRMPower`. + * * `hrmWearDetect` - (Bangle.js 2, 2v19+) if false (default is true) HRM readings won't be turned off if the watch isn't on your arm (based on HRM proximity sensor). This is reset when the HRM is initialised with `Bangle.setHRMPower`. + * * `hrmPushEnv` - (Bangle.js 2, 2v19+) if true (default is false) HRM environment readings will be produced as `Bangle.on(`HRM-env`, ...)` events. This is reset when the HRM is initialised with `Bangle.setHRMPower`. + * * `seaLevelPressure` (Bangle.js 2) Default 1013.25 millibars - this is used when calculating altitude from pressure sensor values from `Bangle.getPressure`/`pressure` events. + * * `lcdBufferPtr` (Bangle.js 2 2v21+) Return a pointer to the first pixel of the 3 bit graphics buffer used by Bangle.js for the screen (stride = 178 bytes) + * * `lcdDoubleRefresh` (Bangle.js 2 2v22+) If enabled, pulses EXTCOMIN twice per poll interval (avoids off-axis flicker) + * Where accelerations are used they are in internal units, where `8192 = 1g` + * + * @param {any} options + * @url http://www.espruino.com/Reference#l_Bangle_setOptions */ - static accelOff(): void; + static setOptions(options: { [key in keyof BangleOptions]?: BangleOptions[key] }): void; /** - * Turn on the accelerometer, take a single reading, and then turn it off again. - * The values reported are the raw values from the chip. In normal configuration: - * * accelerometer: full-scale (32768) is 4g, so you need to divide by 8192 to get - * correctly scaled values - * * gyro: full-scale (32768) is 245 dps, so you need to divide by 134 to get - * correctly scaled values - * If taking more than one reading, we'd suggest you use `Puck.accelOn()` and the - * `Puck.accel` event. - * @returns {any} An Object `{acc:{x,y,z}, gyro:{x,y,z}}` of accelerometer/gyro readings - * @url http://www.espruino.com/Reference#l_Puck_accel + * Return the current state of options as set by `Bangle.setOptions` + * @returns {any} The current state of all options + * @url http://www.espruino.com/Reference#l_Bangle_getOptions */ - static accel(): any; + static getOptions(): BangleOptions; /** - * Writes a register on the LSM6DS3TR-C Accelerometer. Can be used for configuring - * advanced functions. - * Check out [the Puck.js page on the - * accelerometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more - * information and links to modules that use this function. - * - * @param {number} reg - * @param {number} data - * @url http://www.espruino.com/Reference#l_Puck_accelWr + * Also see the `Bangle.lcdPower` event + * You can use `Bangle.setLCDPower` to turn on the LCD (on Bangle.js 2 the LCD is normally on, and draws very little power so can be left on). + * @returns {boolean} Is the display on or not? + * @url http://www.espruino.com/Reference#l_Bangle_isLCDOn */ - static accelWr(reg: number, data: number): void; + static isLCDOn(): boolean; /** - * Reads a register from the LSM6DS3TR-C Accelerometer. Can be used for configuring - * advanced functions. - * Check out [the Puck.js page on the - * accelerometer](http://www.espruino.com/Puck.js#on-board-peripherals) for more - * information and links to modules that use this function. - * - * @param {number} reg - * @returns {number} - * @url http://www.espruino.com/Reference#l_Puck_accelRd + * Also see the `Bangle.backlight` event + * You can use `Bangle.setLCDPowerBacklight` to turn on the LCD backlight. + * @returns {boolean} Is the backlight on or not? + * @url http://www.espruino.com/Reference#l_Bangle_isBacklightOn */ - static accelRd(reg: number): number; + static isBacklightOn(): boolean; /** - * Transmit the given set of IR pulses - data should be an array of pulse times in - * milliseconds (as `[on, off, on, off, on, etc]`). - * For example `Puck.IR(pulseTimes)` - see http://www.espruino.com/Puck.js+Infrared - * for a full example. - * You can also attach an external LED to Puck.js, in which case you can just - * execute `Puck.IR(pulseTimes, led_cathode, led_anode)` - * It is also possible to just supply a single pin for IR transmission with - * `Puck.IR(pulseTimes, led_anode)` (on 2v05 and above). + * This function can be used to lock or unlock Bangle.js (e.g. whether buttons and + * touchscreen work or not) * - * @param {any} data - An array of pulse lengths, in milliseconds - * @param {Pin} [cathode] - [optional] pin to use for IR LED cathode - if not defined, the built-in IR LED is used - * @param {Pin} [anode] - [optional] pin to use for IR LED anode - if not defined, the built-in IR LED is used - * @url http://www.espruino.com/Reference#l_Puck_IR + * @param {boolean} isLocked - `true` if the Bangle is locked (no user input allowed) + * @url http://www.espruino.com/Reference#l_Bangle_setLocked */ - static IR(data: any, cathode?: Pin, anode?: Pin): void; + static setLocked(isLocked: ShortBoolean): void; /** - * Capacitive sense - the higher the capacitance, the higher the number returned. - * If called without arguments, a value depending on the capacitance of what is - * attached to pin D11 will be returned. If you attach a length of wire to D11, - * you'll be able to see a higher value returned when your hand is near the wire - * than when it is away. - * You can also supply pins to use yourself, however if you do this then the TX pin - * must be connected to RX pin and sense plate via a roughly 1MOhm resistor. - * When not supplying pins, Puck.js uses an internal resistor between D12(tx) and - * D11(rx). - * - * @param {Pin} tx - * @param {Pin} rx - * @returns {number} Capacitive sense counter - * @url http://www.espruino.com/Reference#l_Puck_capSense + * Also see the `Bangle.lock` event + * @returns {boolean} Is the screen locked or not? + * @url http://www.espruino.com/Reference#l_Bangle_isLocked */ - static capSense(tx: Pin, rx: Pin): number; + static isLocked(): boolean; /** - * Return a light value based on the light the red LED is seeing. - * **Note:** If called more than 5 times per second, the received light value may - * not be accurate. - * @returns {number} A light value from 0 to 1 - * @url http://www.espruino.com/Reference#l_Puck_light + * @returns {boolean} Is the battery charging or not? + * @url http://www.espruino.com/Reference#l_Bangle_isCharging */ - static light(): number; + static isCharging(): boolean; /** - * **DEPRECATED** - Please use `E.getBattery()` instead. - * Return an approximate battery percentage remaining based on a normal CR2032 - * battery (2.8 - 2.2v). - * @returns {number} A percentage between 0 and 100 - * @url http://www.espruino.com/Reference#l_Puck_getBatteryPercentage + * Writes a command directly to the ST7735 LCD controller + * + * @param {number} cmd + * @param {any} data + * @url http://www.espruino.com/Reference#l_Bangle_lcdWr */ - static getBatteryPercentage(): number; + static lcdWr(cmd: number, data: any): void; /** - * Run a self-test, and return true for a pass. This checks for shorts between - * pins, so your Puck shouldn't have anything connected to it. - * **Note:** This self-test auto starts if you hold the button on your Puck down - * while inserting the battery, leave it pressed for 3 seconds (while the green LED - * is lit) and release it soon after all LEDs turn on. 5 red blinks is a fail, 5 - * green is a pass. - * If the self test fails, it'll set the Puck.js Bluetooth advertising name to - * `Puck.js !ERR` where ERR is a 3 letter error code. - * @returns {boolean} True if the self-test passed - * @url http://www.espruino.com/Reference#l_Puck_selfTest + * Set the power to the Heart rate monitor + * When on, data is output via the `HRM` event on `Bangle`: + * ``` + * Bangle.setHRMPower(true, "myapp"); + * Bangle.on('HRM',print); + * ``` + * *When on, the Heart rate monitor draws roughly 5mA* + * + * @param {boolean} isOn - True if the heart rate monitor should be on, false if not + * @param {any} appID - A string with the app's name in, used to ensure one app can't turn off something another app is using + * @returns {boolean} Is HRM on? + * @url http://www.espruino.com/Reference#l_Bangle_setHRMPower */ - static selfTest(): boolean; - - -} + static setHRMPower(isOn: ShortBoolean, appID: string): boolean; -/** - * Class containing utility functions for the [Jolt.js Smart Bluetooth driver](http://www.espruino.com/Jolt.js) - * @url http://www.espruino.com/Reference#Jolt - */ -declare class Jolt { /** - * `Q0` and `Q1` Qwiic connectors can have their power controlled by a 500mA FET (`Jolt.Q0.fet`) which switches GND. - * The `sda` and `scl` pins on this port are also analog inputs - use `analogRead(Jolt.Q0.sda)`/etc - * To turn this connector on run `Jolt.Q0.setPower(1)` - * @returns {any} An object containing the pins for the Q0 connector on Jolt.js `{sda,scl,fet}` - * @url http://www.espruino.com/Reference#l_Jolt_Q0 + * Is the Heart rate monitor powered? + * Set power with `Bangle.setHRMPower(...);` + * @returns {boolean} Is HRM on? + * @url http://www.espruino.com/Reference#l_Bangle_isHRMOn */ - static Q0: Qwiic; + static isHRMOn(): boolean; /** - * `Q0` and `Q1` Qwiic connectors can have their power controlled by a 500mA FET (`Jolt.Q1.fet`) which switches GND. - * The `sda` and `scl` pins on this port are also analog inputs - use `analogRead(Jolt.Q1.sda)`/etc - * To turn this connector on run `Jolt.Q1.setPower(1)` - * @returns {any} An object containing the pins for the Q1 connector on Jolt.js `{sda,scl,fet}` - * @url http://www.espruino.com/Reference#l_Jolt_Q1 + * Set the power to the GPS. + * When on, data is output via the `GPS` event on `Bangle`: + * ``` + * Bangle.setGPSPower(true, "myapp"); + * Bangle.on('GPS',print); + * ``` + * *When on, the GPS draws roughly 20mA* + * + * @param {boolean} isOn - True if the GPS should be on, false if not + * @param {any} appID - A string with the app's name in, used to ensure one app can't turn off something another app is using + * @returns {boolean} Is the GPS on? + * @url http://www.espruino.com/Reference#l_Bangle_setGPSPower */ - static Q1: Qwiic; + static setGPSPower(isOn: ShortBoolean, appID: string): boolean; /** - * `Q2` and `Q3` have all 4 pins connected to Jolt.js's GPIO (including those usually used for power). - * As such only around 8mA of power can be supplied to any connected device. - * To use this as a normal Qwiic connector, run `Jolt.Q2.setPower(1)` - * @returns {any} An object containing the pins for the Q2 connector on Jolt.js `{sda,scl,gnd,vcc}` - * @url http://www.espruino.com/Reference#l_Jolt_Q2 + * Is the GPS powered? + * Set power with `Bangle.setGPSPower(...);` + * @returns {boolean} Is the GPS on? + * @url http://www.espruino.com/Reference#l_Bangle_isGPSOn */ - static Q2: Qwiic; + static isGPSOn(): boolean; /** - * `Q2` and `Q3` have all 4 pins connected to Jolt.js's GPIO (including those usually used for power). - * As such only around 8mA of power can be supplied to any connected device. - * To use this as a normal Qwiic connector, run `Jolt.Q3.setPower(1)` - * @returns {any} An object containing the pins for the Q3 connector on Jolt.js `{sda,scl,gnd,vcc}` - * @url http://www.espruino.com/Reference#l_Jolt_Q3 + * Get the last available GPS fix info (or `undefined` if GPS is off). + * The fix info received is the same as you'd get from the `Bangle.GPS` event. + * @returns {any} A GPS fix object with `{lat,lon,...}` + * @url http://www.espruino.com/Reference#l_Bangle_getGPSFix */ - static Q3: Qwiic; + static getGPSFix(): GPSFix; /** - * Sets the mode of the motor drivers. Jolt.js has two motor drivers, - * one (`0`) for outputs H0..H3, and one (`1`) for outputs H4..H7. They - * can be controlled independently. - * Mode can be: - * * `undefined` / `false` / `"off"` - the motor driver is off, all motor driver pins are open circuit (the motor driver still has a ~2.5k pulldown to GND) - * * `"auto"` - (default) - if any pin in the set of 4 pins (H0..H3, H4..H7) is set as an output, the driver is turned on. Eg `H0.set()` will - * turn the driver on with a high output, `H0.reset()` will pull the output to GND and `H0.read()` (or `H0.mode("input")` to set the state explicitly) is needed to - * turn the motor driver off. - * * `true` / `"output"` - **[recommended]** driver is set to "Independent bridge" mode. All 4 outputs in the bank are enabled - * * `"motor"` - driver is set to "4 pin interface" mode where pins are paired up (H0+H1, H2+H3, etc). If both - * in a pair are 0 the output is open circuit (motor coast), if both are 1 both otputs are 0 (motor brake), and - * if both are different, those values are on the output: - * `output`/`auto` mode: - * | H0 | H1 | Out 0 | Out 1 | - * |----|----|-------|-------| - * | 0 | 0 | Low | Low | - * | 0 | 1 | Low | High | - * | 1 | 0 | High | Low | - * | 1 | 1 | High | High | - * `motor` mode - * | H0 | H1 | Out 0 | Out 1 | - * |----|----|-------|-------| - * | 0 | 0 | Open | Open | - * | 0 | 1 | Low | High | - * | 1 | 0 | High | Low | - * | 1 | 1 | Low | Low | + * Set the power to the Compass + * When on, data is output via the `mag` event on `Bangle`: + * ``` + * Bangle.setCompassPower(true, "myapp"); + * Bangle.on('mag',print); + * ``` + * *When on, the compass draws roughly 2mA* * - * @param {number} driver - The number of the motor driver (0 or 1) - * @param {any} mode - The mode of the motor driver (see below) - * @url http://www.espruino.com/Reference#l_Jolt_setDriverMode + * @param {boolean} isOn - True if the Compass should be on, false if not + * @param {any} appID - A string with the app's name in, used to ensure one app can't turn off something another app is using + * @returns {boolean} Is the Compass on? + * @url http://www.espruino.com/Reference#l_Bangle_setCompassPower */ - static setDriverMode(driver: number, mode: any): void; + static setCompassPower(isOn: ShortBoolean, appID: string): boolean; /** - * Run a self-test, and return true for a pass. This checks for shorts between - * pins, so your Jolt shouldn't have anything connected to it. - * **Note:** This self-test auto starts if you hold the button on your Jolt down - * while inserting the battery, leave it pressed for 3 seconds (while the green LED - * is lit) and release it soon after all LEDs turn on. 5 red blinks is a fail, 5 - * green is a pass. - * If the self test fails, it'll set the Jolt.js Bluetooth advertising name to - * `Jolt.js !ERR` where ERR is a 3 letter error code. - * @returns {boolean} True if the self-test passed - * @url http://www.espruino.com/Reference#l_Jolt_selfTest + * Is the compass powered? + * Set power with `Bangle.setCompassPower(...);` + * @returns {boolean} Is the Compass on? + * @url http://www.espruino.com/Reference#l_Bangle_isCompassOn */ - static selfTest(): boolean; - - -} - -/** - * Class containing utility functions for the Qwiic connectors - * on the [Jolt.js Smart Bluetooth driver](http://www.espruino.com/Jolt.js). - * Each class (available from `Jolt.Q0`/`Jolt.Q1`/`Jolt.Q2`/`Jolt.Q3`) - * has `sda` and `scl` fields with the pins for SDA and SCL on them. - * On Jolt.js, the four Qwiic connectors can be individually powered: - * * Q0/Q1 - GND is switched with a 500mA FET. The `fet` field contains the pin that controls the FET - * * Q2/Q3 - all 4 pins are connected to GPIO. `gnd` and `vcc` fields contain the pins for GND and VCC - * To control the power, use `Qwiic.setPower`, for example: `Jolt.Q0.setPower(true)` - * @url http://www.espruino.com/Reference#Qwiic - */ -declare class Qwiic { - + static isCompassOn(): boolean; /** - * This turns power for the given Qwiic connector on or off. See `Qwiic` for more information. + * Resets the compass minimum/maximum values. Can be used if the compass isn't + * providing a reliable heading any more. * - * @param {boolean} isOn - Whether the Qwiic connector is to be on or not - * @returns {any} The same Qwiic object (for call chaining) - * @url http://www.espruino.com/Reference#l_Qwiic_setPower + * @url http://www.espruino.com/Reference#l_Bangle_resetCompass */ - setPower(isOn: ShortBoolean): any; + static resetCompass(): void; /** - * @returns {any} An I2C object using this Qwiic connector, already set up - * @url http://www.espruino.com/Reference#l_Qwiic_i2c + * Set the power to the barometer IC. Once enabled, `Bangle.pressure` events are + * fired each time a new barometer reading is available. + * When on, the barometer draws roughly 50uA + * + * @param {boolean} isOn - True if the barometer IC should be on, false if not + * @param {any} appID - A string with the app's name in, used to ensure one app can't turn off something another app is using + * @returns {boolean} Is the Barometer on? + * @url http://www.espruino.com/Reference#l_Bangle_setBarometerPower */ - i2c: any; -} + static setBarometerPower(isOn: ShortBoolean, appID: string): boolean; -/** - * @url http://www.espruino.com/Reference#Pip - */ -declare class Pip { /** - * The video had started - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_Pip_streamStarted + * Is the Barometer powered? + * Set power with `Bangle.setBarometerPower(...);` + * @returns {boolean} Is the Barometer on? + * @url http://www.espruino.com/Reference#l_Bangle_isBarometerOn */ - static on(event: "streamStarted", callback: () => void): void; + static isBarometerOn(): boolean; /** - * The video had ended - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_Pip_streamStopped + * Returns the current amount of steps recorded by the step counter + * @returns {number} The number of steps recorded by the step counter + * @url http://www.espruino.com/Reference#l_Bangle_getStepCount */ - static on(event: "streamStopped", callback: () => void): void; + static getStepCount(): number; /** - * The video had looped - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_Pip_streamLooped + * Sets the current value of the step counter + * + * @param {number} count - The value with which to reload the step counter + * @url http://www.espruino.com/Reference#l_Bangle_setStepCount */ - static on(event: "streamLooped", callback: () => void): void; + static setStepCount(count: number): void; /** - * - * @param {any} fn - Filename - * @param {any} options - [Optional] object `{x:0, y:0, debug:false, repeat:false}` - * @url http://www.espruino.com/Reference#l_Pip_videoStart + * Get the most recent Magnetometer/Compass reading. Data is in the same format as + * the `Bangle.on('mag',` event. + * Returns an `{x,y,z,dx,dy,dz,heading}` object + * * `x/y/z` raw x,y,z magnetometer readings + * * `dx/dy/dz` readings based on calibration since magnetometer turned on + * * `heading` in degrees based on calibrated readings (will be NaN if magnetometer + * hasn't been rotated around 360 degrees). + * **Note:** In 2v15 firmware and earlier the heading is inverted (360-heading). There's + * a fix in the bootloader which will apply a fix for those headings, but old apps may + * still expect an inverted value. + * To get this event you must turn the compass on with `Bangle.setCompassPower(1)`. + * @returns {any} An object containing magnetometer readings (as below) + * @url http://www.espruino.com/Reference#l_Bangle_getCompass */ - static videoStart(fn: any, options: any): void; + static getCompass(): CompassData; /** - * @url http://www.espruino.com/Reference#l_Pip_videoStop + * Get the most recent accelerometer reading. Data is in the same format as the + * `Bangle.on('accel',` event. + * * `x` is X axis (left-right) in `g` + * * `y` is Y axis (up-down) in `g` + * * `z` is Z axis (in-out) in `g` + * * `diff` is difference between this and the last reading in `g` (calculated by + * comparing vectors, not magnitudes) + * * `td` is the elapsed + * * `mag` is the magnitude of the acceleration in `g` + * @returns {any} An object containing accelerometer readings (as below) + * @url http://www.espruino.com/Reference#l_Bangle_getAccel */ - static videoStop(): void; + static getAccel(): AccelData & { td: number }; /** + * `range` is one of: + * * `undefined` or `'10min'` - health data so far in this 10 minute block (eg. 9:00.00 - 9:09.59) + * * `'last'` - health data during the last 10 minute block + * * `'day'` - the health data so far for the day + * `getHealthStatus` returns an object containing: + * * `movement` is the 32 bit sum of all `acc.diff` readings since power on (and + * rolls over). It is the difference in accelerometer values as `g*8192` + * * `steps` is the number of steps during this period + * * `bpm` the best BPM reading from HRM sensor during this period + * * `bpmConfidence` best BPM confidence (0-100%) during this period + * * `bpmMin`/`bpmMax` (2v26+) the minimum/maximum BPM reading from HRM sensor during this period (where confidence is over 90) + * * `activity` (2v26+) the currently assumed activity, one of "UNKNOWN","NOT_WORN","WALKING","EXERCISE" * - * @param {any} fn - Filename - * @param {any} options - [Optional] object `{debug:false, repeat:false}` - * @url http://www.espruino.com/Reference#l_Pip_audioStart + * @param {any} range - What time period to return data for, see below: + * @returns {any} Returns an object containing various health info + * @url http://www.espruino.com/Reference#l_Bangle_getHealthStatus + */ + static getHealthStatus(range?: "current" | "last" | "day"): HealthStatus; + + /** + * Reads debug info. Exposes the current values of `accHistoryIdx`, `accGestureCount`, `accIdleCount`, `pollInterval` and others. + * Please see the declaration of this function for more information (click the `==>` link above [this description](http://www.espruino.com/Reference#l_Bangle_dbg)) + * @returns {any} + * @url http://www.espruino.com/Reference#l_Bangle_dbg */ - static audioStart(fn: any, options: any): void; + static dbg(): any; /** - * Read the given WAV file into RAM + * Writes a register on the touch controller * - * @param {any} fn - Filename - * @returns {any} The raw sound data as a flat string - * @url http://www.espruino.com/Reference#l_Pip_audioRead + * @param {number} reg + * @param {number} data + * @url http://www.espruino.com/Reference#l_Bangle_touchWr */ - static audioRead(fn: any): any; + static touchWr(reg: number, data: number): void; /** - * Return the builtin sound + * Reads a register from the touch controller. See https://github.com/espruino/Espruino/issues/2146#issuecomment-2554296721 for a list + * of registers. When the touchscreen is off (eg the Bangle is locked) then reading from any register will return `255` (`0xFF`) - + * so ensure the Bangle is unlocked with `Bangle.setLocked(false)` before trying to read or write. + * For example `print(Bangle.touchRd(0xa7).toString(16))` returns the `ChipID` register, which is `0xB4` (CST816S) on older Bangles or `0xB6` (CST816D) on newer ones. + * **Note:** On Espruino 2v06 and before this function only returns a number (`cnt` is ignored). * - * @param {any} id - OK/NEXT/COLUMN - * @returns {any} The sound as a native string - * @url http://www.espruino.com/Reference#l_Pip_audioBuiltin + * @param {number} reg - Register number to read + * @param {number} cnt - If specified, returns an array of the given length (max 128). If not (or 0) it returns a number + * @returns {any} + * @url http://www.espruino.com/Reference#l_Bangle_touchRd */ - static audioBuiltin(id: any): any; + static touchRd(reg: number, cnt?: 0): number; + static touchRd(reg: number, cnt: number): number[]; /** - * Return how many samples are free in the ring buffer - * @returns {number} How many samples are left free in the ring buffer - * @url http://www.espruino.com/Reference#l_Pip_audioGetFree + * Writes a register on the accelerometer + * + * @param {number} reg - Register number to write + * @param {number} data - An integer value to write to the register + * @url http://www.espruino.com/Reference#l_Bangle_accelWr */ - static audioGetFree(): number; + static accelWr(reg: number, data: number): void; /** - * Play audio straight from a variable of raw WAV data - this adds everything to the buffer at once so blocks + * Reads a register from the accelerometer + * **Note:** On Espruino 2v06 and before this function only returns a number (`cnt` + * is ignored). * - * @param {any} wav - Raw 16 bit sound data - * @param {any} options - [Optional] object - * @url http://www.espruino.com/Reference#l_Pip_audioStartVar + * @param {number} reg + * @param {number} cnt - If specified, returns an array of the given length (max 128). If not (or 0) it returns a number + * @returns {any} + * @url http://www.espruino.com/Reference#l_Bangle_accelRd */ - static audioStartVar(wav: any, options: any): void; + static accelRd(reg: number, cnt?: 0): number; + static accelRd(reg: number, cnt: number): number[]; /** + * Writes a register on the barometer IC * - * @param {number} vol - * @url http://www.espruino.com/Reference#l_Pip_setVol + * @param {number} reg + * @param {number} data + * @url http://www.espruino.com/Reference#l_Bangle_barometerWr */ - static setVol(vol: number): void; + static barometerWr(reg: number, data: number): void; /** - * Writes a DAC register with a value + * Reads a register from the barometer IC * * @param {number} reg - * @param {number} value - * @url http://www.espruino.com/Reference#l_Pip_writeDACReg + * @param {number} cnt - If specified, returns an array of the given length (max 128). If not (or 0) it returns a number + * @returns {any} + * @url http://www.espruino.com/Reference#l_Bangle_barometerRd */ - static writeDACReg(reg: number, value: number): void; + static barometerRd(reg: number, cnt?: 0): number; + static barometerRd(reg: number, cnt: number): number[]; /** - * Returns the current value of a DAC register + * Writes a register on the Magnetometer/Compass * * @param {number} reg - * @returns {number} The current register value - * @url http://www.espruino.com/Reference#l_Pip_readDACReg + * @param {number} data + * @url http://www.espruino.com/Reference#l_Bangle_compassWr */ - static readDACReg(reg: number): number; + static compassWr(reg: number, data: number): void; /** - * Enable/disabled the DAC power supply (which also powers the audio amp and SD card) + * Read a register on the Magnetometer/Compass * - * @param {boolean} isOn - * @url http://www.espruino.com/Reference#l_Pip_setDACPower - */ - static setDACPower(isOn: ShortBoolean): void; - - /** - * Initialise the ES8388 audio codec IC - * @url http://www.espruino.com/Reference#l_Pip_initDAC + * @param {number} reg + * @param {number} cnt - If specified, returns an array of the given length (max 128). If not (or 0) it returns a number + * @returns {any} + * @url http://www.espruino.com/Reference#l_Bangle_compassRd */ - static initDAC(): void; + static compassRd(reg: number, cnt?: 0): number; + static compassRd(reg: number, cnt: number): number[]; /** - * * 'off'/undefined -> off - * * 'out' -> output + * Writes a register on the Heart rate monitor * - * @param {any} mode - Mode string - see below - * @url http://www.espruino.com/Reference#l_Pip_setDACMode + * @param {number} reg + * @param {number} data + * @url http://www.espruino.com/Reference#l_Bangle_hrmWr */ - static setDACMode(mode: any): void; + static hrmWr(reg: number, data: number): void; /** + * Read a register on the Heart rate monitor * - * @param {boolean} isOn - * @url http://www.espruino.com/Reference#l_Pip_setLCDPower - */ - static setLCDPower(isOn: ShortBoolean): void; - - /** - * Enter standby mode - can only be started by pressing the power button (PA0). - * @url http://www.espruino.com/Reference#l_Pip_off + * @param {number} reg + * @param {number} cnt - If specified, returns an array of the given length (max 128). If not (or 0) it returns a number + * @returns {any} + * @url http://www.espruino.com/Reference#l_Bangle_hrmRd */ - static off(): void; + static hrmRd(reg: number, cnt?: 0): number; + static hrmRd(reg: number, cnt: number): number[]; /** - * Enter sleep mode - JS is still executed - * @url http://www.espruino.com/Reference#l_Pip_sleep + * Changes a pin state on the IO expander + * + * @param {number} mask + * @param {number} isOn + * @url http://www.espruino.com/Reference#l_Bangle_ioWr */ - static sleep(): void; + static ioWr(mask: number, isOn: number): void; /** - * Wake up the pipboy - * @url http://www.espruino.com/Reference#l_Pip_wake + * Read temperature, pressure and altitude data. A promise is returned which will + * be resolved with `{temperature (C), pressure (hPa), altitude (meters)}`. + * If the Barometer has been turned on with `Bangle.setBarometerPower` then this + * will return with the *next* reading as of 2v21 (or the existing reading on 2v20 or earlier). If the Barometer is off, + * conversions take between 500-750ms. + * Altitude assumes a sea-level pressure of 1013.25 hPa, but this cal be adjusted with + * a call to `Bangle.setOptions({ seaLevelPressure : 1013.25 })` - the Bangle.js Settings + * app contains a tool to adjust it. + * If there's no pressure device (for example, the emulator), + * this returns `undefined`, rather than a Promise. + * ``` + * Bangle.getPressure().then(d=>{ + * console.log(d); + * // {temperature, pressure, altitude} + * }); + * ``` + * @returns {any} A promise that will be resolved with `{temperature, pressure, altitude}` + * @url http://www.espruino.com/Reference#l_Bangle_getPressure */ - static wake(): void; + static getPressure(): Promise | undefined; /** - * If `height` isn't specified the image height is used, otherwise only part of the image can be rendered. + * Perform a Spherical [Web Mercator + * projection](https://en.wikipedia.org/wiki/Web_Mercator_projection) of latitude + * and longitude into `x` and `y` coordinates, which are roughly equivalent to + * meters from `{lat:0,lon:0}`. + * This is the formula used for most online mapping and is a good way to compare + * GPS coordinates to work out the distance between them. * - * @param {any} img - * @param {number} x - * @param {number} y - * @param {any} options - scale(int) or { scale:int, noScanEffect:bool, height:int } - * @url http://www.espruino.com/Reference#l_Pip_blitImage + * @param {any} latlong - `{lat:..., lon:...}` + * @returns {any} {x:..., y:...} + * @url http://www.espruino.com/Reference#l_Bangle_project */ - static blitImage(img: any, x: number, y: number, options: any): void; + static project(latlong: { lat: number, lon: number }): { x: number, y: number }; /** - * This copies the contents of the current I2S audio buffer out to an array - * that can be rendered to the screen with drawPoly. - * Because the array is meant to be `x,y,x,y,x,y` only the second elements are - * touched. + * Use the piezo speaker to Beep for a certain time period and frequency * - * @param {any} dst - * @param {number} y1 - * @param {number} y2 - * @url http://www.espruino.com/Reference#l_Pip_getAudioWaveform - */ - static getAudioWaveform(dst: any, y1: number, y2: number): void; - - /** - * @returns {boolean} True if audio is currently playing - * @url http://www.espruino.com/Reference#l_Pip_audioIsPlaying + * @param {number} [time] - [optional] Time in ms (default 200) + * @param {number} [freq] - [optional] Frequency in hz (default 4000) + * @returns {any} A promise, completed when beep is finished + * @url http://www.espruino.com/Reference#l_Bangle_beep */ - static audioIsPlaying(): boolean; + static beep(time?: number, freq?: number): Promise; /** - * @returns {any} Returns `'video'` if a video is playing, or `'audio'` if audio is playing, `undefined` otherwise. - * @url http://www.espruino.com/Reference#l_Pip_streamPlaying + * Use the vibration motor to buzz for a certain time period + * + * @param {number} [time] - [optional] Time in ms (default 200) + * @param {number} [strength] - [optional] Power of vibration from 0 to 1 (Default 1) + * @returns {any} A promise, completed when vibration is finished + * @url http://www.espruino.com/Reference#l_Bangle_buzz */ - static streamPlaying(): any; - - -} + static buzz(time?: number, strength?: number): Promise; -/** - * Class containing utility functions for the [Bangle.js Smart - * Watch](http://www.espruino.com/Bangle.js) - * @url http://www.espruino.com/Reference#Bangle - */ -declare class Bangle { /** - * @url http://www.espruino.com/Reference#l_Bangle_drawWidgets + * Turn Bangle.js off. It can only be woken by pressing BTN1. + * @url http://www.espruino.com/Reference#l_Bangle_off */ - static drawWidgets(): void; + static off(): void; /** - * @url http://www.espruino.com/Reference#l_Bangle_setUI + * Turn Bangle.js (mostly) off, but keep the CPU in sleep mode until BTN1 is + * pressed to preserve the RTC (current time). + * @url http://www.espruino.com/Reference#l_Bangle_softOff */ - static setUI(): void; + static softOff(): void; /** - * Sets the rotation of the LCD display (relative to its nominal orientation) - * - * @param {number} d - The number of degrees to the LCD display (0, 90, 180 or 270) - * @url http://www.espruino.com/Reference#l_Bangle_setLCDRotation + * * On platforms with an LCD of >=8bpp this is 222 x 104 x 2 bits + * * Otherwise it's 119 x 56 x 1 bits + * @returns {any} An image to be used with `g.drawImage` (as a String) + * @url http://www.espruino.com/Reference#l_Bangle_getLogo */ - static setLCDRotation(d: number): void; + static getLogo(): string; /** - * Accelerometer data available with `{x,y,z,diff,mag}` object as a parameter. - * * `x` is X axis (left-right) in `g` - * * `y` is Y axis (up-down) in `g` - * * `z` is Z axis (in-out) in `g` - * * `diff` is difference between this and the last reading in `g` - * * `mag` is the magnitude of the acceleration in `g` - * You can also retrieve the most recent reading with `Bangle.getAccel()`. - * @param {string} event - The event to listen to. - * @param {(xyz: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `xyz` - * @url http://www.espruino.com/Reference#l_Bangle_accel + * Load all widgets from flash Storage. Call this once at the beginning of your + * application if you want any on-screen widgets to be loaded. + * They will be loaded into a global `WIDGETS` array, and can be rendered with + * `Bangle.drawWidgets`. + * @url http://www.espruino.com/Reference#l_Bangle_loadWidgets */ - static on(event: "accel", callback: (xyz: AccelData) => void): void; + static loadWidgets(): void; /** - * Called whenever a step is detected by Bangle.js's pedometer. - * @param {string} event - The event to listen to. - * @param {(up: number) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `up` The number of steps since Bangle.js was last reset - * @url http://www.espruino.com/Reference#l_Bangle_step + * Draw any onscreen widgets that were loaded with `Bangle.loadWidgets()`. + * Widgets should redraw themselves when something changes - you'll only need to + * call drawWidgets if you decide to clear the entire screen with `g.clear()`. + * @url http://www.espruino.com/Reference#l_Bangle_drawWidgets */ - static on(event: "step", callback: (up: number) => void): void; + static drawWidgets(): void; /** - * See `Bangle.getHealthStatus()` for more information. This is used for health - * tracking to allow Bangle.js to record historical exercise data. - * @param {string} event - The event to listen to. - * @param {(info: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `info` An object containing the last 10 minutes health data - * @url http://www.espruino.com/Reference#l_Bangle_health + * @url http://www.espruino.com/Reference#l_Bangle_drawWidgets */ - static on(event: "health", callback: (info: HealthStatus) => void): void; + static drawWidgets(): void; /** - * Has the watch been moved so that it is face-up, or not face up? - * @param {string} event - The event to listen to. - * @param {(up: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `up` `true` if face-up - * @url http://www.espruino.com/Reference#l_Bangle_faceUp + * Load the Bangle.js app launcher, which will allow the user to select an + * application to launch. + * @url http://www.espruino.com/Reference#l_Bangle_showLauncher */ - static on(event: "faceUp", callback: (up: ShortBoolean) => void): void; + static showLauncher(): void; /** - * This event happens when the watch has been twisted around it's axis - for - * instance as if it was rotated so someone could look at the time. - * To tweak when this happens, see the `twist*` options in `Bangle.setOptions()` - * @param {string} event - The event to listen to. - * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_Bangle_twist + * Load the Bangle.js clock - this has the same effect as calling `Bangle.load()`. + * @url http://www.espruino.com/Reference#l_Bangle_showClock */ - static on(event: "twist", callback: () => void): void; + static showClock(): void; /** - * Is the battery charging or not? - * @param {string} event - The event to listen to. - * @param {(charging: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `charging` `true` if charging - * @url http://www.espruino.com/Reference#l_Bangle_charging + * Show a 'recovery' menu that allows you to perform certain tasks on your Bangle. + * You can also enter this menu by restarting your Bangle while holding down the button. + * @url http://www.espruino.com/Reference#l_Bangle_showRecoveryMenu */ - static on(event: "charging", callback: (charging: ShortBoolean) => void): void; + static showRecoveryMenu(): void; /** - * Magnetometer/Compass data available with `{x,y,z,dx,dy,dz,heading}` object as a - * parameter - * * `x/y/z` raw x,y,z magnetometer readings - * * `dx/dy/dz` readings based on calibration since magnetometer turned on - * * `heading` in degrees based on calibrated readings (will be NaN if magnetometer - * hasn't been rotated around 360 degrees). - * **Note:** In 2v15 firmware and earlier the heading is inverted (360-heading). There's - * a fix in the bootloader which will apply a fix for those headings, but old apps may - * still expect an inverted value. - * To get this event you must turn the compass on with `Bangle.setCompassPower(1)`. - * You can also retrieve the most recent reading with `Bangle.getCompass()`. - * @param {string} event - The event to listen to. - * @param {(xyz: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `xyz` - * @url http://www.espruino.com/Reference#l_Bangle_mag + * @url http://www.espruino.com/Reference#l_Bangle_showRecoveryMenu */ - static on(event: "mag", callback: (xyz: CompassData) => void): void; + static showRecoveryMenu(): void; /** - * Raw NMEA GPS / u-blox data messages received as a string - * To get this event you must turn the GPS on with `Bangle.setGPSPower(1)`. - * @param {string} event - The event to listen to. - * @param {(nmea: any, dataLoss: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `nmea` A string containing the raw NMEA data from the GPS - * * `dataLoss` This is set to true if some lines of GPS data have previously been lost (eg because system was too busy to queue up a GPS-raw event) - * @url http://www.espruino.com/Reference#l_Bangle_GPS-raw + * (2v20 and later) Show a test screen that lights green when each sensor on the Bangle + * works and reports within range. + * Swipe on the screen when all items are green and the Bangle will turn bluetooth off + * and display a `TEST PASS` screen for 60 minutes, after which it will turn off. + * You can enter this menu by restarting your Bangle while holding down the button, + * then choosing `Test` from the recovery menu. + * @url http://www.espruino.com/Reference#l_Bangle_showTestScreen */ - static on(event: "GPS-raw", callback: (nmea: string, dataLoss: boolean) => void): void; + static showTestScreen(): void; /** - * GPS data, as an object. Contains: - * ``` - * { "lat": number, // Latitude in degrees - * "lon": number, // Longitude in degrees - * "alt": number, // altitude in M - * "speed": number, // Speed in kph - * "course": number, // Course in degrees - * "time": Date, // Current Time (or undefined if not known) - * "satellites": 7, // Number of satellites - * "fix": 1 // NMEA Fix state - 0 is no fix - * "hdop": number, // Horizontal Dilution of Precision - * } - * ``` - * If a value such as `lat` is not known because there is no fix, it'll be `NaN`. - * `hdop` is a value from the GPS receiver that gives a rough idea of accuracy of - * lat/lon based on the geometry of the satellites in range. Multiply by 5 to get a - * value in meters. This is just a ballpark estimation and should not be considered - * remotely accurate. - * To get this event you must turn the GPS on with `Bangle.setGPSPower(1)`. - * @param {string} event - The event to listen to. - * @param {(fix: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `fix` An object with fix info (see below) - * @url http://www.espruino.com/Reference#l_Bangle_GPS + * This behaves the same as the global `load()` function, but if fast + * loading is possible (`Bangle.setUI` was called with a `remove` handler) + * then instead of a complete reload, the `remove` handler will be + * called and the new app will be loaded straight after with `eval`. + * **This should only be used if the app being loaded also uses widgets** + * (eg it contains a `Bangle.loadWidgets()` call). + * `load()` is slower, but safer. As such, care should be taken + * when using `Bangle.load()` with `Bangle.setUI({..., remove:...})` + * as if your remove handler doesn't completely clean up after your app, + * memory leaks or other issues could occur - see `Bangle.setUI` for more + * information. + * + * @param {any} [file] - [optional] A string containing the file name for the app to be loaded + * @url http://www.espruino.com/Reference#l_Bangle_load */ - static on(event: "GPS", callback: (fix: GPSFix) => void): void; + static load(file: string): void; + static load(): void; /** - * Heat rate data, as an object. Contains: + * This puts Bangle.js into the specified UI input mode, and calls the callback + * provided when there is user input. + * Currently supported interface types are: + * * 'updown' - UI input with upwards motion `cb(-1)`, downwards motion `cb(1)`, + * and select `cb()` + * * Bangle.js 1 uses BTN1/3 for up/down and BTN2 for select + * * Bangle.js 2 uses touchscreen swipe up/down and tap + * * 'leftright' - UI input with left motion `cb(-1)`, right motion `cb(1)`, and + * select `cb()` + * * Bangle.js 1 uses BTN1/3 for left/right and BTN2 for select + * * Bangle.js 2 uses touchscreen swipe left/right and tap/BTN1 for select + * * 'clock' - called for clocks. Sets `Bangle.CLOCK=1` and allows a button to + * start the launcher + * * Bangle.js 1 BTN2 starts the launcher + * * Bangle.js 2 BTN1 starts the launcher + * * 'clockupdown' - called for clocks. Sets `Bangle.CLOCK=1`, allows a button to + * start the launcher, but also provides up/down functionality + * * Bangle.js 1 BTN2 starts the launcher, BTN1/BTN3 call `cb(-1)` and `cb(1)` + * * Bangle.js 2 BTN1 starts the launcher, touchscreen tap in top/bottom right + * hand side calls `cb(-1)` and `cb(1)` + * * `{mode:"custom", ...}` allows you to specify custom handlers for different + * interactions. See below. + * * `undefined` removes all user interaction code + * While you could use setWatch/etc manually, the benefit here is that you don't + * end up with multiple `setWatch` instances, and the actual input method (touch, + * or buttons) is implemented dependent on the watch (Bangle.js 1 or 2) * ``` - * { "bpm": number, // Beats per minute - * "confidence": number, // 0-100 percentage confidence in the heart rate - * "raw": Uint8Array, // raw samples from heart rate monitor - * } + * Bangle.setUI("updown", function (dir) { + * // dir is +/- 1 for swipes up/down + * // dir is 0 when button pressed + * }); * ``` - * To get this event you must turn the heart rate monitor on with - * `Bangle.setHRMPower(1)`. - * @param {string} event - The event to listen to. - * @param {(hrm: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `hrm` An object with heart rate info (see below) - * @url http://www.espruino.com/Reference#l_Bangle_HRM - */ - static on(event: "HRM", callback: (hrm: { bpm: number, confidence: number, raw: Uint8Array }) => void): void; - - /** - * Called when heart rate sensor data is available - see `Bangle.setHRMPower(1)`. - * `hrm` is of the form: + * The first argument can also be an object, in which case more options can be + * specified with `mode:"custom"`: * ``` - * { "raw": -1, // raw value from sensor - * "filt": -1, // bandpass-filtered raw value from sensor - * "bpm": 88.9, // last BPM value measured - * "confidence": 0 // confidence in the BPM value - * } + * Bangle.setUI({ + * mode : "custom", + * back : function() {}, // optional - add a 'back' icon in top-left widget area and call this function when it is pressed , also call it when the hardware button is clicked (does not override btn if defined) + * remove : function() {}, // optional - add a handler for when the UI should be removed (eg stop any intervals/timers here) + * redraw : function() {}, // optional - add a handler to redraw the UI. Not needed but it can allow widgets/etc to provide other functionality that requires the screen to be redrawn + * touch : function(n,e) {}, // optional - (mode:custom only) handler for 'touch' events + * swipe : function(dir) {}, // optional - (mode:custom only) handler for 'swipe' events + * drag : function(e) {}, // optional - (mode:custom only) handler for 'drag' events (Bangle.js 2 only) + * btn : function(n) {}, // optional - (mode:custom only) handler for 'button' events (n==1 on Bangle.js 2, n==1/2/3 depending on button for Bangle.js 1) + * clock : 0 // optional - if set the behavior of 'clock' mode is added (does not override btn if defined) + * }); * ``` - * @param {string} event - The event to listen to. - * @param {(hrm: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `hrm` A object containing instant readings from the heart rate sensor - * @url http://www.espruino.com/Reference#l_Bangle_HRM-raw - */ - static on(event: "HRM-raw", callback: (hrm: { raw: number, filt: number, bpm: number, confidence: number }) => void): void; - - /** - * Called when an environment sample heart rate sensor data is available (this is the amount of light received by the HRM sensor from the environment when its LED is off). On the newest VC31B based watches this is only 4 bit (0..15). - * To get it you need to turn the HRM on with `Bangle.setHRMPower(1)` and also set `Bangle.setOptions({hrmPushEnv:true})`. - * It is also possible to poke registers with `Bangle.hrmWr` to increase the poll rate if needed. See https://banglejs.com/apps/?id=flashcount for an example of this. - * @param {string} event - The event to listen to. - * @param {(env: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `env` An integer containing current environment reading (light level) - * @url http://www.espruino.com/Reference#l_Bangle_HRM-env + * If `remove` is specified, `Bangle.showLauncher`, `Bangle.showClock`, `Bangle.load` and some apps + * may choose to just call the `remove` function and then load a new app without resetting Bangle.js. + * As a result, **if you specify 'remove' you should make sure you test that after calling `Bangle.setUI()` + * without arguments your app is completely unloaded**, otherwise you may end up with memory leaks or + * other issues when switching apps. Please see the [Bangle.js Fast Load Tutorial](https://www.espruino.com/Bangle.js+Fast+Load) for more details on this. + * **Note:** You can override this function in boot code to change the interaction + * mode with the watch. For instance you could make all clocks start the launcher + * with a swipe by using: + * ``` + * (function() { + * var sui = Bangle.setUI; + * Bangle.setUI = function(mode, cb) { + * var m = ("object"==typeof mode) ? mode.mode : mode; + * if (m!="clock") return sui(mode,cb); + * sui(); // clear + * Bangle.CLOCK=1; + * Bangle.swipeHandler = Bangle.showLauncher; + * Bangle.on("swipe", Bangle.swipeHandler); + * }; + * })(); + * ``` + * + * @param {any} type - The type of UI input: 'updown', 'leftright', 'clock', 'clockupdown' or undefined to cancel. Can also be an object (see below) + * @param {any} callback - A function with one argument which is the direction + * @url http://www.espruino.com/Reference#l_Bangle_setUI */ - static on(event: "HRM-env", callback: (env: any) => void): void; + static setUI(type?: undefined): void; + static setUI(type: SetUIArg<"updown" | "leftright">, callback: (direction?: -1 | 1) => void): void; + static setUI(type: SetUIArg<"clock">): void; + static setUI(type: SetUIArg<"clockupdown">, callback?: (direction: -1 | 1) => void): void; + static setUI(type: SetUIArg<"custom"> & { touch?: TouchCallback; swipe?: SwipeCallback; drag?: DragCallback; btn?: (n: 1 | 2 | 3) => void; clock?: boolean | 0 | 1 }): void; /** - * When `Bangle.setBarometerPower(true)` is called, this event is fired containing - * barometer readings. - * Same format as `Bangle.getPressure()` - * @param {string} event - The event to listen to. - * @param {(e: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `e` An object containing `{temperature,pressure,altitude}` - * @url http://www.espruino.com/Reference#l_Bangle_pressure + * @url http://www.espruino.com/Reference#l_Bangle_setUI */ - static on(event: "pressure", callback: (e: PressureData) => void): void; + static setUI(): void; /** - * Has the screen been turned on or off? Can be used to stop tasks that are no - * longer useful if nothing is displayed. Also see `Bangle.isLCDOn()` - * @param {string} event - The event to listen to. - * @param {(on: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `on` `true` if screen is on - * @url http://www.espruino.com/Reference#l_Bangle_lcdPower + * Erase all storage and reload it with the default contents. + * This is only available on Bangle.js 2.0. On Bangle.js 1.0 you need to use + * `Install Default Apps` under the `More...` tab of http://banglejs.com/apps + * + * @param {boolean} noReboot - Do not reboot the watch when done (default false, so will reboot) + * @url http://www.espruino.com/Reference#l_Bangle_factoryReset */ - static on(event: "lcdPower", callback: (on: ShortBoolean) => void): void; + static factoryReset(noReboot: ShortBoolean): void; /** - * Has the backlight been turned on or off? Can be used to stop tasks that are no - * longer useful if want to see in sun screen only. Also see `Bangle.isBacklightOn()` - * @param {string} event - The event to listen to. - * @param {(on: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `on` `true` if backlight is on - * @url http://www.espruino.com/Reference#l_Bangle_backlight + * Returns the rectangle on the screen that is currently reserved for the app. + * @returns {any} An object of the form `{x,y,w,h,x2,y2}` + * @url http://www.espruino.com/Reference#l_Bangle_appRect */ - static on(event: "backlight", callback: (on: ShortBoolean) => void): void; + static appRect: { x: number, y: number, w: number, h: number, x2: number, y2: number }; - /** - * Has the screen been locked? Also see `Bangle.isLocked()` - * @param {string} event - The event to listen to. - * @param {(on: ShortBoolean, reason: string) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `on` `true` if screen is locked, `false` if it is unlocked and touchscreen/buttons will work - * * `reason` (2v20 onwards) If known, the reason for locking/unlocking - 'button','js','tap','doubleTap','faceUp','twist','timeout' - * @url http://www.espruino.com/Reference#l_Bangle_lock - */ - static on(event: "lock", callback: (on: ShortBoolean, reason: string) => void): void; + static CLOCK: ShortBoolean; + static strokes: undefined | { [key: string]: Unistroke }; +} +/** + * The NRF class is for controlling functionality of the Nordic nRF51/nRF52 chips. + * Most functionality is related to Bluetooth Low Energy, however there are also + * some functions related to NFC that apply to NRF52-based devices. + * @url http://www.espruino.com/Reference#NRF + */ +declare class NRF { /** - * If the watch is tapped, this event contains information on the way it was - * tapped. - * `dir` reports the side of the watch that was tapped (not the direction it was - * tapped in). - * ``` - * { - * dir : "left/right/top/bottom/front/back", - * double : true/false // was this a double-tap? - * x : -2 .. 2, // the axis of the tap - * y : -2 .. 2, // the axis of the tap - * z : -2 .. 2 // the axis of the tap - * ``` + * Called when a host device connects to Espruino. The first argument contains the + * address. * @param {string} event - The event to listen to. - * @param {(data: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `data` `{dir, double, x, y, z}` - * @url http://www.espruino.com/Reference#l_Bangle_tap + * @param {(addr: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `addr` The address of the device that has connected + * @url http://www.espruino.com/Reference#l_NRF_connect */ - static on(event: "tap", callback: (data: { dir: "left" | "right" | "top" | "bottom" | "front" | "back", double: boolean, x: TapAxis, y: TapAxis, z: TapAxis }) => void): void; + static on(event: "connect", callback: (addr: any) => void): void; /** - * Emitted when a 'gesture' (fast movement) is detected + * Called when a host device disconnects from Espruino. + * The most common reason is: + * * 19 - `REMOTE_USER_TERMINATED_CONNECTION` + * * 22 - `LOCAL_HOST_TERMINATED_CONNECTION` * @param {string} event - The event to listen to. - * @param {(xyz: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `xyz` An Int8Array of XYZXYZXYZ data - * @url http://www.espruino.com/Reference#l_Bangle_gesture + * @param {(reason: number) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `reason` The reason code reported back by the BLE stack - see Nordic's [`ble_hci.h` file](https://github.com/espruino/Espruino/blob/master/targetlibs/nrf5x_12/components/softdevice/s132/headers/ble_hci.h#L71) for more information + * @url http://www.espruino.com/Reference#l_NRF_disconnect */ - static on(event: "gesture", callback: (xyz: Int8Array) => void): void; + static on(event: "disconnect", callback: (reason: number) => void): void; /** - * Emitted when a 'gesture' (fast movement) is detected, and a Tensorflow model is - * in storage in the `".tfmodel"` file. - * If a `".tfnames"` file is specified as a comma-separated list of names, it will - * be used to decode `gesture` from a number into a string. + * Called when the Nordic Bluetooth stack (softdevice) generates an error. In pretty + * much all cases an Exception will also have been thrown. * @param {string} event - The event to listen to. - * @param {(gesture: any, weights: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `gesture` The name of the gesture (if '.tfnames' exists, or the index. 'undefined' if not matching - * * `weights` An array of floating point values output by the model - * @url http://www.espruino.com/Reference#l_Bangle_aiGesture + * @param {(msg: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `msg` The error string + * @url http://www.espruino.com/Reference#l_NRF_error */ - static on(event: "aiGesture", callback: (gesture: string | undefined, weights: number[]) => void): void; + static on(event: "error", callback: (msg: any) => void): void; /** - * Emitted when a swipe on the touchscreen is detected (a movement from - * left->right, right->left, down->up or up->down) - * Bangle.js 1 is only capable of detecting left/right swipes as it only contains a - * 2 zone touchscreen. + * (Added in 2v19) Called when a central device connects to Espruino, pairs, and sends a passkey that Espruino should display. + * For this to be used, you'll have to specify that your device has a display using `NRF.setSecurity({mitm:1, display:1});` + * For instance: + * ``` + * NRF.setSecurity({mitm:1, display:1}); + * NRF.on("passkey", key => print("Enter PIN: ",passkey)); + * ``` + * It is also possible to specify a static passkey with `NRF.setSecurity({passkey:"123456", mitm:1, display:1});` + * in which case no `passkey` event handler is needed (this method works on Espruino 2v02 and later) + * **Note:** A similar event, [`BluetoothDevice.on("passkey", ...)`](http://www.espruino.com/Reference#l_BluetoothDevice_passkey) is available + * for when Espruino is connecting *to* another device (central mode). * @param {string} event - The event to listen to. - * @param {(directionLR: number, directionUD: number) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `directionLR` `-1` for left, `1` for right, `0` for up/down - * * `directionUD` `-1` for up, `1` for down, `0` for left/right (Bangle.js 2 only) - * @url http://www.espruino.com/Reference#l_Bangle_swipe + * @param {(passkey: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `passkey` A 6 character numeric String to be displayed + * @url http://www.espruino.com/Reference#l_NRF_passkey */ - static on(event: "swipe", callback: SwipeCallback): void; + static on(event: "passkey", callback: (passkey: any) => void): void; /** - * Emitted when the touchscreen is pressed + * Contains updates on the security of the current Bluetooth link. + * See Nordic's `ble_gap_evt_auth_status_t` structure for more information. * @param {string} event - The event to listen to. - * @param {(button: number, xy: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `button` `1` for left, `2` for right - * * `xy` Object of form `{x,y,type}` containing touch coordinates (if the device supports full touch). Clipped to 0..175 (LCD pixel coordinates) on firmware 2v13 and later.`type` is only available on Bangle.js 2 and is an integer, either 0 for swift touches or 2 for longer ones. - * @url http://www.espruino.com/Reference#l_Bangle_touch + * @param {(status: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `status` An object containing `{auth_status,bonded,lv4,kdist_own,kdist_peer}` + * @url http://www.espruino.com/Reference#l_NRF_security */ - static on(event: "touch", callback: TouchCallback): void; + static on(event: "security", callback: (status: any) => void): void; /** - * Emitted when the touchscreen is dragged or released - * The touchscreen extends past the edge of the screen and while `x` and `y` - * coordinates are arranged such that they align with the LCD's pixels, if your - * finger goes towards the edge of the screen, `x` and `y` could end up larger than - * 175 (the screen's maximum pixel coordinates) or smaller than 0. Coordinates from - * the `touch` event are clipped. + * Called when Bluetooth advertising starts or stops on Espruino * @param {string} event - The event to listen to. - * @param {(event: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `event` Object of form `{x,y,dx,dy,b}` containing touch coordinates, difference in touch coordinates, and an integer `b` containing number of touch points (currently 1 or 0) - * @url http://www.espruino.com/Reference#l_Bangle_drag + * @param {(isAdvertising: ShortBoolean) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `isAdvertising` Whether we are advertising or not + * @url http://www.espruino.com/Reference#l_NRF_advertising */ - static on(event: "drag", callback: DragCallback): void; + static on(event: "advertising", callback: (isAdvertising: ShortBoolean) => void): void; /** - * Emitted when the touchscreen is dragged for a large enough distance to count as - * a gesture. - * If Bangle.strokes is defined and populated with data from `Unistroke.new`, the - * `event` argument will also contain a `stroke` field containing the most closely - * matching stroke name. - * For example: - * ``` - * Bangle.strokes = { - * up : Unistroke.new(new Uint8Array([57, 151, ... 158, 137])), - * alpha : Unistroke.new(new Uint8Array([161, 55, ... 159, 161])), - * }; - * Bangle.on('stroke',o=>{ - * print(o.stroke); - * g.clear(1).drawPoly(o.xy); - * }); - * // Might print something like - * { - * "xy": new Uint8Array([149, 50, ... 107, 136]), - * "stroke": "alpha" - * } - * ``` + * Called during the bonding process to update on status + * `status` is one of: + * * `"request"` - Bonding has been requested in code via `NRF.startBonding` + * * `"start"` - The bonding procedure has started + * * `"success"` - The bonding procedure has succeeded (`NRF.startBonding`'s promise resolves) + * * `"fail"` - The bonding procedure has failed (`NRF.startBonding`'s promise rejects) * @param {string} event - The event to listen to. - * @param {(event: any) => void} callback - A function that is executed when the event occurs. Its arguments are: - * * `event` Object of form `{xy:Uint8Array([x1,y1,x2,y2...])}` containing touch coordinates - * @url http://www.espruino.com/Reference#l_Bangle_stroke + * @param {(status: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `status` One of `'request'/'start'/'success'/'fail'` + * @url http://www.espruino.com/Reference#l_NRF_bond */ - static on(event: "stroke", callback: (event: { xy: Uint8Array, stroke?: string }) => void): void; + static on(event: "bond", callback: (status: any) => void): void; /** - * Emitted at midnight (at the point the `day` health info is reset to 0). - * Can be used for housekeeping tasks that don't want to be run during the day. + * Called with a single byte value when Espruino is set up as a HID device and the + * computer it is connected to sends a HID report back to Espruino. This is usually + * used for handling indications such as the Caps Lock LED. * @param {string} event - The event to listen to. * @param {() => void} callback - A function that is executed when the event occurs. - * @url http://www.espruino.com/Reference#l_Bangle_midnight + * @url http://www.espruino.com/Reference#l_NRF_HID */ - static on(event: "midnight", callback: () => void): void; + static on(event: "HID", callback: () => void): void; /** - * This function can be used to turn Bangle.js's LCD backlight off or on. - * This function resets the Bangle's 'activity timer' (like pressing a button or - * the screen would) so after a time period of inactivity set by - * `Bangle.setOptions({backlightTimeout: X});` the backlight will turn off. - * If you want to keep the backlight on permanently (until apps are changed) you can - * do: - * ``` - * Bangle.setOptions({backlightTimeout: 0}) // turn off the timeout - * Bangle.setBacklight(1); // keep screen on - * ``` - * Of course, the backlight depends on `Bangle.setLCDPower` too, so any lcdPowerTimeout/setLCDTimeout will - * also turn the backlight off. The use case is when you require the backlight timeout - * to be shorter than the power timeout. - * - * @param {boolean} isOn - True if the LCD backlight should be on, false if not - * @url http://www.espruino.com/Reference#l_Bangle_setBacklight + * Called with discovered services when discovery is finished + * @param {string} event - The event to listen to. + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_NRF_servicesDiscover */ - static setBacklight(isOn: ShortBoolean): void; + static on(event: "servicesDiscover", callback: () => void): void; /** - * This function can be used to turn Bangle.js's LCD off or on. - * This function resets the Bangle's 'activity timer' (like pressing a button or - * the screen would) so after a time period of inactivity set by - * `Bangle.setLCDTimeout` the screen will turn off. - * If you want to keep the screen on permanently (until apps are changed) you can - * do: - * ``` - * Bangle.setLCDTimeout(0); // turn off the timeout - * Bangle.setLCDPower(1); // keep screen on - * ``` - * **When on full, the LCD draws roughly 40mA.** You can adjust When brightness - * using `Bangle.setLCDBrightness`. - * - * @param {boolean} isOn - True if the LCD should be on, false if not - * @url http://www.espruino.com/Reference#l_Bangle_setLCDPower + * Called with discovered characteristics when discovery is finished + * @param {string} event - The event to listen to. + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_NRF_characteristicsDiscover */ - static setLCDPower(isOn: ShortBoolean): void; + static on(event: "characteristicsDiscover", callback: () => void): void; /** - * This function can be used to adjust the brightness of Bangle.js's display, and - * hence prolong its battery life. - * Due to hardware design constraints on Bangle.js 1, software PWM has to be used which means that - * the display may flicker slightly when Bluetooth is active and the display is not - * at full power. - * **Power consumption** - * * 0 = 7mA - * * 0.1 = 12mA - * * 0.2 = 18mA - * * 0.5 = 28mA - * * 0.9 = 40mA (switching overhead) - * * 1 = 40mA - * In 2v21 and earlier, this function would erroneously turn the LCD backlight on. 2v22 and later - * fix this, and if you want the backlight on your should use `Bangle.setLCDPowerBacklight()` - * - * @param {number} brightness - The brightness of Bangle.js's display - from 0(off) to 1(on full) - * @url http://www.espruino.com/Reference#l_Bangle_setLCDBrightness + * Called when an NFC field is detected + * @param {string} event - The event to listen to. + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_NRF_NFCon */ - static setLCDBrightness(brightness: number): void; + static on(event: "NFCon", callback: () => void): void; /** - * This function can be used to change the way graphics is handled on Bangle.js. - * Available options for `Bangle.setLCDMode` are: - * * `Bangle.setLCDMode()` or `Bangle.setLCDMode("direct")` (the default) - The - * drawable area is 240x240 16 bit. Unbuffered, so draw calls take effect - * immediately. Terminal and vertical scrolling work (horizontal scrolling - * doesn't). - * * `Bangle.setLCDMode("doublebuffered")` - The drawable area is 240x160 16 bit, - * terminal and scrolling will not work. `g.flip()` must be called for draw - * operations to take effect. - * * `Bangle.setLCDMode("120x120")` - The drawable area is 120x120 8 bit, - * `g.getPixel`, terminal, and full scrolling work. Uses an offscreen buffer - * stored on Bangle.js, `g.flip()` must be called for draw operations to take - * effect. - * * `Bangle.setLCDMode("80x80")` - The drawable area is 80x80 8 bit, `g.getPixel`, - * terminal, and full scrolling work. Uses an offscreen buffer stored on - * Bangle.js, `g.flip()` must be called for draw operations to take effect. - * You can also call `Bangle.setLCDMode()` to return to normal, unbuffered - * `"direct"` mode. - * - * @param {any} mode - The LCD mode (See below) - * @url http://www.espruino.com/Reference#l_Bangle_setLCDMode + * Called when an NFC field is no longer detected + * @param {string} event - The event to listen to. + * @param {() => void} callback - A function that is executed when the event occurs. + * @url http://www.espruino.com/Reference#l_NRF_NFCoff */ - static setLCDMode(mode?: LCDMode): void; + static on(event: "NFCoff", callback: () => void): void; /** - * The current LCD mode. - * See `Bangle.setLCDMode` for examples. - * @returns {any} The LCD mode as a String - * @url http://www.espruino.com/Reference#l_Bangle_getLCDMode + * When NFC is started with `NRF.nfcStart`, this is fired when NFC data is + * received. It doesn't get called if NFC is started with `NRF.nfcURL` or + * `NRF.nfcRaw` + * @param {string} event - The event to listen to. + * @param {(arr: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `arr` An ArrayBuffer containign the received data + * @url http://www.espruino.com/Reference#l_NRF_NFCrx */ - static getLCDMode(): LCDMode; + static on(event: "NFCrx", callback: (arr: any) => void): void; /** - * This can be used to move the displayed memory area up or down temporarily. It's - * used for displaying notifications while keeping the main display contents - * intact. - * - * @param {number} y - The amount of pixels to shift the LCD up or down - * @url http://www.espruino.com/Reference#l_Bangle_setLCDOffset + * If a device is connected to Espruino, disconnect from it. + * @url http://www.espruino.com/Reference#l_NRF_disconnect */ - static setLCDOffset(y: number): void; + static disconnect(): void; /** - * Overlay an image or graphics instance on top of the contents of the graphics buffer. - * This only works on Bangle.js 2 because Bangle.js 1 doesn't have an offscreen buffer accessible from the CPU. - * ``` - * // display an alarm clock icon on the screen - * var img = require("heatshrink").decompress(atob(`lss4UBvvv///ovBlMyqoADv/VAwlV//1qtfAQX/BINXDoPVq/9DAP - * /AYIKDrWq0oREAYPW1QAB1IWCBQXaBQWq04WCAQP6BQeqA4P1AQPq1WggEK1WrBAIkBBQJsCBYO///fBQOoPAcqCwP3BQnwgECCwP9 - * GwIKCngWC14sB7QKCh4CBCwN/64KDgfACwWn6vWGwYsBCwOputWJgYsCgGqytVBQYsCLYOlqtqwAsFEINVrR4BFgghBBQosDEINWIQ - * YsDEIQ3DFgYhCG4msSYeVFgnrFhMvOAgsEkE/FhEggYWCFgIhDkEACwQKBEIYKBCwSGFBQJxCQwYhBBQTKDqohCBQhCCEIJlDXwrKE - * BQoWHBQdaCwuqJoI4CCwgKECwJ9CJgIKDq+qBYUq1WtBQf+BYIAC3/VBQX/tQKDz/9BQY5BAAVV/4WCBQJcBKwVf+oHBv4wCAAYhB`)); - * Bangle.setLCDOverlay(img,66,66, {id: "myOverlay", remove: () => print("Removed")}); - * ``` - * Or use a `Graphics` instance: - * ``` - * var ovr = Graphics.createArrayBuffer(100,100,2,{msb:true}); - * ovr.transparent = 0; // (optional) set a transparent color - * ovr.palette = new Uint16Array([0,0,g.toColor("#F00"),g.toColor("#FFF")]); // (optional) set a color palette - * ovr.setColor(1).fillRect({x:0,y:0,w:99,h:99,r:8}); - * ovr.setColor(3).fillRect({x:2,y:2,w:95,h:95,r:7}); - * ovr.setColor(2).setFont("Vector:30").setFontAlign(0,0).drawString("Hi",50,50); - * Bangle.setLCDOverlay(ovr,38,38, {id: "myOverlay", remove: () => print("Removed")}); - * ``` - * To remove an overlay, simply call: - * ``` - * Bangle.setLCDOverlay(undefined, {id: "myOverlay"}); - * ``` - * Before 2v22 the `options` object isn't parsed, and as a result - * the remove callback won't be called, and `Bangle.setLCDOverlay(undefined)` will - * remove *any* active overlay. - * The `remove` callback is called when the current overlay is removed or replaced with - * another, but *not* if setLCDOverlay is called again with an image and the same ID. - * - * @param {any} img - An image, or undefined to clear - * @param {any} x - The X offset the graphics instance should be overlaid on the screen with - * @param {number} y - The Y offset the graphics instance should be overlaid on the screen with - * @param {any} options - [Optional] object `{remove:fn, id:"str"}` - * @url http://www.espruino.com/Reference#l_Bangle_setLCDOverlay + * Disable Bluetooth advertising and disconnect from any device that connected to + * Puck.js as a peripheral (this won't affect any devices that Puck.js initiated + * connections to). + * This makes Puck.js undiscoverable, so it can't be connected to. + * Use `NRF.wake()` to wake up and make Puck.js connectable again. + * @url http://www.espruino.com/Reference#l_NRF_sleep */ - static setLCDOverlay(img: any, x: number, y: number): void; - static setLCDOverlay(): void; - static setLCDOverlay(img: any, x: number, y: number, options: { id : string, remove: () => void }): void; - static setLCDOverlay(img: any, options: { id : string }): void; + static sleep(): void; /** - * This function can be used to turn Bangle.js's LCD power saving on or off. - * With power saving off, the display will remain in the state you set it with - * `Bangle.setLCDPower`. - * With power saving on, the display will turn on if a button is pressed, the watch - * is turned face up, or the screen is updated (see `Bangle.setOptions` for - * configuration). It'll turn off automatically after the given timeout. - * **Note:** This function also sets the Backlight and Lock timeout (the time at - * which the touchscreen/buttons start being ignored). To set both separately, use - * `Bangle.setOptions` - * - * @param {number} isOn - The timeout of the display in seconds, or `0`/`undefined` to turn power saving off. Default is 10 seconds. - * @url http://www.espruino.com/Reference#l_Bangle_setLCDTimeout + * Enable Bluetooth advertising (this is enabled by default), which allows other + * devices to discover and connect to Puck.js. + * Use `NRF.sleep()` to disable advertising. + * @url http://www.espruino.com/Reference#l_NRF_wake */ - static setLCDTimeout(isOn: number): void; + static wake(): void; /** - * Set how often the watch should poll its sensors (accel/hr/mag) for new data and kick the - * Watchdog timer. It isn't recommended that you make this interval much larger - * than 1000ms, but values up to 4000ms are allowed. - * Calling this will set `Bangle.setOptions({powerSave: false})` - disabling the - * dynamic adjustment of poll interval to save battery power when Bangle.js is - * stationary. + * Restart the Bluetooth softdevice (if there is currently a BLE connection, it + * will queue a restart to be done when the connection closes). + * You shouldn't need to call this function in normal usage. However, Nordic's BLE + * softdevice has some settings that cannot be reset. For example there are only a + * certain number of unique UUIDs. Once these are all used the only option is to + * restart the softdevice to clear them all out. + * + * @param {any} [callback] - [optional] A function to be called while the softdevice is uninitialised. Use with caution - accessing console/bluetooth will almost certainly result in a crash. + * @url http://www.espruino.com/Reference#l_NRF_restart + */ + static restart(callback?: any): void; + + /** + * Delete all data stored for all peers (bonding data used for secure connections). This cannot be done + * while a connection is active, so if there is a connection it will be postponed until everything is disconnected + * (which can be done by calling `NRF.disconnect()` and waiting). + * Booting your device while holding all buttons down together should also have the same effect. * - * @param {number} interval - Polling interval in milliseconds (Default is 80ms - 12.5Hz to match accelerometer) - * @url http://www.espruino.com/Reference#l_Bangle_setPollInterval + * @param {any} [callback] - [optional] A function to be called while the softdevice is uninitialised. Use with caution - accessing console/bluetooth will almost certainly result in a crash. + * @url http://www.espruino.com/Reference#l_NRF_eraseBonds */ - static setPollInterval(interval: number): void; + static eraseBonds(callback?: any): void; /** - * Set internal options used for gestures, etc... - * * `wakeOnBTN1` should the LCD turn on when BTN1 is pressed? default = `true` - * * `wakeOnBTN2` (Bangle.js 1) should the LCD turn on when BTN2 is pressed? - * default = `true` - * * `wakeOnBTN3` (Bangle.js 1) should the LCD turn on when BTN3 is pressed? - * default = `true` - * * `wakeOnFaceUp` should the LCD turn on when the watch is turned face up? - * default = `false` - * * `wakeOnTouch` should the LCD turn on when the touchscreen is pressed? On Bangle.js 1 this - * is a physical press on the touchscreen, on Bangle.js 2 we have to use the accelerometer as - * the touchscreen cannot be left powered without running the battery down. default = `false` - * * `wakeOnDoubleTap` (2v20 onwards) should the LCD turn on when the watch is double-tapped on the screen? - * This uses the accelerometer, not the touchscreen itself. default = `false` - * * `wakeOnTwist` should the LCD turn on when the watch is twisted? default = - * `true` - * * `twistThreshold` How much acceleration to register a twist of the watch strap? - * Can be negative for opposite direction. default = `800` - * * `twistMaxY` Maximum acceleration in Y to trigger a twist (low Y means watch is - * facing the right way up). default = `-800` - * * `twistTimeout` How little time (in ms) must a twist take from low->high - * acceleration? default = `1000` - * * `gestureStartThresh` how big a difference before we consider a gesture - * started? default = `sqr(800)` - * * `gestureEndThresh` how small a difference before we consider a gesture ended? - * default = `sqr(2000)` - * * `gestureInactiveCount` how many samples do we keep after a gesture has ended? - * default = `4` - * * `gestureMinLength` how many samples must a gesture have before we notify about - * it? default = `10` - * * `powerSave` after a minute of not being moved, Bangle.js will change the - * accelerometer poll interval down to 800ms (10x accelerometer samples). On - * movement it'll be raised to the default 80ms. If `Bangle.setPollInterval` is - * used this is disabled, and for it to work the poll interval must be either - * 80ms or 800ms. default = `true`. Setting `powerSave:false` will disable this - * automatic power saving, but will **not** change the poll interval from its - * current value. If you desire a specific interval (e.g. the default 80ms) you - * must set it manually with `Bangle.setPollInterval(80)` after setting - * `powerSave:false`. - * * `lowResistanceFix` (Bangle.js 2, 2v22+) In the very rare case that your watch button - * gets damaged such that it has a low resistance and always stays on, putting the watch - * into a boot loop, setting this flag may improve matters (by forcing the input low - * before reading and disabling the hardware watch on BTN1). - * * `lockTimeout` how many milliseconds before the screen locks - * * `lcdPowerTimeout` how many milliseconds before the screen turns off - * * `backlightTimeout` how many milliseconds before the screen's backlight turns - * off - * * `btnLoadTimeout` how many milliseconds does the home button have to be pressed - * for before the clock is reloaded? 1500ms default, or 0 means never. - * * `manualWatchdog` if set, this disables automatic kicking of the watchdog timer - * from the interrupt (when the button isn't held). You will then have to manually - * call `E.kickWatchdog()` from your code or the watch will reset after ~5 seconds. - * * `hrmPollInterval` set the requested poll interval (in milliseconds) for the - * heart rate monitor. On Bangle.js 2 only 10,20,40,80,160,200 ms are supported, - * and polling rate may not be exact. The algorithm's filtering is tuned for - * 20-40ms poll intervals, so higher/lower intervals may effect the reliability - * of the BPM reading. You must call this *before* `Bangle.setHRMPower` - calling - * when the HRM is already on will not affect the poll rate. - * * `hrmSportMode` - on the newest Bangle.js 2 builds with with the proprietary - * heart rate algorithm, this is the sport mode passed to the algorithm. See `libs/misc/vc31_binary/algo.h` - * for more info. -1 = auto, 0 = normal (default), 1 = running, 2 = ... - * * `hrmGreenAdjust` - (Bangle.js 2, 2v19+) if false (default is true) the green LED intensity won't be adjusted to get the HRM sensor 'exposure' correct. This is reset when the HRM is initialised with `Bangle.setHRMPower`. - * * `hrmWearDetect` - (Bangle.js 2, 2v19+) if false (default is true) HRM readings won't be turned off if the watch isn't on your arm (based on HRM proximity sensor). This is reset when the HRM is initialised with `Bangle.setHRMPower`. - * * `hrmPushEnv` - (Bangle.js 2, 2v19+) if true (default is false) HRM environment readings will be produced as `Bangle.on(`HRM-env`, ...)` events. This is reset when the HRM is initialised with `Bangle.setHRMPower`. - * * `seaLevelPressure` (Bangle.js 2) Normally 1013.25 millibars - this is used for - * calculating altitude with the pressure sensor - * * `lcdBufferPtr` (Bangle.js 2 2v21+) Return a pointer to the first pixel of the 3 bit graphics buffer used by Bangle.js for the screen (stride = 178 bytes) - * * `lcdDoubleRefresh` (Bangle.js 2 2v22+) If enabled, pulses EXTCOMIN twice per poll interval (avoids off-axis flicker) - * Where accelerations are used they are in internal units, where `8192 = 1g` + * Get this device's default or current Bluetooth MAC address. + * For Puck.js, the last 5 characters of this (e.g. `ee:ff`) are used in the + * device's advertised Bluetooth name. * - * @param {any} options - * @url http://www.espruino.com/Reference#l_Bangle_setOptions + * @param {boolean} current - If true, return the current address rather than the default + * @returns {any} MAC address - a string of the form 'aa:bb:cc:dd:ee:ff' + * @url http://www.espruino.com/Reference#l_NRF_getAddress */ - static setOptions(options: { [key in keyof BangleOptions]?: BangleOptions[key] }): void; + static getAddress(current: ShortBoolean): any; /** - * Return the current state of options as set by `Bangle.setOptions` - * @returns {any} The current state of all options - * @url http://www.espruino.com/Reference#l_Bangle_getOptions + * Set this device's default Bluetooth MAC address: + * ``` + * NRF.setAddress("ff:ee:dd:cc:bb:aa random"); + * ``` + * Addresses take the form: + * * `"ff:ee:dd:cc:bb:aa"` or `"ff:ee:dd:cc:bb:aa public"` for a public address + * * `"ff:ee:dd:cc:bb:aa random"` for a random static address (the default for + * Espruino) + * This may throw a `INVALID_BLE_ADDR` error if the upper two bits of the address + * don't match the address type. + * To change the address, Espruino must restart the softdevice. It will only do so + * when it is disconnected from other devices. + * + * @param {any} addr - The address to use (as a string) + * @url http://www.espruino.com/Reference#l_NRF_setAddress */ - static getOptions(): BangleOptions; + static setAddress(addr: any): void; /** - * Also see the `Bangle.lcdPower` event - * You can use `Bangle.setLCDPower` to turn on the LCD (on Bangle.js 2 the LCD is normally on, and draws very little power so can be left on). - * @returns {boolean} Is the display on or not? - * @url http://www.espruino.com/Reference#l_Bangle_isLCDOn + * Try to resolve a **bonded** peer's address from a random private resolvable address. If the peer + * is not bonded, there will be no IRK and `undefined` will be returned. + * A bunch of devices, especially smartphones, implement address randomisation and periodically change + * their bluetooth address to prevent being tracked. + * If such a device uses a "random private resolvable address", that address is generated + * with the help of an identity resolving key (IRK) that is exchanged during bonding. + * If we know the IRK of a device, we can check if an address was potentially generated by that device. + * The following will check an address against the IRKs of all bonded devices, + * and return the actual address of a bonded device if the given address was likely generated using that device's IRK: + * ``` + * NRF.on('connect',addr=> { + * // addr could be "aa:bb:cc:dd:ee:ff private-resolvable" + * if (addr.endsWith("private-resolvable")) { + * let resolved = NRF.resolveAddress(addr); + * // resolved is "aa:bb:cc:dd:ee:ff public" + * if (resolved) addr = resolved; + * } + * console.log("Device connected: ", addr); + * }) + * ``` + * You can get the current connection's address using `NRF.getSecurityStatus().connected_addr`, + * so can for instance do `NRF.resolveAddress(NRF.getSecurityStatus().connected_addr)`. + * + * @param {any} options - The address that should be resolved. + * @returns {any} The resolved address, or `undefined` if it couldn't be resolved. + * @url http://www.espruino.com/Reference#l_NRF_resolveAddress */ - static isLCDOn(): boolean; + static resolveAddress(options: any): any; /** - * Also see the `Bangle.backlight` event - * You can use `Bangle.setLCDPowerBacklight` to turn on the LCD backlight. - * @returns {boolean} Is the backlight on or not? - * @url http://www.espruino.com/Reference#l_Bangle_isBacklightOn + * Get the battery level in volts (the voltage that the NRF chip is running off + * of). + * This is the battery level of the device itself - it has nothing to with any + * device that might be connected. + * @returns {number} Battery level in volts + * @url http://www.espruino.com/Reference#l_NRF_getBattery */ - static isBacklightOn(): boolean; + static getBattery(): number; /** - * This function can be used to lock or unlock Bangle.js (e.g. whether buttons and - * touchscreen work or not) + * Change the data that Espruino advertises. + * Data can be of the form `{ UUID : data_as_byte_array }`. The UUID should be a + * [Bluetooth Service + * ID](https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx). + * For example to return battery level at 95%, do: + * ``` + * NRF.setAdvertising({ + * 0x180F : [95] // Service data 0x180F = 95 + * }); + * ``` + * Or you could report the current temperature: + * ``` + * setInterval(function() { + * NRF.setAdvertising({ + * 0x1809 : [Math.round(E.getTemperature())] + * }); + * }, 30000); + * ``` + * If you specify a value for the object key, Service Data is advertised. However + * if you specify `undefined`, the Service UUID is advertised: + * ``` + * NRF.setAdvertising({ + * 0x180D : undefined // Advertise service UUID 0x180D (HRM) + * }); + * ``` + * Service UUIDs can also be supplied in the second argument of `NRF.setServices`, + * but those go in the scan response packet. + * You can also supply the raw advertising data in an array. For example to + * advertise as an Eddystone beacon: + * ``` + * NRF.setAdvertising([0x03, // Length of Service List + * 0x03, // Param: Service List + * 0xAA, 0xFE, // Eddystone ID + * 0x13, // Length of Service Data + * 0x16, // Service Data + * 0xAA, 0xFE, // Eddystone ID + * 0x10, // Frame type: URL + * 0xF8, // Power + * 0x03, // https:// + * 'g','o','o','.','g','l','/','B','3','J','0','O','c'], + * {interval:100}); + * ``` + * (However for Eddystone we'd advise that you use the [Espruino Eddystone + * library](/Puck.js+Eddystone)) + * **Note:** When specifying data as an array, certain advertising options such as + * `discoverable` and `showName` won't have any effect. + * **Note:** The size of Bluetooth LE advertising packets is limited to 31 bytes. + * If you want to advertise more data, consider using an array for `data` (See + * below), or `NRF.setScanResponse`. + * You can even specify an array of arrays or objects, in which case each + * advertising packet will be used in turn - for instance to make your device + * advertise battery level and its name as well as both Eddystone and iBeacon : + * ``` + * NRF.setAdvertising([ + * {0x180F : [E.getBattery()]}, // normal advertising, with battery % + * require("ble_ibeacon").get(...), // iBeacon + * require("ble_eddystone").get(...), // eddystone + * ], {interval:300}); + * ``` + * `options` is an object, which can contain: + * ``` + * { + * name: "Hello" // The name of the device + * showName: true/false // include full name, or nothing + * discoverable: true/false // general discoverable, or limited - default is limited + * connectable: true/false // whether device is connectable - default is true + * scannable : true/false // whether device can be scanned for scan response packets - default is true + * whenConnected : true/false // keep advertising when connected (nRF52 only) + * // switches to advertising as non-connectable when it is connected + * interval: 600 // Advertising interval in msec, between 20 and 10000 (default is 375ms) + * manufacturer: 0x0590 // IF sending manufacturer data, this is the manufacturer ID + * manufacturerData: [...] // IF sending manufacturer data, this is an array of data + * phy: "1mbps/2mbps/coded" // (NRF52833/NRF52840 only) use the long-range coded phy for transmission (1mbps default) + * } + * ``` + * Setting `connectable` and `scannable` to false gives the lowest power + * consumption as the BLE radio doesn't have to listen after sending advertising. + * **NOTE:** Non-`connectable` advertising can't have an advertising interval less + * than 100ms according to the BLE spec. + * So for instance to set the name of Puck.js without advertising any other data + * you can just use the command: + * ``` + * NRF.setAdvertising({},{name:"Hello"}); + * ``` + * You can also specify 'manufacturer data', which is another form of advertising + * data. We've registered the Manufacturer ID 0x0590 (as Pur3 Ltd) for use with + * *Official Espruino devices* - use it to advertise whatever data you'd like, but + * we'd recommend using JSON. + * For example by not advertising a device name you can send up to 24 bytes of JSON + * on Espruino's manufacturer ID: + * ``` + * var data = {a:1,b:2}; + * NRF.setAdvertising({},{ + * showName:false, + * manufacturer:0x0590, + * manufacturerData:JSON.stringify(data) + * }); + * ``` + * If you're using [EspruinoHub](https://github.com/espruino/EspruinoHub) then it + * will automatically decode this into the following MQTT topics: + * * `/ble/advertise/ma:c_:_a:dd:re:ss/espruino` -> `{"a":10,"b":15}` + * * `/ble/advertise/ma:c_:_a:dd:re:ss/a` -> `1` + * * `/ble/advertise/ma:c_:_a:dd:re:ss/b` -> `2` + * Note that **you only have 24 characters available for JSON**, so try to use the + * shortest field names possible and avoid floating point values that can be very + * long when converted to a String. * - * @param {boolean} isLocked - `true` if the Bangle is locked (no user input allowed) - * @url http://www.espruino.com/Reference#l_Bangle_setLocked - */ - static setLocked(isLocked: ShortBoolean): void; - - /** - * Also see the `Bangle.lock` event - * @returns {boolean} Is the screen locked or not? - * @url http://www.espruino.com/Reference#l_Bangle_isLocked - */ - static isLocked(): boolean; - - /** - * @returns {boolean} Is the battery charging or not? - * @url http://www.espruino.com/Reference#l_Bangle_isCharging + * @param {any} data - The service data to advertise as an object - see below for more info + * @param {any} [options] - [optional] Object of options + * @url http://www.espruino.com/Reference#l_NRF_setAdvertising */ - static isCharging(): boolean; + static setAdvertising(data: any, options?: any): void; /** - * Writes a command directly to the ST7735 LCD controller + * This is just like `NRF.setAdvertising`, except instead of advertising the data, + * it returns the packet that would be advertised as an array. * - * @param {number} cmd - * @param {any} data - * @url http://www.espruino.com/Reference#l_Bangle_lcdWr + * @param {any} data - The data to advertise as an object + * @param {any} [options] - [optional] An object of options + * @returns {any} An array containing the advertising data + * @url http://www.espruino.com/Reference#l_NRF_getAdvertisingData */ - static lcdWr(cmd: number, data: any): void; + static getAdvertisingData(data: any, options?: any): any; /** - * Set the power to the Heart rate monitor - * When on, data is output via the `HRM` event on `Bangle`: + * The raw scan response data should be supplied as an array. For example to return + * "Sample" for the device name: * ``` - * Bangle.setHRMPower(true, "myapp"); - * Bangle.on('HRM',print); + * NRF.setScanResponse([0x07, // Length of Data + * 0x09, // Param: Complete Local Name + * 'S', 'a', 'm', 'p', 'l', 'e']); * ``` - * *When on, the Heart rate monitor draws roughly 5mA* + * **Note:** `NRF.setServices(..., {advertise:[ ... ]})` writes advertised services + * into the scan response - so you can't use both `advertise` and `NRF.setServices` + * or one will overwrite the other. * - * @param {boolean} isOn - True if the heart rate monitor should be on, false if not - * @param {any} appID - A string with the app's name in, used to ensure one app can't turn off something another app is using - * @returns {boolean} Is HRM on? - * @url http://www.espruino.com/Reference#l_Bangle_setHRMPower - */ - static setHRMPower(isOn: ShortBoolean, appID: string): boolean; - - /** - * Is the Heart rate monitor powered? - * Set power with `Bangle.setHRMPower(...);` - * @returns {boolean} Is HRM on? - * @url http://www.espruino.com/Reference#l_Bangle_isHRMOn + * @param {any} data - The data to for the scan response + * @url http://www.espruino.com/Reference#l_NRF_setScanResponse */ - static isHRMOn(): boolean; + static setScanResponse(data: any): void; /** - * Set the power to the GPS. - * When on, data is output via the `GPS` event on `Bangle`: + * Change the services and characteristics Espruino advertises. + * If you want to **change** the value of a characteristic, you need to use + * `NRF.updateServices()` instead + * To expose some information on Characteristic `ABCD` on service `BCDE` you could + * do: * ``` - * Bangle.setGPSPower(true, "myapp"); - * Bangle.on('GPS',print); + * NRF.setServices({ + * 0xBCDE : { + * 0xABCD : { + * value : "Hello", + * readable : true + * } + * } + * }); * ``` - * *When on, the GPS draws roughly 20mA* - * - * @param {boolean} isOn - True if the GPS should be on, false if not - * @param {any} appID - A string with the app's name in, used to ensure one app can't turn off something another app is using - * @returns {boolean} Is the GPS on? - * @url http://www.espruino.com/Reference#l_Bangle_setGPSPower - */ - static setGPSPower(isOn: ShortBoolean, appID: string): boolean; - - /** - * Is the GPS powered? - * Set power with `Bangle.setGPSPower(...);` - * @returns {boolean} Is the GPS on? - * @url http://www.espruino.com/Reference#l_Bangle_isGPSOn - */ - static isGPSOn(): boolean; - - /** - * Get the last available GPS fix info (or `undefined` if GPS is off). - * The fix info received is the same as you'd get from the `Bangle.GPS` event. - * @returns {any} A GPS fix object with `{lat,lon,...}` - * @url http://www.espruino.com/Reference#l_Bangle_getGPSFix - */ - static getGPSFix(): GPSFix; - - /** - * Set the power to the Compass - * When on, data is output via the `mag` event on `Bangle`: + * Or to allow the 3 LEDs to be controlled by writing numbers 0 to 7 to a + * characteristic, you can do the following. `evt.data` is an ArrayBuffer. * ``` - * Bangle.setCompassPower(true, "myapp"); - * Bangle.on('mag',print); + * NRF.setServices({ + * 0xBCDE : { + * 0xABCD : { + * writable : true, + * onWrite : function(evt) { + * digitalWrite([LED3,LED2,LED1], evt.data[0]); + * } + * } + * } + * }); * ``` - * *When on, the compass draws roughly 2mA* - * - * @param {boolean} isOn - True if the Compass should be on, false if not - * @param {any} appID - A string with the app's name in, used to ensure one app can't turn off something another app is using - * @returns {boolean} Is the Compass on? - * @url http://www.espruino.com/Reference#l_Bangle_setCompassPower - */ - static setCompassPower(isOn: ShortBoolean, appID: string): boolean; - - /** - * Is the compass powered? - * Set power with `Bangle.setCompassPower(...);` - * @returns {boolean} Is the Compass on? - * @url http://www.espruino.com/Reference#l_Bangle_isCompassOn - */ - static isCompassOn(): boolean; - - /** - * Resets the compass minimum/maximum values. Can be used if the compass isn't - * providing a reliable heading any more. - * - * @url http://www.espruino.com/Reference#l_Bangle_resetCompass - */ - static resetCompass(): void; - - /** - * Set the power to the barometer IC. Once enabled, `Bangle.pressure` events are - * fired each time a new barometer reading is available. - * When on, the barometer draws roughly 50uA - * - * @param {boolean} isOn - True if the barometer IC should be on, false if not - * @param {any} appID - A string with the app's name in, used to ensure one app can't turn off something another app is using - * @returns {boolean} Is the Barometer on? - * @url http://www.espruino.com/Reference#l_Bangle_setBarometerPower - */ - static setBarometerPower(isOn: ShortBoolean, appID: string): boolean; - - /** - * Is the Barometer powered? - * Set power with `Bangle.setBarometerPower(...);` - * @returns {boolean} Is the Barometer on? - * @url http://www.espruino.com/Reference#l_Bangle_isBarometerOn - */ - static isBarometerOn(): boolean; - - /** - * Returns the current amount of steps recorded by the step counter - * @returns {number} The number of steps recorded by the step counter - * @url http://www.espruino.com/Reference#l_Bangle_getStepCount - */ - static getStepCount(): number; - - /** - * Sets the current value of the step counter + * You can supply many different options: + * ``` + * NRF.setServices({ + * 0xBCDE : { + * 0xABCD : { + * value : "Hello", // optional + * maxLen : 5, // optional (otherwise is length of initial value) + * broadcast : false, // optional, default is false + * readable : true, // optional, default is false + * writable : true, // optional, default is false + * notify : true, // optional, default is false + * indicate : true, // optional, default is false + * description: "My Characteristic", // optional, default is null, + * security: { // optional - see NRF.setSecurity + * read: { // optional + * encrypted: false, // optional, default is false + * mitm: false, // optional, default is false + * lesc: false, // optional, default is false + * signed: false // optional, default is false + * }, + * write: { // optional + * encrypted: true, // optional, default is false + * mitm: false, // optional, default is false + * lesc: false, // optional, default is false + * signed: false // optional, default is false + * } + * }, + * onWrite : function(evt) { // optional + * console.log("Got ", evt.data); // an ArrayBuffer + * }, + * onWriteDesc : function(evt) { // optional - called when the 'cccd' descriptor is written + * // for example this is called when notifications are requested by the client: + * console.log("Notifications enabled = ", evt.data[0]&1); + * } + * } + * // more characteristics allowed + * } + * // more services allowed + * }); + * ``` + * **Note:** UUIDs can be integers between `0` and `0xFFFF`, strings of the form + * `"ABCD"`, or strings of the form `"ABCDABCD-ABCD-ABCD-ABCD-ABCDABCDABCD"` + * `options` can be of the form: + * ``` + * NRF.setServices(undefined, { + * hid : new Uint8Array(...), // optional, default is undefined. Enable BLE HID support + * uart : true, // optional, default is true. Enable BLE UART support + * advertise: [ '180D' ] // optional, list of service UUIDs to advertise + * ancs : true, // optional, Bangle.js-only, enable Apple ANCS support for notifications (see `NRF.ancs*`) + * ams : true // optional, Bangle.js-only, enable Apple AMS support for media control (see `NRF.ams*`) + * cts : true // optional, Bangle.js-only, enable Apple Current Time Service support (see `NRF.ctsGetTime`) + * }); + * ``` + * To enable BLE HID, you must set `hid` to an array which is the BLE report + * descriptor. The easiest way to do this is to use the `ble_hid_controls` or + * `ble_hid_keyboard` modules. + * **Note:** Just creating a service doesn't mean that the service will be + * advertised. It will only be available after a device connects. To advertise, + * specify the UUIDs you wish to advertise in the `advertise` field of the second + * `options` argument. For example this will create and advertise a heart rate + * service: + * ``` + * NRF.setServices({ + * 0x180D: { // heart_rate + * 0x2A37: { // heart_rate_measurement + * notify: true, + * value : [0x06, heartrate], + * } + * } + * }, { advertise: [ '180D' ] }); + * ``` + * You may specify 128 bit UUIDs to advertise, however you may get a `DATA_SIZE` + * exception because there is insufficient space in the Bluetooth LE advertising + * packet for the 128 bit UART UUID as well as the UUID you specified. In this case + * you can add `uart:false` after the `advertise` element to disable the UART, + * however you then be unable to connect to Puck.js's console via Bluetooth. + * If you absolutely require two or more 128 bit UUIDs then you will have to + * specify your own raw advertising data packets with `NRF.setAdvertising` + * **Note:** The services on Espruino can only be modified when there is no device + * connected to it as it requires a restart of the Bluetooth stack. **iOS devices + * will 'cache' the list of services** so apps like NRF Connect may incorrectly + * display the old services even after you have modified them. To fix this, disable + * and re-enable Bluetooth on your iOS device, or use an Android device to run NRF + * Connect. + * **Note:** Not all combinations of security configuration values are valid, the + * valid combinations are: encrypted, encrypted + mitm, lesc, signed, signed + + * mitm. See `NRF.setSecurity` for more information. * - * @param {number} count - The value with which to reload the step counter - * @url http://www.espruino.com/Reference#l_Bangle_setStepCount - */ - static setStepCount(count: number): void; - - /** - * Get the most recent Magnetometer/Compass reading. Data is in the same format as - * the `Bangle.on('mag',` event. - * Returns an `{x,y,z,dx,dy,dz,heading}` object - * * `x/y/z` raw x,y,z magnetometer readings - * * `dx/dy/dz` readings based on calibration since magnetometer turned on - * * `heading` in degrees based on calibrated readings (will be NaN if magnetometer - * hasn't been rotated around 360 degrees). - * **Note:** In 2v15 firmware and earlier the heading is inverted (360-heading). There's - * a fix in the bootloader which will apply a fix for those headings, but old apps may - * still expect an inverted value. - * To get this event you must turn the compass on with `Bangle.setCompassPower(1)`. - * @returns {any} An object containing magnetometer readings (as below) - * @url http://www.espruino.com/Reference#l_Bangle_getCompass - */ - static getCompass(): CompassData; - - /** - * Get the most recent accelerometer reading. Data is in the same format as the - * `Bangle.on('accel',` event. - * * `x` is X axis (left-right) in `g` - * * `y` is Y axis (up-down) in `g` - * * `z` is Z axis (in-out) in `g` - * * `diff` is difference between this and the last reading in `g` (calculated by - * comparing vectors, not magnitudes) - * * `td` is the elapsed - * * `mag` is the magnitude of the acceleration in `g` - * @returns {any} An object containing accelerometer readings (as below) - * @url http://www.espruino.com/Reference#l_Bangle_getAccel + * @param {any} data - The service (and characteristics) to advertise + * @param {any} [options] - [optional] Object containing options + * @url http://www.espruino.com/Reference#l_NRF_setServices */ - static getAccel(): AccelData & { td: number }; + static setServices(data: { [key: number]: { [key: number]: { value?: string, maxLen?: number, broadcast?: boolean, readable?: boolean, writable?: boolean, notify?: boolean, indicate?: boolean, description?: string, security?: { read?: { encrypted?: boolean, mitm?: boolean, lesc?: boolean, signed?: boolean }, write?: { encrypted?: boolean, mitm?: boolean, lesc?: boolean, signed?: boolean } }, onWrite?: (evt: { data: ArrayBuffer }) => void } } }, options?: any): void; /** - * `range` is one of: - * * `undefined` or `'10min'` - health data so far in this 10 minute block (eg. 9:00.00 - 9:09.59) - * * `'last'` - health data during the last 10 minute block - * * `'day'` - the health data so far for the day - * `getHealthStatus` returns an object containing: - * * `movement` is the 32 bit sum of all `acc.diff` readings since power on (and - * rolls over). It is the difference in accelerometer values as `g*8192` - * * `steps` is the number of steps during this period - * * `bpm` the best BPM reading from HRM sensor during this period - * * `bpmConfidence` best BPM confidence (0-100%) during this period + * Update values for the services and characteristics Espruino advertises. Only + * services and characteristics previously declared using `NRF.setServices` are + * affected. + * To update the '0xABCD' characteristic in the '0xBCDE' service: + * ``` + * NRF.updateServices({ + * 0xBCDE : { + * 0xABCD : { + * value : "World" + * } + * } + * }); + * ``` + * You can also use 128 bit UUIDs, for example + * `"b7920001-3c1b-4b40-869f-3c0db9be80c6"`. + * To define a service and characteristic and then notify connected clients of a + * change to it when a button is pressed: + * ``` + * NRF.setServices({ + * 0xBCDE : { + * 0xABCD : { + * value : "Hello", + * maxLen : 20, + * notify: true + * } + * } + * }); + * setWatch(function() { + * NRF.updateServices({ + * 0xBCDE : { + * 0xABCD : { + * value : "World!", + * notify: true + * } + * } + * }); + * }, BTN, { repeat:true, edge:"rising", debounce: 50 }); + * ``` + * This only works if the characteristic was created with `notify: true` using + * `NRF.setServices`, otherwise the characteristic will be updated but no + * notification will be sent. + * Also note that `maxLen` was specified. If it wasn't then the maximum length of + * the characteristic would have been 5 - the length of `"Hello"`. + * To indicate (i.e. notify with ACK) connected clients of a change to the '0xABCD' + * characteristic in the '0xBCDE' service: + * ``` + * NRF.updateServices({ + * 0xBCDE : { + * 0xABCD : { + * value : "World", + * indicate: true + * } + * } + * }); + * ``` + * This only works if the characteristic was created with `indicate: true` using + * `NRF.setServices`, otherwise the characteristic will be updated but no + * notification will be sent. + * **Note:** See `NRF.setServices` for more information * - * @param {any} range - What time period to return data for, see below: - * @returns {any} Returns an object containing various health info - * @url http://www.espruino.com/Reference#l_Bangle_getHealthStatus + * @param {any} data - The service (and characteristics) to update + * @url http://www.espruino.com/Reference#l_NRF_updateServices */ - static getHealthStatus(range?: "current" | "last" | "day"): HealthStatus; + static updateServices(data: any): void; /** - * Reads debug info. Exposes the current values of `accHistoryIdx`, `accGestureCount`, `accIdleCount`, `pollInterval` and others. - * Please see the declaration of this function for more information (click the `==>` link above [this description](http://www.espruino.com/Reference#l_Bangle_dbg)) - * @returns {any} - * @url http://www.espruino.com/Reference#l_Bangle_dbg + * Start/stop listening for BLE advertising packets within range. Returns a + * `BluetoothDevice` for each advertising packet. **By default this is not an active + * scan, so Scan Response advertising data is not included (see below)** + * ``` + * // Start scanning + * packets=10; + * NRF.setScan(function(d) { + * packets--; + * if (packets<=0) + * NRF.setScan(); // stop scanning + * else + * console.log(d); // print packet info + * }); + * ``` + * Each `BluetoothDevice` will look a bit like: + * ``` + * BluetoothDevice { + * "id": "aa:bb:cc:dd:ee:ff", // address + * "rssi": -89, // signal strength + * "services": [ "128bit-uuid", ... ], // zero or more service UUIDs + * "data": new Uint8Array([ ... ]).buffer, // ArrayBuffer of returned data + * "serviceData" : { "0123" : [ 1 ] }, // if service data is in 'data', it's extracted here + * "manufacturer" : 0x1234, // if manufacturer data is in 'data', the 16 bit manufacturer ID is extracted here + * "manufacturerData" : new Uint8Array([...]).buffer, // if manufacturer data is in 'data', the data is extracted here as an ArrayBuffer + * "name": "DeviceName" // the advertised device name + * } + * ``` + * You can also supply a set of filters (as described in `NRF.requestDevice`) as a + * second argument, which will allow you to filter the devices you get a callback + * for. This helps to cut down on the time spent processing JavaScript code in + * areas with a lot of Bluetooth advertisements. For example to find only devices + * with the manufacturer data `0x0590` (Espruino's ID) you could do: + * ``` + * NRF.setScan(function(d) { + * console.log(d.manufacturerData); + * }, { filters: [{ manufacturerData:{0x0590:{}} }] }); + * ``` + * You can also specify `active:true` in the second argument to perform active + * scanning (this requests scan response packets) from any devices it finds. + * **Note:** Using a filter in `setScan` filters each advertising packet + * individually. As a result, if you filter based on a service UUID and a device + * advertises with multiple packets (or a scan response when `active:true`) only + * the packets matching the filter are returned. To aggregate multiple packets you + * can use `NRF.findDevices`. + * **Note:** BLE advertising packets can arrive quickly - faster than you'll be + * able to print them to the console. It's best only to print a few, or to use a + * function like `NRF.findDevices(..)` which will collate a list of available + * devices. + * **Note:** Using setScan turns the radio's receive mode on constantly. This can + * draw a *lot* of power (12mA or so), so you should use it sparingly or you can + * run your battery down quickly. + * + * @param {any} callback - The callback to call with received advertising packets, or undefined to stop + * @param {any} [options] - [optional] An object `{filters: ...}` (as would be passed to `NRF.requestDevice`) to filter devices by + * @url http://www.espruino.com/Reference#l_NRF_setScan */ - static dbg(): any; + static setScan(callback: any, options?: any): void; /** - * Writes a register on the touch controller + * This function can be used to quickly filter through Bluetooth devices. + * For instance if you wish to scan for multiple different types of device at the + * same time then you could use `NRF.findDevices` with all the filters you're + * interested in. When scanning is finished you can then use `NRF.filterDevices` to + * pick out just the devices of interest. + * ``` + * // the two types of device we're interested in + * var filter1 = [{serviceData:{"fe95":{}}}]; + * var filter2 = [{namePrefix:"Pixl.js"}]; + * // the following filter will return both types of device + * var allFilters = filter1.concat(filter2); + * // now scan for both types of device, and filter them out afterwards + * NRF.findDevices(function(devices) { + * var devices1 = NRF.filterDevices(devices, filter1); + * var devices2 = NRF.filterDevices(devices, filter2); + * // ... + * }, {filters : allFilters}); + * ``` * - * @param {number} reg - * @param {number} data - * @url http://www.espruino.com/Reference#l_Bangle_touchWr + * @param {any} devices - An array of `BluetoothDevice` objects, from `NRF.findDevices` or similar + * @param {any} filters - A list of filters (as would be passed to `NRF.requestDevice`) to filter devices by + * @returns {any} An array of `BluetoothDevice` objects that match the given filters + * @url http://www.espruino.com/Reference#l_NRF_filterDevices */ - static touchWr(reg: number, data: number): void; + static filterDevices(devices: any, filters: any): any; /** - * Reads a register from the touch controller - * **Note:** On Espruino 2v06 and before this function only returns a number (`cnt` - * is ignored). + * Utility function to return a list of BLE devices detected in range. Behind the + * scenes, this uses `NRF.setScan(...)` and collates the results. + * ``` + * NRF.findDevices(function(devices) { + * console.log(devices); + * }, 1000); + * ``` + * prints something like: + * ``` + * [ + * BluetoothDevice { + * "id" : "e7:e0:57:ad:36:a2 random", + * "rssi": -45, + * "services": [ "4567" ], + * "serviceData" : { "0123" : [ 1 ] }, + * "manufacturer" : 1424, + * "manufacturerData" : new Uint8Array([ ... ]).buffer, + * "data": new ArrayBuffer([ ... ]).buffer, + * "name": "Puck.js 36a2" + * }, + * BluetoothDevice { + * "id": "c0:52:3f:50:42:c9 random", + * "rssi": -65, + * "data": new ArrayBuffer([ ... ]), + * "name": "Puck.js 8f57" + * } + * ] + * ``` + * For more information on the structure returned, see `NRF.setScan`. + * If you want to scan only for specific devices you can replace the timeout with + * an object of the form `{filters: ..., timeout : ..., active: bool}` using the + * filters described in `NRF.requestDevice`. For example to search for devices with + * Espruino's `manufacturerData`: + * ``` + * NRF.findDevices(function(devices) { + * ... + * }, {timeout : 2000, filters : [{ manufacturerData:{0x0590:{}} }] }); + * ``` + * You could then use + * [`BluetoothDevice.gatt.connect(...)`](/Reference#l_BluetoothRemoteGATTServer_connect) + * on the device returned to make a connection. + * You can also use [`NRF.connect(...)`](/Reference#l_NRF_connect) on just the `id` + * string returned, which may be useful if you always want to connect to a specific + * device. + * **Note:** Using findDevices turns the radio's receive mode on for 2000ms (or + * however long you specify). This can draw a *lot* of power (12mA or so), so you + * should use it sparingly or you can run your battery down quickly. + * **Note:** The 'data' field contains the data of *the last packet received*. + * There may have been more packets. To get data for each packet individually use + * `NRF.setScan` instead. * - * @param {number} reg - Register number to read - * @param {number} cnt - If specified, returns an array of the given length (max 128). If not (or 0) it returns a number - * @returns {any} - * @url http://www.espruino.com/Reference#l_Bangle_touchRd + * @param {any} callback - The callback to call with received advertising packets (as `BluetoothDevice`), or undefined to stop + * @param {any} [options] - [optional] A time in milliseconds to scan for (defaults to 2000), Or an optional object `{filters: ..., timeout : ..., active: bool}` (as would be passed to `NRF.requestDevice`) to filter devices by + * @url http://www.espruino.com/Reference#l_NRF_findDevices */ - static touchRd(reg: number, cnt?: 0): number; - static touchRd(reg: number, cnt: number): number[]; + static findDevices(callback: (devices: BluetoothDevice[]) => void, options?: number | { filters?: NRFFilters[], timeout?: number, active?: boolean }): void; /** - * Writes a register on the accelerometer + * Start/stop listening for RSSI values on the currently active connection (where + * This device is a peripheral and is being connected to by a 'central' device) + * ``` + * // Start scanning + * NRF.setRSSIHandler(function(rssi) { + * console.log(rssi); // prints -85 (or similar) + * }); + * // Stop Scanning + * NRF.setRSSIHandler(); + * ``` + * RSSI is the 'Received Signal Strength Indication' in dBm * - * @param {number} reg - Register number to write - * @param {number} data - An integer value to write to the register - * @url http://www.espruino.com/Reference#l_Bangle_accelWr + * @param {any} callback - The callback to call with the RSSI value, or undefined to stop + * @url http://www.espruino.com/Reference#l_NRF_setRSSIHandler */ - static accelWr(reg: number, data: number): void; + static setRSSIHandler(callback: any): void; /** - * Reads a register from the accelerometer - * **Note:** On Espruino 2v06 and before this function only returns a number (`cnt` - * is ignored). + * Set the BLE radio transmit power. The default TX power is 0 dBm, and * - * @param {number} reg - * @param {number} cnt - If specified, returns an array of the given length (max 128). If not (or 0) it returns a number - * @returns {any} - * @url http://www.espruino.com/Reference#l_Bangle_accelRd + * @param {number} power - Transmit power. Accepted values are -40(nRF52 only), -30(nRF51 only), -20, -16, -12, -8, -4, 0, and 4 dBm. On nRF52840 (eg Bangle.js 2) 5/6/7/8 dBm are available too. Others will give an error code. + * @url http://www.espruino.com/Reference#l_NRF_setTxPower */ - static accelRd(reg: number, cnt?: 0): number; - static accelRd(reg: number, cnt: number): number[]; + static setTxPower(power: number): void; /** - * Writes a register on the barometer IC + * **THIS IS DEPRECATED** - please use `NRF.setConnectionInterval` for peripheral + * and `NRF.connect(address, options)`/`BluetoothRemoteGATTServer.connect(options)` + * for central connections. + * This sets the connection parameters - these affect the transfer speed and power + * usage when the device is connected. + * * When not low power, the connection interval is between 7.5 and 20ms + * * When low power, the connection interval is between 500 and 1000ms + * When low power connection is enabled, transfers of data over Bluetooth will be + * very slow, however power usage while connected will be drastically decreased. + * This will only take effect after the connection is disconnected and + * re-established. * - * @param {number} reg - * @param {number} data - * @url http://www.espruino.com/Reference#l_Bangle_barometerWr + * @param {boolean} lowPower - Whether the connection is low power or not + * @url http://www.espruino.com/Reference#l_NRF_setLowPowerConnection */ - static barometerWr(reg: number, data: number): void; + static setLowPowerConnection(lowPower: ShortBoolean): void; /** - * Reads a register from the barometer IC + * Enables NFC and starts advertising the given URL. For example: + * ``` + * NRF.nfcURL("http://espruino.com"); + * ``` * - * @param {number} reg - * @param {number} cnt - If specified, returns an array of the given length (max 128). If not (or 0) it returns a number - * @returns {any} - * @url http://www.espruino.com/Reference#l_Bangle_barometerRd + * @param {any} url - The URL string to expose on NFC, or `undefined` to disable NFC + * @url http://www.espruino.com/Reference#l_NRF_nfcURL */ - static barometerRd(reg: number, cnt?: 0): number; - static barometerRd(reg: number, cnt: number): number[]; + static nfcURL(url: any): void; /** - * Writes a register on the Magnetometer/Compass + * Enables NFC and with an out of band 16 byte pairing key. + * For example the following will enable out of band pairing on BLE such that the + * device will pair when you tap the phone against it: + * ``` + * var bleKey = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00]; + * NRF.on('security',s=>print("security",JSON.stringify(s))); + * NRF.nfcPair(bleKey); + * NRF.setSecurity({oob:bleKey, mitm:true}); + * ``` * - * @param {number} reg - * @param {number} data - * @url http://www.espruino.com/Reference#l_Bangle_compassWr + * @param {any} key - 16 byte out of band key + * @url http://www.espruino.com/Reference#l_NRF_nfcPair */ - static compassWr(reg: number, data: number): void; + static nfcPair(key: any): void; /** - * Read a register on the Magnetometer/Compass + * Enables NFC with a record that will launch the given android app. + * For example: + * ``` + * NRF.nfcAndroidApp("no.nordicsemi.android.nrftoolbox") + * ``` * - * @param {number} reg - * @param {number} cnt - If specified, returns an array of the given length (max 128). If not (or 0) it returns a number - * @returns {any} - * @url http://www.espruino.com/Reference#l_Bangle_compassRd + * @param {any} app - The unique identifier of the given Android App + * @url http://www.espruino.com/Reference#l_NRF_nfcAndroidApp */ - static compassRd(reg: number, cnt?: 0): number; - static compassRd(reg: number, cnt: number): number[]; + static nfcAndroidApp(app: any): void; /** - * Writes a register on the Heart rate monitor + * Enables NFC and starts advertising with Raw data. For example: + * ``` + * NRF.nfcRaw(new Uint8Array([193, 1, 0, 0, 0, 13, 85, 3, 101, 115, 112, 114, 117, 105, 110, 111, 46, 99, 111, 109])); + * // same as NRF.nfcURL("http://espruino.com"); + * ``` * - * @param {number} reg - * @param {number} data - * @url http://www.espruino.com/Reference#l_Bangle_hrmWr + * @param {any} payload - The NFC NDEF message to deliver to the reader + * @url http://www.espruino.com/Reference#l_NRF_nfcRaw */ - static hrmWr(reg: number, data: number): void; + static nfcRaw(payload: any): void; /** - * Read a register on the Heart rate monitor + * **Advanced NFC Functionality.** If you just want to advertise a URL, use + * `NRF.nfcURL` instead. + * Enables NFC and starts advertising. `NFCrx` events will be fired when data is + * received. + * ``` + * NRF.nfcStart(); + * ``` * - * @param {number} reg - * @param {number} cnt - If specified, returns an array of the given length (max 128). If not (or 0) it returns a number - * @returns {any} - * @url http://www.espruino.com/Reference#l_Bangle_hrmRd + * @param {any} payload - Optional 7 byte UID + * @returns {any} Internal tag memory (first 10 bytes of tag data) + * @url http://www.espruino.com/Reference#l_NRF_nfcStart */ - static hrmRd(reg: number, cnt?: 0): number; - static hrmRd(reg: number, cnt: number): number[]; + static nfcStart(payload: any): any; /** - * Changes a pin state on the IO expander + * **Advanced NFC Functionality.** If you just want to advertise a URL, use + * `NRF.nfcURL` instead. + * Disables NFC. + * ``` + * NRF.nfcStop(); + * ``` * - * @param {number} mask - * @param {number} isOn - * @url http://www.espruino.com/Reference#l_Bangle_ioWr + * @url http://www.espruino.com/Reference#l_NRF_nfcStop */ - static ioWr(mask: number, isOn: number): void; + static nfcStop(): void; /** - * Read temperature, pressure and altitude data. A promise is returned which will - * be resolved with `{temperature, pressure, altitude}`. - * If the Barometer has been turned on with `Bangle.setBarometerPower` then this - * will return with the *next* reading as of 2v21 (or the existing reading on 2v20 or earlier). If the Barometer is off, - * conversions take between 500-750ms. - * Altitude assumes a sea-level pressure of 1013.25 hPa - * If there's no pressure device (for example, the emulator), - * this returns `undefined`, rather than a Promise. + * **Advanced NFC Functionality.** If you just want to advertise a URL, use + * `NRF.nfcURL` instead. + * Acknowledges the last frame and optionally transmits a response. If payload is + * an array, then a array.length byte nfc frame is sent. If payload is a int, then + * a 4bit ACK/NACK is sent. **Note:** ```nfcSend``` should always be called after + * an ```NFCrx``` event. * ``` - * Bangle.getPressure().then(d=>{ - * console.log(d); - * // {temperature, pressure, altitude} - * }); + * NRF.nfcSend(new Uint8Array([0x01, 0x02, ...])); + * // or + * NRF.nfcSend(0x0A); + * // or + * NRF.nfcSend(); * ``` - * @returns {any} A promise that will be resolved with `{temperature, pressure, altitude}` - * @url http://www.espruino.com/Reference#l_Bangle_getPressure - */ - static getPressure(): Promise | undefined; - - /** - * Perform a Spherical [Web Mercator - * projection](https://en.wikipedia.org/wiki/Web_Mercator_projection) of latitude - * and longitude into `x` and `y` coordinates, which are roughly equivalent to - * meters from `{lat:0,lon:0}`. - * This is the formula used for most online mapping and is a good way to compare - * GPS coordinates to work out the distance between them. * - * @param {any} latlong - `{lat:..., lon:...}` - * @returns {any} {x:..., y:...} - * @url http://www.espruino.com/Reference#l_Bangle_project + * @param {any} payload - Optional tx data + * @url http://www.espruino.com/Reference#l_NRF_nfcSend */ - static project(latlong: { lat: number, lon: number }): { x: number, y: number }; + static nfcSend(payload: any): void; /** - * Use the piezo speaker to Beep for a certain time period and frequency + * Send a USB HID report. HID must first be enabled with `NRF.setServices({}, {hid: + * hid_report})` * - * @param {number} [time] - [optional] Time in ms (default 200) - * @param {number} [freq] - [optional] Frequency in hz (default 4000) - * @returns {any} A promise, completed when beep is finished - * @url http://www.espruino.com/Reference#l_Bangle_beep + * @param {any} data - Input report data as an array + * @param {any} callback - A callback function to be called when the data is sent + * @url http://www.espruino.com/Reference#l_NRF_sendHIDReport */ - static beep(time?: number, freq?: number): Promise; + static sendHIDReport(data: number[], callback?: () => void): void /** - * Use the vibration motor to buzz for a certain time period + * Check if Apple Notification Center Service (ANCS) is currently active on the BLE + * connection * - * @param {number} [time] - [optional] Time in ms (default 200) - * @param {number} [strength] - [optional] Power of vibration from 0 to 1 (Default 1) - * @returns {any} A promise, completed when vibration is finished - * @url http://www.espruino.com/Reference#l_Bangle_buzz - */ - static buzz(time?: number, strength?: number): Promise; - - /** - * Turn Bangle.js off. It can only be woken by pressing BTN1. - * @url http://www.espruino.com/Reference#l_Bangle_off - */ - static off(): void; - - /** - * Turn Bangle.js (mostly) off, but keep the CPU in sleep mode until BTN1 is - * pressed to preserve the RTC (current time). - * @url http://www.espruino.com/Reference#l_Bangle_softOff + * @returns {boolean} True if Apple Notification Center Service (ANCS) has been initialised and is active + * @url http://www.espruino.com/Reference#l_NRF_ancsIsActive */ - static softOff(): void; + static ancsIsActive(): boolean; /** - * * On platforms with an LCD of >=8bpp this is 222 x 104 x 2 bits - * * Otherwise it's 119 x 56 x 1 bits - * @returns {any} An image to be used with `g.drawImage` (as a String) - * @url http://www.espruino.com/Reference#l_Bangle_getLogo + * Send an ANCS action for a specific Notification UID. Corresponds to + * posaction/negaction in the 'ANCS' event that was received + * + * @param {number} uid - The UID of the notification to respond to + * @param {boolean} positive - `true` for positive action, `false` for negative + * @url http://www.espruino.com/Reference#l_NRF_ancsAction */ - static getLogo(): string; + static ancsAction(uid: number, positive: ShortBoolean): void; /** - * Load all widgets from flash Storage. Call this once at the beginning of your - * application if you want any on-screen widgets to be loaded. - * They will be loaded into a global `WIDGETS` array, and can be rendered with - * `Bangle.drawWidgets`. - * @url http://www.espruino.com/Reference#l_Bangle_loadWidgets + * Get ANCS info for a notification event received via `E.ANCS`, e.g.: + * ``` + * E.on('ANCS', event => { + * NRF.ancsGetNotificationInfo( event.uid ).then(a=>print("Notify",E.toJS(a))); + * }); + * ``` + * Returns: + * ``` + * { + * "uid" : integer, + * "appId": string, + * "title": string, + * "subtitle": string, + * "message": string, + * "messageSize": string, + * "date": string, + * "posAction": string, + * "negAction": string + * } + * ``` + * + * @param {number} uid - The UID of the notification to get information for + * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete + * @url http://www.espruino.com/Reference#l_NRF_ancsGetNotificationInfo */ - static loadWidgets(): void; + static ancsGetNotificationInfo(uid: number): Promise; /** - * Draw any onscreen widgets that were loaded with `Bangle.loadWidgets()`. - * Widgets should redraw themselves when something changes - you'll only need to - * call drawWidgets if you decide to clear the entire screen with `g.clear()`. - * @url http://www.espruino.com/Reference#l_Bangle_drawWidgets + * Get ANCS info for an app (app id is available via `NRF.ancsGetNotificationInfo`) + * Promise returns: + * ``` + * { + * "uid" : int, + * "appId" : string, + * "title" : string, + * "subtitle" : string, + * "message" : string, + * "messageSize" : string, + * "date" : string, + * "posAction" : string, + * "negAction" : string, + * "name" : string, + * } + * ``` + * + * @param {any} id - The app ID to get information for + * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete + * @url http://www.espruino.com/Reference#l_NRF_ancsGetAppInfo */ - static drawWidgets(): void; + static ancsGetAppInfo(id: any): Promise; /** - * @url http://www.espruino.com/Reference#l_Bangle_drawWidgets + * Check if Apple Media Service (AMS) is currently active on the BLE connection + * + * @returns {boolean} True if Apple Media Service (AMS) has been initialised and is active + * @url http://www.espruino.com/Reference#l_NRF_amsIsActive */ - static drawWidgets(): void; + static amsIsActive(): boolean; /** - * Load the Bangle.js app launcher, which will allow the user to select an - * application to launch. - * @url http://www.espruino.com/Reference#l_Bangle_showLauncher + * Get Apple Media Service (AMS) info for the current media player. "playbackinfo" + * returns a concatenation of three comma-separated values: + * - PlaybackState: a string that represents the integer value of the playback + * state: + * - PlaybackStatePaused = 0 + * - PlaybackStatePlaying = 1 + * - PlaybackStateRewinding = 2 + * - PlaybackStateFastForwarding = 3 + * - PlaybackRate: a string that represents the floating point value of the + * playback rate. + * - ElapsedTime: a string that represents the floating point value of the elapsed + * time of the current track, in seconds + * + * @param {any} id - Either 'name', 'playbackinfo' or 'volume' + * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete + * @url http://www.espruino.com/Reference#l_NRF_amsGetPlayerInfo */ - static showLauncher(): void; + static amsGetPlayerInfo(id: any): Promise; /** - * Load the Bangle.js clock - this has the same effect as calling `Bangle.load()`. - * @url http://www.espruino.com/Reference#l_Bangle_showClock + * Get Apple Media Service (AMS) info for the currently-playing track + * + * @param {any} id - Either 'artist', 'album', 'title' or 'duration' + * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete + * @url http://www.espruino.com/Reference#l_NRF_amsGetTrackInfo */ - static showClock(): void; + static amsGetTrackInfo(id: any): Promise; /** - * Show a 'recovery' menu that allows you to perform certain tasks on your Bangle. - * You can also enter this menu by restarting your Bangle while holding down the button. - * @url http://www.espruino.com/Reference#l_Bangle_showRecoveryMenu + * Send an AMS command to an Apple Media Service device to control music playback + * Command is one of play, pause, playpause, next, prev, volup, voldown, repeat, + * shuffle, skipforward, skipback, like, dislike, bookmark + * + * @param {any} id - For example, 'play', 'pause', 'volup' or 'voldown' + * @url http://www.espruino.com/Reference#l_NRF_amsCommand */ - static showRecoveryMenu(): void; + static amsCommand(id: any): void; /** - * @url http://www.espruino.com/Reference#l_Bangle_showRecoveryMenu + * Check if Apple Current Time Service (CTS) is currently active on the BLE connection + * + * @returns {boolean} True if Apple Current Time Service (CTS) has been initialised and is active + * @url http://www.espruino.com/Reference#l_NRF_ctsIsActive */ - static showRecoveryMenu(): void; + static ctsIsActive(): boolean; /** - * (2v20 and later) Show a test screen that lights green when each sensor on the Bangle - * works and reports within range. - * Swipe on the screen when all items are green and the Bangle will turn bluetooth off - * and display a `TEST PASS` screen for 60 minutes, after which it will turn off. - * You can enter this menu by restarting your Bangle while holding down the button, - * then choosing `Test` from the recovery menu. - * @url http://www.espruino.com/Reference#l_Bangle_showTestScreen + * Returns time information from the Current Time Service + * (if requested with `NRF.ctsGetTime` and is activated by calling `NRF.setServices(..., {..., cts:true})`) + * ``` + * { + * date : // Date object with the current date + * day : // if known, 0=sun,1=mon (matches JS `Date`) + * reason : [ // reason for the date change + * "external", // External time change + * "manual", // Manual update + * "timezone", // Timezone changed + * "DST", // Daylight savings + * ] + * timezone // if LTI characteristic exists, this is the timezone + * dst // if LTI characteristic exists, this is the dst adjustment + * } + * ``` + * For instance this can be used as follows to update Espruino's time: + * ``` + * E.on('CTS',e=>{ + * setTime(e.date.getTime()/1000); + * }); + * NRF.ctsGetTime(); // also returns a promise with CTS info + * ``` + * @param {string} event - The event to listen to. + * @param {(info: any) => void} callback - A function that is executed when the event occurs. Its arguments are: + * * `info` An object (see below) + * @url http://www.espruino.com/Reference#l_NRF_CTS */ - static showTestScreen(): void; + static on(event: "CTS", callback: (info: any) => void): void; /** - * This behaves the same as the global `load()` function, but if fast - * loading is possible (`Bangle.setUI` was called with a `remove` handler) - * then instead of a complete reload, the `remove` handler will be - * called and the new app will be loaded straight after with `eval`. - * **This should only be used if the app being loaded also uses widgets** - * (eg it contains a `Bangle.loadWidgets()` call). - * `load()` is slower, but safer. As such, care should be taken - * when using `Bangle.load()` with `Bangle.setUI({..., remove:...})` - * as if your remove handler doesn't completely clean up after your app, - * memory leaks or other issues could occur - see `Bangle.setUI` for more - * information. - * - * @param {any} [file] - [optional] A string containing the file name for the app to be loaded - * @url http://www.espruino.com/Reference#l_Bangle_load + * Read the time from CTS - creates an `NRF.on('CTS', ...)` event as well + * ``` + * NRF.ctsGetTime(); // also returns a promise + * ``` + * @returns {any} A `Promise` that is resolved (or rejected) when time is received + * @url http://www.espruino.com/Reference#l_NRF_ctsGetTime */ - static load(file: string): void; - static load(): void; + static ctsGetTime(): Promise; /** - * This puts Bangle.js into the specified UI input mode, and calls the callback - * provided when there is user input. - * Currently supported interface types are: - * * 'updown' - UI input with upwards motion `cb(-1)`, downwards motion `cb(1)`, - * and select `cb()` - * * Bangle.js 1 uses BTN1/3 for up/down and BTN2 for select - * * Bangle.js 2 uses touchscreen swipe up/down and tap - * * 'leftright' - UI input with left motion `cb(-1)`, right motion `cb(1)`, and - * select `cb()` - * * Bangle.js 1 uses BTN1/3 for left/right and BTN2 for select - * * Bangle.js 2 uses touchscreen swipe left/right and tap/BTN1 for select - * * 'clock' - called for clocks. Sets `Bangle.CLOCK=1` and allows a button to - * start the launcher - * * Bangle.js 1 BTN2 starts the launcher - * * Bangle.js 2 BTN1 starts the launcher - * * 'clockupdown' - called for clocks. Sets `Bangle.CLOCK=1`, allows a button to - * start the launcher, but also provides up/down functionality - * * Bangle.js 1 BTN2 starts the launcher, BTN1/BTN3 call `cb(-1)` and `cb(1)` - * * Bangle.js 2 BTN1 starts the launcher, touchscreen tap in top/bottom right - * hand side calls `cb(-1)` and `cb(1)` - * * `{mode:"custom", ...}` allows you to specify custom handlers for different - * interactions. See below. - * * `undefined` removes all user interaction code - * While you could use setWatch/etc manually, the benefit here is that you don't - * end up with multiple `setWatch` instances, and the actual input method (touch, - * or buttons) is implemented dependent on the watch (Bangle.js 1 or 2) + * Search for available devices matching the given filters. Since we have no UI + * here, Espruino will pick the FIRST device it finds, or it'll call `catch`. + * `options` can have the following fields: + * * `filters` - a list of filters that a device must match before it is returned + * (see below) + * * `timeout` - the maximum time to scan for in milliseconds (scanning stops when + * a match is found. e.g. `NRF.requestDevice({ timeout:2000, filters: [ ... ] })` + * * `active` - whether to perform active scanning (requesting 'scan response' + * packets from any devices that are found). e.g. `NRF.requestDevice({ active:true, + * filters: [ ... ] })` + * * `phy` - (NRF52833/NRF52840 only) the type of Bluetooth signals to scan for (can + * be `"1mbps/coded/both/2mbps"`) + * * `1mbps` (default) - standard Bluetooth LE advertising + * * `coded` - long range + * * `both` - standard and long range + * * `2mbps` - high speed 2mbps (not working) + * * `extended` - (NRF52833/NRF52840 only) support receiving extended-length advertising + * packets (default=true if phy isn't `"1mbps"`) + * * `extended` - (NRF52833/NRF52840 only) support receiving extended-length advertising + * packets (default=true if phy isn't `"1mbps"`) + * * `window` - (2v22+) how long we scan for in milliseconds (default 100ms) + * * `interval` - (2v22+) how often we scan in milliseconds (default 100ms) - `window=interval=100`(default) is all the time. When + * scanning on both `1mbps` and `coded`, `interval` needs to be twice `window`. + * **NOTE:** `timeout` and `active` are not part of the Web Bluetooth standard. + * The following filter types are implemented: + * * `services` - list of services as strings (all of which must match). 128 bit + * services must be in the form '01230123-0123-0123-0123-012301230123' + * * `name` - exact device name + * * `namePrefix` - starting characters of device name + * * `id` - exact device address (`id:"e9:53:86:09:89:99 random"`) (this is + * Espruino-specific, and is not part of the Web Bluetooth spec) + * * `serviceData` - an object containing **lowercase** service characteristics which must all + * match (`serviceData:{"1809":{}}`). Matching of actual service data is not + * supported yet. + * * `manufacturerData` - an object containing manufacturer UUIDs which must all + * match (`manufacturerData:{0x0590:{}}`). Matching of actual manufacturer data + * is not supported yet. * ``` - * Bangle.setUI("updown", function (dir) { - * // dir is +/- 1 for swipes up/down - * // dir is 0 when button pressed - * }); + * NRF.requestDevice({ filters: [{ namePrefix: 'Puck.js' }] }).then(function(device) { ... }); + * // or + * NRF.requestDevice({ filters: [{ services: ['1823'] }] }).then(function(device) { ... }); + * // or + * NRF.requestDevice({ filters: [{ manufacturerData:{0x0590:{}} }] }).then(function(device) { ... }); * ``` - * The first argument can also be an object, in which case more options can be - * specified with `mode:"custom"`: + * As a full example, to send data to another Puck.js to turn an LED on: * ``` - * Bangle.setUI({ - * mode : "custom", - * back : function() {}, // optional - add a 'back' icon in top-left widget area and call this function when it is pressed , also call it when the hardware button is clicked (does not override btn if defined) - * remove : function() {}, // optional - add a handler for when the UI should be removed (eg stop any intervals/timers here) - * redraw : function() {}, // optional - add a handler to redraw the UI. Not needed but it can allow widgets/etc to provide other functionality that requires the screen to be redrawn - * touch : function(n,e) {}, // optional - (mode:custom only) handler for 'touch' events - * swipe : function(dir) {}, // optional - (mode:custom only) handler for 'swipe' events - * drag : function(e) {}, // optional - (mode:custom only) handler for 'drag' events (Bangle.js 2 only) - * btn : function(n) {}, // optional - (mode:custom only) handler for 'button' events (n==1 on Bangle.js 2, n==1/2/3 depending on button for Bangle.js 1) - * clock : 0 // optional - if set the behavior of 'clock' mode is added (does not override btn if defined) + * var gatt; + * NRF.requestDevice({ filters: [{ namePrefix: 'Puck.js' }] }).then(function(device) { + * return device.gatt.connect(); + * }).then(function(g) { + * gatt = g; + * return gatt.getPrimaryService("6e400001-b5a3-f393-e0a9-e50e24dcca9e"); + * }).then(function(service) { + * return service.getCharacteristic("6e400002-b5a3-f393-e0a9-e50e24dcca9e"); + * }).then(function(characteristic) { + * return characteristic.writeValue("LED1.set()\n"); + * }).then(function() { + * gatt.disconnect(); + * console.log("Done!"); * }); * ``` - * If `remove` is specified, `Bangle.showLauncher`, `Bangle.showClock`, `Bangle.load` and some apps - * may choose to just call the `remove` function and then load a new app without resetting Bangle.js. - * As a result, **if you specify 'remove' you should make sure you test that after calling `Bangle.setUI()` - * without arguments your app is completely unloaded**, otherwise you may end up with memory leaks or - * other issues when switching apps. Please see the [Bangle.js Fast Load Tutorial](https://www.espruino.com/Bangle.js+Fast+Load) for more details on this. - * **Note:** You can override this function in boot code to change the interaction - * mode with the watch. For instance you could make all clocks start the launcher - * with a swipe by using: + * Or slightly more concisely, using ES6 arrow functions: * ``` - * (function() { - * var sui = Bangle.setUI; - * Bangle.setUI = function(mode, cb) { - * var m = ("object"==typeof mode) ? mode.mode : mode; - * if (m!="clock") return sui(mode,cb); - * sui(); // clear - * Bangle.CLOCK=1; - * Bangle.swipeHandler = Bangle.showLauncher; - * Bangle.on("swipe", Bangle.swipeHandler); - * }; - * })(); + * var gatt; + * NRF.requestDevice({ filters: [{ namePrefix: 'Puck.js' }]}).then( + * device => device.gatt.connect()).then( + * g => (gatt=g).getPrimaryService("6e400001-b5a3-f393-e0a9-e50e24dcca9e")).then( + * service => service.getCharacteristic("6e400002-b5a3-f393-e0a9-e50e24dcca9e")).then( + * characteristic => characteristic.writeValue("LED1.reset()\n")).then( + * () => { gatt.disconnect(); console.log("Done!"); } ); * ``` + * Note that you have to keep track of the `gatt` variable so that you can + * disconnect the Bluetooth connection when you're done. + * **Note:** Using a filter in `NRF.requestDevice` filters each advertising packet + * individually. As soon as a matching advertisement is received, + * `NRF.requestDevice` resolves the promise and stops scanning. This means that if + * you filter based on a service UUID and a device advertises with multiple packets + * (or a scan response when `active:true`) only the packet matching the filter is + * returned - you may not get the device's name is that was in a separate packet. + * To aggregate multiple packets you can use `NRF.findDevices`. * - * @param {any} type - The type of UI input: 'updown', 'leftright', 'clock', 'clockupdown' or undefined to cancel. Can also be an object (see below) - * @param {any} callback - A function with one argument which is the direction - * @url http://www.espruino.com/Reference#l_Bangle_setUI + * @param {any} options - Options used to filter the device to use + * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete + * @url http://www.espruino.com/Reference#l_NRF_requestDevice */ - static setUI(type?: undefined): void; - static setUI(type: SetUIArg<"updown" | "leftright">, callback: (direction?: -1 | 1) => void): void; - static setUI(type: SetUIArg<"clock">): void; - static setUI(type: SetUIArg<"clockupdown">, callback?: (direction: -1 | 1) => void): void; - static setUI(type: SetUIArg<"custom"> & { touch?: TouchCallback; swipe?: SwipeCallback; drag?: DragCallback; btn?: (n: 1 | 2 | 3) => void; clock?: boolean | 0 | 1 }): void; + static requestDevice(options?: { filters?: NRFFilters[], timeout?: number, active?: boolean, phy?: string, extended?: boolean }): Promise; /** - * @url http://www.espruino.com/Reference#l_Bangle_setUI + * Connect to a BLE device by MAC address. Returns a promise, the argument of which + * is the `BluetoothRemoteGATTServer` connection. + * ``` + * NRF.connect("aa:bb:cc:dd:ee").then(function(server) { + * // ... + * }); + * ``` + * This has the same effect as calling `BluetoothDevice.gatt.connect` on a + * `BluetoothDevice` requested using `NRF.requestDevice`. It just allows you to + * specify the address directly (without having to scan). + * You can use it as follows - this would connect to another Puck device and turn + * its LED on: + * ``` + * var gatt; + * NRF.connect("aa:bb:cc:dd:ee random").then(function(g) { + * gatt = g; + * return gatt.getPrimaryService("6e400001-b5a3-f393-e0a9-e50e24dcca9e"); + * }).then(function(service) { + * return service.getCharacteristic("6e400002-b5a3-f393-e0a9-e50e24dcca9e"); + * }).then(function(characteristic) { + * return characteristic.writeValue("LED1.set()\n"); + * }).then(function() { + * gatt.disconnect(); + * console.log("Done!"); + * }); + * ``` + * **Note:** Espruino Bluetooth devices use a type of BLE address known as 'random + * static', which is different to a 'public' address. To connect to an Espruino + * device you'll need to use an address string of the form `"aa:bb:cc:dd:ee + * random"` rather than just `"aa:bb:cc:dd:ee"`. If you scan for devices with + * `NRF.findDevices`/`NRF.setScan` then addresses are already reported in the + * correct format. + * + * @param {any} mac - The MAC address to connect to + * @param {any} options - (Espruino-specific) An object of connection options (see `BluetoothRemoteGATTServer.connect` for full details) + * @returns {any} A `Promise` that is resolved (or rejected) when the connection is complete + * @url http://www.espruino.com/Reference#l_NRF_connect */ - static setUI(): void; + static connect(mac: any, options: any): Promise; /** - * Erase all storage and reload it with the default contents. - * This is only available on Bangle.js 2.0. On Bangle.js 1.0 you need to use - * `Install Default Apps` under the `More...` tab of http://banglejs.com/apps + * If set to true, whenever a device bonds it will be added to the whitelist. + * When set to false, the whitelist is cleared and newly bonded devices will not be + * added to the whitelist. + * **Note:** This is remembered between `reset()`s but isn't remembered after + * power-on (you'll have to add it to `onInit()`. * - * @param {boolean} noReboot - Do not reboot the watch when done (default false, so will reboot) - * @url http://www.espruino.com/Reference#l_Bangle_factoryReset + * @param {boolean} whitelisting - Are we using a whitelist? (default false) + * @url http://www.espruino.com/Reference#l_NRF_setWhitelist */ - static factoryReset(noReboot: ShortBoolean): void; + static setWhitelist(whitelisting: ShortBoolean): void; /** - * Returns the rectangle on the screen that is currently reserved for the app. - * @returns {any} An object of the form `{x,y,w,h,x2,y2}` - * @url http://www.espruino.com/Reference#l_Bangle_appRect + * When connected, Bluetooth LE devices communicate at a set interval. Lowering the + * interval (e.g. more packets/second) means a lower delay when sending data, higher + * bandwidth, but also more power consumption. + * By default, when connected as a peripheral Espruino automatically adjusts the + * connection interval. When connected it's as fast as possible (7.5ms) but when + * idle for over a minute it drops to 200ms. On continued activity (>1 BLE + * operation) the interval is raised to 7.5ms again. + * The options for `interval` are: + * * `undefined` / `"auto"` : (default) automatically adjust connection interval + * * `100` : set min and max connection interval to the same number (between 7.5ms + * and 4000ms) + * * `{minInterval:20, maxInterval:100}` : set min and max connection interval as a + * range + * This configuration is not remembered during a `save()` - you will have to re-set + * it via `onInit`. + * **Note:** If connecting to another device (as Central), you can use an extra + * argument to `NRF.connect` or `BluetoothRemoteGATTServer.connect` to specify a + * connection interval. + * **Note:** This overwrites any changes imposed by the deprecated + * `NRF.setLowPowerConnection` + * + * @param {any} interval - The connection interval to use (see below) + * @url http://www.espruino.com/Reference#l_NRF_setConnectionInterval */ - static appRect: { x: number, y: number, w: number, h: number, x2: number, y2: number }; - - static CLOCK: ShortBoolean; - static strokes: undefined | { [key: string]: Unistroke }; -} + static setConnectionInterval(interval: any): void; -/** - * Class containing utility functions for accessing IO on the hexagonal badge - * @url http://www.espruino.com/Reference#Badge - */ -declare class Badge { /** - * Capacitive sense - the higher the capacitance, the higher the number returned. - * Supply a corner number between 1 and 6, and an integer value will be returned - * that is proportional to the capacitance + * Sets the security options used when connecting/pairing. This applies to both + * central *and* peripheral mode. + * ``` + * NRF.setSecurity({ + * display : bool // default false, can this device display a passkey on a screen/etc? + * // - sent via the `BluetoothDevice.passkey` event + * keyboard : bool // default false, can this device enter a passkey + * // - request sent via the `BluetoothDevice.passkeyRequest` event + * pair : bool // default true, allow other devices to pair with this device + * bond : bool // default true, Perform bonding + * // This stores info from pairing in flash and allows reconnecting without having to pair each time + * mitm : bool // default false, Man In The Middle protection + * lesc : bool // default false, LE Secure Connections + * passkey : // default "", or a 6 digit passkey to use (display must be true for this) + * oob : [0..15] // if specified, Out Of Band pairing is enabled and + * // the 16 byte pairing code supplied here is used + * encryptUart : bool // default false (unless oob or passkey specified) + * // This sets the BLE UART service such that it + * // is encrypted and can only be used from a paired connection + * privacy : // default false, true to enable with (ideally sensible) defaults, + * // or an object defining BLE privacy / random address options - see below for more info + * // only available if Espruino was compiled with private address support (like for example on Bangle.js 2) + * }); + * ``` + * **NOTE:** Some combinations of arguments will cause an error. For example + * supplying a passkey without `display:1` is not allowed. If `display:1` is set + * you do not require a physical display, the user just needs to know the passkey + * you supplied. + * For instance, to require pairing and to specify a passkey, use: + * ``` + * NRF.setSecurity({passkey:"123456", mitm:1, display:1}); + * ``` + * Or to require pairing and to display a PIN that the connecting device + * provides, use: + * ``` + * NRF.setSecurity({mitm:1, display:1}); + * NRF.on("passkey", key => print("Enter PIN: ", key)); + * ``` + * However, while most devices will request a passkey for pairing at this point it + * is still possible for a device to connect without requiring one (e.g. using the + * 'NRF Connect' app). + * To force a passkey you need to protect each characteristic you define with + * `NRF.setSecurity`. For instance the following code will *require* that the + * passkey `123456` is entered before the characteristic + * `9d020002-bf5f-1d1a-b52a-fe52091d5b12` can be read. + * ``` + * NRF.setSecurity({passkey:"123456", mitm:1, display:1}); + * NRF.setServices({ + * "9d020001-bf5f-1d1a-b52a-fe52091d5b12" : { + * "9d020002-bf5f-1d1a-b52a-fe52091d5b12" : { + * // readable always + * value : "Not Secret" + * }, + * "9d020003-bf5f-1d1a-b52a-fe52091d5b12" : { + * // readable only once bonded + * value : "Secret", + * readable : true, + * security: { + * read: { + * mitm: true, + * encrypted: true + * } + * } + * }, + * "9d020004-bf5f-1d1a-b52a-fe52091d5b12" : { + * // readable always + * // writable only once bonded + * value : "Readable", + * readable : true, + * writable : true, + * onWrite : function(evt) { + * console.log("Wrote ", evt.data); + * }, + * security: { + * write: { + * mitm: true, + * encrypted: true + * } + * } + * } + * } + * }); + * ``` + * **Note:** If `passkey` or `oob` is specified, the Nordic UART service (if + * enabled) will automatically be set to require encryption, but otherwise it is + * open. + * On Bangle.js 2, the `privacy` parameter can be used to set this device's BLE privacy / random address settings. + * The privacy feature provides a way to avoid being tracked over a period of time. + * This works by replacing the real BLE address with a random private address, + * that automatically changes at a specified interval. + * If a `"random_private_resolvable"` address is used, that address is generated with the help + * of an identity resolving key (IRK), that is exchanged during bonding. + * This allows a bonded device to still identify another device that is using a random private resolvable address. + * Note that, while this can help against being tracked, there are other ways a Bluetooth device can reveal its identity. + * For example, the name or services it advertises may be unique enough. + * ``` + * NRF.setSecurity({ + * privacy: { + * mode : "off"/"device_privacy"/"network_privacy" // The privacy mode that should be used. + * addr_type : "random_private_resolvable"/"random_private_non_resolvable" // The type of address to use. + * addr_cycle_s : int // How often the address should change, in seconds. + * } + * }); + * // enabled with (ideally sensible) defaults of: + * // mode: device_privacy + * // addr_type: random_private_resolvable + * // addr_cycle_s: 0 (use default address change interval) + * NRF.setSecurity({ + * privacy: 1 + * }); + * ``` + * `mode` can be one of: + * * `"off"` - Use the real address. + * * `"device_privacy"` - Use a private address. + * * `"network_privacy"` - Use a private address, + * and reject a peer that uses its real address if we know that peer's IRK. + * If `mode` is `"off"`, all other fields are ignored and become optional. + * `addr_type` can be one of: + * * `"random_private_resolvable"` - Address that can be resolved by a bonded peer that knows our IRK. + * * `"random_private_non_resolvable"` - Address that cannot be resolved. + * `addr_cycle_s` must be an integer. Pass `0` to use the default address change interval. + * The default is usually to change the address every 15 minutes (or 900 seconds). * - * @param {number} corner - The corner to use - * @returns {number} Capacitive sense counter - * @url http://www.espruino.com/Reference#l_Badge_capSense + * @param {any} options - An object containing security-related options (see below) + * @url http://www.espruino.com/Reference#l_NRF_setSecurity */ - static capSense(corner: number): number; + static setSecurity(options: any): void; /** - * **DEPRECATED** - Please use `E.getBattery()` instead. - * Return an approximate battery percentage remaining based on a normal CR2032 - * battery (2.8 - 2.2v) - * @returns {number} A percentage between 0 and 100 - * @url http://www.espruino.com/Reference#l_Badge_getBatteryPercentage + * Return an object with information about the security state of the current + * peripheral connection: + * ``` + * { + * connected // The connection is active (not disconnected). + * encrypted // Communication on this link is encrypted. + * mitm_protected // The encrypted communication is also protected against man-in-the-middle attacks. + * bonded // The peer is bonded with us + * advertising // Are we currently advertising? + * connected_addr // If connected=true, the MAC address of the currently connected device + * privacy // Current BLE privacy / random address settings. + * // Only present if Espruino was compiled with private address support (like for example on Bangle.js 2). + * } + * ``` + * If there is no active connection, `{connected:false}` will be returned. + * See `NRF.setSecurity` for information about negotiating a secure connection. + * @returns {any} An object + * @url http://www.espruino.com/Reference#l_NRF_getSecurityStatus */ - static getBatteryPercentage(): number; + static getSecurityStatus(): NRFSecurityStatus; /** - * Set the LCD's contrast * - * @param {number} c - Contrast between 0 and 1 - * @url http://www.espruino.com/Reference#l_Badge_setContrast + * @param {boolean} forceRepair - True if we should force repairing even if there is already valid pairing info + * @returns {any} A promise + * @url http://www.espruino.com/Reference#l_NRF_startBonding */ - static setContrast(c: number): void; + static startBonding(forceRepair: ShortBoolean): any; } @@ -5725,101 +5298,31 @@ declare class Graphics { static createImage(str: string): ImageObject; /** - * Draw a filled arc between two angles - * - * @param {number} a1 - Angle 1 (radians) - * @param {number} a2 - Angle 2 (radians) - * @param {number} r - Radius - * @returns {any} The instance of Graphics this was called on, to allow call chaining - * @url http://www.espruino.com/Reference#l_Graphics_fillArc - */ - fillArc(a1: number, a2: number, r: number): Graphics; - - /** - * Draw rectangle between angles a-ar and a+ar, and radius r1/r2 - * - * @param {number} a - Angle (radians) - * @param {number} ar - Angle either side (radians) - * @param {number} r1 - Radius - * @param {number} r2 - Radius - * @returns {any} The instance of Graphics this was called on, to allow call chaining - * @url http://www.espruino.com/Reference#l_Graphics_fillSeg - */ - fillSeg(a: number, ar: number, r1: number, r2: number): Graphics; - - /** - * Draw A line between angles a-ar and a+ar at radius r - * - * @param {number} a - Angle (radians) - * @param {number} ar - Angle either side (radians) - * @param {number} r - Radius - * @returns {any} The instance of Graphics this was called on, to allow call chaining - * @url http://www.espruino.com/Reference#l_Graphics_drawSeg - */ - drawSeg(a: number, ar: number, r: number): Graphics; - - /** - * Set the current font to Monofonto 23 (2 bpp, cap height = 22 px, total height = 27 px) - * - * @param {number} [scale] - [optional] If >1 the font will be scaled up by that amount - * @returns {any} The instance of Graphics this was called on, to allow call chaining - * @url http://www.espruino.com/Reference#l_Graphics_setFontMonofonto23 - */ - setFontMonofonto23(scale?: number): Graphics; - - /** - * Set the current font to Monofonto 16 (4 bpp, cap height = 16 px) - * - * @param {number} [scale] - [optional] If >1 the font will be scaled up by that amount - * @returns {any} The instance of Graphics this was called on, to allow call chaining - * @url http://www.espruino.com/Reference#l_Graphics_setFontMonofonto16 - */ - setFontMonofonto16(scale?: number): Graphics; - - /** - * Set the current font to Monofonto 18 (2 bpp, cap height = 17 px, total height = 21 px) - * - * @param {number} [scale] - [optional] If >1 the font will be scaled up by that amount - * @returns {any} The instance of Graphics this was called on, to allow call chaining - * @url http://www.espruino.com/Reference#l_Graphics_setFontMonofonto18 - */ - setFontMonofonto18(scale?: number): Graphics; - - /** - * Set the current font to Monofonto 96 (digits and colon only, 2 bpp, cap height = 96 px) - * - * @param {number} [scale] - [optional] If >1 the font will be scaled up by that amount - * @returns {any} The instance of Graphics this was called on, to allow call chaining - * @url http://www.espruino.com/Reference#l_Graphics_setFontMonofonto96 - */ - setFontMonofonto96(scale?: number): Graphics; - - /** - * Set the current font to Monofonto 28 (2 bpp, cap height = 26 px, total height = 33 px) + * Set the current font * - * @param {number} [scale] - [optional] If >1 the font will be scaled up by that amount + * @param {number} scale - The scale factor, default=1 (2=2x size) * @returns {any} The instance of Graphics this was called on, to allow call chaining - * @url http://www.espruino.com/Reference#l_Graphics_setFontMonofonto28 + * @url http://www.espruino.com/Reference#l_Graphics_setFont17 */ - setFontMonofonto28(scale?: number): Graphics; + setFont17(scale: number): Graphics; /** - * Set the current font to Monofonto 120 (digits and colon only, 2 bpp, cap height = 120 px) + * Set the current font * - * @param {number} [scale] - [optional] If >1 the font will be scaled up by that amount + * @param {number} scale - The scale factor, default=1 (2=2x size) * @returns {any} The instance of Graphics this was called on, to allow call chaining - * @url http://www.espruino.com/Reference#l_Graphics_setFontMonofonto120 + * @url http://www.espruino.com/Reference#l_Graphics_setFont28 */ - setFontMonofonto120(scale?: number): Graphics; + setFont28(scale: number): Graphics; /** - * Set the current font to Monofonto 36 (2 bpp, cap height = 34 px, total height = 43 px) + * Set the current font * - * @param {number} [scale] - [optional] If >1 the font will be scaled up by that amount + * @param {number} scale - The scale factor, default=1 (2=2x size) * @returns {any} The instance of Graphics this was called on, to allow call chaining - * @url http://www.espruino.com/Reference#l_Graphics_setFontMonofonto36 + * @url http://www.espruino.com/Reference#l_Graphics_setFont22 */ - setFontMonofonto36(scale?: number): Graphics; + setFont22(scale: number): Graphics; /** * Set the current font @@ -5839,6 +5342,15 @@ declare class Graphics { */ setFont6x15(scale: number): Graphics; + /** + * Set the current font + * + * @param {number} scale - The scale factor, default=1 (2=2x size) + * @returns {any} The instance of Graphics this was called on, to allow call chaining + * @url http://www.espruino.com/Reference#l_Graphics_setFont14 + */ + setFont14(scale: number): Graphics; + /** * On instances of graphics that drive a display with an offscreen buffer, calling * this function will copy the contents of the offscreen buffer to the screen. @@ -6282,7 +5794,7 @@ declare class Graphics { /** * Return the width and height in pixels of a string of text in the current font. The object returned contains: - * ```JS + * ``` * { * width, // Width of the string in pixels * height, // Height of the string in pixels @@ -6313,6 +5825,34 @@ declare class Graphics { */ wrapString(str: string, maxWidth: number): string[]; + /** + * Works out which font to use, and sets the current font to it. + * Usage: + * ``` + * g.findFont("Hello World", { + * w : 100, // optional: width available (default = screen width) + * h : 100, // optional: height available (default = screen height) + * min : 10, // optional: min font height + * max : 30, // optional: max font height + * wrap : true // optional: allow word wrap? + * trim : true // optional: trim to the specified height, add '...' + * }); + * ``` + * Returns: + * ``` + * { + * text : "Hello\nWorld" + * font : "..." + * } + * ``` + * + * @param {any} text - The text to render + * @param {any} options - Options for finding the required font + * @returns {any} An object containing info about the font + * @url http://www.espruino.com/Reference#l_Graphics_findFont + */ + findFont(text: any, options: any): any; + /** * Draw a string of text in the current font. * ``` @@ -6605,8 +6145,13 @@ declare class Graphics { * page](http://www.espruino.com/Graphics#images-bitmaps) for more information on * images. * Will return undefined if data can't be allocated for the image. + * `options` can be either: + * * `undefined` or `"object"` - return an image object + * * `string` - return the image as a string + * * (in 2v26 onwards) `{type:undefined/"object"/"string", x,y,w,h}` - Return only a part of the image as an object/string. * The image data itself will be referenced rather than copied if: * * An image `object` was requested (not `string`) + * * `x`/`y` are 0 and `w`/`h` are the graphics's height * * The `Graphics` instance was created with `Graphics.createArrayBuffer` * * Is 8 bpp *OR* the `{msb:true}` option was given * * No other format options (zigzag/etc) were given @@ -6621,12 +6166,14 @@ declare class Graphics { * var im = gfx.asImage("string"); * ``` * - * @param {any} type - The type of image to return. Either `object`/undefined to return an image object, or `string` to return an image string + * @param {any} options - The type of image to return as a string, or an object `{x,y,w,h,type}` (see below) * @returns {any} An Image that can be used with `Graphics.drawImage` * @url http://www.espruino.com/Reference#l_Graphics_asImage */ asImage(type?: "object"): ImageObject; asImage(type: "string"): string; + asImage(layers: { type?: "object", x?: number, y?: number, w?: number, h?: number }): ImageObject; + asImage(layers: { type: "string", x?: number, y?: number, w?: number, h?: number }): string; /** * Return the area of the Graphics canvas that has been modified, and optionally @@ -6935,7 +6482,7 @@ declare class Waveform { * It has an internal variable called `buffer` (as well as `buffer2` when * double-buffered - see `options` below) which contains the data to input/output. * Options can contain: - * ```JS + * ``` * { * doubleBuffer : bool // whether to allocate two buffers or not (default false) * bits : 8/16 // the amount of bits to use (default 8). @@ -6944,7 +6491,7 @@ declare class Waveform { * When double-buffered, a 'buffer' event will be emitted each time a buffer is * finished with (the argument is that buffer). When the recording stops, a * 'finish' event will be emitted (with the first argument as the buffer). - * ```JS + * ``` * // Output a sine wave * var w = new Waveform(1000); * for (var i=0;i<1000;i++) w.buffer[i]=128+120*Math.sin(i/2); @@ -6952,7 +6499,7 @@ declare class Waveform { * w.on("finish", () => print("Done!")) * w.startOutput(H0,8000); // start playback * ``` - * ```JS + * ``` * // On 2v25, from Storage * var f = require("Storage").read("sound.pcm"); * var w = new Waveform(E.toArrayBuffer(f)); @@ -8494,21 +8041,6 @@ declare class E { */ static showAlert(message?: string, options?: string): Promise; - /** - * @url http://www.espruino.com/Reference#l_E_showMenu - */ - static showMenu(): void; - - /** - * @url http://www.espruino.com/Reference#l_E_showPrompt - */ - static showPrompt(): void; - - /** - * @url http://www.espruino.com/Reference#l_E_showMessage - */ - static showMessage(): void; - /** * Setup the filesystem so that subsequent calls to `E.openFile` and * `require('fs').*` will use an SD card on the supplied SPI device and pin. @@ -8554,36 +8086,6 @@ declare class E { */ static openFile(path: any, mode: any): File; - /** - * Change the parameters used for the flash filesystem. The default address is the - * last 1Mb of 4Mb Flash, 0x300000, with total size of 1Mb. - * Before first use the media needs to be formatted. - * ``` - * fs=require("fs"); - * try { - * fs.readdirSync(); - * } catch (e) { //'Uncaught Error: Unable to mount media : NO_FILESYSTEM' - * console.log('Formatting FS - only need to do once'); - * E.flashFatFS({ format: true }); - * } - * fs.writeFileSync("bang.txt", "This is the way the world ends\nnot with a bang but a whimper.\n"); - * fs.readdirSync(); - * ``` - * This will create a drive of 100 * 4096 bytes at 0x300000. Be careful with the - * selection of flash addresses as you can overwrite firmware! You only need to - * format once, as each will erase the content. - * `E.flashFatFS({ addr:0x300000,sectors:100,format:true });` - * - * @param {any} [options] - * [optional] An object `{ addr : int=0x300000, sectors : int=256, format : bool=false }` - * addr : start address in flash - * sectors: number of sectors to use - * format: Format the media - * @returns {boolean} True on success, or false on failure - * @url http://www.espruino.com/Reference#l_E_flashFatFS - */ - static flashFatFS(options?: any): boolean; - /** * Display a menu on the screen, and set up the buttons to navigate through it. * Supply an object containing menu items. When an item is selected, the function @@ -8713,7 +8215,8 @@ declare class E { * title: "Hello", // optional Title * buttons : {"Ok":true,"Cancel":false}, // optional list of button text & return value * img: "image_string" // optional image string to draw - * remove: function() { } // Bangle.js: optional function to be called when the prompt is removed + * remove: function() { } // Bangle.js: optional function to be called when the prompt is removed# + * buttonHeight : 30, // Bangle.js2: optional height to force the buttons to be * } * ``` * @@ -8722,7 +8225,7 @@ declare class E { * @returns {any} A promise that is resolved when 'Ok' is pressed * @url http://www.espruino.com/Reference#l_E_showPrompt */ - static showPrompt(message: string, options?: { title?: string, buttons?: { [key: string]: T }, image?: string, remove?: () => void }): Promise; + static showPrompt(message: string, options?: { title?: string, buttons?: { [key: string]: T }, buttonHeight?: number, image?: string, remove?: () => void }): Promise; static showPrompt(): void; /** @@ -9100,7 +8603,7 @@ declare class E { /** * (Added 2v25) Enable the nRF52 chip's `LPCOMP` hardware. When enabled, it creates an `E.on("comparator", ...)` * event whenever the pin supplied rises or falls past the setpoint given (with 50mv hysteresis). - * ```JS + * ``` * E.setComparator(D28, 8/16); // compare with VDD/2 * E.on("comparator", e => { * print(e); // 1 for up, or -1 for down @@ -9108,7 +8611,7 @@ declare class E { * ``` * **Note:** There is just one LPCOMP, so you can only enable the comparator on one pin. * **On [Jolt.js](https://www.espruino.com/Jolt.js):** when using `E.setComparator` on the analog pins on the - * Terminal block (`H0`/`H2`/`H4`/`H8`), the `level` you give needs to be in volts. Because the comparator only + * Terminal block (`H0`/`H2`/`H4`/`H6`), the `level` you give needs to be in volts. Because the comparator only * works in 16 steps, you can only detect multiples of 1.37v (1.37/2.74/4.11/etc) * * @param {Pin} pin - The `Pin` to enable the comparator on @@ -9835,8 +9338,10 @@ declare class E { static reboot(): void; /** - * Forces a hard reboot of the microcontroller into the ST DFU mode - * **Note:** The device will stay in DFU mode until it is power-cycled or reset + * Forces a hard reboot of the microcontroller into DFU mode. + * If this is an ST device, this will be the ST DFU mode. + * If this device has an UF2 bootloader, it will reappear as a USB drive, onto which you can copy new firmware. + * **Note:** The device will stay in DFU mode until it is power-cycled or reset. * @url http://www.espruino.com/Reference#l_E_rebootToDFU */ static rebootToDFU(): void; @@ -12074,7 +11579,7 @@ declare class Pin { /** * (Added in 2v20) Get the analogue value of the given pin. See `analogRead` for more information. - * @returns {number} The analog Value of the Pin between 0 and 1 + * @returns {number} The analog value of the `Pin` between 0(GND) and 1(VCC) * @url http://www.espruino.com/Reference#l_Pin_analog */ analog(): number; @@ -12142,67 +11647,6 @@ declare const Boolean: BooleanConstructor // GLOBALS -/** - * @returns {any} An object containing the pins for the Qwiic connector on Curio `{sda,scl}` - * @url http://www.espruino.com/Reference#l__global_Q - */ -declare const Q: Qwiic; - -/** - * @returns {Pin} The pin for the servo motor - * @url http://www.espruino.com/Reference#l__global_SERVO - */ -declare const SERVO: Pin; - -/** - * @returns {Pin} The pin for the IR LED - * @url http://www.espruino.com/Reference#l__global_IRLED - */ -declare const IRLED: Pin; - -/** - * @returns {Pin} The pin for the left IR sensor - * @url http://www.espruino.com/Reference#l__global_IRL - */ -declare const IRL: Pin; - -/** - * @returns {Pin} The pin for the left motor - * @url http://www.espruino.com/Reference#l__global_ML1 - */ -declare const ML1: Pin; - -/** - * @returns {Pin} The pin for the left motor - * @url http://www.espruino.com/Reference#l__global_ML2 - */ -declare const ML2: Pin; - -/** - * @returns {Pin} The pin for the right IR sensor - * @url http://www.espruino.com/Reference#l__global_IRR - */ -declare const IRR: Pin; - -/** - * @returns {Pin} The pin for the right motor - * @url http://www.espruino.com/Reference#l__global_MR1 - */ -declare const MR1: Pin; - -/** - * @returns {Pin} The pin for the right motor - * @url http://www.espruino.com/Reference#l__global_MR2 - */ -declare const MR2: Pin; - -/** - * - * @param {any} col - The colours to use, a 24 element array (8 x RGB) - * @url http://www.espruino.com/Reference#l__global_led - */ -declare function led(col: any): void; - /** * The pin marked SDA on the Arduino pin footprint. This is connected directly to * pin A4. @@ -12278,6 +11722,13 @@ declare function compass(): any; */ declare const FET: Pin; +/** + * In memory serial I/O device accessible via SWD debugger. + * Uses SEGGER RTT so it can be used with openocd and other SEGGER compatible tools. + * @url http://www.espruino.com/Reference#l__global_SWDCON + */ +declare const SWDCON: Serial; + /** * `Q0` and `Q1` Qwiic connectors can have their power controlled by a 500mA FET (`Q0.fet`) which switches GND. * The `sda` and `scl` pins on this port are also analog inputs - use `analogRead(Q0.sda)`/etc @@ -12354,90 +11805,6 @@ declare const LED1: any; */ declare const LED2: any; -/** - * The pin connected to the 'A' button. Reads as `1` when pressed, `0` when not - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_BTNA - */ -declare const BTNA: Pin; - -/** - * The pin connected to the 'B' button. Reads as `1` when pressed, `0` when not - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_BTNB - */ -declare const BTNB: Pin; - -/** - * The pin connected to the up button. Reads as `1` when pressed, `0` when not - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_BTNU - */ -declare const BTNU: Pin; - -/** - * The pin connected to the down button. Reads as `1` when pressed, `0` when not - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_BTND - */ -declare const BTND: Pin; - -/** - * The pin connected to the left button. Reads as `1` when pressed, `0` when not - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_BTNL - */ -declare const BTNL: Pin; - -/** - * The pin connected to the right button. Reads as `1` when pressed, `0` when not - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_BTNR - */ -declare const BTNR: Pin; - -/** - * The pin connected to Corner #1 - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_CORNER1 - */ -declare const CORNER1: Pin; - -/** - * The pin connected to Corner #2 - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_CORNER2 - */ -declare const CORNER2: Pin; - -/** - * The pin connected to Corner #3 - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_CORNER3 - */ -declare const CORNER3: Pin; - -/** - * The pin connected to Corner #4 - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_CORNER4 - */ -declare const CORNER4: Pin; - -/** - * The pin connected to Corner #5 - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_CORNER5 - */ -declare const CORNER5: Pin; - -/** - * The pin connected to Corner #6 - * @returns {Pin} - * @url http://www.espruino.com/Reference#l__global_CORNER6 - */ -declare const CORNER6: Pin; - /** * The Bluetooth Serial port - used when data is sent or received over Bluetooth * Smart on nRF51/nRF52 chips. @@ -12445,54 +11812,6 @@ declare const CORNER6: Pin; */ declare const Bluetooth: Serial; -/** - * @returns {Pin} A Pin - * @url http://www.espruino.com/Reference#l__global_MOS1 - */ -declare const MOS1: Pin; - -/** - * @returns {Pin} A Pin - * @url http://www.espruino.com/Reference#l__global_MOS2 - */ -declare const MOS2: Pin; - -/** - * @returns {Pin} A Pin - * @url http://www.espruino.com/Reference#l__global_MOS3 - */ -declare const MOS3: Pin; - -/** - * @returns {Pin} A Pin - * @url http://www.espruino.com/Reference#l__global_MOS4 - */ -declare const MOS4: Pin; - -/** - * @returns {Pin} A Pin - * @url http://www.espruino.com/Reference#l__global_IOEXT0 - */ -declare const IOEXT0: Pin; - -/** - * @returns {Pin} A Pin - * @url http://www.espruino.com/Reference#l__global_IOEXT1 - */ -declare const IOEXT1: Pin; - -/** - * @returns {Pin} A Pin - * @url http://www.espruino.com/Reference#l__global_IOEXT2 - */ -declare const IOEXT2: Pin; - -/** - * @returns {Pin} A Pin - * @url http://www.espruino.com/Reference#l__global_IOEXT3 - */ -declare const IOEXT3: Pin; - /** * A simple VT100 terminal emulator. * When data is sent to the `Terminal` object, `Graphics.getInstance()` is called @@ -12829,6 +12148,9 @@ declare function poke32(addr: number, value: number | number[]): void; /** * Get the analogue value of the given pin. + * * The value is normally greater than or equal to 0, however in some cases nRF52-based boards can produce values + * less than 0 when the ADC voltage is slightly less than the chip's internal GND. + * * The value returned will always be *less* than 1, even when the ADC reads full range. For example a 12 bit ADC may return 4095 as a full-range value, but this is divided by 4096 to produce `analogRead`'s output value. * This is different to Arduino which only returns an integer between 0 and 1023 * However only pins connected to an ADC will work (see the datasheet) * **Note:** if you didn't call `pinMode` beforehand then this function will also @@ -12840,7 +12162,7 @@ declare function poke32(addr: number, value: number | number[]): void; * @param {Pin} pin * The pin to use * You can find out which pins to use by looking at [your board's reference page](#boards) and searching for pins with the `ADC` markers. - * @returns {number} The Analog Value of the Pin between 0(GND) and 1(VCC). See below. + * @returns {number} The analog value of the `Pin` between 0(GND) and 1(VCC). See below. * @url http://www.espruino.com/Reference#l__global_analogRead */ declare function analogRead(pin: Pin): number; @@ -13084,22 +12406,13 @@ declare function clearWatch(id: number): void; declare function clearWatch(): void; declare const global: { - Q: typeof Q; - SERVO: typeof SERVO; - IRLED: typeof IRLED; - IRL: typeof IRL; - ML1: typeof ML1; - ML2: typeof ML2; - IRR: typeof IRR; - MR1: typeof MR1; - MR2: typeof MR2; - led: typeof led; SDA: typeof SDA; SCL: typeof SCL; show: typeof show; acceleration: typeof acceleration; compass: typeof compass; FET: typeof FET; + SWDCON: typeof SWDCON; Q0: typeof Q0; Q1: typeof Q1; Q2: typeof Q2; @@ -13108,27 +12421,7 @@ declare const global: { LED: typeof LED; LED1: typeof LED1; LED2: typeof LED2; - BTNA: typeof BTNA; - BTNB: typeof BTNB; - BTNU: typeof BTNU; - BTND: typeof BTND; - BTNL: typeof BTNL; - BTNR: typeof BTNR; - CORNER1: typeof CORNER1; - CORNER2: typeof CORNER2; - CORNER3: typeof CORNER3; - CORNER4: typeof CORNER4; - CORNER5: typeof CORNER5; - CORNER6: typeof CORNER6; Bluetooth: typeof Bluetooth; - MOS1: typeof MOS1; - MOS2: typeof MOS2; - MOS3: typeof MOS3; - MOS4: typeof MOS4; - IOEXT0: typeof IOEXT0; - IOEXT1: typeof IOEXT1; - IOEXT2: typeof IOEXT2; - IOEXT3: typeof IOEXT3; Terminal: typeof Terminal; setBusyIndicator: typeof setBusyIndicator; setSleepIndicator: typeof setSleepIndicator; @@ -14654,6 +13947,20 @@ declare module "fs" { */ function statSync(path: any): any; + /** + * Get the number of free sectors on the volume. This returns an object with the following + * fields: + * freeSectors: the number of free sectors + * totalSectors: the total number of sectors on the volume + * sectorSize: the number of bytes per sector + * clusterSize: the number of sectors per cluster + * + * @param {any} path - The path specifying the logical drive + * @returns {any} An object describing the drive, or undefined on failure + * @url http://www.espruino.com/Reference#l_fs_getFree + */ + function getFree(path: any): any; + /** * Create the directory * NOTE: Espruino does not yet support Async file IO, so this function behaves like @@ -14674,6 +13981,13 @@ declare module "fs" { */ function mkdirSync(path: any): boolean; + /** + * Reformat the connected media to a FAT filesystem + * @returns {boolean} True on success, or false on failure + * @url http://www.espruino.com/Reference#l_fs_mkfs + */ + function mkfs(): boolean; + /** * Pipe this file to a destination stream (object which has a `.write(data)` method). * @@ -15145,4 +14459,4 @@ declare module "Storage" { * @url http://www.espruino.com/Reference#l_Storage_open */ function open(name: string, mode: "r" | "w" | "a"): StorageFile; -} +} \ No newline at end of file