Configuration Reference - Kush-Kelaiya22/imPress GitHub Wiki
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:
- 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.
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 |