-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdevice_trigger.py
167 lines (139 loc) · 4.69 KB
/
device_trigger.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
"""Provides device automations for Netatmo."""
from __future__ import annotations
import voluptuous as vol
from homeassistant.components.device_automation import (
DEVICE_TRIGGER_BASE_SCHEMA,
InvalidDeviceAutomationConfig,
)
from homeassistant.components.homeassistant.triggers import event as event_trigger
from homeassistant.const import (
ATTR_DEVICE_ID,
CONF_DEVICE_ID,
CONF_DOMAIN,
CONF_ENTITY_ID,
CONF_PLATFORM,
CONF_TYPE,
)
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
from homeassistant.helpers import (
config_validation as cv,
device_registry as dr,
entity_registry as er,
)
from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo
from homeassistant.helpers.typing import ConfigType
from .climate import STATE_NETATMO_AWAY, STATE_NETATMO_HG, STATE_NETATMO_SCHEDULE
from .const import (
CLIMATE_TRIGGERS,
DOMAIN,
EVENT_TYPE_THERM_MODE,
INDOOR_CAMERA_TRIGGERS,
NETATMO_EVENT,
OUTDOOR_CAMERA_TRIGGERS,
)
CONF_SUBTYPE = "subtype"
DEVICES = {
"Smart Indoor Camera": INDOOR_CAMERA_TRIGGERS,
"Smart Outdoor Camera": OUTDOOR_CAMERA_TRIGGERS,
"Smart Thermostat": CLIMATE_TRIGGERS,
"Smart Valve": CLIMATE_TRIGGERS,
}
SUBTYPES = {
EVENT_TYPE_THERM_MODE: [
STATE_NETATMO_SCHEDULE,
STATE_NETATMO_HG,
STATE_NETATMO_AWAY,
]
}
TRIGGER_TYPES = OUTDOOR_CAMERA_TRIGGERS + INDOOR_CAMERA_TRIGGERS + CLIMATE_TRIGGERS
TRIGGER_SCHEMA = DEVICE_TRIGGER_BASE_SCHEMA.extend(
{
vol.Required(CONF_ENTITY_ID): cv.entity_id_or_uuid,
vol.Required(CONF_TYPE): vol.In(TRIGGER_TYPES),
vol.Optional(CONF_SUBTYPE): str,
}
)
async def async_validate_trigger_config(
hass: HomeAssistant, config: ConfigType
) -> ConfigType:
"""Validate config."""
config = TRIGGER_SCHEMA(config)
device_registry = dr.async_get(hass)
device = device_registry.async_get(config[CONF_DEVICE_ID])
if not device or device.model is None:
raise InvalidDeviceAutomationConfig(
f"Trigger invalid, device with ID {config[CONF_DEVICE_ID]} not found"
)
trigger = config[CONF_TYPE]
if (
not device
or device.model not in DEVICES
or trigger not in DEVICES[device.model]
):
raise InvalidDeviceAutomationConfig(f"Unsupported model {device.model}")
return config
async def async_get_triggers(
hass: HomeAssistant, device_id: str
) -> list[dict[str, str]]:
"""List device triggers for Netatmo devices."""
registry = er.async_get(hass)
device_registry = dr.async_get(hass)
triggers: list[dict[str, str]] = []
for entry in er.async_entries_for_device(registry, device_id):
if (
device := device_registry.async_get(device_id)
) is None or device.model is None:
continue
for trigger in DEVICES.get(device.model, []):
if trigger in SUBTYPES:
triggers.extend(
{
CONF_PLATFORM: "device",
CONF_DEVICE_ID: device_id,
CONF_DOMAIN: DOMAIN,
CONF_ENTITY_ID: entry.id,
CONF_TYPE: trigger,
CONF_SUBTYPE: subtype,
}
for subtype in SUBTYPES[trigger]
)
else:
triggers.append(
{
CONF_PLATFORM: "device",
CONF_DEVICE_ID: device_id,
CONF_DOMAIN: DOMAIN,
CONF_ENTITY_ID: entry.id,
CONF_TYPE: trigger,
}
)
return triggers
async def async_attach_trigger(
hass: HomeAssistant,
config: ConfigType,
action: TriggerActionType,
trigger_info: TriggerInfo,
) -> CALLBACK_TYPE:
"""Attach a trigger."""
device_registry = dr.async_get(hass)
device = device_registry.async_get(config[CONF_DEVICE_ID])
if not device:
return lambda: None
if device.model not in DEVICES:
return lambda: None
event_config = {
event_trigger.CONF_PLATFORM: "event",
event_trigger.CONF_EVENT_TYPE: NETATMO_EVENT,
event_trigger.CONF_EVENT_DATA: {
"type": config[CONF_TYPE],
ATTR_DEVICE_ID: config[ATTR_DEVICE_ID],
},
}
if config[CONF_TYPE] in SUBTYPES:
event_config.update(
{event_trigger.CONF_EVENT_DATA: {"data": {"mode": config[CONF_SUBTYPE]}}}
)
event_config = event_trigger.TRIGGER_SCHEMA(event_config)
return await event_trigger.async_attach_trigger(
hass, event_config, action, trigger_info, platform_type="device"
)