Add changed states device trigger to media_player entity (#64304)
parent
513d6cc467
commit
ff9bea9fa9
|
@ -9,7 +9,10 @@ from homeassistant.components.automation import (
|
|||
AutomationActionType,
|
||||
AutomationTriggerInfo,
|
||||
)
|
||||
from homeassistant.components.device_automation import DEVICE_TRIGGER_BASE_SCHEMA
|
||||
from homeassistant.components.device_automation import (
|
||||
DEVICE_TRIGGER_BASE_SCHEMA,
|
||||
entity,
|
||||
)
|
||||
from homeassistant.components.homeassistant.triggers import state as state_trigger
|
||||
from homeassistant.const import (
|
||||
CONF_DEVICE_ID,
|
||||
|
@ -32,7 +35,7 @@ from .const import DOMAIN
|
|||
|
||||
TRIGGER_TYPES = {"turned_on", "turned_off", "idle", "paused", "playing"}
|
||||
|
||||
TRIGGER_SCHEMA = DEVICE_TRIGGER_BASE_SCHEMA.extend(
|
||||
MEDIA_PLAYER_TRIGGER_SCHEMA = DEVICE_TRIGGER_BASE_SCHEMA.extend(
|
||||
{
|
||||
vol.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||
vol.Required(CONF_TYPE): vol.In(TRIGGER_TYPES),
|
||||
|
@ -40,13 +43,21 @@ TRIGGER_SCHEMA = DEVICE_TRIGGER_BASE_SCHEMA.extend(
|
|||
}
|
||||
)
|
||||
|
||||
TRIGGER_SCHEMA = vol.All(
|
||||
vol.Any(
|
||||
MEDIA_PLAYER_TRIGGER_SCHEMA,
|
||||
entity.TRIGGER_SCHEMA,
|
||||
),
|
||||
vol.Schema({vol.Required(CONF_DOMAIN): DOMAIN}, extra=vol.ALLOW_EXTRA),
|
||||
)
|
||||
|
||||
|
||||
async def async_get_triggers(
|
||||
hass: HomeAssistant, device_id: str
|
||||
) -> list[dict[str, Any]]:
|
||||
"""List device triggers for Media player entities."""
|
||||
registry = await entity_registry.async_get_registry(hass)
|
||||
triggers = []
|
||||
triggers = await entity.async_get_triggers(hass, device_id, DOMAIN)
|
||||
|
||||
# Get all the integration entities for this device
|
||||
for entry in entity_registry.async_entries_for_device(registry, device_id):
|
||||
|
@ -72,6 +83,8 @@ async def async_get_trigger_capabilities(
|
|||
hass: HomeAssistant, config: ConfigType
|
||||
) -> dict[str, vol.Schema]:
|
||||
"""List trigger capabilities."""
|
||||
if config[CONF_TYPE] not in TRIGGER_TYPES:
|
||||
return await entity.async_get_trigger_capabilities(hass, config)
|
||||
return {
|
||||
"extra_fields": vol.Schema(
|
||||
{vol.Optional(CONF_FOR): cv.positive_time_period_dict}
|
||||
|
@ -86,6 +99,8 @@ async def async_attach_trigger(
|
|||
automation_info: AutomationTriggerInfo,
|
||||
) -> CALLBACK_TYPE:
|
||||
"""Attach a trigger."""
|
||||
if config[CONF_TYPE] not in TRIGGER_TYPES:
|
||||
return await entity.async_attach_trigger(hass, config, action, automation_info)
|
||||
if config[CONF_TYPE] == "turned_on":
|
||||
to_state = STATE_ON
|
||||
elif config[CONF_TYPE] == "turned_off":
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
"turned_off": "{entity_name} turned off",
|
||||
"idle": "{entity_name} becomes idle",
|
||||
"paused": "{entity_name} is paused",
|
||||
"playing": "{entity_name} starts playing"
|
||||
"playing": "{entity_name} starts playing",
|
||||
"changed_states": "{entity_name} changed states"
|
||||
}
|
||||
},
|
||||
"state": {
|
||||
|
|
|
@ -58,7 +58,14 @@ async def test_get_triggers(hass, device_reg, entity_reg):
|
|||
)
|
||||
entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id)
|
||||
|
||||
trigger_types = {"turned_on", "turned_off", "idle", "paused", "playing"}
|
||||
trigger_types = {
|
||||
"turned_on",
|
||||
"turned_off",
|
||||
"idle",
|
||||
"paused",
|
||||
"playing",
|
||||
"changed_states",
|
||||
}
|
||||
expected_triggers = [
|
||||
{
|
||||
"platform": "device",
|
||||
|
@ -88,7 +95,7 @@ async def test_get_trigger_capabilities(hass, device_reg, entity_reg):
|
|||
triggers = await async_get_device_automations(
|
||||
hass, DeviceAutomationType.TRIGGER, device_entry.id
|
||||
)
|
||||
assert len(triggers) == 5
|
||||
assert len(triggers) == 6
|
||||
for trigger in triggers:
|
||||
capabilities = await async_get_device_automation_capabilities(
|
||||
hass, DeviceAutomationType.TRIGGER, trigger
|
||||
|
@ -109,7 +116,14 @@ async def test_if_fires_on_state_change(hass, calls):
|
|||
"{{{{ trigger.entity_id}}}} - {{{{ trigger.from_state.state}}}} - "
|
||||
"{{{{ trigger.to_state.state}}}} - {{{{ trigger.for }}}}"
|
||||
)
|
||||
trigger_types = {"turned_on", "turned_off", "idle", "paused", "playing"}
|
||||
trigger_types = {
|
||||
"turned_on",
|
||||
"turned_off",
|
||||
"idle",
|
||||
"paused",
|
||||
"playing",
|
||||
"changed_states",
|
||||
}
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
|
@ -137,47 +151,47 @@ async def test_if_fires_on_state_change(hass, calls):
|
|||
# Fake that the entity is turning on.
|
||||
hass.states.async_set("media_player.entity", STATE_ON)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 1
|
||||
assert (
|
||||
calls[0].data["some"]
|
||||
== "turned_on - device - media_player.entity - off - on - None"
|
||||
)
|
||||
assert len(calls) == 2
|
||||
assert {calls[0].data["some"], calls[1].data["some"]} == {
|
||||
"turned_on - device - media_player.entity - off - on - None",
|
||||
"changed_states - device - media_player.entity - off - on - None",
|
||||
}
|
||||
|
||||
# Fake that the entity is turning off.
|
||||
hass.states.async_set("media_player.entity", STATE_OFF)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 2
|
||||
assert (
|
||||
calls[1].data["some"]
|
||||
== "turned_off - device - media_player.entity - on - off - None"
|
||||
)
|
||||
assert len(calls) == 4
|
||||
assert {calls[2].data["some"], calls[3].data["some"]} == {
|
||||
"turned_off - device - media_player.entity - on - off - None",
|
||||
"changed_states - device - media_player.entity - on - off - None",
|
||||
}
|
||||
|
||||
# Fake that the entity becomes idle.
|
||||
hass.states.async_set("media_player.entity", STATE_IDLE)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 3
|
||||
assert (
|
||||
calls[2].data["some"]
|
||||
== "idle - device - media_player.entity - off - idle - None"
|
||||
)
|
||||
assert len(calls) == 6
|
||||
assert {calls[4].data["some"], calls[5].data["some"]} == {
|
||||
"idle - device - media_player.entity - off - idle - None",
|
||||
"changed_states - device - media_player.entity - off - idle - None",
|
||||
}
|
||||
|
||||
# Fake that the entity starts playing.
|
||||
hass.states.async_set("media_player.entity", STATE_PLAYING)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 4
|
||||
assert (
|
||||
calls[3].data["some"]
|
||||
== "playing - device - media_player.entity - idle - playing - None"
|
||||
)
|
||||
assert len(calls) == 8
|
||||
assert {calls[6].data["some"], calls[7].data["some"]} == {
|
||||
"playing - device - media_player.entity - idle - playing - None",
|
||||
"changed_states - device - media_player.entity - idle - playing - None",
|
||||
}
|
||||
|
||||
# Fake that the entity is paused.
|
||||
hass.states.async_set("media_player.entity", STATE_PAUSED)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 5
|
||||
assert (
|
||||
calls[4].data["some"]
|
||||
== "paused - device - media_player.entity - playing - paused - None"
|
||||
)
|
||||
assert len(calls) == 10
|
||||
assert {calls[8].data["some"], calls[9].data["some"]} == {
|
||||
"paused - device - media_player.entity - playing - paused - None",
|
||||
"changed_states - device - media_player.entity - playing - paused - None",
|
||||
}
|
||||
|
||||
|
||||
async def test_if_fires_on_state_change_with_for(hass, calls):
|
||||
|
|
Loading…
Reference in New Issue