Skip to content

Commit 4f095b8

Browse files
authored
Implement camera toggle (#868)
* Add support for enabling / disabling camera * Add test * Include version * Formatting * Format tests
1 parent 6bf87a7 commit 4f095b8

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

custom_components/frigate/camera.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ def __init__(
217217
self._attr_motion_detection_enabled = self._camera_config.get("motion", {}).get(
218218
"enabled"
219219
)
220+
self._turn_on_off_topic = (
221+
f"{frigate_config['mqtt']['topic_prefix']}" f"/{self._cam_name}/enabled/set"
222+
)
220223
self._ptz_topic = (
221224
f"{frigate_config['mqtt']['topic_prefix']}" f"/{self._cam_name}/ptz"
222225
)
@@ -327,6 +330,28 @@ async def stream_source(self) -> str | None:
327330
"""Return the source of the stream."""
328331
return self._stream_source
329332

333+
async def async_turn_on(self) -> None:
334+
"""Turn on the camera."""
335+
if self._frigate_config.get("version", "0.14") >= "0.16":
336+
await async_publish(
337+
self.hass,
338+
self._turn_on_off_topic,
339+
"ON",
340+
0,
341+
False,
342+
)
343+
344+
async def async_turn_off(self) -> None:
345+
"""Turn off the camera."""
346+
if self._frigate_config.get("version", "0.14") >= "0.16":
347+
await async_publish(
348+
self.hass,
349+
self._turn_on_off_topic,
350+
"OFF",
351+
0,
352+
False,
353+
)
354+
330355
async def async_enable_motion_detection(self) -> None:
331356
"""Enable motion detection for this camera."""
332357
await async_publish(

tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
TEST_PASSWORD = "secret_password"
8080
TEST_FRIGATE_INSTANCE_ID = "frigate_client_id"
8181
TEST_CONFIG = {
82+
"version": "0.16-0",
8283
"cameras": {
8384
"front_door": {
8485
"best_image_timeout": 60,

tests/test_camera.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
DOMAIN as CAMERA_DOMAIN,
4040
SERVICE_DISABLE_MOTION,
4141
SERVICE_ENABLE_MOTION,
42+
SERVICE_TURN_OFF,
43+
SERVICE_TURN_ON,
4244
StreamType,
4345
async_get_image,
4446
async_get_stream_source,
@@ -446,6 +448,60 @@ async def test_camera_device_info(hass: HomeAssistant) -> None:
446448
assert TEST_CAMERA_FRONT_DOOR_ENTITY_ID in entities_from_device
447449

448450

451+
async def test_camera_enable_camera(hass: HomeAssistant, mqtt_mock: Any) -> None:
452+
"""Test built in camera toggle."""
453+
454+
await setup_mock_frigate_config_entry(hass)
455+
456+
entity_state = hass.states.get(TEST_CAMERA_FRONT_DOOR_ENTITY_ID)
457+
assert entity_state
458+
assert entity_state.state == "streaming"
459+
assert entity_state.attributes["supported_features"] == 2
460+
461+
async_fire_mqtt_message(hass, "frigate/front_door/enabled/state", "ON")
462+
await hass.async_block_till_done()
463+
464+
entity_state = hass.states.get(TEST_CAMERA_FRONT_DOOR_ENTITY_ID)
465+
assert entity_state
466+
467+
await hass.services.async_call(
468+
CAMERA_DOMAIN,
469+
SERVICE_TURN_ON,
470+
{ATTR_ENTITY_ID: TEST_CAMERA_FRONT_DOOR_ENTITY_ID},
471+
blocking=True,
472+
)
473+
mqtt_mock.async_publish.assert_called_once_with(
474+
"frigate/front_door/enabled/set", "ON", 0, False
475+
)
476+
477+
478+
async def test_camera_disable_camera(hass: HomeAssistant, mqtt_mock: Any) -> None:
479+
"""Test built in camera toggle."""
480+
481+
await setup_mock_frigate_config_entry(hass)
482+
483+
entity_state = hass.states.get(TEST_CAMERA_FRONT_DOOR_ENTITY_ID)
484+
assert entity_state
485+
assert entity_state.state == "streaming"
486+
assert entity_state.attributes["supported_features"] == 2
487+
488+
async_fire_mqtt_message(hass, "frigate/front_door/enabled/state", "OFF")
489+
await hass.async_block_till_done()
490+
491+
entity_state = hass.states.get(TEST_CAMERA_FRONT_DOOR_ENTITY_ID)
492+
assert entity_state
493+
494+
await hass.services.async_call(
495+
CAMERA_DOMAIN,
496+
SERVICE_TURN_OFF,
497+
{ATTR_ENTITY_ID: TEST_CAMERA_FRONT_DOOR_ENTITY_ID},
498+
blocking=True,
499+
)
500+
mqtt_mock.async_publish.assert_called_once_with(
501+
"frigate/front_door/enabled/set", "OFF", 0, False
502+
)
503+
504+
449505
async def test_camera_enable_motion_detection(
450506
hass: HomeAssistant, mqtt_mock: Any
451507
) -> None:

0 commit comments

Comments
 (0)