Rename DataManager to CameraManager.

This commit is contained in:
Dermot Duffy
2023-01-24 19:36:54 -08:00
parent e0d2dfaa60
commit 39b44863ce
23 changed files with 183 additions and 187 deletions
@@ -1,9 +1,9 @@
import isEqual from 'lodash-es/isEqual'; import isEqual from 'lodash-es/isEqual';
import orderBy from 'lodash-es/orderBy'; import orderBy from 'lodash-es/orderBy';
import sortedUniqBy from 'lodash-es/sortedUniqBy'; import sortedUniqBy from 'lodash-es/sortedUniqBy';
import { RecordingSegment, RecordingSegments } from '../frigate'; import { RecordingSegment, RecordingSegments } from '../utils/frigate';
import { DateRange, MemoryRangeSet } from './data-manager-range'; import { DateRange, MemoryRangeSet } from './range';
import { DataQuery, QueryResults } from './data-types'; import { DataQuery, QueryResults } from './types';
interface RequestCacheItem<Request, Response> { interface RequestCacheItem<Request, Response> {
request: Request; request: Request;
@@ -11,14 +11,14 @@ interface RequestCacheItem<Request, Response> {
expires?: Date; expires?: Date;
} }
interface DataManagerCache<Request, Response> { interface CameraManagerCache<Request, Response> {
get(request: Request): Response | null; get(request: Request): Response | null;
has(request: Request): boolean; has(request: Request): boolean;
set(request: Request, response: Response, expiry?: Date): void; set(request: Request, response: Response, expiry?: Date): void;
} }
export class MemoryRequestCache<Request, Response> export class MemoryRequestCache<Request, Response>
implements DataManagerCache<Request, Response> implements CameraManagerCache<Request, Response>
{ {
protected _data: RequestCacheItem<Request, Response>[] = []; protected _data: RequestCacheItem<Request, Response>[] = [];
+42
View File
@@ -0,0 +1,42 @@
import { CameraConfig } from '../types';
import { RecordingSegmentsCache } from './cache';
import { CameraManagerEngine } from './engine';
import { FrigateCameraManagerEngine } from './engine-frigate';
import { DataQuery } from './types';
export class CameraManagerEngineFactory {
protected _engines: Map<string, CameraManagerEngine> = new Map();
protected _getOrCreateEngine(engineKey: string): CameraManagerEngine | null {
const cachedEngine = this._engines.get(engineKey);
if (cachedEngine) {
return cachedEngine;
}
let newEngine: CameraManagerEngine | null = null;
switch (engineKey) {
case 'frigate':
newEngine = new FrigateCameraManagerEngine(new RecordingSegmentsCache());
break;
}
if (newEngine) {
this._engines.set(engineKey, newEngine);
}
return newEngine;
}
public getEngineForQuery(
cameras: Map<string, CameraConfig>,
query: DataQuery,
): CameraManagerEngine | null {
const cameraConfig = cameras.get(query.cameraID);
return cameraConfig ? this.getEngineForCamera(cameraConfig) : null;
}
public getEngineForCamera(cameraConfig: CameraConfig): CameraManagerEngine | null {
let engineKey: string | null = null;
if (cameraConfig.frigate.camera_name) {
engineKey = 'frigate';
}
return engineKey ? this._getOrCreateEngine(engineKey) : null;
}
}
@@ -3,11 +3,11 @@ import add from 'date-fns/add';
import endOfHour from 'date-fns/endOfHour'; 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 } from '../../types'; import { CameraConfig, FrigateRecording } 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 '../basic'; import { errorToConsole } from '../utils/basic';
import { import {
getEvents, getEvents,
getRecordingSegments, getRecordingSegments,
@@ -17,14 +17,14 @@ import {
RecordingSegments, RecordingSegments,
RecordingSummary, RecordingSummary,
retainEvent, retainEvent,
} from '../frigate'; } from '../utils/frigate';
import { RecordingSegmentsCache } from './data-manager-cache'; import { RecordingSegmentsCache } from './cache';
import { import {
DataManagerEngine, CameraManagerEngine,
DATA_MANAGER_ENGINE_EVENT_LIMIT_DEFAULT, CAMERA_MANAGER_ENGINE_EVENT_LIMIT_DEFAULT,
} from './data-manager-engine'; } from './engine';
import { DataManagerError } from './data-manager-error'; import { CameraManagerError } from './error';
import { DateRange } from './data-manager-range'; import { DateRange } from './range';
import { import {
Engine, Engine,
EventQuery, EventQuery,
@@ -40,7 +40,7 @@ import {
QueryType, QueryType,
RecordingQuery, RecordingQuery,
RecordingSegmentsQuery, RecordingSegmentsQuery,
} from './data-types'; } from './types';
const EVENT_REQUEST_CACHE_MAX_AGE_SECONDS = 60; const EVENT_REQUEST_CACHE_MAX_AGE_SECONDS = 60;
const RECORDING_SUMMARY_REQUEST_CACHE_MAX_AGE_SECONDS = 60; const RECORDING_SUMMARY_REQUEST_CACHE_MAX_AGE_SECONDS = 60;
@@ -70,7 +70,7 @@ class FrigateQueryResultsClassifier {
} }
} }
export class FrigateDataManagerEngine implements DataManagerEngine { export class FrigateCameraManagerEngine implements CameraManagerEngine {
protected _recordingSegmentsCache: RecordingSegmentsCache; protected _recordingSegmentsCache: RecordingSegmentsCache;
constructor(recordingSegmentsCache: RecordingSegmentsCache) { constructor(recordingSegmentsCache: RecordingSegmentsCache) {
@@ -157,7 +157,7 @@ export class FrigateDataManagerEngine implements DataManagerEngine {
await retainEvent(hass, clientID, media.getID(cameraConfig), favorite); await retainEvent(hass, clientID, media.getID(cameraConfig), favorite);
} catch (e) { } catch (e) {
errorToConsole(e as Error); errorToConsole(e as Error);
throw new DataManagerError((e as Error).message); throw new CameraManagerError((e as Error).message);
} }
media.setFavorite(favorite); media.setFavorite(favorite);
@@ -183,7 +183,7 @@ export class FrigateDataManagerEngine implements DataManagerEngine {
...(query?.limit && { limit: query.limit }), ...(query?.limit && { limit: query.limit }),
...(query?.hasClip && { has_clip: query.hasClip }), ...(query?.hasClip && { has_clip: query.hasClip }),
...(query?.hasSnapshot && { has_snapshot: query.hasSnapshot }), ...(query?.hasSnapshot && { has_snapshot: query.hasSnapshot }),
limit: query?.limit ?? DATA_MANAGER_ENGINE_EVENT_LIMIT_DEFAULT, limit: query?.limit ?? CAMERA_MANAGER_ENGINE_EVENT_LIMIT_DEFAULT,
}; };
try { try {
@@ -196,7 +196,7 @@ export class FrigateDataManagerEngine implements DataManagerEngine {
return result; return result;
} catch (e) { } catch (e) {
errorToConsole(e as Error); errorToConsole(e as Error);
throw new DataManagerError((e as Error).message, query); throw new CameraManagerError((e as Error).message, query);
} }
} }
@@ -222,7 +222,7 @@ export class FrigateDataManagerEngine implements DataManagerEngine {
); );
} catch (e) { } catch (e) {
errorToConsole(e as Error); errorToConsole(e as Error);
throw new DataManagerError((e as Error).message, query); throw new CameraManagerError((e as Error).message, query);
} }
const recordings: FrigateRecording[] = []; const recordings: FrigateRecording[] = [];
@@ -295,7 +295,7 @@ export class FrigateDataManagerEngine implements DataManagerEngine {
segments = await getRecordingSegments(hass, request); segments = await getRecordingSegments(hass, request);
} catch (e) { } catch (e) {
errorToConsole(e as Error); errorToConsole(e as Error);
throw new DataManagerError((e as Error).message, query); throw new CameraManagerError((e as Error).message, query);
} }
this._recordingSegmentsCache.add(query.cameraID, range, segments); this._recordingSegmentsCache.add(query.cameraID, range, segments);
@@ -1,7 +1,7 @@
import { HomeAssistant } from 'custom-card-helpers'; import { HomeAssistant } from 'custom-card-helpers';
import { CameraConfig } from '../../types'; import { CameraConfig } from '../types';
import { MediaQueries, MediaQueriesResults } from '../../view'; import { MediaQueries, MediaQueriesResults } from '../view';
import { ViewMedia } from '../../view-media'; import { ViewMedia } from '../view-media';
import { import {
EventQuery, EventQuery,
PartialEventQuery, PartialEventQuery,
@@ -10,11 +10,11 @@ import {
QueryReturnType, QueryReturnType,
RecordingQuery, RecordingQuery,
RecordingSegmentsQuery, RecordingSegmentsQuery,
} from './data-types'; } from './types';
export const DATA_MANAGER_ENGINE_EVENT_LIMIT_DEFAULT = 10000; export const CAMERA_MANAGER_ENGINE_EVENT_LIMIT_DEFAULT = 10000;
export interface DataManagerEngine { export interface CameraManagerEngine {
generateDefaultEventQuery( generateDefaultEventQuery(
cameraID: string, cameraID: string,
cameraConfig: CameraConfig, cameraConfig: CameraConfig,
+3
View File
@@ -0,0 +1,3 @@
import { FrigateCardError } from '../types';
export class CameraManagerError extends FrigateCardError {}
@@ -1,6 +1,6 @@
import { HomeAssistant } from 'custom-card-helpers'; import { HomeAssistant } from 'custom-card-helpers';
import { CameraConfig } from '../../types.js'; import { CameraConfig } from '../types.js';
import { arrayify, setify } from '../basic.js'; import { arrayify, setify } from '../utils/basic.js';
import { import {
DataQuery, DataQuery,
EventQuery, EventQuery,
@@ -18,12 +18,12 @@ import {
RecordingQueryResults, RecordingQueryResults,
RecordingSegmentsQuery, RecordingSegmentsQuery,
RecordingSegmentsQueryResults, RecordingSegmentsQueryResults,
} from './data-types.js'; } from './types.js';
import orderBy from 'lodash-es/orderBy'; import orderBy from 'lodash-es/orderBy';
import { DataManagerEngineFactory } from './data-manager-engine-factory.js'; import { CameraManagerEngineFactory } from './engine-factory.js';
import { ViewMedia } from '../../view-media.js'; import { ViewMedia } from '../view-media.js';
import { MediaQueries, MediaQueriesResults } from '../../view.js'; import { MediaQueries, MediaQueriesResults } from '../view.js';
import { MemoryRequestCache } from './data-manager-cache.js'; import { MemoryRequestCache } from './cache.js';
export class QueryClassifier { export class QueryClassifier {
public static isEventQuery(query: DataQuery | PartialDataQuery): query is EventQuery { public static isEventQuery(query: DataQuery | PartialDataQuery): query is EventQuery {
@@ -61,13 +61,13 @@ export class QueryResultClassifier {
export type RequestCache = MemoryRequestCache<DataQuery, QueryResults>; export type RequestCache = MemoryRequestCache<DataQuery, QueryResults>;
export class DataManager { export class CameraManager {
protected _engineFactory: DataManagerEngineFactory; protected _engineFactory: CameraManagerEngineFactory;
protected _cameras: Map<string, CameraConfig>; protected _cameras: Map<string, CameraConfig>;
protected _requestCache: RequestCache; protected _requestCache: RequestCache;
constructor( constructor(
engineFactory: DataManagerEngineFactory, engineFactory: CameraManagerEngineFactory,
cameras: Map<string, CameraConfig>, cameras: Map<string, CameraConfig>,
requestCache: RequestCache, requestCache: RequestCache,
) { ) {
@@ -296,7 +296,7 @@ export class DataManager {
await Promise.all(_queries.map((query) => processQuery(query))); await Promise.all(_queries.map((query) => processQuery(query)));
console.debug( console.debug(
'Frigate Card DataManager request (Cached:', 'Frigate Card CameraManager request (Cached:',
`${queryCachedCount}/${_queries.length},`, `${queryCachedCount}/${_queries.length},`,
`Duration: ${(new Date().getTime() - queryStartTime.getTime()) / 1000}s,`, `Duration: ${(new Date().getTime() - queryStartTime.getTime()) / 1000}s,`,
'Queries:', 'Queries:',
@@ -1,5 +1,5 @@
import { FrigateEvents, FrigateRecording } from '../../types'; import { FrigateEvents, FrigateRecording } from '../types';
import { RecordingSegments } from '../frigate'; import { RecordingSegments } from '../utils/frigate';
// ==== // ====
// Base // Base
@@ -5,7 +5,7 @@ import endOfDay from 'date-fns/endOfDay';
import endOfMinute from 'date-fns/endOfMinute'; import endOfMinute from 'date-fns/endOfMinute';
import endOfWeek from 'date-fns/endOfWeek'; import endOfWeek from 'date-fns/endOfWeek';
import startOfWeek from 'date-fns/startOfWeek'; import startOfWeek from 'date-fns/startOfWeek';
import { DateRange } from './data-manager-range'; import { DateRange } from './range';
export const convertRangeToCacheFriendlyTimes = ( export const convertRangeToCacheFriendlyTimes = (
range: DateRange, range: DateRange,
+11 -11
View File
@@ -91,10 +91,10 @@ import { isValidMediaLoadedInfo } from './utils/media-info.js';
import { View } from './view.js'; import { View } from './view.js';
import pkg from '../package.json'; import pkg from '../package.json';
import { ViewContext } from 'view'; import { ViewContext } from 'view';
import { DataManager } from './utils/data/data-manager.js'; import { CameraManager } from './camera/manager.js';
import { setLowPerformanceProfile, setPerformanceCSSStyles } from './performance.js'; import { setLowPerformanceProfile, setPerformanceCSSStyles } from './performance.js';
import { DataManagerEngineFactory } from './utils/data/data-manager-engine-factory.js'; import { CameraManagerEngineFactory } from './camera/engine-factory.js';
import { RequestCache } from './utils/data/data-manager-cache.js'; import { RequestCache } from './camera/cache.js';
/** A note on media callbacks: /** A note on media callbacks:
* *
@@ -205,7 +205,7 @@ export class FrigateCard extends LitElement {
// A cache of resolved media URLs/mimetypes for use in the whole card. // A cache of resolved media URLs/mimetypes for use in the whole card.
protected _resolvedMediaCache = new ResolvedMediaCache(); protected _resolvedMediaCache = new ResolvedMediaCache();
protected _dataManager?: DataManager; protected _cameraManager?: CameraManager;
// The mouse handler may be called continually, throttle it to at most once // The mouse handler may be called continually, throttle it to at most once
// per second for performance reasons. // per second for performance reasons.
@@ -1101,8 +1101,8 @@ export class FrigateCard extends LitElement {
*/ */
protected willUpdate(changedProps: PropertyValues): void { protected willUpdate(changedProps: PropertyValues): void {
if (this._cameras && (changedProps.has('_config') || changedProps.has('_cameras'))) { if (this._cameras && (changedProps.has('_config') || changedProps.has('_cameras'))) {
this._dataManager = new DataManager( this._cameraManager = new CameraManager(
new DataManagerEngineFactory(), new CameraManagerEngineFactory(),
this._cameras, this._cameras,
new RequestCache(), new RequestCache(),
); );
@@ -1336,7 +1336,7 @@ export class FrigateCard extends LitElement {
return; return;
} }
const path = this._dataManager?.getMediaDownloadPath(media); const path = this._cameraManager?.getMediaDownloadPath(media);
if (!path) { if (!path) {
return; return;
} }
@@ -2018,7 +2018,7 @@ export class FrigateCard extends LitElement {
.view=${this._view} .view=${this._view}
.cameras=${this._cameras} .cameras=${this._cameras}
.galleryConfig=${this._getConfig().event_gallery} .galleryConfig=${this._getConfig().event_gallery}
.dataManager=${this._dataManager} .cameraManager=${this._cameraManager}
.cardWideConfig=${this._cardWideConfig} .cardWideConfig=${this._cardWideConfig}
> >
</frigate-card-gallery>` </frigate-card-gallery>`
@@ -2030,7 +2030,7 @@ export class FrigateCard extends LitElement {
.cameras=${this._cameras} .cameras=${this._cameras}
.viewerConfig=${this._getConfig().media_viewer} .viewerConfig=${this._getConfig().media_viewer}
.resolvedMediaCache=${this._resolvedMediaCache} .resolvedMediaCache=${this._resolvedMediaCache}
.dataManager=${this._dataManager} .cameraManager=${this._cameraManager}
.cardWideConfig=${this._cardWideConfig} .cardWideConfig=${this._cardWideConfig}
> >
</frigate-card-viewer>` </frigate-card-viewer>`
@@ -2041,7 +2041,7 @@ export class FrigateCard extends LitElement {
.view=${this._view} .view=${this._view}
.cameras=${this._cameras} .cameras=${this._cameras}
.timelineConfig=${this._getConfig().timeline} .timelineConfig=${this._getConfig().timeline}
.dataManager=${this._dataManager} .cameraManager=${this._cameraManager}
> >
</frigate-card-timeline>` </frigate-card-timeline>`
: ``} : ``}
@@ -2062,7 +2062,7 @@ export class FrigateCard extends LitElement {
.conditionState=${this._conditionState} .conditionState=${this._conditionState}
.liveOverrides=${getOverridesByKey(this._getConfig().overrides, 'live')} .liveOverrides=${getOverridesByKey(this._getConfig().overrides, 'live')}
.cameras=${this._cameras} .cameras=${this._cameras}
.dataManager=${this._dataManager} .cameraManager=${this._cameraManager}
.cardWideConfig=${this._cardWideConfig} .cardWideConfig=${this._cardWideConfig}
class="${classMap(liveClasses)}" class="${classMap(liveClasses)}"
> >
+5 -5
View File
@@ -22,7 +22,7 @@ import {
getFullDependentBrowseMediaQueryParametersOrDispatchError, getFullDependentBrowseMediaQueryParametersOrDispatchError,
} from '../utils/ha/browse-media'; } from '../utils/ha/browse-media';
import { changeViewToRecentEventsForCameraAndDependents, changeViewToRecentRecordingForCameraAndDependents } from '../utils/media-to-view.js'; import { changeViewToRecentEventsForCameraAndDependents, changeViewToRecentRecordingForCameraAndDependents } from '../utils/media-to-view.js';
import { DataManager } from '../utils/data/data-manager.js'; import { CameraManager } from '../camera/manager.js';
import { View } from '../view.js'; import { View } from '../view.js';
import { renderProgressIndicator } from './message.js'; import { renderProgressIndicator } from './message.js';
import './thumbnail.js'; import './thumbnail.js';
@@ -54,7 +54,7 @@ export class FrigateCardGallery extends LitElement {
public cameras?: Map<string, CameraConfig>; public cameras?: Map<string, CameraConfig>;
@property({ attribute: false }) @property({ attribute: false })
public dataManager?: DataManager; public cameraManager?: CameraManager;
@property({ attribute: false }) @property({ attribute: false })
public cardWideConfig?: CardWideConfig; public cardWideConfig?: CardWideConfig;
@@ -71,7 +71,7 @@ export class FrigateCardGallery extends LitElement {
// !this.cameras || // !this.cameras ||
// !this.view.isGalleryView() || // !this.view.isGalleryView() ||
// !mediaType || // !mediaType ||
// !this.dataManager // !this.cameraManager
// ) { // ) {
// return; // return;
// } // }
@@ -81,7 +81,7 @@ export class FrigateCardGallery extends LitElement {
// changeViewToRecentRecordingForCameraAndDependents( // changeViewToRecentRecordingForCameraAndDependents(
// this, // this,
// this.hass, // this.hass,
// this.dataManager, // this.cameraManager,
// this.cameras, // this.cameras,
// this.view, // this.view,
// { // {
@@ -92,7 +92,7 @@ export class FrigateCardGallery extends LitElement {
// changeViewToRecentEventsForCameraAndDependents( // changeViewToRecentEventsForCameraAndDependents(
// this, // this,
// this.hass, // this.hass,
// this.dataManager, // this.cameraManager,
// this.cameras, // this.cameras,
// this.view, // this.view,
// { // {
+3 -3
View File
@@ -51,7 +51,7 @@ import '../surround.js';
import { EmblaCarouselPlugins } from '../carousel.js'; import { EmblaCarouselPlugins } from '../carousel.js';
import { classMap } from 'lit/directives/class-map.js'; import { classMap } from 'lit/directives/class-map.js';
import { updateElementStyleFromMediaLayoutConfig } from '../../utils/media-layout.js'; import { updateElementStyleFromMediaLayoutConfig } from '../../utils/media-layout.js';
import { DataManager } from '../../utils/data/data-manager.js'; import { CameraManager } from '../../camera/manager.js';
import { HomeAssistant } from 'custom-card-helpers'; import { HomeAssistant } from 'custom-card-helpers';
import { dispatchMessageEvent, dispatchErrorMessageEvent } from '../message.js'; import { dispatchMessageEvent, dispatchErrorMessageEvent } from '../message.js';
import { HassEntity } from 'home-assistant-js-websocket'; import { HassEntity } from 'home-assistant-js-websocket';
@@ -115,7 +115,7 @@ export class FrigateCardLive extends LitElement {
public liveOverrides?: LiveOverrides; public liveOverrides?: LiveOverrides;
@property({ attribute: false }) @property({ attribute: false })
public dataManager?: DataManager; public cameraManager?: CameraManager;
@property({ attribute: false }) @property({ attribute: false })
public cardWideConfig?: CardWideConfig; public cardWideConfig?: CardWideConfig;
@@ -231,7 +231,7 @@ export class FrigateCardLive extends LitElement {
.thumbnailConfig=${config.controls.thumbnails} .thumbnailConfig=${config.controls.thumbnails}
.timelineConfig=${config.controls.timeline} .timelineConfig=${config.controls.timeline}
.cameras=${this.cameras} .cameras=${this.cameras}
.dataManager=${this.dataManager} .cameraManager=${this.cameraManager}
.inBackground=${this._inBackground} .inBackground=${this._inBackground}
@frigate-card:message=${(ev: CustomEvent<Message>) => { @frigate-card:message=${(ev: CustomEvent<Message>) => {
this._renderKey++; this._renderKey++;
+6 -6
View File
@@ -16,7 +16,7 @@ import {
ThumbnailsControlConfig, ThumbnailsControlConfig,
} from '../types.js'; } from '../types.js';
import { contentsChanged, dispatchFrigateCardEvent } from '../utils/basic.js'; import { contentsChanged, dispatchFrigateCardEvent } from '../utils/basic.js';
import { DataManager } from '../utils/data/data-manager.js'; import { CameraManager } from '../camera/manager.js';
import { View } from '../view.js'; import { View } from '../view.js';
import { ThumbnailCarouselTap } from './thumbnail-carousel.js'; import { ThumbnailCarouselTap } from './thumbnail-carousel.js';
import './surround-basic.js'; import './surround-basic.js';
@@ -58,7 +58,7 @@ export class FrigateCardSurround extends LitElement {
public cameras?: Map<string, CameraConfig>; public cameras?: Map<string, CameraConfig>;
@property({ attribute: false }) @property({ attribute: false })
public dataManager?: DataManager; public cameraManager?: CameraManager;
/** /**
* Fetch thumbnail media when a target is not specified in the view (e.g. for * Fetch thumbnail media when a target is not specified in the view (e.g. for
@@ -69,7 +69,7 @@ export class FrigateCardSurround extends LitElement {
protected async _fetchMedia(): Promise<void> { protected async _fetchMedia(): Promise<void> {
if ( if (
!this.cameras || !this.cameras ||
!this.dataManager || !this.cameraManager ||
!this.fetchMedia || !this.fetchMedia ||
this.inBackground || this.inBackground ||
!this.hass || !this.hass ||
@@ -84,7 +84,7 @@ export class FrigateCardSurround extends LitElement {
await changeViewToRecentEventsForCameraAndDependents( await changeViewToRecentEventsForCameraAndDependents(
this, this,
this.hass, this.hass,
this.dataManager, this.cameraManager,
this.cameras, this.cameras,
this.view, this.view,
{ {
@@ -156,7 +156,7 @@ export class FrigateCardSurround extends LitElement {
slot=${this.thumbnailConfig.mode} slot=${this.thumbnailConfig.mode}
.hass=${this.hass} .hass=${this.hass}
.config=${this.thumbnailConfig} .config=${this.thumbnailConfig}
.dataManager=${this.dataManager} .cameraManager=${this.cameraManager}
.view=${this.view} .view=${this.view}
.cameras=${this.cameras} .cameras=${this.cameras}
.selected=${this.view.queryResults?.getSelectedIndex() ?? undefined} .selected=${this.view.queryResults?.getSelectedIndex() ?? undefined}
@@ -194,7 +194,7 @@ export class FrigateCardSurround extends LitElement {
.timelineConfig=${this.timelineConfig} .timelineConfig=${this.timelineConfig}
.thumbnailDetails=${this.thumbnailConfig?.show_details} .thumbnailDetails=${this.thumbnailConfig?.show_details}
.thumbnailSize=${this.thumbnailConfig?.size} .thumbnailSize=${this.thumbnailConfig?.size}
.dataManager=${this.dataManager} .cameraManager=${this.cameraManager}
> >
</frigate-card-timeline-core>` </frigate-card-timeline-core>`
: ''} : ''}
+3 -3
View File
@@ -24,7 +24,7 @@ import { FrigateCardCarousel } from './carousel.js';
import './thumbnail.js'; import './thumbnail.js';
import './carousel.js'; import './carousel.js';
import { ifDefined } from 'lit/directives/if-defined.js'; import { ifDefined } from 'lit/directives/if-defined.js';
import { DataManager } from '../utils/data/data-manager.js'; import { CameraManager } from '../camera/manager.js';
export interface ThumbnailCarouselTap { export interface ThumbnailCarouselTap {
queryResults: MediaQueriesResults; queryResults: MediaQueriesResults;
@@ -42,7 +42,7 @@ export class FrigateCardThumbnailCarousel extends LitElement {
public cameras?: Map<string, CameraConfig>; public cameras?: Map<string, CameraConfig>;
@property({ attribute: false }) @property({ attribute: false })
public dataManager?: DataManager; public cameraManager?: CameraManager;
protected _refCarousel: Ref<FrigateCardCarousel> = createRef(); protected _refCarousel: Ref<FrigateCardCarousel> = createRef();
@@ -161,7 +161,7 @@ export class FrigateCardThumbnailCarousel extends LitElement {
return html` <frigate-card-thumbnail return html` <frigate-card-thumbnail
class="${classMap(classes)}" class="${classMap(classes)}"
.dataManager=${this.dataManager} .cameraManager=${this.cameraManager}
.hass=${this.hass} .hass=${this.hass}
.media=${media} .media=${media}
.cameraConfig=${cameraConfig} .cameraConfig=${cameraConfig}
+4 -4
View File
@@ -19,7 +19,7 @@ import { TaskStatus } from '@lit-labs/task';
import type { CameraConfig, ExtendedHomeAssistant } from '../types.js'; import type { CameraConfig, ExtendedHomeAssistant } from '../types.js';
import { ViewMedia } from '../view-media.js'; import { ViewMedia } from '../view-media.js';
import { DataManager } from '../utils/data/data-manager.js'; import { CameraManager } from '../camera/manager.js';
// The minimum width of a thumbnail with details enabled. // The minimum width of a thumbnail with details enabled.
export const THUMBNAIL_DETAILS_WIDTH_MIN = 300; export const THUMBNAIL_DETAILS_WIDTH_MIN = 300;
@@ -221,9 +221,9 @@ export class FrigateCardThumbnail extends LitElement {
@property({ attribute: false }) @property({ attribute: false })
public hass?: ExtendedHomeAssistant; public hass?: ExtendedHomeAssistant;
// DataManager used for marking media as favorite. // CameraManager used for marking media as favorite.
@property({ attribute: false }) @property({ attribute: false })
public dataManager?: DataManager; public cameraManager?: CameraManager;
@property({ attribute: true }) @property({ attribute: true })
public media?: ViewMedia; public media?: ViewMedia;
@@ -296,7 +296,7 @@ export class FrigateCardThumbnail extends LitElement {
@click=${(ev: Event) => { @click=${(ev: Event) => {
stopEventFromActivatingCardWideActions(ev); stopEventFromActivatingCardWideActions(ev);
if (this.hass && this.cameraConfig && this.media) { if (this.hass && this.cameraConfig && this.media) {
this.dataManager?.favoriteMedia( this.cameraManager?.favoriteMedia(
this.hass, this.hass,
this.cameraConfig, this.cameraConfig,
this.media, this.media,
+22 -22
View File
@@ -49,13 +49,13 @@ import {
createViewForRecordings, createViewForRecordings,
generateMediaViewerContext, generateMediaViewerContext,
} from '../utils/media-to-view'; } from '../utils/media-to-view';
import { DataManager } from '../utils/data/data-manager'; import { CameraManager } from '../camera/manager';
import { EventMediaQueries, MediaQueries, View } from '../view'; import { EventMediaQueries, MediaQueries, View } from '../view';
import { dispatchMessageEvent } from './message.js'; import { dispatchMessageEvent } from './message.js';
import './thumbnail.js'; import './thumbnail.js';
import { FrigateCardTimelineItem, TimelineDataSource } from '../utils/timeline-source'; import { FrigateCardTimelineItem, TimelineDataSource } from '../utils/timeline-source';
import { ViewMedia, ViewMediaClassifier } from '../view-media'; import { ViewMedia, ViewMediaClassifier } from '../view-media';
import { rangesOverlap } from '../utils/data/data-manager-range'; import { rangesOverlap } from '../camera/range';
interface FrigateCardGroupData { interface FrigateCardGroupData {
id: string; id: string;
@@ -89,7 +89,7 @@ declare module 'view' {
interface ThumbnailDataRequest { interface ThumbnailDataRequest {
item: IdType; item: IdType;
hass?: ExtendedHomeAssistant; hass?: ExtendedHomeAssistant;
dataManager?: DataManager; cameraManager?: CameraManager;
cameraConfig?: CameraConfig; cameraConfig?: CameraConfig;
media?: ViewMedia; media?: ViewMedia;
view?: View; view?: View;
@@ -142,7 +142,7 @@ export class FrigateCardTimelineThumbnail extends LitElement {
if ( if (
!dataRequest.hass || !dataRequest.hass ||
!dataRequest.dataManager || !dataRequest.cameraManager ||
!dataRequest.cameraConfig || !dataRequest.cameraConfig ||
!dataRequest.media || !dataRequest.media ||
!dataRequest.view !dataRequest.view
@@ -152,7 +152,7 @@ export class FrigateCardTimelineThumbnail extends LitElement {
return html` <frigate-card-thumbnail return html` <frigate-card-thumbnail
.hass=${dataRequest.hass} .hass=${dataRequest.hass}
.dataManager=${dataRequest.dataManager} .cameraManager=${dataRequest.cameraManager}
.cameraConfig=${dataRequest.cameraConfig} .cameraConfig=${dataRequest.cameraConfig}
.media=${dataRequest.media} .media=${dataRequest.media}
.view=${dataRequest.view} .view=${dataRequest.view}
@@ -188,7 +188,7 @@ export class FrigateCardTimelineCore extends LitElement {
public mini = false; public mini = false;
@property({ attribute: false }) @property({ attribute: false })
public dataManager?: DataManager; public cameraManager?: CameraManager;
@state() @state()
protected _locked = false; protected _locked = false;
@@ -245,7 +245,7 @@ export class FrigateCardTimelineCore extends LitElement {
request.detail.cameraConfig = media request.detail.cameraConfig = media
? this.cameras?.get(media.getCameraID()) ? this.cameras?.get(media.getCameraID())
: undefined; : undefined;
request.detail.dataManager = this.dataManager; request.detail.cameraManager = this.cameraManager;
request.detail.media = media; request.detail.media = media;
request.detail.view = this.view; request.detail.view = this.view;
} }
@@ -392,7 +392,7 @@ export class FrigateCardTimelineCore extends LitElement {
!this._timeline || !this._timeline ||
!this.view || !this.view ||
// !this.view.target?.length || // !this.view.target?.length ||
!this.dataManager !this.cameraManager
) { ) {
return; return;
} }
@@ -401,7 +401,7 @@ export class FrigateCardTimelineCore extends LitElement {
// const canSeek = !!this.view?.isViewerView(); // const canSeek = !!this.view?.isViewerView();
// const context = canSeek // const context = canSeek
// ? generateMediaViewerContextForChildren( // ? generateMediaViewerContextForChildren(
// this.dataManager, // this.cameraManager,
// this.view.target, // this.view.target,
// targetTime, // targetTime,
// ) // )
@@ -453,7 +453,7 @@ export class FrigateCardTimelineCore extends LitElement {
!this._timeline || !this._timeline ||
!this.cameras || !this.cameras ||
!this.view || !this.view ||
!this.dataManager || !this.cameraManager ||
!properties.what !properties.what
) { ) {
return; return;
@@ -467,7 +467,7 @@ export class FrigateCardTimelineCore extends LitElement {
) { ) {
viewPromise = createViewForRecordings( viewPromise = createViewForRecordings(
this.hass, this.hass,
this.dataManager, this.cameraManager,
this.cameras, this.cameras,
this.view, this.view,
{ {
@@ -483,7 +483,7 @@ export class FrigateCardTimelineCore extends LitElement {
} else if (this.timelineConfig?.show_recordings && properties.what === 'axis') { } else if (this.timelineConfig?.show_recordings && properties.what === 'axis') {
viewPromise = createViewForRecordings( viewPromise = createViewForRecordings(
this.hass, this.hass,
this.dataManager, this.cameraManager,
this.cameras, this.cameras,
this.view, this.view,
{ {
@@ -499,7 +499,7 @@ export class FrigateCardTimelineCore extends LitElement {
this.view.query?.areRecordingQueries() this.view.query?.areRecordingQueries()
) { ) {
viewPromise = (async (): Promise<View | null> => { viewPromise = (async (): Promise<View | null> => {
if (!properties.item || !this.dataManager || !this.hass) { if (!properties.item || !this.cameraManager || !this.hass) {
return null; return null;
} }
const view = await this._createViewWithEventMediaQuery( const view = await this._createViewWithEventMediaQuery(
@@ -518,7 +518,7 @@ export class FrigateCardTimelineCore extends LitElement {
view.mergeInContext( view.mergeInContext(
await generateMediaViewerContext( await generateMediaViewerContext(
this.hass, this.hass,
this.dataManager, this.cameraManager,
results, results,
properties.time, properties.time,
), ),
@@ -645,12 +645,12 @@ export class FrigateCardTimelineCore extends LitElement {
noSetWindow?: boolean; noSetWindow?: boolean;
}, },
): Promise<View | null> { ): Promise<View | null> {
if (!this.hass || !this.dataManager || !this.cameras || !this.view || !query) { if (!this.hass || !this.cameraManager || !this.cameras || !this.view || !query) {
return null; return null;
} }
const view = await createViewForEvents( const view = await createViewForEvents(
this.hass, this.hass,
this.dataManager, this.cameraManager,
this.cameras, this.cameras,
this.view, this.view,
{ {
@@ -983,11 +983,11 @@ export class FrigateCardTimelineCore extends LitElement {
protected _alreadyHasAcceptableMediaQuery(freshMediaQuery: MediaQueries): boolean { protected _alreadyHasAcceptableMediaQuery(freshMediaQuery: MediaQueries): boolean {
return ( return (
!!this.dataManager && !!this.cameraManager &&
!!this.view?.query && !!this.view?.query &&
!!this.view.queryResults && !!this.view.queryResults &&
freshMediaQuery.isEqual(this.view.query) && freshMediaQuery.isEqual(this.view.query) &&
this.dataManager.areMediaQueriesResultsFresh( this.cameraManager.areMediaQueriesResultsFresh(
this.view.query, this.view.query,
this.view.queryResults, this.view.queryResults,
) )
@@ -1033,13 +1033,13 @@ export class FrigateCardTimelineCore extends LitElement {
} }
if ( if (
changedProps.has('dataManager') || changedProps.has('cameraManager') ||
changedProps.has('cameras') || changedProps.has('cameras') ||
changedProps.has('timelineConfig') changedProps.has('timelineConfig')
) { ) {
if (this.dataManager && this.cameras && this.timelineConfig) { if (this.cameraManager && this.cameras && this.timelineConfig) {
this._timelineSource = new TimelineDataSource( this._timelineSource = new TimelineDataSource(
this.dataManager, this.cameraManager,
this._getTimelineCameraIDs(), this._getTimelineCameraIDs(),
this.timelineConfig.media, this.timelineConfig.media,
); );
@@ -1069,7 +1069,7 @@ export class FrigateCardTimelineCore extends LitElement {
protected updated(changedProperties: PropertyValues): void { protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties); super.updated(changedProperties);
if (changedProperties.has('cameras') || changedProperties.has('dataManager')) { if (changedProperties.has('cameras') || changedProperties.has('cameraManager')) {
this._destroy(); this._destroy();
} }
+3 -3
View File
@@ -2,7 +2,7 @@ import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit
import { customElement, property } from 'lit/decorators.js'; import { customElement, property } from 'lit/decorators.js';
import timelineStyle from '../scss/timeline.scss'; import timelineStyle from '../scss/timeline.scss';
import { CameraConfig, ExtendedHomeAssistant, TimelineConfig } from '../types'; import { CameraConfig, ExtendedHomeAssistant, TimelineConfig } from '../types';
import { DataManager } from '../utils/data/data-manager'; import { CameraManager } from '../camera/manager';
import { View } from '../view'; import { View } from '../view';
import './surround.js'; import './surround.js';
import './timeline-core.js'; import './timeline-core.js';
@@ -27,7 +27,7 @@ export class FrigateCardTimeline extends LitElement {
public timelineConfig?: TimelineConfig; public timelineConfig?: TimelineConfig;
@property({ attribute: false }) @property({ attribute: false })
public dataManager?: DataManager; public cameraManager?: CameraManager;
/** /**
* Master render method. * Master render method.
@@ -51,7 +51,7 @@ export class FrigateCardTimeline extends LitElement {
.timelineConfig=${this.timelineConfig} .timelineConfig=${this.timelineConfig}
.thumbnailDetails=${this.timelineConfig.controls.thumbnails.show_details} .thumbnailDetails=${this.timelineConfig.controls.thumbnails.show_details}
.thumbnailSize=${this.timelineConfig.controls.thumbnails.size} .thumbnailSize=${this.timelineConfig.controls.thumbnails.size}
.dataManager=${this.dataManager} .cameraManager=${this.cameraManager}
> >
</frigate-card-timeline-core> </frigate-card-timeline-core>
</frigate-card-surround>`; </frigate-card-surround>`;
+6 -6
View File
@@ -46,7 +46,7 @@ import '../patches/ha-hls-player';
import './surround.js'; import './surround.js';
import { renderTask } from '../utils/task.js'; import { renderTask } from '../utils/task.js';
import { updateElementStyleFromMediaLayoutConfig } from '../utils/media-layout.js'; import { updateElementStyleFromMediaLayoutConfig } from '../utils/media-layout.js';
import { DataManager } from '../utils/data/data-manager.js'; import { CameraManager } from '../camera/manager.js';
import { import {
changeViewToRecentEventsForCameraAndDependents, changeViewToRecentEventsForCameraAndDependents,
changeViewToRecentRecordingForCameraAndDependents, changeViewToRecentRecordingForCameraAndDependents,
@@ -92,7 +92,7 @@ export class FrigateCardViewer extends LitElement {
public resolvedMediaCache?: ResolvedMediaCache; public resolvedMediaCache?: ResolvedMediaCache;
@property({ attribute: false }) @property({ attribute: false })
public dataManager?: DataManager; public cameraManager?: CameraManager;
@property({ attribute: false }) @property({ attribute: false })
public cardWideConfig?: CardWideConfig; public cardWideConfig?: CardWideConfig;
@@ -107,7 +107,7 @@ export class FrigateCardViewer extends LitElement {
!this.view || !this.view ||
!this.cameras || !this.cameras ||
!this.viewerConfig || !this.viewerConfig ||
!this.dataManager !this.cameraManager
) { ) {
return; return;
} }
@@ -134,7 +134,7 @@ export class FrigateCardViewer extends LitElement {
changeViewToRecentRecordingForCameraAndDependents( changeViewToRecentRecordingForCameraAndDependents(
this, this,
this.hass, this.hass,
this.dataManager, this.cameraManager,
this.cameras, this.cameras,
this.view, this.view,
{ {
@@ -145,7 +145,7 @@ export class FrigateCardViewer extends LitElement {
changeViewToRecentEventsForCameraAndDependents( changeViewToRecentEventsForCameraAndDependents(
this, this,
this.hass, this.hass,
this.dataManager, this.cameraManager,
this.cameras, this.cameras,
this.view, this.view,
{ {
@@ -161,7 +161,7 @@ export class FrigateCardViewer extends LitElement {
.view=${this.view} .view=${this.view}
.thumbnailConfig=${this.viewerConfig.controls.thumbnails} .thumbnailConfig=${this.viewerConfig.controls.thumbnails}
.timelineConfig=${this.viewerConfig.controls.timeline} .timelineConfig=${this.viewerConfig.controls.timeline}
.dataManager=${this.dataManager} .cameraManager=${this.cameraManager}
.cameras=${this.cameras} .cameras=${this.cameras}
> >
<frigate-card-viewer-carousel <frigate-card-viewer-carousel
@@ -1,42 +0,0 @@
import { CameraConfig } from '../../types';
import { RecordingSegmentsCache } from './data-manager-cache';
import { DataManagerEngine } from './data-manager-engine';
import { FrigateDataManagerEngine } from './data-manager-engine-frigate';
import { DataQuery } from './data-types';
export class DataManagerEngineFactory {
protected _engines: Map<string, DataManagerEngine> = new Map();
protected _getOrCreateEngine(engineKey: string): DataManagerEngine | null {
const cachedEngine = this._engines.get(engineKey);
if (cachedEngine) {
return cachedEngine;
}
let newEngine: DataManagerEngine | null = null;
switch (engineKey) {
case 'frigate':
newEngine = new FrigateDataManagerEngine(new RecordingSegmentsCache());
break;
}
if (newEngine) {
this._engines.set(engineKey, newEngine);
}
return newEngine;
}
public getEngineForQuery(
cameras: Map<string, CameraConfig>,
query: DataQuery,
): DataManagerEngine | null {
const cameraConfig = cameras.get(query.cameraID);
return cameraConfig ? this.getEngineForCamera(cameraConfig) : null;
}
public getEngineForCamera(cameraConfig: CameraConfig): DataManagerEngine | null {
let engineKey: string | null = null;
if (cameraConfig.frigate.camera_name) {
engineKey = 'frigate';
}
return engineKey ? this._getOrCreateEngine(engineKey) : null;
}
}
-3
View File
@@ -1,3 +0,0 @@
import { FrigateCardError } from '../../types';
export class DataManagerError extends FrigateCardError {}
+18 -18
View File
@@ -6,7 +6,7 @@ import { ViewContext } from 'view';
import { CameraConfig, ClipsOrSnapshotsOrAll, FrigateCardView } from '../types'; import { CameraConfig, ClipsOrSnapshotsOrAll, FrigateCardView } from '../types';
import { EventMediaQueries, RecordingMediaQueries, View } from '../view'; import { EventMediaQueries, RecordingMediaQueries, View } from '../view';
import { RecordingSegments } from './frigate'; import { RecordingSegments } from './frigate';
import { DataManager } from './data/data-manager'; import { CameraManager } from '../camera/manager';
import { getAllDependentCameras } from './camera.js'; import { getAllDependentCameras } from './camera.js';
import { ViewMedia, ViewMediaClassifier } from '../view-media'; import { ViewMedia, ViewMediaClassifier } from '../view-media';
import { HomeAssistant } from 'custom-card-helpers'; import { HomeAssistant } from 'custom-card-helpers';
@@ -14,7 +14,7 @@ import { HomeAssistant } from 'custom-card-helpers';
export const changeViewToRecentEventsForCameraAndDependents = async ( export const changeViewToRecentEventsForCameraAndDependents = async (
element: HTMLElement, element: HTMLElement,
hass: HomeAssistant, hass: HomeAssistant,
dataManager: DataManager, cameraManager: CameraManager,
cameras: Map<string, CameraConfig>, cameras: Map<string, CameraConfig>,
view: View, view: View,
options?: { options?: {
@@ -23,7 +23,7 @@ export const changeViewToRecentEventsForCameraAndDependents = async (
}, },
): Promise<void> => { ): Promise<void> => {
( (
await createViewForEvents(hass, dataManager, cameras, view, { await createViewForEvents(hass, cameraManager, cameras, view, {
...options, ...options,
limit: 50, // Capture the 50 most recent events. limit: 50, // Capture the 50 most recent events.
}) })
@@ -32,7 +32,7 @@ export const changeViewToRecentEventsForCameraAndDependents = async (
export const createViewForEvents = async ( export const createViewForEvents = async (
hass: HomeAssistant, hass: HomeAssistant,
dataManager: DataManager, cameraManager: CameraManager,
cameras: Map<string, CameraConfig>, cameras: Map<string, CameraConfig>,
view: View, view: View,
options?: { options?: {
@@ -51,7 +51,7 @@ export const createViewForEvents = async (
? options.cameraIDs ? options.cameraIDs
: new Set(getAllDependentCameras(cameras, view.camera)); : new Set(getAllDependentCameras(cameras, view.camera));
const queries = dataManager.generateDefaultEventQueries(cameraIDs, { const queries = cameraManager.generateDefaultEventQueries(cameraIDs, {
...(options?.limit && { limit: options.limit }), ...(options?.limit && { limit: options.limit }),
...((!options?.mediaType || ['clips', 'all'].includes(options.mediaType)) && { ...((!options?.mediaType || ['clips', 'all'].includes(options.mediaType)) && {
hasClip: true, hasClip: true,
@@ -60,7 +60,7 @@ export const createViewForEvents = async (
}); });
query = new EventMediaQueries(queries); query = new EventMediaQueries(queries);
} }
const queryResults = await dataManager.executeMediaQuery(hass, query); const queryResults = await cameraManager.executeMediaQuery(hass, query);
return view?.evolve({ return view?.evolve({
view: options?.targetView, view: options?.targetView,
@@ -73,7 +73,7 @@ export const createViewForEvents = async (
* Change the view to a recent recording. * Change the view to a recent recording.
* @param element The element to dispatch the view change from. * @param element The element to dispatch the view change from.
* @param hass The Home Assistant object. * @param hass The Home Assistant object.
* @param dataManager The datamanager to use for data access. * @param cameraManager The datamanager to use for data access.
* @param cameras The camera configurations. * @param cameras The camera configurations.
* @param view The current view. * @param view The current view.
* @param options A set of cameraIDs to fetch recordings for, and a targetView to dispatch to. * @param options A set of cameraIDs to fetch recordings for, and a targetView to dispatch to.
@@ -81,7 +81,7 @@ export const createViewForEvents = async (
export const changeViewToRecentRecordingForCameraAndDependents = async ( export const changeViewToRecentRecordingForCameraAndDependents = async (
element: HTMLElement, element: HTMLElement,
hass: HomeAssistant, hass: HomeAssistant,
dataManager: DataManager, cameraManager: CameraManager,
cameras: Map<string, CameraConfig>, cameras: Map<string, CameraConfig>,
view: View, view: View,
options?: { options?: {
@@ -90,7 +90,7 @@ export const changeViewToRecentRecordingForCameraAndDependents = async (
): Promise<void> => { ): Promise<void> => {
const now = new Date(); const now = new Date();
( (
await createViewForRecordings(hass, dataManager, cameras, view, { await createViewForRecordings(hass, cameraManager, cameras, view, {
...options, ...options,
// Fetch 7 days worth of recordings (including recordings that are for the // Fetch 7 days worth of recordings (including recordings that are for the
// current hour). // current hour).
@@ -103,7 +103,7 @@ export const changeViewToRecentRecordingForCameraAndDependents = async (
/** /**
* Create a view for recordings. * Create a view for recordings.
* @param hass The Home Assistant object. * @param hass The Home Assistant object.
* @param dataManager The datamanager to use for data access. * @param cameraManager The datamanager to use for data access.
* @param cameras The camera configurations. * @param cameras The camera configurations.
* @param view The current view. * @param view The current view.
* @param options A specific window (start and end) to fetch recordings for, a * @param options A specific window (start and end) to fetch recordings for, a
@@ -112,7 +112,7 @@ export const changeViewToRecentRecordingForCameraAndDependents = async (
*/ */
export const createViewForRecordings = async ( export const createViewForRecordings = async (
hass: HomeAssistant, hass: HomeAssistant,
dataManager: DataManager, cameraManager: CameraManager,
cameras: Map<string, CameraConfig>, cameras: Map<string, CameraConfig>,
view: View, view: View,
options?: { options?: {
@@ -127,13 +127,13 @@ export const createViewForRecordings = async (
? options.cameraIDs ? options.cameraIDs
: new Set(getAllDependentCameras(cameras, view.camera)); : new Set(getAllDependentCameras(cameras, view.camera));
const queries = dataManager.generateDefaultRecordingQueries(cameraIDs, { const queries = cameraManager.generateDefaultRecordingQueries(cameraIDs, {
...(options?.start && { start: options.start }), ...(options?.start && { start: options.start }),
...(options?.end && { end: options.end }), ...(options?.end && { end: options.end }),
}); });
const query = new RecordingMediaQueries(queries); const query = new RecordingMediaQueries(queries);
const queryResults = await dataManager.executeMediaQuery(hass, query); const queryResults = await cameraManager.executeMediaQuery(hass, query);
let viewerContext: ViewContext | undefined = {}; let viewerContext: ViewContext | undefined = {};
const mediaArray = queryResults?.getResults(); const mediaArray = queryResults?.getResults();
@@ -143,7 +143,7 @@ export const createViewForRecordings = async (
); );
viewerContext = await generateMediaViewerContext( viewerContext = await generateMediaViewerContext(
hass, hass,
dataManager, cameraManager,
mediaArray, mediaArray,
options.targetTime, options.targetTime,
); );
@@ -164,14 +164,14 @@ export const createViewForRecordings = async (
* Generate the media view context for a set of media children (used to set * Generate the media view context for a set of media children (used to set
* seek times into each media item). * seek times into each media item).
* @param hass The Home Assistant object. * @param hass The Home Assistant object.
* @param dataManager The datamanager to use for data access. * @param cameraManager The datamanager to use for data access.
* @param media The media. * @param media The media.
* @param targetTime The target time. * @param targetTime The target time.
* @returns The ViewContext. * @returns The ViewContext.
*/ */
export const generateMediaViewerContext = async ( export const generateMediaViewerContext = async (
hass: HomeAssistant, hass: HomeAssistant,
dataManager: DataManager, cameraManager: CameraManager,
media: ViewMedia[], media: ViewMedia[],
targetTime: Date, targetTime: Date,
): Promise<ViewContext> => { ): Promise<ViewContext> => {
@@ -188,14 +188,14 @@ export const generateMediaViewerContext = async (
let seekSeconds: number | null = null; let seekSeconds: number | null = null;
if (targetTime >= start && targetTime <= end) { if (targetTime >= start && targetTime <= end) {
const query = dataManager.generateDefaultRecordingSegmentsQueries( const query = cameraManager.generateDefaultRecordingSegmentsQueries(
child.getCameraID(), child.getCameraID(),
{ {
start: start, start: start,
end: end, end: end,
}, },
)[0]; )[0];
const segments = (await dataManager.getRecordingSegments(hass, query)).get(query); const segments = (await cameraManager.getRecordingSegments(hass, query)).get(query);
if (segments) { if (segments) {
seekSeconds = getSeekTimeInSegments( seekSeconds = getSeekTimeInSegments(
+11 -15
View File
@@ -4,17 +4,13 @@ import sub from 'date-fns/sub';
import { DataSet } from 'vis-data'; import { DataSet } from 'vis-data';
import { IdType, TimelineItem, TimelineWindow } from 'vis-timeline/esnext'; import { IdType, TimelineItem, TimelineWindow } from 'vis-timeline/esnext';
import { CameraConfig, ClipsOrSnapshotsOrAll } from '../types'; import { CameraConfig, ClipsOrSnapshotsOrAll } from '../types';
import { DataManager } from './data/data-manager'; import { CameraManager } from '../camera/manager';
import { EventQuery } from './data/data-types'; import { EventQuery } from '../camera/types';
import { RecordingSegment, RecordingSegments } from './frigate'; import { RecordingSegment, RecordingSegments } from './frigate';
import { capEndDate, convertRangeToCacheFriendlyTimes } from './data/data-manager-util'; import { capEndDate, convertRangeToCacheFriendlyTimes } from '../camera/util';
import { EventMediaQueries } from '../view'; import { EventMediaQueries } from '../view';
import { ViewMedia } from '../view-media'; import { ViewMedia } from '../view-media';
import { import { compressRanges, ExpiringMemoryRangeSet, MemoryRangeSet } from '../camera/range';
compressRanges,
ExpiringMemoryRangeSet,
MemoryRangeSet,
} from './data/data-manager-range';
import { ModifyInterface } from './basic'; import { ModifyInterface } from './basic';
// Allow timeline freshness to be at least this number of seconds out of date // Allow timeline freshness to be at least this number of seconds out of date
@@ -36,7 +32,7 @@ export interface FrigateCardTimelineItem extends TimelineItem {
} }
export class TimelineDataSource { export class TimelineDataSource {
protected _dataManager: DataManager; protected _cameraManager: CameraManager;
protected _dataset: DataSet<FrigateCardTimelineItem> = new DataSet(); protected _dataset: DataSet<FrigateCardTimelineItem> = new DataSet();
// The ranges in which recordings have been calculated and added for. // The ranges in which recordings have been calculated and added for.
@@ -53,11 +49,11 @@ export class TimelineDataSource {
protected _mediaType: ClipsOrSnapshotsOrAll; protected _mediaType: ClipsOrSnapshotsOrAll;
constructor( constructor(
dataManager: DataManager, cameraManager: CameraManager,
cameraIDs: Set<string>, cameraIDs: Set<string>,
media: ClipsOrSnapshotsOrAll, media: ClipsOrSnapshotsOrAll,
) { ) {
this._dataManager = dataManager; this._cameraManager = cameraManager;
this._cameraIDs = cameraIDs; this._cameraIDs = cameraIDs;
this._mediaType = media; this._mediaType = media;
} }
@@ -108,7 +104,7 @@ export class TimelineDataSource {
} }
public getTimelineEventQueries(window: TimelineWindow): EventQuery[] { public getTimelineEventQueries(window: TimelineWindow): EventQuery[] {
return this._dataManager.generateDefaultEventQueries(this._cameraIDs, { return this._cameraManager.generateDefaultEventQueries(this._cameraIDs, {
start: window.start, start: window.start,
end: window.end, end: window.end,
...(this._mediaType === 'clips' && { hasClip: true }), ...(this._mediaType === 'clips' && { hasClip: true }),
@@ -137,7 +133,7 @@ export class TimelineDataSource {
this.getTimelineEventQueries(cacheFriendlyWindow), this.getTimelineEventQueries(cacheFriendlyWindow),
); );
const results = await this._dataManager.executeMediaQuery(hass, query); const results = await this._cameraManager.executeMediaQuery(hass, query);
for (const media of results?.getResults() ?? []) { for (const media of results?.getResults() ?? []) {
const endTime = media.getEndTime(); const endTime = media.getEndTime();
const startTime = media.getStartTime(); const startTime = media.getStartTime();
@@ -222,7 +218,7 @@ export class TimelineDataSource {
endCap: true, endCap: true,
}); });
const queries = this._dataManager.generateDefaultRecordingSegmentsQueries( const queries = this._cameraManager.generateDefaultRecordingSegmentsQueries(
this._cameraIDs, this._cameraIDs,
{ {
start: cacheFriendlyWindow.start, start: cacheFriendlyWindow.start,
@@ -230,7 +226,7 @@ export class TimelineDataSource {
}, },
); );
const results = await this._dataManager.getRecordingSegments(hass, queries); const results = await this._cameraManager.getRecordingSegments(hass, queries);
const newSegments: Map<string, RecordingSegments> = new Map(); const newSegments: Map<string, RecordingSegments> = new Map();
for (const [query, result] of results) { for (const [query, result] of results) {
+2 -2
View File
@@ -1,5 +1,5 @@
// Easy: // Easy:
// - TODO: Search for references to frigate.js and see where it's being called outside of the dataManager. Can I collapse some of those functions in? // - TODO: Search for references to frigate.js and see where it's being called outside of the cameraManager. Can I collapse some of those functions in?
// - TODO: Refactor thumbnailsControlSchema to all use the shortform for other thumbnail users beyond live. // - TODO: Refactor thumbnailsControlSchema to all use the shortform for other thumbnail users beyond live.
// - TODO: limit param in recordings should do something // - TODO: limit param in recordings should do something
// - TODO: Should be able to set live media to 'all' and have it work. // - TODO: Should be able to set live media to 'all' and have it work.
@@ -36,7 +36,7 @@ import {
FRIGATE_CARD_VIEW_DEFAULT, FRIGATE_CARD_VIEW_DEFAULT,
} from './types.js'; } from './types.js';
import { dispatchFrigateCardEvent } from './utils/basic.js'; import { dispatchFrigateCardEvent } from './utils/basic.js';
import { EventQuery, MediaQuery, RecordingQuery } from './utils/data/data-types.js'; import { EventQuery, MediaQuery, RecordingQuery } from './camera/types.js';
import { ViewMedia } from './view-media.js'; import { ViewMedia } from './view-media.js';
export interface ViewEvolveParameters { export interface ViewEvolveParameters {