diff --git a/homeassistant/components/bosch_shc/strings.json b/homeassistant/components/bosch_shc/strings.json index 89b89e04e6bb..624ed18b5375 100644 --- a/homeassistant/components/bosch_shc/strings.json +++ b/homeassistant/components/bosch_shc/strings.json @@ -135,6 +135,9 @@ "bypass_infinite": { "name": "Break function never expires" }, + "camera_ambientlight": { + "name": "Ambient light" + }, "camera_light": { "name": "Camera light" }, diff --git a/homeassistant/components/bosch_shc/switch.py b/homeassistant/components/bosch_shc/switch.py index 7d2ec51365a8..e3369796489c 100644 --- a/homeassistant/components/bosch_shc/switch.py +++ b/homeassistant/components/bosch_shc/switch.py @@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Any, override from boschshcpy import ( BypassService, + CameraAmbientLightService, CameraLightService, PowerSwitchService, PrivacyModeService, @@ -93,6 +94,15 @@ SWITCH_TYPES: dict[str, SHCSwitchEntityDescription] = { on_value=PrivacyModeService.State.DISABLED, should_poll=True, ), + "cameraoutdoorgen2_cameraambientlight": SHCSwitchEntityDescription( + key="cameraoutdoorgen2_cameraambientlight", + translation_key="camera_ambientlight", + device_class=SwitchDeviceClass.SWITCH, + entity_category=EntityCategory.CONFIG, + on_key="cameraambientlight", + on_value=CameraAmbientLightService.State.ON, + should_poll=True, + ), "child_lock": SHCSwitchEntityDescription( key="child_lock", translation_key="child_lock", @@ -327,6 +337,18 @@ async def async_setup_entry( for switch in session.device_helper.camera_outdoor_gen2 ) + entities.extend( + SHCSwitch( + hass=hass, + device=switch, + parent_id=shc_info.unique_id, + entry_id=config_entry.entry_id, + description=SWITCH_TYPES["cameraoutdoorgen2_cameraambientlight"], + unique_id_suffix="cameraoutdoorgen2_cameraambientlight", + ) + for switch in session.device_helper.camera_outdoor_gen2 + ) + entities.extend( SHCSwitch( hass=hass, diff --git a/tests/components/bosch_shc/conftest.py b/tests/components/bosch_shc/conftest.py index 7e70e1d1a75c..e4086a1e3fa8 100644 --- a/tests/components/bosch_shc/conftest.py +++ b/tests/components/bosch_shc/conftest.py @@ -9,6 +9,7 @@ from boschshcpy import ( AlarmService, BatteryLevelService, BypassService, + CameraAmbientLightService, CameraLightService, PowerSwitchService, PrivacyModeService, @@ -195,6 +196,7 @@ def camera_outdoor_gen2_device( device_id: str = "hdm:Cameras:outdoorgen2-1", name: str = "Outdoor Camera", privacymode: PrivacyModeService.State = PrivacyModeService.State.ENABLED, + cameraambientlight: CameraAmbientLightService.State = CameraAmbientLightService.State.OFF, ) -> SHCCameraOutdoorGen2: """Build a minimal device double for the camera_outdoor_gen2 bucket.""" device = create_autospec(SHCCameraOutdoorGen2, instance=True, spec_set=True) @@ -208,6 +210,7 @@ def camera_outdoor_gen2_device( device.deleted = False device.status = "AVAILABLE" device.privacymode = privacymode + device.cameraambientlight = cameraambientlight return device diff --git a/tests/components/bosch_shc/test_switch.py b/tests/components/bosch_shc/test_switch.py index 6493b83ca230..89dba388853a 100644 --- a/tests/components/bosch_shc/test_switch.py +++ b/tests/components/bosch_shc/test_switch.py @@ -5,6 +5,7 @@ from unittest.mock import MagicMock, patch from boschshcpy import ( BypassService, + CameraAmbientLightService, CameraLightService, PrivacyModeService, SilentModeService, @@ -1087,3 +1088,47 @@ async def test_camera_outdoor_gen2_privacy_mode( blocking=True, ) assert device.privacymode is False + + +@pytest.mark.parametrize( + "device_buckets", + [ + { + "camera_outdoor_gen2": [ + camera_outdoor_gen2_device( + cameraambientlight=CameraAmbientLightService.State.OFF + ) + ] + } + ], + indirect=True, +) +@pytest.mark.usefixtures("mock_session") +async def test_camera_outdoor_gen2_ambient_light( + hass: HomeAssistant, + mock_session: MagicMock, + mock_config_entry: MockConfigEntry, +) -> None: + """An Outdoor Camera Gen2's ambient light is exposed and controllable as a switch.""" + await setup_integration(hass, mock_config_entry) + device = mock_session.device_helper.camera_outdoor_gen2[0] + + state = hass.states.get("switch.outdoor_camera_ambient_light") + assert state is not None + assert state.state == "off" + + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "switch.outdoor_camera_ambient_light"}, + blocking=True, + ) + assert device.cameraambientlight is True + + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "switch.outdoor_camera_ambient_light"}, + blocking=True, + ) + assert device.cameraambientlight is False