Skip to content

Configuration Reference

Varun Karthic edited this page Oct 8, 2026 · 1 revision

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.

Contents


Backend settings

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.

Security and secrets

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.

Sessions

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.

Data and first run

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))".

Script variables

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)

How device configuration works

Each board takes its settings from two places:

  1. Kconfig (idf.py menuconfig): compile-time defaults built into the firmware.
  2. 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.

Gateway (C6)

idf.py menuconfig → imPress C6 Gateway Configuration. NVS namespace impress.

Wi-Fi

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 –

Backend Server

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)

Timing

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

Battery ADC (optional)

Kconfig Default Meaning
BATTERY_ADC_EN n read the supply voltage
BATTERY_ADC_GPIO 4 ADC pin

Also in NVS

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

Hub (S3)

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).

Student module

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

Changing configuration on a deployed device

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)

Fixed timings

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

Clone this wiki locally