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:
Dermot Duffy
2025-12-07 16:57:33 -08:00
committed by GitHub
parent 3279481b0e
commit 596a37903f
20 changed files with 917 additions and 88 deletions
+17
View File
@@ -10,6 +10,7 @@ A "Camera Engine" defines what "type" of camera is being configured (e.g. `friga
| `generic` | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: |
| `motioneye` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :heavy_multiplication_x: | :white_check_mark: | :heavy_multiplication_x: | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :white_check_mark: | :white_check_mark: |
| `reolink` | :white_check_mark: | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: | :white_check_mark: | :eight_spoked_asterisk: | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :white_check_mark: | :heavy_multiplication_x: |
| `tplink` | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :eight_spoked_asterisk: | :white_check_mark: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: | :heavy_multiplication_x: |
### Live providers supported per Engine
@@ -19,6 +20,7 @@ A "Camera Engine" defines what "type" of camera is being configured (e.g. `friga
| `generic` | :white_check_mark: | :white_check_mark: | :heavy_multiplication_x: | :white_check_mark: | :white_check_mark: |
| `motioneye` | :white_check_mark: | :white_check_mark: | :heavy_multiplication_x: | :white_check_mark: | :heavy_multiplication_x: |
| `reolink` | :white_check_mark: | :white_check_mark: | :heavy_multiplication_x: | :white_check_mark: | :heavy_multiplication_x: |
| `tplink` | :white_check_mark: | :white_check_mark: | :heavy_multiplication_x: | :white_check_mark: | :white_check_mark: |
See [Live Provider Configuration](live-provider.md) for more details on live providers.
@@ -112,6 +114,21 @@ Zero-configuration PTZ support is available for Reolink if your camera supports
> [!IMPORTANT]
> For Home Assistant control of Reolink camera PTZ functions, the relevent `button` entities must be enabled. To verify, navigate to `Settings -> Devices & services -> Reolink -> [Choose Device]`, and ensure the `PTZ` entities are enabled. Disabled entities are shown under the `+X disabled entities` label.
## `tplink`
[](../common/experimental-warning.md ':include')
The `tplink` engine provides support for TPLink/Tapo cameras.
```yaml
cameras:
- camera_entity: camera.tapo_xxx_live_view
```
### PTZ Support
Zero-configuration PTZ support is available for TPLink/Tapo cameras that have pan/tilt capabilities.
## Fully expanded reference
[](../common/expanded-warning.md ':include')
+5
View File
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="256" height="256">
<path d="M0 0 C26.14434533 -0.72288512 49.9600937 7.64611281 69.38671875 25.3125 C88.2717809 43.40139596 96.55079638 68.42490419 97.265625 94.09375 C96.94352486 121.47226222 86.49734687 145.15852541 67.640625 164.84375 C48.24601431 183.64464812 23.75721126 190.61232158 -2.734375 190.28125 C-7.436875 190.24 -12.139375 190.19875 -16.984375 190.15625 C-16.984375 172.33625 -16.984375 154.51625 -16.984375 136.15625 C-9.394375 135.82625 -1.804375 135.49625 6.015625 135.15625 C18.02265058 133.29309086 26.95933822 129.60855193 34.515625 119.78125 C41.36238612 109.58811688 43.30819935 98.25170438 41.58984375 86.16015625 C39.51844005 76.38770565 35.29278822 68.22349741 27.203125 62.15625 C16.80968654 55.65840316 4.80544663 54.2307569 -7.140625 56.84765625 C-18.33687784 60.60594899 -26.67094881 67.09315849 -32.26953125 77.55859375 C-35.05540172 83.55969825 -36.08102174 88.92660162 -36.30078125 95.55078125 C-36.33888916 96.63464111 -36.37699707 97.71850098 -36.41625977 98.83520508 C-36.45936279 100.1992749 -36.50246582 101.56334473 -36.546875 102.96875 C-36.69125 107.320625 -36.835625 111.6725 -36.984375 116.15625 C-54.804375 116.15625 -72.624375 116.15625 -90.984375 116.15625 C-91.5861874 83.05656809 -88.43663153 54.43892655 -64.984375 29.15625 C-47.57427445 11.32086455 -24.75288588 1.29596261 0 0 Z " fill="#48C8D3" transform="translate(155.984375,0.84375)"/>
<path d="M0 0 C39.93 0 79.86 0 121 0 C121 39.93 121 79.86 121 121 C71 121 71 121 66 117 C63.85529247 113.85132353 63.7556918 111.25918777 63.77294922 107.49707031 C63.77310028 106.39623108 63.77325134 105.29539185 63.77340698 104.16119385 C63.78372955 102.97878113 63.79405212 101.79636841 63.8046875 100.578125 C63.8075174 99.36300232 63.81034729 98.14787964 63.81326294 96.89593506 C63.82446046 93.01385665 63.84956466 89.13200871 63.875 85.25 C63.88503034 82.61849291 63.89415609 79.98698221 63.90234375 77.35546875 C63.92439843 70.90356716 63.95787196 64.45180005 64 58 C63.04612648 58.00999275 63.04612648 58.00999275 62.07298279 58.02018738 C55.4379483 58.08669947 48.80300897 58.13186656 42.16772461 58.16479492 C39.6934016 58.1798556 37.21910518 58.20030825 34.74487305 58.22631836 C31.1827131 58.2628203 27.620907 58.27975404 24.05859375 58.29296875 C22.95728622 58.30845261 21.8559787 58.32393646 20.72129822 58.33988953 C14.69081959 58.34120274 10.28924103 57.9927906 5 55 C-8.49681274 40.79282869 0 18.01550479 0 0 Z " fill="#49C8D3" transform="translate(0,135)"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

+1
View File
@@ -11,3 +11,4 @@ builtin custom items not found in the traditional [Material Design Icons
| `iris` | ![Iris Icon](../images/icons/iris.svg ':size=24 :class=svg-icon') |
| `motioneye` | ![motionEye Icon](../images/icons/motioneye.svg ':size=24 :class=svg-icon') |
| `reolink` | ![Reolink Icon](../images/icons/reolink.svg ':size=24 :class=svg-icon') |
| `tplink` | ![TPLink Icon](../images/icons/tplink.svg ':size=24 :class=svg-icon') |