Move some Frigate specific interfaces under the Frigate engine.

This commit is contained in:
Dermot Duffy
2023-01-24 19:36:54 -08:00
parent e08cb95b16
commit 5385d4d5fd
9 changed files with 39 additions and 43 deletions
+2 -2
View File
@@ -4,7 +4,7 @@ import endOfHour from 'date-fns/endOfHour';
import getUnixTime from 'date-fns/getUnixTime'; import getUnixTime from 'date-fns/getUnixTime';
import startOfHour from 'date-fns/startOfHour'; import startOfHour from 'date-fns/startOfHour';
import { CAMERA_BIRDSEYE } from '../../const'; import { CAMERA_BIRDSEYE } from '../../const';
import { CameraConfig, FrigateRecording, RecordingSegment } from '../../types'; import { CameraConfig, RecordingSegment } from '../../types';
import { MediaQueries, MediaQueriesResults } from '../../view'; import { MediaQueries, MediaQueriesResults } from '../../view';
import { ViewMedia, ViewMediaClassifier, ViewMediaFactory } from '../../view-media'; import { ViewMedia, ViewMediaClassifier, ViewMediaFactory } from '../../view-media';
import { errorToConsole } from '../../utils/basic'; import { errorToConsole } from '../../utils/basic';
@@ -31,7 +31,7 @@ import {
RecordingQuery, RecordingQuery,
RecordingSegmentsQuery, RecordingSegmentsQuery,
} from '../types'; } from '../types';
import { RecordingSummary } from './schema'; import { FrigateRecording, RecordingSummary } from './types';
import { getEvents, getRecordingSegments, getRecordingsSummary, NativeFrigateEventQuery, NativeFrigateRecordingSegmentsQuery, retainEvent } from './requests'; import { getEvents, getRecordingSegments, getRecordingsSummary, NativeFrigateEventQuery, NativeFrigateRecordingSegmentsQuery, retainEvent } from './requests';
const EVENT_REQUEST_CACHE_MAX_AGE_SECONDS = 60; const EVENT_REQUEST_CACHE_MAX_AGE_SECONDS = 60;
+2 -4
View File
@@ -2,12 +2,10 @@ import { HomeAssistant } from 'custom-card-helpers';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import { import {
FrigateCardError, FrigateCardError,
FrigateEvents,
frigateEventsSchema,
RecordingSegment, RecordingSegment,
} from '../../types'; } from '../../types';
import { homeAssistantWSRequest } from '../../utils/ha'; import { homeAssistantWSRequest } from '../../utils/ha';
import { recordingSegmentsSchema, RecordingSummary, recordingSummarySchema, RetainResult, retainResultSchema } from './schema'; import { FrigateEvent, frigateEventsSchema, recordingSegmentsSchema, RecordingSummary, recordingSummarySchema, RetainResult, retainResultSchema } from './types';
/** /**
* Get the recordings summary. May throw. * Get the recordings summary. May throw.
@@ -115,7 +113,7 @@ export interface NativeFrigateEventQuery {
export const getEvents = async ( export const getEvents = async (
hass: HomeAssistant, hass: HomeAssistant,
params?: NativeFrigateEventQuery, params?: NativeFrigateEventQuery,
): Promise<FrigateEvents> => { ): Promise<FrigateEvent[]> => {
return await homeAssistantWSRequest( return await homeAssistantWSRequest(
hass, hass,
frigateEventsSchema, frigateEventsSchema,
@@ -1,5 +1,22 @@
import { z } from 'zod'; import { z } from 'zod';
export const eventSchema = z.object({
camera: z.string(),
end_time: z.number().nullable(),
false_positive: z.boolean().nullable(),
has_clip: z.boolean(),
has_snapshot: z.boolean(),
id: z.string(),
label: z.string(),
start_time: z.number(),
top_score: z.number(),
zones: z.string().array(),
retain_indefinitely: z.boolean().optional(),
});
export const frigateEventsSchema = eventSchema.array();
export type FrigateEvent = z.infer<typeof eventSchema>;
const recordingSummaryHourSchema = z.object({ const recordingSummaryHourSchema = z.object({
hour: z.preprocess((arg) => Number(arg), z.number().min(0).max(23)), hour: z.preprocess((arg) => Number(arg), z.number().min(0).max(23)),
duration: z.number().min(0), duration: z.number().min(0),
@@ -31,3 +48,11 @@ export const retainResultSchema = z.object({
message: z.string(), message: z.string(),
}); });
export type RetainResult = z.infer<typeof retainResultSchema>; export type RetainResult = z.infer<typeof retainResultSchema>;
export interface FrigateRecording {
// Frigate camera name (may not be unique)
camera: string;
start_time: number;
end_time: number;
events: number;
}
+2 -5
View File
@@ -1,11 +1,8 @@
import utcToZonedTime from 'date-fns-tz/utcToZonedTime'; import utcToZonedTime from 'date-fns-tz/utcToZonedTime';
import fromUnixTime from 'date-fns/fromUnixTime'; import fromUnixTime from 'date-fns/fromUnixTime';
import { import { ClipsOrSnapshots } from '../../types';
ClipsOrSnapshots,
FrigateEvent,
FrigateRecording,
} from '../../types';
import { formatDateAndTime, prettifyTitle } from '../../utils/basic'; import { formatDateAndTime, prettifyTitle } from '../../utils/basic';
import { FrigateEvent, FrigateRecording } from './types';
/** /**
* Given an event generate a title. * Given an event generate a title.
+3 -2
View File
@@ -1,4 +1,5 @@
import { FrigateEvents, FrigateRecording, RecordingSegment } from '../types'; import { RecordingSegment } from '../types';
import { FrigateEvent, FrigateRecording } from './frigate/types';
// ==== // ====
// Base // Base
@@ -119,7 +120,7 @@ export interface RecordingSegmentsQueryResults extends QueryResults {
export interface FrigateEventQueryResults extends EventQueryResults { export interface FrigateEventQueryResults extends EventQueryResults {
engine: Engine.Frigate; engine: Engine.Frigate;
events: FrigateEvents; events: FrigateEvent[];
} }
export interface FrigateRecordingQueryResults extends RecordingQueryResults { export interface FrigateRecordingQueryResults extends RecordingQueryResults {
+2 -26
View File
@@ -13,6 +13,7 @@ import {
} from 'custom-card-helpers'; } from 'custom-card-helpers';
import { StyleInfo } from 'lit/directives/style-map.js'; import { StyleInfo } from 'lit/directives/style-map.js';
import { z } from 'zod'; import { z } from 'zod';
import { eventSchema, FrigateEvent, FrigateRecording } from './camera/frigate/types.js';
import { deepRemoveDefaults } from './utils/zod.js'; import { deepRemoveDefaults } from './utils/zod.js';
// The min allowed size of buttons. // The min allowed size of buttons.
@@ -1415,14 +1416,6 @@ export interface BrowseMediaSource {
children?: BrowseMediaSource[] | null; children?: BrowseMediaSource[] | null;
} }
export interface FrigateRecording {
// Frigate camera name (may not be unique)
camera: string;
start_time: number;
end_time: number;
events: number;
}
export interface FrigateBrowseMediaSource extends BrowseMediaSource { export interface FrigateBrowseMediaSource extends BrowseMediaSource {
children?: FrigateBrowseMediaSource[] | null; children?: FrigateBrowseMediaSource[] | null;
frigate?: { frigate?: {
@@ -1432,23 +1425,6 @@ export interface FrigateBrowseMediaSource extends BrowseMediaSource {
}; };
} }
export const frigateEventSchema = z.object({
camera: z.string(),
end_time: z.number().nullable(),
false_positive: z.boolean().nullable(),
has_clip: z.boolean(),
has_snapshot: z.boolean(),
id: z.string(),
label: z.string(),
start_time: z.number(),
top_score: z.number(),
zones: z.string().array(),
retain_indefinitely: z.boolean().optional(),
});
export type FrigateEvent = z.infer<typeof frigateEventSchema>;
export const frigateEventsSchema = frigateEventSchema.array();
export type FrigateEvents = z.infer<typeof frigateEventsSchema>;
export const frigateBrowseMediaSourceSchema: z.ZodSchema<BrowseMediaSource> = z.lazy( export const frigateBrowseMediaSourceSchema: z.ZodSchema<BrowseMediaSource> = z.lazy(
() => () =>
@@ -1464,7 +1440,7 @@ export const frigateBrowseMediaSourceSchema: z.ZodSchema<BrowseMediaSource> = z.
children: z.array(frigateBrowseMediaSourceSchema).nullable().optional(), children: z.array(frigateBrowseMediaSourceSchema).nullable().optional(),
frigate: z frigate: z
.object({ .object({
event: frigateEventSchema, event: eventSchema,
}) })
.optional(), .optional(),
}), }),
+1 -2
View File
@@ -1,5 +1,6 @@
import { HomeAssistant } from 'custom-card-helpers'; import { HomeAssistant } from 'custom-card-helpers';
import { homeAssistantWSRequest } from '.'; import { homeAssistantWSRequest } from '.';
import { FrigateEvent, FrigateRecording } from '../../camera/frigate/types';
import { dispatchErrorMessageEvent } from '../../components/message.js'; import { dispatchErrorMessageEvent } from '../../components/message.js';
import { localize } from '../../localize/localize.js'; import { localize } from '../../localize/localize.js';
import { import {
@@ -9,8 +10,6 @@ import {
ClipsOrSnapshots, ClipsOrSnapshots,
FrigateBrowseMediaSource, FrigateBrowseMediaSource,
frigateBrowseMediaSourceSchema, frigateBrowseMediaSourceSchema,
FrigateEvent,
FrigateRecording,
MEDIA_CLASS_PLAYLIST, MEDIA_CLASS_PLAYLIST,
MEDIA_CLASS_VIDEO, MEDIA_CLASS_VIDEO,
MEDIA_TYPE_PLAYLIST, MEDIA_TYPE_PLAYLIST,
+1 -2
View File
@@ -3,8 +3,6 @@ import isEqual from 'lodash-es/isEqual';
import { import {
BrowseMediaSource, BrowseMediaSource,
CameraConfig, CameraConfig,
FrigateEvent,
FrigateRecording,
MEDIA_TYPE_IMAGE, MEDIA_TYPE_IMAGE,
} from './types.js'; } from './types.js';
import { ModifyInterface } from './utils/basic.js'; import { ModifyInterface } from './utils/basic.js';
@@ -15,6 +13,7 @@ import {
getRecordingMediaContentID, getRecordingMediaContentID,
getRecordingTitle, getRecordingTitle,
} from './camera/frigate/util.js'; } from './camera/frigate/util.js';
import { FrigateEvent, FrigateRecording } from './camera/frigate/types.js';
export type ViewMediaType = 'clip' | 'snapshot' | 'recording'; export type ViewMediaType = 'clip' | 'snapshot' | 'recording';
export type ViewMediaSourceType = FrigateEvent | FrigateRecording | BrowseMediaSource; export type ViewMediaSourceType = FrigateEvent | FrigateRecording | BrowseMediaSource;
+1
View File
@@ -20,6 +20,7 @@
// Hard: // Hard:
// - TODO: Implement dragging the timeline seeking forward in both Frigate recordings & events. // - TODO: Implement dragging the timeline seeking forward in both Frigate recordings & events.
// - TODO: Implement gallery. // - TODO: Implement gallery.
// - TODO: Remove FrigateBrowseMediaSource if not necessary (post-gallery).
// - TODO: In generateMediaViewerContext there is an assumption that recordings start/end on the hour, which is true for Frigate but that assumption should be in the engine. // - TODO: In generateMediaViewerContext there is an assumption that recordings start/end on the hour, which is true for Frigate but that assumption should be in the engine.
// - TODO: What should the timeline do when an event is clicked on that is not in the queryResults (or if queryResults is empty)? // - TODO: What should the timeline do when an event is clicked on that is not in the queryResults (or if queryResults is empty)?
// - TODO: Should the timeline data source clear events (as it currently does) when the query changes? // - TODO: Should the timeline data source clear events (as it currently does) when the query changes?