mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +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"
|
"unidirectional_incoming": "Unidirectional incoming"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"switch": {
|
||||||
|
"automation": {
|
||||||
|
"state": {
|
||||||
|
"on": "[%key:common::state::enabled%",
|
||||||
|
"off": "[%key:common::state::disabled%"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
from typing import Any, TypeAlias
|
from typing import Any, TypeAlias
|
||||||
|
|
||||||
from aiohue.v2 import HueBridgeV2
|
from aiohue.v2 import HueBridgeV2
|
||||||
|
from aiohue.v2.controllers.config import BehaviorInstance, BehaviorInstanceController
|
||||||
from aiohue.v2.controllers.events import EventType
|
from aiohue.v2.controllers.events import EventType
|
||||||
from aiohue.v2.controllers.sensors import (
|
from aiohue.v2.controllers.sensors import (
|
||||||
LightLevel,
|
LightLevel,
|
||||||
@ -12,7 +13,11 @@ from aiohue.v2.controllers.sensors import (
|
|||||||
MotionController,
|
MotionController,
|
||||||
)
|
)
|
||||||
|
|
||||||
from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity
|
from homeassistant.components.switch import (
|
||||||
|
SwitchDeviceClass,
|
||||||
|
SwitchEntity,
|
||||||
|
SwitchEntityDescription,
|
||||||
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import EntityCategory
|
from homeassistant.const import EntityCategory
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
@ -22,7 +27,9 @@ from .bridge import HueBridge
|
|||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .v2.entity import HueBaseEntity
|
from .v2.entity import HueBaseEntity
|
||||||
|
|
||||||
ControllerType: TypeAlias = LightLevelController | MotionController
|
ControllerType: TypeAlias = (
|
||||||
|
BehaviorInstanceController | LightLevelController | MotionController
|
||||||
|
)
|
||||||
|
|
||||||
SensingService: TypeAlias = LightLevel | Motion
|
SensingService: TypeAlias = LightLevel | Motion
|
||||||
|
|
||||||
@ -43,11 +50,18 @@ async def async_setup_entry(
|
|||||||
@callback
|
@callback
|
||||||
def register_items(controller: ControllerType):
|
def register_items(controller: ControllerType):
|
||||||
@callback
|
@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."""
|
"""Add entity from Hue resource."""
|
||||||
async_add_entities(
|
if isinstance(resource, BehaviorInstance):
|
||||||
[HueSensingServiceEnabledEntity(bridge, controller, resource)]
|
async_add_entities(
|
||||||
)
|
[HueBehaviorInstanceEnabledEntity(bridge, controller, resource)]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
async_add_entities(
|
||||||
|
[HueSensingServiceEnabledEntity(bridge, controller, resource)]
|
||||||
|
)
|
||||||
|
|
||||||
# add all current items in controller
|
# add all current items in controller
|
||||||
for item in controller:
|
for item in controller:
|
||||||
@ -63,24 +77,13 @@ async def async_setup_entry(
|
|||||||
# setup for each switch-type hue resource
|
# setup for each switch-type hue resource
|
||||||
register_items(api.sensors.motion)
|
register_items(api.sensors.motion)
|
||||||
register_items(api.sensors.light_level)
|
register_items(api.sensors.light_level)
|
||||||
|
register_items(api.config.behavior_instance)
|
||||||
|
|
||||||
|
|
||||||
class HueSensingServiceEnabledEntity(HueBaseEntity, SwitchEntity):
|
class HueResourceEnabledEntity(HueBaseEntity, SwitchEntity):
|
||||||
"""Representation of a Switch entity from Hue SensingService."""
|
"""Representation of a Switch entity from a Hue resource that can be toggled enabled."""
|
||||||
|
|
||||||
_attr_entity_category = EntityCategory.CONFIG
|
controller: BehaviorInstanceController | LightLevelController | MotionController
|
||||||
_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
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self) -> bool:
|
def is_on(self) -> bool:
|
||||||
@ -98,3 +101,32 @@ class HueSensingServiceEnabledEntity(HueBaseEntity, SwitchEntity):
|
|||||||
await self.bridge.async_request_call(
|
await self.bridge.async_request_call(
|
||||||
self.controller.set_enabled, self.resource.id, enabled=False
|
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"
|
"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": {
|
"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": [
|
"where": [
|
||||||
{
|
{
|
||||||
"group": {
|
"group": {
|
||||||
"rid": "c14cf1cf-6c7a-4984-b8bb-c5b71aeb70fc",
|
"rid": "5e799732-e82e-46ab-b5d9-52b701bd7cbc",
|
||||||
"rtype": "entertainment_configuration"
|
"rtype": "room"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependees": [
|
"dependees": [
|
||||||
{
|
{
|
||||||
"level": "critical",
|
|
||||||
"target": {
|
"target": {
|
||||||
"rid": "c14cf1cf-6c7a-4984-b8bb-c5b71aeb70fc",
|
"rid": "5e799732-e82e-46ab-b5d9-52b701bd7cbc",
|
||||||
"rtype": "entertainment_configuration"
|
"rtype": "room"
|
||||||
},
|
},
|
||||||
|
"level": "critical",
|
||||||
"type": "ResourceDependee"
|
"type": "ResourceDependee"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"enabled": true,
|
"status": "running",
|
||||||
"id": "0670cfb1-2bd7-4237-a0e3-1827a44d7231",
|
|
||||||
"last_error": "",
|
"last_error": "",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "state_after_streaming"
|
"name": "Timer Test"
|
||||||
},
|
}
|
||||||
"migrated_from": "/resourcelinks/47450",
|
|
||||||
"script_id": "7719b841-6b3d-448d-a0e7-601ae9edb6a2",
|
|
||||||
"status": "running",
|
|
||||||
"type": "behavior_instance"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"configuration_schema": {
|
"configuration_schema": {
|
||||||
|
@ -14,8 +14,8 @@ async def test_switch(
|
|||||||
await setup_platform(hass, mock_bridge_v2, "switch")
|
await setup_platform(hass, mock_bridge_v2, "switch")
|
||||||
# there shouldn't have been any requests at this point
|
# there shouldn't have been any requests at this point
|
||||||
assert len(mock_bridge_v2.mock_requests) == 0
|
assert len(mock_bridge_v2.mock_requests) == 0
|
||||||
# 3 entities should be created from test data
|
# 4 entities should be created from test data
|
||||||
assert len(hass.states.async_all()) == 3
|
assert len(hass.states.async_all()) == 4
|
||||||
|
|
||||||
# test config switch to enable/disable motion sensor
|
# test config switch to enable/disable motion sensor
|
||||||
test_entity = hass.states.get("switch.hue_motion_sensor_motion")
|
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.state == "on"
|
||||||
assert test_entity.attributes["device_class"] == "switch"
|
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(
|
async def test_switch_turn_on_service(
|
||||||
hass: HomeAssistant, mock_bridge_v2, v2_resources_test_data
|
hass: HomeAssistant, mock_bridge_v2, v2_resources_test_data
|
||||||
|
Loading…
x
Reference in New Issue
Block a user