-
-
Notifications
You must be signed in to change notification settings - Fork 32k
/
Copy pathreproduce_state.py
98 lines (82 loc) · 3.08 KB
/
reproduce_state.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
"""Module that groups code required to handle state restore for component."""
from __future__ import annotations
import asyncio
from collections.abc import Iterable
import logging
from typing import Any
from homeassistant.const import (
ATTR_MODE,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
)
from homeassistant.core import Context, HomeAssistant, State
from .const import ATTR_HUMIDITY, DOMAIN, SERVICE_SET_HUMIDITY, SERVICE_SET_MODE
_LOGGER = logging.getLogger(__name__)
async def _async_reproduce_states(
hass: HomeAssistant,
state: State,
*,
context: Context | None = None,
reproduce_options: dict[str, Any] | None = None,
) -> None:
"""Reproduce component states."""
if (cur_state := hass.states.get(state.entity_id)) is None:
_LOGGER.warning("Unable to find entity %s", state.entity_id)
return
async def call_service(service: str, keys: Iterable[str]) -> None:
"""Call service with set of attributes given."""
data = {"entity_id": state.entity_id}
for key in keys:
if key in state.attributes:
data[key] = state.attributes[key]
await hass.services.async_call(
DOMAIN, service, data, blocking=True, context=context
)
if state.state == STATE_OFF:
# Ensure the device is off if it needs to be and exit
if cur_state.state != STATE_OFF:
await call_service(SERVICE_TURN_OFF, [])
return
if state.state != STATE_ON:
# we can't know how to handle this
_LOGGER.warning(
"Invalid state specified for %s: %s", state.entity_id, state.state
)
return
# First of all, turn on if needed, because the device might not
# be able to set mode and humidity while being off
if cur_state.state != STATE_ON:
await call_service(SERVICE_TURN_ON, [])
# refetch the state as turning on might allow us to see some more values
if (cur_state := hass.states.get(state.entity_id)) is None:
_LOGGER.warning("Unable to find entity %s", state.entity_id)
return
# Then set the mode before target humidity, because switching modes
# may invalidate target humidity
if ATTR_MODE in state.attributes and state.attributes[
ATTR_MODE
] != cur_state.attributes.get(ATTR_MODE):
await call_service(SERVICE_SET_MODE, [ATTR_MODE])
# Next, restore target humidity for the current mode
if ATTR_HUMIDITY in state.attributes and state.attributes[
ATTR_HUMIDITY
] != cur_state.attributes.get(ATTR_HUMIDITY):
await call_service(SERVICE_SET_HUMIDITY, [ATTR_HUMIDITY])
async def async_reproduce_states(
hass: HomeAssistant,
states: Iterable[State],
*,
context: Context | None = None,
reproduce_options: dict[str, Any] | None = None,
) -> None:
"""Reproduce component states."""
await asyncio.gather(
*(
_async_reproduce_states(
hass, state, context=context, reproduce_options=reproduce_options
)
for state in states
)
)