mirror of
https://github.com/home-assistant/core.git
synced 2026-08-06 05:14:06 +01:00
Fix Hue Mimic Presence automations switch (#177691)
This commit is contained in:
committed by
GitHub
parent
ab2c62ad06
commit
eb2d2e7ebe
@@ -12,6 +12,7 @@ from aiohue.v2.controllers.sensors import (
|
||||
Motion,
|
||||
MotionController,
|
||||
)
|
||||
from aiohue.v2.models.behavior_instance import PresenceMimickingState
|
||||
from aiohue.v2.models.behavior_script import BehaviorScriptCategory
|
||||
|
||||
from homeassistant.components.switch import (
|
||||
@@ -143,8 +144,13 @@ class HueResourceEnabledEntity(HueBaseEntity, SwitchEntity):
|
||||
|
||||
|
||||
class HueBehaviorInstanceEnabledEntity(HueResourceEnabledEntity):
|
||||
"""Representation of a Switch entity to enable/disable a Hue Behavior Instance."""
|
||||
"""Representation of a Switch entity to enable/disable a Hue Behavior Instance.
|
||||
|
||||
Automations that the Hue app runs with a play button, such as mimic
|
||||
presence, are started and stopped. All others are enabled and disabled.
|
||||
"""
|
||||
|
||||
controller: BehaviorInstanceController
|
||||
resource: BehaviorInstance
|
||||
|
||||
entity_description = SwitchEntityDescription(
|
||||
@@ -159,6 +165,30 @@ class HueBehaviorInstanceEnabledEntity(HueResourceEnabledEntity):
|
||||
"""Return name for this entity."""
|
||||
return f"Automation: {self.resource.metadata.name}"
|
||||
|
||||
@property
|
||||
@override
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if the switch is on."""
|
||||
if (run_state := self.resource.presence_mimicking_state) is not None:
|
||||
return run_state is PresenceMimickingState.STARTED
|
||||
return self.resource.enabled
|
||||
|
||||
@override
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the entity on."""
|
||||
if self.resource.presence_mimicking_state is None:
|
||||
await super().async_turn_on(**kwargs)
|
||||
return
|
||||
await self.bridge.async_request_call(self.controller.start, self.resource.id)
|
||||
|
||||
@override
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the entity off."""
|
||||
if self.resource.presence_mimicking_state is None:
|
||||
await super().async_turn_off(**kwargs)
|
||||
return
|
||||
await self.bridge.async_request_call(self.controller.stop, self.resource.id)
|
||||
|
||||
|
||||
class HueMotionSensorEnabledEntity(HueResourceEnabledEntity):
|
||||
"""Representation of a Switch entity to enable/disable a Hue motion sensor."""
|
||||
|
||||
@@ -162,3 +162,28 @@ FAKE_BEHAVIOR_INSTANCE = {
|
||||
"status": "running",
|
||||
"type": "behavior_instance",
|
||||
}
|
||||
|
||||
FAKE_PRESENCE_MIMICKING_SCRIPT = {
|
||||
"configuration_schema": {},
|
||||
"description": "PM Automation",
|
||||
"id": "fake_behavior_script_id_2",
|
||||
"metadata": {"category": "automation", "name": "PM"},
|
||||
"state_schema": {},
|
||||
"supported_features": [],
|
||||
"trigger_schema": {},
|
||||
"type": "behavior_script",
|
||||
"version": "0.0.1",
|
||||
}
|
||||
|
||||
FAKE_PRESENCE_MIMICKING_INSTANCE = {
|
||||
"configuration": {},
|
||||
"dependees": [], # codespell:ignore dependees
|
||||
"enabled": True,
|
||||
"id": "fake_behavior_instance_id_2",
|
||||
"last_error": "",
|
||||
"metadata": {"name": "Mimic presence"},
|
||||
"script_id": "fake_behavior_script_id_2",
|
||||
"state": {"pm_state": "stopped"},
|
||||
"status": "running",
|
||||
"type": "behavior_instance",
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ from .const import (
|
||||
FAKE_BEHAVIOR_SCRIPT,
|
||||
FAKE_BINARY_SENSOR,
|
||||
FAKE_DEVICE,
|
||||
FAKE_PRESENCE_MIMICKING_INSTANCE,
|
||||
FAKE_PRESENCE_MIMICKING_SCRIPT,
|
||||
FAKE_ZIGBEE_CONNECTIVITY,
|
||||
)
|
||||
|
||||
@@ -198,3 +200,79 @@ async def test_internal_behavior_instance_entity_removed(
|
||||
await setup_platform(hass, mock_bridge_v2, Platform.SWITCH)
|
||||
|
||||
assert entity_registry.async_get(stale_entity.entity_id) is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("pm_state", "expected_state"), [("started", "on"), ("stopped", "off")]
|
||||
)
|
||||
async def test_presence_mimicking_switch_state(
|
||||
hass: HomeAssistant,
|
||||
mock_bridge_v2: Mock,
|
||||
v2_resources_test_data: JsonArrayType,
|
||||
pm_state: str,
|
||||
expected_state: str,
|
||||
) -> None:
|
||||
"""Test the switch follows the run state instead of enabled."""
|
||||
instance = {**FAKE_PRESENCE_MIMICKING_INSTANCE, "state": {"pm_state": pm_state}}
|
||||
await mock_bridge_v2.api.load_test_data(
|
||||
[*v2_resources_test_data, FAKE_PRESENCE_MIMICKING_SCRIPT, instance]
|
||||
)
|
||||
|
||||
await setup_platform(hass, mock_bridge_v2, Platform.SWITCH)
|
||||
|
||||
test_entity = hass.states.get("switch.philips_hue_automation_mimic_presence")
|
||||
assert test_entity is not None
|
||||
assert test_entity.state == expected_state
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("service", "expected_trigger"),
|
||||
[("turn_on", {"start": {}}), ("turn_off", {"stop": {}})],
|
||||
)
|
||||
async def test_presence_mimicking_switch_services(
|
||||
hass: HomeAssistant,
|
||||
mock_bridge_v2: Mock,
|
||||
v2_resources_test_data: JsonArrayType,
|
||||
service: str,
|
||||
expected_trigger: dict,
|
||||
) -> None:
|
||||
"""Test the switch starts and stops instead of touching enabled."""
|
||||
await mock_bridge_v2.api.load_test_data(
|
||||
[
|
||||
*v2_resources_test_data,
|
||||
FAKE_PRESENCE_MIMICKING_SCRIPT,
|
||||
FAKE_PRESENCE_MIMICKING_INSTANCE,
|
||||
]
|
||||
)
|
||||
|
||||
await setup_platform(hass, mock_bridge_v2, Platform.SWITCH)
|
||||
|
||||
await hass.services.async_call(
|
||||
"switch",
|
||||
service,
|
||||
{"entity_id": "switch.philips_hue_automation_mimic_presence"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(mock_bridge_v2.mock_requests) == 1
|
||||
assert mock_bridge_v2.mock_requests[0]["method"] == "put"
|
||||
assert mock_bridge_v2.mock_requests[0]["json"] == {"trigger": expected_trigger}
|
||||
|
||||
|
||||
async def test_regular_automation_switch_uses_enabled(
|
||||
hass: HomeAssistant, mock_bridge_v2: Mock, v2_resources_test_data: JsonArrayType
|
||||
) -> None:
|
||||
"""Test an automation without a run state still toggles enabled."""
|
||||
await mock_bridge_v2.api.load_test_data(v2_resources_test_data)
|
||||
|
||||
await setup_platform(hass, mock_bridge_v2, Platform.SWITCH)
|
||||
|
||||
await hass.services.async_call(
|
||||
"switch",
|
||||
"turn_off",
|
||||
{"entity_id": "switch.philips_hue_automation_timer_test"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(mock_bridge_v2.mock_requests) == 1
|
||||
assert mock_bridge_v2.mock_requests[0]["json"] == {"enabled": False}
|
||||
|
||||
Reference in New Issue
Block a user