115 lines
4.0 KiB
TypeScript
115 lines
4.0 KiB
TypeScript
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
|
|
import { CameraConfig } from '../config/types';
|
|
import { localize } from '../localize/localize';
|
|
import { BrowseMediaManager } from '../utils/ha/browse-media/browse-media-manager';
|
|
import { BrowseMedia } from '../utils/ha/browse-media/types';
|
|
import { EntityRegistryManager } from '../utils/ha/entity-registry';
|
|
import { Entity } from '../utils/ha/entity-registry/types';
|
|
import { ResolvedMediaCache } from '../utils/ha/resolved-media';
|
|
import { MemoryRequestCache, RecordingSegmentsCache, RequestCache } from './cache';
|
|
import { CameraManagerEngine } from './engine';
|
|
import { CameraInitializationError } from './error';
|
|
import { CameraEventCallback, Engine } from './types';
|
|
import { getCameraEntityFromConfig } from './utils/camera-entity-from-config';
|
|
|
|
export class CameraManagerEngineFactory {
|
|
protected _entityRegistryManager: EntityRegistryManager;
|
|
protected _resolvedMediaCache: ResolvedMediaCache;
|
|
|
|
constructor(
|
|
entityRegistryManager: EntityRegistryManager,
|
|
resolvedMediaCache: ResolvedMediaCache,
|
|
) {
|
|
this._entityRegistryManager = entityRegistryManager;
|
|
this._resolvedMediaCache = resolvedMediaCache;
|
|
}
|
|
|
|
public async createEngine(
|
|
engine: Engine,
|
|
eventCallback?: CameraEventCallback,
|
|
): Promise<CameraManagerEngine> {
|
|
let cameraManagerEngine: CameraManagerEngine;
|
|
switch (engine) {
|
|
case Engine.Generic:
|
|
const { GenericCameraManagerEngine } = await import('./generic/engine-generic');
|
|
cameraManagerEngine = new GenericCameraManagerEngine(eventCallback);
|
|
break;
|
|
case Engine.Frigate:
|
|
const { FrigateCameraManagerEngine } = await import('./frigate/engine-frigate');
|
|
cameraManagerEngine = new FrigateCameraManagerEngine(
|
|
new RecordingSegmentsCache(),
|
|
new RequestCache(),
|
|
eventCallback,
|
|
);
|
|
break;
|
|
case Engine.MotionEye:
|
|
const { MotionEyeCameraManagerEngine } = await import(
|
|
'./motioneye/engine-motioneye'
|
|
);
|
|
cameraManagerEngine = new MotionEyeCameraManagerEngine(
|
|
new BrowseMediaManager(new MemoryRequestCache<string, BrowseMedia>()),
|
|
this._resolvedMediaCache,
|
|
new RequestCache(),
|
|
eventCallback,
|
|
);
|
|
}
|
|
return cameraManagerEngine;
|
|
}
|
|
|
|
public async getEngineForCamera(
|
|
hass: HomeAssistant,
|
|
cameraConfig: CameraConfig,
|
|
): Promise<Engine | null> {
|
|
let engine: Engine | null = null;
|
|
if (cameraConfig.engine === 'frigate') {
|
|
engine = Engine.Frigate;
|
|
} else if (cameraConfig.engine === 'motioneye') {
|
|
engine = Engine.MotionEye;
|
|
} else if (cameraConfig.engine === 'generic') {
|
|
engine = Engine.Generic;
|
|
} else {
|
|
const cameraEntity = getCameraEntityFromConfig(cameraConfig);
|
|
|
|
if (cameraEntity) {
|
|
let entity: Entity | null;
|
|
try {
|
|
entity = await this._entityRegistryManager.getEntity(hass, cameraEntity);
|
|
} catch (e) {
|
|
// If the camera is not in the registry, but is in the HA states it is
|
|
// assumed to be a generic camera.
|
|
if (hass.states[cameraEntity]) {
|
|
return Engine.Generic;
|
|
}
|
|
// Otherwise, it's probably a typo so throw an exception.
|
|
throw new CameraInitializationError(
|
|
localize('error.no_camera_entity'),
|
|
cameraConfig,
|
|
);
|
|
}
|
|
|
|
switch (entity?.platform) {
|
|
case 'frigate':
|
|
engine = Engine.Frigate;
|
|
break;
|
|
case 'motioneye':
|
|
engine = Engine.MotionEye;
|
|
break;
|
|
default:
|
|
engine = Engine.Generic;
|
|
}
|
|
} else if (cameraConfig.frigate.camera_name) {
|
|
// Frigate technically does not need an entity, if the camera name is
|
|
// manually set the camera is assumed to be Frigate.
|
|
engine = Engine.Frigate;
|
|
} else if (
|
|
cameraConfig.webrtc_card?.url ||
|
|
(cameraConfig.go2rtc?.url && cameraConfig.go2rtc?.stream)
|
|
) {
|
|
engine = Engine.Generic;
|
|
}
|
|
}
|
|
|
|
return engine;
|
|
}
|
|
}
|