-
Notifications
You must be signed in to change notification settings - Fork 69
JavaScript
The latest version of firmware now supports running JavaScript applications, using mjs. This version of JavaScript has some restrictions. Scripts are typically saved to the SD Card/apps/Scripts
folder. You launch JS files by starting at the Main Menu on the Flipper Zero and selecting Apps
/Scripts
/name.js file.
This page is comparing the dev
branch of the various firmware, since that is where the updates are happening. If you are on a release
branch, some of the features listed here may not yet have been ported over to your firmware.
Just like JavaScript in the browser, Flipper JS has different levels of support depending on which firmware you are running on. 😭 The implemented modules vary by firmware, so check your firmware's applications/system/js_app/modules folder to see what features are supported.
The most common JavaScript pattern seems to be:
- Use badusb to connect the keyboard to computer
- Press
Windows
+R
and type powershell - Runs the following badusb script (which starts executing after the entire script is entered):
- tell user to close window when window closes
- sleep 10 seconds
- figure out "Flipper Mass Storage" drive
- run commands (sometimes from USB drive, sometimes locally)
- copy output to USB drive
- delete MRU and history
- close window
- Attach USB drive
- Wait for USB drive to be ejected
- Stop USB drive
The most common request seems to be:
- badusb.print and badusb.println only support US keyboard layout. If you have a different layout, likely badusb scripts will have invalid characters, like
"
and|
will get replaced by different symbols. altPrint and altPrintln may be able to avoid some of these issues; however windows like PowerShell often require thatNumLock
is turned on (or else they ignore the input). Other windows like Notepad will accept the alt codes regardless of theNumLock
state. To successfully type in PowerShell you would have to do abadusb.press("NUMLOCK"); altPrint(str); badusb.press("NUMLOCK"); altPrint(str); badusb.press("ENTER");
to ensure that the content was typed.
As of 4/20/2024 the supported modules are as follows:
Feature | Description | OFW (Official) | Momentum | Unleashed | RogueMaster | Xtreme |
---|---|---|---|---|---|---|
console | Console object for logging | |||||
delay | Waits num milliseconds | |||||
ffi_address | Foreign Function Interface (FFI) address | |||||
parse_int | String to number | not implemented | ||||
Print message on screen and logs | ||||||
require | Import module | |||||
to_string | Number to string | |||||
to_hex_string | Number to hex string | |||||
to_lower_case | Convert string to lowercase | not implemented | ||||
to_upper_case | Convert string to uppercase | not implemented | ||||
__filepath | Path of script | not implemented | ||||
__dirpath | Path of script directory | not implemented |
The delay
function delays for the specified number of milliseconds before continuing to the next statement.
delay(100); // wait 100 milliseconds
The ffi_address
function converts a method signature into an address? No examples use this method directly.
The parse_int
function converts a string into number.
let str = "42";
let num = parse_int(str); // num will be a number with a value of 42
The print
function displays text on the screen and also in the logs.
The function allows passing multiple parameters of various types.
print("hello");
print(42);
let answer=true;
print("got",answer);
The require
function loads a module. If the module is unknown it will throw an error.
The parameter is the name of the module.
let badusb = require("badusb");
The to_string
function will convert a number into a string.
The parameter is a number.
let num = 42;
let str = to_string(num); // str is the string "42".
The to_hex_string
function will convert a number into a hex string.
The parameter is a number.
let num = 1337;
let str = to_hex_string(num); // str is the string "539" (because 1337 decimal is 0x539).
The to_lower_case
function converts a string to lowercase.
The parameter is the string to convert.
let str = "Hello World";
print(to_lower_case(str)); // prints: hello world
The to_upper_case
function converts a string to uppercase.
The parameter is the string to convert.
let str = "Hello World";
print(to_upper_case(str)); // prints: HELLO WORLD
The __filepath
is the path to the JS file that is being run.
print("This JS file is",__filepath);
The __dirpath
is the folder where the JS file is being run from.
let otherFile = __dirpath + "/demo.img"; // path to another file in the same folder as our script.
print(otherFile);
As of 4/20/2024 the supported modules are as follows:
Feature | Description | OFW (Official) | Momentum | Unleashed | RogueMaster | Xtreme |
---|---|---|---|---|---|---|
badusb | Send keystrokes as hid | missing: quit, altPrint, altPrintln, num0-num9 | missing: layout_path parameter in setup | |||
blebeacon | Send BLE events | not implemented | ||||
dialog | Show dialog, select File | missing: pickFile | ||||
flipper | Device info | |||||
gpio | Input/Output hardware pins | not implemented | ||||
keyboard | Text and Byte input | not implemented | missing feature: add_illegal_symbols | missing feature: add_illegal_symbols | missing feature: add_illegal_symbols | |
math | Math functions | not implemented | ||||
notification | LED sequences | |||||
serial | Serial port | missing: end, readAny | ||||
storage | Flipper SD Card files | not implemented | not implemented | missing: append | ||
subghz | Sub-GHz Radio | not implemented | ||||
submenu | Submenu | not implemented | ||||
textbox | Textbox | not implemented | ||||
usbdisk | USB disk images | not implemented | ||||
widget | UI drawing | not implemented | missing: addIcon | missing: addIcon | missing: addIcon) |
let badusb = require("badusb");
badusb is used to simulate an HID (Human Interface Device), like a USB keyboard, sending various keystrokes to the attached computer.
-
setup
({ vid: number, pid: number, mfr_name: string, prod_name: string, layout: string }): undefined | error
-
quit
(): undefined | error
-
isConnected
(): bool | error
-
press
(...keyAndModifiers: string | number): undefined | error
-
hold
(...keyAndModifiers: string | number): undefined | error
-
release
(...keyAndModifiers: string | number | undefined): undefined | error
-
print
(text: string, delay: number | undefined): undefined | error
-
println
(text: string, delay: number | undefined): undefined | error
-
altPrint
(text: string, delay: number | undefined): undefined | error
-
altPrintln
(text: string, delay: number | undefined): undefined | error
The setup
function takes an configuration object with the vendor id (vid
), the product id (pid
), the manufacturer name (mfr_name
) and the product name (prod_name
). This function will change the USB port from the typical Flipper port into a device with the specified vid/pid, acting as a USB keyboard. When you are done using the bad usb, you should call quit. You cannot call this method a second time without first calling quit
. The layout parameter (layout
) should be a fully qualified path to a .kl
keyboard layout.
badusb.setup({ vid: 0xAAAA, pid: 0xBBBB, mfr_name: "Flipper", prod_name: "Zero", layout: "/ext/badusb/assets/layouts/en-US.kl" });
The quit
function will change the USB port back to the typical Flipper port. This will also happen when the script exits.
badusb.quit();
The isConnected
function will return true if the Flipper Zero is connected to a computer.
let connected = badusb.isConnected();
The press
function will press and release a key combination. See badusb keys for the list of additional supported key names.
badusb.press("CTRL", "c");
The hold
function will hold down a key combination. Use release to release the keys. See badusb keys for the list of additional supported key names.
badusb.hold("ENTER");
delay(2000);
badusb.release("ENTER");
The release
function will release a key combination that was pressed with hold. See badusb keys for the list of additional supported key names.
badusb.hold("ENTER");
delay(2000);
badusb.release("ENTER");
The print
function will type the string specified. It takes an optional 2nd parameter with a delay in milliseconds (up to 60 seconds) to wait before returning to the caller.
badusb.print("Hello", 1000); // Wait 1 second before typing next part...
badusb.print(" world!");
The println
function will type the string specified and then press Enter. It takes an optional 2nd parameter with a delay in milliseconds (up to 60 seconds) to wait before returning to the caller.
badusb.println("Hello", 1000); // Wait 1 second before typing next part...
badusb.println("world!");
The altPrint
function will type the string specified using the numeric keypad. It takes an optional 2nd parameter with a delay in milliseconds (up to 60 seconds) to wait before returning to the caller.
badusb.altPrint("Hello", 1000); // Wait 1 second before typing next part...
badusb.alpPrint(" world!");
The altPrintln
function will type the string specified using the numeric keypad and then press Enter. It takes an optional 2nd parameter with a delay in milliseconds (up to 60 seconds) to wait before returning to the caller.
badusb.altPrintln("Hello", 1000); // Wait 1 second before typing next part...
badusb.altPrintln("world!");
{"CTRL", KEY_MOD_LEFT_CTRL},
{"SHIFT", KEY_MOD_LEFT_SHIFT},
{"ALT", KEY_MOD_LEFT_ALT},
{"GUI", KEY_MOD_LEFT_GUI},
{"DOWN", HID_KEYBOARD_DOWN_ARROW},
{"LEFT", HID_KEYBOARD_LEFT_ARROW},
{"RIGHT", HID_KEYBOARD_RIGHT_ARROW},
{"UP", HID_KEYBOARD_UP_ARROW},
{"ENTER", HID_KEYBOARD_RETURN},
{"PAUSE", HID_KEYBOARD_PAUSE},
{"CAPSLOCK", HID_KEYBOARD_CAPS_LOCK},
{"DELETE", HID_KEYBOARD_DELETE_FORWARD},
{"BACKSPACE", HID_KEYBOARD_DELETE},
{"END", HID_KEYBOARD_END},
{"ESC", HID_KEYBOARD_ESCAPE},
{"HOME", HID_KEYBOARD_HOME},
{"INSERT", HID_KEYBOARD_INSERT},
{"NUMLOCK", HID_KEYPAD_NUMLOCK},
{"PAGEUP", HID_KEYBOARD_PAGE_UP},
{"PAGEDOWN", HID_KEYBOARD_PAGE_DOWN},
{"PRINTSCREEN", HID_KEYBOARD_PRINT_SCREEN},
{"SCROLLLOCK", HID_KEYBOARD_SCROLL_LOCK},
{"SPACE", HID_KEYBOARD_SPACEBAR},
{"TAB", HID_KEYBOARD_TAB},
{"MENU", HID_KEYBOARD_APPLICATION},
{"F1", HID_KEYBOARD_F1},
{"F2", HID_KEYBOARD_F2},
{"F3", HID_KEYBOARD_F3},
{"F4", HID_KEYBOARD_F4},
{"F5", HID_KEYBOARD_F5},
{"F6", HID_KEYBOARD_F6},
{"F7", HID_KEYBOARD_F7},
{"F8", HID_KEYBOARD_F8},
{"F9", HID_KEYBOARD_F9},
{"F10", HID_KEYBOARD_F10},
{"F11", HID_KEYBOARD_F11},
{"F12", HID_KEYBOARD_F12},
{"F13", HID_KEYBOARD_F13},
{"F14", HID_KEYBOARD_F14},
{"F15", HID_KEYBOARD_F15},
{"F16", HID_KEYBOARD_F16},
{"F17", HID_KEYBOARD_F17},
{"F18", HID_KEYBOARD_F18},
{"F19", HID_KEYBOARD_F19},
{"F20", HID_KEYBOARD_F20},
{"F21", HID_KEYBOARD_F21},
{"F22", HID_KEYBOARD_F22},
{"F23", HID_KEYBOARD_F23},
{"F24", HID_KEYBOARD_F24},
{"NUM0", HID_KEYPAD_0}, // Not in OFW as of 3/26/2024
{"NUM1", HID_KEYPAD_1}, // Not in OFW as of 3/26/2024
{"NUM2", HID_KEYPAD_2}, // Not in OFW as of 3/26/2024
{"NUM3", HID_KEYPAD_3}, // Not in OFW as of 3/26/2024
{"NUM4", HID_KEYPAD_4}, // Not in OFW as of 3/26/2024
{"NUM5", HID_KEYPAD_5}, // Not in OFW as of 3/26/2024
{"NUM6", HID_KEYPAD_6}, // Not in OFW as of 3/26/2024
{"NUM7", HID_KEYPAD_7}, // Not in OFW as of 3/26/2024
{"NUM8", HID_KEYPAD_8}, // Not in OFW as of 3/26/2024
{"NUM9", HID_KEYPAD_9}, // Not in OFW as of 3/26/2024
let blebeacon = require("blebeacon");
blebeacon is used to send BLE (Bluetooth Low Energy) beacon messages.
-
isActive
(): bool | error
-
setConfig
(mac: Uint8Array, power: number | undefined, intvMin: number | undefined, intvMax: number | undefined): undefined | error
-
setData
(data: Uint8Array): undefined | error
-
start
(): undefined | error
-
stop
(): undefined | error
-
keepAlive
(keep: boolean): undefined | error
The isActive
function returns true
if a BLE beacon is currently running, otherwise it returns false
. You can call stop to stop the running beacon.
let bool_active = blebeacon.isActive();
Pass a true
to the keepAlive
function if you want the BLE beacon to continue running when your script exits. The default configuration is false
, which will stop sending the BLE beacon when the script exits.
blebeacon.keepAlive(false);
The setConfig
function sets the mac address for the BLE beacon. You can optionally specify the power level, min time (milliseconds) and max time (milliseconds) parameters.
let mac = Uint8Array([0x42,0x42,0x42,0x42,0x42,0x42]);
blebeacon.setConfig(mac, 0x1F, 50, 150); // power level: 0x1F, minTime: 50ms, maxTime: 150ms
The setData
function sets the data for the BLE beacon.
let packet = [14, 0xFF, 0x75, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, 0xFF, 0x00, 0x00, 0x43, 0x05];
blebeacon.setData(Uint8Array(packet));
The start
function will start sending BLE beacons. You should call setConfig and setData before calling start.
blebeacon.start();
The stop
function will stop sending a BLE beacon if it is currently running. If it is already stopped, the function call will be ignored.
blebeacon.stop();
let dialog = require("dialog");
dialog is used to show a message (with Left/Center/Right options) or allow user to select a file.
-
message
({ header: string, text: string, button_left: string | undefined, button_center: string | undefined, button_right: string | undefined }): string | error
-
custom
(header: string, text: string): boolean | error
-
pickFile
(path: string, ext: string): string | error
The custom
function will display a dialog with header, text, and LCR button choices. If back is pressed it will return empty string. You can set a button to undefined
if you do not want it to be selectable.
let dialog_params = ({
header: "Test header",
text: "Test text",
button_left: "Left",
button_right: "Right",
button_center: "OK"
});
let result = dialog.custom(dialog_params);
// Check result
if (result === "") { print("Back pressed."); }
else if (result === dialog_params.button_left) { print("Left pressed."); }
else if (result === dialog_params.button_right) { print("Right pressed."); }
else if (result === dialog_params.button_center) { print("OK pressed."); }
The message
function will display a dialog with header, text, and OK button. If back is pressed it will return false, otherwise true.
let result = dialog.message("Dialog header", "Press OK button");
if (result) { print("OK pressed.); } else { print("Back pressed."); }
The pickFile
function will prompt the user to select a file. The first parameter is the directory to start in. The second parameter is the file extension.
let result = dialog.pickFile("/ext/subghz", ".sub"); // Use "*" for second parameter to allow all files.
print("File path:"+result);
let flipper = require("flipper");
flipper is used to access information about the Flipper Zero device.
-
getModel
() : string
-
getName
() : string
-
getBatteryCharge
() : number
The getModel
function will return the model of the device (like "flipper Zero")
let result = flipper.getModel();
print("Model:"+result); // prints "Model: flipper Zero"
The getName
function will return the unique name of this Flipper.
let result = flipper.getName();
print("Name:"+result); // prints "Name: Rim"
The getBatteryCharge
function will return the current battery level of this Flipper.
let result = flipper.getBatteryCharge();
print("Battery:"+result); // prints "Battery: 98"
let gpio = require("gpio");
gpio is used to access the General Purpose Input/Output (GPIO) pins of the Flipper Zero.
-
init
(pin: string, mode: string, pull: string) : undefined | error
-
read
(pin: string) : boolean | error
-
write
(pin: string, data: boolean) : undefined | error
The init
function configures the pin for the specified mode.
The first parameter is the name of the pin:
- "PA7", "PA6", "PA4", "PB3", "PB2", "PC3", "PA14" (pin 10), "PA13" (pin 12), "PB6" (pin 13), "PB7" (pin 14), "PC1", "PC0", "PB14" (pin 17).
The second parameter supports the following:
- "input", "outputPushPull", "outputOpenDrain", "analog", it also supports these values (but lacks APIs to leverage the advanced state):
- "altFunctionPushPull", "altFunctionOpenDrain", "interruptRise", "interruptFall", "interruptRiseFall", "eventRise", "eventFall", "eventRiseFall"
The third parameter supports the following:
- "no", "up" (applies an internal pull-up resistor to 3V3), "down" (applies an internal pull-down resistor to GND)
gpio.init("PA7", "outputPushPull", "no"); // Configure pin 2 (Pin A7) as output with no pull-up resistor.
gpio.init("PA6", "outputOpenDrain", "no"); // Configure pin 3 (Pin A6) as output (open-drain) with no pull-up resistor.
gpio.init("PA4", "input", "up"); // Configure pin 4 (Pin A4) as input with a pull-up resistor.
The read
function reads the status of a pin. The pin should first be init as "input".
let result = gpio.read("PA4"); // returns false when pin PA4 is low, otherwise true.
print(result);
The write
function changes the status of a pin. The pin should first be init as "outputPushPull" or "outputOpenDrain".
If the pin is "outputPushPull", setting false
will set the pin to 0 volts and true
will set the pin to 3.3 volts.
If the pin is "outputOpenDrain", setting false
will set the pin to 0 volts and true
will set the pin to floating.
gpio.write("PA7", true); // Set the pin to 3.3 volts
gpio.write("PA6", false); // Set the pin to 0 volts
let keyboard = require("keyboard");
keyboard is used to input text or hex data.
-
setHeader
(header: string) : undefined | error
-
text
(allocSize: number, defaultText: string, selected: boolean) : string | undefined | error
-
byte
(numBytes: number, data: Uint8Array) : Uint8Array | undefined | error
The setHeader
function sets the header text that will be displayed by the byte
and text
functions.
keyboard.setHeader("Example Input");
The text
function prompts the user to enter some text and then returns the inputted text. If the user presses the back button then undefined
is returned.
The first parameter is the number of bytes of memory to allocate for the response, which includes a byte for the null-terminator. So if you want to allow entering up to 8 characters, you would pass a value of 8+1 to the function.
The second parameter is the default text to display.
The third parameter is true
if the text should be selected otherwise false
. Having the text selected allows the user to quickly replace the text with something else.
let result = keyboard.text(8+1, "demo", true);
print("Text is:"+result);
The byte
function prompts the user to enter a hex value and then returns the value. If the user presses the back button then undefined
is returned.
The first parameter is the number of bytes for the hex value.
The second parameter is the initial hex value to display.
let result = keyboard.byte(6, Uint8Array([1, 2, 3, 4, 5, 6]));
if (result !== undefined) {
let data = Uint8Array(result);
result = "0x";
for (let i = 0; i < data.byteLength; i++) {
if (data[i] < 0x10) result += "0";
result += to_hex_string(data[i]);
}
}
let math = require("math");
math is used to perform various math operations on numbers.
-
abs
(x : double) : double | undefined
-
acos
(x : double) : double | nan
-
acosh
(x : double) : double | undefined | error
-
asin
(x : double) : double | error
-
asinh
(x : double) : double | error
-
atan
(x : double) : double | error
-
atan2
(y : double, x : double) : double | error
-
atanh
(x : double) : double | error
-
cbrt
(x : double) : double | error
-
ceil
(x : double) : double | error
-
clz32
(x : double) : double | error
-
cos
(x : double) : double | error
-
exp
(x : double) : double | error
-
floor
(x : double) : double | error
-
log
(x : double) : double | error
-
max
(x : double, y : double) : double | error
-
min
(x : double, y : double) : double | error
-
pow
(base : double, exponent : double) : double | error
-
random
() : double | error
-
sign
(x : double) : double | error
-
sin
(x : double) : double | error
-
sqrt
(x : double) : double | error
-
trunc
(x : double) : double | error
-
PI
: double
-
E
: double
The abs
function returns the absolute value of the input parameter. Negative numbers become positive and positive numbers are unchanged.
print(math.abs(-4)); // 4
The max
function returns the larger of the two parameters.
print(math.max(15,4)); // 15
The min
function returns the smaller of the two parameters.
print(math.max(15,4)); // 4
The random
function returns a random number between 0 and 2 (exclusive).
print(math.random()); // 1.082337
The trunc
function removes the fractional part of a number.
print(trunc(-3.432)); // -3.0
The PI
constant is a double with value 3.14159265358979323846
.
var pi = math.PI;
The E
constant is a double with value 2.7182818284590452354
.
var e = math.E;
let notify = require("notification");
notification is used to blink the status LED, play tones, and vibrate the Flipper Zero.
success() : undefined
error() : undefined
blink(color: string, type: string) : undefined | error
The success
function is called to indicate a successful action to the user. Status light blinks green, vibrates, plays happy "do-de-da-lat" sound.
notify.success();
The error
function is called to indicate an error to the user. Status light blinks red, vibrates, plays mad "do-do" sound.
notify.error();
The blink
function is called to cause the status LED to blink. Often this is called in a loop with a delay to have the LED blink multiple times. NOTE: If the USB cable is plugged in the LED is turned to green and the blink may not be seen.
The first parameter is the name of the color. Supported colors are: "blue", "red", "green", "yellow", "cyan", "magenta".
The second parameter is the type of notification. Supported types are: "short", "long".
for (let i = 0; i < 10; i++) {
notify.blink("red", "short");
delay(500);
}
let serial = require("serial");
serial is used for USART (pins 13, 14) and LPUART (pins 15, 16) communication on the Flipper Zero.
-
setup
(port: string, baudrate: number) : undefined | error
-
end
() : undefined | error
-
write
(string | number | Uint8Array | [...number]) : undefined | error
-
read
(readlen: number [, timeout: number] ) : string | undefined | error
-
readln
( [timeout: number] ) : string | undefined | error
-
readBytes
(readlen: number [, timeout: number] ) : array | undefined | error
-
readAny
( [timeout: number] ) : string | undefined | error
-
expect
(array | string [, timeout: number] ) : number | undefined | error
The setup
function is used to initialize the serial port. Once it is initialized, it cannot be initialized again until end
is called.
The first parameter is the port. The valid values are "usart" (for pins 13 & 14) or "lpuart" (for pins 15 & 16).
The second parameter is the baud rate.
serial.setup("lpuart", 115200);
The end
function is used to deinitialize the serial port. It should only be called after the setup
function is called.
serial.end();
The write
function sends data on the serial port. The port must already be initialized. The parameter can be a string, number or array. The numeric values must all be in the range of (0x00..0xFF).
serial.write([0x0a]);
serial.write("uci\n");
let storage = require("storage");
storage is used for accessing the SD card in the Flipper Zero.
-
read
(path: string) : string | error
-
read v2
(path: string, size: number, offset: number) : string | error
-
write
(path: string, data: string) : boolean | error
-
write v2
(path: string, data: array | string) : boolean | error
-
append
(path: string, data: string) : boolean | error
-
exists
(path: string) : boolean | error
-
remove
(path: string) : boolean | error
-
virtualInit
(path: string) : boolean | error
-
virtualMount
() : undefined | error
-
virtualQuit
() : undefined | error
In Version 1.0 (still used by Xtreme) the read
function reads a file up to 128KB in size and returns the contents as a string.
The first parameter is the path of the file.
let data = storage.read("/ext/demo.txt");
print(data);
In Version 2.0 (Momentum and Unleashed) the read
function reads a file up to 128KB in size, starting at the specified offset and returns the contents as a binary array.
The first parameter is the path of the file. The second parameter is the size to read. The third parameter is the offset.
function arraybuf_to_string(arraybuf) {
let string = "";
let data_view = Uint8Array(arraybuf);
for (let i = 0; i < data_view.length; i++) {
string += chr(data_view[i]);
}
return string;
}
let data = storage.read("/ext/demo.txt", 4096, 20480); // Read up to 4096 bytes, starting at offset 20480.
print(arraybuf_to_string(data));
The write
function writes a string to a file, returning true
if successful. Overwrites existing file.
The first parameter is the path of the file.
The second parameter is the contents to write. (In version 2, Momentum/RogueMaster you can also write binary data)
let result = storage.write("/ext/demo.txt", "Hello world");
if (!result) { print("Failed to write file."); }
The append
function appends a string to a file, returning true
if successful.
The first parameter is the path of the file.
The second parameter is the contents to append.
let result = storage.append("/ext/demo.txt", "Line 2.");
if (!result) { print("Failed to append to file."); }
The exists
function returns true
if a file exists at the specified path, otherwise false
.
The parameter is the path of the file.
let result = storage.exists("/ext/demo.txt");
if (result) { print("File exists"); } else { print("File does not exist"); }
The remove
function deletes a file at the specified path, returning true
if successful.
The parameter is the path of the file.
let result = storage.remove("/ext/demo.txt");
if (!result) { print("Failed to remove file."); }
The virtualInit
function maps virtual storage to a file.
The first parameter is the path to the file to mount. The file should be created with usbdisk.createImage.
let usb = require("usbdisk");
let path = __dirpath + "4MB.img";
usbdisk.createImage(path, 4*1024*1024); // Create the image using usbdisk.createImage.
storage.virtualInit(path);
The virtualMount
function attaches virtual storage to the /mnt/
folder.
let result = storage.virtualMount();
if (result) {
storage.write("/mnt/demo.txt", "Hello World");
} else {
print("failed to mount");
}
The virtualQuit
function detaches virtual storage from the /mnt/
folder.
storage.virtualQuit();
let subghz = require("subghz");
subghz is used for accessing the subghz radio (CC1101) on the Flipper Zero.
-
getFrequency
() : number
-
getRssi
() : number | error
-
getState
() : string
-
isExternal
() : boolean
-
setFrequency
(frequency: number) : number | error
-
setIdle
() : undefined
-
setRx
() : undefined
-
setup
() : undefined
-
transmitFile
(file: string) : boolean | undefined | error
The getFrequency
function returns the current frequency for the received or last sent signal.
let rssi = subghz.getRssi();
print("rssi: ", rssi);
The getRssi
function returns the current RSSI (Receive Signal Signal Indicator) for the received signal. The subghz must be in receive mode.
let rssi = subghz.getRssi();
print("rssi: ", rssi);
The getState
function returns the current state of the radio. Valid states are "RX", "TX", "IDLE" and "".
let state = subghz.getState();
print("state: ", state);
The isExternal
function returns true
if an external CC1101 radio is being used, otherwise it returns false
.
let result = subghz.isExternal();
if (result) { print("external radio"); } else { print("internal radio"); }
The setFrequency
function is used to set the frequency of the radio. The state must be "IDLE" before setting the frequency.
The first parameter is the frequency in hertz. The frequency must be a frequency allowed by the firmware.
subghz.setFrequency(433920000);
The setIdle
function is used to set the state of the radio to "IDLE".
subghz.setIdle();
The setRx
function is used to set the state of the radio to "RX".
subghz.setRx();
The setup
function initializes the subghz radio. It configures to use the external radio based on firmware settings. It sets the radio to "IDLE" and changes the default frequency to 433.92MHz.
subghz.setup();
The transmitFile
function sets a subghz file. The '.sub' file can use a supported protocol or it can use RAW
format. The file is sent on the frequency specified in the file, and the getFrequency
value is updated. If the file is successful sent the function will return true
.
let result = subghz.transmitFile("/ext/subghz/demo.sub");
if (result) { print("sent"); } else { print("failed to send"); }
let submenu = require("submenu");
submenu is used for creating a scrollable menu of items and returning the selected one.
-
addItem
(label: string, id: number) : undefined | error
-
setHeader
(label: string) : undefined | error
-
show
() : number : undefined
The addItem
function adds a new entry to the menu.
The first parameter is the name of the entry.
The second parameter is the id associated with the entry, which will be returned when the user selects the item.
submenu.addItem("Calculate tip", 0);
The setHeader
function updates the header that is displayed at the top of the submenu.
submenu.setHeader("Choose an item");
The show
function displays the submenu and returns the id of the item selected. If the user presses the Back
button, then undefined
is returned.
let result = submenu.show();
if (result === undefined) {
print("User pressed back");
} else if (result === 0) {
print("User selected id 0.");
}
let textbox = require("textbox");
textbox is used for creating a dynamic display of text on the Flipper Zero. Contents are displayed in a non-blocking way, allowing the script to continue running and update the UI. The user can scroll the textbox contents, however whenever it is updated, focus is reset.
-
addText
(contents: string) : undefined | error
-
close
() : undefined
-
emptyText
() : undefined
-
isOpen
() : boolean
-
setConfig
(focus: string, font: string) : undefined | error
-
show
() : undefined
The addText
function appends the specified text to the end of the textbox.
The parameter is the contents to append.
textbox.addText("Hello world");
The close
function closes the textbox.
textbox.close();
The emptyText
function clears the contents of the textbox.
textbox.emptyText();
The isOpen
function returns true
if the textbox is currently visible. After a show
command the textbox is visible until it is closed by either calling close
or by the user pressing the Back
button.
let result = textbox.isOpen();
if (!result) { print("textbox is closed"); } else { print("textbox is open"); }
The setConfig
function configures the textbox.
The first parameter is where focus should be set when it is updated. Valid values are "start" (set focus to beginning of text) and "end" (set focus to the end of the text).
The second parameter is the font to use. Valid values are "text" and "hex".
textbox.setConfig("end", "text");
The show
function displays the textbox. It will be visible until it is closed by either calling close
or by the user pressing the Back
button.
textbox.show();
let usbdisk = require("usbdisk");
usbdisk is used for exposing a special file on the SD Card as a USB thumb drive via the Flipper Zero's USB port. This is helpful for copying files between the host computer and the Flipper Zero without needing any special software installed.
-
createImage
(path: string, capacity: number) : undefined | error
-
start
(path: string) : undefined | error
-
stop
() : undefined | error
-
wasEjected
() : boolean | error
The createImage
function is used to create a special file that can be used as the USB drive. Note: This file can also be used by storage.virtualInit to read and write files to it.
The first parameter is the path to the file.
The second parameter is the number of bytes to reserve for the image.
usbdisk.createImage("/ext/apps_data/mass_storage/4MB.img", 4*1024*1024);
The start
function will expose the file as a USB drive.
The parameter is the path to the file.
usbdisk.start("/ext/apps_data/mass_storage/4MB.img");
The stop
function will detach the USB drive.
usbdisk.stop();
The wasEjected
function will return true
if the USB drive has been ejected from the host computer.
// Wait for the disk to be ejected.
while (usbdisk.wasEjected()) {
delay(1000);
}
let widget = require("widget");
widget is used for displaying non-blocking UI elements.
-
addBox
(x: number, y: number, w: number, h: number): number
-
addCircle
(x: number, y: number, r: number): number
-
addDisc
(x: number, y: number, r: number): number
-
addDot
(x: number, y: number): number
-
addFrame
(x: number, y: number, w: number, h: number): number
-
addGlyph
(x: number, y: number, ch: number): number
-
addIcon
(x: number, y: number, icon: string): number
-
addLine
(x1: number, y1: number, x2: number, y2: number): number
-
addRbox
(x: number, y: number, w: number, h: number, r: number): number
-
addRframe
(x: number, y: number, w: number, h: number, r: number): number
-
addText
(x: number, y: number, font: string, text: string): number
-
addXbm
(x: number, y: number, index: number): number
-
close
(): undefined
-
loadImageXbm
(path: string): number
-
remove
(id: number): boolean
-
isOpen
(): boolean
-
show
(): undefined
The addBox
function will add a filled in box at (x,y) with a width of (w,h).
The first parameter is the x coordinate. 0 is left most. 127 is right most.
The second parameter is the y coordinate. 0 is top most. 63 is bottom most.
The third parameter is the width.
The fourth parameter is the height.
let x=10; // over
let y=15; // down
let w=20; // 20 pixels wide
let h=10; // 10 pixels high
let id = widget.addBox(x,y,w,h); // You can remove later with: remove(id);
The addCircle
function will add a circle centered at (x,y) with a radius of (r).
The first parameter is the x coordinate. 0 is left most. 127 is right most.
The second parameter is the y coordinate. 0 is top most. 63 is bottom most.
The third parameter is the radius.
let x=10; // over
let y=15; // down
let r=5; // 5 pixel radius
let id = widget.addCircle(x,y,r); // You can remove later with: remove(id);
The addCircle
function will add a filled in disc centered at (x,y) with a radius of (r).
The first parameter is the x coordinate. 0 is left most. 127 is right most.
The second parameter is the y coordinate. 0 is top most. 63 is bottom most.
The third parameter is the radius.
let x=10; // over
let y=15; // down
let r=5; // 5 pixel radius
let id = widget.addDisc(x,y,r); // You can remove later with: remove(id);
The addDot
function will set the pixel at (x,y).
The first parameter is the x coordinate. 0 is left most. 127 is right most.
The second parameter is the y coordinate. 0 is top most. 63 is bottom most.
let x=10; // over
let y=15; // down
let id = widget.addDot(x,y); // You can remove later with: remove(id);
The addFrame
function will add an outlined rectangle at (x,y) with a width of (w,h).
The first parameter is the x coordinate. 0 is left most. 127 is right most.
The second parameter is the y coordinate. 0 is top most. 63 is bottom most.
The third parameter is the width.
The fourth parameter is the height.
let x=10; // over
let y=15; // down
let w=20; // 20 pixels wide
let h=10; // 10 pixels high
let id = widget.addFrame(x,y,w,h); // You can remove later with: remove(id);
The addGlyph
function will add a glyph at (x,y) using the character specified.
The first parameter is the x coordinate. 0 is left most. 127 is right most.
The second parameter is the y coordinate. 0 is top most. 63 is bottom most.
The third parameter is the code of the glyph.
let x=10; // over
let y=15; // down
let ch=35; // typically ascii code of glyph.
let id = widget.addGlyph(x, y, ch); // You can remove later with: remove(id);
The addIcon
function will add an icon at (x,y) using the icon specified. addIcon
requires the firmware to know the name of the icons, which takes additional memory and may not be possible to implement in all firmware. For cross-firmware compatibility your script can use addXbm with local .xbm files instead.
The first parameter is the x coordinate. 0 is left most. 127 is right most.
The second parameter is the y coordinate. 0 is top most. 63 is bottom most.
The third parameter is the name of the icon.
let x=10; // over
let y=15; // down
let icon="ButtonUp_7x4";
let id = widget.addIcon(x, y, icon); // You can remove later with: remove(id);
The addLine
function will draw a line from (x1,y1) to (x2,y2).
The first parameter is the x coordinate of the first point. 0 is left most. 127 is right most.
The second parameter is the y coordinate of the first point. 0 is top most. 63 is bottom most.
The third parameter is the x coordinate of the second point. 0 is left most. 127 is right most.
The fourth parameter is the y coordinate of the second point. 0 is top most. 63 is bottom most.
let x1=10; // over
let y1=15; // down
let x2=100; // over
let y2=35; // down
let id = widget.addLine(x1, y1, x2, y2); // You can remove later with: remove(id);
The addRbox
function will add a filled in box at (x,y) with a width of (w,h) with rounded corners of radius (r).
The first parameter is the x coordinate. 0 is left most. 127 is right most.
The second parameter is the y coordinate. 0 is top most. 63 is bottom most.
The third parameter is the width.
The fourth parameter is the height.
The firth parameter is the radius.
let x=10; // over
let y=15; // down
let w=20; // 20 pixels wide
let h=10; // 10 pixels high
let r=3; // 3 pixel radius
let id = widget.addBox(x,y,w,h,r); // You can remove later with: remove(id);
The addRbox
function will add an outlined rectangle at (x,y) with a width of (w,h) with rounded corners of radius (r).
The first parameter is the x coordinate. 0 is left most. 127 is right most.
The second parameter is the y coordinate. 0 is top most. 63 is bottom most.
The third parameter is the width.
The fourth parameter is the height.
The firth parameter is the radius.
let x=10; // over
let y=15; // down
let w=20; // 20 pixels wide
let h=10; // 10 pixels high
let r=3; // 3 pixel radius
let id = widget.addRbox(x,y,w,h,r); // You can remove later with: remove(id);
The addText
function will add text at (x,y) with the specified font.
The first parameter is the x coordinate. 0 is left most. 127 is right most.
The second parameter is the y coordinate. 0 is top most. 63 is bottom most.
The third parameter is the font. Valid values are: "Primary", "Secondary".
The fourth parameter is the height.
The firth parameter is the radius.
let x=10; // over
let y=15; // down
let font="Primary"; // Large font
let text="Hello!";
let id = widget.addText(x,y,font,text); // You can remove later with: remove(id);
The addXbm
function will render a XBM image at (x,y) with the specified image.
The first parameter is the x coordinate. 0 is left most. 127 is right most.
The second parameter is the y coordinate. 0 is top most. 63 is bottom most.
The third parameter is the image identifier. Use loadImageXbm
to get the identifier.
let x=10; // over
let y=15; // down
let identifier= widget.loadImageXbm(__dirpath + "/demo.xbm");
let id = widget.addText(x,y,identifier); // You can remove later with: remove(id);
The close
function will stop displaying the widget.
The loadImageXbm
function is used to load an image. You can then pass the returned value to addXbm
.
The parameter is the path to the xbm file.
let identifier= widget.loadImageXbm(__dirpath + "/demo.xbm");
The remove
function is used to remove a previously added component.
The parameter is the id that was returned from a previous add... method.
let line = widget.addLine(10, 10, 100, 60);
widget.show();
delay(1000);
widget.remove(line); // Remove the previously added component.
delay(1000);
widget.close();
The isOpen
function is used to tell if the widget is being displayed. When a user presses the Back
button the widget will be dismissed and this function will return false
.
widget.show();
while (widget.isOpen()) {
delay(100);
}
The show
function is used to display the widget. The widget can be dismissed by pressing the Back
button or by calling close
.
widget.show();