camera

ESP32 Camera API

This page summarizes the REST and WebSocket endpoints exposed by the firmware. The camera can operate without an SD card by building with the CAMERA_ONLY_MODE flag.

REST Endpoints

Method Path Description
GET /api/status Current Wi‑Fi, battery and camera status.
GET /api/capture Take a snapshot and return the file name.
POST /api/delete?file=/path Delete a file from the SD card.
GET /api/list List files on the SD card.
POST /api/format-sd Recursively erase non-config files.
POST /api/format-sd-esp Use ESP-IDF to format the card.
GET /api/sd-status SD availability and free space.
POST /api/update-cert Save a new TLS certificate and key.
GET /cert-status Current certificate CN and expiry date.
POST /api/passphrase/setup Set a passphrase and optional recovery code.
POST /api/passphrase/unlock Unlock the camera with the passphrase.
POST /api/passphrase/unlock-recovery Unlock using the recovery code.
POST /api/passphrase/reset Change the passphrase and recovery code.
POST /api/firstboot/setup Configure Wi‑Fi and mode on first boot.
    Optional fields ssid_backup, wifipass_backup, and fallback_ap control Wi‑Fi failover.
GET /api/firstboot/scan Scan for nearby Wi‑Fi networks.

Wi‑Fi passwords are stored encrypted in /config.json using AES‑CTR with an HMAC‑SHA256 tag to detect tampering. Backup credentials are stored in the same encrypted form under ssid_backup and wifipass_backup. The fallback_ap flag controls whether the device starts its own AP if both networks fail.

WebSocket

wss://<camera-ip>/ws streams MJPEG frames to connected clients. Call web_server_loop() in the firmware loop to push frames.

The root path / serves the web UI from SPIFFS when no SD card is present. Build a minimal standalone UI with npm run build-spiffs in the ui/ folder. The output is written to esp/esp32-cammycam/data/. Flash these files with pio run --target uploadfs. See ../communication/README.md for an overview of how the camera talks to the hub.

Chunked recording

When motion triggers a recording the firmware writes 5‑second MJPEG chunks to /clips/tmp/clip_<timestamp>_partN.mjpeg. If paired with a hub each chunk is posted to /api/upload-clip-part and removed locally. After the final part a small JSON file is sent to /api/upload-clip-meta so the hub can merge the clips and add overlays.

Serial setup mode

During the first seconds of boot the firmware listens for commands on the USB serial port. Use SETUP <ssid> <password> <mode> to configure Wi‑Fi and mode or PASSPHRASE <value> to set the passphrase. The board stops waiting after a short timeout so it will still boot without a serial monitor.

Kill switch

Hold the two buttons wired to BUTTON1_PIN and BUTTON2_PIN for about 15 seconds to erase the flash and remove /config.json. The board will reboot with factory settings.

Startup diagnostics

setup() waits only three seconds for Serial before continuing. The reboot reason from esp_reset_reason() is logged to /events.log. Brownout or watchdog resets print a warning to help diagnose power issues.