fix: Small (rare) bug in Frigate PTZ identification capability (#2296)

[skip ci]
This commit is contained in:
Dermot Duffy
2025-12-20 14:52:07 -08:00
committed by GitHub
parent b06e0aea4d
commit d17ecd6c12
2 changed files with 75 additions and 9 deletions
+3 -3
View File
@@ -327,14 +327,14 @@ export class FrigateCamera extends Camera {
if (panTilt.length || zoom.length || presets?.length) { if (panTilt.length || zoom.length || presets?.length) {
return { return {
...(panTilt && { ...(panTilt.length && {
left: panTilt, left: panTilt,
right: panTilt, right: panTilt,
up: panTilt, up: panTilt,
down: panTilt, down: panTilt,
}), }),
...(zoom && { zoomIn: zoom, zoomOut: zoom }), ...(zoom.length && { zoomIn: zoom, zoomOut: zoom }),
...(presets && { presets: presets }), ...(presets?.length && { presets: presets }),
}; };
} }
return null; return null;
+72 -6
View File
@@ -292,16 +292,82 @@ describe('FrigateCamera', () => {
}); });
expect(camera.getCapabilities()?.has('ptz')).toBeTruthy(); expect(camera.getCapabilities()?.has('ptz')).toBeTruthy();
expect(camera.getCapabilities()?.getPTZCapabilities()).toEqual({ expect(camera.getCapabilities()?.getPTZCapabilities()).toEqual({
left: [], // pt-r and zoom-r don't match 'pt' and 'zoom', so only presets
right: [],
up: [],
down: [],
zoomIn: [],
zoomOut: [],
presets: ['preset01'], presets: ['preset01'],
}); });
expect(camera.getCapabilities()?.hasPTZCapability()).toBeTruthy(); expect(camera.getCapabilities()?.hasPTZCapability()).toBeTruthy();
}); });
it('when getPTZInfo returns only zoom capabilities', async () => {
vi.spyOn(global.console, 'warn').mockReturnValue(undefined);
const camera = new FrigateCamera(
createCameraConfig({
frigate: {
camera_name: 'front_door',
},
}),
mock<CameraManagerEngine>(),
);
vi.mocked(getPTZInfo).mockResolvedValue({
features: ['zoom'],
name: 'front_door',
presets: [],
});
await camera.initialize({
hass: createHASS(),
entityRegistryManager: mock<EntityRegistryManager>(),
stateWatcher: mock<StateWatcher>(),
frigateEventWatcher: mock<FrigateEventWatcher>(),
});
expect(camera.getCapabilities()?.has('ptz')).toBeTruthy();
// Should only have zoom capabilities, not empty pan/tilt arrays
expect(camera.getCapabilities()?.getPTZCapabilities()).toEqual({
zoomIn: ['continuous'],
zoomOut: ['continuous'],
});
expect(camera.getCapabilities()?.hasPTZCapability()).toBeTruthy();
});
it('when getPTZInfo returns only pan/tilt capabilities', async () => {
vi.spyOn(global.console, 'warn').mockReturnValue(undefined);
const camera = new FrigateCamera(
createCameraConfig({
frigate: {
camera_name: 'front_door',
},
}),
mock<CameraManagerEngine>(),
);
vi.mocked(getPTZInfo).mockResolvedValue({
features: ['pt'],
name: 'front_door',
presets: [],
});
await camera.initialize({
hass: createHASS(),
entityRegistryManager: mock<EntityRegistryManager>(),
stateWatcher: mock<StateWatcher>(),
frigateEventWatcher: mock<FrigateEventWatcher>(),
});
expect(camera.getCapabilities()?.has('ptz')).toBeTruthy();
// Should only have pan/tilt capabilities, not empty zoom arrays
expect(camera.getCapabilities()?.getPTZCapabilities()).toEqual({
left: ['continuous'],
right: ['continuous'],
up: ['continuous'],
down: ['continuous'],
});
expect(camera.getCapabilities()?.hasPTZCapability()).toBeTruthy();
});
}); });
}); });