import { ExpiringEqualityCache } from '../cache/expiring-cache'; import { SSLCiphers } from '../config/schema/cameras'; import { AdvancedCameraCardView } from '../config/schema/common/const'; import { InternalIcon } from '../config/schema/common/icon'; import { BaseQuery, QueryFilters, QuerySource } from '../query-source'; import { CapabilityKey, Endpoint } from '../types'; import { ViewMedia } from '../view/item'; // ==== // Base // ==== export enum QueryType { Event = 'event-query', Recording = 'recording-query', RecordingSegments = 'recording-segments-query', MediaMetadata = 'media-metadata', Review = 'review-query', } export enum QueryResultsType { Event = 'event-results', Recording = 'recording-results', RecordingSegments = 'recording-segments-results', MediaMetadata = 'media-metadata-results', Review = 'review-results', } export enum Engine { Frigate = 'frigate', Generic = 'generic', MotionEye = 'motioneye', Reolink = 'reolink', TPLink = 'tplink', } export interface CameraQuery { type: QueryType; cameraIDs: Set; } export type PartialCameraQuery = Partial; interface TimeBasedDataQuery { start: Date; end: Date; } interface LimitedDataQuery { limit: number; } export interface MediaQuery extends BaseQuery, CameraQuery, QueryFilters, Partial, Partial { source: QuerySource.Camera; } export interface QueryResults { type: QueryResultsType; engine: Engine; expiry?: Date; cached?: boolean; } // Generic recording segment type (inspired by Frigate recording segments). export interface RecordingSegment { start_time: number; end_time: number; id: string; } export type QueryReturnType = QT extends EventQuery ? EventQueryResults : QT extends RecordingQuery ? RecordingQueryResults : QT extends RecordingSegmentsQuery ? RecordingSegmentsQueryResults : QT extends MediaMetadataQuery ? MediaMetadataQueryResults : QT extends ReviewQuery ? ReviewQueryResults : never; export type PartialQueryConcreteType = PQT extends PartialEventQuery ? EventQuery : PQT extends PartialRecordingQuery ? RecordingQuery : PQT extends PartialRecordingSegmentsQuery ? RecordingSegmentsQuery : PQT extends PartialReviewQuery ? ReviewQuery : never; export type ResultsMap = Map>; export type EventQueryResultsMap = ResultsMap; export type RecordingQueryResultsMap = ResultsMap; export type RecordingSegmentsQueryResultsMap = ResultsMap; export type MediaMetadataQueryResultsMap = ResultsMap; export interface MediaMetadata { days?: Set; tags?: Set; where?: Set; what?: Set; } interface CapabilitySearchAllAny { allCapabilities?: CapabilityKey[]; anyCapabilities?: CapabilityKey[]; } export type CapabilitySearchKeys = CapabilityKey | CapabilitySearchAllAny; export interface CapabilitySearchOptions { // If true, include a parent camera in results when any of its dependent // (child) cameras have the capability, even if the parent itself doesn't. inclusive?: boolean; } export interface CameraManagerCameraMetadata { title: string; icon: InternalIcon; // Engine icon is just a string since it will never be entity-derived. engineIcon?: string; } export interface CameraEndpointsContext { media?: ViewMedia; view?: AdvancedCameraCardView; } export interface CameraEndpoints { ui?: Endpoint; go2rtc?: Endpoint; jsmpeg?: Endpoint; webrtcCard?: Endpoint; } export interface CameraProxyConfig { dynamic: boolean; live: boolean; media: boolean; ssl_verification: boolean; ssl_ciphers: SSLCiphers; } export interface EngineOptions { useCache?: boolean; } export interface CameraEvent { cameraID: string; // Source ID (e.g. entity ID or Frigate event ID), used to determine what has // triggered/untriggered. id: string; type: | 'new' // A new event has started. | 'update' // An update for an event is available (except GenAI). | 'end' // An event has ended. | 'genai'; // An AI based update is available. // When fidelity is `high`, the engine is assumed to provide exact details of // what new media is available. Otherwise all media types are assumed to be // possibly newly available. fidelity?: 'high' | 'low'; // Whether new media may be available. clip?: boolean; snapshot?: boolean; review?: boolean; } export type CameraEventCallback = (ev: CameraEvent) => void; export class CameraManagerRequestCache extends ExpiringEqualityCache< CameraQuery, QueryResults > {} // ==================== // Default Query Params // ==================== /** * Default query parameters that engines can provide based on camera configuration. */ export interface DefaultQueryParameters { // Object labels (what was detected) what?: Set; // Zones (where detection occurred) where?: Set; } // =========== // Event Query // =========== export interface EventQuery extends MediaQuery { type: QueryType.Event; // Frigate equivalent: has_snapshot hasSnapshot?: boolean; // Frigate equivalent: has_clip hasClip?: boolean; } export type PartialEventQuery = Partial; export interface EventQueryResults extends QueryResults { type: QueryResultsType.Event; } // =============== // Recording Query // =============== export interface RecordingQuery extends MediaQuery { type: QueryType.Recording; } export type PartialRecordingQuery = Partial; export interface RecordingQueryResults extends QueryResults { type: QueryResultsType.Recording; } // ======================== // Recording Segments Query // ======================== export interface RecordingSegmentsQuery extends CameraQuery, TimeBasedDataQuery { type: QueryType.RecordingSegments; } export type PartialRecordingSegmentsQuery = Partial; export interface RecordingSegmentsQueryResults extends QueryResults { type: QueryResultsType.RecordingSegments; segments: RecordingSegment[]; } // ==================== // Media metadata Query // ==================== export interface MediaMetadataQuery extends CameraQuery { type: QueryType.MediaMetadata; } export interface MediaMetadataQueryResults extends QueryResults { type: QueryResultsType.MediaMetadata; metadata: MediaMetadata; } // ============ // Review Query // ============ export interface ReviewQuery extends MediaQuery { type: QueryType.Review; } export type PartialReviewQuery = Partial; export interface ReviewQueryResults extends QueryResults { type: QueryResultsType.Review; } export type ReviewQueryResultsMap = ResultsMap;