-
-
Notifications
You must be signed in to change notification settings - Fork 31.1k
/
device_action.py
146 lines (121 loc) · 4.84 KB
/
device_action.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""Provides device automations for Cover."""
from __future__ import annotations
import voluptuous as vol
from homeassistant.components.device_automation import async_validate_entity_schema
from homeassistant.const import (
ATTR_ENTITY_ID,
CONF_DEVICE_ID,
CONF_DOMAIN,
CONF_ENTITY_ID,
CONF_TYPE,
SERVICE_CLOSE_COVER,
SERVICE_CLOSE_COVER_TILT,
SERVICE_OPEN_COVER,
SERVICE_OPEN_COVER_TILT,
SERVICE_SET_COVER_POSITION,
SERVICE_SET_COVER_TILT_POSITION,
SERVICE_STOP_COVER,
)
from homeassistant.core import Context, HomeAssistant
from homeassistant.helpers import entity_registry as er
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import get_supported_features
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
from . import ATTR_POSITION, ATTR_TILT_POSITION, DOMAIN, CoverEntityFeature
CMD_ACTION_TYPES = {"open", "close", "stop", "open_tilt", "close_tilt"}
POSITION_ACTION_TYPES = {"set_position", "set_tilt_position"}
CMD_ACTION_SCHEMA = cv.DEVICE_ACTION_BASE_SCHEMA.extend(
{
vol.Required(CONF_TYPE): vol.In(CMD_ACTION_TYPES),
vol.Required(CONF_ENTITY_ID): cv.entity_id_or_uuid,
}
)
POSITION_ACTION_SCHEMA = cv.DEVICE_ACTION_BASE_SCHEMA.extend(
{
vol.Required(CONF_TYPE): vol.In(POSITION_ACTION_TYPES),
vol.Required(CONF_ENTITY_ID): cv.entity_id_or_uuid,
vol.Optional("position", default=0): vol.All(
vol.Coerce(int), vol.Range(min=0, max=100)
),
}
)
_ACTION_SCHEMA = vol.Any(CMD_ACTION_SCHEMA, POSITION_ACTION_SCHEMA)
async def async_validate_action_config(
hass: HomeAssistant, config: ConfigType
) -> ConfigType:
"""Validate config."""
return async_validate_entity_schema(hass, config, _ACTION_SCHEMA)
async def async_get_actions(
hass: HomeAssistant, device_id: str
) -> list[dict[str, str]]:
"""List device actions for Cover devices."""
registry = er.async_get(hass)
actions = []
# Get all the integrations entities for this device
for entry in er.async_entries_for_device(registry, device_id):
if entry.domain != DOMAIN:
continue
supported_features = get_supported_features(hass, entry.entity_id)
# Add actions for each entity that belongs to this integration
base_action = {
CONF_DEVICE_ID: device_id,
CONF_DOMAIN: DOMAIN,
CONF_ENTITY_ID: entry.id,
}
if supported_features & CoverEntityFeature.SET_POSITION:
actions.append({**base_action, CONF_TYPE: "set_position"})
if supported_features & CoverEntityFeature.OPEN:
actions.append({**base_action, CONF_TYPE: "open"})
if supported_features & CoverEntityFeature.CLOSE:
actions.append({**base_action, CONF_TYPE: "close"})
if supported_features & CoverEntityFeature.STOP:
actions.append({**base_action, CONF_TYPE: "stop"})
if supported_features & CoverEntityFeature.SET_TILT_POSITION:
actions.append({**base_action, CONF_TYPE: "set_tilt_position"})
if supported_features & CoverEntityFeature.OPEN_TILT:
actions.append({**base_action, CONF_TYPE: "open_tilt"})
if supported_features & CoverEntityFeature.CLOSE_TILT:
actions.append({**base_action, CONF_TYPE: "close_tilt"})
return actions
async def async_get_action_capabilities(
hass: HomeAssistant, config: ConfigType
) -> dict[str, vol.Schema]:
"""List action capabilities."""
if config[CONF_TYPE] not in POSITION_ACTION_TYPES:
return {}
return {
"extra_fields": vol.Schema(
{
vol.Optional(ATTR_POSITION, default=0): vol.All(
vol.Coerce(int), vol.Range(min=0, max=100)
)
}
)
}
async def async_call_action_from_config(
hass: HomeAssistant,
config: ConfigType,
variables: TemplateVarsType,
context: Context | None,
) -> None:
"""Execute a device action."""
service_data = {ATTR_ENTITY_ID: config[CONF_ENTITY_ID]}
if config[CONF_TYPE] == "open":
service = SERVICE_OPEN_COVER
elif config[CONF_TYPE] == "close":
service = SERVICE_CLOSE_COVER
elif config[CONF_TYPE] == "stop":
service = SERVICE_STOP_COVER
elif config[CONF_TYPE] == "open_tilt":
service = SERVICE_OPEN_COVER_TILT
elif config[CONF_TYPE] == "close_tilt":
service = SERVICE_CLOSE_COVER_TILT
elif config[CONF_TYPE] == "set_position":
service = SERVICE_SET_COVER_POSITION
service_data[ATTR_POSITION] = config["position"]
elif config[CONF_TYPE] == "set_tilt_position":
service = SERVICE_SET_COVER_TILT_POSITION
service_data[ATTR_TILT_POSITION] = config["position"]
await hass.services.async_call(
DOMAIN, service, service_data, blocking=True, context=context
)