154 lines
5.4 KiB
TypeScript
154 lines
5.4 KiB
TypeScript
import { HASSManagerReadonlyInterface } from '../card-controller/hass/types';
|
|
import { CameraConfig } from '../config/schema/cameras';
|
|
import { BrowseMediaWalker } from '../ha/browse-media/walker';
|
|
import { DeviceRegistryManager } from '../ha/registry/device';
|
|
import { EntityRegistryManager } from '../ha/registry/entity/types';
|
|
import { ResolvedMediaCache } from '../ha/resolved-media';
|
|
import { HomeAssistant } from '../ha/types';
|
|
import { RecordingSegmentsCache } from './cache';
|
|
import { CameraManagerEngine } from './engine';
|
|
import { CameraNoEntityError } from './error';
|
|
import { CameraEventCallback, CameraManagerRequestCache, Engine } from './types';
|
|
import { getCameraEntityFromConfig } from './utils/camera-entity-from-config';
|
|
|
|
interface CameraManagerEngineFactoryOptions {
|
|
hassManager: HASSManagerReadonlyInterface;
|
|
resolvedMediaCache: ResolvedMediaCache;
|
|
eventCallback?: CameraEventCallback;
|
|
}
|
|
|
|
export class CameraManagerEngineFactory {
|
|
private _entityRegistryManager: EntityRegistryManager;
|
|
private _deviceRegistryManager: DeviceRegistryManager;
|
|
|
|
constructor(
|
|
entityRegistryManager: EntityRegistryManager,
|
|
deviceRegistryManager: DeviceRegistryManager,
|
|
) {
|
|
this._entityRegistryManager = entityRegistryManager;
|
|
this._deviceRegistryManager = deviceRegistryManager;
|
|
}
|
|
|
|
public async createEngine(
|
|
engine: Engine,
|
|
options: CameraManagerEngineFactoryOptions,
|
|
): Promise<CameraManagerEngine> {
|
|
let cameraManagerEngine: CameraManagerEngine;
|
|
switch (engine) {
|
|
case Engine.Generic:
|
|
const { GenericCameraManagerEngine } = await import('./generic/engine-generic');
|
|
cameraManagerEngine = new GenericCameraManagerEngine(
|
|
options.hassManager,
|
|
this._entityRegistryManager,
|
|
options.eventCallback,
|
|
);
|
|
break;
|
|
case Engine.Frigate:
|
|
const { FrigateCameraManagerEngine } = await import('./frigate/engine-frigate');
|
|
cameraManagerEngine = new FrigateCameraManagerEngine(
|
|
this._entityRegistryManager,
|
|
options.hassManager,
|
|
new RecordingSegmentsCache(),
|
|
new CameraManagerRequestCache(),
|
|
options.eventCallback,
|
|
);
|
|
break;
|
|
case Engine.MotionEye:
|
|
const { MotionEyeCameraManagerEngine } = await import(
|
|
'./motioneye/engine-motioneye'
|
|
);
|
|
cameraManagerEngine = new MotionEyeCameraManagerEngine(
|
|
this._entityRegistryManager,
|
|
options.hassManager,
|
|
new BrowseMediaWalker(),
|
|
options.resolvedMediaCache,
|
|
new CameraManagerRequestCache(),
|
|
options.eventCallback,
|
|
);
|
|
break;
|
|
case Engine.Reolink:
|
|
const { ReolinkCameraManagerEngine } = await import('./reolink/engine-reolink');
|
|
cameraManagerEngine = new ReolinkCameraManagerEngine(
|
|
this._entityRegistryManager,
|
|
this._deviceRegistryManager,
|
|
options.hassManager,
|
|
new BrowseMediaWalker(),
|
|
options.resolvedMediaCache,
|
|
new CameraManagerRequestCache(),
|
|
options.eventCallback,
|
|
);
|
|
break;
|
|
case Engine.TPLink:
|
|
const { TPLinkCameraManagerEngine } = await import('./tplink/engine-tplink');
|
|
cameraManagerEngine = new TPLinkCameraManagerEngine(
|
|
this._entityRegistryManager,
|
|
options.hassManager,
|
|
options.eventCallback,
|
|
);
|
|
break;
|
|
}
|
|
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 if (cameraConfig.engine === 'reolink') {
|
|
engine = Engine.Reolink;
|
|
} else if (cameraConfig.engine === 'tplink') {
|
|
engine = Engine.TPLink;
|
|
} else {
|
|
const cameraEntity = getCameraEntityFromConfig(cameraConfig);
|
|
|
|
if (cameraEntity) {
|
|
const entity = await this._entityRegistryManager.getEntity(hass, cameraEntity);
|
|
if (!entity) {
|
|
// 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 CameraNoEntityError(cameraConfig);
|
|
}
|
|
|
|
switch (entity?.platform) {
|
|
case 'frigate':
|
|
engine = Engine.Frigate;
|
|
break;
|
|
case 'motioneye':
|
|
engine = Engine.MotionEye;
|
|
break;
|
|
case 'reolink':
|
|
engine = Engine.Reolink;
|
|
break;
|
|
case 'tplink':
|
|
engine = Engine.TPLink;
|
|
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;
|
|
}
|
|
}
|