본문으로 건너뛰기

Peripherals

List the MIPI and USB cameras and ALSA microphones SiMa Sentinel reports on the selected board, preview a camera, and test a microphone. Sentinel discovers the devices and Insight reads its catalog. Discovery never captures frames or audio, opens a sound device, changes sensor controls, or publishes streams; only a camera preview or a microphone test, started explicitly, captures, and only while it runs. Each camera mode is Available or Unsupported, decided from Sentinel's report: for a MIPI camera, its sensor is in the board's camera overlays, the ISP outputs its size, and its format is NV12 (a fixed fact about Neat's CameraInput, not queried from the board); for a USB camera, Sentinel reports it in MJPEG on the uvcvideo driver, which Neat's USB camera input reads. Core has no audio input node, so microphones carry no verdict.

📄️Scan the selected board for cameras and microphones

Asks SiMa Sentinel on the board (`/run/simaai-sentinel/api.sock`, `POST /v1/peripherals/refresh`) to rescan; Sentinel answers with the catalog of a scan that started after the request (it returns `504` after 10 s and `429` when 8 refreshes already wait). Over SSH the socket is reached with a stdlib `python3` helper. Each mode's `support` comes from Sentinel's catalog alone (see `SupportTier`). Microphones are Sentinel's ALSA capture devices, read from `/proc/asound` and sysfs without opening a sound device; their `availability` is Sentinel's own, passed through. A camera whose provider failed keeps Sentinel's last good modes (`modes_source: previous-scan`). `changes` lists devices added or removed since the previous refresh. Concurrent refreshes of one board share a single scan. Sentinel errors (not installed, not running, discovery disabled, too old, malformed answer) return `503` or `502` with an install or update hint.

📄️Start a camera preview

Starts an explicit, temporary capture: over the board connection Insight runs a GStreamer pipeline (`gst-launch-1.0`; `libcamerasrc` for a MIPI camera, `v4l2src` on the camera's `/dev/v4l/by-id` path for a USB camera, or on its `/dev/videoN` node once a SiMa Sentinel rescan still reports the scanned camera there) that scales the mode to at most 640 pixels wide at up to 15 fps and writes JPEG frames to its stdout. Insight answers once the first frame arrived (within 10 s, or two frame periods for a mode slower than 0.2 fps, at most 60 s) and relays the frames at `stream_url`. Discovery never starts capture; only this call does. The mode defaults to the camera's `default_selection` and must be one the last scan listed: for a MIPI camera an `available` or `unverified` mode in NV12, for a USB camera any listed mode in MJPG or a raw format (YUYV, UYVY, YVYU, NV12, NV21, YU12, YV12, GREY, RGB3, BGR3). The rate is the scan's exact fraction (`framerate_num`/`framerate_den`). A camera listed from SiMa Sentinel's last successful scan, because its provider failed during the refresh (`modes_source: previous-scan`), is refused with 503 `peripheral_unavailable`: its device may have changed since. A USB camera without a `/dev/v4l/by-id` link whose `/dev/videoN` node Sentinel no longer reports for the scanned camera (same id, vendor, product and serial), because it was replugged or replaced, is refused with 409 `stale_snapshot`. Insight refuses a camera the scan or a check just before the start finds in use, or one the pipeline cannot acquire (409 `camera_in_use`); a board without `gst-launch-1.0`, or without a GStreamer element the pipeline needs (named in `tool`), returns 502 `tool_missing` with the packages to install; a pipeline that fails or sends no frame returns 502 `command_failed` with its output in `detail`. While a preview runs the camera cannot be opened by an application. Capture stops on `stop`, when its stream response ends, when nobody opens the stream within 15 s, when a refresh starts, or when the selected board changes.

📄️Stream a camera preview

Relays the preview's JPEG frames as a long-lived `multipart/x-mixed-replace; boundary=frame` response, one `image/jpeg` part with a `Content-Length` per frame, for an `<img>` element. Insight checks the board's framing and refuses a frame over 4 MiB. One viewer per session: a second request returns 409 `preview_active`. When the response ends (the viewer disconnects, or the board sends nothing for 10 s, or for two frame periods for a mode slower than 0.2 fps, at most 60 s) the preview stops on the board. An unknown or superseded session id returns 404.

📄️Start a microphone test

Starts recording from a scanned microphone on the board and returns `202` at once. It records until `POST .../test/stop` or for `seconds` (at most 30); poll `GET` for the live level and the result. Insight first re-reads SiMa Sentinel's catalog: when that microphone's capture target or identity changed since the scan (a replug, or a restarted Sentinel routing the id elsewhere), it returns `409 stale_snapshot` without recording; other catalog changes, such as a previewing camera's rate, do not count; it also refuses a microphone whose provider data is from an earlier scan (`409 stale_snapshot`), and one without a safe Sentinel selector (`502 peripheral_response`). Sentinel's availability is not used to refuse: Insight then checks the capture PCM on the board and returns `409 microphone_in_use`, naming the holding process where it can see it, only when a substream is open now. The board runs `arecord` on Sentinel's `plughw:CARD=<id>,DEV=<n>` selector, converted to 16-bit PCM at 48 kHz when the device offers it (else its nearest rate below, never above 48 kHz) and at most two channels. Only one test records at a time (`409 test_running`). Returns `409 stale_snapshot` when the selected board changed since the scan. A busy device, a board without `arecord`, or a failed recording ends the test with `state: failed` and the error.

📄️Stop the microphone test's recording

Ends the test named by `token` on the selected board at once; a token that is not the current test's (a late Stop for an earlier test) stops nothing and returns null. It ends the recording even when `arecord` has stopped producing audio; what was recorded becomes the result, read through `GET` as usual. A test stopped before 0.1 s was recorded ends with `stopped_early`. Returns the test, or null when there is none for the selected board. It never stops another application.