bosch_shc: add Camera 360 notifications switch (#183750)

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Thomas
2026-10-04 09:06:25 +02:00
committed by GitHub
co-authored by Claude Sonnet 5.5
parent 739065d17d
commit 6a686b9105
4 changed files with 95 additions and 0 deletions
@@ -144,6 +144,9 @@
"camera_light": {
"name": "Camera light"
},
"camera_notification": {
"name": "Notifications"
},
"child_lock": {
"name": "Child lock"
},
@@ -9,6 +9,7 @@ from boschshcpy import (
CameraAmbientLightService,
CameraFrontLightService,
CameraLightService,
CameraNotificationService,
PowerSwitchService,
PrivacyModeService,
SHCShutterContact2,
@@ -88,6 +89,15 @@ SWITCH_TYPES: dict[str, SHCSwitchEntityDescription] = {
on_value=PrivacyModeService.State.DISABLED,
should_poll=True,
),
"camera360_notification": SHCSwitchEntityDescription(
key="camera360_notification",
translation_key="camera_notification",
device_class=SwitchDeviceClass.SWITCH,
entity_category=EntityCategory.CONFIG,
on_key="cameranotification",
on_value=CameraNotificationService.State.ENABLED,
should_poll=True,
),
"cameraoutdoorgen2": SHCSwitchEntityDescription(
key="cameraoutdoorgen2",
device_class=SwitchDeviceClass.SWITCH,
@@ -336,6 +346,18 @@ async def async_setup_entry(
for switch in session.device_helper.camera_360
)
entities.extend(
SHCSwitch(
hass=hass,
device=switch,
parent_id=shc_info.unique_id,
entry_id=config_entry.entry_id,
description=SWITCH_TYPES["camera360_notification"],
unique_id_suffix="camera360_notification",
)
for switch in session.device_helper.camera_360
)
entities.extend(
SHCSwitch(
hass=hass,
+24
View File
@@ -12,10 +12,12 @@ from boschshcpy import (
CameraAmbientLightService,
CameraFrontLightService,
CameraLightService,
CameraNotificationService,
PowerSwitchService,
PrivacyModeService,
RoutingService,
SHCBatteryDevice,
SHCCamera360,
SHCCameraEyes,
SHCCameraOutdoorGen2,
SHCLightSwitchBSM,
@@ -193,6 +195,28 @@ def camera_eyes_device(
return device
def camera_360_device(
device_id: str = "hdm:Cameras:360-1",
name: str = "Camera 360",
privacymode: PrivacyModeService.State = PrivacyModeService.State.ENABLED,
cameranotification: CameraNotificationService.State = CameraNotificationService.State.DISABLED,
) -> SHCCamera360:
"""Build a minimal device double for the camera_360 bucket."""
device = create_autospec(SHCCamera360, instance=True, spec_set=True)
device.name = name
device.id = device_id
device.root_device_id = "test-mac"
device.serial = f"serial-{device_id}"
device.manufacturer = "Bosch"
device.device_model = "CAMERA_360"
device.device_services = []
device.deleted = False
device.status = "AVAILABLE"
device.privacymode = privacymode
device.cameranotification = cameranotification
return device
def camera_outdoor_gen2_device(
device_id: str = "hdm:Cameras:outdoorgen2-1",
name: str = "Outdoor Camera",
+46
View File
@@ -8,6 +8,7 @@ from boschshcpy import (
CameraAmbientLightService,
CameraFrontLightService,
CameraLightService,
CameraNotificationService,
PrivacyModeService,
SilentModeService,
ThermostatService,
@@ -25,6 +26,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from .conftest import (
camera_360_device,
camera_eyes_device,
camera_outdoor_gen2_device,
light_switch_bsm_device,
@@ -1049,6 +1051,50 @@ async def test_camera_eyes_cameralight(
assert device.cameralight is False
@pytest.mark.parametrize(
"device_buckets",
[
{
"camera_360": [
camera_360_device(
cameranotification=CameraNotificationService.State.ENABLED
)
]
}
],
indirect=True,
)
@pytest.mark.usefixtures("mock_session")
async def test_camera_360_notification(
hass: HomeAssistant,
mock_session: MagicMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""A Camera 360's notifications are exposed and controllable as a switch."""
await setup_integration(hass, mock_config_entry)
device = mock_session.device_helper.camera_360[0]
state = hass.states.get("switch.camera_360_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_360_notifications"},
blocking=True,
)
assert device.cameranotification is False
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "switch.camera_360_notifications"},
blocking=True,
)
assert device.cameranotification is True
@pytest.mark.parametrize(
"device_buckets",
[