feat: Add TPLink camera engine support (#2257)
* Related #2183 <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Introduce `tplink` camera engine with relative PTZ via button entities, add icons/docs support, refactor to `EntityCamera`, and extend tests/schema/factory for auto-detection. > > - **Engines** > - **New `tplink` engine**: > - Add `Engine.TPLink`, schema support (`engine: 'tplink'`). > - Implement `TPLinkCameraManagerEngine` and `TPLinkCamera` (relative PTZ via `button.*` entities; no presets/zoom; stop is no-op). > - Update `engine-factory` to create/auto-detect `tplink` (platform `tplink`). > - **Refactor** > - Replace `BrowseMediaCamera` with `EntityCamera`; update `motioneye` and `reolink` cameras and `motioneye` engine type checks. > - **UI/Icons** > - Add `tplink.svg`; wire into `IconController`; update docs icon copy script. > - **Docs** > - Add `tplink` to engine capability and live-provider matrices; new `tplink` section incl. PTZ note; add custom icon entry. > - **Tests** > - Add TPLink camera/engine tests and factory tests; remove obsolete `BrowseMediaCamera` test. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 74a688c3bd602912d63a22c3c6fa2f4b60ec14f9. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This commit is contained in:
@@ -1,48 +0,0 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { mock } from 'vitest-mock-extended';
|
||||
import { BrowseMediaCamera } from '../../../src/camera-manager/browse-media/camera';
|
||||
import { CameraManagerEngine } from '../../../src/camera-manager/engine';
|
||||
import { StateWatcherSubscriptionInterface } from '../../../src/card-controller/hass/state-watcher';
|
||||
import { Entity, EntityRegistryManager } from '../../../src/ha/registry/entity/types';
|
||||
import { createCameraConfig, createHASS } from '../../test-utils';
|
||||
|
||||
describe('BrowseMediaCamera', () => {
|
||||
describe('should initialize', () => {
|
||||
it('without a camera_entity', async () => {
|
||||
const camera = new BrowseMediaCamera(
|
||||
createCameraConfig(),
|
||||
mock<CameraManagerEngine>(),
|
||||
);
|
||||
|
||||
expect(
|
||||
async () =>
|
||||
await camera.initialize({
|
||||
hass: createHASS(),
|
||||
stateWatcher: mock<StateWatcherSubscriptionInterface>(),
|
||||
entityRegistryManager: mock<EntityRegistryManager>(),
|
||||
}),
|
||||
).rejects.toThrowError(/Could not find camera entity/);
|
||||
});
|
||||
|
||||
it('with a camera_entity', async () => {
|
||||
const camera = new BrowseMediaCamera(
|
||||
createCameraConfig({
|
||||
camera_entity: 'camera.foo',
|
||||
}),
|
||||
mock<CameraManagerEngine>(),
|
||||
);
|
||||
const entityRegistryManager = mock<EntityRegistryManager>();
|
||||
const entity = mock<Entity>();
|
||||
entityRegistryManager.getEntity.mockResolvedValue(entity);
|
||||
|
||||
expect(
|
||||
await camera.initialize({
|
||||
hass: createHASS(),
|
||||
stateWatcher: mock<StateWatcherSubscriptionInterface>(),
|
||||
entityRegistryManager: entityRegistryManager,
|
||||
}),
|
||||
).toBe(camera);
|
||||
expect(camera.getEntity()).toBe(entity);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user