Home Assistant Unofficial Reference 2024.12.1
shade_data.py
Go to the documentation of this file.
1 """Shade data for the Hunter Douglas PowerView integration."""
2 
3 from __future__ import annotations
4 
5 from dataclasses import fields
6 from typing import Any
7 
8 from aiopvapi.resources.model import PowerviewData
9 from aiopvapi.resources.shade import BaseShade, ShadePosition
10 
11 from .util import async_map_data_by_id
12 
13 POSITION_FIELDS = [field for field in fields(ShadePosition) if field.name != "velocity"]
14 
15 
16 def copy_position_data(source: ShadePosition, target: ShadePosition) -> ShadePosition:
17  """Copy position data from source to target for None values only."""
18  for field in POSITION_FIELDS:
19  if (value := getattr(source, field.name)) is not None:
20  setattr(target, field.name, value)
21 
22 
24  """Coordinate shade data between multiple api calls."""
25 
26  def __init__(self) -> None:
27  """Init the shade data."""
28  self._raw_data_by_id_raw_data_by_id: dict[int, dict[str | int, Any]] = {}
29  self._shade_group_data_by_id_shade_group_data_by_id: dict[int, BaseShade] = {}
30  self.positions: dict[int, ShadePosition] = {}
31 
32  def get_raw_data(self, shade_id: int) -> dict[str | int, Any]:
33  """Get data for the shade."""
34  return self._raw_data_by_id_raw_data_by_id[shade_id]
35 
36  def get_all_raw_data(self) -> dict[int, dict[str | int, Any]]:
37  """Get data for all shades."""
38  return self._raw_data_by_id_raw_data_by_id
39 
40  def get_shade(self, shade_id: int) -> BaseShade:
41  """Get specific shade from the coordinator."""
42  return self._shade_group_data_by_id_shade_group_data_by_id[shade_id]
43 
44  def get_shade_position(self, shade_id: int) -> ShadePosition:
45  """Get positions for a shade."""
46  if shade_id not in self.positions:
47  shade_position = ShadePosition()
48  # If we have the group data, use it to populate the initial position
49  if shade := self._shade_group_data_by_id_shade_group_data_by_id.get(shade_id):
50  copy_position_data(shade.current_position, shade_position)
51  self.positions[shade_id] = shade_position
52  return self.positions[shade_id]
53 
54  def update_from_group_data(self, shade_id: int) -> None:
55  """Process an update from the group data."""
56  data = self._shade_group_data_by_id_shade_group_data_by_id[shade_id]
57  copy_position_data(data.current_position, self.get_shade_positionget_shade_position(data.id))
58 
59  def store_group_data(self, shade_data: PowerviewData) -> None:
60  """Store data from the all shades endpoint.
61 
62  This does not update the shades or positions (self.positions)
63  as the data may be stale. update_from_group_data
64  with a shade_id will update a specific shade
65  from the group data.
66  """
67  self._shade_group_data_by_id_shade_group_data_by_id = shade_data.processed
68  self._raw_data_by_id_raw_data_by_id = async_map_data_by_id(shade_data.raw)
69 
70  def update_shade_position(self, shade_id: int, new_position: ShadePosition) -> None:
71  """Update a single shades position."""
72  copy_position_data(new_position, self.get_shade_positionget_shade_position(shade_id))
73 
74  def update_shade_velocity(self, shade_id: int, shade_data: ShadePosition) -> None:
75  """Update a single shades velocity."""
76  # the hub will always return a velocity of 0 on initial connect,
77  # separate definition to store consistent value in HA
78  # this value is purely driven from HA
79  if shade_data.velocity is not None:
80  self.get_shade_positionget_shade_position(shade_id).velocity = shade_data.velocity
None update_shade_position(self, int shade_id, ShadePosition new_position)
Definition: shade_data.py:70
None update_shade_velocity(self, int shade_id, ShadePosition shade_data)
Definition: shade_data.py:74
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
ShadePosition copy_position_data(ShadePosition source, ShadePosition target)
Definition: shade_data.py:16
def async_map_data_by_id(Iterable[dict[str|int, Any]] data)
Definition: util.py:19