mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
Discover switch entities from Hue behavior_script instances (#101262)
This commit is contained in:
parent
054407722d
commit
35616e100d
@ -104,6 +104,14 @@
|
||||
"unidirectional_incoming": "Unidirectional incoming"
|
||||
}
|
||||
}
|
||||
},
|
||||
"switch": {
|
||||
"automation": {
|
||||
"state": {
|
||||
"on": "[%key:common::state::enabled%",
|
||||
"off": "[%key:common::state::disabled%"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
from typing import Any, TypeAlias
|
||||
|
||||
from aiohue.v2 import HueBridgeV2
|
||||
from aiohue.v2.controllers.config import BehaviorInstance, BehaviorInstanceController
|
||||
from aiohue.v2.controllers.events import EventType
|
||||
from aiohue.v2.controllers.sensors import (
|
||||
LightLevel,
|
||||
@ -12,7 +13,11 @@ from aiohue.v2.controllers.sensors import (
|
||||
MotionController,
|
||||
)
|
||||
|
||||
from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity
|
||||
from homeassistant.components.switch import (
|
||||
SwitchDeviceClass,
|
||||
SwitchEntity,
|
||||
SwitchEntityDescription,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
@ -22,7 +27,9 @@ from .bridge import HueBridge
|
||||
from .const import DOMAIN
|
||||
from .v2.entity import HueBaseEntity
|
||||
|
||||
ControllerType: TypeAlias = LightLevelController | MotionController
|
||||
ControllerType: TypeAlias = (
|
||||
BehaviorInstanceController | LightLevelController | MotionController
|
||||
)
|
||||
|
||||
SensingService: TypeAlias = LightLevel | Motion
|
||||
|
||||
@ -43,11 +50,18 @@ async def async_setup_entry(
|
||||
@callback
|
||||
def register_items(controller: ControllerType):
|
||||
@callback
|
||||
def async_add_entity(event_type: EventType, resource: SensingService) -> None:
|
||||
def async_add_entity(
|
||||
event_type: EventType, resource: SensingService | BehaviorInstance
|
||||
) -> None:
|
||||
"""Add entity from Hue resource."""
|
||||
async_add_entities(
|
||||
[HueSensingServiceEnabledEntity(bridge, controller, resource)]
|
||||
)
|
||||
if isinstance(resource, BehaviorInstance):
|
||||
async_add_entities(
|
||||
[HueBehaviorInstanceEnabledEntity(bridge, controller, resource)]
|
||||
)
|
||||
else:
|
||||
async_add_entities(
|
||||
[HueSensingServiceEnabledEntity(bridge, controller, resource)]
|
||||
)
|
||||
|
||||
# add all current items in controller
|
||||
for item in controller:
|
||||
@ -63,24 +77,13 @@ async def async_setup_entry(
|
||||
# setup for each switch-type hue resource
|
||||
register_items(api.sensors.motion)
|
||||
register_items(api.sensors.light_level)
|
||||
register_items(api.config.behavior_instance)
|
||||
|
||||
|
||||
class HueSensingServiceEnabledEntity(HueBaseEntity, SwitchEntity):
|
||||
"""Representation of a Switch entity from Hue SensingService."""
|
||||
class HueResourceEnabledEntity(HueBaseEntity, SwitchEntity):
|
||||
"""Representation of a Switch entity from a Hue resource that can be toggled enabled."""
|
||||
|
||||
_attr_entity_category = EntityCategory.CONFIG
|
||||
_attr_device_class = SwitchDeviceClass.SWITCH
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
bridge: HueBridge,
|
||||
controller: LightLevelController | MotionController,
|
||||
resource: SensingService,
|
||||
) -> None:
|
||||
"""Initialize the entity."""
|
||||
super().__init__(bridge, controller, resource)
|
||||
self.resource = resource
|
||||
self.controller = controller
|
||||
controller: BehaviorInstanceController | LightLevelController | MotionController
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
@ -98,3 +101,32 @@ class HueSensingServiceEnabledEntity(HueBaseEntity, SwitchEntity):
|
||||
await self.bridge.async_request_call(
|
||||
self.controller.set_enabled, self.resource.id, enabled=False
|
||||
)
|
||||
|
||||
|
||||
class HueSensingServiceEnabledEntity(HueResourceEnabledEntity):
|
||||
"""Representation of a Switch entity from Hue SensingService."""
|
||||
|
||||
entity_description = SwitchEntityDescription(
|
||||
key="behavior_instance",
|
||||
device_class=SwitchDeviceClass.SWITCH,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
)
|
||||
|
||||
|
||||
class HueBehaviorInstanceEnabledEntity(HueResourceEnabledEntity):
|
||||
"""Representation of a Switch entity to enable/disable a Hue Behavior Instance."""
|
||||
|
||||
resource: BehaviorInstance
|
||||
|
||||
entity_description = SwitchEntityDescription(
|
||||
key="behavior_instance",
|
||||
device_class=SwitchDeviceClass.SWITCH,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
has_entity_name=False,
|
||||
translation_key="automation",
|
||||
)
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
"""Return name for this entity."""
|
||||
return f"Automation: {self.resource.metadata.name}"
|
||||
|
@ -2050,37 +2050,53 @@
|
||||
"type": "temperature"
|
||||
},
|
||||
{
|
||||
"id": "9ad57767-e622-4f91-9086-2e5573bc781b",
|
||||
"type": "behavior_instance",
|
||||
"script_id": "e73bc72d-96b1-46f8-aa57-729861f80c78",
|
||||
"enabled": true,
|
||||
"state": {
|
||||
"timer_state": "stopped"
|
||||
},
|
||||
"configuration": {
|
||||
"end_state": "last_state",
|
||||
"duration": {
|
||||
"seconds": 60
|
||||
},
|
||||
"what": [
|
||||
{
|
||||
"group": {
|
||||
"rid": "5e799732-e82e-46ab-b5d9-52b701bd7cbc",
|
||||
"rtype": "room"
|
||||
},
|
||||
"recall": {
|
||||
"rid": "732ff1d9-76a7-4630-aad0-c8acc499bb0b",
|
||||
"rtype": "recipe"
|
||||
}
|
||||
}
|
||||
],
|
||||
"where": [
|
||||
{
|
||||
"group": {
|
||||
"rid": "c14cf1cf-6c7a-4984-b8bb-c5b71aeb70fc",
|
||||
"rtype": "entertainment_configuration"
|
||||
"rid": "5e799732-e82e-46ab-b5d9-52b701bd7cbc",
|
||||
"rtype": "room"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"dependees": [
|
||||
{
|
||||
"level": "critical",
|
||||
"target": {
|
||||
"rid": "c14cf1cf-6c7a-4984-b8bb-c5b71aeb70fc",
|
||||
"rtype": "entertainment_configuration"
|
||||
"rid": "5e799732-e82e-46ab-b5d9-52b701bd7cbc",
|
||||
"rtype": "room"
|
||||
},
|
||||
"level": "critical",
|
||||
"type": "ResourceDependee"
|
||||
}
|
||||
],
|
||||
"enabled": true,
|
||||
"id": "0670cfb1-2bd7-4237-a0e3-1827a44d7231",
|
||||
"status": "running",
|
||||
"last_error": "",
|
||||
"metadata": {
|
||||
"name": "state_after_streaming"
|
||||
},
|
||||
"migrated_from": "/resourcelinks/47450",
|
||||
"script_id": "7719b841-6b3d-448d-a0e7-601ae9edb6a2",
|
||||
"status": "running",
|
||||
"type": "behavior_instance"
|
||||
"name": "Timer Test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"configuration_schema": {
|
||||
|
@ -14,8 +14,8 @@ async def test_switch(
|
||||
await setup_platform(hass, mock_bridge_v2, "switch")
|
||||
# there shouldn't have been any requests at this point
|
||||
assert len(mock_bridge_v2.mock_requests) == 0
|
||||
# 3 entities should be created from test data
|
||||
assert len(hass.states.async_all()) == 3
|
||||
# 4 entities should be created from test data
|
||||
assert len(hass.states.async_all()) == 4
|
||||
|
||||
# test config switch to enable/disable motion sensor
|
||||
test_entity = hass.states.get("switch.hue_motion_sensor_motion")
|
||||
@ -24,6 +24,13 @@ async def test_switch(
|
||||
assert test_entity.state == "on"
|
||||
assert test_entity.attributes["device_class"] == "switch"
|
||||
|
||||
# test config switch to enable/disable a behavior_instance resource (=builtin automation)
|
||||
test_entity = hass.states.get("switch.automation_timer_test")
|
||||
assert test_entity is not None
|
||||
assert test_entity.name == "Automation: Timer Test"
|
||||
assert test_entity.state == "on"
|
||||
assert test_entity.attributes["device_class"] == "switch"
|
||||
|
||||
|
||||
async def test_switch_turn_on_service(
|
||||
hass: HomeAssistant, mock_bridge_v2, v2_resources_test_data
|
||||
|
Loading…
x
Reference in New Issue
Block a user