fix: Ignore startup triggers from cameras without the trigger capability (#2621)
- Closes: #2103
This commit is contained in:
@@ -71,6 +71,13 @@ export class CameraTriggersManager {
|
|||||||
.getCameraManager()
|
.getCameraManager()
|
||||||
.getStore()
|
.getStore()
|
||||||
.getCameras()) {
|
.getCameras()) {
|
||||||
|
// A camera without the trigger capability never subscribes to its
|
||||||
|
// configured trigger entities, so its already-on entities must not
|
||||||
|
// synthesize a trigger here either.
|
||||||
|
if (!camera.getCapabilities()?.has('trigger')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (const entityID of camera.getConfig().triggers.entities) {
|
for (const entityID of camera.getConfig().triggers.entities) {
|
||||||
if (isTriggeredState(hass?.states[entityID]?.state)) {
|
if (isTriggeredState(hass?.states[entityID]?.state)) {
|
||||||
triggered = true;
|
triggered = true;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { triggersSchema, type TriggersOptions } from '../../src/config/schema/vi
|
|||||||
import {
|
import {
|
||||||
createCameraConfig,
|
createCameraConfig,
|
||||||
createCameraManager,
|
createCameraManager,
|
||||||
|
createCapabilities,
|
||||||
createCardAPI,
|
createCardAPI,
|
||||||
createConfig,
|
createConfig,
|
||||||
createHASS,
|
createHASS,
|
||||||
@@ -1566,6 +1567,90 @@ describe('CameraTriggersManager', () => {
|
|||||||
expect(api.getViewManager().setViewByParametersWithNewQuery).not.toBeCalled();
|
expect(api.getViewManager().setViewByParametersWithNewQuery).not.toBeCalled();
|
||||||
expect(api.getViewManager().setViewDefaultWithNewQuery).not.toBeCalled();
|
expect(api.getViewManager().setViewDefaultWithNewQuery).not.toBeCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not trigger a camera without the trigger capability', async () => {
|
||||||
|
const api = createTriggerAPI();
|
||||||
|
vi.mocked(api.getCameraManager().getStore).mockReturnValue(
|
||||||
|
createStore([
|
||||||
|
{
|
||||||
|
cameraID: 'camera_1',
|
||||||
|
capabilities: createCapabilities({ trigger: false }),
|
||||||
|
config: createCameraConfig({
|
||||||
|
triggers: {
|
||||||
|
entities: ['binary_sensor.motion'],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
const hass = createHASS({
|
||||||
|
'binary_sensor.motion': createStateEntity({
|
||||||
|
state: 'on',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
vi.mocked(api.getHASSManager().getHASS).mockReturnValue(hass);
|
||||||
|
|
||||||
|
const manager = new CameraTriggersManager(api);
|
||||||
|
const result = await manager.handleInitialCameraTriggers();
|
||||||
|
|
||||||
|
expect(result).toBeFalsy();
|
||||||
|
expect(manager.isTriggered()).toBeFalsy();
|
||||||
|
expect(api.getViewManager().setViewByParametersWithNewQuery).not.toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should target the startup action at a camera that has the trigger capability', async () => {
|
||||||
|
const api = createTriggerAPI({
|
||||||
|
config: {
|
||||||
|
actions: {
|
||||||
|
trigger: 'live',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
vi.mocked(api.getCameraManager().getStore).mockReturnValue(
|
||||||
|
createStore([
|
||||||
|
{
|
||||||
|
cameraID: 'substream',
|
||||||
|
capabilities: createCapabilities({ substream: true, trigger: false }),
|
||||||
|
config: createCameraConfig({
|
||||||
|
triggers: {
|
||||||
|
entities: ['binary_sensor.motion'],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cameraID: 'camera_1',
|
||||||
|
config: createCameraConfig({
|
||||||
|
dependencies: {
|
||||||
|
cameras: ['substream'],
|
||||||
|
},
|
||||||
|
triggers: {
|
||||||
|
entities: ['binary_sensor.motion'],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
const hass = createHASS({
|
||||||
|
'binary_sensor.motion': createStateEntity({
|
||||||
|
state: 'on',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
vi.mocked(api.getHASSManager().getHASS).mockReturnValue(hass);
|
||||||
|
|
||||||
|
const manager = new CameraTriggersManager(api);
|
||||||
|
const result = await manager.handleInitialCameraTriggers();
|
||||||
|
|
||||||
|
expect(result).toBeTruthy();
|
||||||
|
expect(manager.getTriggeredCameraIDs()).toEqual(new Set(['camera_1']));
|
||||||
|
expect(api.getViewManager().setViewByParametersWithNewQuery).toHaveBeenCalledWith({
|
||||||
|
params: {
|
||||||
|
view: 'live',
|
||||||
|
camera: 'camera_1',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should take actions with human interactions when interaction mode is active', async () => {
|
it('should take actions with human interactions when interaction mode is active', async () => {
|
||||||
|
|||||||
@@ -381,6 +381,7 @@ export const createCapabilities = (capabilities?: CapabilitiesRaw): Capabilities
|
|||||||
recordings: false,
|
recordings: false,
|
||||||
seek: false,
|
seek: false,
|
||||||
snapshots: false,
|
snapshots: false,
|
||||||
|
trigger: true,
|
||||||
...capabilities,
|
...capabilities,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user