Avoid duplicate engine creation.
This commit is contained in:
@@ -22,7 +22,7 @@ export class CameraManagerEngineFactory {
|
|||||||
this._cardWideConfig = cardWideConfig;
|
this._cardWideConfig = cardWideConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createEngine(engine: Engine): Promise<CameraManagerEngine | null> {
|
public createEngine(engine: Engine): CameraManagerEngine | null {
|
||||||
let cameraManagerEngine: CameraManagerEngine | null = null;
|
let cameraManagerEngine: CameraManagerEngine | null = null;
|
||||||
switch (engine) {
|
switch (engine) {
|
||||||
case Engine.Generic:
|
case Engine.Generic:
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import {
|
|||||||
RecordingSegmentsQueryResultsMap,
|
RecordingSegmentsQueryResultsMap,
|
||||||
ResultsMap,
|
ResultsMap,
|
||||||
CameraEndpoints,
|
CameraEndpoints,
|
||||||
|
Engine,
|
||||||
} from './types.js';
|
} from './types.js';
|
||||||
import orderBy from 'lodash-es/orderBy';
|
import orderBy from 'lodash-es/orderBy';
|
||||||
import { CameraManagerEngineFactory } from './engine-factory.js';
|
import { CameraManagerEngineFactory } from './engine-factory.js';
|
||||||
@@ -106,26 +107,39 @@ export class CameraManager {
|
|||||||
this._store = new CameraManagerStore();
|
this._store = new CameraManagerStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected async _getEnginesForCameras(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
camerasConfig: CamerasConfig,
|
||||||
|
): Promise<Map<CameraConfig, CameraManagerEngine>> {
|
||||||
|
const output: Map<CameraConfig, CameraManagerEngine> = new Map();
|
||||||
|
const engines: Map<Engine, CameraManagerEngine> = new Map();
|
||||||
|
|
||||||
|
for (const cameraConfig of camerasConfig) {
|
||||||
|
const engineType = await this._engineFactory.getEngineForCamera(
|
||||||
|
hass,
|
||||||
|
cameraConfig,
|
||||||
|
);
|
||||||
|
const engine = engineType
|
||||||
|
? engines.get(engineType) ?? this._engineFactory.createEngine(engineType)
|
||||||
|
: null;
|
||||||
|
if (!engine || !engineType) {
|
||||||
|
throw new CameraInitializationError(
|
||||||
|
localize('error.no_camera_engine'),
|
||||||
|
cameraConfig,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
engines.set(engineType, engine);
|
||||||
|
output.set(cameraConfig, engine);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
protected async _initializeCamera(
|
protected async _initializeCamera(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
engine: CameraManagerEngine,
|
||||||
entityRegistryManager: EntityRegistryManager,
|
entityRegistryManager: EntityRegistryManager,
|
||||||
inputCameraConfig: CameraConfig,
|
inputCameraConfig: CameraConfig,
|
||||||
): Promise<InitializedCamera> {
|
): Promise<InitializedCamera> {
|
||||||
const engineType = await this._engineFactory.getEngineForCamera(
|
|
||||||
hass,
|
|
||||||
inputCameraConfig,
|
|
||||||
);
|
|
||||||
const engine = engineType
|
|
||||||
? this._store.getEngineOfType(engineType) ??
|
|
||||||
(await this._engineFactory.createEngine(engineType))
|
|
||||||
: null;
|
|
||||||
if (!engine) {
|
|
||||||
throw new CameraInitializationError(
|
|
||||||
localize('error.no_camera_engine'),
|
|
||||||
inputCameraConfig,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const initializedConfig = await engine.initializeCamera(
|
const initializedConfig = await engine.initializeCamera(
|
||||||
hass,
|
hass,
|
||||||
entityRegistryManager,
|
entityRegistryManager,
|
||||||
@@ -159,10 +173,15 @@ export class CameraManager {
|
|||||||
await entityRegistryManager.fetchEntityList(hass);
|
await entityRegistryManager.fetchEntityList(hass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Engines are created sequentially, to avoid duplicate creation of the same
|
||||||
|
// engine. See: https://github.com/dermotduffy/frigate-hass-card/issues/941
|
||||||
|
const engineByConfig = await this._getEnginesForCameras(hass, camerasConfig);
|
||||||
|
|
||||||
|
// Configuration is initialized in parallel.
|
||||||
const results = await allPromises(
|
const results = await allPromises(
|
||||||
camerasConfig,
|
engineByConfig.entries(),
|
||||||
async (cameraConfig) =>
|
async ([cameraConfig, engine]) =>
|
||||||
await this._initializeCamera(hass, entityRegistryManager, cameraConfig),
|
await this._initializeCamera(hass, engine, entityRegistryManager, cameraConfig),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Do the additions based off the result-order, to ensure the map order is
|
// Do the additions based off the result-order, to ensure the map order is
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import uniq from 'lodash-es/uniq';
|
|
||||||
import { CameraConfig } from '../types';
|
import { CameraConfig } from '../types';
|
||||||
import { ViewMedia } from '../view/media';
|
import { ViewMedia } from '../view/media';
|
||||||
import { CameraManagerEngine } from './engine';
|
import { CameraManagerEngine } from './engine';
|
||||||
@@ -8,7 +7,7 @@ type CameraManagerEngineCameraIDMap = Map<CameraManagerEngine, Set<string>>;
|
|||||||
|
|
||||||
export class CameraManagerStore {
|
export class CameraManagerStore {
|
||||||
protected _configs: Map<string, CameraConfig> = new Map();
|
protected _configs: Map<string, CameraConfig> = new Map();
|
||||||
protected _engines: Map<string, CameraManagerEngine> = new Map();
|
protected _enginesByCamera: Map<string, CameraManagerEngine> = new Map();
|
||||||
protected _enginesByType: Map<Engine, CameraManagerEngine> = new Map();
|
protected _enginesByType: Map<Engine, CameraManagerEngine> = new Map();
|
||||||
|
|
||||||
public addCamera(
|
public addCamera(
|
||||||
@@ -17,7 +16,7 @@ export class CameraManagerStore {
|
|||||||
engine: CameraManagerEngine,
|
engine: CameraManagerEngine,
|
||||||
): void {
|
): void {
|
||||||
this._configs.set(cameraID, cameraConfig);
|
this._configs.set(cameraID, cameraConfig);
|
||||||
this._engines.set(cameraID, engine);
|
this._enginesByCamera.set(cameraID, engine);
|
||||||
this._enginesByType.set(engine.getEngineType(), engine);
|
this._enginesByType.set(engine.getEngineType(), engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +53,7 @@ export class CameraManagerStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getEngineForCameraID(cameraID: string): CameraManagerEngine | null {
|
public getEngineForCameraID(cameraID: string): CameraManagerEngine | null {
|
||||||
return this._engines.get(cameraID) ?? null;
|
return this._enginesByCamera.get(cameraID) ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getEnginesForCameraIDs(
|
public getEnginesForCameraIDs(
|
||||||
@@ -84,6 +83,6 @@ export class CameraManagerStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getAllEngines(): CameraManagerEngine[] {
|
public getAllEngines(): CameraManagerEngine[] {
|
||||||
return uniq([...this._engines.values()]);
|
return [...this._enginesByType.values()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user