Remove the MediaQuery wrapper from the camera manager.

This commit is contained in:
Dermot Duffy
2023-01-29 20:00:45 -08:00
parent 767d4ee7a0
commit 01c3a79ff1
9 changed files with 69 additions and 69 deletions
+18 -34
View File
@@ -31,8 +31,6 @@ import {
import orderBy from 'lodash-es/orderBy';
import { CameraManagerEngineFactory } from './engine-factory.js';
import { ViewMedia } from '../view/media.js';
import { MediaQueriesResults } from '../view/media-queries-results';
import { MediaQueries } from '../view/media-queries.js';
import uniqBy from 'lodash-es/uniqBy';
import { CameraManagerEngine } from './engine.js';
import sum from 'lodash-es/sum';
@@ -123,9 +121,7 @@ export class CameraManager {
});
}
public async getMediaMetadata(
hass: HomeAssistant,
): Promise<MediaMetadata | null> {
public async getMediaMetadata(hass: HomeAssistant): Promise<MediaMetadata | null> {
const what: Set<string> = new Set();
const where: Set<string> = new Set();
const days: Set<string> = new Set();
@@ -148,7 +144,7 @@ export class CameraManager {
engineMetadata.days.forEach(days.add, days);
}
}
}
};
await allPromises(engines, (engine) => processMetadata(engine));
@@ -159,7 +155,7 @@ export class CameraManager {
...(what.size && { what: what }),
...(where.size && { where: where }),
...(days.size && { days: days }),
}
};
}
protected _generateDefaultQueries<PQT extends PartialDataQuery>(
@@ -228,25 +224,14 @@ export class CameraManager {
return await this._handleQuery(hass, query);
}
public async executeMediaQueries(
public async executeMediaQueries<T extends MediaQuery>(
hass: HomeAssistant,
mediaQueries: MediaQueries,
): Promise<MediaQueriesResults | null> {
const queries: (RecordingQuery | EventQuery)[] | null = mediaQueries.getQueries();
if (!queries) {
return null;
}
const mediaArray = this._convertQueryResultsToMedia(
queries: T[],
): Promise<ViewMedia[] | null> {
return this._convertQueryResultsToMedia(
hass,
await this._handleQuery(hass, queries),
);
return new MediaQueriesResults(
mediaArray,
// Select the first (most-recent) item.
mediaArray.length ? 0 : null,
);
}
public async extendMediaQueries<T extends MediaQuery>(
@@ -328,9 +313,13 @@ export class CameraManager {
}
return {
canFavoriteEvents: engines.some((engine) => engine.getCapabilities()?.canFavoriteEvents),
canFavoriteRecordings: engines.some((engine) => engine.getCapabilities()?.canFavoriteRecordings),
}
canFavoriteEvents: engines.some(
(engine) => engine.getCapabilities()?.canFavoriteEvents,
),
canFavoriteRecordings: engines.some(
(engine) => engine.getCapabilities()?.canFavoriteRecordings,
),
};
}
public getMediaCapabilities(media: ViewMedia): CameraManagerMediaCapabilities | null {
@@ -368,18 +357,13 @@ export class CameraManager {
}
}
public areMediaQueriesResultsFresh(
queries: MediaQueries,
results: MediaQueriesResults,
public areMediaQueriesResultsFresh<T extends MediaQuery>(
queries: T[],
resultsTimestamp: Date,
): boolean {
const now = new Date();
const resultsTimestamp = results.getResultsTimestamp();
if (!resultsTimestamp) {
return false;
}
for (const query of queries.getQueries() ?? []) {
for (const query of queries) {
const engines = this._engineFactory.getEnginesForCameraIDs(
this._cameras,
query.cameraIDs,
-1
View File
@@ -239,7 +239,6 @@ export class FrigateCardThumbnail extends LitElement {
@property({ attribute: false })
public hass?: ExtendedHomeAssistant;
// CameraManager used for marking media as favorite.
@property({ attribute: false })
public cameraManager?: CameraManager;
+13 -11
View File
@@ -59,6 +59,7 @@ import { ViewMedia } from '../view/media';
import { ViewMediaClassifier } from '../view/media-classifier';
import { rangesOverlap } from '../camera-manager/range';
import { View } from '../view/view';
import { MediaQuery } from '../camera-manager/types';
interface FrigateCardGroupData {
id: string;
@@ -501,11 +502,9 @@ export class FrigateCardTimelineCore extends LitElement {
targetTime: properties.time,
},
);
} else if (
properties.item &&
properties.what === 'item'
) {
const newResults = this.view.queryResults?.clone()
} else if (properties.item && properties.what === 'item') {
const newResults = this.view.queryResults
?.clone()
.resetSelectedResult()
.selectResultIfFound(
(media) => !!this.cameras && media.getID() === properties.item,
@@ -972,14 +971,17 @@ export class FrigateCardTimelineCore extends LitElement {
}
protected _alreadyHasAcceptableMediaQuery(freshMediaQuery: MediaQueries): boolean {
const currentQueries = this.view?.query?.getQueries();
const currentResultTimestamp = this.view?.queryResults?.getResultsTimestamp();
return (
!!this.cameraManager &&
!!this.view?.query &&
!!this.view.queryResults &&
freshMediaQuery.isEqual(this.view.query) &&
this.cameraManager.areMediaQueriesResultsFresh(
this.view.query,
this.view.queryResults,
!!currentQueries &&
!!currentResultTimestamp &&
isEqual(currentQueries, freshMediaQuery.getQueries()) &&
this.cameraManager.areMediaQueriesResultsFresh<MediaQuery>(
currentQueries,
currentResultTimestamp,
)
);
}
+1
View File
@@ -42,6 +42,7 @@ export class FrigateCardTimeline extends LitElement {
.hass=${this.hass}
.view=${this.view}
.thumbnailConfig=${this.timelineConfig.controls.thumbnails}
.cameraManager=${this.cameraManager}
.cameras=${this.cameras}
>
<frigate-card-timeline-core
+9 -4
View File
@@ -380,18 +380,23 @@ export class FrigateCardViewerCarousel extends LitElement {
const clipQuery = this.view.query.clone();
clipQuery.convertToClipsQueries();
let results: MediaQueriesResults | null;
const queries = clipQuery.getQueries();
if (!queries) {
return;
}
let mediaArray: ViewMedia[] | null;
try {
results = await this.cameraManager.executeMediaQueries(this.hass, clipQuery);
mediaArray = await this.cameraManager.executeMediaQueries(this.hass, queries);
} catch (e) {
errorToConsole(e as Error);
return;
}
if (!results) {
if (!mediaArray) {
return;
}
const results = new MediaQueriesResults(mediaArray);
results.selectResultIfFound((clipMedia) => clipMedia.getID() === media.getID());
if (!results.hasSelectedResult()) {
return;
+15 -4
View File
@@ -15,6 +15,7 @@ import { HomeAssistant } from 'custom-card-helpers';
import { dispatchFrigateCardErrorEvent } from '../components/message';
import { MediaQueriesResults } from '../view/media-queries-results';
import { errorToConsole } from './basic';
import { MediaQuery } from '../camera-manager/types';
export const changeViewToRecentEventsForCameraAndDependents = async (
element: HTMLElement,
@@ -179,19 +180,29 @@ const executeMediaQueryForView = async (
targetTime?: Date;
},
): Promise<View | null> => {
let queryResults: MediaQueriesResults | null;
let mediaArray: ViewMedia[] | null;
const queries = query.getQueries();
if (!queries) {
return null;
}
try {
queryResults = await cameraManager.executeMediaQueries(hass, query);
mediaArray = await cameraManager.executeMediaQueries<MediaQuery>(hass, queries);
} catch (e) {
errorToConsole(e as Error);
dispatchFrigateCardErrorEvent(element, e as Error);
return null;
}
if (!mediaArray) {
return null;
}
const queryResults = new MediaQueriesResults(mediaArray);
let viewerContext: ViewContext | undefined = {};
const mediaArray = queryResults?.getResults();
if (queryResults && mediaArray && options?.targetTime && options.cameraIDs) {
if (options?.targetTime && options.cameraIDs) {
queryResults.selectBestResult((media) =>
findClosestMediaIndex(media, options.targetTime as Date, options.cameraIDs),
);
+12 -7
View File
@@ -7,9 +7,12 @@ import { ClipsOrSnapshotsOrAll, RecordingSegment } from '../types';
import { CameraManager } from '../camera-manager/manager';
import { EventQuery } from '../camera-manager/types';
import { capEndDate, convertRangeToCacheFriendlyTimes } from '../camera-manager/util';
import { EventMediaQueries } from '../view/media-queries';
import { ViewMedia } from '../view/media';
import { compressRanges, ExpiringMemoryRangeSet, MemoryRangeSet } from '../camera-manager/range';
import {
compressRanges,
ExpiringMemoryRangeSet,
MemoryRangeSet,
} from '../camera-manager/range';
import { errorToConsole, ModifyInterface } from './basic.js';
// Allow timeline freshness to be at least this number of seconds out of date
@@ -132,14 +135,13 @@ export class TimelineDataSource {
}
const cacheFriendlyWindow = this.getCacheFriendlyEventWindow(window);
const eventQueries = this.getTimelineEventQueries(cacheFriendlyWindow)
const eventQueries = this.getTimelineEventQueries(cacheFriendlyWindow);
if (!eventQueries) {
return;
}
const query = new EventMediaQueries(eventQueries);
const results = await this._cameraManager.executeMediaQueries(hass, query);
for (const media of results?.getResults() ?? []) {
const mediaArray = await this._cameraManager.executeMediaQueries(hass, eventQueries);
for (const media of mediaArray ?? []) {
const endTime = media.getEndTime();
const startTime = media.getStartTime();
const id = media.getID();
@@ -234,7 +236,10 @@ export class TimelineDataSource {
if (!recordingQueries) {
return;
}
const results = await this._cameraManager.getRecordingSegments(hass, recordingQueries);
const results = await this._cameraManager.getRecordingSegments(
hass,
recordingQueries,
);
const newSegments: Map<string, RecordingSegment[]> = new Map();
for (const [query, result] of results) {
+1 -3
View File
@@ -10,9 +10,7 @@ export class MediaQueriesResults {
if (results) {
this.setResults(results);
}
if (selectedIndex !== undefined) {
this.selectResult(selectedIndex);
}
this.selectResult(selectedIndex ?? 0);
}
public clone(): MediaQueriesResults {
-5
View File
@@ -1,4 +1,3 @@
import isEqual from 'lodash-es/isEqual';
import cloneDeep from 'lodash-es/cloneDeep.js';
import { EventQuery, MediaQuery, RecordingQuery } from '../camera-manager/types.js';
@@ -17,10 +16,6 @@ export class MediaQueriesBase<T extends MediaQuery> {
return cloneDeep(this);
}
public isEqual(that: MediaQueries): boolean {
return isEqual(this.getQueries(), that.getQueries());
}
public getQueries(): T[] | null {
return this._queries;
}