feat: Auto-resolve Frigate client_id from camera entity (#2475)
Credit goes to @Eduardo-Jaramillo for the inspiration and contribution of https://github.com/dermotduffy/advanced-camera-card/pull/2474 .
This commit is contained in:
committed by
dermotduffy
parent
9d088d7bcb
commit
261a7e1a92
@@ -24,7 +24,12 @@ import { CameraTriggerEventType } from '../../../src/config/schema/cameras';
|
||||
import { Entity, EntityRegistryManager } from '../../../src/ha/registry/entity/types';
|
||||
import { ViewMediaType } from '../../../src/view/item';
|
||||
import { EntityRegistryManagerMock } from '../../ha/registry/entity/mock';
|
||||
import { createCameraConfig, createHASS, createRegistryEntity } from '../../test-utils';
|
||||
import {
|
||||
createCameraConfig,
|
||||
createHASS,
|
||||
createRegistryEntity,
|
||||
createStateEntity,
|
||||
} from '../../test-utils';
|
||||
|
||||
vi.mock('../../../src/camera-manager/frigate/requests');
|
||||
|
||||
@@ -168,6 +173,118 @@ describe('FrigateCamera', () => {
|
||||
expect(camera.getConfig().frigate.camera_name).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('should resolve client_id', () => {
|
||||
it('from a non-default value on the entity attributes', async () => {
|
||||
const camera = new FrigateCamera(
|
||||
createCameraConfig({
|
||||
camera_entity: 'camera.front_door',
|
||||
frigate: { camera_name: 'front_door' },
|
||||
}),
|
||||
mock<CameraManagerEngine>(),
|
||||
);
|
||||
await camera.initialize({
|
||||
hass: createHASS({
|
||||
'camera.front_door': createStateEntity({
|
||||
entity_id: 'camera.front_door',
|
||||
attributes: { client_id: 'remote_frigate' },
|
||||
}),
|
||||
}),
|
||||
entityRegistryManager: mock<EntityRegistryManager>(),
|
||||
stateWatcher: mock<StateWatcher>(),
|
||||
frigateEventWatcher: mock<FrigateEventWatcher>(),
|
||||
frigateReviewWatcher: mock<FrigateReviewWatcher>(),
|
||||
});
|
||||
expect(camera.getConfig().frigate.client_id).toBe('remote_frigate');
|
||||
});
|
||||
|
||||
it('falls back to "frigate" when the entity attribute is missing', async () => {
|
||||
const camera = new FrigateCamera(
|
||||
createCameraConfig({
|
||||
camera_entity: 'camera.front_door',
|
||||
frigate: { camera_name: 'front_door' },
|
||||
}),
|
||||
mock<CameraManagerEngine>(),
|
||||
);
|
||||
await camera.initialize({
|
||||
hass: createHASS({
|
||||
'camera.front_door': createStateEntity({
|
||||
entity_id: 'camera.front_door',
|
||||
attributes: {},
|
||||
}),
|
||||
}),
|
||||
entityRegistryManager: mock<EntityRegistryManager>(),
|
||||
stateWatcher: mock<StateWatcher>(),
|
||||
frigateEventWatcher: mock<FrigateEventWatcher>(),
|
||||
frigateReviewWatcher: mock<FrigateReviewWatcher>(),
|
||||
});
|
||||
expect(camera.getConfig().frigate.client_id).toBe('frigate');
|
||||
});
|
||||
|
||||
it('falls back to "frigate" when no camera_entity is configured', async () => {
|
||||
const camera = new FrigateCamera(
|
||||
createCameraConfig({
|
||||
frigate: { camera_name: 'front_door' },
|
||||
}),
|
||||
mock<CameraManagerEngine>(),
|
||||
);
|
||||
await camera.initialize({
|
||||
hass: createHASS(),
|
||||
entityRegistryManager: mock<EntityRegistryManager>(),
|
||||
stateWatcher: mock<StateWatcher>(),
|
||||
frigateEventWatcher: mock<FrigateEventWatcher>(),
|
||||
frigateReviewWatcher: mock<FrigateReviewWatcher>(),
|
||||
});
|
||||
expect(camera.getConfig().frigate.client_id).toBe('frigate');
|
||||
});
|
||||
|
||||
it('preserves an explicit value', async () => {
|
||||
const camera = new FrigateCamera(
|
||||
createCameraConfig({
|
||||
camera_entity: 'camera.front_door',
|
||||
frigate: { camera_name: 'front_door', client_id: 'remote_x' },
|
||||
}),
|
||||
mock<CameraManagerEngine>(),
|
||||
);
|
||||
await camera.initialize({
|
||||
hass: createHASS({
|
||||
'camera.front_door': createStateEntity({
|
||||
entity_id: 'camera.front_door',
|
||||
attributes: { client_id: 'something_else' },
|
||||
}),
|
||||
}),
|
||||
entityRegistryManager: mock<EntityRegistryManager>(),
|
||||
stateWatcher: mock<StateWatcher>(),
|
||||
frigateEventWatcher: mock<FrigateEventWatcher>(),
|
||||
frigateReviewWatcher: mock<FrigateReviewWatcher>(),
|
||||
});
|
||||
expect(camera.getConfig().frigate.client_id).toBe('remote_x');
|
||||
});
|
||||
|
||||
it('leaves client_id untouched when the camera entity is unavailable', async () => {
|
||||
const camera = new FrigateCamera(
|
||||
createCameraConfig({
|
||||
camera_entity: 'camera.front_door',
|
||||
frigate: { camera_name: 'front_door' },
|
||||
}),
|
||||
mock<CameraManagerEngine>(),
|
||||
);
|
||||
await camera.initialize({
|
||||
hass: createHASS({
|
||||
'camera.front_door': createStateEntity({
|
||||
entity_id: 'camera.front_door',
|
||||
state: 'unavailable',
|
||||
attributes: {},
|
||||
}),
|
||||
}),
|
||||
entityRegistryManager: mock<EntityRegistryManager>(),
|
||||
stateWatcher: mock<StateWatcher>(),
|
||||
frigateEventWatcher: mock<FrigateEventWatcher>(),
|
||||
frigateReviewWatcher: mock<FrigateReviewWatcher>(),
|
||||
});
|
||||
expect(camera.getConfig().frigate.client_id).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('should detect capabilities', () => {
|
||||
|
||||
@@ -113,6 +113,7 @@ const createFrigateCameraConfig = (
|
||||
return createCameraConfig({
|
||||
frigate: {
|
||||
camera_name: 'camera-1',
|
||||
client_id: 'frigate',
|
||||
},
|
||||
camera_entity: 'camera.office',
|
||||
...config,
|
||||
@@ -355,6 +356,17 @@ describe('FrigateCameraManagerEngine', () => {
|
||||
);
|
||||
expect(endpoint).toBeNull();
|
||||
});
|
||||
|
||||
it('should get no path when client_id is unresolved', async () => {
|
||||
const endpoint = await createEngine().getMediaDownloadPath(
|
||||
createHASS(),
|
||||
createFrigateCameraConfig({
|
||||
frigate: { camera_name: 'camera-1' },
|
||||
}),
|
||||
createClipMedia(),
|
||||
);
|
||||
expect(endpoint).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('generateDefaultEventQuery', () => {
|
||||
|
||||
@@ -20,9 +20,7 @@ describe('config defaults', () => {
|
||||
cameras: [],
|
||||
},
|
||||
engine: 'auto',
|
||||
frigate: {
|
||||
client_id: 'frigate',
|
||||
},
|
||||
frigate: {},
|
||||
go2rtc: {
|
||||
metadata_fetch_timeout_seconds: 2,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user