Relay P1/A1 camera frames to viewers

GET /printers/:id/snapshot asks the farm's gateway for one JPEG frame
(camera_snapshot_request) and returns it no-store. Concurrent viewers
share one read and a frame under 800 ms old is reused, because the
printer's camera serves one client. /stream answers kind "snapshot" for
these printers; printers.camera_snapshot is set from telemetry.

scripts/e2e-camera-snapshot.sh reads real frames from the P1P through
the real proxy and backend.
This commit is contained in:
2026-10-29 16:11:10 +00:00
parent cd34f7b597
commit a190c896da
10 changed files with 1176 additions and 6 deletions
+6 -1
View File
@@ -1,4 +1,4 @@
import { pgTable, uuid, text, timestamp, jsonb, pgEnum, real, integer, uniqueIndex } from "drizzle-orm/pg-core";
import { pgTable, uuid, text, timestamp, jsonb, pgEnum, real, integer, boolean, uniqueIndex } from "drizzle-orm/pg-core";
import { farms } from "./farms";
export const printerVendorEnum = pgEnum("printer_vendor", ["bambu", "prusa", "klipper"]);
@@ -70,6 +70,11 @@ export const printers = pgTable(
* restream it.
*/
cameraStream: text("camera_stream"),
/**
* The camera can only be read as single JPEG frames (a P1/A1), which the
* gateway serves on request. Mutually exclusive with `cameraStream`.
*/
cameraSnapshot: boolean("camera_snapshot").notNull().default(false),
/**
* The printer's own state string, kept alongside the narrowed
* `status` enum. Worth storing both: the enum is what the UI filters