bosch_shc: add Motion Detector 2 pet immunity switch entity (#182924)

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Thomas
2026-09-22 19:13:13 +02:00
committed by GitHub
co-authored by Claude Sonnet 5
parent ea00804703
commit b5ab1d7740
4 changed files with 83 additions and 0 deletions
@@ -101,6 +101,9 @@
"child_lock": {
"name": "Child lock"
},
"pet_immunity_enabled": {
"name": "Pet immunity"
},
"routing": {
"name": "Range extension"
}
@@ -108,6 +108,15 @@ SWITCH_TYPES: dict[str, SHCSwitchEntityDescription] = {
on_value=BypassService.State.BYPASS_ACTIVE,
should_poll=False,
),
"pet_immunity_enabled": SHCSwitchEntityDescription(
key="pet_immunity_enabled",
translation_key="pet_immunity_enabled",
device_class=SwitchDeviceClass.SWITCH,
entity_category=EntityCategory.CONFIG,
on_key="pet_immunity_enabled",
on_value=True,
should_poll=False,
),
}
@@ -257,6 +266,18 @@ async def async_setup_entry(
for switch in session.device_helper.shutter_contacts2
)
entities.extend(
SHCSwitch(
hass=hass,
device=switch,
parent_id=shc_info.unique_id,
entry_id=config_entry.entry_id,
description=SWITCH_TYPES["pet_immunity_enabled"],
unique_id_suffix="pet_immunity",
)
for switch in session.device_helper.motion_detectors2
)
async_add_entities(entities)
+22
View File
@@ -14,6 +14,7 @@ from boschshcpy import (
SHCLightSwitchBSM,
SHCMicromoduleBlinds,
SHCMicromoduleRelay,
SHCMotionDetector2,
SHCPresenceSimulationSystem,
SHCShutterContact2,
SHCShutterControl,
@@ -73,6 +74,7 @@ _EMPTY_DEVICE_BUCKETS: dict[str, Any] = {
"micromodule_relays",
"micromodule_shutter_controls",
"motion_detectors",
"motion_detectors2",
"roomthermostats",
"shutter_contacts",
"shutter_contacts2",
@@ -332,3 +334,23 @@ def shutter_contact2_device(
device.bypass = bypass
device.bypass_infinite = bypass_infinite
return device
def motion_detector2_device(
device_id: str = "hdm:ZigBee:motiondetector1",
name: str = "Motion Detector",
pet_immunity_enabled: bool = False,
) -> SHCMotionDetector2:
"""Build a minimal device double for the motion_detectors2 bucket."""
device = create_autospec(SHCMotionDetector2, 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 = "MD2"
device.device_services = []
device.deleted = False
device.status = "AVAILABLE"
device.pet_immunity_enabled = pet_immunity_enabled
return device
+37
View File
@@ -19,6 +19,7 @@ from homeassistant.helpers import entity_registry as er
from .conftest import (
light_switch_bsm_device,
micromodule_relay_device,
motion_detector2_device,
presence_simulation_system_device,
setup_integration,
shutter_contact2_device,
@@ -317,3 +318,39 @@ async def test_shutter_contact2_bypass_unique_id(
assert bypass_entry is not None
assert bypass_infinite_entry is not None
assert bypass_entry.unique_id != bypass_infinite_entry.unique_id
@pytest.mark.parametrize(
"device_buckets",
[{"motion_detectors2": [motion_detector2_device(pet_immunity_enabled=False)]}],
indirect=True,
)
@pytest.mark.usefixtures("mock_session")
async def test_motion_detector2_pet_immunity(
hass: HomeAssistant,
mock_session: MagicMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""A Motion Detector 2's pet immunity setting is exposed and controllable."""
await setup_integration(hass, mock_config_entry)
device = mock_session.device_helper.motion_detectors2[0]
state = hass.states.get("switch.motion_detector_pet_immunity")
assert state is not None
assert state.state == "off"
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "switch.motion_detector_pet_immunity"},
blocking=True,
)
assert device.pet_immunity_enabled is True
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "switch.motion_detector_pet_immunity"},
blocking=True,
)
assert device.pet_immunity_enabled is False