Useful settings
Access keys, QR codes, asset storage, button actions, voice chat, power management, nightly reboots and debug logging.
A tour of the most useful options under a frame's Settings tab. Unless noted otherwise, each one is available in the self-hosted backend, in FrameOS Cloud and on a standalone frame's admin page - the cloud's settings page lists the exact set it accepts.
Frame access
Each frame's HTTP server (port 8787) has three access modes - private, protected, and
public - controlling who needs the access key to view or control the frame. See
Controlling the frame for details, and the
HTTP API for exactly what each mode opens.
QR control code
By default the frame overlays its control URL as a QR code on the display. You can position it, restyle it, or turn it off entirely.
Assets
Downloaded images (OpenAI, Unsplash, galleries…) are saved to /srv/assets on the frame's SD card
when there's enough free space. This avoids re-downloading (and re-paying for) the same images
after a reboot. Browse, upload, rename and delete them under the frame's Assets tab, reuse
them with the Local image app, or point a path state field at a file or folder so the
control page gets a picker.
This works the same way on ESP32 boards with a TF card slot. Images too large to decode in memory also spool here on their way to the screen - see Big images on small devices.
Scenes write into the assets folder, so on a Pi it must be /srv/assets, or a folder under
/mnt or /media: pointed anywhere else it could overwrite FrameOS's own
files. A folder already set elsewhere is left alone. ESP32 boards mount their SD card there and aren't
held to it. What a scene may do in the folder is up to its apps'
permissions.
Setup hotspot
When a Pi can't join a network on boot it raises a WiFi hotspot of its own, so you can give it
new credentials from your phone (Wifi Hotspot Setup → Enabled on boot if no network
connection). Leave its name and password blank - the default for new frames - and
a frame with a screen makes them up the first time it needs them: FrameOS-XXXX from its WiFi
MAC address, and a 10-character password it draws on the panel with a QR code. A frame without a
screen keeps the password frame1234. Whatever you type into those fields is used as is, so
frames set up earlier keep FrameOS-Setup / frame1234 until you clear them. Joining the hotspot
opens the setup page by itself on most phones (a captive portal), and the hotspot shuts down
after five minutes by default.
Buttons, voice and input
List the frame's buttons by pin and label under GPIO buttons - the hardware presets fill them
in. Each button has a role (primary, next, prev, back, menu, refresh…), defaulting
from its label, and scenes hear presses as button and gpio
events. On an ESP32 a changed map reaches the board with its next settings
sync, and it restarts to rebind the pins (the cloud pushes it too).
Button actions say what a press does on this frame whatever scene is
showing: next or previous scene, render, show a particular scene, Scene switcher and Scene
settings, Back and Forward, and - on displays that can
switch their panel off - display on, off or on/off. Each row is one press (press, double press or
long press) of one of the frame's buttons, or on a touch screen one
edge swipe, and a press bound there never reaches the scene. The Seeed
reTerminal presets come with LEFT held = previous scene and RIGHT held = next; the
ESP32 guide lists every board's. A frame keeps the map it was set up
with, so an ESP32 from before a preset changed keeps its old one until you change the rows, or run
set hardware <preset> and restart on its console. A HyperPixel whose map you never touched
follows the current default. To tell one installed scene which of your keys are its own, use
Map buttons in that scene's menu instead (details).
ESP32 boards get a Buzzer, LED and microphone box under the buttons:
- Button beep GPIO and Button beep tone (Hz): boards with a buzzer - the Seeed reTerminals - click when a press registers.
- Status LED GPIO and its type: the reTerminal E-series' green LED lights with the buzzer's notes. The placeholder shows the board's own pin.
- Microphone GPIO (clock, data, power) and the Voice chat switch, with the four Voice chat may switches under it: Change settings, Use installed scenes, Create new scenes (off by default) and Access photo albums. See voice chat. The voice chat controls only show on a frame with a microphone: the E1001/E1002/E1003 presets have one, the E1004 doesn't, and filling in the pins of one you added makes them appear.
A Pi with a keyboard or touchscreen has an Input section: the Keyboard layout a key's character is read in, and Grab keyboards, which keeps the console from seeing keys meant for the scene. Saving either restarts the runtime. ESP32, Pico and virtual frames don't show it.
Power and battery
Frames that can sleep - the ESP32-S3 and the Pico W boards - get a Power section: deep sleep between refreshes, sleeping only while on battery, aligning wake-ups to wall-clock boundaries, waking periodically to pick up queued commands, and battery voltage sensing (the ADC pin, the divider ratio and, on boards that switch the divider, its enable pin - the hardware presets fill these in). A sleeping ESP32 also wakes on any of its GPIO buttons, and the frame list says asleep · wakes in 5 min while it's down. A Raspberry Pi is always awake and always wall-powered, so it has none of this.
Nightly reboot
Frames reboot nightly by default - cheap insurance against memory leaks on a device meant to run for years. To anyone watching, it looks like a regular re-render. You can disable it or change the time. A reboot or restart can also be a schedule entry, which is how ESP32 frames do it.
Metrics
Frames sample CPU, memory, temperature and disk and ship them to the backend - or to the cloud,
if you switched that on for the frame - every 60 seconds.
Change the interval under Metrics, or set it to 0 to turn the sampler off entirely. Changes
apply without a restart.
Render scale
Scale, next to the scaling mode in the frame's settings, makes a scene built for a small screen
fill a big one. A .tsx or .jsx app is told its
canvas is the panel divided by the scale, lays its UI out at that size, and what it returns is
drawn sharp at the panel's full size. An app that fetches for its size asks for less too: at 2, a
quarter of the data.
Automatic, the default, is the panel's shorter edge over 600 pixels, rounded down to a quarter
and never below 1: 800×480 and 720×720 stay at 1, 1200×1600 is 2, 1872×1404 is 2.25. A scene can
override it in its own settings, or with a numeric state field whose role is renderScale. On an
ESP32's console it's set render_scale 2, with 0 for automatic. Plain .js and .ts apps keep
the panel's pixels, and a picture an app hands over as pixels is stretched, so it goes soft where
vectors stay sharp.
Time zone
Set the frame's time zone so schedules, clocks and calendars line up: the on-device scheduler
fires in the frame's zone, and so do clocks in JavaScript apps and the weather forecast. Pick it
under Device settings → Timezone (IANA names like Europe/Brussels); on Raspberry Pi OS the
first option, Detect from frame, keeps whatever the OS already has. The backend's
Settings → Default timezone is what a new frame starts with, and an SD image built in the
backend or the cloud carries the zone with it. Time sync itself works out of the box.
In FrameOS Cloud every way of adding a frame - SD image, ESP32 flasher, claim code - seeds the new frame's zone from the browser you used, so a frame comes up in local time without a visit to its settings.
An ESP32 keeps a zone too: it stores the name plus a few-kilobyte slice of time
zone data for that one zone, so daylight saving switches correctly without a full database on the
chip. It takes the zone from the backend or the cloud, or from set time_zone Europe/Brussels on
the serial console. If the zone
arrives without its data slice (the console command, say), the frame fetches the
slice once from tz.frameos.net on its next online render pass and stays on UTC until then - worth
knowing on a locked-down network, where SD images also poll networkcheck.frameos.net on boot.
HTTP response size
Maximum HTTP response size for apps caps how much any single download - an image, a calendar feed, an API reply - may carry. A response that announces a bigger size is refused before the first byte; a stream that grows past it is cut off. The default is 64 MiB on a Pi and 4 MiB on an ESP32, where it's read at boot (saving it reboots the frame). Raise it for bigger sources. On an ESP32 a baseline JPEG or PNG decodes straight off the socket and never needs to be held whole; anything that does - a progressive JPEG, a large feed - spills to the SD card when there is one, so a 20 MB gallery photo needs nothing but a higher limit. See Big images on small devices.
HTTPS
Switch on HTTPS API and the frame serves its web app and API over TLS on port 8443, next to
plain HTTP on 8787 - or instead of it, with Expose only HTTPS port. The frame does this
itself on every Linux frame, SD-image frames included. If
the certificate can't be loaded or the port is taken, the frame logs tls:config_error or
tls:start_error and stays reachable over plain HTTP.
Port and HTTPS changes saved on the frame's own admin page take effect on save: the page follows the frame to its new address, and a port that is already in use refuses the save instead of locking you out. A time zone or network share changed there is applied too, no deploy needed.
Debug logging
Enable debug logging to get per-app timing in the logs - useful to find out which app slows down your renders.
SSH keys
Both the backend and the cloud keep a list of SSH public keys
under Settings → SSH keys in the backend and Account → Settings in the cloud (the backend
can also generate a keypair for you; the cloud stores public halves only). Mark the ones that should go onto every new frame, and the SD image builders
and the frame's settings page offer them as checkboxes - a key on the card lands in root's
authorized_keys on first boot, next to whatever root password you chose.
The other way round, the backend pins a frame's SSH host key the first time it connects, and refuses a different machine at that address. Replaced the Pi or re-flashed the card? Forget host key in the frame's settings resets it (there is one for the build host too).
Builds (self-hosted backend only)
FrameOS is distributed as released binaries, and a normal deploy compiles nothing. The backend's Settings page keeps the old build machinery under Advanced: legacy source builds, collapsed behind a Show link: local Docker cross-compilation, a remote SSH build host, or building on the device itself. A source build only happens for a legacy compiled scene, for a frame whose installation mode you set to Build from source by hand, or for a distro outside the release matrix. Releases cover Debian / Raspberry Pi OS bookworm and trixie and Ubuntu 24.04 and 26.04, so a frame still on bullseye builds from source until you upgrade its OS. The Home Assistant add-on has no Docker socket, so it stays on precompiled binaries unless you point it at a build host.
HTTP API
Every route a frame serves - turn the display on and off, switch scenes, set state, fetch the image, read logs - with authentication, events, and how ESP32 and Pico frames differ.
FrameOS Remote
The optional on-device companion that connects frames back to the backend for logs, metrics, terminal access and remote management.