fix: Configured PTZ actions should overrule auto-detected actions (not merge with them) (#1558)

* fix: Configured PTZ actions should overrule auto-detected actions (not merge with them)

* Don't populate capabilities unless there is some basis
This commit is contained in:
Dermot Duffy
2024-09-21 18:32:40 -07:00
committed by GitHub
parent 7fd6bc6bee
commit c225a9aeab
6 changed files with 31 additions and 30 deletions
+5
View File
@@ -203,6 +203,11 @@ to allow for precise/smooth controls, and if unavailable will translate multiple
`relative` steps with optional delays between each step. Manually configured `relative` steps with optional delays between each step. Manually configured
[actions](../actions/README.md) may be configured to call either variety. [actions](../actions/README.md) may be configured to call either variety.
When PTZ actions are manually set in the config, they will replace the
auto-detected actions. For example if `actions_left` is set for a Frigate
camera, it will be used for all `left` PTZ actions even though Frigate cameras
natively support continuous actions (`actions_left_start`, `actions_left_stop`).
?> Frigate auto-detected PTZ actions will always be `continuous` as this is what ?> Frigate auto-detected PTZ actions will always be `continuous` as this is what
the integration currently offers. the integration currently offers.
+7 -10
View File
@@ -4,10 +4,7 @@ import { StateWatcherSubscriptionInterface } from '../../card-controller/hass/st
import { CameraConfig } from '../../config/types'; import { CameraConfig } from '../../config/types';
import { localize } from '../../localize/localize'; import { localize } from '../../localize/localize';
import { PTZCapabilities, PTZMovementType } from '../../types'; import { PTZCapabilities, PTZMovementType } from '../../types';
import { import { errorToConsole } from '../../utils/basic';
errorToConsole,
recursivelyMergeObjectsConcatenatingArraysUniquely,
} from '../../utils/basic';
import { EntityRegistryManager } from '../../utils/ha/entity-registry'; import { EntityRegistryManager } from '../../utils/ha/entity-registry';
import { Entity } from '../../utils/ha/entity-registry/types'; import { Entity } from '../../utils/ha/entity-registry/types';
import { Camera, CameraInitializationOptions } from '../camera'; import { Camera, CameraInitializationOptions } from '../camera';
@@ -125,13 +122,13 @@ export class FrigateCamera extends Camera {
const configPTZCapabilities = getPTZCapabilitiesFromCameraConfig(this.getConfig()); const configPTZCapabilities = getPTZCapabilitiesFromCameraConfig(this.getConfig());
const frigatePTZCapabilities = await this._getPTZCapabilities(hass, config); const frigatePTZCapabilities = await this._getPTZCapabilities(hass, config);
const combinedPTZCapabilities =
const combinedPTZCapabilities: PTZCapabilities | null =
configPTZCapabilities || frigatePTZCapabilities configPTZCapabilities || frigatePTZCapabilities
? recursivelyMergeObjectsConcatenatingArraysUniquely( ? {
{}, ...frigatePTZCapabilities,
configPTZCapabilities, ...configPTZCapabilities,
frigatePTZCapabilities, }
)
: null; : null;
const birdseye = isBirdseye(config); const birdseye = isBirdseye(config);
+9 -7
View File
@@ -70,13 +70,15 @@ export const getPTZCapabilitiesFromCameraConfig = (
zoomOut?.length || zoomOut?.length ||
presets?.length presets?.length
? { ? {
left: left ?? undefined, // Only return keys with some capability (to aid with action merging
right: right ?? undefined, // later).
up: up ?? undefined, ...(left ? { left } : {}),
down: down ?? undefined, ...(right ? { right } : {}),
zoomIn: zoomIn ?? undefined, ...(up ? { up } : {}),
zoomOut: zoomOut ?? undefined, ...(down ? { down } : {}),
presets: presets, ...(zoomIn ? { zoomIn } : {}),
...(zoomOut ? { zoomOut } : {}),
...(presets ? { presets } : {}),
} }
: null; : null;
}; };
+3 -2
View File
@@ -210,8 +210,9 @@ describe('FrigateCamera', () => {
entityRegistryManager: mock<EntityRegistryManager>(), entityRegistryManager: mock<EntityRegistryManager>(),
stateWatcher: mock<StateWatcher>(), stateWatcher: mock<StateWatcher>(),
frigateEventWatcher: mock<FrigateEventWatcher>(), frigateEventWatcher: mock<FrigateEventWatcher>(),
}), });
expect(camera.getCapabilities()?.has('ptz')).toBeFalsy();
expect(camera.getCapabilities()?.has('ptz')).toBeFalsy();
expect(camera.getCapabilities()?.hasPTZCapability()).toBeFalsy(); expect(camera.getCapabilities()?.hasPTZCapability()).toBeFalsy();
expect(consoleSpy).toBeCalled(); expect(consoleSpy).toBeCalled();
}); });
+6 -10
View File
@@ -163,11 +163,9 @@ describe('getPTZCapabilitiesFromCameraConfig', () => {
}, },
}), }),
), ),
)?.toEqual( )?.toEqual({
expect.objectContaining({ [capabilityName]: ['relative'],
[capabilityName]: ['relative'], });
}),
);
}); });
}); });
@@ -182,10 +180,8 @@ describe('getPTZCapabilitiesFromCameraConfig', () => {
}, },
}), }),
), ),
)?.toEqual( )?.toEqual({
expect.objectContaining({ presets: ['window'],
presets: ['window'], });
}),
);
}); });
}); });
+1 -1
View File
@@ -1,4 +1,4 @@
import { describe, expect, it, vi } from 'vitest'; import { describe, expect, it } from 'vitest';
import { Capabilities } from '../../src/camera-manager/capabilities'; import { Capabilities } from '../../src/camera-manager/capabilities';
import { import {
getPTZTarget, getPTZTarget,