Replace rpicam-still/rpicam-vid with picamera2 daemon, add WebSocket …#2813
Replace rpicam-still/rpicam-vid with picamera2 daemon, add WebSocket …#2813nevion wants to merge 1 commit into
Conversation
|
I really like this possibility, but I cannot integrate this change as-is. The changes to libcamera.py would need to be reverted and changes would need to be integrated as a new camera interface. Something like I am not sure if the other changes are breaking or not. |
|
the problem is just that you want libcamera support as the default right? It is not too much work to use python-libcamera to support the low level library in the daemon rather than calling the standalone binaries. I've only used libcamera for rpis but apparently it covered a few more cases. |
|
It is not about it being the default. The current libcamera functionality is currently used by hundreds of people and I need to keep supporting the current method of functionality. Adding a new camera interface is preferred since it allows people to keep using what works, but the additional interface can be used by different users. |
bc5da19 to
26c93a5
Compare
…live stream Single-process picamera2 daemon owns the camera and serves frames via shared memory + Unix socket IPC. Three camera backends: picamera2 (preferred), python3-libcamera (raw bindings), libcamera-still (subprocess fallback). Camera backends (camera_backend.py): - Picamera2Backend, LibcameraBackend, LibcameraStillBackend with auto-detection - LibcameraBackend: control lookup via getattr(libcamera.controls, name) - LibcameraStillBackend: capture lock, timeout wrapper, stale process cleanup, sticky controls, fixed temp filenames, --awb off support - requested_exposure/gain injected into metadata from pending controls Daemon (picamera2_daemon.py): - Backend-agnostic grab loop, set_backend hot-switch via IPC - Watchdog thread: auto-restarts backend if grab loop stalls for 120s - _last_applied tracks controls across frames for OSD synchronization - _capture_time stamped for frame staleness detection Stream and display: - WebSocket preferred (works with gthread via flask-sock/simple-websocket) - /api/stream/frame.jpg: single-frame polling with requestAnimationFrame pacing - /api/stream/metadata: reads directly from daemon socket (no stale cache) - allsky_player.js: _pollInFlight guard, frame_age warning display - OSD shows requested exposure/gain rounded to 2 decimals Dashboard camera controls (capture_buttons.js): - Driver selector (picamera2/libcamera/libcamera-still) - Auto-exposure toggle (TARGET_ADU_DISABLE) with config reload trigger - Exposure slider loads from config DB (CCD_EXPOSURE_MAX), not live metadata - Gain syncs from live metadata, exposure stays at user-set value - Config saves via UPDATE (upsert), not INSERT, to prevent row proliferation Config and capture: - LIBCAMERA.BACKEND field, TARGET_ADU_DISABLE flag - image.py: skip calculate_exposure when TARGET_ADU_DISABLE is set - Slider updates CCD_EXPOSURE_MAX + all mode gains simultaneously - Config level preserved on save, capture worker reload queued on changes - PYTHONDONTWRITEBYTECODE=1 in systemd services
|
@aaronwmorris there you go, leaves the subprocess version and allows switching drivers + disabling auto exposure, these settings are synchronized to the backend configuration. |

Replace rpicam-still/rpicam-vid with picamera2 daemon + WebSocket live stream
Problem
The current libcamera backend spawns separate processes (rpicam-still for capture, rpicam-vid for streaming) that fight over exclusive camera access. The live stream must stop/restart the entire indi-allsky service to acquire the camera, and vice versa.
Solution
A single-process picamera2 daemon that owns the camera and serves both capture and streaming simultaneously via IPC (shared memory + Unix socket).
Changes
Camera daemon (
picamera2_daemon.py):# color/xy/anchor/sizedirectives)Client (
picamera2_client.py):libcamera.py refactor:
setCcdExposureuses daemon client instead of rpicam-still subprocessWebSocket live stream:
[4B JSON len][metadata JSON][JPEG data]Camera controls:
Infrastructure:
picamera2-daemon.service: systemd unit (starts before indi-allsky)wsgi.py: root redirect for direct SSL without reverse proxy_stop_allsky/_start_allskyremoved (no camera contention)flask-sockadded to requirementsTesting