Repository navigation
Configuration Reference
Every setting in imPress: the backend's environment variables, the scripts' variables, and each board's build-time and stored configuration. Reference: docs/guides/configuration.md. A repository test fails if a backend setting is missing from that page.
- Backend settings
- Script variables
- How device configuration works
- Gateway (C6)
- Hub (S3)
- Student module
- Changing configuration on a deployed device
- Fixed timings
Environment variables with the prefix IMPRESS_, or lines in backend/.env. The file is read from the directory the server starts in; scripts/start.sh starts in backend/. Lists use JSON syntax. Source: backend/app/config.py. Template: backend/.env.example.
| Variable | Default | What it does |
|---|---|---|
IMPRESS_DEBUG |
false |
Development mode. With false, the server refuses to start while IMPRESS_JWT_SECRET or IMPRESS_DEVICE_API_KEY has its published default. With true it only logs a warning. Never true in production. |
IMPRESS_JWT_SECRET |
public default | Must be set. Used by legacy JWT helpers only: login sessions are opaque tokens. install.sh generates it. |
IMPRESS_JWT_ALGORITHM |
HS256 |
Legacy. |
IMPRESS_JWT_EXPIRE_MINUTES |
1440 |
Legacy. |
IMPRESS_DEVICE_API_KEY |
public default | The shared provisioning key. It must equal every device's api_key. Devices register with it and are then issued their own key. install.sh generates it. |
IMPRESS_DEVICE_KEYS_REQUIRED |
false |
true: the shared key is accepted for registration only; every other device call needs the device's own key. Turn on once every device runs firmware with per-device keys. See Security. |
IMPRESS_FIRMWARE_SIGNING_KEY |
empty | Path to the site's firmware public key (PEM, from scripts/firmware_key.sh). When set, uploads must be signed with it, and images that aren't are never deployed. An unreadable file stops the server at startup. Empty: signatures are recorded, not required. See Security. |
IMPRESS_WS_REQUIRE_AUTH |
true |
Require credentials on WebSockets. Turn off only for isolated debugging. |
IMPRESS_CORS_ORIGINS |
["http://localhost:5173","http://localhost:3000"] |
Browser origins allowed to call the API from another site. The built-in web app is same-origin and doesn't need an entry. |
| Variable | Default | What it does |
|---|---|---|
IMPRESS_SESSION_IDLE_MINUTES |
60 |
A session ends after this long without activity. |
IMPRESS_SESSION_HARD_MINUTES |
360 |
A session ends this long after login, whatever the activity. |
IMPRESS_SESSION_WARNING_MINUTES |
5 |
The web app warns this long before the hard limit. |
| Variable | Default | What it does |
|---|---|---|
IMPRESS_DATABASE_URL |
sqlite+aiosqlite:///./impress.db |
SQLAlchemy async URL. Relative paths are relative to backend/. |
IMPRESS_FIRMWARE_DIR |
./firmware_bins |
Where firmware images are stored (named by SHA-256). |
IMPRESS_INITIAL_ADMIN_PASSWORD |
empty | Password of the first super admin, used on the first start only. Empty: a random one is printed once in the log. |
IMPRESS_APP_NAME |
imPress Backend |
Cosmetic. |
IMPRESS_SQL_ECHO |
false |
Logs every SQL statement with its parameters. Never in production: it logs personal data. |
Generate a secret with python -c "import secrets; print(secrets.token_urlsafe(32))".
These are read by the scripts in scripts/, not by the backend itself.
| Variable | Script | Meaning |
|---|---|---|
PYTHON |
install.sh |
interpreter to use (default python3; must be ≥ 3.12) |
IMPRESS_HOST, IMPRESS_PORT
|
start.sh |
listen address and port (127.0.0.1, 8000) |
IMPRESS_SSL_CERTFILE, IMPRESS_SSL_KEYFILE
|
start.sh |
serve HTTPS/WSS; both or neither |
IMPRESS_SIGNING_KEY |
build_signed.sh |
path to the private signing key |
--base, --password, --device-key, --cafile
|
smoke_test.py |
server URL, admin password, device key (default: from .env), CA to trust for HTTPS |
--key |
verify_firmware.py |
public key that must have signed the image |
| first argument | firmware_key.sh |
where to create the key pair (default ~/.impress/firmware-signing) |
Each board takes its settings from two places:
-
Kconfig (
idf.py menuconfig): compile-time defaults built into the firmware. - NVS: a key–value store in flash.
On the first boot the board writes its Kconfig defaults into NVS. From then on, NVS wins: rebuilding with new Kconfig defaults does not change a board that has already booted, unless its NVS is erased or edited.
Guarantees:
- Bad values: empty or oversized NVS values are ignored, and the Kconfig default is used (#18).
- Firmware updates: NVS survives them.
idf.py menuconfig → imPress C6 Gateway Configuration. NVS namespace impress.
| Kconfig | Default | NVS key | Notes |
|---|---|---|---|
WIFI_SSID |
impress-hotspot |
wifi_ssid (≤ 32) |
2.4 GHz network |
WIFI_PASSWORD |
impress123 |
wifi_pass (≤ 64) |
WPA2-PSK or better |
WIFI_MAX_RETRY |
10 | – |
| Kconfig | Default | NVS key | Notes |
|---|---|---|---|
BACKEND_HOST |
192.168.137.1 |
backend_h (≤ 127) |
IP or hostname of the backend. With TLS: the name in the server's certificate |
BACKEND_PORT |
8000 |
backend_p |
HTTP port, or the HTTPS port with TLS (usually 443) |
DEVICE_API_KEY |
impress-device-key-2024 |
api_key (≤ 127) |
the shared provisioning key; must equal IMPRESS_DEVICE_API_KEY
|
| – | – | dev_key |
this gateway's own key, received from /register. Sent instead of api_key once present; erased when the backend answers 401 (an admin reset it) |
CLASS_SESSION_ID |
0 (= assigned by the backend) |
class_id |
updated from registration and from WebSocket class assignment |
BACKEND_TLS |
off | – | use https:// and wss://
|
BACKEND_TLS_CRT_BUNDLE / BACKEND_TLS_CA_FILE
|
bundle | – | trust public CAs, or only firmware/class_c6/certs/backend_ca.pem (embedded at build time) |
| Kconfig | Default | Range | Meaning |
|---|---|---|---|
HEARTBEAT_INTERVAL_S |
15 | 5–300 | heartbeat with telemetry and diagnostics |
WS_PING_INTERVAL_S |
30 | 10–120 | WebSocket keep-alive |
STATUS_PING_INTERVAL_S |
120 | 60–600 | classroom status ping |
SPI_BATCH_MAX_WAIT_MS |
500 | post a batch after this idle time | |
BATCH_MAX_SIZE |
20 | messages per batch post |
| Kconfig | Default | Meaning |
|---|---|---|
BATTERY_ADC_EN |
n | read the supply voltage |
BATTERY_ADC_GPIO |
4 | ADC pin |
| Key | Meaning |
|---|---|
boot_count |
boots since the first flash (diagnostics) |
ota_target |
the version an OTA update is installing, so the new image can report success or rollback |
init_done |
NVS has been initialised from Kconfig |
idf.py menuconfig → imPress S3 Class Module Configuration. NVS namespace s3_cfg.
| Kconfig | Default | NVS key | Notes |
|---|---|---|---|
WIFI_SSID / WIFI_PASSWORD
|
impress-hotspot / impress123
|
wifi_ssid / wifi_pass
|
used only for the OTA hop |
WIFI_MAX_RETRY |
5 | – | |
BACKEND_HOST / BACKEND_PORT
|
192.168.1.100 / 8000
|
backend_host / backend_port
|
set these to the same server as the gateway's |
DEVICE_API_KEY |
impress-device-key-2024 |
api_key |
shared provisioning key |
| – | – | dev_key |
the hub's own key, issued when it registers during an OTA hop |
BACKEND_TLS, BACKEND_TLS_CRT_BUNDLE / BACKEND_TLS_CA_FILE
|
off | – | as on the gateway; the CA file is firmware/class_s3/certs/backend_ca.pem
|
HEARTBEAT_INTERVAL_MS |
5000 | – | hub → gateway heartbeat, and the student sweep |
STUDENT_TIMEOUT_MS |
60000 | – | silence before a student is reported as having left |
SPI_POLL_INTERVAL_MS |
50 | – | longest wait between SPI exchanges |
SPI_CLOCK_MHZ |
10 | – | SPI clock; lower it on noisy wiring |
MESH_WIFI_CHANNEL |
1 | – | must equal the students' MESH_WIFI_CHANNEL |
The hub's sdkconfig also enables app rollback (CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE) and makes PSRAM optional (CONFIG_SPIRAM_IGNORE_NOTFOUND).
There is no menuconfig menu; these are compile-time constants in firmware/student/main/config.h:
| Constant | Default | Meaning |
|---|---|---|
MESH_WIFI_CHANNEL |
1 | must equal the hub's |
MESH_RELAY_TTL |
5 | maximum hops |
STUDENT_HAS_DISPLAY / STUDENT_HAS_LED
|
0 / 0 | board variant |
PIN_BTN_1..4, PIN_BTN_CONFIRM
|
4, 16, 18, 22, 23 | buttons A–D and CONFIRM |
PIN_I2C_SDA / PIN_I2C_SCL
|
8 / 9 | OLED |
HEARTBEAT_INTERVAL_MS |
30000 | student heartbeat |
DEBOUNCE_MS |
50 | button debounce |
DEFAULT_ENROLLMENT |
0000000000 |
"unprovisioned" marker; never a real student |
NVS namespace impress on the module:
| Key | Meaning |
|---|---|
enroll |
the identity |
s_name, s_program, s_email
|
local profile cache; never transmitted |
init_done |
NVS has been initialised |
| Goal | How |
|---|---|
| New defaults for new boards |
idf.py menuconfig, build, flash |
| Change one board's Wi-Fi, backend or key | write the NVS keys above with an NVS partition image (nvs_partition_gen.py) or a provisioning tool. They take effect on the next boot. Or erase the flash and reflash with new defaults (idf.py erase-flash flash, which also erases the device key and class) |
| Change the class a gateway belongs to | on the backend: register it with another classroom_code, or relink it as an admin. Nothing changes on the device |
| Re-issue a device key | Modules page → Diagnostics → Reset key (Device Management) |
| Turn on TLS or signature checks | a firmware build with those options, deployed over the air (Security) |
These are constants in the code, not settings:
| What | Value |
|---|---|
| A device is offline after | 30 s without contact |
| A student module is "seen" (not connected) after | 90 s without contact |
| Presence sweep | every 15 s |
| Deployment scheduler | every 5 s |
| Session cleanup | every 5 min |
| Gateway health watchdog after an OTA update | 120 s |
| Hub link considered down after | 15 s without a hub heartbeat |
| CSV import limits | 1 MB, 500 rows |
imPress v2.1 · Repository · Issues · Source docs: docs/ · Not yet verified on hardware: see Testing and CI
Understand
Set up
Use
Operate
Develop
More