Home Assistant Unofficial Reference 2024.12.1
reproduce_state.py
Go to the documentation of this file.
1 """Reproduce an Cover state."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 from collections.abc import Iterable
7 import logging
8 from typing import Any
9 
10 from homeassistant.const import (
11  ATTR_ENTITY_ID,
12  SERVICE_CLOSE_COVER,
13  SERVICE_CLOSE_COVER_TILT,
14  SERVICE_OPEN_COVER,
15  SERVICE_OPEN_COVER_TILT,
16  SERVICE_SET_COVER_POSITION,
17  SERVICE_SET_COVER_TILT_POSITION,
18 )
19 from homeassistant.core import Context, HomeAssistant, State
20 
21 from . import (
22  ATTR_CURRENT_POSITION,
23  ATTR_CURRENT_TILT_POSITION,
24  ATTR_POSITION,
25  ATTR_TILT_POSITION,
26  DOMAIN,
27  CoverState,
28 )
29 
30 _LOGGER = logging.getLogger(__name__)
31 
32 VALID_STATES = {
33  CoverState.CLOSED,
34  CoverState.CLOSING,
35  CoverState.OPEN,
36  CoverState.OPENING,
37 }
38 
39 
41  hass: HomeAssistant,
42  state: State,
43  *,
44  context: Context | None = None,
45  reproduce_options: dict[str, Any] | None = None,
46 ) -> None:
47  """Reproduce a single state."""
48  if (cur_state := hass.states.get(state.entity_id)) is None:
49  _LOGGER.warning("Unable to find entity %s", state.entity_id)
50  return
51 
52  if state.state not in VALID_STATES:
53  _LOGGER.warning(
54  "Invalid state specified for %s: %s", state.entity_id, state.state
55  )
56  return
57 
58  # Return if we are already at the right state.
59  if (
60  cur_state.state == state.state
61  and cur_state.attributes.get(ATTR_CURRENT_POSITION)
62  == state.attributes.get(ATTR_CURRENT_POSITION)
63  and cur_state.attributes.get(ATTR_CURRENT_TILT_POSITION)
64  == state.attributes.get(ATTR_CURRENT_TILT_POSITION)
65  ):
66  return
67 
68  service_data = {ATTR_ENTITY_ID: state.entity_id}
69  service_data_tilting = {ATTR_ENTITY_ID: state.entity_id}
70 
71  if not (
72  cur_state.state == state.state
73  and cur_state.attributes.get(ATTR_CURRENT_POSITION)
74  == state.attributes.get(ATTR_CURRENT_POSITION)
75  ):
76  # Open/Close
77  if state.state in [CoverState.CLOSED, CoverState.CLOSING]:
78  service = SERVICE_CLOSE_COVER
79  elif state.state in [CoverState.OPEN, CoverState.OPENING]:
80  if (
81  ATTR_CURRENT_POSITION in cur_state.attributes
82  and ATTR_CURRENT_POSITION in state.attributes
83  ):
84  service = SERVICE_SET_COVER_POSITION
85  service_data[ATTR_POSITION] = state.attributes[ATTR_CURRENT_POSITION]
86  else:
87  service = SERVICE_OPEN_COVER
88 
89  await hass.services.async_call(
90  DOMAIN, service, service_data, context=context, blocking=True
91  )
92 
93  if (
94  ATTR_CURRENT_TILT_POSITION in state.attributes
95  and ATTR_CURRENT_TILT_POSITION in cur_state.attributes
96  and cur_state.attributes.get(ATTR_CURRENT_TILT_POSITION)
97  != state.attributes.get(ATTR_CURRENT_TILT_POSITION)
98  ):
99  # Tilt position
100  if state.attributes.get(ATTR_CURRENT_TILT_POSITION) == 100:
101  service_tilting = SERVICE_OPEN_COVER_TILT
102  elif state.attributes.get(ATTR_CURRENT_TILT_POSITION) == 0:
103  service_tilting = SERVICE_CLOSE_COVER_TILT
104  else:
105  service_tilting = SERVICE_SET_COVER_TILT_POSITION
106  service_data_tilting[ATTR_TILT_POSITION] = state.attributes[
107  ATTR_CURRENT_TILT_POSITION
108  ]
109 
110  await hass.services.async_call(
111  DOMAIN,
112  service_tilting,
113  service_data_tilting,
114  context=context,
115  blocking=True,
116  )
117 
118 
120  hass: HomeAssistant,
121  states: Iterable[State],
122  *,
123  context: Context | None = None,
124  reproduce_options: dict[str, Any] | None = None,
125 ) -> None:
126  """Reproduce Cover states."""
127  # Reproduce states in parallel.
128  await asyncio.gather(
129  *(
131  hass, state, context=context, reproduce_options=reproduce_options
132  )
133  for state in states
134  )
135  )
None _async_reproduce_state(HomeAssistant hass, State state, *Context|None context=None, dict[str, Any]|None reproduce_options=None)
None async_reproduce_states(HomeAssistant hass, Iterable[State] states, *Context|None context=None, dict[str, Any]|None reproduce_options=None)