mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-10-11 09:12:32 +02:00
Add guides on Getting Started with JS (#4150)
- Get started section added to the JS docs - Small fixes in the JS modules docs
This commit is contained in:
16
documentation/js/js_about.md
Normal file
16
documentation/js/js_about.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# About the JavaScript engine {#js_about_js_engine}
|
||||
|
||||
> Developing applications for Flipper Zero is now much more accessible with the introduction of JavaScript support.
|
||||
|
||||
Previously, building an app for Flipper Zero required C/C++ skills, setting up a development environment, and studying the code of existing applications and documentation. While embedded developers are very familiar with all of this, we wanted to make it easier for people from all backgrounds to create apps for Flipper Zero.
|
||||
|
||||
Flipper firmware now includes a built-in scripting engine that runs JavaScript, one of the most widely used programming languages. You can create script files, share them with others, and launch them directly from the **Apps/Scripts** menu on your Flipper Zero — no need for compiling on a PC.
|
||||
|
||||
JavaScript support is based on the [mJS scripting engine](https://github.com/cesanta/mjs). Originally designed for microcontrollers, mJS makes efficient use of system resources, requiring less than 50k of flash space and 2k of RAM. We've kept the core features of mJS and also added some useful improvements, such as support for compact binary arrays.
|
||||
|
||||
> [!note]
|
||||
> mJS has some limitations compared to JavaScript engines built into modern browsers. For details on capabilities and limitations, refer to the [mJS documentation on GitHub](https://github.com/cesanta/mjs).
|
||||
|
||||
JavaScript apps can interact with Flipper Zero's resources, including its GUI, buttons, USB-HID device, GPIO, UART interfaces, and more. Let's go through the steps to create your first JavaScript app for Flipper Zero.
|
||||
|
||||
**Next step:** [Your first JavaScript app](#js_your_first_js_app)
|
@@ -1,6 +1,5 @@
|
||||
# js_badusb {#js_badusb}
|
||||
# BadUSB module {#js_badusb}
|
||||
|
||||
# BadUSB module
|
||||
```js
|
||||
let badusb = require("badusb");
|
||||
```
|
||||
@@ -58,7 +57,7 @@ badusb.press(0x47); // Press key with HID code (hex) 0x47 (Scroll lock)
|
||||
Hold a key. Up to 5 keys (excluding modifiers) can be held simultaneously.
|
||||
|
||||
### Parameters
|
||||
Same as `press`
|
||||
Same as `press`.
|
||||
|
||||
### Examples:
|
||||
```js
|
||||
@@ -70,9 +69,9 @@ badusb.hold("CTRL", "v"); // Press and hold CTRL + "v" combo
|
||||
Release a previously held key.
|
||||
|
||||
### Parameters
|
||||
Same as `press`
|
||||
Same as `press`.
|
||||
|
||||
Release all keys if called without parameters
|
||||
Release all keys if called without parameters.
|
||||
|
||||
### Examples:
|
||||
```js
|
||||
@@ -85,7 +84,7 @@ Print a string.
|
||||
|
||||
### Parameters
|
||||
- A string to print
|
||||
- (optional) delay between key presses
|
||||
- *(optional)* Delay between key presses
|
||||
|
||||
### Examples:
|
||||
```js
|
||||
@@ -98,7 +97,7 @@ Same as `print` but ended with "ENTER" press.
|
||||
|
||||
### Parameters
|
||||
- A string to print
|
||||
- (optional) delay between key presses
|
||||
- *(optional)* Delay between key presses
|
||||
|
||||
### Examples:
|
||||
```js
|
||||
|
77
documentation/js/js_developing_apps_using_js_sdk.md
Normal file
77
documentation/js/js_developing_apps_using_js_sdk.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Developing apps using JavaScript SDK {#js_developing_apps_using_js_sdk}
|
||||
|
||||
In the [previous guide](#js_your_first_js_app), we learned how to create and run a JavaScript app on Flipper Zero. However, when debugging a script, you often need to repeatedly modify the code and test it on the device. While you can use qFlipper for this, it involves a lot of repetitive steps. Fortunately, there's a more efficient alternative — the Flipper Zero JavaScript SDK, a set of tools that simplify app development in JavaScript.
|
||||
|
||||
Main features of the Flipper Zero JavaScript SDK:
|
||||
|
||||
* [Loading and running an app with a single command](#js_sdk_run_app)
|
||||
* [Code completion](#js_sdk_code_completion)
|
||||
* [JS code minifier (compressor)](#js_sdk_js_minifier)
|
||||
|
||||
In this guide, we'll install the JavaScript SDK and learn how to run JavaScript apps on Flipper Zero using it.
|
||||
|
||||
## How to get JavaScript SDK
|
||||
|
||||
The JavaScript SDK for Flipper Zero is distributed as an [NPM package](npmjs.com/package/\@flipperdevices/fz-sdk), so you can install it using a package manager like npm, pnpm, or yarn. You'll also need Node.js, a JavaScript runtime environment required for the NPM package manager to work.
|
||||
|
||||
> [!note]
|
||||
> In this guide, we'll use **npm**, the default package manager for Node.js.
|
||||
|
||||
Follow these steps:
|
||||
|
||||
1. Install **Node.js + npm** on your PC. Check out this [official Downloads page](https://nodejs.org/en/download/package-manager), select your OS and preferences, and run the provided commands in your terminal.
|
||||
|
||||
2. Open a terminal in the folder where you want to store your project.
|
||||
|
||||
3. Run the `npx @flipperdevices/create-fz-app@latest` command to create a JavaScript app template and include the JavaScript SDK into it. This command will launch an interactive wizard. You'll need to specify the project name and choose a package manager (in our case, **npm**).
|
||||
|
||||
You'll now find a JavaScript app template in your project folder, alongside the JavaScript SDK package, all necessary dependencies and configs. The app code will be in the `index.ts` file.
|
||||
|
||||
Now, let's take a look at the main features of the Flipper Zero JavaScript SDK.
|
||||
|
||||
## Running your app {#js_sdk_run_app}
|
||||
|
||||
To run the application:
|
||||
|
||||
1. Connect your Flipper Zero to your PC via USB.
|
||||
|
||||
2. Open a terminal in your app's folder.
|
||||
|
||||
3. Run the `npm start` command to copy the JS file to Flipper Zero and run it.
|
||||
|
||||
\image html js_sdk_npm_start.jpg width=800
|
||||
|
||||
You'll see output messages from the `print()` function in the terminal.
|
||||
|
||||
## Updating your app {#js_sdk_update_app}
|
||||
|
||||
After making changes to your app's code, simply run `npm start` again. As long as your Flipper Zero is still connected, the updated app will launch, and the old `.js` file on Flipper Zero will be replaced with the new version.
|
||||
|
||||
|
||||
## Other JavaScript SDK features
|
||||
|
||||
As you can see, it's quite easy to launch and update your app with a single command. Now let's explore two more important features of the Flipper Zero JavaScript SDK: **code completion** and **JS minifier**.
|
||||
|
||||
|
||||
### Code completion {#js_sdk_code_completion}
|
||||
|
||||
Code completion helps speed up the development process by automatically suggesting code as you type, reducing the need to refer to documentation.
|
||||
|
||||
\image html js_sdk_code_completion.jpg width=800
|
||||
|
||||
> [!note]
|
||||
> Code completion works in code editors and IDEs that support Language Server, for example, [VS Code](https://code.visualstudio.com/).
|
||||
|
||||
|
||||
### JS minifier {#js_sdk_js_minifier}
|
||||
|
||||
The JS minifier reduces the size of JavaScript files by removing unnecessary characters (like spaces, tabs and line breaks) and shortening variable names. This can make your scripts run a bit faster without changing their logic.
|
||||
|
||||
However, it has a drawback — it can make debugging harder, as error messages in minified files are harder to read in larger applications. For this reason, it's recommended to disable the JS minifier during debugging and it's disabled by default. To enable it, set the `minify` parameter to `true` in the `fz-sdk.config.json5` file in your app folder. This will minify your JavaScript app before loading it onto Flipper Zero.
|
||||
|
||||
|
||||
## What's next?
|
||||
|
||||
You've learned how to run and debug simple JavaScript apps. But how can you access Flipper Zero's hardware from your JS code? For that, you'll need to use JS modules — which we'll cover in the next guide.
|
||||
|
||||
**Next step:** [Using JavaScript modules](#js_using_js_modules)
|
@@ -1,6 +1,5 @@
|
||||
# js_event_loop {#js_event_loop}
|
||||
# Event Loop module {#js_event_loop}
|
||||
|
||||
# Event Loop module
|
||||
```js
|
||||
let eventLoop = require("event_loop");
|
||||
```
|
||||
@@ -84,7 +83,7 @@ Because we have two extra arguments, if we return anything other than an array
|
||||
of length 2, the arguments will be kept as-is for the next call.
|
||||
|
||||
The first two arguments that get passed to our callback are:
|
||||
- The subscription manager that lets us `.cancel()` our subscription
|
||||
- The subscription manager that lets us `.cancel()` our subscription.
|
||||
- The event item, used for events that have extra data. Timer events do not,
|
||||
they just produce `undefined`.
|
||||
|
||||
|
@@ -1,14 +1,12 @@
|
||||
# js_gpio {#js_gpio}
|
||||
# GPIO module {#js_gpio}
|
||||
|
||||
The module allows you to control GPIO pins of the expansion connector on Flipper Zero. Call the `require` function to load the module before first using its methods. This module depends on the `event_loop` module, so it **must** be imported after `event_loop` is imported:
|
||||
|
||||
# GPIO module
|
||||
```js
|
||||
let eventLoop = require("event_loop");
|
||||
let gpio = require("gpio");
|
||||
```
|
||||
|
||||
This module depends on the `event_loop` module, so it _must_ only be imported
|
||||
after `event_loop` is imported.
|
||||
|
||||
# Example
|
||||
```js
|
||||
let eventLoop = require("event_loop");
|
||||
@@ -31,11 +29,11 @@ Gets a `Pin` object that can be used to manage a pin.
|
||||
- `pin`: pin identifier (examples: `"pc3"`, `7`, `"pa6"`, `3`)
|
||||
|
||||
### Returns
|
||||
A `Pin` object
|
||||
A `Pin` object.
|
||||
|
||||
## `Pin` object
|
||||
### `Pin.init()`
|
||||
Configures a pin
|
||||
Configures a pin.
|
||||
|
||||
#### Parameters
|
||||
- `mode`: `Mode` object:
|
||||
@@ -49,28 +47,28 @@ Configures a pin
|
||||
- `pull` (optional): either `"up"`, `"down"` or unset
|
||||
|
||||
### `Pin.write()`
|
||||
Writes a digital value to a pin configured with `direction: "out"`
|
||||
Writes a digital value to a pin configured with `direction: "out"`.
|
||||
|
||||
#### Parameters
|
||||
- `value`: boolean logic level to write
|
||||
|
||||
### `Pin.read()`
|
||||
Reads a digital value from a pin configured with `direction: "in"` and any
|
||||
`inMode` except `"analog"`
|
||||
`inMode` except `"analog"`.
|
||||
|
||||
#### Returns
|
||||
Boolean logic level
|
||||
|
||||
### `Pin.readAnalog()`
|
||||
Reads an analog voltage level in millivolts from a pin configured with
|
||||
`direction: "in"` and `inMode: "analog"`
|
||||
`direction: "in"` and `inMode: "analog"`.
|
||||
|
||||
#### Returns
|
||||
Voltage on pin in millivolts
|
||||
Voltage on pin in millivolts.
|
||||
|
||||
### `Pin.interrupt()`
|
||||
Attaches an interrupt to a pin configured with `direction: "in"` and
|
||||
`inMode: "interrupt"` or `"event"`
|
||||
`inMode: "interrupt"` or `"event"`.
|
||||
|
||||
#### Returns
|
||||
An event loop `Contract` object that identifies the interrupt event source. The
|
||||
|
@@ -1,13 +1,22 @@
|
||||
# js_gui {#js_gui}
|
||||
# GUI module {#js_gui}
|
||||
|
||||
The module allows you to use GUI (graphical user interface) in concepts off the Flipper Zero firmware. Call the `require` function to load the module before first using its methods. This module depends on the `event_loop` module, so it **must** be imported after the `event_loop` import:
|
||||
|
||||
# GUI module
|
||||
```js
|
||||
let eventLoop = require("event_loop");
|
||||
let gui = require("gui");
|
||||
```
|
||||
## Submodules
|
||||
|
||||
This module depends on the `event_loop` module, so it _must_ only be imported
|
||||
after `event_loop` is imported.
|
||||
GUI module has several submodules:
|
||||
|
||||
- @subpage js_gui__submenu — Displays a scrollable list of clickable textual entries
|
||||
- @subpage js_gui__loading — Displays an animated hourglass icon
|
||||
- @subpage js_gui__empty_screen — Just empty screen
|
||||
- @subpage js_gui__text_input — Keyboard-like text input
|
||||
- @subpage js_gui__text_box — Simple multiline text box
|
||||
- @subpage js_gui__dialog — Dialog with up to 3 options
|
||||
- @subpage js_gui__widget — Displays a combination of custom elements on one screen
|
||||
|
||||
## Conceptualizing GUI
|
||||
### Event loop
|
||||
@@ -27,23 +36,23 @@ always access the canvas through a viewport.
|
||||
In Flipper's terminology, a "View" is a fullscreen design element that assumes
|
||||
control over the entire viewport and all input events. Different types of views
|
||||
are available (not all of which are unfortunately currently implemented in JS):
|
||||
| View | Has JS adapter? |
|
||||
|----------------------|-----------------------|
|
||||
| `button_menu` | ❌ |
|
||||
| `button_panel` | ❌ |
|
||||
| `byte_input` | ✅ |
|
||||
| `dialog_ex` | ✅ (as `dialog`) |
|
||||
| `empty_screen` | ✅ |
|
||||
| `file_browser` | ✅ (as `file_picker`) |
|
||||
| `loading` | ✅ |
|
||||
| `menu` | ❌ |
|
||||
| `number_input` | ❌ |
|
||||
| `popup` | ❌ |
|
||||
| `submenu` | ✅ |
|
||||
| `text_box` | ✅ |
|
||||
| `text_input` | ✅ |
|
||||
| `variable_item_list` | ❌ |
|
||||
| `widget` | ✅ |
|
||||
| View | Has JS adapter? |
|
||||
|----------------------|------------------|
|
||||
| `button_menu` | ❌ |
|
||||
| `button_panel` | ❌ |
|
||||
| `byte_input` | ❌ |
|
||||
| `dialog_ex` | ✅ (as `dialog`) |
|
||||
| `empty_screen` | ✅ |
|
||||
| `file_browser` | ❌ |
|
||||
| `loading` | ✅ |
|
||||
| `menu` | ❌ |
|
||||
| `number_input` | ❌ |
|
||||
| `popup` | ❌ |
|
||||
| `submenu` | ✅ |
|
||||
| `text_box` | ✅ |
|
||||
| `text_input` | ✅ |
|
||||
| `variable_item_list` | ❌ |
|
||||
| `widget` | ❌ |
|
||||
|
||||
In JS, each view has its own set of properties (or just "props"). The programmer
|
||||
can manipulate these properties in two ways:
|
||||
@@ -119,7 +128,7 @@ eventLoop.run();
|
||||
The `viewDispatcher` constant holds the `ViewDispatcher` singleton.
|
||||
|
||||
### `viewDispatcher.switchTo(view)`
|
||||
Switches to a view, giving it control over the display and input
|
||||
Switches to a view, giving it control over the display and input.
|
||||
|
||||
#### Parameters
|
||||
- `view`: the `View` to switch to
|
||||
@@ -127,24 +136,24 @@ Switches to a view, giving it control over the display and input
|
||||
### `viewDispatcher.sendTo(direction)`
|
||||
Sends the viewport that the dispatcher manages to the front of the stackup
|
||||
(effectively making it visible), or to the back (effectively making it
|
||||
invisible)
|
||||
invisible).
|
||||
|
||||
#### Parameters
|
||||
- `direction`: either `"front"` or `"back"`
|
||||
|
||||
### `viewDispatcher.sendCustom(event)`
|
||||
Sends a custom number to the `custom` event handler
|
||||
Sends a custom number to the `custom` event handler.
|
||||
|
||||
#### Parameters
|
||||
- `event`: number to send
|
||||
|
||||
### `viewDispatcher.custom`
|
||||
An event loop `Contract` object that identifies the custom event source,
|
||||
triggered by `ViewDispatcher.sendCustom(event)`
|
||||
triggered by `ViewDispatcher.sendCustom(event)`.
|
||||
|
||||
### `viewDispatcher.navigation`
|
||||
An event loop `Contract` object that identifies the navigation event source,
|
||||
triggered when the back key is pressed
|
||||
triggered when the back key is pressed.
|
||||
|
||||
## `ViewFactory`
|
||||
When you import a module implementing a view, a `ViewFactory` is instantiated.
|
||||
@@ -152,10 +161,10 @@ For example, in the example above, `loadingView`, `submenuView` and `emptyView`
|
||||
are view factories.
|
||||
|
||||
### `ViewFactory.make()`
|
||||
Creates an instance of a `View`
|
||||
Creates an instance of a `View`.
|
||||
|
||||
### `ViewFactory.make(props)`
|
||||
Creates an instance of a `View` and assigns initial properties from `props`
|
||||
Creates an instance of a `View` and assigns initial properties from `props`.
|
||||
|
||||
#### Parameters
|
||||
- `props`: simple key-value object, e.g. `{ header: "Header" }`
|
||||
|
@@ -1,6 +1,5 @@
|
||||
# js_gui__dialog {#js_gui__dialog}
|
||||
# Dialog GUI view {#js_gui__dialog}
|
||||
|
||||
# Dialog GUI view
|
||||
Displays a dialog with up to three options.
|
||||
|
||||
<img src="dialog.png" width="200" alt="Sample screenshot of the view" />
|
||||
@@ -16,16 +15,16 @@ This module depends on the `gui` module, which in turn depends on the
|
||||
recommended to conceptualize these modules first before using this one.
|
||||
|
||||
# Example
|
||||
For an example refer to the `gui.js` example script.
|
||||
For an example, refer to the `gui.js` example script.
|
||||
|
||||
# View props
|
||||
## `header`
|
||||
Text that appears in bold at the top of the screen
|
||||
Text that appears in bold at the top of the screen.
|
||||
|
||||
Type: `string`
|
||||
|
||||
## `text`
|
||||
Text that appears in the middle of the screen
|
||||
Text that appears in the middle of the screen.
|
||||
|
||||
Type: `string`
|
||||
|
||||
|
@@ -1,7 +1,6 @@
|
||||
# js_gui__empty_screen {#js_gui__empty_screen}
|
||||
# Empty Screen GUI view {#js_gui__empty_screen}
|
||||
|
||||
# Empty Screen GUI View
|
||||
Displays nothing.
|
||||
Displays an empty screen.
|
||||
|
||||
<img src="empty.png" width="200" alt="Sample screenshot of the view" />
|
||||
|
||||
@@ -16,7 +15,7 @@ This module depends on the `gui` module, which in turn depends on the
|
||||
recommended to conceptualize these modules first before using this one.
|
||||
|
||||
# Example
|
||||
For an example refer to the GUI example.
|
||||
For an example, refer to the GUI example.
|
||||
|
||||
# View props
|
||||
This view does not have any props.
|
||||
|
@@ -1,8 +1,6 @@
|
||||
# js_gui__loading {#js_gui__loading}
|
||||
# Loading GUI view {#js_gui__loading}
|
||||
|
||||
# Loading GUI View
|
||||
Displays an animated hourglass icon. Suppresses all `navigation` events, making
|
||||
it impossible for the user to exit the view by pressing the back key.
|
||||
Displays an animated hourglass icon. Suppresses all `navigation` events, making it impossible for the user to exit the view by pressing the BACK key.
|
||||
|
||||
<img src="loading.png" width="200" alt="Sample screenshot of the view" />
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
# js_gui__submenu {#js_gui__submenu}
|
||||
# Submenu GUI view {#js_gui__submenu}
|
||||
|
||||
# Submenu GUI view
|
||||
Displays a scrollable list of clickable textual entries.
|
||||
|
||||
<img src="submenu.png" width="200" alt="Sample screenshot of the view" />
|
||||
@@ -16,16 +15,16 @@ This module depends on the `gui` module, which in turn depends on the
|
||||
recommended to conceptualize these modules first before using this one.
|
||||
|
||||
# Example
|
||||
For an example refer to the GUI example.
|
||||
For an example, refer to the GUI example.
|
||||
|
||||
# View props
|
||||
## `header`
|
||||
Single line of text that appears above the list
|
||||
A single line of text that appears above the list.
|
||||
|
||||
Type: `string`
|
||||
|
||||
## `items`
|
||||
The list of options
|
||||
The list of options.
|
||||
|
||||
Type: `string[]`
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
# js_gui__text_box {#js_gui__text_box}
|
||||
# Text box GUI view {#js_gui__text_box}
|
||||
|
||||
# Text box GUI view
|
||||
Displays a scrollable read-only text field.
|
||||
|
||||
<img src="text_box.png" width="200" alt="Sample screenshot of the view" />
|
||||
@@ -16,7 +15,7 @@ This module depends on the `gui` module, which in turn depends on the
|
||||
recommended to conceptualize these modules first before using this one.
|
||||
|
||||
# Example
|
||||
For an example refer to the `gui.js` example script.
|
||||
For an example, refer to the `gui.js` example script.
|
||||
|
||||
# View props
|
||||
## `text`
|
||||
|
@@ -1,6 +1,5 @@
|
||||
# js_gui__text_input {#js_gui__text_input}
|
||||
# Text input GUI view {#js_gui__text_input}
|
||||
|
||||
# Text input GUI view
|
||||
Displays a keyboard.
|
||||
|
||||
<img src="text_input.png" width="200" alt="Sample screenshot of the view" />
|
||||
@@ -16,29 +15,29 @@ This module depends on the `gui` module, which in turn depends on the
|
||||
recommended to conceptualize these modules first before using this one.
|
||||
|
||||
# Example
|
||||
For an example refer to the `gui.js` example script.
|
||||
For an example, refer to the `gui.js` example script.
|
||||
|
||||
# View props
|
||||
## `minLength`
|
||||
Smallest allowed text length
|
||||
The shortest allowed text length.
|
||||
|
||||
Type: `number`
|
||||
|
||||
## `maxLength`
|
||||
Biggest allowed text length
|
||||
The longest allowed text length.
|
||||
|
||||
Type: `number`
|
||||
|
||||
Default: `32`
|
||||
|
||||
## `header`
|
||||
Single line of text that appears above the keyboard
|
||||
A single line of text that appears above the keyboard.
|
||||
|
||||
Type: `string`
|
||||
|
||||
# View events
|
||||
## `input`
|
||||
Fires when the user selects the "save" button and the text matches the length
|
||||
Fires when the user selects the "Save" button and the text matches the length
|
||||
constrained by `minLength` and `maxLength`.
|
||||
|
||||
Item type: `string`
|
||||
|
@@ -1,7 +1,6 @@
|
||||
# js_gui__widget {#js_gui__widget}
|
||||
# Widget GUI view {#js_gui__widget}
|
||||
|
||||
# Widget GUI view
|
||||
Displays a combination of custom elements on one screen
|
||||
Displays a combination of custom elements on one screen.
|
||||
|
||||
<img src="widget.png" width="200" alt="Sample screenshot of the view" />
|
||||
|
||||
@@ -16,7 +15,7 @@ This module depends on the `gui` module, which in turn depends on the
|
||||
recommended to conceptualize these modules first before using this one.
|
||||
|
||||
# Example
|
||||
For an example refer to the `gui.js` example script.
|
||||
For an example, refer to the `gui.js` example script.
|
||||
|
||||
# View props
|
||||
This view does not have any props.
|
||||
|
@@ -1,6 +1,7 @@
|
||||
# js_math {#js_math}
|
||||
# Math module {#js_math}
|
||||
|
||||
The module contains mathematical methods and constants. Call the `require` function to load the module before first using its methods:
|
||||
|
||||
# Math module
|
||||
```js
|
||||
let math = require("math");
|
||||
```
|
||||
|
@@ -1,13 +1,12 @@
|
||||
# js_notification {#js_notification}
|
||||
# Notification module {#js_notification}
|
||||
|
||||
# Notification module
|
||||
```js
|
||||
let notify = require("notification");
|
||||
```
|
||||
# Methods
|
||||
|
||||
## success
|
||||
"Success" flipper notification message
|
||||
"Success" flipper notification message.
|
||||
|
||||
### Examples:
|
||||
```js
|
||||
@@ -15,7 +14,7 @@ notify.success();
|
||||
```
|
||||
|
||||
## error
|
||||
"Error" flipper notification message
|
||||
"Error" flipper notification message.
|
||||
|
||||
### Examples:
|
||||
```js
|
||||
@@ -23,7 +22,7 @@ notify.error();
|
||||
```
|
||||
|
||||
## blink
|
||||
Blink notification LED
|
||||
Blink notification LED.
|
||||
|
||||
### Parameters
|
||||
- Blink color (blue/red/green/yellow/cyan/magenta)
|
||||
|
@@ -1,6 +1,5 @@
|
||||
# js_serial {#js_serial}
|
||||
# Serial module {#js_serial}
|
||||
|
||||
# Serial module
|
||||
```js
|
||||
let serial = require("serial");
|
||||
```
|
||||
@@ -20,7 +19,7 @@ serial.setup("lpuart", 115200);
|
||||
```
|
||||
|
||||
## write
|
||||
Write data to serial port
|
||||
Write data to serial port.
|
||||
|
||||
### Parameters
|
||||
One or more arguments of the following types:
|
||||
@@ -41,7 +40,7 @@ Read a fixed number of characters from serial port.
|
||||
|
||||
### Parameters
|
||||
- Number of bytes to read
|
||||
- (optional) Timeout value in ms
|
||||
- *(optional)* Timeout value in ms
|
||||
|
||||
### Returns
|
||||
A sting of received characters or undefined if nothing was received before timeout.
|
||||
@@ -53,10 +52,10 @@ serial.read(10, 5000); // Read 10 bytes, with 5s timeout
|
||||
```
|
||||
|
||||
## readln
|
||||
Read from serial port until line break character
|
||||
Read from serial port until line break character.
|
||||
|
||||
### Parameters
|
||||
(optional) Timeout value in ms
|
||||
*(optional)* Timeout value in ms.
|
||||
|
||||
### Returns
|
||||
A sting of received characters or undefined if nothing was received before timeout.
|
||||
@@ -68,11 +67,11 @@ serial.readln(5000); // Read with 5s timeout
|
||||
```
|
||||
|
||||
## readBytes
|
||||
Read from serial port until line break character
|
||||
Read from serial port until line break character.
|
||||
|
||||
### Parameters
|
||||
- Number of bytes to read
|
||||
- (optional) Timeout value in ms
|
||||
- *(optional)* Timeout value in ms
|
||||
|
||||
### Returns
|
||||
ArrayBuffer with received data or undefined if nothing was received before timeout.
|
||||
@@ -86,13 +85,13 @@ serial.readBytes(1, 0);
|
||||
```
|
||||
|
||||
## expect
|
||||
Search for a string pattern in received data stream
|
||||
Search for a string pattern in received data stream.
|
||||
|
||||
### Parameters
|
||||
- Single argument or array of the following types:
|
||||
- A string
|
||||
- Array of numbers, each number is interpreted as a byte
|
||||
- (optional) Timeout value in ms
|
||||
- *(optional)* Timeout value in ms
|
||||
|
||||
### Returns
|
||||
Index of matched pattern in input patterns list, undefined if nothing was found.
|
||||
|
42
documentation/js/js_using_js_modules.md
Normal file
42
documentation/js/js_using_js_modules.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Using JavaScript modules {#js_using_js_modules}
|
||||
|
||||
In the previous guides, we learned how to write a basic JavaScript app using [built-in functions](#js_builtin). However, the set of built-in functions is limited, so when developing your JS apps, you'll likely want to use external JS modules. These modules offer a wide range of functions (methods) for various tasks.
|
||||
|
||||
For example:
|
||||
* The `serial` module enables transmitting and receiving data via a serial interface
|
||||
* The `badusb` module enables USB keyboard emulation and sending key press events via USB
|
||||
* The `math` module provides mathematical functions
|
||||
|
||||
JS modules are written in C/C++, making them fast and efficient. They come with Flipper Zero firmware and are stored on the microSD card in compiled form as **FAL (Flipper Application File)** files.
|
||||
|
||||
> [!note]
|
||||
> You can find the implementation of all supported JS modules in the [Flipper Zero firmware repository](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/system/js_app/modules). Also, check out the [docs for JS modules](#js_modules) for more details.
|
||||
|
||||
## How to use JS modules in your app
|
||||
|
||||
Before using any of the JS module methods, you **must** import the module using the `require()` function. This loads the module into RAM, allowing you to access its methods.
|
||||
|
||||
To save RAM and improve performance, avoid loading modules you don't plan to use. Also, all loaded modules will be automatically unloaded from RAM after the app execution ends.
|
||||
|
||||
To load a module, call the `require()` function with the module name in quotes. For example, to load the `notification` module, write this:
|
||||
|
||||
\code{.js}
|
||||
let notify = require("notification");
|
||||
\endcode
|
||||
|
||||
Now you can call methods of the `notification` module using the `notify` variable to access them:
|
||||
|
||||
\code{.js}
|
||||
let notify = require("notification");
|
||||
|
||||
notify.success();
|
||||
print("success notification");
|
||||
\endcode
|
||||
|
||||
## What's next?
|
||||
|
||||
Congratulations, you've completed the **Getting Started** section of our JS docs. You've learned how to run and debug JS apps, and how to use JS modules. Now, we invite you to check out the [main JavaScript page](#js) where you'll find:
|
||||
|
||||
* JavaScript app examples
|
||||
* Documentation on JS modules
|
||||
* Additional resources related to JavaScript on Flipper Zero
|
83
documentation/js/js_your_first_js_app.md
Normal file
83
documentation/js/js_your_first_js_app.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Your first JavaScript app {#js_your_first_js_app}
|
||||
|
||||
In this guide, we'll create a simple script that outputs ordinal numbers with a delay and learn how to run it on Flipper Zero in different ways. All you need is your Flipper Zero, a PC, and a USB cable.
|
||||
|
||||
## Step 1. Create the script file
|
||||
|
||||
Create a new text file `first_app.js`. Paste the code below into it and save the file:
|
||||
|
||||
\code{.js}
|
||||
print("start");
|
||||
delay(1000);
|
||||
print("1");
|
||||
delay(500);
|
||||
print("2");
|
||||
delay(500);
|
||||
print("3");
|
||||
delay(500);
|
||||
print("end");
|
||||
\endcode
|
||||
|
||||
What the code does:
|
||||
* Outputs the text **start**, waits 1 second
|
||||
* Outputs the numbers **1**, **2** and **3**, with a 0.5-second pause after each number
|
||||
* Outputs the text **end**
|
||||
|
||||
The `print()` function is used to output text. The string to be output is in the brackets. This is a built-in function, so you don't need to include additional JS modules. You can use this function anywhere in your application.
|
||||
|
||||
Another built-in function, `delay()`, implements delay. The delay time in milliseconds is given in the brackets. Since 1000 milliseconds equals 1 second, a 1-second delay is written as 1000, and a 0.5-second delay as 500.
|
||||
|
||||
> [!note]
|
||||
> Find the list of built-in functions in [Built-in functions](#js_builtin).
|
||||
|
||||
## Step 2. Copy the file to Flipper Zero
|
||||
|
||||
To copy the JavaScript file to Flipper Zero, follow these steps:
|
||||
1. Connect your Flipper Zero to your PC via USB.
|
||||
2. Open the **qFlipper** application.
|
||||
3. Go to the **File manager** tab and open the path `SD Card/apps/Scripts/`.
|
||||
4. Drag and drop the file into the qFlipper window.
|
||||
|
||||
> [!note]
|
||||
> To learn more about qFlipper, visit the [dedicated section in our user documentation](https://docs.flipper.net/qflipper).
|
||||
|
||||
Your script is now ready to run on Flipper Zero.
|
||||
|
||||
## Step 3. Run your script
|
||||
|
||||
You can launch your app in two ways:
|
||||
|
||||
* From the Flipper Zero menu
|
||||
* Remotely from your PC using the CLI (command-line interface)
|
||||
|
||||
Let's explore them both.
|
||||
|
||||
### How to run a script from Flipper Zero's menu
|
||||
|
||||
1. Go to **Apps → Scripts** in your Flipper Zero's menu. Here, you'll see a list of scripts located in the `SD Card/apps/Scripts/` folder.
|
||||
2. Select the script you want to run.
|
||||
3. Press the **OK** button to run the script.
|
||||
|
||||
\image html js_first_app_on_fz.jpg width=500
|
||||
|
||||
The Flipper Zero screen will display the strings with the specified delay, as defined by the `print()` and `delay()` functions.
|
||||
|
||||
### How to run script using CLI
|
||||
|
||||
The command-line interface (CLI) is a text-based interface that lets you control your Flipper Zero from your computer, including running scripts. Running JavaScript apps via CLI is useful for debugging, as it lets you write and test code remotely, without switching between your PC and the device.
|
||||
|
||||
To run the script via CLI:
|
||||
|
||||
1. Connect your Flipper Zero to your PC via USB.
|
||||
2. Access the CLI using one of the [recommended methods](https://docs.flipper.net/development/cli#HfXTy).
|
||||
3. Enter the `js path` command, replacing `path` with the path to the script file on your Flipper Zero:
|
||||
|
||||
\code{.sh}
|
||||
js /ext/apps/Scripts/first_app.js
|
||||
\endcode
|
||||
|
||||
\image html js_first_app_on_cli.jpg width=700
|
||||
|
||||
As you can see, unlike running JavaScript apps from the Flipper Zero UI, all output from the `print()` function is sent to the CLI, not the device screen.
|
||||
|
||||
**Next step:** [Developing apps using JavaScript SDK](#js_developing_apps_using_js_sdk)
|
Reference in New Issue
Block a user