- Add support for Frigate reviews / detections. - Add support for GenAI metadata. - Significant internal refactor to more flexible "UnifiedQuery" to allow mixing cameras with simple metadata and review metadata (e.g. a timeline view of a Frigate camera with reviews, and a Reolink camera with simple metadata). - Add support for folder media as camera media. There are a few more PRs to commit prior to this going live, but commiting this for now due to the scale of the change. BREAKING CHANGE: `media_type` and `events_type` are retired under `live`, `viewer` and `timeline` configuration sections, instead media type is associated (once) with the camera under `media`.
152 lines
4.3 KiB
TypeScript
152 lines
4.3 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
import { Capabilities } from '../../../../src/camera-manager/capabilities';
|
|
import { PTZMultiAction } from '../../../../src/card-controller/actions/actions/ptz-multi';
|
|
import { PTZMovementType } from '../../../../src/types';
|
|
import {
|
|
createCameraManager,
|
|
createCardAPI,
|
|
createStore,
|
|
createView,
|
|
} from '../../../test-utils';
|
|
|
|
describe('should handle ptz multi action', () => {
|
|
describe.each([
|
|
['with explicit target_id', 'camera.office'],
|
|
['without explicit target_id', null],
|
|
])('%s', async (_testTitle: string, targetID: string | null) => {
|
|
it('should use real ptz when camera has ptz support', async () => {
|
|
const api = createCardAPI();
|
|
vi.mocked(api.getViewManager().getView).mockReturnValue(
|
|
createView({
|
|
camera: 'camera.office',
|
|
}),
|
|
);
|
|
const store = createStore([
|
|
{
|
|
cameraID: 'camera.office',
|
|
capabilities: new Capabilities({ ptz: { left: [PTZMovementType.Relative] } }),
|
|
},
|
|
]);
|
|
vi.mocked(api.getCameraManager).mockReturnValue(createCameraManager(store));
|
|
|
|
const action = new PTZMultiAction(
|
|
{},
|
|
{
|
|
action: 'fire-dom-event',
|
|
advanced_camera_card_action: 'ptz_multi',
|
|
ptz_action: 'left',
|
|
...(targetID && { target_id: targetID }),
|
|
},
|
|
);
|
|
|
|
await action.execute(api);
|
|
|
|
expect(api.getCameraManager().executePTZAction).toBeCalledWith(
|
|
'camera.office',
|
|
'left',
|
|
{
|
|
phase: undefined,
|
|
preset: undefined,
|
|
},
|
|
);
|
|
expect(api.getViewManager().setViewWithMergedContext).not.toBeCalled();
|
|
});
|
|
|
|
it('should use digital ptz when camera does not have ptz support', async () => {
|
|
const api = createCardAPI();
|
|
vi.mocked(api.getViewManager().getView).mockReturnValue(
|
|
createView({
|
|
camera: 'camera.office',
|
|
}),
|
|
);
|
|
const store = createStore([
|
|
{
|
|
cameraID: 'camera.office',
|
|
},
|
|
]);
|
|
vi.mocked(api.getCameraManager).mockReturnValue(createCameraManager(store));
|
|
|
|
const action = new PTZMultiAction(
|
|
{},
|
|
{
|
|
action: 'fire-dom-event',
|
|
advanced_camera_card_action: 'ptz_multi',
|
|
ptz_action: 'right',
|
|
...(targetID && { target_id: targetID }),
|
|
},
|
|
);
|
|
|
|
await action.execute(api);
|
|
|
|
expect(api.getCameraManager().executePTZAction).not.toBeCalled();
|
|
expect(api.getViewManager().setViewWithMergedContext).toHaveBeenLastCalledWith({
|
|
zoom: {
|
|
'camera.office': {
|
|
observed: undefined,
|
|
requested: expect.objectContaining({
|
|
pan: {
|
|
x: 55,
|
|
y: 50,
|
|
},
|
|
zoom: 1,
|
|
}),
|
|
},
|
|
},
|
|
});
|
|
});
|
|
});
|
|
|
|
it('should do nothing without a view or explicit target_id', async () => {
|
|
const api = createCardAPI();
|
|
const store = createStore([
|
|
{
|
|
cameraID: 'camera.office',
|
|
},
|
|
]);
|
|
vi.mocked(api.getCameraManager).mockReturnValue(createCameraManager(store));
|
|
|
|
const action = new PTZMultiAction(
|
|
{},
|
|
{
|
|
action: 'fire-dom-event',
|
|
advanced_camera_card_action: 'ptz_multi',
|
|
ptz_action: 'right',
|
|
},
|
|
);
|
|
|
|
await action.execute(api);
|
|
|
|
expect(api.getCameraManager().executePTZAction).not.toBeCalled();
|
|
expect(api.getViewManager().setViewWithMergedContext).not.toBeCalled();
|
|
});
|
|
|
|
it('should do nothing with a media-less view without an explicit target_id', async () => {
|
|
const api = createCardAPI();
|
|
vi.mocked(api.getViewManager().getView).mockReturnValue(
|
|
createView({
|
|
view: 'timeline',
|
|
}),
|
|
);
|
|
const store = createStore([
|
|
{
|
|
cameraID: 'camera.office',
|
|
},
|
|
]);
|
|
vi.mocked(api.getCameraManager).mockReturnValue(createCameraManager(store));
|
|
|
|
const action = new PTZMultiAction(
|
|
{},
|
|
{
|
|
action: 'fire-dom-event',
|
|
advanced_camera_card_action: 'ptz_multi',
|
|
ptz_action: 'right',
|
|
},
|
|
);
|
|
|
|
await action.execute(api);
|
|
|
|
expect(api.getCameraManager().executePTZAction).not.toBeCalled();
|
|
expect(api.getViewManager().setViewWithMergedContext).not.toBeCalled();
|
|
});
|
|
});
|