From 635942650d13cef941cc78d951457f68599be89b Mon Sep 17 00:00:00 2001 From: Thomas <10558666+mosandlt@users.noreply.github.com> Date: Sun, 4 Oct 2026 09:51:27 +0200 Subject: [PATCH] bosch_shc: add Camera Eyes notifications switch (#183735) Co-authored-by: Claude Sonnet 5.5 --- homeassistant/components/bosch_shc/switch.py | 21 +++++++++ tests/components/bosch_shc/conftest.py | 2 + tests/components/bosch_shc/test_switch.py | 46 +++++++++++++++++++- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/bosch_shc/switch.py b/homeassistant/components/bosch_shc/switch.py index bf953c1f2763..a11a6c5045f7 100644 --- a/homeassistant/components/bosch_shc/switch.py +++ b/homeassistant/components/bosch_shc/switch.py @@ -82,6 +82,15 @@ SWITCH_TYPES: dict[str, SHCSwitchEntityDescription] = { on_value=CameraLightService.State.ON, should_poll=True, ), + "cameraeyes_notification": SHCSwitchEntityDescription( + key="cameraeyes_notification", + translation_key="camera_notification", + device_class=SwitchDeviceClass.SWITCH, + entity_category=EntityCategory.CONFIG, + on_key="cameranotification", + on_value=CameraNotificationService.State.ENABLED, + should_poll=True, + ), "camera360": SHCSwitchEntityDescription( key="camera360", device_class=SwitchDeviceClass.SWITCH, @@ -335,6 +344,18 @@ async def async_setup_entry( for switch in session.device_helper.camera_eyes ) + entities.extend( + SHCSwitch( + hass=hass, + device=switch, + parent_id=shc_info.unique_id, + entry_id=config_entry.entry_id, + description=SWITCH_TYPES["cameraeyes_notification"], + unique_id_suffix="cameraeyes_notification", + ) + for switch in session.device_helper.camera_eyes + ) + entities.extend( SHCSwitch( hass=hass, diff --git a/tests/components/bosch_shc/conftest.py b/tests/components/bosch_shc/conftest.py index 48ea139a5abe..636f515d652e 100644 --- a/tests/components/bosch_shc/conftest.py +++ b/tests/components/bosch_shc/conftest.py @@ -180,6 +180,7 @@ def camera_eyes_device( device_id: str = "hdm:Cameras:eyes-1", name: str = "Camera Eyes", cameralight: CameraLightService.State = CameraLightService.State.OFF, + cameranotification: CameraNotificationService.State = CameraNotificationService.State.DISABLED, ) -> SHCCameraEyes: """Build a minimal device double for the camera_eyes bucket.""" device = create_autospec(SHCCameraEyes, instance=True, spec_set=True) @@ -193,6 +194,7 @@ def camera_eyes_device( device.deleted = False device.status = "AVAILABLE" device.cameralight = cameralight + device.cameranotification = cameranotification return device diff --git a/tests/components/bosch_shc/test_switch.py b/tests/components/bosch_shc/test_switch.py index e8910b3dd2c9..f05a49ff4029 100644 --- a/tests/components/bosch_shc/test_switch.py +++ b/tests/components/bosch_shc/test_switch.py @@ -1070,7 +1070,7 @@ async def test_camera_360_notification( mock_session: MagicMock, mock_config_entry: MockConfigEntry, ) -> None: - """A Camera 360's notifications are exposed and controllable as a switch.""" + """A Camera 360' notifications are exposed and controllable as a switch.""" await setup_integration(hass, mock_config_entry) device = mock_session.device_helper.camera_360[0] @@ -1095,6 +1095,50 @@ async def test_camera_360_notification( assert device.cameranotification is True +@pytest.mark.parametrize( + "device_buckets", + [ + { + "camera_eyes": [ + camera_eyes_device( + cameranotification=CameraNotificationService.State.ENABLED + ) + ] + } + ], + indirect=True, +) +@pytest.mark.usefixtures("mock_session") +async def test_camera_eyes_notification( + hass: HomeAssistant, + mock_session: MagicMock, + mock_config_entry: MockConfigEntry, +) -> None: + """A Camera Eyes' notifications are exposed and controllable as a switch.""" + await setup_integration(hass, mock_config_entry) + device = mock_session.device_helper.camera_eyes[0] + + state = hass.states.get("switch.camera_eyes_notifications") + assert state is not None + assert state.state == "on" + + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "switch.camera_eyes_notifications"}, + blocking=True, + ) + assert device.cameranotification is False + + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "switch.camera_eyes_notifications"}, + blocking=True, + ) + assert device.cameranotification is True + + @pytest.mark.parametrize( "device_buckets", [